kryten-webqueue 0.1.2__tar.gz → 0.1.6__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 (58) hide show
  1. {kryten_webqueue-0.1.2 → kryten_webqueue-0.1.6}/.github/workflows/release.yml +0 -22
  2. {kryten_webqueue-0.1.2 → kryten_webqueue-0.1.6}/PKG-INFO +1 -1
  3. {kryten_webqueue-0.1.2 → kryten_webqueue-0.1.6}/kryten_webqueue/queue/shadow.py +21 -3
  4. {kryten_webqueue-0.1.2 → kryten_webqueue-0.1.6}/pyproject.toml +1 -1
  5. {kryten_webqueue-0.1.2 → kryten_webqueue-0.1.6}/.github/workflows/python-publish.yml +0 -0
  6. {kryten_webqueue-0.1.2 → kryten_webqueue-0.1.6}/.gitignore +0 -0
  7. {kryten_webqueue-0.1.2 → kryten_webqueue-0.1.6}/README.md +0 -0
  8. {kryten_webqueue-0.1.2 → kryten_webqueue-0.1.6}/config.example.json +0 -0
  9. {kryten_webqueue-0.1.2 → kryten_webqueue-0.1.6}/deploy/kryten-webqueue.service +0 -0
  10. {kryten_webqueue-0.1.2 → kryten_webqueue-0.1.6}/deploy/nginx-queue.conf +0 -0
  11. {kryten_webqueue-0.1.2 → kryten_webqueue-0.1.6}/docs/IMPLEMENTATION_SPEC.md +0 -0
  12. {kryten_webqueue-0.1.2 → kryten_webqueue-0.1.6}/docs/IMPL_API_GATE.md +0 -0
  13. {kryten_webqueue-0.1.2 → kryten_webqueue-0.1.6}/docs/IMPL_ECONOMY.md +0 -0
  14. {kryten_webqueue-0.1.2 → kryten_webqueue-0.1.6}/docs/IMPL_KRYTEN_PY.md +0 -0
  15. {kryten_webqueue-0.1.2 → kryten_webqueue-0.1.6}/docs/IMPL_ROBOT.md +0 -0
  16. {kryten_webqueue-0.1.2 → kryten_webqueue-0.1.6}/docs/PRE_PLAN_GAPS.md +0 -0
  17. {kryten_webqueue-0.1.2 → kryten_webqueue-0.1.6}/docs/PRODUCT_PLAN.md +0 -0
  18. {kryten_webqueue-0.1.2 → kryten_webqueue-0.1.6}/kryten_webqueue/__init__.py +0 -0
  19. {kryten_webqueue-0.1.2 → kryten_webqueue-0.1.6}/kryten_webqueue/__main__.py +0 -0
  20. {kryten_webqueue-0.1.2 → kryten_webqueue-0.1.6}/kryten_webqueue/api_gate/__init__.py +0 -0
  21. {kryten_webqueue-0.1.2 → kryten_webqueue-0.1.6}/kryten_webqueue/api_gate/client.py +0 -0
  22. {kryten_webqueue-0.1.2 → kryten_webqueue-0.1.6}/kryten_webqueue/app.py +0 -0
  23. {kryten_webqueue-0.1.2 → kryten_webqueue-0.1.6}/kryten_webqueue/auth/__init__.py +0 -0
  24. {kryten_webqueue-0.1.2 → kryten_webqueue-0.1.6}/kryten_webqueue/auth/otp.py +0 -0
  25. {kryten_webqueue-0.1.2 → kryten_webqueue-0.1.6}/kryten_webqueue/auth/rate_limit.py +0 -0
  26. {kryten_webqueue-0.1.2 → kryten_webqueue-0.1.6}/kryten_webqueue/auth/session.py +0 -0
  27. {kryten_webqueue-0.1.2 → kryten_webqueue-0.1.6}/kryten_webqueue/catalog/__init__.py +0 -0
  28. {kryten_webqueue-0.1.2 → kryten_webqueue-0.1.6}/kryten_webqueue/catalog/db.py +0 -0
  29. {kryten_webqueue-0.1.2 → kryten_webqueue-0.1.6}/kryten_webqueue/catalog/images.py +0 -0
  30. {kryten_webqueue-0.1.2 → kryten_webqueue-0.1.6}/kryten_webqueue/catalog/sync.py +0 -0
  31. {kryten_webqueue-0.1.2 → kryten_webqueue-0.1.6}/kryten_webqueue/config.py +0 -0
  32. {kryten_webqueue-0.1.2 → kryten_webqueue-0.1.6}/kryten_webqueue/playlists/__init__.py +0 -0
  33. {kryten_webqueue-0.1.2 → kryten_webqueue-0.1.6}/kryten_webqueue/playlists/fire.py +0 -0
  34. {kryten_webqueue-0.1.2 → kryten_webqueue-0.1.6}/kryten_webqueue/playlists/importer.py +0 -0
  35. {kryten_webqueue-0.1.2 → kryten_webqueue-0.1.6}/kryten_webqueue/playlists/scheduler.py +0 -0
  36. {kryten_webqueue-0.1.2 → kryten_webqueue-0.1.6}/kryten_webqueue/queue/__init__.py +0 -0
  37. {kryten_webqueue-0.1.2 → kryten_webqueue-0.1.6}/kryten_webqueue/queue/ordering.py +0 -0
  38. {kryten_webqueue-0.1.2 → kryten_webqueue-0.1.6}/kryten_webqueue/queue/poller.py +0 -0
  39. {kryten_webqueue-0.1.2 → kryten_webqueue-0.1.6}/kryten_webqueue/routes/__init__.py +0 -0
  40. {kryten_webqueue-0.1.2 → kryten_webqueue-0.1.6}/kryten_webqueue/routes/admin_playlists.py +0 -0
  41. {kryten_webqueue-0.1.2 → kryten_webqueue-0.1.6}/kryten_webqueue/routes/admin_queue.py +0 -0
  42. {kryten_webqueue-0.1.2 → kryten_webqueue-0.1.6}/kryten_webqueue/routes/admin_schedules.py +0 -0
  43. {kryten_webqueue-0.1.2 → kryten_webqueue-0.1.6}/kryten_webqueue/routes/auth.py +0 -0
  44. {kryten_webqueue-0.1.2 → kryten_webqueue-0.1.6}/kryten_webqueue/routes/catalog.py +0 -0
  45. {kryten_webqueue-0.1.2 → kryten_webqueue-0.1.6}/kryten_webqueue/routes/pages.py +0 -0
  46. {kryten_webqueue-0.1.2 → kryten_webqueue-0.1.6}/kryten_webqueue/routes/queue.py +0 -0
  47. {kryten_webqueue-0.1.2 → kryten_webqueue-0.1.6}/kryten_webqueue/routes/user.py +0 -0
  48. {kryten_webqueue-0.1.2 → kryten_webqueue-0.1.6}/kryten_webqueue/static/css/main.css +0 -0
  49. {kryten_webqueue-0.1.2 → kryten_webqueue-0.1.6}/kryten_webqueue/static/js/main.js +0 -0
  50. {kryten_webqueue-0.1.2 → kryten_webqueue-0.1.6}/kryten_webqueue/templates/admin/index.html +0 -0
  51. {kryten_webqueue-0.1.2 → kryten_webqueue-0.1.6}/kryten_webqueue/templates/auth/login.html +0 -0
  52. {kryten_webqueue-0.1.2 → kryten_webqueue-0.1.6}/kryten_webqueue/templates/base.html +0 -0
  53. {kryten_webqueue-0.1.2 → kryten_webqueue-0.1.6}/kryten_webqueue/templates/catalog/browse.html +0 -0
  54. {kryten_webqueue-0.1.2 → kryten_webqueue-0.1.6}/kryten_webqueue/templates/queue/index.html +0 -0
  55. {kryten_webqueue-0.1.2 → kryten_webqueue-0.1.6}/kryten_webqueue/templates/user/dashboard.html +0 -0
  56. {kryten_webqueue-0.1.2 → kryten_webqueue-0.1.6}/kryten_webqueue/ws/__init__.py +0 -0
  57. {kryten_webqueue-0.1.2 → kryten_webqueue-0.1.6}/kryten_webqueue/ws/handler.py +0 -0
  58. {kryten_webqueue-0.1.2 → kryten_webqueue-0.1.6}/kryten_webqueue/ws/manager.py +0 -0
