kryten-webqueue 0.23.0__tar.gz → 0.23.1__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 (107) hide show
  1. kryten_webqueue-0.23.1/.github/workflows/python-publish.yml +93 -0
  2. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/.github/workflows/release.yml +6 -12
  3. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/CHANGELOG.md +8 -0
  4. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/PKG-INFO +1 -1
  5. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/pyproject.toml +1 -1
  6. kryten_webqueue-0.23.0/.github/workflows/python-publish.yml +0 -75
  7. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/.gitignore +0 -0
  8. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/README.md +0 -0
  9. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/config.example.json +0 -0
  10. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/deploy/kryten-webqueue.service +0 -0
  11. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/deploy/nginx-queue.conf +0 -0
  12. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/docs/IMPLEMENTATION_SPEC.md +0 -0
  13. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/docs/IMPL_API_GATE.md +0 -0
  14. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/docs/IMPL_ECONOMY.md +0 -0
  15. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/docs/IMPL_KRYTEN_PY.md +0 -0
  16. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/docs/IMPL_ROBOT.md +0 -0
  17. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/docs/PLAN_PRESENCE_AND_PROMOS.md +0 -0
  18. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/docs/PRE_PLAN_GAPS.md +0 -0
  19. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/docs/PRODUCT_PLAN.md +0 -0
  20. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/docs/SPEC_JOBS_AND_BROWSE.md +0 -0
  21. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/docs/UX_POLISH_PLAN.md +0 -0
  22. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/__init__.py +0 -0
  23. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/__main__.py +0 -0
  24. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/api_gate/__init__.py +0 -0
  25. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/api_gate/client.py +0 -0
  26. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/app.py +0 -0
  27. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/auth/__init__.py +0 -0
  28. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/auth/otp.py +0 -0
  29. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/auth/rate_limit.py +0 -0
  30. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/auth/session.py +0 -0
  31. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/catalog/__init__.py +0 -0
  32. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/catalog/db.py +0 -0
  33. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/catalog/images.py +0 -0
  34. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/catalog/mediacms.py +0 -0
  35. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/catalog/sync.py +0 -0
  36. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/config.py +0 -0
  37. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/integrations/__init__.py +0 -0
  38. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/integrations/cmsutils/__init__.py +0 -0
  39. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/integrations/cmsutils/_common.py +0 -0
  40. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/integrations/cmsutils/enrichmeta.py +0 -0
  41. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/integrations/cmsutils/enrichtitles.py +0 -0
  42. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/integrations/cmsutils/enrichtv.py +0 -0
  43. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/integrations/cmsutils/fetchurls.py +0 -0
  44. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/integrations/ytpipe/__init__.py +0 -0
  45. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/integrations/ytpipe/downloader.py +0 -0
  46. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/jobs/__init__.py +0 -0
  47. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/jobs/fetchurls_auth.py +0 -0
  48. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/jobs/manager.py +0 -0
  49. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/jobs/tasks.py +0 -0
  50. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/logging_config.py +0 -0
  51. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/playlists/__init__.py +0 -0
  52. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/playlists/bulk_add.py +0 -0
  53. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/playlists/fire.py +0 -0
  54. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/playlists/importer.py +0 -0
  55. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/playlists/ordering.py +0 -0
  56. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/playlists/scheduler.py +0 -0
  57. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/promos/__init__.py +0 -0
  58. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/promos/director.py +0 -0
  59. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/queue/__init__.py +0 -0
  60. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/queue/ordering.py +0 -0
  61. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/queue/poller.py +0 -0
  62. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/queue/presence.py +0 -0
  63. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/queue/shadow.py +0 -0
  64. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/routes/__init__.py +0 -0
  65. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/routes/admin_catalog.py +0 -0
  66. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/routes/admin_jobs.py +0 -0
  67. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/routes/admin_playlists.py +0 -0
  68. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/routes/admin_promos.py +0 -0
  69. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/routes/admin_queue.py +0 -0
  70. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/routes/admin_schedules.py +0 -0
  71. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/routes/auth.py +0 -0
  72. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/routes/catalog.py +0 -0
  73. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/routes/pages.py +0 -0
  74. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/routes/queue.py +0 -0
  75. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/routes/user.py +0 -0
  76. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/static/css/main.css +0 -0
  77. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/static/js/main.js +0 -0
  78. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/templates/admin/index.html +0 -0
  79. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/templates/admin/playlists.html +0 -0
  80. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/templates/admin/promos.html +0 -0
  81. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/templates/admin/queue_mgmt.html +0 -0
  82. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/templates/admin/schedules.html +0 -0
  83. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/templates/auth/login.html +0 -0
  84. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/templates/base.html +0 -0
  85. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/templates/catalog/browse.html +0 -0
  86. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/templates/catalog/item_detail.html +0 -0
  87. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/templates/catalog/item_not_found.html +0 -0
  88. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/templates/queue/index.html +0 -0
  89. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/templates/user/dashboard.html +0 -0
  90. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/ws/__init__.py +0 -0
  91. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/ws/handler.py +0 -0
  92. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/kryten_webqueue/ws/manager.py +0 -0
  93. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/tests/__init__.py +0 -0
  94. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/tests/test_config_persistence.py +0 -0
  95. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/tests/test_fetchurls_sharepoint.py +0 -0
  96. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/tests/test_phase1.py +0 -0
  97. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/tests/test_phase2_jobs.py +0 -0
  98. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/tests/test_phase3_jobs.py +0 -0
  99. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/tests/test_phase4_live_fixes.py +0 -0
  100. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/tests/test_playlist_import.py +0 -0
  101. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/tests/test_presence_refund.py +0 -0
  102. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/tests/test_promo_director.py +0 -0
  103. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/tests/test_promo_pool_exclusion.py +0 -0
  104. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/tests/test_queue_announce.py +0 -0
  105. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/tests/test_save_results_to_playlist.py +0 -0
  106. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/tests/test_schedule_lock.py +0 -0
  107. {kryten_webqueue-0.23.0 → kryten_webqueue-0.23.1}/tests/test_search_facets.py +0 -0
