kryten-webqueue 0.30.0__tar.gz → 0.31.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.
Files changed (127) hide show
  1. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/CHANGELOG.md +8 -0
  2. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/PKG-INFO +1 -1
  3. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/static/js/admin.js +6 -1
  4. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/pyproject.toml +1 -1
  5. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/.github/workflows/python-publish.yml +0 -0
  6. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/.github/workflows/release.yml +0 -0
  7. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/.gitignore +0 -0
  8. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/README.md +0 -0
  9. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/config.example.json +0 -0
  10. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/deploy/kryten-webqueue.service +0 -0
  11. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/deploy/nginx-queue.conf +0 -0
  12. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/docs/IMPLEMENTATION_SPEC.md +0 -0
  13. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/docs/IMPL_API_GATE.md +0 -0
  14. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/docs/IMPL_ECONOMY.md +0 -0
  15. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/docs/IMPL_KRYTEN_PY.md +0 -0
  16. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/docs/IMPL_ROBOT.md +0 -0
  17. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/docs/Kryten-Economy Service Quality Survey Report at v0.13.0.md +0 -0
  18. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/docs/Kryten-Webqueue Service Quality Survey Report at v0.27.1.md +0 -0
  19. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/docs/Log for incorrect promo insertion problem.txt +0 -0
  20. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/docs/PLAN_PRESENCE_AND_PROMOS.md +0 -0
  21. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/docs/PRE_PLAN_GAPS.md +0 -0
  22. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/docs/PRODUCT_PLAN.md +0 -0
  23. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/docs/SPEC_JOBS_AND_BROWSE.md +0 -0
  24. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/docs/UX_POLISH_PLAN.md +0 -0
  25. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/__init__.py +0 -0
  26. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/__main__.py +0 -0
  27. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/api_gate/__init__.py +0 -0
  28. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/api_gate/client.py +0 -0
  29. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/app.py +0 -0
  30. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/auth/__init__.py +0 -0
  31. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/auth/otp.py +0 -0
  32. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/auth/rate_limit.py +0 -0
  33. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/auth/session.py +0 -0
  34. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/catalog/__init__.py +0 -0
  35. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/catalog/db/__init__.py +0 -0
  36. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/catalog/db/_catalog.py +0 -0
  37. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/catalog/db/_connection.py +0 -0
  38. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/catalog/db/_feedback.py +0 -0
  39. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/catalog/db/_playlists.py +0 -0
  40. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/catalog/db/_queue.py +0 -0
  41. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/catalog/images.py +0 -0
  42. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/catalog/mediacms.py +0 -0
  43. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/catalog/sync.py +0 -0
  44. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/config.py +0 -0
  45. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/integrations/__init__.py +0 -0
  46. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/integrations/cmsutils/__init__.py +0 -0
  47. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/integrations/cmsutils/_common.py +0 -0
  48. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/integrations/cmsutils/enrichmeta.py +0 -0
  49. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/integrations/cmsutils/enrichtitles.py +0 -0
  50. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/integrations/cmsutils/enrichtv.py +0 -0
  51. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/integrations/cmsutils/fetchurls.py +0 -0
  52. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/integrations/ytpipe/__init__.py +0 -0
  53. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/integrations/ytpipe/downloader.py +0 -0
  54. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/jobs/__init__.py +0 -0
  55. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/jobs/fetchurls_auth.py +0 -0
  56. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/jobs/manager.py +0 -0
  57. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/jobs/tasks.py +0 -0
  58. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/logging_config.py +0 -0
  59. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/playlists/__init__.py +0 -0
  60. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/playlists/bulk_add.py +0 -0
  61. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/playlists/fire.py +0 -0
  62. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/playlists/importer.py +0 -0
  63. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/playlists/ordering.py +0 -0
  64. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/playlists/scheduler.py +0 -0
  65. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/promos/__init__.py +0 -0
  66. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/promos/director.py +0 -0
  67. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/queue/__init__.py +0 -0
  68. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/queue/ordering.py +0 -0
  69. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/queue/poller.py +0 -0
  70. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/queue/presence.py +0 -0
  71. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/queue/race_poller.py +0 -0
  72. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/queue/shadow.py +0 -0
  73. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/routes/__init__.py +0 -0
  74. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/routes/admin_catalog.py +0 -0
  75. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/routes/admin_feedback.py +0 -0
  76. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/routes/admin_jobs.py +0 -0
  77. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/routes/admin_moderation.py +0 -0
  78. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/routes/admin_playlists.py +0 -0
  79. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/routes/admin_promos.py +0 -0
  80. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/routes/admin_queue.py +0 -0
  81. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/routes/admin_schedules.py +0 -0
  82. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/routes/auth.py +0 -0
  83. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/routes/catalog.py +0 -0
  84. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/routes/feedback.py +0 -0
  85. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/routes/pages.py +0 -0
  86. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/routes/queue.py +0 -0
  87. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/routes/user.py +0 -0
  88. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/static/css/main.css +0 -0
  89. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/static/js/admin-playlists.js +0 -0
  90. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/static/js/admin-promos.js +0 -0
  91. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/static/js/admin-queue-mgmt.js +0 -0
  92. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/static/js/admin-schedules.js +0 -0
  93. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/static/js/main.js +0 -0
  94. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/templates/admin/index.html +0 -0
  95. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/templates/admin/playlists.html +0 -0
  96. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/templates/admin/promos.html +0 -0
  97. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/templates/admin/queue_mgmt.html +0 -0
  98. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/templates/admin/schedules.html +0 -0
  99. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/templates/auth/login.html +0 -0
  100. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/templates/base.html +0 -0
  101. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/templates/catalog/browse.html +0 -0
  102. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/templates/catalog/item_detail.html +0 -0
  103. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/templates/catalog/item_not_found.html +0 -0
  104. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/templates/feedback/index.html +0 -0
  105. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/templates/queue/index.html +0 -0
  106. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/templates/race.html +0 -0
  107. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/templates/user/dashboard.html +0 -0
  108. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/ws/__init__.py +0 -0
  109. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/ws/handler.py +0 -0
  110. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/kryten_webqueue/ws/manager.py +0 -0
  111. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/tests/__init__.py +0 -0
  112. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/tests/test_config_persistence.py +0 -0
  113. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/tests/test_feedback.py +0 -0
  114. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/tests/test_fetchurls_sharepoint.py +0 -0
  115. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/tests/test_phase1.py +0 -0
  116. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/tests/test_phase2_jobs.py +0 -0
  117. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/tests/test_phase3_jobs.py +0 -0
  118. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/tests/test_phase4_live_fixes.py +0 -0
  119. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/tests/test_playlist_import.py +0 -0
  120. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/tests/test_presence_refund.py +0 -0
  121. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/tests/test_promo_director.py +0 -0
  122. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/tests/test_promo_pool_exclusion.py +0 -0
  123. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/tests/test_queue_announce.py +0 -0
  124. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/tests/test_race_poller.py +0 -0
  125. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/tests/test_save_results_to_playlist.py +0 -0
  126. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/tests/test_schedule_lock.py +0 -0
  127. {kryten_webqueue-0.30.0 → kryten_webqueue-0.31.0}/tests/test_search_facets.py +0 -0
