kryten-webqueue 0.2.9__tar.gz → 0.3.1__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.2.9 → kryten_webqueue-0.3.1}/PKG-INFO +1 -1
- {kryten_webqueue-0.2.9 → kryten_webqueue-0.3.1}/kryten_webqueue/app.py +10 -9
- {kryten_webqueue-0.2.9 → kryten_webqueue-0.3.1}/kryten_webqueue/catalog/sync.py +11 -1
- {kryten_webqueue-0.2.9 → kryten_webqueue-0.3.1}/pyproject.toml +1 -1
- {kryten_webqueue-0.2.9 → kryten_webqueue-0.3.1}/.github/workflows/python-publish.yml +0 -0
- {kryten_webqueue-0.2.9 → kryten_webqueue-0.3.1}/.github/workflows/release.yml +0 -0
- {kryten_webqueue-0.2.9 → kryten_webqueue-0.3.1}/.gitignore +0 -0
- {kryten_webqueue-0.2.9 → kryten_webqueue-0.3.1}/README.md +0 -0
- {kryten_webqueue-0.2.9 → kryten_webqueue-0.3.1}/config.example.json +0 -0
- {kryten_webqueue-0.2.9 → kryten_webqueue-0.3.1}/deploy/kryten-webqueue.service +0 -0
- {kryten_webqueue-0.2.9 → kryten_webqueue-0.3.1}/deploy/nginx-queue.conf +0 -0
- {kryten_webqueue-0.2.9 → kryten_webqueue-0.3.1}/docs/IMPLEMENTATION_SPEC.md +0 -0
- {kryten_webqueue-0.2.9 → kryten_webqueue-0.3.1}/docs/IMPL_API_GATE.md +0 -0
- {kryten_webqueue-0.2.9 → kryten_webqueue-0.3.1}/docs/IMPL_ECONOMY.md +0 -0
- {kryten_webqueue-0.2.9 → kryten_webqueue-0.3.1}/docs/IMPL_KRYTEN_PY.md +0 -0
- {kryten_webqueue-0.2.9 → kryten_webqueue-0.3.1}/docs/IMPL_ROBOT.md +0 -0
- {kryten_webqueue-0.2.9 → kryten_webqueue-0.3.1}/docs/PRE_PLAN_GAPS.md +0 -0
- {kryten_webqueue-0.2.9 → kryten_webqueue-0.3.1}/docs/PRODUCT_PLAN.md +0 -0
- {kryten_webqueue-0.2.9 → kryten_webqueue-0.3.1}/kryten_webqueue/__init__.py +0 -0
- {kryten_webqueue-0.2.9 → kryten_webqueue-0.3.1}/kryten_webqueue/__main__.py +0 -0
- {kryten_webqueue-0.2.9 → kryten_webqueue-0.3.1}/kryten_webqueue/api_gate/__init__.py +0 -0
- {kryten_webqueue-0.2.9 → kryten_webqueue-0.3.1}/kryten_webqueue/api_gate/client.py +0 -0
- {kryten_webqueue-0.2.9 → kryten_webqueue-0.3.1}/kryten_webqueue/auth/__init__.py +0 -0
- {kryten_webqueue-0.2.9 → kryten_webqueue-0.3.1}/kryten_webqueue/auth/otp.py +0 -0
- {kryten_webqueue-0.2.9 → kryten_webqueue-0.3.1}/kryten_webqueue/auth/rate_limit.py +0 -0
- {kryten_webqueue-0.2.9 → kryten_webqueue-0.3.1}/kryten_webqueue/auth/session.py +0 -0
- {kryten_webqueue-0.2.9 → kryten_webqueue-0.3.1}/kryten_webqueue/catalog/__init__.py +0 -0
- {kryten_webqueue-0.2.9 → kryten_webqueue-0.3.1}/kryten_webqueue/catalog/db.py +0 -0
- {kryten_webqueue-0.2.9 → kryten_webqueue-0.3.1}/kryten_webqueue/catalog/images.py +0 -0
- {kryten_webqueue-0.2.9 → kryten_webqueue-0.3.1}/kryten_webqueue/config.py +0 -0
- {kryten_webqueue-0.2.9 → kryten_webqueue-0.3.1}/kryten_webqueue/playlists/__init__.py +0 -0
- {kryten_webqueue-0.2.9 → kryten_webqueue-0.3.1}/kryten_webqueue/playlists/fire.py +0 -0
- {kryten_webqueue-0.2.9 → kryten_webqueue-0.3.1}/kryten_webqueue/playlists/importer.py +0 -0
- {kryten_webqueue-0.2.9 → kryten_webqueue-0.3.1}/kryten_webqueue/playlists/scheduler.py +0 -0
- {kryten_webqueue-0.2.9 → kryten_webqueue-0.3.1}/kryten_webqueue/queue/__init__.py +0 -0
- {kryten_webqueue-0.2.9 → kryten_webqueue-0.3.1}/kryten_webqueue/queue/ordering.py +0 -0
- {kryten_webqueue-0.2.9 → kryten_webqueue-0.3.1}/kryten_webqueue/queue/poller.py +0 -0
- {kryten_webqueue-0.2.9 → kryten_webqueue-0.3.1}/kryten_webqueue/queue/shadow.py +0 -0
- {kryten_webqueue-0.2.9 → kryten_webqueue-0.3.1}/kryten_webqueue/routes/__init__.py +0 -0
- {kryten_webqueue-0.2.9 → kryten_webqueue-0.3.1}/kryten_webqueue/routes/admin_playlists.py +0 -0
- {kryten_webqueue-0.2.9 → kryten_webqueue-0.3.1}/kryten_webqueue/routes/admin_queue.py +0 -0
- {kryten_webqueue-0.2.9 → kryten_webqueue-0.3.1}/kryten_webqueue/routes/admin_schedules.py +0 -0
- {kryten_webqueue-0.2.9 → kryten_webqueue-0.3.1}/kryten_webqueue/routes/auth.py +0 -0
- {kryten_webqueue-0.2.9 → kryten_webqueue-0.3.1}/kryten_webqueue/routes/catalog.py +0 -0
- {kryten_webqueue-0.2.9 → kryten_webqueue-0.3.1}/kryten_webqueue/routes/pages.py +0 -0
- {kryten_webqueue-0.2.9 → kryten_webqueue-0.3.1}/kryten_webqueue/routes/queue.py +0 -0
- {kryten_webqueue-0.2.9 → kryten_webqueue-0.3.1}/kryten_webqueue/routes/user.py +0 -0
- {kryten_webqueue-0.2.9 → kryten_webqueue-0.3.1}/kryten_webqueue/static/css/main.css +0 -0
- {kryten_webqueue-0.2.9 → kryten_webqueue-0.3.1}/kryten_webqueue/static/js/main.js +0 -0
- {kryten_webqueue-0.2.9 → kryten_webqueue-0.3.1}/kryten_webqueue/templates/admin/index.html +0 -0
- {kryten_webqueue-0.2.9 → kryten_webqueue-0.3.1}/kryten_webqueue/templates/auth/login.html +0 -0
- {kryten_webqueue-0.2.9 → kryten_webqueue-0.3.1}/kryten_webqueue/templates/base.html +0 -0
- {kryten_webqueue-0.2.9 → kryten_webqueue-0.3.1}/kryten_webqueue/templates/catalog/browse.html +0 -0
- {kryten_webqueue-0.2.9 → kryten_webqueue-0.3.1}/kryten_webqueue/templates/queue/index.html +0 -0
- {kryten_webqueue-0.2.9 → kryten_webqueue-0.3.1}/kryten_webqueue/templates/user/dashboard.html +0 -0
- {kryten_webqueue-0.2.9 → kryten_webqueue-0.3.1}/kryten_webqueue/ws/__init__.py +0 -0
- {kryten_webqueue-0.2.9 → kryten_webqueue-0.3.1}/kryten_webqueue/ws/handler.py +0 -0
- {kryten_webqueue-0.2.9 → kryten_webqueue-0.3.1}/kryten_webqueue/ws/manager.py +0 -0
|
@@ -45,15 +45,7 @@ async def lifespan(app: FastAPI):
|
|
|
45
45
|
api_gate = ApiGateClient(config.api_gate_url, config.api_gate_token)
|
|
46
46
|
app.state.api_gate = api_gate
|
|
47
47
|
|
|
48
|
-
#
|
|
49
|
-
catalog_sync = CatalogSync(
|
|
50
|
-
mediacms_url=config.mediacms_url,
|
|
51
|
-
mediacms_token=config.mediacms_token,
|
|
52
|
-
db=db,
|
|
53
|
-
)
|
|
54
|
-
app.state.catalog_sync = catalog_sync
|
|
55
|
-
|
|
56
|
-
# Cover art resolver
|
|
48
|
+
# Cover art resolver (created before sync so it can be passed in)
|
|
57
49
|
cover_art = CoverArtResolver(
|
|
58
50
|
image_dir=config.image_dir,
|
|
59
51
|
placeholder_dir=config.placeholder_dir,
|
|
@@ -62,6 +54,15 @@ async def lifespan(app: FastAPI):
|
|
|
62
54
|
)
|
|
63
55
|
app.state.cover_art = cover_art
|
|
64
56
|
|
|
57
|
+
# Catalog sync
|
|
58
|
+
catalog_sync = CatalogSync(
|
|
59
|
+
mediacms_url=config.mediacms_url,
|
|
60
|
+
mediacms_token=config.mediacms_token,
|
|
61
|
+
db=db,
|
|
62
|
+
cover_art=cover_art,
|
|
63
|
+
)
|
|
64
|
+
app.state.catalog_sync = catalog_sync
|
|
65
|
+
|
|
65
66
|
# WebSocket manager
|
|
66
67
|
ws_manager = WebSocketManager()
|
|
67
68
|
app.state.ws_manager = ws_manager
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import asyncio
|
|
1
2
|
import httpx
|
|
2
3
|
import logging
|
|
3
4
|
from datetime import datetime, UTC
|
|
@@ -28,7 +29,7 @@ def _describe_httpx_error(exc: Exception, url: str) -> str:
|
|
|
28
29
|
class CatalogSync:
|
|
29
30
|
"""Synchronizes catalog data from MediaCMS."""
|
|
30
31
|
|
|
31
|
-
def __init__(self, *, mediacms_url: str, mediacms_token: str, db):
|
|
32
|
+
def __init__(self, *, mediacms_url: str, mediacms_token: str, db, cover_art=None):
|
|
32
33
|
# Strip any accidental /api/v1 suffix — the sync code appends it itself
|
|
33
34
|
url = mediacms_url.rstrip("/")
|
|
34
35
|
for suffix in ("/api/v1", "/api"):
|
|
@@ -38,6 +39,7 @@ class CatalogSync:
|
|
|
38
39
|
self._url = url
|
|
39
40
|
self._token = mediacms_token
|
|
40
41
|
self._db = db
|
|
42
|
+
self._cover_art = cover_art
|
|
41
43
|
self._client = httpx.AsyncClient(
|
|
42
44
|
headers={"Authorization": f"Token {mediacms_token}"},
|
|
43
45
|
timeout=30.0,
|
|
@@ -127,6 +129,14 @@ class CatalogSync:
|
|
|
127
129
|
await self._db.insert_catalog(row)
|
|
128
130
|
stats["new"] += 1
|
|
129
131
|
|
|
132
|
+
# Fetch TMDB/OMDB cover art if not already cached
|
|
133
|
+
if self._cover_art and not (existing and existing.get("cover_art_path")):
|
|
134
|
+
try:
|
|
135
|
+
await self._cover_art.resolve(token, row["title"], self._db)
|
|
136
|
+
except Exception as e:
|
|
137
|
+
logger.debug(f"Cover art resolve failed for {token}: {e}")
|
|
138
|
+
await asyncio.sleep(0.25)
|
|
139
|
+
|
|
130
140
|
def _build_manifest_url(self, media: dict) -> str:
|
|
131
141
|
# Use the MediaCMS watch page URL (e.g. https://www.dropsugar.co/view?m=TOKEN)
|
|
132
142
|
url = media.get("url", "")
|
|
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
|
|
File without changes
|
|
File without changes
|
{kryten_webqueue-0.2.9 → kryten_webqueue-0.3.1}/kryten_webqueue/templates/catalog/browse.html
RENAMED
|
File without changes
|
|
File without changes
|
{kryten_webqueue-0.2.9 → kryten_webqueue-0.3.1}/kryten_webqueue/templates/user/dashboard.html
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|