@@ -0,0 +1,93 @@
1
+ name: Publish Python Package to PyPI
2
+
3
+ # Builds and publishes to PyPI. This workflow MUST run top-level (never invoked
4
+ # via a reusable `uses:` call). PyPI Trusted Publishing matches the OIDC
5
+ # `job_workflow_ref` claim — the filename of the workflow that contains the
6
+ # running job — against the configured publisher (python-publish.yml). Running
7
+ # this as a reusable workflow would change that filename and break publishing
8
+ # (and is explicitly unsupported by PyPI).
9
+ on:
10
+ # Primary automated path: fire after "Release Automation" (release.yml)
11
+ # finishes creating the tag + GitHub Release. workflow_run keeps this workflow
12
+ # top-level, unlike a reusable `uses:` invocation.
13
+ workflow_run:
14
+ workflows: ["Release Automation"]
15
+ types: [completed]
16
+ # Manual fallbacks: publishing a GitHub Release by hand, or pushing a tag.
17
+ release:
18
+ types: [published]
19
+ push:
20
+ tags:
21
+ - 'kryten-webqueue-v*'
22
+ - 'v*'
23
+
24
+ permissions:
25
+ contents: read
26
+
27
+ jobs:
28
+ release-build:
29
+ name: Build distribution packages
30
+ runs-on: ubuntu-latest
31
+ # When triggered by release.yml's completion, only proceed on success.
32
+ # release/tag triggers aren't workflow_run events, so they always build.
33
+ if: ${{ github.event_name != 'workflow_run' || github.event.workflow_run.conclusion == 'success' }}
34
+
35
+ steps:
36
+ - name: Checkout repository
37
+ uses: actions/checkout@v7
38
+ with:
39
+ # For a workflow_run trigger, build the exact commit release.yml
40
+ # processed; otherwise build the tag/release commit.
41
+ ref: ${{ github.event.workflow_run.head_sha || github.sha }}
42
+
43
+ - name: Install uv
44
+ uses: astral-sh/setup-uv@v8.2.0
45
+ with:
46
+ version: "latest"
47
+
48
+ - name: Set up Python
49
+ uses: actions/setup-python@v6
50
+ with:
51
+ python-version: "3.12"
52
+
53
+ - name: Build release distributions
54
+ run: |
55
+ uv build
56
+ echo "📦 Built packages:"
57
+ ls -lh dist/
58
+
59
+ - name: Upload distributions
60
+ uses: actions/upload-artifact@v7
61
+ with:
62
+ name: release-dists
63
+ path: dist/
64
+
65
+ pypi-publish:
66
+ name: Publish to PyPI
67
+ runs-on: ubuntu-latest
68
+ needs:
69
+ - release-build
70
+ environment:
71
+ name: pypi
72
+ permissions:
73
+ id-token: write
74
+
75
+ steps:
76
+ - name: Retrieve release distributions
77
+ uses: actions/download-artifact@v8
78
+ with:
79
+ name: release-dists
80
+ path: dist/
81
+
82
+ - name: Publish release distributions to PyPI
83
+ uses: pypa/gh-action-pypi-publish@release/v1
84
+ with:
85
+ packages-dir: dist/
86
+ skip-existing: true
87
+ attestations: false
88
+
89
+ - name: Success notification
90
+ if: success()
91
+ run: |
92
+ echo "✅ Successfully published to PyPI!"
93
+ echo "🔗 Package URL: https://pypi.org/project/kryten-webqueue/"
@@ -1,6 +1,10 @@
1
1
  name: Release Automation
2
2
 
