Files
product-vamp/generator/__main__.py
T
khodowany fe42d811fa
ci / checks (push) Successful in 42m54s
Formatting
2026-09-15 00:06:02 -05:00

71 lines
2.9 KiB
Python

from __future__ import annotations
import argparse
import shutil
import tempfile
from pathlib import Path
from generator.arrange.generate import generate_performance_scores
from generator.practice.generate import generate_practice_scores
from generator.score import count_json_files, validate_generated_tree
from generator.summary import validate_expected_performance_summary, validate_practice_variants
from generator.musicxml import load_musicxml
RUNTIME_FONT_FILES = ("Petaluma.otf", "PetalumaScript.otf", "OFL.txt")
def copy_runtime_fonts(static_assets_dir: Path, output_dir: Path) -> None:
source = static_assets_dir / "fonts" / "petaluma"
destination = output_dir / "fonts" / "petaluma"
destination.mkdir(parents=True, exist_ok=True)
for name in RUNTIME_FONT_FILES:
shutil.copy2(source / name, destination / name)
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(description="Generate Product Vamp package score assets.")
parser.add_argument("--data-dir", type=Path, required=True)
parser.add_argument("--output-dir", type=Path, required=True)
parser.add_argument("--static-assets-dir", type=Path, default=Path("package/assets"))
parser.add_argument("--clean", action="store_true")
parser.add_argument("--check", action="store_true")
return parser.parse_args()
def generate_assets(args: argparse.Namespace) -> None:
data_dir = args.data_dir.resolve()
output_dir = args.output_dir.resolve()
static_assets_dir = args.static_assets_dir.resolve()
for source in sorted(data_dir.rglob('*.xml')):
load_musicxml(source)
output_dir.parent.mkdir(parents=True, exist_ok=True)
with tempfile.TemporaryDirectory(prefix='.vamp-assets-', dir=output_dir.parent) as temporary:
staged = Path(temporary) / 'assets'
if not args.clean and output_dir.exists():
shutil.copytree(output_dir, staged)
staged.mkdir(parents=True, exist_ok=True)
copy_runtime_fonts(static_assets_dir, staged)
performance_count = generate_performance_scores(data_dir / 'songs', staged / 'songs')
practice_count = generate_practice_scores(data_dir / 'practice', staged / 'practice')
validate_generated_tree(staged)
if args.check:
validate_expected_performance_summary(data_dir / 'expected' / 'performance_summary.json', staged / 'songs')
validate_practice_variants(staged / 'practice')
backup = Path(temporary) / 'previous'
if output_dir.exists():
output_dir.rename(backup)
try:
staged.rename(output_dir)
except OSError:
if backup.exists():
backup.rename(output_dir)
raise
print(f'Generated Product Vamp assets: {performance_count} performance scores, '
f'{practice_count} practice score variants, {count_json_files(output_dir)} total JSON files.')
if args.check:
print('Generator check passed.')
def main() -> int:
generate_assets(parse_args())
return 0
if __name__ == "__main__":
raise SystemExit(main())