Skip to content

Commit

Permalink
support transitive artist aliases (closes #101)
Browse files Browse the repository at this point in the history
  • Loading branch information
azuline committed Apr 26, 2024
1 parent 65dc217 commit fa141c3
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 11 deletions.
35 changes: 28 additions & 7 deletions rose/cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -1824,7 +1824,7 @@ def list_releases_delete_this(
args: list[str | bool] = []
if artist_filter:
artists: list[str] = [artist_filter]
for alias in c.artist_aliases_map.get(artist_filter, []):
for alias in _get_all_artist_aliases(c, artist_filter):
artists.append(alias)
query += f"""
AND EXISTS (
Expand Down Expand Up @@ -2234,7 +2234,7 @@ def list_artists(c: Config) -> list[str]:

def artist_exists(c: Config, artist: str) -> bool:
args: list[str] = [artist]
for alias in c.artist_aliases_map.get(artist, []):
for alias in _get_all_artist_aliases(c, artist):
args.append(alias)
with connect(c) as conn:
cursor = conn.execute(
Expand Down Expand Up @@ -2301,18 +2301,39 @@ def _unpack_artists(
aliases: bool = True,
) -> ArtistMapping:
mapping = ArtistMapping()
seen: set[tuple[str, str]] = set()
for name, role in _unpack(names, roles):
role_artists: list[Artist] = getattr(mapping, role)
role_artists.append(Artist(name=name, alias=False))
seen: set[str] = {name}
if aliases:
for alias in c.artist_aliases_parents_map.get(name, []):
if alias not in seen:
seen.add((name, role))
if not aliases:
continue

# Get all immediate and transitive artist aliases.
unvisited: set[str] = {name}
while unvisited:
cur = unvisited.pop()
for alias in c.artist_aliases_parents_map.get(cur, []):
if (alias, role) not in seen:
role_artists.append(Artist(name=alias, alias=True))
seen.add(alias)
seen.add((alias, role))
unvisited.add(alias)
return mapping


def _get_all_artist_aliases(c: Config, x: str) -> list[str]:
"""Includes transitive aliases."""
aliases: set[str] = set()
unvisited: set[str] = {x}
while unvisited:
cur = unvisited.pop()
if cur in aliases:
continue
aliases.add(cur)
unvisited.update(c.artist_aliases_map.get(cur, []))
return list(aliases)


def _get_parent_genres(genres: list[str]) -> list[str]:
rval: set[str] = set()
for g in genres:
Expand Down
28 changes: 24 additions & 4 deletions rose/cache_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -1252,18 +1252,28 @@ def test_get_release_and_associated_tracks(config: Config) -> None:
def test_get_release_applies_artist_aliases(config: Config) -> None:
config = dataclasses.replace(
config,
artist_aliases_map={"Hype Boy": ["Bass Man"]},
artist_aliases_parents_map={"Bass Man": ["Hype Boy"]},
artist_aliases_map={"Hype Boy": ["Bass Man"], "Bubble Gum": ["Hype Boy"]},
artist_aliases_parents_map={"Bass Man": ["Hype Boy"], "Hype Boy": ["Bubble Gum"]},
)
release = get_release(config, "r1")
assert release is not None
assert release.releaseartists == ArtistMapping(
main=[Artist("Techno Man"), Artist("Bass Man"), Artist("Hype Boy", True)],
main=[
Artist("Techno Man"),
Artist("Bass Man"),
Artist("Hype Boy", True),
Artist("Bubble Gum", True),
],
)
tracks = get_tracks_associated_with_release(config, release)
for t in tracks:
assert t.trackartists == ArtistMapping(
main=[Artist("Techno Man"), Artist("Bass Man"), Artist("Hype Boy", True)],
main=[
Artist("Techno Man"),
Artist("Bass Man"),
Artist("Hype Boy", True),
Artist("Bubble Gum", True),
],
)


Expand Down Expand Up @@ -1805,6 +1815,16 @@ def test_artist_exists_with_alias(config: Config) -> None:
assert artist_exists(config, "Hype Boy")


@pytest.mark.usefixtures("seeded_cache")
def test_artist_exists_with_alias_transient(config: Config) -> None:
config = dataclasses.replace(
config,
artist_aliases_map={"Hype Boy": ["Bass Man"], "Bubble Gum": ["Hype Boy"]},
artist_aliases_parents_map={"Bass Man": ["Hype Boy"], "Hype Boy": ["Bubble Gum"]},
)
assert artist_exists(config, "Bubble Gum")


@pytest.mark.usefixtures("seeded_cache")
def test_genre_exists(config: Config) -> None:
assert genre_exists(config, "Deep House")
Expand Down

0 comments on commit fa141c3

Please sign in to comment.