Music_Metadata_Enricher/scanner.py
dschlueter f7cf520dbe Initial implementation of Music Metadata Enricher
AI-powered per-album pipeline: scan → local hints → MusicBrainz/Discogs/Claude
resolve → cover art → interactive or auto review → tag write + rename + report.
All external dependencies optional; 17/17 unit tests passing.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-29 05:42:03 +02:00

59 lines
1.7 KiB
Python

from __future__ import annotations
import sys
from pathlib import Path
from typing import List
from models import AlbumScan, AUDIO_EXTENSIONS, IMAGE_EXTENSIONS, TRACKLIST_EXTENSIONS
def _is_hidden(name: str) -> bool:
return name.startswith(".") or name.startswith("_")
def scan_album(album_dir: Path) -> AlbumScan:
result = AlbumScan(album_dir=album_dir)
for dirpath, dirnames, filenames in album_dir.walk() if hasattr(album_dir, "walk") else _os_walk(album_dir):
dirnames[:] = [d for d in dirnames if not _is_hidden(d)]
current = Path(dirpath) if isinstance(dirpath, str) else dirpath
for name in filenames:
if _is_hidden(name):
continue
p = current / name
ext = p.suffix.lower()
if ext in AUDIO_EXTENSIONS:
result.audio_files.append(p)
elif ext in IMAGE_EXTENSIONS:
result.image_files.append(p)
elif ext in TRACKLIST_EXTENSIONS:
result.tracklist_files.append(p)
else:
result.other_files.append(p)
result.audio_files.sort()
result.image_files.sort()
result.tracklist_files.sort()
return result
def _os_walk(album_dir: Path):
import os
return os.walk(
album_dir,
followlinks=False,
onerror=lambda e: print(f"⚠️ Scan-Fehler: {e}", file=sys.stderr),
)
def collect_album_dirs(root: Path) -> List[Path]:
dirs: List[Path] = []
try:
for item in sorted(root.iterdir()):
if item.is_dir() and not _is_hidden(item.name):
dirs.append(item)
except (PermissionError, OSError) as e:
print(f"⚠️ Lesefehler {root}: {e}", file=sys.stderr)
return dirs