kryten-webqueue 0.6.1__tar.gz → 0.6.2__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 (67) hide show
  1. {kryten_webqueue-0.6.1 → kryten_webqueue-0.6.2}/CHANGELOG.md +8 -0
  2. {kryten_webqueue-0.6.1 → kryten_webqueue-0.6.2}/PKG-INFO +1 -1
  3. {kryten_webqueue-0.6.1 → kryten_webqueue-0.6.2}/kryten_webqueue/queue/ordering.py +26 -5
  4. {kryten_webqueue-0.6.1 → kryten_webqueue-0.6.2}/pyproject.toml +1 -1
  5. {kryten_webqueue-0.6.1 → kryten_webqueue-0.6.2}/.github/workflows/python-publish.yml +0 -0
  6. {kryten_webqueue-0.6.1 → kryten_webqueue-0.6.2}/.github/workflows/release.yml +0 -0
  7. {kryten_webqueue-0.6.1 → kryten_webqueue-0.6.2}/.gitignore +0 -0
  8. {kryten_webqueue-0.6.1 → kryten_webqueue-0.6.2}/README.md +0 -0
  9. {kryten_webqueue-0.6.1 → kryten_webqueue-0.6.2}/config.example.json +0 -0
  10. {kryten_webqueue-0.6.1 → kryten_webqueue-0.6.2}/deploy/kryten-webqueue.service +0 -0
  11. {kryten_webqueue-0.6.1 → kryten_webqueue-0.6.2}/deploy/nginx-queue.conf +0 -0
  12. {kryten_webqueue-0.6.1 → kryten_webqueue-0.6.2}/docs/IMPLEMENTATION_SPEC.md +0 -0
  13. {kryten_webqueue-0.6.1 → kryten_webqueue-0.6.2}/docs/IMPL_API_GATE.md +0 -0
  14. {kryten_webqueue-0.6.1 → kryten_webqueue-0.6.2}/docs/IMPL_ECONOMY.md +0 -0
  15. {kryten_webqueue-0.6.1 → kryten_webqueue-0.6.2}/docs/IMPL_KRYTEN_PY.md +0 -0
  16. {kryten_webqueue-0.6.1 → kryten_webqueue-0.6.2}/docs/IMPL_ROBOT.md +0 -0
  17. {kryten_webqueue-0.6.1 → kryten_webqueue-0.6.2}/docs/PRE_PLAN_GAPS.md +0 -0
  18. {kryten_webqueue-0.6.1 → kryten_webqueue-0.6.2}/docs/PRODUCT_PLAN.md +0 -0
  19. {kryten_webqueue-0.6.1 → kryten_webqueue-0.6.2}/kryten_webqueue/__init__.py +0 -0
  20. {kryten_webqueue-0.6.1 → kryten_webqueue-0.6.2}/kryten_webqueue/__main__.py +0 -0
  21. {kryten_webqueue-0.6.1 → kryten_webqueue-0.6.2}/kryten_webqueue/api_gate/__init__.py +0 -0
  22. {kryten_webqueue-0.6.1 → kryten_webqueue-0.6.2}/kryten_webqueue/api_gate/client.py +0 -0
  23. {kryten_webqueue-0.6.1 → kryten_webqueue-0.6.2}/kryten_webqueue/app.py +0 -0
  24. {kryten_webqueue-0.6.1 → kryten_webqueue-0.6.2}/kryten_webqueue/auth/__init__.py +0 -0
  25. {kryten_webqueue-0.6.1 → kryten_webqueue-0.6.2}/kryten_webqueue/auth/otp.py +0 -0
  26. {kryten_webqueue-0.6.1 → kryten_webqueue-0.6.2}/kryten_webqueue/auth/rate_limit.py +0 -0
  27. {kryten_webqueue-0.6.1 → kryten_webqueue-0.6.2}/kryten_webqueue/auth/session.py +0 -0
  28. {kryten_webqueue-0.6.1 → kryten_webqueue-0.6.2}/kryten_webqueue/catalog/__init__.py +0 -0
  29. {kryten_webqueue-0.6.1 → kryten_webqueue-0.6.2}/kryten_webqueue/catalog/db.py +0 -0
  30. {kryten_webqueue-0.6.1 → kryten_webqueue-0.6.2}/kryten_webqueue/catalog/images.py +0 -0
  31. {kryten_webqueue-0.6.1 → kryten_webqueue-0.6.2}/kryten_webqueue/catalog/sync.py +0 -0
  32. {kryten_webqueue-0.6.1 → kryten_webqueue-0.6.2}/kryten_webqueue/config.py +0 -0
  33. {kryten_webqueue-0.6.1 → kryten_webqueue-0.6.2}/kryten_webqueue/jobs/__init__.py +0 -0
  34. {kryten_webqueue-0.6.1 → kryten_webqueue-0.6.2}/kryten_webqueue/jobs/manager.py +0 -0
  35. {kryten_webqueue-0.6.1 → kryten_webqueue-0.6.2}/kryten_webqueue/playlists/__init__.py +0 -0
  36. {kryten_webqueue-0.6.1 → kryten_webqueue-0.6.2}/kryten_webqueue/playlists/fire.py +0 -0
  37. {kryten_webqueue-0.6.1 → kryten_webqueue-0.6.2}/kryten_webqueue/playlists/importer.py +0 -0
  38. {kryten_webqueue-0.6.1 → kryten_webqueue-0.6.2}/kryten_webqueue/playlists/scheduler.py +0 -0
  39. {kryten_webqueue-0.6.1 → kryten_webqueue-0.6.2}/kryten_webqueue/queue/__init__.py +0 -0
  40. {kryten_webqueue-0.6.1 → kryten_webqueue-0.6.2}/kryten_webqueue/queue/poller.py +0 -0
  41. {kryten_webqueue-0.6.1 → kryten_webqueue-0.6.2}/kryten_webqueue/queue/shadow.py +0 -0
  42. {kryten_webqueue-0.6.1 → kryten_webqueue-0.6.2}/kryten_webqueue/routes/__init__.py +0 -0
  43. {kryten_webqueue-0.6.1 → kryten_webqueue-0.6.2}/kryten_webqueue/routes/admin_jobs.py +0 -0
  44. {kryten_webqueue-0.6.1 → kryten_webqueue-0.6.2}/kryten_webqueue/routes/admin_playlists.py +0 -0
  45. {kryten_webqueue-0.6.1 → kryten_webqueue-0.6.2}/kryten_webqueue/routes/admin_queue.py +0 -0
  46. {kryten_webqueue-0.6.1 → kryten_webqueue-0.6.2}/kryten_webqueue/routes/admin_schedules.py +0 -0
  47. {kryten_webqueue-0.6.1 → kryten_webqueue-0.6.2}/kryten_webqueue/routes/auth.py +0 -0
  48. {kryten_webqueue-0.6.1 → kryten_webqueue-0.6.2}/kryten_webqueue/routes/catalog.py +0 -0
  49. {kryten_webqueue-0.6.1 → kryten_webqueue-0.6.2}/kryten_webqueue/routes/pages.py +0 -0
  50. {kryten_webqueue-0.6.1 → kryten_webqueue-0.6.2}/kryten_webqueue/routes/queue.py +0 -0
  51. {kryten_webqueue-0.6.1 → kryten_webqueue-0.6.2}/kryten_webqueue/routes/user.py +0 -0
  52. {kryten_webqueue-0.6.1 → kryten_webqueue-0.6.2}/kryten_webqueue/static/css/main.css +0 -0
  53. {kryten_webqueue-0.6.1 → kryten_webqueue-0.6.2}/kryten_webqueue/static/js/main.js +0 -0
  54. {kryten_webqueue-0.6.1 → kryten_webqueue-0.6.2}/kryten_webqueue/templates/admin/index.html +0 -0
  55. {kryten_webqueue-0.6.1 → kryten_webqueue-0.6.2}/kryten_webqueue/templates/admin/playlists.html +0 -0
  56. {kryten_webqueue-0.6.1 → kryten_webqueue-0.6.2}/kryten_webqueue/templates/admin/queue_mgmt.html +0 -0
  57. {kryten_webqueue-0.6.1 → kryten_webqueue-0.6.2}/kryten_webqueue/templates/admin/schedules.html +0 -0
  58. {kryten_webqueue-0.6.1 → kryten_webqueue-0.6.2}/kryten_webqueue/templates/auth/login.html +0 -0
  59. {kryten_webqueue-0.6.1 → kryten_webqueue-0.6.2}/kryten_webqueue/templates/base.html +0 -0
  60. {kryten_webqueue-0.6.1 → kryten_webqueue-0.6.2}/kryten_webqueue/templates/catalog/browse.html +0 -0
  61. {kryten_webqueue-0.6.1 → kryten_webqueue-0.6.2}/kryten_webqueue/templates/catalog/item_detail.html +0 -0
  62. {kryten_webqueue-0.6.1 → kryten_webqueue-0.6.2}/kryten_webqueue/templates/catalog/item_not_found.html +0 -0
  63. {kryten_webqueue-0.6.1 → kryten_webqueue-0.6.2}/kryten_webqueue/templates/queue/index.html +0 -0
  64. {kryten_webqueue-0.6.1 → kryten_webqueue-0.6.2}/kryten_webqueue/templates/user/dashboard.html +0 -0
  65. {kryten_webqueue-0.6.1 → kryten_webqueue-0.6.2}/kryten_webqueue/ws/__init__.py +0 -0
  66. {kryten_webqueue-0.6.1 → kryten_webqueue-0.6.2}/kryten_webqueue/ws/handler.py +0 -0
  67. {kryten_webqueue-0.6.1 → kryten_webqueue-0.6.2}/kryten_webqueue/ws/manager.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.6.2] - 2026-06-07
