refactor(content): reorganize demo content and add one_to_rule article - #80
refactor(content): reorganize demo content and add one_to_rule article#80Andreas-Garcia wants to merge 26 commits into
Conversation
…vantages over other tools - Introduced a new section comparing AudioMeta with mutagen, eyed3, and mid3v2/vorbiscomment. - Highlighted features such as unified API, merged multi-format read, and CLI integration.
- Updated .gitignore to exclude generated demo outputs from version control, now located under content/articles/. - Revised AGENTS.md and DEMO_INSTALLATION.md to reflect new paths for demo tapes and outputs. - Enhanced demo authoring guidelines in .cursor/rules/demo-tape-authoring.mdc and demo video documentation in .cursor/rules/demo-videos.mdc. - Introduced a new content/articles/README.md to clarify the structure and usage of article-specific demo assets. - Adjusted paths in pyproject.toml and other related documentation to align with the new content organization.
- Deleted obsolete demo files including README.md, sample audio, and demo tapes. - Updated installation script to reflect new paths for demo tapes. - Cleaned up the demo directory structure to enhance organization and clarity.
- Revised the video generation script to reflect changes in the structure and content of the video, including updated dimensions and layout for the intro and content pages. - Adjusted the script to build GIFs for reading and writing metadata, focusing on ID3v2, RIFF, ID3v1, and Vorbis formats. - Updated the accompanying documentation to clarify the new structure of the video, including the transition from a 2x2 grid to a side-by-side panel layout for better comparison of formats.
- Updated the video generation script to ensure all cell GIFs are sourced from tapes, eliminating the use of placeholders. The script now fails early if any required output is missing. - Revised documentation in AGENTS.md, .cursor/rules/demo-tape-authoring.mdc, and .cursor/rules/demo-videos.mdc to clarify the new requirements for demo panels and the structure of the hero video. - Improved README.md to reflect changes in prerequisites and the overall build process, emphasizing the need for all tapes to run successfully for the hero video generation.
Made-with: Cursor
Made-with: Cursor
Made-with: Cursor
- Removed output directory from .gitignore to allow tracking of generated files. - Enhanced error handling in video generation and VHS tape scripts to ensure the virtual environment is activated and dependencies are installed before execution. - Updated metadata key type for DISC_NUMBER to support None values. - Added clear command and sleep intervals in tape scripts for better readability during execution.
- Updated `.gitignore` to explicitly track scripts related to the hero video in `one_to_rule/`. - Changed references in demo scripts and documentation to use `samples/sample.mp3` and `samples/sample.flac` for consistency. - Enhanced README files to clarify the structure and usage of audio files within the article directory. - Removed unnecessary `clear` commands from tape scripts to improve output clarity.
- Introduced `ensure_demo_read_id3v1.py` to create a demo MP3 file with ID3v1 tags. - Added `print_id3v1_tags.py` to extract and display ID3v1 tag information from the generated demo file. - Created `generate_one_to_rule_video.sh` to automate video generation, including GIF creation and side-by-side comparisons for audio metadata. - Implemented `run_demo_side_by_side.sh` and `run_demo_side_by_side_vorbis.sh` for visual comparisons of audio metadata extraction methods. - Added `sync_article_sample_metadata.py` to align audio sample metadata across formats. - Enhanced error handling and documentation in the new scripts for clarity and usability.
- Moved demo-related scripts to a dedicated `scripts/` directory within the `one_to_rule/` article folder for better organization. - Updated paths in scripts and documentation to reflect the new structure, ensuring consistency across references to audio samples and generated outputs. - Enhanced README files to clarify the usage of scripts and the structure of the article directory. - Improved error handling and documentation in the updated scripts for better usability and clarity.
- Updated the output directory structure in the `one_to_rule` article to separate final deliverables and intermediate files into `output/final/` and `output/work/`, respectively. - Modified scripts to reflect the new output paths, ensuring clarity in the generation process for both GIFs and MP4 videos. - Enhanced README documentation to clarify the changes in output organization and usage.
- Updated the `generate_one_to_rule_video.sh` script to allow specifying a custom final filename for the output video. - Adjusted README files to reflect changes in output paths and usage instructions for video generation. - Improved error handling and path management in demo scripts to ensure consistency and clarity across the project.
- Added best practices for video generation to the demo videos documentation, including guidelines for brand text color and immediate regeneration after visual changes. - Updated the `generate_one_to_rule_video.sh` script to improve text color consistency and adjust logo handling for better visual output. - Enhanced error handling for logo file checks and clarified comments in the script for improved usability.
…re .local/ - generate_one_to_rule_video.sh: reduce COMPARISON_FOOTER_DESCEND_PX 44 -> 12 - CHANGELOG.md: add Fixed entry for DISC_NUMBER optional type (int | None) - .gitignore: ignore .local/ (generated PR description scratch files)
…emo-video # Conflicts: # CHANGELOG.md # pyproject.toml
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 51 out of 59 changed files in this pull request and generated 1 comment.
Suppressed comments (5)
content/demo/demos/tapes/audiometa_demo.tape:25
- From
content/demo/demos,cd ../..lands incontent/, not the repo root. This breaks subsequent commands/paths (e.g.audiometa/test/assets/...,content/demo/scripts/...).
content/demo/demos/tapes/audiometa_demo_script.tape:23 - From
content/demo/demos,cd ../..lands incontent/, not the repo root, socat content/demo/scripts/...andpython content/demo/scripts/...will fail.
content/demo/scripts/run_demo_tape.py:36 relis assigned but never used, which will fail linting (unused variable).
content/demo/demos/README.md:10- The README says the tapes run a hidden
cd ../..to reach repo root, but fromcontent/demo/demosthat only reachescontent/. The correct path to repo root iscd ../../...
audiometa/utils/unified_metadata_key.py:82 - Changing
DISC_NUMBERto returnint | Nonefromget_optional_type()will cause downstream code that checksopt is int(e.g. unified metadata field schema construction) to treatdisc_numberas a non-integer. Ifdisc_numberis intended to remain an integer field that may be null, the schema/value-shape logic should be updated accordingly (similar toDISC_TOTAL).
UnifiedMetadataKey.GENRES_NAMES: list[str],
UnifiedMetadataKey.RATING: int | float,
UnifiedMetadataKey.LANGUAGE: str,
UnifiedMetadataKey.RELEASE_DATE: str,
UnifiedMetadataKey.TRACK_NUMBER: str, # Can be int or str
UnifiedMetadataKey.DISC_NUMBER: int | None,
UnifiedMetadataKey.DISC_TOTAL: int | None,
UnifiedMetadataKey.BPM: int,
UnifiedMetadataKey.COMPOSERS: list[str],
| args = parser.parse_args() | ||
|
|
||
| repo_root = Path(__file__).resolve().parent.parent.parent | ||
| articles_dir = repo_root / "content" / "articles" | ||
| if not articles_dir.is_dir(): | ||
| print("Error: content/articles/ not found.", file=sys.stderr) | ||
| sys.exit(1) |
Homebrew's media-info formula moved past the pinned version with no older bottle available, failing the macOS test job's exact-version check unrelated to this PR's content changes.
- Fix DISC_NUMBER field schema regression: get_optional_type() now returns int | None for DISC_NUMBER, which fell through the schema's `is int` check to value_type "string" / optional_value False. DISC_NUMBER now shares DISC_TOTAL's explicit schema branch. - Fix repo_root resolution in run_demo_tape.py (was one .parent short, content/articles/ was never found) and remove unused rel variable. - Fix cd ../.. -> cd ../../.. in both library demo tapes and their README so repo-root-relative paths in the recordings resolve correctly from content/demo/demos. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 54 out of 62 changed files in this pull request and generated no new comments.
Suppressed comments (3)
content/articles/one_to_rule/scripts/generate_one_to_rule_video.sh:102
- The hero-video script hard-requires
assets/logo-round.png, but the article README claimsassets/logo.pngis also acceptable. Sinceassets/logo.pngexists, add a fallback so the build doesn’t fail unnecessarily if only one of the two logo files is present.
AUDIO_META_LOGO_STILL="$REPO_ROOT/assets/logo-round.png"
[[ -f "$AUDIO_META_LOGO_STILL" ]] || {
echo "Error: static logo not found: assets/logo-round.png" >&2
exit 1
}
system-dependencies-demo.toml:16
- The installation instructions mention
bash scripts/install-demo-dependencies-ubuntu.sh, but that script does not exist in this branch. This makes the demo dependency doc misleading for Ubuntu users; point to the canonical Ubuntu instructions instead.
content/articles/one_to_rule/scripts/generate_one_to_rule_video.sh:56 - The comment says the height is scaled to 85%, but the calculation uses 70%. Either the comment or the scaling constant should change; at minimum the comment should match the actual behavior to avoid future layout confusion.
This issue also appears on line 98 of the same file.
# Baseline cell height was 420; overall video height is 15% lower (85% scale).
BASE_CELL_H=420
CELL_H=$((BASE_CELL_H * 70 / 100))
- Add assets/logo.png fallback in generate_one_to_rule_video.sh to match the README's documented behavior; the script previously hard-required logo-round.png only. - Fix stale comment claiming 85% scale when the code computes 70%. - Fix system-dependencies-demo.toml install note pointing at a nonexistent scripts/install-demo-dependencies-ubuntu.sh. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 54 out of 62 changed files in this pull request and generated no new comments.
Suppressed comments (1)
audiometa/utils/unified_metadata_key.py:80
get_optional_type()now returns runtime typing objects likeint | None(forDISC_NUMBER/DISC_TOTAL), but the method signature still advertises a concretetype[...]return. Updating the return annotation toobject(or a dedicated alias for runtime typing objects) avoids implying callers will always receive a class/type object.
UnifiedMetadataKey.TRACK_NUMBER: str, # Can be int or str
UnifiedMetadataKey.DISC_NUMBER: int | None,
UnifiedMetadataKey.DISC_TOTAL: int | None,
Copilot review round 3: the annotation claimed type[int | float | str | list[str]], but the map already returns non-type runtime objects (unions, generic aliases).
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 55 out of 63 changed files in this pull request and generated no new comments.
Suppressed comments (2)
content/demo/scripts/run_demo_tape.py:131
- The
Output ...line rewrite usesre.sub(...)without verifying a replacement occurred. If a tape is missing anOutputdirective (or uses a different casing/format), this will silently leave the tape unchanged and the script may write output somewhere unexpected. Consider usingre.subnand failing fast when no replacement happens.
content/articles/one_to_rule/scripts/print_id3v1_tags.py:27 - Minor output formatting:
Comment:{comment}is missing a space after the colon, unlike the other fields. This looks unintentional and makes the demo output harder to read.
sys.stdout.write(f"Comment:{comment}\n")
- run_demo_tape.py: fail fast if a tape has no Output directive to rewrite - print_id3v1_tags.py: fix missing space after "Comment:" label
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 55 out of 63 changed files in this pull request and generated no new comments.
Suppressed comments (1)
content/articles/one_to_rule/scripts/ensure_demo_read_id3v1.py:10
_strip_id3v2()computes the ID3v2 tag size without masking synchsafe bytes, and doesn’t account for the optional v2.4 footer flag. This can miscompute the slice offset and leave ID3 bytes in the output (or skip too far) for some tags.
def _strip_id3v2(data: bytes) -> bytes:
while len(data) >= 10 and data[:3] == b"ID3":
size = (data[6] << 21) | (data[7] << 14) | (data[8] << 7) | data[9]
data = data[10 + size :]
return data
ensure_demo_read_id3v1.py: mask synchsafe size bytes and account for the optional ID3v2.4 footer when stripping ID3v2 tags.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 55 out of 63 changed files in this pull request and generated no new comments.
Suppressed comments (1)
content/demo/scripts/run_demo_tape.py:122
run_demo_tape.pyis a general article tape runner, but it hard-codes the placeholder token name@@ONE_TO_RULE_ABS@@. This makes it harder to reuse for other articles and couples a shared tool to one specific article name.
|
Closing in favor of 5 focused, stacked PRs — this branch bundled six unrelated concerns (CI pin fix, a real type bug, demo-tooling reorg, doc-only README additions, and a large new content deliverable) which made it hard to review as a whole. Replacements:
Verified the union of the 5 branches' diffs matches this branch's diff against |
Description
Reorganizes demo/content tooling under a single
content/hub and adds the "one to rule them all" article: a hero video comparing audiometa's unified reading against other tools (RIFF, ID3v2, ID3v1, Vorbis), plus side-by-side GIF generation and supporting scripts. Also fixesDISC_NUMBER's optional type to allowNone, matchingDISC_TOTAL.Key changes:
Content restructuring
content/demo/: New hub for library demo docs (docs/), demo-only scripts (scripts/), and shared tapes/output (demos/). Replaces the olddocs/demos/and root-levelscripts/demo_repl.py/scripts/run_demo_tape.py.content/articles/: New home for per-article content, each with its owntapes/,samples/,scripts/, andoutput/(work/for intermediates,final/for deliverables)..gitignore: Reworked to ignore generated GIF/MP4/WAV/FLAC/MP3 output undercontent/**/output/and loose article files, while explicitly tracking article scripts and whitelistedsamples/sample.{mp3,flac,wav}..pre-commit-config.yaml:check-added-large-filesnow also excludescontent/articles/*/samples/, since the whitelisted demo audio (FLAC/WAV) can exceed 10MB.New article: one_to_rule
content/articles/one_to_rule/scripts/generate_one_to_rule_video.shcomposes the intro + four reading comparisons intooutput/final/one_to_rule_them_all.mp4.ensure_demo_read_id3v1.py(builds an ID3v1-only sample),print_id3v1_tags.py(prints tags for the comparison panel),sync_article_sample_metadata.py(aligns tags across sample formats),run_demo_side_by_side.sh/run_demo_side_by_side_vorbis.sh,run_vhs_tape.sh.samples/sample.mp3,samples/sample.flac,samples/sample.wav(same underlying track).assets/logo.mp4(intro logo video).Fix
UnifiedMetadataKeyoptional types:DISC_NUMBERis nowint | None(wasint), so files without a disc number validate consistently withDISC_TOTAL.Docs
README.md: New ecosystem section with portfolio links (themusictree.org, AudioMeta Python project page,the-music-tree-frontend).CHANGELOG.md: Entries for the demo layout move and theDISC_NUMBERfix..cursor/rules/demo-videos.mdc,.cursor/rules/demo-tape-authoring.mdc: Updated for the newcontent/paths.Related Issues
None
Type of Change
Pre-PR Checklist
Code Quality
pre-commit run --all-filesTests
pytestpytest --cov=audiometa --cov-report=term-missing --cov-fail-under=85Documentation
Git Hygiene
Breaking Changes
Breaking Changes Description
N/A —
docs/demos/and root-level demo scripts are moved, not part of the public library API.Testing Instructions
How to Test
bash content/articles/one_to_rule/scripts/generate_one_to_rule_video.sh(requires ffmpeg, ffprobe, metaflac, mid3v2, vhs); confirmcontent/articles/one_to_rule/output/final/one_to_rule_them_all.mp4.python content/demo/scripts/run_demo_tape.py(orvhs content/demo/demos/tapes/audiometa_demo.tape); confirm output undercontent/demo/demos/output/.disc_numbervalidates asNoneinstead of raising.Test Results
(Add after running the steps above.)
Additional Context
Merge branch 'main' into ...commits from being kept in sync over time; the diff againstmainis the net set of changes above.Checklist for Reviewers