#!/usr/bin/env python3 """ Reformat ∆•MIX FLAC filenames and metadata titles. Filename changes: ∆•MIX13.flac → ∆•MIX_013.flac ∆•MIX74 (07-04 Mix).flac → ∆•MIX_074_(07-04_Mix).flac ∆•MIX (Ponies @ Dawn Fusion Mix).flac → ∆•MIX_(Ponies_@_Dawn_Fusion_Mix).flac ∆•MIXΩ (PVFM 13th Birthday).flac → ∆•MIXΩ_(PVFM_13th_Birthday).flac ∆•RYZ • SPEEDWAGON B2B.flac → ∆•RYZ_•_SPEEDWAGON_B2B.flac Metadata title changes (same as mp3 script): ∆•MIX99 → ∆•MIX 099 Usage: python3 reformat_mixes_flac.py /path/to/FLAC/folder python3 reformat_mixes_flac.py /path/to/FLAC/folder --dry-run """ import os import re import sys from pathlib import Path try: from mutagen.flac import FLAC except ImportError: print("Missing dependency. Install with: pip install mutagen") sys.exit(1) MIX_NUMBER_RE = re.compile(r'([∆Δ]•MIX)(\d+)(.*)', re.DOTALL) def transform_title(title: str) -> str: """∆•MIX99 → ∆•MIX 099""" m = MIX_NUMBER_RE.match(title) if not m: return title return f"{m.group(1)} {int(m.group(2)):03d}{m.group(3)}" KEEP_AS_IS = {'∆•RYZ • SPEEDWAGON B2B', 'Δ•RYZ • SPEEDWAGON B2B'} def transform_filename(name: str) -> str: """ 1. Replace spaces with underscores in the stem (except excluded files). 2. Insert underscore + zero-pad number where present. """ stem, ext = os.path.splitext(name) # Files explicitly excluded from space replacement if stem in KEEP_AS_IS: return name # Step 1: spaces → underscores stem = stem.replace(' ', '_') # Step 2: zero-pad number (∆•MIX13 → ∆•MIX_013) m = MIX_NUMBER_RE.match(stem) if m: stem = f"{m.group(1)}_{int(m.group(2)):03d}{m.group(3)}" return stem + ext def process(directory: str, dry_run: bool = False): folder = Path(directory) flac_files = sorted(folder.glob('*.flac')) if not flac_files: print(f"No .flac files found in {folder}") return rename_queue = [] for path in flac_files: print(f"\n{path.name}") # --- metadata --- try: audio = FLAC(str(path)) old_title = audio['title'][0] if 'title' in audio else None new_title = transform_title(old_title) if old_title else None if new_title and new_title != old_title: print(f" title: {old_title!r} → {new_title!r}") if not dry_run: audio['title'] = new_title audio.save() else: print(f" title: {old_title!r} (no change)") except Exception as e: print(f" ERROR reading metadata: {e}") # --- filename --- new_name = transform_filename(path.name) if new_name != path.name: print(f" file: {path.name} → {new_name}") if not dry_run: rename_queue.append((path, path.parent / new_name)) else: print(f" file: {path.name} (no change)") for old, new in rename_queue: old.rename(new) renamed = len(rename_queue) if dry_run: print(f"\n[dry run] would rename {renamed} files. Run without --dry-run to apply.") else: print(f"\nDone. {renamed} files renamed.") if __name__ == '__main__': args = sys.argv[1:] dry = '--dry-run' in args args = [a for a in args if a != '--dry-run'] directory = args[0] if args else '.' process(directory, dry_run=dry)