kryten-webqueue 0.35.8__tar.gz → 0.36.0__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.35.8 → kryten_webqueue-0.36.0}/CHANGELOG.md +32 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/PKG-INFO +1 -1
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/catalog/db/_connection.py +4 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/catalog/db/_enrichment.py +2 -1
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/catalog/enrichment/classify.py +33 -4
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/catalog/enrichment/steps/title.py +11 -1
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/static/css/main.css +37 -3
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/templates/catalog/item_detail.html +16 -1
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/pyproject.toml +1 -1
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/.github/workflows/gitleaks.yml +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/.github/workflows/python-publish.yml +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/.github/workflows/release.yml +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/.gitignore +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/.gitleaks.toml +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/.pre-commit-config.yaml +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/AGENT-WORKFLOW-GUIDE.md +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/README.md +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/config.example.json +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/deploy/kryten-webqueue.service +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/deploy/nginx-queue.conf +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/docs/IMPLEMENTATION_SPEC.md +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/docs/IMPL_API_GATE.md +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/docs/IMPL_ECONOMY.md +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/docs/IMPL_KRYTEN_PY.md +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/docs/IMPL_ROBOT.md +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/docs/Kryten-Economy Service Quality Survey Report at v0.13.0.md +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/docs/Kryten-Webqueue Service Quality Survey Report at v0.27.1.md +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/docs/Log for incorrect promo insertion problem.txt +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/docs/PLAN_PRESENCE_AND_PROMOS.md +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/docs/PRE_PLAN_GAPS.md +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/docs/PRODUCT_PLAN.md +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/docs/SPEC_CATALOG_ENRICHMENT_PIPELINE.md +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/docs/SPEC_EMOTE_REHOST.md +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/docs/SPEC_JOBS_AND_BROWSE.md +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/docs/UX_POLISH_PLAN.md +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/__init__.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/__main__.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/api_gate/__init__.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/api_gate/client.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/app.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/auth/__init__.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/auth/otp.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/auth/rate_limit.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/auth/session.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/catalog/__init__.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/catalog/db/__init__.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/catalog/db/_catalog.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/catalog/db/_feedback.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/catalog/db/_people.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/catalog/db/_playlists.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/catalog/db/_queue.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/catalog/db/_watchlist.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/catalog/enrichment/__init__.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/catalog/enrichment/normalise.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/catalog/enrichment/pipeline.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/catalog/enrichment/providers.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/catalog/enrichment/report.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/catalog/enrichment/steps/__init__.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/catalog/enrichment/steps/art.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/catalog/enrichment/steps/categories.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/catalog/enrichment/steps/meta.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/catalog/enrichment/steps/sync.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/catalog/enrichment/steps/tags.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/catalog/images.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/catalog/mediacms.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/catalog/sync.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/config.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/integrations/__init__.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/integrations/cmsutils/__init__.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/integrations/cmsutils/_common.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/integrations/cmsutils/enrichmeta.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/integrations/cmsutils/enrichtitles.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/integrations/cmsutils/enrichtv.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/integrations/cmsutils/fetchurls.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/integrations/cmsutils/motdposters.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/integrations/cmsutils/playedmovies.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/integrations/ytpipe/__init__.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/integrations/ytpipe/downloader.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/jobs/__init__.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/jobs/fetchurls_auth.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/jobs/job_scheduler.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/jobs/manager.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/jobs/rehost_emotes.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/jobs/tasks.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/logging_config.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/playlists/__init__.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/playlists/bulk_add.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/playlists/fire.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/playlists/importer.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/playlists/ordering.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/playlists/scheduler.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/promos/__init__.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/promos/director.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/queue/__init__.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/queue/completion.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/queue/ordering.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/queue/poller.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/queue/presence.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/queue/race_poller.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/queue/shadow.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/routes/__init__.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/routes/admin_catalog.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/routes/admin_feedback.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/routes/admin_job_schedules.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/routes/admin_jobs.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/routes/admin_moderation.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/routes/admin_playlists.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/routes/admin_promos.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/routes/admin_queue.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/routes/admin_schedules.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/routes/auth.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/routes/catalog.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/routes/feedback.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/routes/pages.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/routes/queue.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/routes/user.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/static/js/admin-playlists.js +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/static/js/admin-promos.js +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/static/js/admin-queue-mgmt.js +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/static/js/admin-schedules.js +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/static/js/admin.js +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/static/js/main.js +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/templates/admin/index.html +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/templates/admin/playlists.html +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/templates/admin/promos.html +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/templates/admin/queue_mgmt.html +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/templates/admin/schedules.html +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/templates/auth/login.html +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/templates/base.html +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/templates/catalog/browse.html +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/templates/catalog/item_not_found.html +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/templates/feedback/index.html +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/templates/queue/index.html +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/templates/race.html +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/templates/user/dashboard.html +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/templates/user/my_list.html +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/ws/__init__.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/ws/handler.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/ws/manager.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/tests/__init__.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/tests/test_classify.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/tests/test_config_persistence.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/tests/test_feedback.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/tests/test_fetchurls_sharepoint.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/tests/test_people_facets.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/tests/test_phase1.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/tests/test_phase2_jobs.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/tests/test_phase3_jobs.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/tests/test_phase4_live_fixes.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/tests/test_playlist_import.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/tests/test_presence_refund.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/tests/test_promo_director.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/tests/test_promo_pool_exclusion.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/tests/test_providers.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/tests/test_queue_announce.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/tests/test_race_poller.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/tests/test_recently_played_hide.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/tests/test_save_results_to_playlist.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/tests/test_schedule_lock.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/tests/test_search_facets.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/tests/test_title_normalization.py +0 -0
- {kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/tests/test_watchlist.py +0 -0
|
@@ -2,6 +2,38 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [0.36.0] - 2026-08-14
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- **New hosted movie shows.** Added support for "13 Nights of Elvira", "JBB" (shorthand
|
|
10
|
+
for Joe Bob Briggs), and "TLDI" (shorthand for The Last Drive-In).
|
|
11
|
+
- **Hosted movie title formatting.** Hosted movies now display as "Movie Title (YYYY) - Show Name"
|
|
12
|
+
(e.g., "Friday the 13th (1980) - Svengoolie"), ensuring year is always in parentheses
|
|
13
|
+
and show name is appended as a suffix.
|
|
14
|
+
- **Collapsible cast & crew in descriptions.** When person/role/studio data exists, the
|
|
15
|
+
"Cast & Crew" section in item descriptions is now collapsed by default to avoid
|
|
16
|
+
duplication. Users can expand it with a single click.
|
|
17
|
+
- **Improved YouTube title cleanup.** Enhanced detection of YouTube imports with pipe
|
|
18
|
+
characters and "full movie" patterns (e.g., "Title | Full Movie HD | Description"),
|
|
19
|
+
extracting the clean title before the first pipe.
|
|
20
|
+
- **Distinct tag styling.** Tags now display with orange/accent color borders to
|
|
21
|
+
differentiate them from categories (purple) and persons/studios (green/gold).
|
|
22
|
+
|
|
23
|
+
### Fixed
|
|
24
|
+
|
|
25
|
+
- **Better Monstervision title extraction.** Monstervision titles like "Monstervision 01
|
|
26
|
+
Friday the 13th Part 1" now extract to clean movie titles with proper database lookups.
|
|
27
|
+
|
|
28
|
+
## [0.35.9] - 2026-08-14
|
|
29
|
+
|
|
30
|
+
### Fixed
|
|
31
|
+
|
|
32
|
+
- **Missing database column for categories step.** Added `last_categories_at` column
|
|
33
|
+
to `item_enrichment_state` table (migration v20) to support the categories enrichment
|
|
34
|
+
step. This fixes `OperationalError: no such column: e.last_categories_at` that blocked
|
|
35
|
+
enrichment jobs when the categories step was included.
|
|
36
|
+
|
|
5
37
|
## [0.35.8] - 2026-08-14
|
|
6
38
|
|
|
7
39
|
### Fixed
|
|
@@ -43,6 +43,7 @@ class _EnrichmentMixin:
|
|
|
43
43
|
"last_meta_at",
|
|
44
44
|
"last_art_at",
|
|
45
45
|
"last_tags_at",
|
|
46
|
+
"last_categories_at",
|
|
46
47
|
}
|
|
47
48
|
safe = {k: v for k, v in fields.items() if k in allowed}
|
|
48
49
|
if not safe:
|
|
@@ -77,7 +78,7 @@ class _EnrichmentMixin:
|
|
|
77
78
|
e.tv_show, e.tv_season, e.tv_episode_num,
|
|
78
79
|
e.description_score, e.tmdb_id, e.imdb_id, e.meta_json,
|
|
79
80
|
e.last_classify_at, e.last_title_at, e.last_meta_at,
|
|
80
|
-
e.last_art_at, e.last_tags_at
|
|
81
|
+
e.last_art_at, e.last_tags_at, e.last_categories_at
|
|
81
82
|
FROM catalog c
|
|
82
83
|
LEFT JOIN item_enrichment_state e ON e.friendly_token = c.friendly_token
|
|
83
84
|
"""
|
{kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/catalog/enrichment/classify.py
RENAMED
|
@@ -35,6 +35,15 @@ HOSTED_SHOW_REGISTRY: list[HostedShowEntry] = [
|
|
|
35
35
|
None,
|
|
36
36
|
"joebobbriggs",
|
|
37
37
|
),
|
|
38
|
+
# "JBB" shorthand for Joe Bob Briggs
|
|
39
|
+
HostedShowEntry(
|
|
40
|
+
re.compile(r"\bJBB\b", re.I),
|
|
41
|
+
"Joe Bob Briggs",
|
|
42
|
+
"hosted_movie",
|
|
43
|
+
"keep",
|
|
44
|
+
None,
|
|
45
|
+
"joebobbriggs",
|
|
46
|
+
),
|
|
38
47
|
HostedShowEntry(
|
|
39
48
|
re.compile(r"JBBTLDI|Joe\s*Bob\s+TLDI", re.I),
|
|
40
49
|
"The Last Drive-In with Joe Bob Briggs",
|
|
@@ -43,6 +52,15 @@ HOSTED_SHOW_REGISTRY: list[HostedShowEntry] = [
|
|
|
43
52
|
None,
|
|
44
53
|
"lastdrivein",
|
|
45
54
|
),
|
|
55
|
+
# "TLDI" shorthand for The Last Drive-In
|
|
56
|
+
HostedShowEntry(
|
|
57
|
+
re.compile(r"\bTLDI\b", re.I),
|
|
58
|
+
"The Last Drive-In with Joe Bob Briggs",
|
|
59
|
+
"hosted_movie",
|
|
60
|
+
"keep",
|
|
61
|
+
None,
|
|
62
|
+
"lastdrivein",
|
|
63
|
+
),
|
|
46
64
|
HostedShowEntry(
|
|
47
65
|
re.compile(r"(?:The\s+)?Last\s+Drive[\s\-]*In", re.I),
|
|
48
66
|
"The Last Drive-In with Joe Bob Briggs",
|
|
@@ -67,6 +85,14 @@ HOSTED_SHOW_REGISTRY: list[HostedShowEntry] = [
|
|
|
67
85
|
None,
|
|
68
86
|
"svengoolie",
|
|
69
87
|
),
|
|
88
|
+
HostedShowEntry(
|
|
89
|
+
re.compile(r"13\s+Nights?\s+of\s+Elvira", re.I),
|
|
90
|
+
"13 Nights of Elvira",
|
|
91
|
+
"hosted_movie",
|
|
92
|
+
"keep",
|
|
93
|
+
None,
|
|
94
|
+
"elvira",
|
|
95
|
+
),
|
|
70
96
|
HostedShowEntry(
|
|
71
97
|
re.compile(r"Riff\s*Trax(?:\s+Live)?", re.I),
|
|
72
98
|
"RiffTrax",
|
|
@@ -225,8 +251,9 @@ class ItemClassification:
|
|
|
225
251
|
|
|
226
252
|
|
|
227
253
|
# YouTube "Title | English Full Movie | Genre1 Genre2" pattern
|
|
254
|
+
# Also handles variants like "Title | Full Movie HD | Description"
|
|
228
255
|
_YT_FULL_MOVIE_RE = re.compile(
|
|
229
|
-
r"^(?P<title>.+?)\s
|
|
256
|
+
r"^(?P<title>.+?)\s*\|.*(Full\s+(?:Movie|Film|Length|Feature)).*$", re.I
|
|
230
257
|
)
|
|
231
258
|
|
|
232
259
|
|
|
@@ -299,18 +326,20 @@ def classify_item(
|
|
|
299
326
|
|
|
300
327
|
# 4. Movie (>= 30 min)
|
|
301
328
|
if duration_sec >= 1800:
|
|
329
|
+
# YouTube title cleanup: extract title before first pipe if "full movie" appears
|
|
302
330
|
yt = _YT_FULL_MOVIE_RE.match(raw_title.strip())
|
|
303
331
|
if yt:
|
|
304
332
|
clean_title = yt.group("title").strip()
|
|
305
|
-
|
|
333
|
+
# Extract year from the clean title part
|
|
334
|
+
clean_title, year = normalize_and_clean(clean_title)
|
|
306
335
|
return ItemClassification(
|
|
307
336
|
friendly_token=friendly_token,
|
|
308
337
|
raw_title=raw_title,
|
|
309
338
|
content_type="movie",
|
|
310
339
|
hosted=None,
|
|
311
340
|
lookup_title=clean_title,
|
|
312
|
-
lookup_year=
|
|
313
|
-
genre_hints=
|
|
341
|
+
lookup_year=year,
|
|
342
|
+
genre_hints=[],
|
|
314
343
|
duration_sec=duration_sec,
|
|
315
344
|
description_score=description_score,
|
|
316
345
|
has_real_art=has_real_art,
|
{kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/catalog/enrichment/steps/title.py
RENAMED
|
@@ -89,6 +89,16 @@ class TitleStep:
|
|
|
89
89
|
else:
|
|
90
90
|
candidate = clean
|
|
91
91
|
return candidate if candidate != cls.raw_title else None
|
|
92
|
+
if ct == "hosted_movie" and cls.hosted:
|
|
93
|
+
# Format as "Movie Title (YYYY) - Show Name"
|
|
94
|
+
t = cls.hosted.movie_title
|
|
95
|
+
y = cls.hosted.movie_year
|
|
96
|
+
show = cls.hosted.show_name
|
|
97
|
+
if y:
|
|
98
|
+
candidate = f"{t} ({y}) - {show}"
|
|
99
|
+
else:
|
|
100
|
+
candidate = f"{t} - {show}"
|
|
101
|
+
return candidate if candidate != cls.raw_title else None
|
|
92
102
|
if ct == "riffed_movie" and cls.hosted:
|
|
93
103
|
entry_template = cls.hosted # HostedInfo has show_name
|
|
94
104
|
if "{title}" in (cls.hosted.show_name or ""):
|
|
@@ -100,7 +110,7 @@ class TitleStep:
|
|
|
100
110
|
return (
|
|
101
111
|
f"RiffTrax Presents: {t} ({y})" if y else f"RiffTrax Presents: {t}"
|
|
102
112
|
)
|
|
103
|
-
#
|
|
113
|
+
# archive / unknown / tv_episode: no change
|
|
104
114
|
return None
|
|
105
115
|
|
|
106
116
|
async def _push_title(
|
|
@@ -740,9 +740,9 @@ a.np-chip {
|
|
|
740
740
|
border: 1px solid var(--accent);
|
|
741
741
|
}
|
|
742
742
|
.np-chip-tag {
|
|
743
|
-
background:
|
|
744
|
-
color: var(--
|
|
745
|
-
border: 1px solid var(--
|
|
743
|
+
background: rgba(232, 150, 16, 0.15);
|
|
744
|
+
color: var(--accent);
|
|
745
|
+
border: 1px solid var(--accent);
|
|
746
746
|
}
|
|
747
747
|
.np-chip-person {
|
|
748
748
|
background: rgba(0, 168, 120, 0.15);
|
|
@@ -768,6 +768,40 @@ a.np-chip {
|
|
|
768
768
|
font-weight: 600;
|
|
769
769
|
}
|
|
770
770
|
|
|
771
|
+
/* Cast & Crew collapsible section in item detail */
|
|
772
|
+
.item-detail-cast-crew-collapse {
|
|
773
|
+
margin-top: 1rem;
|
|
774
|
+
padding: 0.5rem 0;
|
|
775
|
+
}
|
|
776
|
+
.item-detail-cast-crew-collapse summary {
|
|
777
|
+
cursor: pointer;
|
|
778
|
+
padding: 0.5rem;
|
|
779
|
+
background: var(--bg-secondary);
|
|
780
|
+
border-radius: var(--radius);
|
|
781
|
+
color: var(--text-secondary);
|
|
782
|
+
font-size: 0.9rem;
|
|
783
|
+
user-select: none;
|
|
784
|
+
list-style: none;
|
|
785
|
+
display: flex;
|
|
786
|
+
align-items: center;
|
|
787
|
+
}
|
|
788
|
+
.item-detail-cast-crew-collapse summary::-webkit-details-marker {
|
|
789
|
+
display: none;
|
|
790
|
+
}
|
|
791
|
+
.item-detail-cast-crew-collapse summary::before {
|
|
792
|
+
content: "▸";
|
|
793
|
+
display: inline-block;
|
|
794
|
+
margin-right: 0.5rem;
|
|
795
|
+
transition: transform 0.2s;
|
|
796
|
+
}
|
|
797
|
+
.item-detail-cast-crew-collapse[open] summary::before {
|
|
798
|
+
transform: rotate(90deg);
|
|
799
|
+
}
|
|
800
|
+
.item-detail-cast-crew-collapse summary:hover {
|
|
801
|
+
background: var(--bg-hover);
|
|
802
|
+
color: var(--text-primary);
|
|
803
|
+
}
|
|
804
|
+
|
|
771
805
|
/* WebSocket status */
|
|
772
806
|
.ws-connected {
|
|
773
807
|
color: var(--success);
|
{kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/templates/catalog/item_detail.html
RENAMED
|
@@ -41,7 +41,22 @@
|
|
|
41
41
|
</div>
|
|
42
42
|
|
|
43
43
|
{% if item.description %}
|
|
44
|
-
|
|
44
|
+
{% set has_people_data = people.cast or people.director or people.producer or people.writer or studios %}
|
|
45
|
+
{% if has_people_data %}
|
|
46
|
+
{# Split description at "Cast & Crew" and make that section collapsible #}
|
|
47
|
+
{% set description_parts = item.description.split('Cast & Crew') %}
|
|
48
|
+
{% if description_parts|length > 1 %}
|
|
49
|
+
<div class="item-detail-description">{{ description_parts[0] }}</div>
|
|
50
|
+
<details class="item-detail-cast-crew-collapse">
|
|
51
|
+
<summary>Cast & Crew (from description)</summary>
|
|
52
|
+
<div class="item-detail-description">{{ description_parts[1] }}</div>
|
|
53
|
+
</details>
|
|
54
|
+
{% else %}
|
|
55
|
+
<p class="item-detail-description">{{ item.description }}</p>
|
|
56
|
+
{% endif %}
|
|
57
|
+
{% else %}
|
|
58
|
+
<p class="item-detail-description">{{ item.description }}</p>
|
|
59
|
+
{% endif %}
|
|
45
60
|
{% else %}
|
|
46
61
|
<p class="item-detail-description empty-state">No description available.</p>
|
|
47
62
|
{% endif %}
|
|
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.35.8 → kryten_webqueue-0.36.0}/docs/Log for incorrect promo insertion problem.txt
RENAMED
|
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.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/catalog/enrichment/__init__.py
RENAMED
|
File without changes
|
{kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/catalog/enrichment/normalise.py
RENAMED
|
File without changes
|
{kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/catalog/enrichment/pipeline.py
RENAMED
|
File without changes
|
{kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/catalog/enrichment/providers.py
RENAMED
|
File without changes
|
{kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/catalog/enrichment/report.py
RENAMED
|
File without changes
|
|
File without changes
|
{kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/catalog/enrichment/steps/art.py
RENAMED
|
File without changes
|
|
File without changes
|
{kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/catalog/enrichment/steps/meta.py
RENAMED
|
File without changes
|
{kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/catalog/enrichment/steps/sync.py
RENAMED
|
File without changes
|
{kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/catalog/enrichment/steps/tags.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/integrations/cmsutils/__init__.py
RENAMED
|
File without changes
|
{kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/integrations/cmsutils/_common.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/integrations/cmsutils/enrichtv.py
RENAMED
|
File without changes
|
{kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/integrations/cmsutils/fetchurls.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/integrations/ytpipe/__init__.py
RENAMED
|
File without changes
|
{kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/integrations/ytpipe/downloader.py
RENAMED
|
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.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/routes/admin_job_schedules.py
RENAMED
|
File without changes
|
|
File without changes
|
{kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/routes/admin_moderation.py
RENAMED
|
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.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/static/js/admin-playlists.js
RENAMED
|
File without changes
|
|
File without changes
|
{kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/static/js/admin-queue-mgmt.js
RENAMED
|
File without changes
|
{kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/static/js/admin-schedules.js
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/templates/admin/index.html
RENAMED
|
File without changes
|
{kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/templates/admin/playlists.html
RENAMED
|
File without changes
|
{kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/templates/admin/promos.html
RENAMED
|
File without changes
|
{kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/templates/admin/queue_mgmt.html
RENAMED
|
File without changes
|
{kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/templates/admin/schedules.html
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/templates/catalog/browse.html
RENAMED
|
File without changes
|
|
File without changes
|
{kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/templates/feedback/index.html
RENAMED
|
File without changes
|
{kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/templates/queue/index.html
RENAMED
|
File without changes
|
|
File without changes
|
{kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/templates/user/dashboard.html
RENAMED
|
File without changes
|
{kryten_webqueue-0.35.8 → kryten_webqueue-0.36.0}/kryten_webqueue/templates/user/my_list.html
RENAMED
|
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
|