#!/usr/bin/env python3 """Unified entry point for the NCMR songs-videos helper tools. Dispatches to a sibling script, forwards all remaining arguments, and keeps the exit status. Use whichever feels natural — this dispatcher, or the script directly. python3 scripts/tools.py --help python3 scripts/tools.py hwprobe python3 scripts/tools.py tools lrc2srt song.lrc -o song.srt The same thing, called directly: python3 scripts/hwprobe.py """ from __future__ import annotations import os import runpy import sys HERE = os.path.dirname(os.path.abspath(__file__)) #: name -> (module filename, one-line summary) TOOLS: dict[str, tuple[str, str]] = { "hwprobe": ("hwprobe.py", "which ffmpeg encoders this machine can actually use"), "ffmpeg": ("ffmpeg_tools.py", "mux, bake subtitles, build still-image videos, strip audio"), "lrc2srt": ("lrc2srt.py", "convert LRC lyrics to SRT"), "srt2ass": ("srt2ass.py", "convert SRT subtitles to ASS"), "bom": ("bom_gen.py", "generate the untracked-asset bill of materials"), } ALIASES = { "ffmpeg_tools": "ffmpeg", "ffmpeg-tools": "ffmpeg", "bom_gen": "bom", "lrc": "lrc2srt", "srt": "srt2ass", } def usage(stream=sys.stdout) -> None: print("usage: tools.py [options] [-- ]", file=stream) print(" tools.py --help | --list", file=stream) print(file=stream) print("tools:", file=stream) width = max(len(name) for name in TOOLS) for name, (_filename, summary) in TOOLS.items(): print(f" {name.ljust(width)} {summary}", file=stream) print(file=stream) print("Every tool also runs standalone: python3 scripts/.py --help", file=stream) def main(argv: list[str] | None = None) -> int: argv = list(sys.argv[1:] if argv is None else argv) if not argv or argv[0] in ("-h", "--help", "help", "list", "--list"): usage(stream=sys.stderr if not argv else sys.stdout) return 0 if argv else 2 name = ALIASES.get(argv[0], argv[0]) if name not in TOOLS: print(f"tools.py: unknown tool {argv[0]!r}", file=sys.stderr) print(file=sys.stderr) usage(stream=sys.stderr) return 2 filename, _summary = TOOLS[name] path = os.path.join(HERE, filename) if not os.path.isfile(path): print(f"tools.py: {filename} is missing from {HERE}", file=sys.stderr) return 1 remaining = argv[1:] if remaining and remaining[0] == "--": remaining = remaining[1:] sys.argv = [path, *remaining] # run_path gives the child the same process, so its exit code is ours. try: runpy.run_path(path, run_name="__main__") except SystemExit as exc: code = exc.code if code is None: return 0 if isinstance(code, int): return code print(code, file=sys.stderr) return 1 return 0 if __name__ == "__main__": raise SystemExit(main())