@@ -101,25 +101,3 @@ jobs:
101
101
  permissions:
102
102
  id-token: write
103
103
  contents: read
104
-
105
- notify-release:
106
- name: Notify Release Created
107
- runs-on: ubuntu-latest
108
- needs: [create-release, publish-to-pypi]
109
-
110
- steps:
111
- - uses: actions/checkout@v4
112
-
113
- - name: Read version from pyproject.toml
114
- id: version
115
- run: |
116
- VERSION=$(grep -m1 'version = "' pyproject.toml | cut -d '"' -f 2)
117
- echo "version=$VERSION" >> $GITHUB_OUTPUT
118
- echo "tag=v$VERSION" >> $GITHUB_OUTPUT
119
-
120
- - name: Send notification
121
- run: |
122
- echo "📢 Release notification"
123
- echo "Version: ${{ steps.version.outputs.tag }}"
124
- echo "Repository: ${{ github.repository }}"
125
- echo "Release URL: https://github.com/${{ github.repository }}/releases/tag/${{ steps.version.outputs.tag }}"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kryten-webqueue
3
- Version: 0.1.2
3
+ Version: 0.1.6
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
@@ -5,6 +5,24 @@ from datetime import datetime, timedelta, UTC
5
5
  logger = logging.getLogger(__name__)
