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.
- kryten_webqueue/__init__.py +0 -0
- kryten_webqueue/__main__.py +10 -0
- kryten_webqueue/api_gate/__init__.py +0 -0
- kryten_webqueue/api_gate/client.py +113 -0
- kryten_webqueue/app.py +184 -0
- kryten_webqueue/auth/__init__.py +0 -0
- kryten_webqueue/auth/otp.py +10 -0
- kryten_webqueue/auth/rate_limit.py +29 -0
- kryten_webqueue/auth/session.py +40 -0
- kryten_webqueue/catalog/__init__.py +0 -0
- kryten_webqueue/catalog/db.py +562 -0
- kryten_webqueue/catalog/images.py +114 -0
- kryten_webqueue/catalog/sync.py +96 -0
- kryten_webqueue/config.py +46 -0
- kryten_webqueue/playlists/__init__.py +0 -0
- kryten_webqueue/playlists/fire.py +71 -0
- kryten_webqueue/playlists/importer.py +92 -0
- kryten_webqueue/playlists/scheduler.py +72 -0
- kryten_webqueue/queue/__init__.py +0 -0
- kryten_webqueue/queue/ordering.py +186 -0
- kryten_webqueue/queue/poller.py +43 -0
- kryten_webqueue/queue/shadow.py +116 -0
- kryten_webqueue/routes/__init__.py +0 -0
- kryten_webqueue/routes/admin_playlists.py +98 -0
- kryten_webqueue/routes/admin_queue.py +64 -0
- kryten_webqueue/routes/admin_schedules.py +129 -0
- kryten_webqueue/routes/auth.py +83 -0
- kryten_webqueue/routes/catalog.py +44 -0
- kryten_webqueue/routes/pages.py +82 -0
- kryten_webqueue/routes/queue.py +144 -0
- kryten_webqueue/routes/user.py +35 -0
- kryten_webqueue/static/css/main.css +470 -0
- kryten_webqueue/static/js/main.js +26 -0
- kryten_webqueue/templates/admin/index.html +98 -0
- kryten_webqueue/templates/auth/login.html +69 -0
- kryten_webqueue/templates/base.html +41 -0
- kryten_webqueue/templates/catalog/browse.html +105 -0
- kryten_webqueue/templates/queue/index.html +126 -0
- kryten_webqueue/templates/user/dashboard.html +87 -0
- kryten_webqueue/ws/__init__.py +0 -0
- kryten_webqueue/ws/handler.py +59 -0
- kryten_webqueue/ws/manager.py +57 -0
- kryten_webqueue-0.1.1.dist-info/METADATA +127 -0
- kryten_webqueue-0.1.1.dist-info/RECORD +46 -0
- kryten_webqueue-0.1.1.dist-info/WHEEL +4 -0
- 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,,
|