reeln 0.0.23__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 (147) hide show
  1. reeln-0.0.23/.coveragerc +13 -0
  2. reeln-0.0.23/.github/workflows/ci.yml +59 -0
  3. reeln-0.0.23/.github/workflows/release.yml +45 -0
  4. reeln-0.0.23/.gitignore +52 -0
  5. reeln-0.0.23/.readthedocs.yaml +18 -0
  6. reeln-0.0.23/CHANGELOG.md +105 -0
  7. reeln-0.0.23/LICENSE +661 -0
  8. reeln-0.0.23/Makefile +45 -0
  9. reeln-0.0.23/PKG-INFO +167 -0
  10. reeln-0.0.23/README.md +142 -0
  11. reeln-0.0.23/assets/logo.jpg +0 -0
  12. reeln-0.0.23/docs/changelog.md +5 -0
  13. reeln-0.0.23/docs/cli/config.md +36 -0
  14. reeln-0.0.23/docs/cli/doctor.md +86 -0
  15. reeln-0.0.23/docs/cli/game.md +358 -0
  16. reeln-0.0.23/docs/cli/index.md +30 -0
  17. reeln-0.0.23/docs/cli/media.md +47 -0
  18. reeln-0.0.23/docs/cli/plugins.md +230 -0
  19. reeln-0.0.23/docs/cli/render.md +236 -0
  20. reeln-0.0.23/docs/conf.py +67 -0
  21. reeln-0.0.23/docs/guide/configuration.md +340 -0
  22. reeln-0.0.23/docs/guide/sports.md +52 -0
  23. reeln-0.0.23/docs/index.md +54 -0
  24. reeln-0.0.23/docs/install.md +76 -0
  25. reeln-0.0.23/docs/quickstart.md +273 -0
  26. reeln-0.0.23/docs/requirements.txt +4 -0
  27. reeln-0.0.23/pyproject.toml +64 -0
  28. reeln-0.0.23/pytest.ini +3 -0
  29. reeln-0.0.23/reeln/__init__.py +5 -0
  30. reeln-0.0.23/reeln/__main__.py +7 -0
  31. reeln-0.0.23/reeln/cli.py +103 -0
  32. reeln-0.0.23/reeln/commands/__init__.py +0 -0
  33. reeln-0.0.23/reeln/commands/config_cmd.py +57 -0
  34. reeln-0.0.23/reeln/commands/event.py +161 -0
  35. reeln-0.0.23/reeln/commands/game.py +483 -0
  36. reeln-0.0.23/reeln/commands/media.py +41 -0
  37. reeln-0.0.23/reeln/commands/plugins_cmd.py +269 -0
  38. reeln-0.0.23/reeln/commands/render.py +775 -0
  39. reeln-0.0.23/reeln/core/__init__.py +0 -0
  40. reeln-0.0.23/reeln/core/config.py +413 -0
  41. reeln-0.0.23/reeln/core/debug.py +324 -0
  42. reeln-0.0.23/reeln/core/doctor.py +284 -0
  43. reeln-0.0.23/reeln/core/errors.py +71 -0
  44. reeln-0.0.23/reeln/core/events.py +228 -0
  45. reeln-0.0.23/reeln/core/ffmpeg.py +474 -0
  46. reeln-0.0.23/reeln/core/finish.py +77 -0
  47. reeln-0.0.23/reeln/core/highlights.py +625 -0
  48. reeln-0.0.23/reeln/core/iterations.py +166 -0
  49. reeln-0.0.23/reeln/core/log.py +83 -0
  50. reeln-0.0.23/reeln/core/orchestrator.py +133 -0
  51. reeln-0.0.23/reeln/core/overlay.py +183 -0
  52. reeln-0.0.23/reeln/core/plugin_config.py +100 -0
  53. reeln-0.0.23/reeln/core/plugin_registry.py +419 -0
  54. reeln-0.0.23/reeln/core/profiles.py +220 -0
  55. reeln-0.0.23/reeln/core/prompts.py +284 -0
  56. reeln-0.0.23/reeln/core/prune.py +262 -0
  57. reeln-0.0.23/reeln/core/renderer.py +99 -0
  58. reeln-0.0.23/reeln/core/segment.py +162 -0
  59. reeln-0.0.23/reeln/core/shorts.py +226 -0
  60. reeln-0.0.23/reeln/core/teams.py +102 -0
  61. reeln-0.0.23/reeln/core/templates.py +141 -0
  62. reeln-0.0.23/reeln/core/throttle.py +82 -0
  63. reeln-0.0.23/reeln/data/__init__.py +1 -0
  64. reeln-0.0.23/reeln/data/templates/__init__.py +1 -0
  65. reeln-0.0.23/reeln/data/templates/goal_overlay.ass +24 -0
  66. reeln-0.0.23/reeln/models/__init__.py +0 -0
  67. reeln-0.0.23/reeln/models/config.py +56 -0
  68. reeln-0.0.23/reeln/models/debug.py +51 -0
  69. reeln-0.0.23/reeln/models/doctor.py +33 -0
  70. reeln-0.0.23/reeln/models/game.py +175 -0
  71. reeln-0.0.23/reeln/models/plugin.py +100 -0
  72. reeln-0.0.23/reeln/models/plugin_schema.py +93 -0
  73. reeln-0.0.23/reeln/models/profile.py +137 -0
  74. reeln-0.0.23/reeln/models/render_plan.py +88 -0
  75. reeln-0.0.23/reeln/models/segment.py +26 -0
  76. reeln-0.0.23/reeln/models/short.py +68 -0
  77. reeln-0.0.23/reeln/models/team.py +57 -0
  78. reeln-0.0.23/reeln/models/template.py +29 -0
  79. reeln-0.0.23/reeln/plugins/__init__.py +24 -0
  80. reeln-0.0.23/reeln/plugins/capabilities.py +48 -0
  81. reeln-0.0.23/reeln/plugins/hooks.py +37 -0
  82. reeln-0.0.23/reeln/plugins/loader.py +184 -0
  83. reeln-0.0.23/reeln/plugins/registry.py +68 -0
  84. reeln-0.0.23/registry/plugins.json +15 -0
  85. reeln-0.0.23/tests/__init__.py +0 -0
  86. reeln-0.0.23/tests/conftest.py +30 -0
  87. reeln-0.0.23/tests/integration/__init__.py +0 -0
  88. reeln-0.0.23/tests/integration/conftest.py +172 -0
  89. reeln-0.0.23/tests/integration/test_cli_lifecycle.py +398 -0
  90. reeln-0.0.23/tests/integration/test_ffmpeg_lifecycle.py +187 -0
  91. reeln-0.0.23/tests/integration/test_ffmpeg_real.py +30 -0
  92. reeln-0.0.23/tests/integration/test_game_lifecycle.py +315 -0
  93. reeln-0.0.23/tests/unit/__init__.py +0 -0
  94. reeln-0.0.23/tests/unit/commands/__init__.py +0 -0
  95. reeln-0.0.23/tests/unit/commands/test_cli.py +229 -0
  96. reeln-0.0.23/tests/unit/commands/test_config_cmd.py +118 -0
  97. reeln-0.0.23/tests/unit/commands/test_event.py +496 -0
  98. reeln-0.0.23/tests/unit/commands/test_game.py +1937 -0
  99. reeln-0.0.23/tests/unit/commands/test_media.py +148 -0
  100. reeln-0.0.23/tests/unit/commands/test_plugins_cmd.py +747 -0
  101. reeln-0.0.23/tests/unit/commands/test_render.py +3332 -0
  102. reeln-0.0.23/tests/unit/core/__init__.py +0 -0
  103. reeln-0.0.23/tests/unit/core/test_config.py +853 -0
  104. reeln-0.0.23/tests/unit/core/test_debug.py +544 -0
  105. reeln-0.0.23/tests/unit/core/test_doctor.py +396 -0
  106. reeln-0.0.23/tests/unit/core/test_errors.py +158 -0
  107. reeln-0.0.23/tests/unit/core/test_events.py +563 -0
  108. reeln-0.0.23/tests/unit/core/test_ffmpeg.py +697 -0
  109. reeln-0.0.23/tests/unit/core/test_finish.py +174 -0
  110. reeln-0.0.23/tests/unit/core/test_highlights.py +1237 -0
  111. reeln-0.0.23/tests/unit/core/test_iterations.py +668 -0
  112. reeln-0.0.23/tests/unit/core/test_log.py +95 -0
  113. reeln-0.0.23/tests/unit/core/test_orchestrator.py +311 -0
  114. reeln-0.0.23/tests/unit/core/test_overlay.py +317 -0
  115. reeln-0.0.23/tests/unit/core/test_plugin_config.py +231 -0
  116. reeln-0.0.23/tests/unit/core/test_plugin_registry.py +809 -0
  117. reeln-0.0.23/tests/unit/core/test_profiles.py +415 -0
  118. reeln-0.0.23/tests/unit/core/test_prompts.py +638 -0
  119. reeln-0.0.23/tests/unit/core/test_prune.py +551 -0
  120. reeln-0.0.23/tests/unit/core/test_renderer.py +271 -0
  121. reeln-0.0.23/tests/unit/core/test_segment.py +279 -0
  122. reeln-0.0.23/tests/unit/core/test_shorts.py +401 -0
  123. reeln-0.0.23/tests/unit/core/test_teams.py +293 -0
  124. reeln-0.0.23/tests/unit/core/test_templates.py +292 -0
  125. reeln-0.0.23/tests/unit/core/test_throttle.py +157 -0
  126. reeln-0.0.23/tests/unit/models/__init__.py +0 -0
  127. reeln-0.0.23/tests/unit/models/test_config.py +124 -0
  128. reeln-0.0.23/tests/unit/models/test_debug.py +135 -0
  129. reeln-0.0.23/tests/unit/models/test_doctor.py +74 -0
  130. reeln-0.0.23/tests/unit/models/test_game.py +695 -0
  131. reeln-0.0.23/tests/unit/models/test_plugin.py +280 -0
  132. reeln-0.0.23/tests/unit/models/test_plugin_schema.py +237 -0
  133. reeln-0.0.23/tests/unit/models/test_profile.py +267 -0
  134. reeln-0.0.23/tests/unit/models/test_render_plan.py +319 -0
  135. reeln-0.0.23/tests/unit/models/test_segment.py +53 -0
  136. reeln-0.0.23/tests/unit/models/test_short.py +152 -0
  137. reeln-0.0.23/tests/unit/models/test_team.py +166 -0
  138. reeln-0.0.23/tests/unit/models/test_template.py +63 -0
  139. reeln-0.0.23/tests/unit/plugins/__init__.py +0 -0
  140. reeln-0.0.23/tests/unit/plugins/test_capabilities.py +114 -0
  141. reeln-0.0.23/tests/unit/plugins/test_hooks.py +84 -0
  142. reeln-0.0.23/tests/unit/plugins/test_init.py +67 -0
  143. reeln-0.0.23/tests/unit/plugins/test_loader.py +411 -0
  144. reeln-0.0.23/tests/unit/plugins/test_registry.py +135 -0
  145. reeln-0.0.23/tests/unit/test_init.py +17 -0
  146. reeln-0.0.23/tests/unit/test_main.py +15 -0
  147. reeln-0.0.23/uv.lock +1126 -0
@@ -0,0 +1,13 @@
1
+ [run]
2
+ branch = true
3
+ source = reeln
4
+
5
+ [report]
6
+ fail_under = 100
7
+ show_missing = true
8
+ exclude_lines =
9
+ pragma: no cover
10
+ if __name__ == .__main__
11
+ if TYPE_CHECKING
12
+ raise NotImplementedError
13
+ \.\.\.
@@ -0,0 +1,59 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ env:
10
+ NO_COLOR: "1"
11
+ _TYPER_FORCE_DISABLE_TERMINAL: "1"
12
+
13
+ jobs:
14
+ test:
15
+ runs-on: ubuntu-latest
16
+ strategy:
17
+ matrix:
18
+ python-version: ["3.11", "3.12", "3.13"]
19
+
20
+ steps:
21
+ - uses: actions/checkout@v4
22
+
23
+ - uses: astral-sh/setup-uv@v5
24
+ with:
25
+ enable-cache: true
26
+
27
+ - name: Set up Python ${{ matrix.python-version }}
28
+ run: uv python install ${{ matrix.python-version }}
29
+
30
+ - name: Install dependencies
31
+ run: uv sync --extra dev --extra interactive
32
+
33
+ - name: Lint
34
+ run: uv run ruff check .
35
+
36
+ - name: Type check
37
+ run: uv run mypy reeln/
38
+
39
+ - name: Test
40
+ run: uv run python -m pytest tests/ -n auto --cov=reeln --cov-branch --cov-fail-under=100 -m "not integration" -q
41
+
42
+ docs:
43
+ runs-on: ubuntu-latest
44
+
45
+ steps:
46
+ - uses: actions/checkout@v4
47
+
48
+ - uses: astral-sh/setup-uv@v5
49
+ with:
50
+ enable-cache: true
51
+
52
+ - name: Set up Python
53
+ run: uv python install 3.11
54
+
55
+ - name: Install dependencies
56
+ run: uv sync --extra docs
57
+
58
+ - name: Build docs
59
+ run: uv run python -m sphinx -W docs/ docs/_build/html
@@ -0,0 +1,45 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*"
7
+
8
+ env:
9
+ NO_COLOR: "1"
10
+ _TYPER_FORCE_DISABLE_TERMINAL: "1"
11
+
12
+ jobs:
13
+ publish:
14
+ runs-on: ubuntu-latest
15
+ environment: release
16
+ permissions:
17
+ id-token: write
18
+
19
+ steps:
20
+ - uses: actions/checkout@v4
21
+
22
+ - uses: astral-sh/setup-uv@v5
23
+ with:
24
+ enable-cache: true
25
+
26
+ - name: Set up Python
27
+ run: uv python install 3.11
28
+
29
+ - name: Install dependencies
30
+ run: uv sync --extra dev --extra interactive
31
+
32
+ - name: Lint
33
+ run: uv run ruff check .
34
+
35
+ - name: Type check
36
+ run: uv run mypy reeln/
37
+
38
+ - name: Test
39
+ run: uv run python -m pytest tests/ -n auto --cov=reeln --cov-branch --cov-fail-under=100 -m "not integration" -q
40
+
41
+ - name: Build
42
+ run: uv build
43
+
44
+ - name: Publish to PyPI
45
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,52 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.egg-info/
6
+ *.egg
7
+ dist/
8
+ build/
9
+ .venv/
10
+ venv/
11
+ *.whl
12
+
13
+ # Testing / Coverage
14
+ .coverage
15
+ htmlcov/
16
+ .pytest_cache/
17
+ .tox/
18
+
19
+ # Media — prevent accidental video commits
20
+ *.mkv
21
+ *.mp4
22
+ *.mov
23
+ *.avi
24
+ *.webm
25
+ *.ts
26
+
27
+ # Project artifacts
28
+ secrets/
29
+ output/
30
+ .tmp/
31
+
32
+ # Sphinx docs build
33
+ docs/_build/
34
+
35
+ # AI dev docs — dev-only, not tracked
36
+ CLAUDE.md
37
+ AGENTS.md
38
+
39
+ # IDE
40
+ .idea/
41
+ .vscode/
42
+ *.swp
43
+ *.swo
44
+ *~
45
+
46
+ # OS
47
+ .DS_Store
48
+ Thumbs.db
49
+
50
+ # Environment
51
+ .env
52
+ .env.*
@@ -0,0 +1,18 @@
1
+ # Read the Docs configuration file
2
+ # See https://docs.readthedocs.io/en/stable/config-file/v2.html
3
+
4
+ version: 2
5
+
6
+ build:
7
+ os: ubuntu-22.04
8
+ tools:
9
+ python: "3.11"
10
+
11
+ sphinx:
12
+ configuration: docs/conf.py
13
+
14
+ python:
15
+ install:
16
+ - requirements: docs/requirements.txt
17
+ - method: pip
18
+ path: .
@@ -0,0 +1,105 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [0.0.23] - 2026-03-03
11
+
12
+ First feature-complete release of reeln — platform-agnostic CLI toolkit for livestreamers.
13
+
14
+ ### Added
15
+
16
+ #### CLI Commands
17
+ - `reeln --version` — show version, ffmpeg info, and installed plugin versions
18
+ - `reeln doctor` — comprehensive health check: ffmpeg, codecs, hardware acceleration, config, permissions
19
+ - `reeln config show` — display current configuration as JSON
20
+ - `reeln config doctor` — validate config, warn on issues
21
+ - `reeln game init` — initialize game workspace with sport-specific segment subdirectories
22
+ - `reeln game segment <N>` — merge replays in a segment directory into a highlight video
23
+ - `reeln game highlights` — merge all segment highlights into a full-game highlight reel
24
+ - `reeln game finish` — mark a game as finished with summary
25
+ - `reeln game prune` — remove generated artifacts from a finished game directory
26
+ - `reeln game event list` — list events with filters (`--segment`, `--type`, `--untagged`)
27
+ - `reeln game event tag` — tag an event with type, player, and metadata
28
+ - `reeln game event tag-all` — bulk-tag all events in a segment
29
+ - `reeln game compile` — compile raw event clips into a single video by criteria
30
+ - `reeln render short` — render a 9:16 short from a clip
31
+ - `reeln render preview` — fast low-res preview render
32
+ - `reeln render apply` — apply a named render profile to a clip (full-frame, no crop/scale)
33
+ - `reeln render reel` — assemble rendered shorts into a concatenated reel
34
+ - `reeln media prune` — scan and prune all finished game directories
35
+ - `reeln plugins list` — list installed plugins with version info
36
+ - `reeln plugins search` — search the plugin registry
37
+ - `reeln plugins info <name>` — show detailed plugin information
38
+ - `reeln plugins install <name>` — install a plugin from the registry with auto-enable
39
+ - `reeln plugins update [name]` — update a plugin or all installed plugins
40
+ - `reeln plugins enable <name>` / `reeln plugins disable <name>` — enable/disable plugins
41
+
42
+ #### Core Features
43
+ - Package skeleton: `pyproject.toml`, Makefile, `.coveragerc`, `pytest.ini`, `python -m reeln` support
44
+ - Structured logging module with JSON and human formatters
45
+ - Error hierarchy: `ReelnError` base with typed subclasses
46
+ - FFmpeg discovery with cross-platform support (PATH, brew, apt, choco), version checking (5.0+ minimum)
47
+ - Media probe helpers: duration, fps, resolution via ffprobe
48
+ - Deterministic ffmpeg command builders (concat, render) with golden test assertions
49
+ - `FFmpegRenderer` implementation with `render()` and `preview()` methods
50
+ - Config system: JSON loading, schema validation, `config_version`, XDG-compliant paths, env var overrides (`REELN_<SECTION>_<KEY>`), deep merge, atomic writes, named profiles
51
+ - Segment model: generic time division abstraction with sport alias registry (hockey, basketball, soccer, football, baseball, lacrosse, generic) and custom sport registration
52
+ - Game lifecycle: `GameInfo`, `GameState`, `GameEvent` models with JSON serialization, double-header auto-detection, `game.json` state tracking
53
+ - `GameEvent` model for first-class event tracking with UUID-based IDs, prefix matching, extensible metadata, and idempotent creation
54
+ - Render state tracking in `game.json` via `RenderEntry` with event auto-linking
55
+ - ShortConfig model with crop modes (pad, crop), output formats (vertical, square), anchor positions
56
+ - Filter graph builders: scale, pad, crop, speed, LUT, subtitle — composable and golden-tested
57
+ - Render profiles: named configuration sets for reusable rendering parameter overrides (speed, LUT, subtitle template, encoding)
58
+ - Multi-iteration rendering: run a clip through N render profiles sequentially and concatenate results
59
+ - Template engine: `{{key}}` placeholder substitution for `.ass` subtitle files
60
+ - `TemplateContext`, `TemplateProvider` protocol, `build_base_context()` for game/event context
61
+ - ASS subtitle helpers: `rgb_to_ass()`, `format_ass_time()`
62
+ - Bundled `goal_overlay` ASS subtitle template with dynamic font sizing and team-colored background
63
+ - `builtin:` prefix for `subtitle_template` in render profiles (e.g. `"builtin:goal_overlay"`)
64
+ - `build_overlay_context()` for computing overlay-specific template variables from event metadata
65
+ - `--player` and `--assists` CLI flags on `render short`, `render preview`, and `render apply` — populate overlay template variables without game event tagging; override event data when both are present
66
+ - Default `player-overlay` render profile and `goal` iteration mapping in bundled config
67
+ - `TeamProfile` model with metadata (logo, roster, colors, jersey colors, period length)
68
+ - Team profile management: load, save, list, delete with atomic writes
69
+ - Interactive team selection and game time prompting in `game init`
70
+ - `--game-time`, `--level`, `--period-length`, `--venue` options on `game init`
71
+ - `--debug` flag on game and render commands — writes pipeline debug artifacts with ffmpeg commands, filter chains, and metadata
72
+ - HTML debug index (`debug/index.html`) with summary table and per-operation sections
73
+ - `--dry-run` support across all destructive and render commands
74
+ - `PruneResult` model, `format_bytes()`, `find_game_dirs()` helpers
75
+ - `CompilationResult` model for compilation output tracking
76
+ - `questionary` as optional dependency (`pip install reeln[interactive]`)
77
+
78
+ #### Plugin System
79
+ - Plugin system foundation: lifecycle hooks, capability protocols, hook registry
80
+ - `Hook` enum with 11 lifecycle hooks: `PRE_RENDER`, `POST_RENDER`, `ON_CLIP_AVAILABLE`, `ON_EVENT_CREATED`, `ON_EVENT_TAGGED`, `ON_GAME_INIT`, `ON_GAME_FINISH`, `ON_HIGHLIGHTS_MERGED`, `ON_ERROR`, `ON_SEGMENT_START`, `ON_SEGMENT_COMPLETE`
81
+ - `HookRegistry` with safe emission — handler exceptions are caught and logged
82
+ - Capability protocols: `Uploader`, `MetadataEnricher`, `Notifier`, `Generator`
83
+ - Plugin orchestrator: sequential pipeline (Generator -> MetadataEnricher -> Uploader -> Notifier)
84
+ - Plugin loader: `discover_plugins()`, `load_plugin()`, `load_enabled_plugins()`, `activate_plugins()`
85
+ - Plugin config schema declaration with `ConfigField` and `PluginConfigSchema`
86
+ - Remote plugin registry with cache, search, install, update, and auto-enable
87
+ - `author` and `license` fields on plugin registry entries
88
+ - `ThrottledReader` for upload throughput limiting, `upload_lock()` for serialization
89
+ - `filelock>=3.0` dependency
90
+
91
+ #### CI/CD & Docs
92
+ - GitHub Actions CI workflow (Python 3.11/3.12/3.13 matrix, lint, type check, tests, docs build)
93
+ - GitHub Actions release workflow (tag-based PyPI publish via trusted publisher)
94
+ - CI and docs badges in README
95
+ - Documentation infrastructure: Sphinx + MyST, Furo theme, Read the Docs config
96
+ - Full docs site: install guide, quickstart tutorial, CLI reference, configuration guide, sports guide
97
+
98
+ ### Fixed
99
+ - `render short --render-profile` now correctly resolves `subtitle_template` from the profile — previously the template was silently dropped in the single-profile path
100
+
101
+ ### Changed
102
+ - `--rink` CLI flag renamed to `--venue` for sport-agnostic terminology
103
+ - Segment merge and highlights merge output written to `paths.output_dir` for discoverability
104
+ - `period_length` moved from `TeamProfile` to `GameInfo`
105
+ - Full test suite with 100% line + branch coverage