Add project skeleton: CLI pipeline for CD digitization

Modular Python package with Typer CLI (scan/apply/process commands),
Pydantic data models, OCR via Tesseract, LLM-based tracklist parsing,
mutagen audio tagging, M3U playlist generation, and cover processing.
Includes 8 passing tests and ruff lint config.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Dieter Schlüter 2026-02-15 00:47:54 +01:00
commit 3e073250ca
17 changed files with 1027 additions and 0 deletions

View file

@ -0,0 +1,57 @@
"""CD-Ripping via abcde."""
from __future__ import annotations
import logging
import subprocess
from pathlib import Path
logger = logging.getLogger(__name__)
def rip_disc(
device: str,
output_dir: Path,
audio_format: str = "flac",
eject: bool = True,
) -> Path:
"""Rippt eine CD mit abcde in output_dir.
Args:
device: CD-Laufwerk, z.B. '/dev/cdrom'
output_dir: Zielverzeichnis für die gerippten Dateien
audio_format: Ausgabeformat (flac, mp3, ogg, opus)
eject: CD nach dem Rippen auswerfen
Returns:
Pfad zum Verzeichnis mit den gerippten Dateien
"""
output_dir.mkdir(parents=True, exist_ok=True)
cmd = [
"abcde",
"-n", # kein CDDB-Lookup
"-N", # non-interaktiv
"-p", # führende Nullen bei Tracknummern
"-o", audio_format,
"-d", device,
"-D", # kein Debug
]
if eject:
cmd.append("-x")
logger.info("Starte Ripping: %s", " ".join(cmd))
result = subprocess.run(
cmd,
cwd=str(output_dir),
capture_output=True,
text=True,
)
if result.returncode != 0:
logger.error("abcde Fehler: %s", result.stderr)
raise RuntimeError(f"abcde fehlgeschlagen (exit {result.returncode}): {result.stderr}")
logger.info("Ripping abgeschlossen: %s", output_dir)
return output_dir