kryten-webqueue 0.1.1__py3-none-any.whl

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 (46) hide show
  1. kryten_webqueue/__init__.py +0 -0
  2. kryten_webqueue/__main__.py +10 -0
  3. kryten_webqueue/api_gate/__init__.py +0 -0
  4. kryten_webqueue/api_gate/client.py +113 -0
  5. kryten_webqueue/app.py +184 -0
  6. kryten_webqueue/auth/__init__.py +0 -0
  7. kryten_webqueue/auth/otp.py +10 -0
  8. kryten_webqueue/auth/rate_limit.py +29 -0
  9. kryten_webqueue/auth/session.py +40 -0
  10. kryten_webqueue/catalog/__init__.py +0 -0
  11. kryten_webqueue/catalog/db.py +562 -0
  12. kryten_webqueue/catalog/images.py +114 -0
  13. kryten_webqueue/catalog/sync.py +96 -0
  14. kryten_webqueue/config.py +46 -0
  15. kryten_webqueue/playlists/__init__.py +0 -0
  16. kryten_webqueue/playlists/fire.py +71 -0
  17. kryten_webqueue/playlists/importer.py +92 -0
  18. kryten_webqueue/playlists/scheduler.py +72 -0
  19. kryten_webqueue/queue/__init__.py +0 -0
  20. kryten_webqueue/queue/ordering.py +186 -0
  21. kryten_webqueue/queue/poller.py +43 -0
  22. kryten_webqueue/queue/shadow.py +116 -0
  23. kryten_webqueue/routes/__init__.py +0 -0
  24. kryten_webqueue/routes/admin_playlists.py +98 -0
  25. kryten_webqueue/routes/admin_queue.py +64 -0
  26. kryten_webqueue/routes/admin_schedules.py +129 -0
  27. kryten_webqueue/routes/auth.py +83 -0
  28. kryten_webqueue/routes/catalog.py +44 -0
  29. kryten_webqueue/routes/pages.py +82 -0
  30. kryten_webqueue/routes/queue.py +144 -0
  31. kryten_webqueue/routes/user.py +35 -0
  32. kryten_webqueue/static/css/main.css +470 -0
  33. kryten_webqueue/static/js/main.js +26 -0
  34. kryten_webqueue/templates/admin/index.html +98 -0
  35. kryten_webqueue/templates/auth/login.html +69 -0
  36. kryten_webqueue/templates/base.html +41 -0
  37. kryten_webqueue/templates/catalog/browse.html +105 -0
  38. kryten_webqueue/templates/queue/index.html +126 -0
  39. kryten_webqueue/templates/user/dashboard.html +87 -0
  40. kryten_webqueue/ws/__init__.py +0 -0
  41. kryten_webqueue/ws/handler.py +59 -0
  42. kryten_webqueue/ws/manager.py +57 -0
  43. kryten_webqueue-0.1.1.dist-info/METADATA +127 -0
  44. kryten_webqueue-0.1.1.dist-info/RECORD +46 -0
  45. kryten_webqueue-0.1.1.dist-info/WHEEL +4 -0
  46. kryten_webqueue-0.1.1.dist-info/entry_points.txt +2 -0
