kryten-webqueue 0.40.2__tar.gz → 0.40.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.40.2 → kryten_webqueue-0.40.4}/CHANGELOG.md +24 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/PKG-INFO +1 -1
- kryten_webqueue-0.40.4/kryten_webqueue/static/js/keybindings.js +59 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/templates/base.html +1 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/templates/catalog/browse.html +25 -5
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/pyproject.toml +1 -1
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/.github/workflows/gitleaks.yml +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/.github/workflows/python-publish.yml +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/.github/workflows/release.yml +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/.gitignore +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/.gitleaks.toml +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/.pre-commit-config.yaml +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/AGENT-WORKFLOW-GUIDE.md +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/AGENTS.md +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/README.md +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/config.example.json +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/deploy/kryten-webqueue.service +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/deploy/nginx-queue.conf +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/docs/IMPLEMENTATION_SPEC.md +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/docs/IMPL_API_GATE.md +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/docs/IMPL_ECONOMY.md +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/docs/IMPL_KRYTEN_PY.md +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/docs/IMPL_ROBOT.md +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/docs/Kryten-Economy Service Quality Survey Report at v0.13.0.md +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/docs/Kryten-Webqueue Service Quality Survey Report at v0.27.1.md +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/docs/Log for incorrect promo insertion problem.txt +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/docs/PLAN_PRESENCE_AND_PROMOS.md +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/docs/PRD_TMDB_LOCAL_INDEX.md +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/docs/PRE_PLAN_GAPS.md +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/docs/PRODUCT_PLAN.md +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/docs/SPEC-Visual-UX-Sprint-August-2026.md +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/docs/SPEC_ADMIN_ITEM_EDITOR.md +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/docs/SPEC_CATALOG_ENRICHMENT_PIPELINE.md +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/docs/SPEC_EMOTE_REHOST.md +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/docs/SPEC_JOBS_AND_BROWSE.md +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/docs/SPEC_TMDB_LOCAL_INDEX.md +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/docs/UX_POLISH_PLAN.md +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/__init__.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/__main__.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/api_gate/__init__.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/api_gate/client.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/app.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/auth/__init__.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/auth/otp.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/auth/rate_limit.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/auth/session.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/catalog/__init__.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/catalog/db/__init__.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/catalog/db/_catalog.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/catalog/db/_connection.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/catalog/db/_enrichment.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/catalog/db/_feedback.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/catalog/db/_fetch_queue.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/catalog/db/_people.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/catalog/db/_playlists.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/catalog/db/_queue.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/catalog/db/_watchlist.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/catalog/enrichment/__init__.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/catalog/enrichment/classify.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/catalog/enrichment/normalise.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/catalog/enrichment/pipeline.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/catalog/enrichment/providers.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/catalog/enrichment/report.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/catalog/enrichment/steps/__init__.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/catalog/enrichment/steps/art.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/catalog/enrichment/steps/categories.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/catalog/enrichment/steps/identify.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/catalog/enrichment/steps/meta.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/catalog/enrichment/steps/sync.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/catalog/enrichment/steps/tags.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/catalog/enrichment/steps/title.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/catalog/images.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/catalog/mediacms.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/catalog/sync.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/catalog/tmdb_index/__init__.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/catalog/tmdb_index/_schema.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/catalog/tmdb_index/_textmatch.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/catalog/tmdb_index/_ttscrape.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/catalog/tmdb_index/builder.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/catalog/tmdb_index/coverage.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/catalog/tmdb_index/index.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/config.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/integrations/__init__.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/integrations/cmsutils/__init__.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/integrations/cmsutils/_common.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/integrations/cmsutils/enrichmeta.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/integrations/cmsutils/enrichtitles.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/integrations/cmsutils/enrichtv.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/integrations/cmsutils/fetchurls.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/integrations/cmsutils/motdposters.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/integrations/cmsutils/playedmovies.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/integrations/ytpipe/__init__.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/integrations/ytpipe/downloader.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/jobs/__init__.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/jobs/fetchurls_auth.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/jobs/job_scheduler.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/jobs/manager.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/jobs/rehost_emotes.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/jobs/tasks.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/logging_config.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/playlists/__init__.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/playlists/bulk_add.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/playlists/fire.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/playlists/importer.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/playlists/ordering.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/playlists/scheduler.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/promos/__init__.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/promos/director.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/queue/__init__.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/queue/completion.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/queue/ordering.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/queue/poller.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/queue/presence.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/queue/race_poller.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/queue/shadow.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/routes/__init__.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/routes/admin_catalog.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/routes/admin_feedback.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/routes/admin_job_schedules.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/routes/admin_jobs.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/routes/admin_moderation.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/routes/admin_playlists.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/routes/admin_promos.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/routes/admin_queue.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/routes/admin_schedules.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/routes/auth.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/routes/catalog.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/routes/feedback.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/routes/pages.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/routes/queue.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/routes/user.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/static/css/main.css +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/static/js/admin-playlists.js +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/static/js/admin-promos.js +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/static/js/admin-queue-mgmt.js +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/static/js/admin-schedules.js +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/static/js/admin.js +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/static/js/main.js +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/templates/admin/index.html +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/templates/admin/playlists.html +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/templates/admin/promos.html +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/templates/admin/queue_mgmt.html +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/templates/admin/schedules.html +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/templates/auth/login.html +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/templates/catalog/edit_item_modal.html +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/templates/catalog/item_detail.html +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/templates/catalog/item_not_found.html +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/templates/feedback/index.html +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/templates/queue/index.html +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/templates/race.html +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/templates/user/dashboard.html +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/templates/user/my_list.html +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/ws/__init__.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/ws/handler.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/ws/manager.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/scripts/AGENTS.md +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/scripts/patch_mediacms_bulk_facets.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/scripts/patch_mediacms_tags.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/scripts/trigger_enrich.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/tests/__init__.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/tests/test_catalog_delete.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/tests/test_classify.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/tests/test_config_persistence.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/tests/test_feedback.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/tests/test_fetchurls_sharepoint.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/tests/test_identify_step.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/tests/test_people_facets.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/tests/test_phase1.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/tests/test_phase2_jobs.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/tests/test_phase3_jobs.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/tests/test_phase4_live_fixes.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/tests/test_playlist_import.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/tests/test_presence_refund.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/tests/test_promo_director.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/tests/test_promo_pool_exclusion.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/tests/test_providers.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/tests/test_queue_announce.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/tests/test_race_poller.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/tests/test_recently_played_hide.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/tests/test_save_results_to_playlist.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/tests/test_schedule_lock.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/tests/test_search_facets.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/tests/test_title_normalization.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/tests/test_tmdb_index.py +0 -0
- {kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/tests/test_watchlist.py +0 -0
|
@@ -2,6 +2,30 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [0.40.4] - 2026-08-21
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- **Keyboard pagination on browse/search pages.** The Left and Right arrow keys
|
|
10
|
+
now navigate to the previous/next page of results. Keys are ignored while
|
|
11
|
+
typing in a field or when a modal is open, and fall through to the browser's
|
|
12
|
+
default behaviour on the first/last page. Backed by a new global
|
|
13
|
+
`keybindings.js` registry (`Keybindings.register`/`unregister`) so future
|
|
14
|
+
shortcuts can be added without re-implementing the "don't steal keys while
|
|
15
|
+
typing" guard.
|
|
16
|
+
|
|
17
|
+
## [0.40.3] - 2026-08-21
|
|
18
|
+
|
|
19
|
+
### Fixed
|
|
20
|
+
|
|
21
|
+
- **Browse/search pagination no longer bounces back to page 1 when a non-default
|
|
22
|
+
duration or sort is active.** Pagination links omitted the `duration` filter
|
|
23
|
+
(and carried a stale `hide_short=0` param), so paging landed on a URL without
|
|
24
|
+
`duration`; the client-side preference-restore then re-applied the saved filter
|
|
25
|
+
via `applyFacets()`, which rebuilds the URL without `page` — sending the user
|
|
26
|
+
to page 1. Links now carry `duration`, and `restorePreferences()` skips any URL
|
|
27
|
+
that already has a `page` param so explicit pagination is never hijacked.
|
|
28
|
+
|
|
5
29
|
## [0.40.2] - 2026-08-21
|
|
6
30
|
|
|
7
31
|
### Changed
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/* kryten-webqueue — Keyboard shortcuts
|
|
2
|
+
*
|
|
3
|
+
* A tiny global registry so pages can bind keys without each re-implementing
|
|
4
|
+
* "ignore keystrokes while the user is typing / a modal is open" logic.
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* Keybindings.register('ArrowRight', () => { ... }); // return false to fall through
|
|
8
|
+
* Keybindings.unregister('ArrowRight');
|
|
9
|
+
*
|
|
10
|
+
* Key strings are modifier-prefixed and use the raw KeyboardEvent.key value,
|
|
11
|
+
* e.g. 'ArrowLeft', 'ctrl+k', 'shift+/'.
|
|
12
|
+
*/
|
|
13
|
+
(function () {
|
|
14
|
+
const bindings = new Map();
|
|
15
|
+
|
|
16
|
+
function isEditableTarget(el) {
|
|
17
|
+
if (!el) return false;
|
|
18
|
+
const tag = el.tagName;
|
|
19
|
+
if (tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT') return true;
|
|
20
|
+
return !!el.isContentEditable;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function keyFromEvent(e) {
|
|
24
|
+
const parts = [];
|
|
25
|
+
if (e.ctrlKey) parts.push('ctrl');
|
|
26
|
+
if (e.altKey) parts.push('alt');
|
|
27
|
+
if (e.shiftKey) parts.push('shift');
|
|
28
|
+
if (e.metaKey) parts.push('meta');
|
|
29
|
+
parts.push(e.key);
|
|
30
|
+
return parts.join('+');
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function onKeyDown(e) {
|
|
34
|
+
// Never steal keys while typing in a field.
|
|
35
|
+
if (isEditableTarget(document.activeElement)) return;
|
|
36
|
+
// Leave an open modal to its own keyboard handling.
|
|
37
|
+
if (document.querySelector('.modal-overlay')) return;
|
|
38
|
+
|
|
39
|
+
const handler = bindings.get(keyFromEvent(e));
|
|
40
|
+
if (!handler) return;
|
|
41
|
+
|
|
42
|
+
// Handlers return false to decline (e.g. no target to act on), in which
|
|
43
|
+
// case we leave the browser's default behaviour intact.
|
|
44
|
+
if (handler(e) !== false) {
|
|
45
|
+
e.preventDefault();
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
document.addEventListener('keydown', onKeyDown);
|
|
50
|
+
|
|
51
|
+
window.Keybindings = {
|
|
52
|
+
register(key, handler) {
|
|
53
|
+
bindings.set(key, handler);
|
|
54
|
+
},
|
|
55
|
+
unregister(key) {
|
|
56
|
+
bindings.delete(key);
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
})();
|
{kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/templates/catalog/browse.html
RENAMED
|
@@ -125,7 +125,7 @@
|
|
|
125
125
|
</div>
|
|
126
126
|
|
|
127
127
|
{% set sort_q = ('&sort=' ~ sort) if (sort and sort != 'default') else '' %}
|
|
128
|
-
{% set
|
|
128
|
+
{% set duration_q = ('&duration=' ~ duration) if (duration and duration != '10+') else '' %}
|
|
129
129
|
{% set person_q = ('&person=' ~ active_person | urlencode) if active_person else '' %}
|
|
130
130
|
{% set studio_q = ('&studio=' ~ active_studio | urlencode) if active_studio else '' %}
|
|
131
131
|
{% if not items %}
|
|
@@ -168,7 +168,7 @@
|
|
|
168
168
|
|
|
169
169
|
<div class="pagination">
|
|
170
170
|
{% if page > 1 %}
|
|
171
|
-
<a href="?page={{ page - 1 }}{% if query %}&q={{ query }}{% endif %}{% if active_category %}&category={{ active_category }}{% endif %}{% if active_tag %}&tag={{ active_tag | urlencode }}{% endif %}{{ sort_q }}{{
|
|
171
|
+
<a id="pagination-prev" href="?page={{ page - 1 }}{% if query %}&q={{ query }}{% endif %}{% if active_category %}&category={{ active_category }}{% endif %}{% if active_tag %}&tag={{ active_tag | urlencode }}{% endif %}{{ sort_q }}{{ duration_q }}{{ person_q }}{{ studio_q }}" class="btn btn-sm">← Prev</a>
|
|
172
172
|
{% endif %}
|
|
173
173
|
|
|
174
174
|
{% set start_page = [1, page - 2] | max %}
|
|
@@ -177,14 +177,14 @@
|
|
|
177
177
|
{% if p == page %}
|
|
178
178
|
<span class="page-num page-current">{{ p }}</span>
|
|
179
179
|
{% else %}
|
|
180
|
-
<a href="?page={{ p }}{% if query %}&q={{ query }}{% endif %}{% if active_category %}&category={{ active_category }}{% endif %}{% if active_tag %}&tag={{ active_tag | urlencode }}{% endif %}{{ sort_q }}{{
|
|
180
|
+
<a href="?page={{ p }}{% if query %}&q={{ query }}{% endif %}{% if active_category %}&category={{ active_category }}{% endif %}{% if active_tag %}&tag={{ active_tag | urlencode }}{% endif %}{{ sort_q }}{{ duration_q }}{{ person_q }}{{ studio_q }}" class="btn btn-sm btn-page">{{ p }}</a>
|
|
181
181
|
{% endif %}
|
|
182
182
|
{% endfor %}
|
|
183
183
|
|
|
184
184
|
<span class="page-info">of {{ total_pages }}</span>
|
|
185
185
|
|
|
186
186
|
{% if page < total_pages %}
|
|
187
|
-
<a href="?page={{ page + 1 }}{% if query %}&q={{ query }}{% endif %}{% if active_category %}&category={{ active_category }}{% endif %}{% if active_tag %}&tag={{ active_tag | urlencode }}{% endif %}{{ sort_q }}{{
|
|
187
|
+
<a id="pagination-next" href="?page={{ page + 1 }}{% if query %}&q={{ query }}{% endif %}{% if active_category %}&category={{ active_category }}{% endif %}{% if active_tag %}&tag={{ active_tag | urlencode }}{% endif %}{{ sort_q }}{{ duration_q }}{{ person_q }}{{ studio_q }}" class="btn btn-sm">Next →</a>
|
|
188
188
|
{% endif %}
|
|
189
189
|
</div>
|
|
190
190
|
{% endblock %}
|
|
@@ -229,7 +229,11 @@ function applyFacets() {
|
|
|
229
229
|
const sortSel = document.getElementById('sort-select');
|
|
230
230
|
const durationSel = document.getElementById('duration-select');
|
|
231
231
|
const url = new URL(window.location.href);
|
|
232
|
-
|
|
232
|
+
|
|
233
|
+
// Never hijack an explicit paginated navigation: applyFacets() drops the
|
|
234
|
+
// page, so restoring a saved pref here would bounce the user back to page 1.
|
|
235
|
+
if (url.searchParams.has('page')) return;
|
|
236
|
+
|
|
233
237
|
// Restore sort preference
|
|
234
238
|
if (sortSel && !url.searchParams.has('sort')) {
|
|
235
239
|
let saved = null;
|
|
@@ -471,6 +475,22 @@ async function clearPlayed(token) {
|
|
|
471
475
|
}
|
|
472
476
|
// queueItem / playNext / queueAsAdmin / showToast / escapeHtml are provided by /static/js/main.js
|
|
473
477
|
initWatchlistButtons();
|
|
478
|
+
|
|
479
|
+
// Left/Right arrows page through browse/search results. Handlers decline
|
|
480
|
+
// (return false) when there's no prev/next link so the browser keeps its
|
|
481
|
+
// default arrow behaviour on the first/last page.
|
|
482
|
+
if (window.Keybindings) {
|
|
483
|
+
Keybindings.register('ArrowLeft', () => {
|
|
484
|
+
const prev = document.getElementById('pagination-prev');
|
|
485
|
+
if (!prev) return false;
|
|
486
|
+
window.location.href = prev.href;
|
|
487
|
+
});
|
|
488
|
+
Keybindings.register('ArrowRight', () => {
|
|
489
|
+
const next = document.getElementById('pagination-next');
|
|
490
|
+
if (!next) return false;
|
|
491
|
+
window.location.href = next.href;
|
|
492
|
+
});
|
|
493
|
+
}
|
|
474
494
|
</script>
|
|
475
495
|
|
|
476
496
|
{% include "catalog/edit_item_modal.html" %}
|
|
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.40.2 → kryten_webqueue-0.40.4}/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
|
|
File without changes
|
|
File without changes
|
{kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/catalog/db/_fetch_queue.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/catalog/enrichment/__init__.py
RENAMED
|
File without changes
|
{kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/catalog/enrichment/classify.py
RENAMED
|
File without changes
|
{kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/catalog/enrichment/normalise.py
RENAMED
|
File without changes
|
{kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/catalog/enrichment/pipeline.py
RENAMED
|
File without changes
|
{kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/catalog/enrichment/providers.py
RENAMED
|
File without changes
|
{kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/catalog/enrichment/report.py
RENAMED
|
File without changes
|
|
File without changes
|
{kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/catalog/enrichment/steps/art.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/catalog/enrichment/steps/meta.py
RENAMED
|
File without changes
|
{kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/catalog/enrichment/steps/sync.py
RENAMED
|
File without changes
|
{kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/catalog/enrichment/steps/tags.py
RENAMED
|
File without changes
|
{kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/catalog/enrichment/steps/title.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/catalog/tmdb_index/__init__.py
RENAMED
|
File without changes
|
{kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/catalog/tmdb_index/_schema.py
RENAMED
|
File without changes
|
{kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/catalog/tmdb_index/_textmatch.py
RENAMED
|
File without changes
|
{kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/catalog/tmdb_index/_ttscrape.py
RENAMED
|
File without changes
|
{kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/catalog/tmdb_index/builder.py
RENAMED
|
File without changes
|
{kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/catalog/tmdb_index/coverage.py
RENAMED
|
File without changes
|
{kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/catalog/tmdb_index/index.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/integrations/cmsutils/__init__.py
RENAMED
|
File without changes
|
{kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/integrations/cmsutils/_common.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/integrations/cmsutils/enrichtv.py
RENAMED
|
File without changes
|
{kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/integrations/cmsutils/fetchurls.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/integrations/ytpipe/__init__.py
RENAMED
|
File without changes
|
{kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/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.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/routes/admin_job_schedules.py
RENAMED
|
File without changes
|
|
File without changes
|
{kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/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
|
|
File without changes
|
{kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/static/js/admin-playlists.js
RENAMED
|
File without changes
|
|
File without changes
|
{kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/static/js/admin-queue-mgmt.js
RENAMED
|
File without changes
|
{kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/static/js/admin-schedules.js
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/templates/admin/index.html
RENAMED
|
File without changes
|
{kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/templates/admin/playlists.html
RENAMED
|
File without changes
|
{kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/templates/admin/promos.html
RENAMED
|
File without changes
|
{kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/templates/admin/queue_mgmt.html
RENAMED
|
File without changes
|
{kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/templates/admin/schedules.html
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/templates/catalog/item_detail.html
RENAMED
|
File without changes
|
|
File without changes
|
{kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/templates/feedback/index.html
RENAMED
|
File without changes
|
{kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/templates/queue/index.html
RENAMED
|
File without changes
|
|
File without changes
|
{kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/kryten_webqueue/templates/user/dashboard.html
RENAMED
|
File without changes
|
{kryten_webqueue-0.40.2 → kryten_webqueue-0.40.4}/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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|