diff --git a/executor.py b/executor.py index f13c808..3bff22e 100644 --- a/executor.py +++ b/executor.py @@ -36,12 +36,16 @@ def _safe_name(s: str) -> str: return _SAFE_RE.sub("_", s).strip(". ") -def _proposed_filename(proposal: TrackProposal, ext: str) -> str: +def _proposed_filename(proposal: TrackProposal, ext: str, albumartist: str = "") -> str: tn = f"{proposal.track_number:02d}" if proposal.track_number else "00" prefix = f"{proposal.disc_number}-{tn}" if proposal.disc_number and proposal.disc_number > 1 else tn - artist = _safe_name(proposal.artist or "Unknown") + track_artist = _safe_name(proposal.artist or "Unknown") + aa = _safe_name(albumartist) title = _safe_name(proposal.title or "Unknown") - return f"{prefix} - {artist} - {title}{ext}" + # Include albumartist when it differs from track artist (e.g. pianist vs. composer) + if aa and aa.casefold() != track_artist.casefold() and aa.casefold() not in ("various artists", "unknown"): + return f"{prefix} - {aa} - {track_artist} - {title}{ext}" + return f"{prefix} - {track_artist} - {title}{ext}" def backup_file(path: Path, backup_dir: Path) -> bool: @@ -194,7 +198,7 @@ def execute_album( cover_embedded = True if do_rename: - new_name = _proposed_filename(tp, tp.path.suffix) + new_name = _proposed_filename(tp, tp.path.suffix, proposal.albumartist or "") candidate = tp.path.parent / new_name if candidate != tp.path: try: diff --git a/metadata_resolver.py b/metadata_resolver.py index 56a8ccc..bd6b17a 100644 --- a/metadata_resolver.py +++ b/metadata_resolver.py @@ -272,8 +272,8 @@ def _resolve_via_openrouter(hints: AlbumHints, partial: Dict) -> Optional[Dict]: def _claude_resolve(hints: AlbumHints, partial: Dict) -> Optional[Dict]: """ - Reihenfolge: Ollama (lokal, kostenlos) → OpenRouter (günstig) → Claude API. - Ollama wird versucht wenn OLLAMA_HOST erreichbar; kein Key nötig. + Reihenfolge: Ollama (lokal, kostenlos) → OpenRouter (günstig). + Claude API wird bewusst nicht genutzt (zu teuer). """ # 1. Ollama lokal (bevorzugt — kostenlos, RTX 3090) result = _resolve_via_ollama(hints, partial) @@ -286,21 +286,6 @@ def _claude_resolve(hints: AlbumHints, partial: Dict) -> Optional[Dict]: if result: return result - # 3. Claude API als letzter Fallback - if not HAS_ANTHROPIC or not ANTHROPIC_API_KEY: - return None - try: - client = anthropic.Anthropic(api_key=ANTHROPIC_API_KEY) - prompt = _build_resolve_prompt(hints, partial) - message = client.messages.create( - model="claude-haiku-4-5-20251001", - max_tokens=300, - messages=[{"role": "user", "content": prompt}], - ) - text = message.content[0].text.strip() - return _parse_json_response(text) - except Exception as e: - print(f" ⚠️ Claude-API-Fehler: {e}", file=sys.stderr) return None diff --git a/music_enricher.py b/music_enricher.py index aabd5ae..30387cc 100644 --- a/music_enricher.py +++ b/music_enricher.py @@ -96,7 +96,7 @@ def process_album( hints, use_fingerprint=not args.no_fingerprint, use_api=not args.no_api, - use_claude=bool(os.getenv("ANTHROPIC_API_KEY")), + use_claude=not args.no_api, ) # Cover art @@ -235,8 +235,8 @@ def main() -> None: sys.exit(1) print(f"🎵 {len(album_dirs)} Album-Verzeichnisse gefunden.") - if os.getenv("ANTHROPIC_API_KEY"): - print("🤖 Claude API aktiv.") + if os.getenv("OLLAMA_HOST") or True: # Ollama always attempted + print("🤖 LLM-Resolve: Ollama → OpenRouter (kein Claude)") if not args.no_api: print("🔍 MusicBrainz-Lookup aktiv.") if args.dry_run: