Skip to content

Commit

Permalink
ensure line uniqueness when editing playlists in case of virtual file…
Browse files Browse the repository at this point in the history
…name collision
  • Loading branch information
azuline committed Oct 28, 2023
1 parent 9adb6c1 commit 20b4a30
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 5 deletions.
20 changes: 16 additions & 4 deletions rose/playlists.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import json
import logging
from collections import Counter
from pathlib import Path
from typing import Any

Expand Down Expand Up @@ -145,13 +146,24 @@ def edit_playlist_in_editor(c: Config, playlist_name: str) -> None:
with path.open("rb") as fp:
data = tomllib.load(fp)
raw_tracks = data.get("tracks", [])
edited_track_descriptions = click.edit(
"\n".join([r["description_meta"] for r in raw_tracks])
)

# Because tracks are not globally unique, we append the UUID if there are any conflicts.
# discriminator.
lines_to_edit: list[str] = []
uuid_mapping: dict[str, str] = {}
line_occurrences = Counter([r["description_meta"] for r in raw_tracks])
for r in raw_tracks:
if line_occurrences[r["description_meta"]] > 1:
line = f'{r["description_meta"]} [{r["uuid"]}]'
else:
line = r["description_meta"]
lines_to_edit.append(line)
uuid_mapping[line] = r["uuid"]

edited_track_descriptions = click.edit("\n".join(lines_to_edit))
if edited_track_descriptions is None:
logger.info("Aborting: metadata file not submitted.")
return
uuid_mapping = {r["description_meta"]: r["uuid"] for r in raw_tracks}

edited_tracks: list[dict[str, Any]] = []
for desc in edited_track_descriptions.strip().split("\n"):
Expand Down
41 changes: 40 additions & 1 deletion rose/playlists_test.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import shutil
from pathlib import Path
from typing import Any

import pytest
import tomllib

from rose.cache import connect
from conftest import TEST_RELEASE_1
from rose.cache import connect, update_cache
from rose.config import Config
from rose.playlists import (
add_track_to_playlist,
Expand Down Expand Up @@ -137,3 +139,40 @@ def test_edit_playlists_remove_track(monkeypatch: Any, config: Config, source_di
with filepath.open("rb") as fp:
data = tomllib.load(fp)
assert len(data["tracks"]) == 1


def test_edit_playlists_duplicate_track_name(monkeypatch: Any, config: Config) -> None:
"""
When there are duplicate virtual filenames, we append UUID. Check that it works by asserting on
the seen text and checking that reversing the order works.
"""
# Generate conflicting virtual tracknames by having two copies of a release in the library.
shutil.copytree(TEST_RELEASE_1, config.music_source_dir / "a")
shutil.copytree(TEST_RELEASE_1, config.music_source_dir / "b")
update_cache(config)

with connect(config) as conn:
# Get the first track of each release.
cursor = conn.execute("SELECT id FROM tracks WHERE source_path LIKE '%01.m4a'")
track_ids = [r["id"] for r in cursor]
assert len(track_ids) == 2

create_playlist(config, "You & Me")
for tid in track_ids:
add_track_to_playlist(config, "You & Me", tid)

seen = ""
def editfn(x: str) -> str:
nonlocal seen
seen = x
return "\n".join(reversed(x.split("\n")))

monkeypatch.setattr("rose.playlists.click.edit", editfn)
edit_playlist_in_editor(config, "You & Me")

assert seen == "\n".join([f"BLACKPINK - Track 1.m4a [{tid}]" for tid in track_ids])

with (config.music_source_dir / "!playlists" / "You & Me.toml").open("rb") as fp:
data = tomllib.load(fp)
assert data["tracks"][0]["uuid"] == track_ids[1]
assert data["tracks"][1]["uuid"] == track_ids[0]

0 comments on commit 20b4a30

Please sign in to comment.