kryten-webqueue 0.35.0__tar.gz → 0.35.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (162) hide show
  1. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/CHANGELOG.md +22 -0
  2. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/PKG-INFO +1 -1
  3. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/jobs/tasks.py +58 -12
  4. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/static/css/main.css +6 -0
  5. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/static/js/admin.js +6 -4
  6. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/pyproject.toml +1 -1
  7. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/.github/workflows/gitleaks.yml +0 -0
  8. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/.github/workflows/python-publish.yml +0 -0
  9. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/.github/workflows/release.yml +0 -0
  10. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/.gitignore +0 -0
  11. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/.gitleaks.toml +0 -0
  12. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/.pre-commit-config.yaml +0 -0
  13. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/AGENT-WORKFLOW-GUIDE.md +0 -0
  14. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/README.md +0 -0
  15. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/config.example.json +0 -0
  16. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/deploy/kryten-webqueue.service +0 -0
  17. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/deploy/nginx-queue.conf +0 -0
  18. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/docs/IMPLEMENTATION_SPEC.md +0 -0
  19. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/docs/IMPL_API_GATE.md +0 -0
  20. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/docs/IMPL_ECONOMY.md +0 -0
  21. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/docs/IMPL_KRYTEN_PY.md +0 -0
  22. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/docs/IMPL_ROBOT.md +0 -0
  23. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/docs/Kryten-Economy Service Quality Survey Report at v0.13.0.md +0 -0
  24. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/docs/Kryten-Webqueue Service Quality Survey Report at v0.27.1.md +0 -0
  25. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/docs/Log for incorrect promo insertion problem.txt +0 -0
  26. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/docs/PLAN_PRESENCE_AND_PROMOS.md +0 -0
  27. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/docs/PRE_PLAN_GAPS.md +0 -0
  28. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/docs/PRODUCT_PLAN.md +0 -0
  29. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/docs/SPEC_CATALOG_ENRICHMENT_PIPELINE.md +0 -0
  30. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/docs/SPEC_EMOTE_REHOST.md +0 -0
  31. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/docs/SPEC_JOBS_AND_BROWSE.md +0 -0
  32. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/docs/UX_POLISH_PLAN.md +0 -0
  33. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/__init__.py +0 -0
  34. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/__main__.py +0 -0
  35. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/api_gate/__init__.py +0 -0
  36. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/api_gate/client.py +0 -0
  37. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/app.py +0 -0
  38. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/auth/__init__.py +0 -0
  39. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/auth/otp.py +0 -0
  40. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/auth/rate_limit.py +0 -0
  41. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/auth/session.py +0 -0
  42. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/catalog/__init__.py +0 -0
  43. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/catalog/db/__init__.py +0 -0
  44. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/catalog/db/_catalog.py +0 -0
  45. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/catalog/db/_connection.py +0 -0
  46. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/catalog/db/_enrichment.py +0 -0
  47. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/catalog/db/_feedback.py +0 -0
  48. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/catalog/db/_people.py +0 -0
  49. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/catalog/db/_playlists.py +0 -0
  50. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/catalog/db/_queue.py +0 -0
  51. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/catalog/db/_watchlist.py +0 -0
  52. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/catalog/enrichment/__init__.py +0 -0
  53. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/catalog/enrichment/classify.py +0 -0
  54. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/catalog/enrichment/normalise.py +0 -0
  55. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/catalog/enrichment/pipeline.py +0 -0
  56. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/catalog/enrichment/providers.py +0 -0
  57. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/catalog/enrichment/report.py +0 -0
  58. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/catalog/enrichment/steps/__init__.py +0 -0
  59. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/catalog/enrichment/steps/art.py +0 -0
  60. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/catalog/enrichment/steps/categories.py +0 -0
  61. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/catalog/enrichment/steps/meta.py +0 -0
  62. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/catalog/enrichment/steps/sync.py +0 -0
  63. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/catalog/enrichment/steps/tags.py +0 -0
  64. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/catalog/enrichment/steps/title.py +0 -0
  65. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/catalog/images.py +0 -0
  66. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/catalog/mediacms.py +0 -0
  67. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/catalog/sync.py +0 -0
  68. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/config.py +0 -0
  69. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/integrations/__init__.py +0 -0
  70. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/integrations/cmsutils/__init__.py +0 -0
  71. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/integrations/cmsutils/_common.py +0 -0
  72. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/integrations/cmsutils/enrichmeta.py +0 -0
  73. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/integrations/cmsutils/enrichtitles.py +0 -0
  74. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/integrations/cmsutils/enrichtv.py +0 -0
  75. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/integrations/cmsutils/fetchurls.py +0 -0
  76. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/integrations/cmsutils/motdposters.py +0 -0
  77. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/integrations/cmsutils/playedmovies.py +0 -0
  78. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/integrations/ytpipe/__init__.py +0 -0
  79. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/integrations/ytpipe/downloader.py +0 -0
  80. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/jobs/__init__.py +0 -0
  81. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/jobs/fetchurls_auth.py +0 -0
  82. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/jobs/job_scheduler.py +0 -0
  83. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/jobs/manager.py +0 -0
  84. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/jobs/rehost_emotes.py +0 -0
  85. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/logging_config.py +0 -0
  86. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/playlists/__init__.py +0 -0
  87. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/playlists/bulk_add.py +0 -0
  88. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/playlists/fire.py +0 -0
  89. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/playlists/importer.py +0 -0
  90. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/playlists/ordering.py +0 -0
  91. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/playlists/scheduler.py +0 -0
  92. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/promos/__init__.py +0 -0
  93. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/promos/director.py +0 -0
  94. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/queue/__init__.py +0 -0
  95. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/queue/completion.py +0 -0
  96. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/queue/ordering.py +0 -0
  97. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/queue/poller.py +0 -0
  98. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/queue/presence.py +0 -0
  99. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/queue/race_poller.py +0 -0
  100. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/queue/shadow.py +0 -0
  101. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/routes/__init__.py +0 -0
  102. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/routes/admin_catalog.py +0 -0
  103. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/routes/admin_feedback.py +0 -0
  104. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/routes/admin_job_schedules.py +0 -0
  105. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/routes/admin_jobs.py +0 -0
  106. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/routes/admin_moderation.py +0 -0
  107. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/routes/admin_playlists.py +0 -0
  108. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/routes/admin_promos.py +0 -0
  109. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/routes/admin_queue.py +0 -0
  110. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/routes/admin_schedules.py +0 -0
  111. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/routes/auth.py +0 -0
  112. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/routes/catalog.py +0 -0
  113. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/routes/feedback.py +0 -0
  114. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/routes/pages.py +0 -0
  115. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/routes/queue.py +0 -0
  116. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/routes/user.py +0 -0
  117. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/static/js/admin-playlists.js +0 -0
  118. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/static/js/admin-promos.js +0 -0
  119. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/static/js/admin-queue-mgmt.js +0 -0
  120. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/static/js/admin-schedules.js +0 -0
  121. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/static/js/main.js +0 -0
  122. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/templates/admin/index.html +0 -0
  123. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/templates/admin/playlists.html +0 -0
  124. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/templates/admin/promos.html +0 -0
  125. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/templates/admin/queue_mgmt.html +0 -0
  126. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/templates/admin/schedules.html +0 -0
  127. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/templates/auth/login.html +0 -0
  128. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/templates/base.html +0 -0
  129. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/templates/catalog/browse.html +0 -0
  130. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/templates/catalog/item_detail.html +0 -0
  131. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/templates/catalog/item_not_found.html +0 -0
  132. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/templates/feedback/index.html +0 -0
  133. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/templates/queue/index.html +0 -0
  134. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/templates/race.html +0 -0
  135. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/templates/user/dashboard.html +0 -0
  136. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/templates/user/my_list.html +0 -0
  137. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/ws/__init__.py +0 -0
  138. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/ws/handler.py +0 -0
  139. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/kryten_webqueue/ws/manager.py +0 -0
  140. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/tests/__init__.py +0 -0
  141. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/tests/test_classify.py +0 -0
  142. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/tests/test_config_persistence.py +0 -0
  143. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/tests/test_feedback.py +0 -0
  144. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/tests/test_fetchurls_sharepoint.py +0 -0
  145. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/tests/test_people_facets.py +0 -0
  146. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/tests/test_phase1.py +0 -0
  147. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/tests/test_phase2_jobs.py +0 -0
  148. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/tests/test_phase3_jobs.py +0 -0
  149. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/tests/test_phase4_live_fixes.py +0 -0
  150. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/tests/test_playlist_import.py +0 -0
  151. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/tests/test_presence_refund.py +0 -0
  152. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/tests/test_promo_director.py +0 -0
  153. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/tests/test_promo_pool_exclusion.py +0 -0
  154. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/tests/test_providers.py +0 -0
  155. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/tests/test_queue_announce.py +0 -0
  156. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/tests/test_race_poller.py +0 -0
  157. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/tests/test_recently_played_hide.py +0 -0
  158. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/tests/test_save_results_to_playlist.py +0 -0
  159. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/tests/test_schedule_lock.py +0 -0
  160. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/tests/test_search_facets.py +0 -0
  161. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/tests/test_title_normalization.py +0 -0
  162. {kryten_webqueue-0.35.0 → kryten_webqueue-0.35.1}/tests/test_watchlist.py +0 -0