@@ -0,0 +1,127 @@
1
+ Metadata-Version: 2.4
2
+ Name: kryten-webqueue
3
+ Version: 0.1.1
4
+ Summary: Netflix/Tubi-style catalog browser and pay-to-play queue management for CyTube
5
+ Author: grobertson
6
+ License-Expression: MIT
7
+ Requires-Python: >=3.12
8
+ Requires-Dist: aiosqlite>=0.20
9
+ Requires-Dist: apscheduler>=3.10
10
+ Requires-Dist: fastapi>=0.115
11
+ Requires-Dist: httpx>=0.27
12
+ Requires-Dist: jinja2>=3.1
13
+ Requires-Dist: pillow>=10.0
14
+ Requires-Dist: pydantic>=2.0
15
+ Requires-Dist: pyjwt>=2.8
16
+ Requires-Dist: uvicorn[standard]>=0.30
17
+ Requires-Dist: websockets>=12.0
18
+ Provides-Extra: dev
19
+ Requires-Dist: black>=24.0; extra == 'dev'
20
+ Requires-Dist: httpx; extra == 'dev'
21
+ Requires-Dist: mypy>=1.10; extra == 'dev'
22
+ Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
23
+ Requires-Dist: pytest>=8.0; extra == 'dev'
24
+ Requires-Dist: ruff>=0.4; extra == 'dev'
25
+ Description-Content-Type: text/markdown
26
+
27
+ # kryten-webqueue
28
+
29
+ Netflix/Tubi-style catalog browser and pay-to-play queue management for CyTube.
30
+
31
+ ## Architecture
32
+
33
+ ```
34
+ Browser → nginx (queue.dropsugar.co) → kryten-webqueue (:2010) → kryten-api-gate (:24444) → NATS services
35
+ ```
36
+
37
+ - **HTTP-only** — webqueue never touches NATS directly
38
+ - **SQLite** for all local state (catalog, OTPs, queue shadow, playlists, schedules)
39
+ - **WebSocket** for real-time queue updates
40
+ - **Polling** api-gate every 3 seconds for playlist state
41
+
42
+ ## Quick Start
43
+
44
+ ```bash
45
+ # Install
46
+ python -m venv .venv
47
+ .venv/bin/pip install -e .
48
+
49
+ # Configure
50
+ cp config.example.json /etc/kryten-webqueue/config.json
51
+ # Edit config.json with your secrets
52
+
53
+ # Run
54
+ WQ_CONFIG=/etc/kryten-webqueue/config.json python -m kryten_webqueue
55
+ ```
56
+
57
+ ## Configuration
58
+
59
+ See `config.example.json` for all options. Required secrets:
60
+
61
+ | Key | Description |
62
+ |-----|-------------|
63
+ | `secret_key` | Random string for JWT signing (≥32 chars) |
64
+ | `api_gate_token` | Bearer token for kryten-api-gate |
65
+ | `mediacms_token` | API token for MediaCMS catalog sync |
66
+
67
+ ## Deployment
68
+
69
+ ```bash
70
+ # Install service
71
+ sudo cp deploy/kryten-webqueue.service /etc/systemd/system/
72
+ sudo systemctl daemon-reload
73
+ sudo systemctl enable --now kryten-webqueue
74
+
75
+ # nginx
76
+ sudo cp deploy/nginx-queue.conf /etc/nginx/sites-available/queue.dropsugar.co
77
+ sudo ln -s /etc/nginx/sites-available/queue.dropsugar.co /etc/nginx/sites-enabled/
78
+ sudo nginx -t && sudo systemctl reload nginx
79
+ ```
80
+
81
+ ## API Endpoints
82
+
83
+ ### Auth
84
+ - `POST /auth/otp/request` — Request OTP (delivered via PM)
85
+ - `POST /auth/otp/verify` — Verify OTP, get session cookie
86
+ - `POST /auth/logout` — Clear session
87
+ - `GET /auth/me` — Current user info
88
+
89
+ ### Catalog
90
+ - `GET /catalog/browse` — Paginated browse (with category filter)
91
+ - `GET /catalog/search?q=...` — Full-text search
92
+ - `GET /catalog/item/{token}` — Item detail
93
+ - `GET /catalog/categories` — List categories
94
+
95
+ ### Queue
96
+ - `GET /queue/state` — Current queue state
97
+ - `POST /queue/add` — Add item (FIFO pay-queue)
98
+ - `POST /queue/playnext` — Add as play-next (premium)
99
+ - `GET /queue/preview?friendly_token=...&tier=...` — Cost preview
100
+ - `GET /queue/history` — User's queue history
101
+
102
+ ### User
103
+ - `GET /user/balance` — Economy balance
104
+ - `GET /user/transactions` — Transaction history
105
+ - `GET /user/profile` — Profile info
106
+
107
+ ### Admin (rank ≥ 3)
108
+ - `GET/POST/PUT/DELETE /admin/playlists/...` — Saved playlists CRUD
109
+ - `GET/POST/PUT/DELETE /admin/schedules/...` — Schedule CRUD
110
+ - `POST /admin/schedules/{id}/fire` — Manual fire
111
+ - `POST /admin/queue/clear` — Clear queue (refunds pay items)
112
+ - `DELETE /admin/queue/{uid}` — Remove item
113
+ - `POST /admin/queue/sync-now` — Trigger catalog sync
114
+
115
+ ### WebSocket
116
+ - `ws://host/ws` — Real-time queue updates (auth via session cookie)
117
+
118
+ ## Dependencies
119
+
120
+ - Python ≥ 3.12
121
+ - kryten-api-gate ≥ 0.3.6
122
+ - kryten-py ≥ 0.16.1 (upstream, not a direct dependency)
123
+ - kryten-economy ≥ 0.8.11 (upstream, not a direct dependency)
124
+
125
+ ## License
126
+
127
+ Proprietary — DropSugar / Q&A
@@ -0,0 +1,46 @@
1
+ kryten_webqueue/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ kryten_webqueue/__main__.py,sha256=TEGuK2O7CWuIh6YwUbD7S3wfmUP8hmKm_GAmVgGIEg8,277
3
+ kryten_webqueue/app.py,sha256=RRS6E4zCzqWFAxydZ3N4PJT1li3XAeWfAPfGfJtiEso,5783
4
+ kryten_webqueue/config.py,sha256=1TyxH1VZqAOOfw8Ermn7yAo9tQvnNsoLt_ExjdNEHek,1102
5
+ kryten_webqueue/api_gate/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
+ kryten_webqueue/api_gate/client.py,sha256=bFikl2c0JM-rkkGacKU6KrEGbfBamhvt5o-Dg2u0-wg,3998
7
+ kryten_webqueue/auth/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
+ kryten_webqueue/auth/otp.py,sha256=P7K4gOTLhPdnABnG5lDNmqITwhVCRvb7OfI4l48JJkc,261
9
+ kryten_webqueue/auth/rate_limit.py,sha256=cyK6e9ajoIMW-bKCjlNXnapmC2W-kAk4qjVxQ-DkwJA,915
10
+ kryten_webqueue/auth/session.py,sha256=Cg7JHqrnQ9sVfst6X6BXzUNcZphdsSFx5djW7Dod8BU,1456
11
+ kryten_webqueue/catalog/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
+ kryten_webqueue/catalog/db.py,sha256=VxsTe03znFlynYnus-d9zCxM9mRR45rDza2h-ziKQn0,22846
13
+ kryten_webqueue/catalog/images.py,sha256=k_o31JebREtbZuwn-l_N8BSMHlf9kU5Q_3e7JhREUVM,4026
14
+ kryten_webqueue/catalog/sync.py,sha256=oiuUjI-hWuFr1pj7xHFSuP4qY1Sf_IZ8TKu013_wUaw,3379
15
+ kryten_webqueue/playlists/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
+ kryten_webqueue/playlists/fire.py,sha256=oVa7jUkZy9-kQERakU54artPZa4xCLxsynUTKuaBYcw,2554
17
+ kryten_webqueue/playlists/importer.py,sha256=3h6tnZJ4OtH3gjhWqzLeHGcnbFfeR7LhA4Apb9CAgGI,3134
18
+ kryten_webqueue/playlists/scheduler.py,sha256=HaY9LqgAap8NwVaJBdOnCVzyteH55HW0alECbL_CM0U,2338
19
+ kryten_webqueue/queue/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
+ kryten_webqueue/queue/ordering.py,sha256=PqXm_KICwUL65cb3AlUwJLCIhxvA-lLGorMum_s3drE,5530
21
+ kryten_webqueue/queue/poller.py,sha256=xZq-YGI6hlAIMDm07W8pvXoG1dPOSKLk9cjyY62tjj0,1484
22
+ kryten_webqueue/queue/shadow.py,sha256=AK0NY54PJUWdG-zNU0nSTxpl-6FAx84Umxu-UNhP4o8,4397
23
+ kryten_webqueue/routes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
24
+ kryten_webqueue/routes/admin_playlists.py,sha256=IFo2iQcCJhTcW96pKhtAaaVZsuNGJq9IYNVFVqxZOKc,3513
25
+ kryten_webqueue/routes/admin_queue.py,sha256=ZU8j6Tt8zhWv2OTW2FWgEkrXTEAi4nLcYqzy8EdEHxA,2143
26
+ kryten_webqueue/routes/admin_schedules.py,sha256=sTZNvOGbemUrT5384yQRHq1VPoUE_6Z0Fn3kH_660DQ,4079
27
+ kryten_webqueue/routes/auth.py,sha256=Bgnnem2amfXROH4Ff6QhHnK0vBqkvpPlpuJZ3m9eKyo,2598
28
+ kryten_webqueue/routes/catalog.py,sha256=B3BN9lyA4_-VHOkkWPY0YRf4uTOfkKIUx1WPwS62DfE,1537
29
+ kryten_webqueue/routes/pages.py,sha256=UMmeqUPQSEMAOXyD6QXXMjMXZv52Rk9LM_-MzKmV_0Q,2861
30
+ kryten_webqueue/routes/queue.py,sha256=cEe4rzT4DDcVD1lncXbNHjcropaas1-msAkSD2e6QSM,4321
31
+ kryten_webqueue/routes/user.py,sha256=bti9N1NNY2pg_ow5T9rKWSykjPRbXJqKv2xqfBerxDo,1219
32
+ kryten_webqueue/static/css/main.css,sha256=9RyqeGL75WbPl7eGXbxEtwRGownNKWpmLreSyCg7HEU,8990
33
+ kryten_webqueue/static/js/main.js,sha256=ks3aLOPNRa60cz5WrvFnLmbHj1_rWFD0eQ106s7Cnjs,834
34
+ kryten_webqueue/templates/base.html,sha256=ln_ag9ptFHDS4AH5i73iQMsR8p3COEC-poDTZ-g_VAA,1288
35
+ kryten_webqueue/templates/admin/index.html,sha256=5ZwUUIv7SFsj9x2s-zFwUIKWnrueGcgkSf8E1Fe5Ja4,3327
36
+ kryten_webqueue/templates/auth/login.html,sha256=wPKuX-T4LtjSwAT8yWH6e4Mt3nl073rTa2R612wjy9A,2524
37
+ kryten_webqueue/templates/catalog/browse.html,sha256=_XPaxbA4V-9cz12BBgeDAB33ZGwu02WhSMnv3WTWXG8,3826
38
+ kryten_webqueue/templates/queue/index.html,sha256=EcvGk-ew3OUn5iv9WLH7L7v6s6Z7fCs4l5WRFt7ulwE,4192
39
+ kryten_webqueue/templates/user/dashboard.html,sha256=XER97ToXjZuyZaxH8FXmotYpmNA-xLJp6FP0FeU74mY,2782
40
+ kryten_webqueue/ws/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
41
+ kryten_webqueue/ws/handler.py,sha256=3B8xcfMdFMLrTXkHerOFMIlcfYzhp_DSSP9-To8sYfc,1659
42
+ kryten_webqueue/ws/manager.py,sha256=3-d92KbH3tegIKBWbClqv1nUut3nUZli7oBaNVTXzME,1928
43
+ kryten_webqueue-0.1.1.dist-info/METADATA,sha256=NMwkl4rgev3FkaO336BxhmfUq_I8UUb8MeSPkBIoRHw,3854
44
+ kryten_webqueue-0.1.1.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
45
+ kryten_webqueue-0.1.1.dist-info/entry_points.txt,sha256=QvrQn5MkZpYnumu_5gldPIW1cbyGl2f5oIfE0Dh3sGU,66
46
+ kryten_webqueue-0.1.1.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.29.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ kryten-webqueue = kryten_webqueue.__main__:main