Regenerate M3U playlist after rename with correct order and durations
_update_m3u(): writes #EXTM3U + #EXTINF:seconds,Artist - Title + filename per track, in disc/track order (same order as the renamed files). Duration is read from mutagen; -1 if unavailable. execute_album(): after renaming, finds existing *.m3u / *.m3u8 in the album directory and overwrites it. Only triggered when files_renamed > 0 and a playlist file exists — never creates a new one from scratch. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
40a2ef3fb6
commit
888464b4d0
1 changed files with 40 additions and 0 deletions
40
executor.py
40
executor.py
|
|
@ -206,6 +206,33 @@ def write_tags(path: Path, proposal: TrackProposal, album_proposal: AlbumProposa
|
|||
return False
|
||||
|
||||
|
||||
def _update_m3u(m3u_path: Path, tracks: List[tuple]) -> bool:
|
||||
"""
|
||||
Schreibt M3U neu mit den umbenannten Dateien in Track-Reihenfolge.
|
||||
tracks: [(TrackProposal, actual_path_after_rename), ...]
|
||||
"""
|
||||
try:
|
||||
lines = ["#EXTM3U"]
|
||||
for tp, track_path in tracks:
|
||||
duration = -1
|
||||
if HAS_MUTAGEN:
|
||||
try:
|
||||
audio = MutagenFile(str(track_path))
|
||||
if audio and hasattr(audio, "info") and audio.info:
|
||||
duration = int(audio.info.length)
|
||||
except Exception:
|
||||
pass
|
||||
label = f"{tp.artist} - {tp.title}" if tp.artist else (tp.title or track_path.stem)
|
||||
lines.append(f"#EXTINF:{duration},{label}")
|
||||
lines.append(track_path.name)
|
||||
m3u_path.write_text("\n".join(lines) + "\n", encoding="utf-8")
|
||||
print(f" 📋 Playlist aktualisiert: {m3u_path.name}")
|
||||
return True
|
||||
except Exception as e:
|
||||
print(f" ⚠️ M3U-Fehler {m3u_path.name}: {e}", file=sys.stderr)
|
||||
return False
|
||||
|
||||
|
||||
def execute_album(
|
||||
proposal: AlbumProposal,
|
||||
backup_dir: Optional[Path],
|
||||
|
|
@ -215,6 +242,7 @@ def execute_album(
|
|||
report_data: List[Dict[str, Any]],
|
||||
) -> Dict[str, int]:
|
||||
stats = {"tags_written": 0, "covers_embedded": 0, "files_renamed": 0, "errors": 0}
|
||||
final_tracks: List[tuple] = [] # (TrackProposal, final_path) für M3U
|
||||
|
||||
for tp in proposal.tracks:
|
||||
old_title = tp.path.stem
|
||||
|
|
@ -263,6 +291,9 @@ def execute_album(
|
|||
print(f" ⚠️ Umbenennungsfehler {tp.path.name}: {e}", file=sys.stderr)
|
||||
stats["errors"] += 1
|
||||
|
||||
if not dry_run:
|
||||
final_tracks.append((tp, new_path))
|
||||
|
||||
report_data.append({
|
||||
"status": "dry-run" if dry_run else "ok",
|
||||
"album_dir": str(proposal.album_dir.name),
|
||||
|
|
@ -284,6 +315,15 @@ def execute_album(
|
|||
"sources": ", ".join(proposal.sources),
|
||||
})
|
||||
|
||||
# M3U-Playlist aktualisieren wenn Dateien umbenannt wurden
|
||||
if do_rename and not dry_run and stats["files_renamed"] > 0 and final_tracks:
|
||||
m3u_files = (
|
||||
list(proposal.album_dir.glob("*.m3u")) +
|
||||
list(proposal.album_dir.glob("*.m3u8"))
|
||||
)
|
||||
if m3u_files:
|
||||
_update_m3u(m3u_files[0], final_tracks)
|
||||
|
||||
# Nach allen Umbenennungen: Verzeichnis Linux-kompatibel bereinigen
|
||||
if do_rename and not dry_run:
|
||||
sanitize_dir_names(proposal.album_dir)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue