-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathplay_queue.py
More file actions
99 lines (86 loc) · 3.56 KB
/
Copy pathplay_queue.py
File metadata and controls
99 lines (86 loc) · 3.56 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
"""Pure helpers for OpenBox's persistent play queue."""
from __future__ import annotations
from datetime import datetime, timezone
CAP = 500
NOTE_LIMIT = 200
def normalize_queue(value):
if not isinstance(value, list):
return []
result = []
for item in value[:CAP]:
if not isinstance(item, dict):
continue
game_id = str(item.get("game_id") or "").strip()
if not game_id:
continue
result.append({
"game_id": game_id,
"added_at": str(item.get("added_at") or datetime.now(timezone.utc).isoformat()),
"note": str(item.get("note") or "")[:NOTE_LIMIT],
"skip": bool(item.get("skip")),
})
return result
def resolve_queue(state):
games = {str(game.get("game_id")): game for game in state.get("games", []) if isinstance(game, dict)}
result = []
for entry in normalize_queue(state.get("queue")):
game = games.get(entry["game_id"])
result.append({
**entry,
"name": game.get("name", "Missing") if game else "Missing",
"platform": game.get("platform", "") if game else "",
"cover": game.get("cover", "") if game else "",
"path_exists": bool(game and game.get("path")),
"missing": game is None,
})
return result
def enqueue(state, game_ids, position=None, note=""):
if not isinstance(game_ids, list) or not all(isinstance(item, str) and item.strip() for item in game_ids):
raise ValueError("game_ids must be a list of strings.")
known = {str(game.get("game_id")) for game in state.get("games", [])}
unknown = [item for item in game_ids if item not in known]
if unknown:
raise ValueError(f"Game not found: {unknown[0]}")
queue = normalize_queue(state.get("queue"))
entries = [{"game_id": item, "added_at": datetime.now(timezone.utc).isoformat(), "note": str(note or "")[:NOTE_LIMIT], "skip": False} for item in game_ids]
if position is None:
queue.extend(entries)
else:
position = max(0, min(int(position), len(queue)))
queue[position:position] = entries
state["queue"] = queue[:CAP]
return game_ids
def remove(state, game_ids):
ids = set(game_ids or [])
before = normalize_queue(state.get("queue"))
state["queue"] = [item for item in before if item["game_id"] not in ids]
return len(before) - len(state["queue"])
def reorder(state, ordered_game_ids):
current = normalize_queue(state.get("queue"))
if len(ordered_game_ids or []) != len(current) or sorted(ordered_game_ids) != sorted(item["game_id"] for item in current):
raise ValueError("ordered_game_ids must contain the current queue entries.")
buckets = {}
for item in current:
buckets.setdefault(item["game_id"], []).append(item)
state["queue"] = [buckets[item].pop(0) for item in ordered_game_ids]
return state["queue"]
def advance(state, current_game_id=None):
queue = normalize_queue(state.get("queue"))
start = -1
if current_game_id:
for index, item in enumerate(queue):
if item["game_id"] == current_game_id:
start = index
break
games = {str(game.get("game_id")): game for game in state.get("games", [])}
for index in range(start + 1, len(queue)):
item = queue[index]
if item.get("skip"):
continue
game = games.get(item["game_id"])
if not game or not game.get("path"):
item["skip"] = True
continue
return item
state["queue"] = queue
return None