@@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.31.0] — 2026-07-04
9
+
10
+ ### Fixed
11
+
12
+ - **Moderation list "Remove" button now works.** The button was rendered with `onclick="removeModEntry(${JSON.stringify(e.username)})"` — `JSON.stringify` wraps the value in double quotes that immediately terminate the `onclick="…"` attribute, so browsers reported *"unexpected end of input at admin:1:16"* and the function was never called. The button now uses a `data-mod-rm-username` attribute with a delegated `click` listener on the stable `#mod-entries-list` container, consistent with how the "Moderate…" buttons in the Recent Users table work. The existing `confirm()` dialog inside `removeModEntry` is unaffected and will now prompt as intended.
13
+
14
+ [0.31.0]: https://github.com/grobertson/kryten-webqueue/releases/tag/v0.31.0
15
+
8
16
  ## [0.30.0] — 2026-07-04
9
17
 
10
18
  ### Fixed
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kryten-webqueue
3
- Version: 0.30.0
3
+ Version: 0.31.0
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
@@ -527,7 +527,7 @@ function renderModEntries(el, entries) {
527
527
  <td>${escapeHtml(e.reason || '—')}</td>
528
528
  <td>${escapeHtml(e.moderator || '—')}</td>
529
529
  <td>${e.added_at ? formatLocalDateTime(e.added_at) : '—'}</td>
530
- <td><button class="btn btn-sm btn-danger" onclick="removeModEntry(${JSON.stringify(e.username)})">Remove</button></td>
530
+ <td><button class="btn btn-sm btn-danger" data-mod-rm-username="${escapeHtml(e.username)}">Remove</button></td>
531
531
  </tr>`).join('')}
532
532
  </table>`;
533
533
  }
@@ -561,6 +561,11 @@ async function submitAddModEntry() {
561
561
  }
562
562
 
563
563
  document.getElementById('mod-entries-refresh').addEventListener('click', loadModEntries);
564
+
565
+ document.getElementById('mod-entries-list').addEventListener('click', (e) => {
566
+ const btn = e.target.closest('[data-mod-rm-username]');
567
+ if (btn) removeModEntry(btn.dataset.modRmUsername);
568
+ });
564
569
  document.querySelectorAll('.mod-filter-btn').forEach(btn => {
565
570
  btn.addEventListener('click', () => {
566
571
  document.querySelectorAll('.mod-filter-btn').forEach(b => b.classList.remove('active'));
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "kryten-webqueue"
3
- version = "0.30.0"
3
+ version = "0.31.0"
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"