6
6
 
7
7
 
8
+ def _to_seconds(value) -> float:
9
+ """Convert a duration value to seconds. Handles int/float and 'HH:MM:SS' strings."""
10
+ if value is None:
11
+ return 0.0
12
+ if isinstance(value, (int, float)):
13
+ return float(value)
14
+ s = str(value).strip()
15
+ parts = s.split(":")
16
+ try:
17
+ if len(parts) == 3:
18
+ return int(parts[0]) * 3600 + int(parts[1]) * 60 + float(parts[2])
19
+ if len(parts) == 2:
20
+ return int(parts[0]) * 60 + float(parts[1])
21
+ return float(s)
22
+ except (ValueError, IndexError):
23
+ return 0.0
24
+
25
+
8
26
  class QueueShadow:
9
27
  """Local mirror of the CyTube playlist state."""
10
28
 
@@ -56,7 +74,7 @@ class QueueShadow:
56
74
  "title": polled.get("title", ""),
57
75
  "media_type": polled.get("type", "unknown"),
58
76
  "media_id": polled.get("id", ""),
59
- "duration_sec": float(polled.get("duration", 0) or 0),
77
+ "duration_sec": _to_seconds(polled.get("duration")),
60
78
  "is_pay": False,
61
79
  "paid_by": None,
62
80
  "tier": None,
@@ -79,12 +97,12 @@ class QueueShadow:
79
97
  # Start from now-playing elapsed or now
80
98
  start_cursor = datetime.now(UTC)
81
99
  if self._now_playing:
82
- remaining = float(self._now_playing.get("duration", 0) or 0) - float(self._now_playing.get("currentTime", 0) or 0)
100
+ remaining = _to_seconds(self._now_playing.get("duration")) - _to_seconds(self._now_playing.get("currentTime"))
83
101
  start_cursor += timedelta(seconds=max(0, remaining))
84
102
 
85
103
  for item in self._items:
86
104
  item["estimated_start_at"] = start_cursor.isoformat()
87
- duration = float(item.get("duration_sec", 0) or 0)
105
+ duration = _to_seconds(item.get("duration_sec"))
88
106
  start_cursor += timedelta(seconds=duration)
89
107
 
90
108
  async def insert_at(self, item: dict, position: int):
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "kryten-webqueue"
3
- version = "0.1.2"
3
+ version = "0.1.6"
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"