kryten-webqueue 0.44.3__tar.gz → 0.44.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.44.3 → kryten_webqueue-0.44.4}/CHANGELOG.md +12 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/PKG-INFO +1 -1
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/integrations/ytpipe/downloader.py +55 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/pyproject.toml +1 -1
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/.github/workflows/gitleaks.yml +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/.github/workflows/python-publish.yml +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/.github/workflows/release.yml +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/.gitignore +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/.gitleaks.toml +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/.pre-commit-config.yaml +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/AGENT-WORKFLOW-GUIDE.md +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/AGENTS.md +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/README.md +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/config.example.json +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/deploy/kryten-webqueue.service +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/deploy/nginx-queue.conf +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/docs/IMPLEMENTATION_SPEC.md +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/docs/IMPL_API_GATE.md +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/docs/IMPL_ECONOMY.md +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/docs/IMPL_KRYTEN_PY.md +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/docs/IMPL_ROBOT.md +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/docs/Kryten-Economy Service Quality Survey Report at v0.13.0.md +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/docs/Kryten-Webqueue Service Quality Survey Report at v0.27.1.md +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/docs/Log for incorrect promo insertion problem.txt +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/docs/PLAN_PRESENCE_AND_PROMOS.md +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/docs/PRD_TMDB_LOCAL_INDEX.md +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/docs/PRE_PLAN_GAPS.md +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/docs/PRODUCT_PLAN.md +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/docs/PUBLIC_API.md +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/docs/SPEC-Visual-UX-Sprint-August-2026.md +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/docs/SPEC_ADMIN_ITEM_EDITOR.md +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/docs/SPEC_CATALOG_ENRICHMENT_PIPELINE.md +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/docs/SPEC_EMOTE_REHOST.md +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/docs/SPEC_JOBS_AND_BROWSE.md +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/docs/SPEC_TMDB_LOCAL_INDEX.md +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/docs/UX_POLISH_PLAN.md +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/__init__.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/__main__.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/api_gate/__init__.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/api_gate/client.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/app.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/auth/__init__.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/auth/device_keys.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/auth/otp.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/auth/rate_limit.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/auth/session.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/catalog/__init__.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/catalog/db/__init__.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/catalog/db/_blackouts.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/catalog/db/_catalog.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/catalog/db/_connection.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/catalog/db/_devices.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/catalog/db/_enrichment.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/catalog/db/_feedback.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/catalog/db/_fetch_queue.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/catalog/db/_people.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/catalog/db/_playlists.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/catalog/db/_queue.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/catalog/db/_watchlist.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/catalog/enrichment/__init__.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/catalog/enrichment/classify.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/catalog/enrichment/normalise.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/catalog/enrichment/pipeline.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/catalog/enrichment/providers.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/catalog/enrichment/report.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/catalog/enrichment/steps/__init__.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/catalog/enrichment/steps/art.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/catalog/enrichment/steps/categories.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/catalog/enrichment/steps/identify.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/catalog/enrichment/steps/meta.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/catalog/enrichment/steps/sync.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/catalog/enrichment/steps/tags.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/catalog/enrichment/steps/title.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/catalog/images.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/catalog/mediacms.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/catalog/sync.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/catalog/tmdb_index/__init__.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/catalog/tmdb_index/_schema.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/catalog/tmdb_index/_textmatch.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/catalog/tmdb_index/_ttscrape.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/catalog/tmdb_index/builder.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/catalog/tmdb_index/coverage.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/catalog/tmdb_index/index.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/config.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/integrations/__init__.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/integrations/cmsutils/__init__.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/integrations/cmsutils/_common.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/integrations/cmsutils/blackout_scan.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/integrations/cmsutils/enrichmeta.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/integrations/cmsutils/enrichtitles.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/integrations/cmsutils/enrichtv.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/integrations/cmsutils/fetchurls.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/integrations/cmsutils/motdposters.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/integrations/cmsutils/playedmovies.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/integrations/ytpipe/__init__.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/jobs/__init__.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/jobs/fetchurls_auth.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/jobs/job_scheduler.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/jobs/log_capture.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/jobs/manager.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/jobs/rehost_emotes.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/jobs/tasks.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/logging_config.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/playlists/__init__.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/playlists/bulk_add.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/playlists/fire.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/playlists/importer.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/playlists/ordering.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/playlists/scheduler.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/promos/__init__.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/promos/director.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/queue/__init__.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/queue/completion.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/queue/ordering.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/queue/poller.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/queue/presence.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/queue/race_poller.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/queue/shadow.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/routes/__init__.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/routes/admin_catalog.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/routes/admin_feedback.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/routes/admin_job_schedules.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/routes/admin_jobs.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/routes/admin_moderation.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/routes/admin_playlists.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/routes/admin_promos.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/routes/admin_queue.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/routes/admin_schedules.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/routes/auth.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/routes/catalog.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/routes/devices.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/routes/feedback.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/routes/pages.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/routes/public_api.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/routes/queue.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/routes/user.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/static/css/main.css +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/static/js/admin-playlists.js +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/static/js/admin-promos.js +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/static/js/admin-queue-mgmt.js +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/static/js/admin-schedules.js +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/static/js/admin.js +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/static/js/keybindings.js +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/static/js/main.js +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/templates/admin/index.html +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/templates/admin/playlists.html +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/templates/admin/promos.html +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/templates/admin/queue_mgmt.html +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/templates/admin/schedules.html +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/templates/auth/login.html +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/templates/base.html +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/templates/catalog/browse.html +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/templates/catalog/edit_item_modal.html +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/templates/catalog/item_detail.html +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/templates/catalog/item_not_found.html +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/templates/feedback/index.html +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/templates/queue/index.html +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/templates/race.html +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/templates/user/dashboard.html +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/templates/user/link_device.html +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/templates/user/my_list.html +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/ws/__init__.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/ws/handler.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/ws/manager.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/scripts/AGENTS.md +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/scripts/patch_mediacms_bulk_facets.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/scripts/patch_mediacms_tags.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/scripts/trigger_enrich.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/tests/__init__.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/tests/test_catalog_blackout.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/tests/test_catalog_delete.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/tests/test_classify.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/tests/test_config_persistence.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/tests/test_device_linking.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/tests/test_feedback.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/tests/test_fetch_queue_pacing.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/tests/test_fetchurls_sharepoint.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/tests/test_identify_step.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/tests/test_job_logs_and_queue_visibility.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/tests/test_people_facets.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/tests/test_phase1.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/tests/test_phase2_jobs.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/tests/test_phase3_jobs.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/tests/test_phase4_live_fixes.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/tests/test_playlist_import.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/tests/test_presence_refund.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/tests/test_promo_director.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/tests/test_promo_pool_exclusion.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/tests/test_providers.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/tests/test_queue_announce.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/tests/test_race_poller.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/tests/test_recently_played_hide.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/tests/test_save_results_to_playlist.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/tests/test_schedule_lock.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/tests/test_search_facets.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/tests/test_title_normalization.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/tests/test_tmdb_index.py +0 -0
- {kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/tests/test_watchlist.py +0 -0
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.44.4] - 2026-08-30
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- **Pre-upload video validation.** After download and before uploading to
|
|
8
|
+
MediaCMS, the fetcher now runs `ffprobe` on the file and rejects it if it has
|
|
9
|
+
no video stream or zero duration. MediaCMS deletes any upload it can't identify
|
|
10
|
+
as video (its `media_init` removes the original when `ffprobe` fails), which
|
|
11
|
+
otherwise showed up as a successful `201` followed by a silently vanished item.
|
|
12
|
+
A bad download now fails fast with a clear reason instead. If `ffprobe` is
|
|
13
|
+
unavailable the check is skipped (non-fatal).
|
|
14
|
+
|
|
3
15
|
## [0.44.3] - 2026-08-29
|
|
4
16
|
|
|
5
17
|
### Fixed
|
{kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/integrations/ytpipe/downloader.py
RENAMED
|
@@ -22,6 +22,7 @@ import argparse
|
|
|
22
22
|
import json
|
|
23
23
|
import os
|
|
24
24
|
import re
|
|
25
|
+
import subprocess
|
|
25
26
|
import sys
|
|
26
27
|
import time
|
|
27
28
|
from pathlib import Path
|
|
@@ -3069,6 +3070,57 @@ class MediaDownloaderToMediaCMS:
|
|
|
3069
3070
|
|
|
3070
3071
|
return results
|
|
3071
3072
|
|
|
3073
|
+
def _validate_downloaded_video(self, file_path: str) -> None:
|
|
3074
|
+
"""Reject an unreadable download before uploading.
|
|
3075
|
+
|
|
3076
|
+
MediaCMS runs ffprobe on every upload and *deletes* anything it can't
|
|
3077
|
+
identify as video, so a truncated/invalid file would upload with a 201
|
|
3078
|
+
and then silently vanish. Fail here instead, with a clear reason.
|
|
3079
|
+
"""
|
|
3080
|
+
if not os.path.exists(file_path) or os.path.getsize(file_path) == 0:
|
|
3081
|
+
raise ValueError(f"downloaded file missing or empty: {file_path}")
|
|
3082
|
+
try:
|
|
3083
|
+
proc = subprocess.run(
|
|
3084
|
+
[
|
|
3085
|
+
"ffprobe",
|
|
3086
|
+
"-v",
|
|
3087
|
+
"error",
|
|
3088
|
+
"-select_streams",
|
|
3089
|
+
"v:0",
|
|
3090
|
+
"-show_entries",
|
|
3091
|
+
"stream=codec_type:format=duration",
|
|
3092
|
+
"-of",
|
|
3093
|
+
"json",
|
|
3094
|
+
file_path,
|
|
3095
|
+
],
|
|
3096
|
+
capture_output=True,
|
|
3097
|
+
text=True,
|
|
3098
|
+
timeout=120,
|
|
3099
|
+
)
|
|
3100
|
+
except (OSError, subprocess.SubprocessError) as e:
|
|
3101
|
+
# ffprobe missing/errored: don't block the upload on our own check.
|
|
3102
|
+
print(f"[WARN] skipping pre-upload validation (ffprobe unavailable): {e}")
|
|
3103
|
+
return
|
|
3104
|
+
if proc.returncode != 0:
|
|
3105
|
+
raise ValueError(
|
|
3106
|
+
f"ffprobe could not read the file: {proc.stderr.strip()[:200]}"
|
|
3107
|
+
)
|
|
3108
|
+
try:
|
|
3109
|
+
meta = json.loads(proc.stdout or "{}")
|
|
3110
|
+
except ValueError:
|
|
3111
|
+
raise ValueError("ffprobe returned unparseable output")
|
|
3112
|
+
has_video = any(
|
|
3113
|
+
s.get("codec_type") == "video" for s in meta.get("streams") or []
|
|
3114
|
+
)
|
|
3115
|
+
try:
|
|
3116
|
+
duration = float((meta.get("format") or {}).get("duration") or 0)
|
|
3117
|
+
except (TypeError, ValueError):
|
|
3118
|
+
duration = 0.0
|
|
3119
|
+
if not has_video or duration <= 0:
|
|
3120
|
+
raise ValueError(
|
|
3121
|
+
f"downloaded file is not a valid video (video_stream={has_video}, duration={duration})"
|
|
3122
|
+
)
|
|
3123
|
+
|
|
3072
3124
|
def process_video(
|
|
3073
3125
|
self,
|
|
3074
3126
|
url: str,
|
|
@@ -3132,6 +3184,9 @@ class MediaDownloaderToMediaCMS:
|
|
|
3132
3184
|
print(f"Downloaded: {file_path}")
|
|
3133
3185
|
|
|
3134
3186
|
try:
|
|
3187
|
+
# Reject unreadable downloads before upload (MediaCMS deletes files
|
|
3188
|
+
# ffprobe can't parse, which otherwise looks like a vanished upload).
|
|
3189
|
+
self._validate_downloaded_video(file_path)
|
|
3135
3190
|
# Upload to MediaCMS
|
|
3136
3191
|
if not playlist_info:
|
|
3137
3192
|
print("Uploading to MediaCMS...")
|
|
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.44.3 → kryten_webqueue-0.44.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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{kryten_webqueue-0.44.3 → kryten_webqueue-0.44.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.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/catalog/enrichment/__init__.py
RENAMED
|
File without changes
|
{kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/catalog/enrichment/classify.py
RENAMED
|
File without changes
|
{kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/catalog/enrichment/normalise.py
RENAMED
|
File without changes
|
{kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/catalog/enrichment/pipeline.py
RENAMED
|
File without changes
|
{kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/catalog/enrichment/providers.py
RENAMED
|
File without changes
|
{kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/catalog/enrichment/report.py
RENAMED
|
File without changes
|
|
File without changes
|
{kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/catalog/enrichment/steps/art.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/catalog/enrichment/steps/meta.py
RENAMED
|
File without changes
|
{kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/catalog/enrichment/steps/sync.py
RENAMED
|
File without changes
|
{kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/catalog/enrichment/steps/tags.py
RENAMED
|
File without changes
|
{kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/catalog/enrichment/steps/title.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/catalog/tmdb_index/__init__.py
RENAMED
|
File without changes
|
{kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/catalog/tmdb_index/_schema.py
RENAMED
|
File without changes
|
{kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/catalog/tmdb_index/_textmatch.py
RENAMED
|
File without changes
|
{kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/catalog/tmdb_index/_ttscrape.py
RENAMED
|
File without changes
|
{kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/catalog/tmdb_index/builder.py
RENAMED
|
File without changes
|
{kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/catalog/tmdb_index/coverage.py
RENAMED
|
File without changes
|
{kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/catalog/tmdb_index/index.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/integrations/cmsutils/__init__.py
RENAMED
|
File without changes
|
{kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/integrations/cmsutils/_common.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/integrations/cmsutils/enrichtv.py
RENAMED
|
File without changes
|
{kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/integrations/cmsutils/fetchurls.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/integrations/ytpipe/__init__.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
|
|
File without changes
|
{kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/routes/admin_job_schedules.py
RENAMED
|
File without changes
|
|
File without changes
|
{kryten_webqueue-0.44.3 → kryten_webqueue-0.44.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
|
|
File without changes
|
|
File without changes
|
{kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/static/js/admin-playlists.js
RENAMED
|
File without changes
|
|
File without changes
|
{kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/static/js/admin-queue-mgmt.js
RENAMED
|
File without changes
|
{kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/static/js/admin-schedules.js
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/templates/admin/index.html
RENAMED
|
File without changes
|
{kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/templates/admin/playlists.html
RENAMED
|
File without changes
|
{kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/templates/admin/promos.html
RENAMED
|
File without changes
|
{kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/templates/admin/queue_mgmt.html
RENAMED
|
File without changes
|
{kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/templates/admin/schedules.html
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/templates/catalog/browse.html
RENAMED
|
File without changes
|
|
File without changes
|
{kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/templates/catalog/item_detail.html
RENAMED
|
File without changes
|
|
File without changes
|
{kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/templates/feedback/index.html
RENAMED
|
File without changes
|
{kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/templates/queue/index.html
RENAMED
|
File without changes
|
|
File without changes
|
{kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/templates/user/dashboard.html
RENAMED
|
File without changes
|
{kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/kryten_webqueue/templates/user/link_device.html
RENAMED
|
File without changes
|
{kryten_webqueue-0.44.3 → kryten_webqueue-0.44.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
|
{kryten_webqueue-0.44.3 → kryten_webqueue-0.44.4}/tests/test_job_logs_and_queue_visibility.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
|