3
- # Automatically create GitHub releases when version in pyproject.toml changes
3
+ # Automatically create GitHub releases when version in pyproject.toml changes.
4
+ # Publishing to PyPI is handled separately by python-publish.yml, which triggers
5
+ # on this workflow's completion (see its workflow_run trigger). Publishing is
6
+ # intentionally NOT inlined here: PyPI Trusted Publishing matches the OIDC
7
+ # job_workflow_ref filename, which is configured as python-publish.yml.
4
8
  on:
5
9
  push:
6
10
  branches:
@@ -11,8 +15,6 @@ on:
11
15
 
12
16
  permissions:
13
17
  contents: write
14
- pull-requests: read
15
- id-token: write
16
18
 
17
19
  jobs:
18
20
  create-release:
@@ -20,7 +22,7 @@ jobs:
20
22
  runs-on: ubuntu-latest
21
23
 
22
24
  steps:
23
- - uses: actions/checkout@v4
25
+ - uses: actions/checkout@v7
24
26
  with:
25
27
  fetch-depth: 0 # Full history for changelog
26
28
 
@@ -93,11 +95,3 @@ jobs:
93
95
  if: steps.check_tag.outputs.exists == 'true'
94
96
  run: |
95
97
  echo "ℹ️ Release ${{ steps.version.outputs.tag }} already exists - skipping"
96
-
97
- publish-to-pypi:
98
- name: Publish to PyPI
99
- needs: [create-release]
100
- uses: ./.github/workflows/python-publish.yml
101
- permissions:
102
- id-token: write
103
- contents: read
@@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file.
4
4
 
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
+ ## [0.23.1] — 2026-06-21
8
+
9
+ ### Changed
10
+
11
+ - **Release CI hardening (no runtime changes).** PyPI publishing was moved out of a reusable workflow into a top-level one. PyPI Trusted Publishing matches the OIDC `job_workflow_ref` claim — the filename of the workflow containing the running job — against the configured publisher (`python-publish.yml`); invoking that workflow via a reusable `uses:` call is unsupported by PyPI and raised a "workflow misconfiguration" warning. `python-publish.yml` now triggers via `workflow_run` after `release.yml` completes (keeping it top-level so the publisher filename stays `python-publish.yml`), and `release.yml` no longer calls it reusably. All GitHub Actions were bumped off the deprecated Node 20 runtime: `actions/checkout@v7`, `actions/setup-python@v6`, `actions/upload-artifact@v7`, `actions/download-artifact@v8`, and `astral-sh/setup-uv@v8.2.0`.
12
+
13
+ [0.23.1]: https://github.com/grobertson/kryten-webqueue/releases/tag/v0.23.1
14
+
7
15
  ## [0.23.0] — 2026-06-21
8
16
 
9
17
  ### Fixed
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kryten-webqueue
3
- Version: 0.23.0
3
+ Version: 0.23.1
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
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "kryten-webqueue"
3
- version = "0.23.0"
3
+ version = "0.23.1"
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"
@@ -1,75 +0,0 @@
1
- name: Publish Python Package to PyPI
2
-
3
- on:
4
- workflow_call:
5
- release:
6
- types: [published]
7
- push:
8
- tags:
9
- - 'kryten-webqueue-v*'
10
- - 'v*'
11
-
12
- permissions:
13
- contents: read
14
- id-token: write
15
-
16
- jobs:
17
- release-build:
18
- name: Build distribution packages
19
- runs-on: ubuntu-latest
20
-
21
- steps:
22
- - name: Checkout repository
23
- uses: actions/checkout@v4
24
-
25
- - name: Install uv
26
- uses: astral-sh/setup-uv@v4
27
- with:
28
- version: "latest"
29
-
30
- - name: Set up Python
31
- uses: actions/setup-python@v5
32
- with:
33
- python-version: "3.12"
34
-
35
- - name: Build release distributions
36
- run: |
37
- uv build
38
- echo "📦 Built packages:"
39
- ls -lh dist/
40
-
41
- - name: Upload distributions
42
- uses: actions/upload-artifact@v4
43
- with:
44
- name: release-dists
45
- path: dist/
46
-
47
- pypi-publish:
48
- name: Publish to PyPI
49
- runs-on: ubuntu-latest
50
- needs:
51
- - release-build
52
- environment:
53
- name: pypi
54
- permissions:
55
- id-token: write
56
-
57
- steps:
58
- - name: Retrieve release distributions
59
- uses: actions/download-artifact@v4
60
- with:
61
- name: release-dists
62
- path: dist/
63
-
64
- - name: Publish release distributions to PyPI
65
- uses: pypa/gh-action-pypi-publish@release/v1
66
- with:
67
- packages-dir: dist/
68
- skip-existing: true
69
- attestations: false
70
-
71
- - name: Success notification
72
- if: success()
73
- run: |
74
- echo "✅ Successfully published to PyPI!"
75
- echo "🔗 Package URL: https://pypi.org/project/kryten-webqueue/"