""" fcco-Converter V2 – Metadaten-Modul Hilfsfunktionen für ID3-Tags, Cover-Bilder und Albumname-Generierung. """ import re from datetime import datetime from pathlib import Path from mutagen.easyid3 import EasyID3 from mutagen.id3 import ID3, APIC from .config import WEEKDAY_SHORT_DE def generate_album_name(veranstaltung: str = "") -> str: """Erstellt einen Albumnamen basierend auf dem aktuellen Datum und der Veranstaltung.""" date_str = datetime.now().strftime("%d.%m.%Y") if veranstaltung: return f"{date_str} {veranstaltung}" return date_str def generate_folder_name(date_part: str, veranstaltung: str) -> str: """Erstellt den Ordnernamen für den Export.""" if veranstaltung: return f"{date_part} {veranstaltung}" return date_part def generate_date_part() -> str: """Erstellt das Datumskürzel (z.B. '260719Sa') für die aktuelle Zeit.""" now = datetime.now() return now.strftime("%y%m%d") + WEEKDAY_SHORT_DE[now.weekday()] def extract_event_from_folder(file_path: Path) -> tuple[str, str]: """Versucht, Datum und Veranstaltung aus dem Ordnernamen zu extrahieren. Erwartetes Format: 'YYMMDDWt Veranstaltungsname' z.B. '260406Mo Ostermontag' Returns: (date_part, veranstaltung) oder ("", "") wenn nicht erkannt. """ folder_name = file_path.parent.name if len(folder_name) >= 8 and folder_name[:6].isdigit() and folder_name[6:8] in WEEKDAY_SHORT_DE: date_part = folder_name[:8] veranstaltung = folder_name[8:].strip() if len(folder_name) > 8 else "" return date_part, veranstaltung return "", "" def extract_title_from_filename(filename: str) -> str: """Extrahiert einen sauberen Titel aus dem komplexen Dateinamen-Format. Format-Erwartung: [Prefix]_[Track]_[Type]_[Lang][ Remainder] Beispiele: 260719So_N_10_Predigt_D Vorname Nachname -> "Predigt Vorname Nachname" 260719So_N_04_Lied_D Zum blauen Himmel -> "Zum blauen Himmel" """ # Regulärer Ausdruck, um die Komponenten zu extrahieren match = re.match(r"^.*?_\d+_(?P[a-zA-Z]+)_(?P[a-zA-Z]+)(?: (?P.*))?$", filename) if not match: return filename typ = match.group("type") lang = match.group("lang") remainder = match.group("remainder") or "" typ_lower = typ.lower() if typ_lower in ["predigt", "vorwort", "gedicht"]: if remainder: return f"{typ} {remainder}" return f"{typ} {lang}" elif typ_lower == "lied": if remainder: return remainder return f"{typ} {lang}" elif typ_lower in ["chor", "orchester"]: if remainder: return f"{remainder} ({typ})" return f"{typ} {lang}" else: # Fallback if remainder: return f"{typ} {remainder}" return f"{typ} {lang}" from mutagen.id3 import ID3, APIC, TIT2, TPE1, TALB, TRCK, TDRC def apply_id3_tags( mp3_path: Path, title: str, artist: str, album: str, track_number: int, year: str, cover_data: bytes | None = None, cover_mime: str = "image/jpeg", ) -> None: """Schreibt ID3-Metadaten und optional ein Cover in die MP3-Datei.""" try: tags = ID3(str(mp3_path)) except Exception: tags = ID3() tags.add(TIT2(encoding=3, text=title)) tags.add(TPE1(encoding=3, text=artist or "Unbekannt")) tags.add(TALB(encoding=3, text=album or "Unbekanntes Album")) tags.add(TRCK(encoding=3, text=str(track_number))) if year: tags.add(TDRC(encoding=3, text=year)) if cover_data: tags.add( APIC( encoding=3, mime=cover_mime, type=3, desc="Cover", data=cover_data, ) ) tags.save(str(mp3_path), v2_version=3)