Einheitliches Dateinamen-Schema: 01_-_Titel_-_Kuenstler.flac
organizer: Separator vor Titel angleichen (war: 01_Titel_-_K., neu: 01_-_Titel_-_K.) playlist: Glob-Pattern und Fallback auf neues Schema angepasst tests: Assertions aktualisiert Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
bafea5f335
commit
4e6d82a41d
4 changed files with 21 additions and 21 deletions
|
|
@ -132,7 +132,7 @@ def build_mapping(
|
|||
for audio_file, track in zip(audio_files, disc.tracks):
|
||||
safe_title = _sanitize_filename(track.title)
|
||||
safe_artist = _sanitize_filename(track.artist or album.artist)
|
||||
new_name = f"{track.track_number:02d}_{safe_title}_-_{safe_artist}{audio_file.suffix}"
|
||||
new_name = f"{track.track_number:02d}_-_{safe_title}_-_{safe_artist}{audio_file.suffix}"
|
||||
mapping[audio_file] = target_dir / new_name
|
||||
|
||||
return mapping
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ def generate_playlist(album: Album, album_dir: Path) -> Path:
|
|||
for track in disc.tracks:
|
||||
safe_title = _sanitize_filename(track.title)
|
||||
# Audiodatei im Zielverzeichnis finden
|
||||
pattern = f"{track.track_number:02d}_{safe_title}*"
|
||||
pattern = f"{track.track_number:02d}_-_{safe_title}*"
|
||||
if multi_disc:
|
||||
search_dir = album_dir / f"CD{disc.disc_number}"
|
||||
else:
|
||||
|
|
@ -46,7 +46,7 @@ def generate_playlist(album: Album, album_dir: Path) -> Path:
|
|||
filename = matches[0].name
|
||||
else:
|
||||
# Fallback: generischer Name mit .flac
|
||||
filename = f"{track.track_number:02d}_{safe_title}.flac"
|
||||
filename = f"{track.track_number:02d}_-_{safe_title}.flac"
|
||||
logger.warning("Datei nicht gefunden, Fallback: %s", filename)
|
||||
|
||||
lines.append(f"#EXTINF:0,{track.title}")
|
||||
|
|
|
|||
|
|
@ -167,8 +167,8 @@ class TestBuildMapping:
|
|||
mapping = build_mapping(album, tmp_path, tmp_path / "output")
|
||||
|
||||
targets = list(mapping.values())
|
||||
assert targets[0].name == "01_Erster_Song_-_TestArtist.flac"
|
||||
assert targets[1].name == "02_Zweiter_Song_-_TestArtist.flac"
|
||||
assert targets[0].name == "01_-_Erster_Song_-_TestArtist.flac"
|
||||
assert targets[1].name == "02_-_Zweiter_Song_-_TestArtist.flac"
|
||||
# Single-Disc: kein CD1-Unterordner
|
||||
assert "CD1" not in str(targets[0])
|
||||
|
||||
|
|
@ -207,7 +207,7 @@ class TestBuildMapping:
|
|||
# Source and target are in the same directory
|
||||
assert src.parent == tmp_path
|
||||
assert dst.parent == tmp_path
|
||||
assert dst.name == "01_Song_-_Artist.flac"
|
||||
assert dst.name == "01_-_Song_-_Artist.flac"
|
||||
|
||||
def test_track_artist_overrides_album_artist(self, tmp_path: Path) -> None:
|
||||
(tmp_path / "track01.flac").touch()
|
||||
|
|
@ -227,8 +227,8 @@ class TestBuildMapping:
|
|||
)
|
||||
mapping = build_mapping(album, tmp_path, in_place=True)
|
||||
targets = list(mapping.values())
|
||||
assert targets[0].name == "01_Song_A_-_Artist_X.flac"
|
||||
assert targets[1].name == "02_Song_B_-_Various_Artists.flac"
|
||||
assert targets[0].name == "01_-_Song_A_-_Artist_X.flac"
|
||||
assert targets[1].name == "02_-_Song_B_-_Various_Artists.flac"
|
||||
|
||||
def test_output_dir_structure(self, tmp_path: Path) -> None:
|
||||
(tmp_path / "track01.flac").touch()
|
||||
|
|
|
|||
|
|
@ -21,17 +21,17 @@ def test_generate_playlist_single_disc(tmp_path: Path):
|
|||
"""M3U für Single-CD: keine CD-Prefix, korrekte Dateinamen."""
|
||||
album = _make_album(n_tracks=2, n_discs=1)
|
||||
|
||||
# Dummy-Audiodateien mit Künstler-Suffix
|
||||
(tmp_path / "01_Disc1_Song_1_-_Artist.flac").touch()
|
||||
(tmp_path / "02_Disc1_Song_2_-_Artist.flac").touch()
|
||||
# Dummy-Audiodateien im Schema 01_-_Titel_-_Künstler
|
||||
(tmp_path / "01_-_Disc1_Song_1_-_Artist.flac").touch()
|
||||
(tmp_path / "02_-_Disc1_Song_2_-_Artist.flac").touch()
|
||||
|
||||
playlist_path = generate_playlist(album, tmp_path)
|
||||
assert playlist_path.exists()
|
||||
|
||||
content = playlist_path.read_text()
|
||||
assert "#EXTM3U" in content
|
||||
assert "01_Disc1_Song_1_-_Artist.flac" in content
|
||||
assert "02_Disc1_Song_2_-_Artist.flac" in content
|
||||
assert "01_-_Disc1_Song_1_-_Artist.flac" in content
|
||||
assert "02_-_Disc1_Song_2_-_Artist.flac" in content
|
||||
# Kein CD-Prefix bei Single-Disc
|
||||
assert "CD1/" not in content
|
||||
|
||||
|
|
@ -44,16 +44,16 @@ def test_generate_playlist_multi_disc(tmp_path: Path):
|
|||
cd2 = tmp_path / "CD2"
|
||||
cd1.mkdir()
|
||||
cd2.mkdir()
|
||||
(cd1 / "01_Disc1_Song_1_-_Artist.flac").touch()
|
||||
(cd1 / "02_Disc1_Song_2_-_Artist.flac").touch()
|
||||
(cd2 / "01_Disc2_Song_1_-_Artist.flac").touch()
|
||||
(cd2 / "02_Disc2_Song_2_-_Artist.flac").touch()
|
||||
(cd1 / "01_-_Disc1_Song_1_-_Artist.flac").touch()
|
||||
(cd1 / "02_-_Disc1_Song_2_-_Artist.flac").touch()
|
||||
(cd2 / "01_-_Disc2_Song_1_-_Artist.flac").touch()
|
||||
(cd2 / "02_-_Disc2_Song_2_-_Artist.flac").touch()
|
||||
|
||||
playlist_path = generate_playlist(album, tmp_path)
|
||||
content = playlist_path.read_text()
|
||||
|
||||
assert "CD1/01_Disc1_Song_1_-_Artist.flac" in content
|
||||
assert "CD2/01_Disc2_Song_1_-_Artist.flac" in content
|
||||
assert "CD1/01_-_Disc1_Song_1_-_Artist.flac" in content
|
||||
assert "CD2/01_-_Disc2_Song_1_-_Artist.flac" in content
|
||||
|
||||
|
||||
def test_generate_playlist_filename(tmp_path: Path):
|
||||
|
|
@ -79,7 +79,7 @@ def test_generate_playlist_extinf_contains_title(tmp_path: Path):
|
|||
)
|
||||
],
|
||||
)
|
||||
(tmp_path / "01_Für_Elise_-_A.flac").touch()
|
||||
(tmp_path / "01_-_Für_Elise_-_A.flac").touch()
|
||||
playlist_path = generate_playlist(album, tmp_path)
|
||||
content = playlist_path.read_text()
|
||||
assert "#EXTINF:0,Für Elise" in content
|
||||
|
|
@ -95,4 +95,4 @@ def test_generate_playlist_fallback_if_file_missing(tmp_path: Path):
|
|||
# Keine Audiodatei anlegen
|
||||
playlist_path = generate_playlist(album, tmp_path)
|
||||
content = playlist_path.read_text()
|
||||
assert "01_Ghost.flac" in content
|
||||
assert "01_-_Ghost.flac" in content
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue