paces 0.0.4__tar.gz → 0.0.5__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 (31) hide show
  1. {paces-0.0.4 → paces-0.0.5}/PKG-INFO +13 -2
  2. {paces-0.0.4 → paces-0.0.5}/README.md +9 -0
  3. {paces-0.0.4 → paces-0.0.5}/paces/__init__.py +19 -0
  4. paces-0.0.5/paces/derivation.py +957 -0
  5. {paces-0.0.4 → paces-0.0.5}/paces/model.py +12 -1
  6. {paces-0.0.4 → paces-0.0.5}/paces/render.py +42 -1
  7. {paces-0.0.4 → paces-0.0.5}/paces/tools.py +118 -1
  8. {paces-0.0.4 → paces-0.0.5}/pyproject.toml +12 -2
  9. paces-0.0.5/tests/test_derivation.py +938 -0
  10. paces-0.0.5/tests/test_render_media.py +132 -0
  11. paces-0.0.5/tests/video_synth.py +32 -0
  12. {paces-0.0.4 → paces-0.0.5}/.gitignore +0 -0
  13. {paces-0.0.4 → paces-0.0.5}/LICENSE +0 -0
  14. {paces-0.0.4 → paces-0.0.5}/docs/README.md +0 -0
  15. {paces-0.0.4 → paces-0.0.5}/docs/alignment/README.md +0 -0
  16. {paces-0.0.4 → paces-0.0.5}/docs/poc-reference/README.md +0 -0
  17. {paces-0.0.4 → paces-0.0.5}/docs/poc-reference/artifacts/clips.json +0 -0
  18. {paces-0.0.4 → paces-0.0.5}/paces/__main__.py +0 -0
  19. {paces-0.0.4 → paces-0.0.5}/paces/edits.py +0 -0
  20. {paces-0.0.4 → paces-0.0.5}/paces/measure.py +0 -0
  21. {paces-0.0.4 → paces-0.0.5}/paces/projection.py +0 -0
  22. {paces-0.0.4 → paces-0.0.5}/paces/segmenters.py +0 -0
  23. {paces-0.0.4 → paces-0.0.5}/tests/audio_synth.py +0 -0
  24. {paces-0.0.4 → paces-0.0.5}/tests/data/routine.json +0 -0
  25. {paces-0.0.4 → paces-0.0.5}/tests/poc_fixture.py +0 -0
  26. {paces-0.0.4 → paces-0.0.5}/tests/test_chapters.py +0 -0
  27. {paces-0.0.4 → paces-0.0.5}/tests/test_edits.py +0 -0
  28. {paces-0.0.4 → paces-0.0.5}/tests/test_measure.py +0 -0
  29. {paces-0.0.4 → paces-0.0.5}/tests/test_roundtrip_poc.py +0 -0
  30. {paces-0.0.4 → paces-0.0.5}/tests/test_segment.py +0 -0
  31. {paces-0.0.4 → paces-0.0.5}/tests/test_smoke.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: paces
3
- Version: 0.0.4
3
+ Version: 0.0.5
4
4
  Summary: Turn instructional media into structured, interactive learning material
5
5
  Project-URL: Homepage, https://github.com/thorwhalen/paces
6
6
  Project-URL: Repository, https://github.com/thorwhalen/paces
@@ -20,7 +20,7 @@ Requires-Dist: argcomplete>=3; extra == 'cli'
20
20
  Requires-Dist: argh>=0.30; extra == 'cli'
21
21
  Provides-Extra: dev
22
22
  Requires-Dist: argh>=0.30; extra == 'dev'
23
- Requires-Dist: mixing[audio,beats]>=0.0.36; extra == 'dev'
23
+ Requires-Dist: mixing[audio,beats]>=0.0.39; extra == 'dev'
24
24
  Requires-Dist: numba>=0.59; extra == 'dev'
25
25
  Requires-Dist: pytest-cov>=4.0; extra == 'dev'
26
26
  Requires-Dist: pytest>=7.0; extra == 'dev'
@@ -28,6 +28,8 @@ Requires-Dist: ruff>=0.1.0; extra == 'dev'
28
28
  Provides-Extra: docs
29
29
  Requires-Dist: sphinx-rtd-theme>=1.0; extra == 'docs'
30
30
  Requires-Dist: sphinx>=6.0; extra == 'docs'
31
+ Provides-Extra: media
32
+ Requires-Dist: mixing>=0.0.39; extra == 'media'
31
33
  Description-Content-Type: text/markdown
32
34
 
33
35
  # paces
@@ -79,9 +81,17 @@ Same thing from the shell:
79
81
  ```bash
80
82
  paces segment VIDEO_URL --steps steps.json --grid grid.json --output seg.json
81
83
  paces to-document seg.json --source VIDEO_URL --title "My routine" --output document.json
84
+ paces derive document.json --media routine.mp4 # real loop clips + gifs + posters
82
85
  paces render document.json --output page.html
83
86
  ```
84
87
 
88
+ `derive` (`pip install paces[media]`) cuts a loopable mp4, a palette-quality
89
+ gif and a poster for every excerpt-bearing span, writes them to `media/` next
90
+ to the document, and the practice page embeds them as looping clips. Crop
91
+ recipes persist in a hand-overridable `document.recipes.json` sidecar; the
92
+ `subject_locator=` seam (default: no crop) is where pose-based auto-crop
93
+ plugs in. Design record: `docs/adr/0005-media-derivation.md`.
94
+
85
95
  ## How it thinks
86
96
 
87
97
  **Analysis and rendering are separate phases** with a serialisable document
@@ -111,6 +121,7 @@ content (`OpenQuestion`), and human edits are protected from regeneration
111
121
  | measure the grid from the media | `segment(local_media, steps=[(name, counts), ...])` — no grid needed; tempo + structure measured, origin estimated and flagged (`pip install paces[audio]`) |
112
122
  | protect edits from regeneration | `apply_edits(doc, patches, by="user:you")` + `merge_regenerated(committed, fresh)` |
113
123
  | the committed artifact | `to_document(seg, ...)` → `StepDocument` |
124
+ | real clips/gifs/posters for the page | `derive_document(doc, media=..., doc_path=...)` / `paces derive` (`pip install paces[media]`) |
114
125
  | a practice page | `render_html(doc)` |
115
126
  | wall-clock times from counts | `resolve(doc)` |
116
127
  | sanity checks | `validate_document(doc)` |
@@ -47,9 +47,17 @@ Same thing from the shell:
47
47
  ```bash
48
48
  paces segment VIDEO_URL --steps steps.json --grid grid.json --output seg.json
49
49
  paces to-document seg.json --source VIDEO_URL --title "My routine" --output document.json
50
+ paces derive document.json --media routine.mp4 # real loop clips + gifs + posters
50
51
  paces render document.json --output page.html
51
52
  ```
52
53
 
54
+ `derive` (`pip install paces[media]`) cuts a loopable mp4, a palette-quality
55
+ gif and a poster for every excerpt-bearing span, writes them to `media/` next
56
+ to the document, and the practice page embeds them as looping clips. Crop
57
+ recipes persist in a hand-overridable `document.recipes.json` sidecar; the
58
+ `subject_locator=` seam (default: no crop) is where pose-based auto-crop
59
+ plugs in. Design record: `docs/adr/0005-media-derivation.md`.
60
+
53
61
  ## How it thinks
54
62
 
55
63
  **Analysis and rendering are separate phases** with a serialisable document
@@ -79,6 +87,7 @@ content (`OpenQuestion`), and human edits are protected from regeneration
79
87
  | measure the grid from the media | `segment(local_media, steps=[(name, counts), ...])` — no grid needed; tempo + structure measured, origin estimated and flagged (`pip install paces[audio]`) |
80
88
  | protect edits from regeneration | `apply_edits(doc, patches, by="user:you")` + `merge_regenerated(committed, fresh)` |
81
89
  | the committed artifact | `to_document(seg, ...)` → `StepDocument` |
90
+ | real clips/gifs/posters for the page | `derive_document(doc, media=..., doc_path=...)` / `paces derive` (`pip install paces[media]`) |
82
91
  | a practice page | `render_html(doc)` |
83
92
  | wall-clock times from counts | `resolve(doc)` |
84
93
  | sanity checks | `validate_document(doc)` |
@@ -48,6 +48,16 @@ from paces.model import (
48
48
  seconds_per_unit,
49
49
  validate_document,
50
50
  )
51
+ from paces.derivation import (
52
+ DeriveResult,
53
+ DirStore,
54
+ LocateQuery,
55
+ SubjectObservation,
56
+ check_media_requirements,
57
+ derive_document,
58
+ full_frame,
59
+ resolve_crop_box,
60
+ )
51
61
  from paces.edits import apply_edits, merge_regenerated
52
62
  from paces.measure import GridMeasurement, measure_grid
53
63
  from paces.projection import to_document
@@ -91,6 +101,15 @@ __all__ = [
91
101
  "measure_grid",
92
102
  "GridMeasurement",
93
103
  "to_document",
104
+ # media derivation (issue #1, ADR-0005)
105
+ "derive_document",
106
+ "DeriveResult",
107
+ "DirStore",
108
+ "LocateQuery",
109
+ "SubjectObservation",
110
+ "full_frame",
111
+ "resolve_crop_box",
112
+ "check_media_requirements",
94
113
  # editing & regeneration
95
114
  "apply_edits",
96
115
  "merge_regenerated",