@@ -2,6 +2,28 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [0.35.1] - 2026-08-13
6
+
7
+ ### Fixed
8
+
9
+ - **Catalog Enrich job UX.** The `catalog_enrich` admin job modal was
10
+ unusable — raw comma-separated step names, unexplained "tokens" field.
11
+
12
+ - **Steps** is now a dropdown of labelled presets (e.g. *"Full pipeline",
13
+ "Enrichment only", "Art only", "Title cleanup only"*) rather than a
14
+ free-text field requiring knowledge of internal step names.
15
+ - **Specific items** replaces the opaque "Tokens" label. Placeholder text
16
+ and help text explain that these are the short MediaCMS media IDs visible
17
+ in item URLs, and that leaving it blank processes the whole catalog.
18
+ - **All fields** now show help text beneath them (Force re-run, Dry run,
19
+ Item limit, Description quality threshold are all explained).
20
+ - Help text rendering added to `_jobFieldHtml` in `admin.js` — all jobs
21
+ that define a `help` key on their schema fields now display it. A
22
+ `placeholder` key is also honoured on text/number inputs.
23
+ - `.field-help` CSS class added for the muted hint lines.
24
+ - Token parsing accepts comma- or space-separated IDs and ignores `"all"`
25
+ for the default blank case.
26
+
5
27
  ## [0.35.0] - 2026-08-13