9
+
10
+ ### Fixed
11
+
12
+ - **Queue position resolution when something is playing** — CyTube's now-playing payload (`changeMedia`) carries the media `{id, type, title, seconds}` but no playlist `uid`, so `_now_playing_uid()` always returned `None`, causing Queue / Play Next / Queue-as-Admin to fail with "Queue position unavailable (now-playing unknown)" (HTTP 400) even while a video was clearly playing. The now-playing uid is now recovered by matching the media `id`/`type` against the shadow playlist (which does carry uids). Fixes all queue insertion paths.
13
+
14
+ [0.6.2]: https://github.com/grobertson/kryten-webqueue/releases/tag/v0.6.2
15
+
8
16
  ## [0.6.1] - 2026-06-05
9
17
 
10
18
  ### Added
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kryten-webqueue
3
- Version: 0.6.1
3
+ Version: 0.6.2
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
@@ -51,7 +51,13 @@ async def _announce_queued(api_gate, shadow, *, uid: int, title: str, username:
51
51
 
52
52
 
53
53
  async def _now_playing_uid(api_gate, shadow) -> int | None:
54
- """UID of the currently-playing item, preferring fresh state over the cache."""
54
+ """UID of the currently-playing item, preferring fresh state over the cache.
55
+
56
+ CyTube's now-playing payload (``changeMedia``) carries the media
57
+ ``{id, type, title, seconds}`` but no playlist ``uid``. When the uid is
58
+ absent we recover it by matching the now-playing media id/type against the
59
+ shadow playlist (whose items do carry uids).
60
+ """
55
61
  np = None
56
62
  try:
57
63
  np = await api_gate.get_now_playing()
@@ -62,10 +68,25 @@ async def _now_playing_uid(api_gate, shadow) -> int | None:
62
68
  if not np:
63
69
  return None
64
70
  uid = np.get("uid")
65
- try:
66
- return int(uid) if uid is not None else None
67
- except (TypeError, ValueError):
68
- return None
71
+ if uid is not None:
72
+ try:
73
+ return int(uid)
74
+ except (TypeError, ValueError):
75
+ pass
76
+ # Fall back to matching the now-playing media against the shadow playlist.
77
+ np_id = np.get("id")
78
+ np_type = np.get("type")
79
+ if np_id is not None:
80
+ for it in shadow.items:
81
+ if it.get("media_id") == np_id and (
82
+ np_type is None or it.get("media_type") == np_type
83
+ ):
84
+ it_uid = it.get("uid")
85
+ try:
86
+ return int(it_uid) if it_uid is not None else None
87
+ except (TypeError, ValueError):
88
+ return None
89
+ return None
69
90
 
70
91
 
71
92
  def _shadow_index_after_uid(shadow, target_uid: int | None) -> int:
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "kryten-webqueue"
3
- version = "0.6.1"
3
+ version = "0.6.2"
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"