kryten-webqueue 0.4.2__tar.gz → 0.4.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {kryten_webqueue-0.4.2 → kryten_webqueue-0.4.4}/PKG-INFO +1 -1
- {kryten_webqueue-0.4.2 → kryten_webqueue-0.4.4}/kryten_webqueue/queue/ordering.py +24 -18
- {kryten_webqueue-0.4.2 → kryten_webqueue-0.4.4}/kryten_webqueue/routes/queue.py +16 -10
- {kryten_webqueue-0.4.2 → kryten_webqueue-0.4.4}/pyproject.toml +1 -1
- {kryten_webqueue-0.4.2 → kryten_webqueue-0.4.4}/.github/workflows/python-publish.yml +0 -0
- {kryten_webqueue-0.4.2 → kryten_webqueue-0.4.4}/.github/workflows/release.yml +0 -0
- {kryten_webqueue-0.4.2 → kryten_webqueue-0.4.4}/.gitignore +0 -0
- {kryten_webqueue-0.4.2 → kryten_webqueue-0.4.4}/README.md +0 -0
- {kryten_webqueue-0.4.2 → kryten_webqueue-0.4.4}/config.example.json +0 -0
- {kryten_webqueue-0.4.2 → kryten_webqueue-0.4.4}/deploy/kryten-webqueue.service +0 -0
- {kryten_webqueue-0.4.2 → kryten_webqueue-0.4.4}/deploy/nginx-queue.conf +0 -0
- {kryten_webqueue-0.4.2 → kryten_webqueue-0.4.4}/docs/IMPLEMENTATION_SPEC.md +0 -0
- {kryten_webqueue-0.4.2 → kryten_webqueue-0.4.4}/docs/IMPL_API_GATE.md +0 -0
- {kryten_webqueue-0.4.2 → kryten_webqueue-0.4.4}/docs/IMPL_ECONOMY.md +0 -0
- {kryten_webqueue-0.4.2 → kryten_webqueue-0.4.4}/docs/IMPL_KRYTEN_PY.md +0 -0
- {kryten_webqueue-0.4.2 → kryten_webqueue-0.4.4}/docs/IMPL_ROBOT.md +0 -0
- {kryten_webqueue-0.4.2 → kryten_webqueue-0.4.4}/docs/PRE_PLAN_GAPS.md +0 -0
- {kryten_webqueue-0.4.2 → kryten_webqueue-0.4.4}/docs/PRODUCT_PLAN.md +0 -0
- {kryten_webqueue-0.4.2 → kryten_webqueue-0.4.4}/kryten_webqueue/__init__.py +0 -0
- {kryten_webqueue-0.4.2 → kryten_webqueue-0.4.4}/kryten_webqueue/__main__.py +0 -0
- {kryten_webqueue-0.4.2 → kryten_webqueue-0.4.4}/kryten_webqueue/api_gate/__init__.py +0 -0
- {kryten_webqueue-0.4.2 → kryten_webqueue-0.4.4}/kryten_webqueue/api_gate/client.py +0 -0
- {kryten_webqueue-0.4.2 → kryten_webqueue-0.4.4}/kryten_webqueue/app.py +0 -0
- {kryten_webqueue-0.4.2 → kryten_webqueue-0.4.4}/kryten_webqueue/auth/__init__.py +0 -0
- {kryten_webqueue-0.4.2 → kryten_webqueue-0.4.4}/kryten_webqueue/auth/otp.py +0 -0
- {kryten_webqueue-0.4.2 → kryten_webqueue-0.4.4}/kryten_webqueue/auth/rate_limit.py +0 -0
- {kryten_webqueue-0.4.2 → kryten_webqueue-0.4.4}/kryten_webqueue/auth/session.py +0 -0
- {kryten_webqueue-0.4.2 → kryten_webqueue-0.4.4}/kryten_webqueue/catalog/__init__.py +0 -0
- {kryten_webqueue-0.4.2 → kryten_webqueue-0.4.4}/kryten_webqueue/catalog/db.py +0 -0
- {kryten_webqueue-0.4.2 → kryten_webqueue-0.4.4}/kryten_webqueue/catalog/images.py +0 -0
- {kryten_webqueue-0.4.2 → kryten_webqueue-0.4.4}/kryten_webqueue/catalog/sync.py +0 -0
- {kryten_webqueue-0.4.2 → kryten_webqueue-0.4.4}/kryten_webqueue/config.py +0 -0
- {kryten_webqueue-0.4.2 → kryten_webqueue-0.4.4}/kryten_webqueue/playlists/__init__.py +0 -0
- {kryten_webqueue-0.4.2 → kryten_webqueue-0.4.4}/kryten_webqueue/playlists/fire.py +0 -0
- {kryten_webqueue-0.4.2 → kryten_webqueue-0.4.4}/kryten_webqueue/playlists/importer.py +0 -0
- {kryten_webqueue-0.4.2 → kryten_webqueue-0.4.4}/kryten_webqueue/playlists/scheduler.py +0 -0
- {kryten_webqueue-0.4.2 → kryten_webqueue-0.4.4}/kryten_webqueue/queue/__init__.py +0 -0
- {kryten_webqueue-0.4.2 → kryten_webqueue-0.4.4}/kryten_webqueue/queue/poller.py +0 -0
- {kryten_webqueue-0.4.2 → kryten_webqueue-0.4.4}/kryten_webqueue/queue/shadow.py +0 -0
- {kryten_webqueue-0.4.2 → kryten_webqueue-0.4.4}/kryten_webqueue/routes/__init__.py +0 -0
- {kryten_webqueue-0.4.2 → kryten_webqueue-0.4.4}/kryten_webqueue/routes/admin_playlists.py +0 -0
- {kryten_webqueue-0.4.2 → kryten_webqueue-0.4.4}/kryten_webqueue/routes/admin_queue.py +0 -0
- {kryten_webqueue-0.4.2 → kryten_webqueue-0.4.4}/kryten_webqueue/routes/admin_schedules.py +0 -0
- {kryten_webqueue-0.4.2 → kryten_webqueue-0.4.4}/kryten_webqueue/routes/auth.py +0 -0
- {kryten_webqueue-0.4.2 → kryten_webqueue-0.4.4}/kryten_webqueue/routes/catalog.py +0 -0
- {kryten_webqueue-0.4.2 → kryten_webqueue-0.4.4}/kryten_webqueue/routes/pages.py +0 -0
- {kryten_webqueue-0.4.2 → kryten_webqueue-0.4.4}/kryten_webqueue/routes/user.py +0 -0
- {kryten_webqueue-0.4.2 → kryten_webqueue-0.4.4}/kryten_webqueue/static/css/main.css +0 -0
- {kryten_webqueue-0.4.2 → kryten_webqueue-0.4.4}/kryten_webqueue/static/js/main.js +0 -0
- {kryten_webqueue-0.4.2 → kryten_webqueue-0.4.4}/kryten_webqueue/templates/admin/index.html +0 -0
- {kryten_webqueue-0.4.2 → kryten_webqueue-0.4.4}/kryten_webqueue/templates/admin/playlists.html +0 -0
- {kryten_webqueue-0.4.2 → kryten_webqueue-0.4.4}/kryten_webqueue/templates/admin/queue_mgmt.html +0 -0
- {kryten_webqueue-0.4.2 → kryten_webqueue-0.4.4}/kryten_webqueue/templates/admin/schedules.html +0 -0
- {kryten_webqueue-0.4.2 → kryten_webqueue-0.4.4}/kryten_webqueue/templates/auth/login.html +0 -0
- {kryten_webqueue-0.4.2 → kryten_webqueue-0.4.4}/kryten_webqueue/templates/base.html +0 -0
- {kryten_webqueue-0.4.2 → kryten_webqueue-0.4.4}/kryten_webqueue/templates/catalog/browse.html +0 -0
- {kryten_webqueue-0.4.2 → kryten_webqueue-0.4.4}/kryten_webqueue/templates/queue/index.html +0 -0
- {kryten_webqueue-0.4.2 → kryten_webqueue-0.4.4}/kryten_webqueue/templates/user/dashboard.html +0 -0
- {kryten_webqueue-0.4.2 → kryten_webqueue-0.4.4}/kryten_webqueue/ws/__init__.py +0 -0
- {kryten_webqueue-0.4.2 → kryten_webqueue-0.4.4}/kryten_webqueue/ws/handler.py +0 -0
- {kryten_webqueue-0.4.2 → kryten_webqueue-0.4.4}/kryten_webqueue/ws/manager.py +0 -0
|
@@ -2,6 +2,8 @@ import asyncio
|
|
|
2
2
|
import uuid
|
|
3
3
|
import logging
|
|
4
4
|
|
|
5
|
+
import httpx
|
|
6
|
+
|
|
5
7
|
logger = logging.getLogger(__name__)
|
|
6
8
|
|
|
7
9
|
# Module-level lock for queue ordering
|
|
@@ -25,15 +27,17 @@ async def insert_pay_queue(
|
|
|
25
27
|
async with _queue_lock:
|
|
26
28
|
request_id = str(uuid.uuid4())
|
|
27
29
|
|
|
28
|
-
# Spend currency
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
30
|
+
# Spend currency (api-gate _unwrap strips the success envelope;
|
|
31
|
+
# raise_for_status propagates failures as httpx.HTTPStatusError)
|
|
32
|
+
try:
|
|
33
|
+
await api_gate.queue_spend(
|
|
34
|
+
username=username,
|
|
35
|
+
duration_sec=duration_sec,
|
|
36
|
+
tier=tier,
|
|
37
|
+
request_id=request_id,
|
|
38
|
+
)
|
|
39
|
+
except httpx.HTTPStatusError as exc:
|
|
40
|
+
return {"success": False, "error": f"Spend failed: {exc.response.status_code}"}
|
|
37
41
|
|
|
38
42
|
# Find position: after last pay item, or prepend if none
|
|
39
43
|
last_pay_uid = await db.get_last_pay_uid()
|
|
@@ -109,15 +113,17 @@ async def insert_pay_playnext(
|
|
|
109
113
|
async with _queue_lock:
|
|
110
114
|
request_id = str(uuid.uuid4())
|
|
111
115
|
|
|
112
|
-
# Spend currency
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
116
|
+
# Spend currency (api-gate _unwrap strips the success envelope;
|
|
117
|
+
# raise_for_status propagates failures as httpx.HTTPStatusError)
|
|
118
|
+
try:
|
|
119
|
+
await api_gate.queue_spend(
|
|
120
|
+
username=username,
|
|
121
|
+
duration_sec=duration_sec,
|
|
122
|
+
tier=tier,
|
|
123
|
+
request_id=request_id,
|
|
124
|
+
)
|
|
125
|
+
except httpx.HTTPStatusError as exc:
|
|
126
|
+
return {"success": False, "error": f"Spend failed: {exc.response.status_code}"}
|
|
121
127
|
|
|
122
128
|
# Add to CyTube playlist at prepend position
|
|
123
129
|
add_result = await api_gate.playlist_add(
|
|
@@ -36,16 +36,19 @@ async def add_to_queue(request: Request, user: dict = Depends(get_current_user))
|
|
|
36
36
|
if not item:
|
|
37
37
|
raise HTTPException(404, "Item not found in catalog")
|
|
38
38
|
|
|
39
|
-
# Preview cost
|
|
39
|
+
# Preview cost (api-gate _unwrap strips the success envelope; raise_for_status
|
|
40
|
+
# handles non-2xx, so no success check needed here)
|
|
40
41
|
preview = await api_gate.queue_preview(
|
|
41
42
|
username=user["username"],
|
|
42
43
|
duration_sec=item["duration_sec"],
|
|
43
44
|
tier=tier,
|
|
44
45
|
)
|
|
45
|
-
if not preview.get("
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
z_cost = preview
|
|
46
|
+
if not preview.get("available", True):
|
|
47
|
+
error_code = preview.get("error_code") or "unavailable"
|
|
48
|
+
raise HTTPException(400, error_code)
|
|
49
|
+
z_cost = preview.get("cost_z")
|
|
50
|
+
if z_cost is None:
|
|
51
|
+
raise HTTPException(502, "Cost preview returned no cost value")
|
|
49
52
|
|
|
50
53
|
result = await insert_pay_queue(
|
|
51
54
|
api_gate=api_gate,
|
|
@@ -88,16 +91,19 @@ async def play_next(request: Request, user: dict = Depends(get_current_user)):
|
|
|
88
91
|
if not item:
|
|
89
92
|
raise HTTPException(404, "Item not found in catalog")
|
|
90
93
|
|
|
91
|
-
# Preview cost
|
|
94
|
+
# Preview cost (api-gate _unwrap strips the success envelope; raise_for_status
|
|
95
|
+
# handles non-2xx, so no success check needed here)
|
|
92
96
|
preview = await api_gate.queue_preview(
|
|
93
97
|
username=user["username"],
|
|
94
98
|
duration_sec=item["duration_sec"],
|
|
95
99
|
tier=tier,
|
|
96
100
|
)
|
|
97
|
-
if not preview.get("
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
z_cost = preview
|
|
101
|
+
if not preview.get("available", True):
|
|
102
|
+
error_code = preview.get("error_code") or "unavailable"
|
|
103
|
+
raise HTTPException(400, error_code)
|
|
104
|
+
z_cost = preview.get("cost_z")
|
|
105
|
+
if z_cost is None:
|
|
106
|
+
raise HTTPException(502, "Cost preview returned no cost value")
|
|
101
107
|
|
|
102
108
|
result = await insert_pay_playnext(
|
|
103
109
|
api_gate=api_gate,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{kryten_webqueue-0.4.2 → kryten_webqueue-0.4.4}/kryten_webqueue/templates/admin/playlists.html
RENAMED
|
File without changes
|
{kryten_webqueue-0.4.2 → kryten_webqueue-0.4.4}/kryten_webqueue/templates/admin/queue_mgmt.html
RENAMED
|
File without changes
|
{kryten_webqueue-0.4.2 → kryten_webqueue-0.4.4}/kryten_webqueue/templates/admin/schedules.html
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{kryten_webqueue-0.4.2 → kryten_webqueue-0.4.4}/kryten_webqueue/templates/catalog/browse.html
RENAMED
|
File without changes
|
|
File without changes
|
{kryten_webqueue-0.4.2 → kryten_webqueue-0.4.4}/kryten_webqueue/templates/user/dashboard.html
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|