6
28
 
7
29
  ### Added
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: kryten-webqueue
3
- Version: 0.35.0
3
+ Version: 0.35.1
4
4
  Summary: Netflix/Tubi-style catalog browser and pay-to-play queue management for CyTube
5
5
  Author: grobertson
6
6
  License-Expression: MIT
@@ -104,9 +104,11 @@ async def catalog_enrich_job(params: dict, ctx) -> dict:
104
104
  )
105
105
  step_param = params.get("steps", "all")
106
106
  steps = None if step_param == "all" else [s.strip() for s in step_param.split(",")]
107
- token_param = params.get("tokens", "all")
107
+ token_param = (params.get("tokens") or "").strip()
108
108
  tokens = (
109
- None if token_param == "all" else [t.strip() for t in token_param.split(",")]
109
+ None
110
+ if not token_param or token_param == "all"
111
+ else [t.strip() for t in token_param.replace(",", " ").split() if t.strip()]
110
112
  )
111
113
 
112
114
  report = await pipeline.run(
@@ -124,19 +126,55 @@ async def catalog_enrich_job(params: dict, ctx) -> dict:
124
126
  CATALOG_ENRICH_SCHEMA = [
125
127
  {
126
128
  "name": "steps",
127
- "label": "Steps",
128
- "type": "string",
129
+ "label": "Pipeline steps",
130
+ "type": "enum",
129
131
  "default": "all",
130
132
  "required": False,
131
- "help": "Comma-separated: sync,classify,title,meta,art,tags,categories — or 'all'",
133
+ "options": [
134
+ {
135
+ "value": "all",
136
+ "label": "Full pipeline — sync → classify → title → meta → art → tags",
137
+ },
138
+ {
139
+ "value": "classify,meta,art,tags",
140
+ "label": "Enrichment only — classify, fetch metadata, art, and tags (no sync)",
141
+ },
142
+ {"value": "art", "label": "Art only — (re-)fetch poster art"},
143
+ {
144
+ "value": "classify,art",
145
+ "label": "Classify + art — re-detect content type then fetch art",
146
+ },
147
+ {
148
+ "value": "classify,meta",
149
+ "label": "Classify + metadata — descriptions and credits only",
150
+ },
151
+ {
152
+ "value": "tags",
153
+ "label": "Tags only — push genres/MPAA/hosted-show tags to CMS",
154
+ },
155
+ {
156
+ "value": "title",
157
+ "label": "Title cleanup only — normalise and push corrected titles",
158
+ },
159
+ {"value": "sync", "label": "Sync only — pull latest items from MediaCMS"},
160
+ {
161
+ "value": "classify",
162
+ "label": "Classify only — detect hosted shows, TV episodes, etc.",
163
+ },
164
+ ],
165
+ "help": "Choose which parts of the pipeline to run. 'Full pipeline' is the normal nightly run.",
132
166
  },
133
167
  {
134
168
  "name": "tokens",
135
- "label": "Tokens",
169
+ "label": "Specific items (optional)",
136
170
  "type": "string",
137
- "default": "all",
171
+ "default": None,
138
172
  "required": False,
139
- "help": "Comma-separated friendly_tokens to process, or 'all'",
173
+ "placeholder": "Leave blank for entire catalog",
174
+ "help": (
175
+ "Paste one or more MediaCMS media IDs (the short alphanumeric codes in item URLs, "
176
+ "e.g. AbCd1234) separated by commas or spaces. Leave blank to process the entire catalog."
177
+ ),
140
178
  },
141
179
  {
142
180
  "name": "force",
@@ -144,28 +182,36 @@ CATALOG_ENRICH_SCHEMA = [
144
182
  "type": "bool",
145
183
  "default": False,
146
184
  "required": False,
185
+ "help": "Re-process items even if they were enriched before. Useful after fixing a bug or adding a new hosted-show pattern.",
147
186
  },
148
187
  {
149
188
  "name": "dry_run",
150
- "label": "Dry run",
189
+ "label": "Dry run (preview only)",
151
190
  "type": "bool",
152
191
  "default": False,
153
192
  "required": False,
193
+ "help": "Walk through the pipeline and log what would change, but write nothing to the database or CMS.",
154
194
  },
155
195
  {
156
196
  "name": "limit",
157
- "label": "Limit",
197
+ "label": "Item limit per step",
158
198
  "type": "int",
159
199
  "default": None,
160
200
  "required": False,
161
- "help": "Max items per step (leave blank for all)",
201
+ "placeholder": "blank = no limit",
202
+ "help": "Stop after processing this many items per step. Handy for a quick test run before committing to the full catalog.",
162
203
  },
163
204
  {
164
205
  "name": "min_score",
165
- "label": "Min description score",
206
+ "label": "Description quality threshold",
166
207
  "type": "int",
167
208
  "default": 50,
168
209
  "required": False,
210
+ "help": (
211
+ "Skip the metadata step for items whose description already scores at or above this value "
212
+ "(0–130 scale; a fully-enriched description scores ~100). Lower this or use Force re-run "
213
+ "to refresh already-enriched items."
214
+ ),
169
215
  },
170
216
  ]
171
217
 
@@ -1506,6 +1506,12 @@ a.np-chip {
1506
1506
  font: inherit;
1507
1507
  width: 100%;
1508
1508
  }
1509
+ .field-help {
1510
+ font-size: 0.74rem;
1511
+ color: var(--text-secondary);
1512
+ opacity: 0.8;
1513
+ line-height: 1.4;
1514
+ }
1509
1515
  .check {
1510
1516
  display: flex;
1511
1517
  align-items: center;
@@ -49,11 +49,12 @@ function _jobFieldHtml(f, prefix = 'jobparam-') {
49
49
  const id = `${prefix}${f.name}`;
50
50
  const label = escapeHtml(f.label || f.name);
51
51
  const def = f.default;
52
+ const helpHtml = f.help ? `<span class="field-help">${escapeHtml(f.help)}</span>` : '';
52
53
  if (f.type === 'bool') {
53
54
  return `<label class="field field-inline">
54
55
  <input type="checkbox" id="${id}" ${def ? 'checked' : ''}>
55
56
  <span>${label}</span>
56
- </label>`;
57
+ </label>${helpHtml ? `<div style="margin:-0.5rem 0 0.85rem 0">${helpHtml}</div>` : ''}`;
57
58
  }
58
59
  if (f.type === 'enum') {
59
60
  const opts = (f.options || []).map(o => {
@@ -63,17 +64,18 @@ function _jobFieldHtml(f, prefix = 'jobparam-') {
63
64
  return `<option value="${escapeHtml(String(val))}" ${sel}>${escapeHtml(String(txt))}</option>`;
64
65
  }).join('');
65
66
  return `<label class="field"><span>${label}</span>
66
- <select id="${id}">${opts}</select></label>`;
67
+ <select id="${id}">${opts}</select>${helpHtml}</label>`;
67
68
  }
68
69
  if (f.type === 'playlist') {
69
70
  return `<label class="field"><span>${label}</span>
70
- <select id="${id}" data-playlist-picker="1"><option value="">—</option></select></label>`;
71
+ <select id="${id}" data-playlist-picker="1"><option value="">—</option></select>${helpHtml}</label>`;
71
72
  }
72
73
  const inputType = (f.type === 'int' || f.type === 'float') ? 'number' : 'text';
73
74
  const step = f.type === 'float' ? ' step="any"' : '';
74
75
  const val = (def === null || def === undefined) ? '' : escapeHtml(String(def));
76
+ const placeholder = f.placeholder ? ` placeholder="${escapeHtml(f.placeholder)}"` : '';
75
77
  return `<label class="field"><span>${label}${f.required ? ' *' : ''}</span>
76
- <input type="${inputType}"${step} id="${id}" value="${val}"></label>`;
78
+ <input type="${inputType}"${step}${placeholder} id="${id}" value="${val}">${helpHtml}</label>`;
77
79
  }
78
80
 
79
81
  async function openJobRunnerModal(job) {
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "kryten-webqueue"
3
- version = "0.35.0"
3
+ version = "0.35.1"
4
4
  description = "Netflix/Tubi-style catalog browser and pay-to-play queue management for CyTube"
5
5
  readme = "README.md"
6
6
  license = "MIT"