-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
356 additions
and
71 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
from dataclasses import dataclass | ||
from pathlib import Path | ||
|
||
|
||
@dataclass | ||
class CachedArtist: | ||
name: str | ||
role: str | ||
|
||
|
||
@dataclass | ||
class CachedRelease: | ||
id: str | ||
source_path: Path | ||
virtual_dirname: str | ||
title: str | ||
release_type: str | ||
release_year: int | None | ||
new: bool | ||
genres: list[str] | ||
labels: list[str] | ||
artists: list[CachedArtist] | ||
|
||
|
||
@dataclass | ||
class CachedTrack: | ||
id: str | ||
source_path: Path | ||
virtual_filename: str | ||
title: str | ||
release_id: str | ||
trackno: str | ||
discno: str | ||
duration_sec: int | ||
|
||
artists: list[CachedArtist] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
from pathlib import Path | ||
from typing import Iterator | ||
|
||
from rose.cache.database import connect | ||
from rose.cache.dataclasses import CachedArtist, CachedRelease | ||
from rose.foundation.conf import Config | ||
|
||
|
||
def list_albums(c: Config) -> Iterator[CachedRelease]: | ||
with connect(c) as conn: | ||
cursor = conn.execute( | ||
r""" | ||
WITH genres AS ( | ||
SELECT | ||
release_id, | ||
GROUP_CONCAT(genre, ' \\ ') AS genres | ||
FROM releases_genres | ||
GROUP BY release_id | ||
), labels AS ( | ||
SELECT | ||
release_id, | ||
GROUP_CONCAT(label, ' \\ ') AS labels | ||
FROM releases_labels | ||
GROUP BY release_id | ||
), artists AS ( | ||
SELECT | ||
release_id, | ||
GROUP_CONCAT(artist, ' \\ ') AS names, | ||
GROUP_CONCAT(role, ' \\ ') AS roles | ||
FROM releases_artists | ||
GROUP BY release_id | ||
) | ||
SELECT | ||
r.id | ||
, r.source_path | ||
, r.virtual_dirname | ||
, r.title | ||
, r.release_type | ||
, r.release_year | ||
, r.new | ||
, COALESCE(g.genres, '') AS genres | ||
, COALESCE(l.labels, '') AS labels | ||
, COALESCE(a.names, '') AS artist_names | ||
, COALESCE(a.roles, '') AS artist_roles | ||
FROM releases r | ||
LEFT JOIN genres g ON g.release_id = r.id | ||
LEFT JOIN labels l ON l.release_id = r.id | ||
LEFT JOIN artists a ON a.release_id = r.id | ||
""" | ||
) | ||
for row in cursor: | ||
artists: list[CachedArtist] = [] | ||
for n, r in zip(row["artist_names"].split(r" \\ "), row["artist_roles"].split(r" \\ ")): | ||
artists.append(CachedArtist(name=n, role=r)) | ||
yield CachedRelease( | ||
id=row["id"], | ||
source_path=Path(row["source_path"]), | ||
virtual_dirname=row["virtual_dirname"], | ||
title=row["title"], | ||
release_type=row["release_type"], | ||
release_year=row["release_year"], | ||
new=bool(row["new"]), | ||
genres=sorted(row["genres"].split(r" \\ ")), | ||
labels=sorted(row["labels"].split(r" \\ ")), | ||
artists=artists, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
from pathlib import Path | ||
|
||
from rose.cache.database import connect | ||
from rose.cache.dataclasses import CachedArtist, CachedRelease | ||
from rose.cache.read import list_albums | ||
from rose.foundation.conf import Config | ||
|
||
|
||
def seed_data(c: Config) -> None: | ||
with connect(c) as conn: | ||
conn.executescript( | ||
"""\ | ||
INSERT INTO releases (id, source_path, title, release_type, release_year, new) | ||
VALUES ('r1', '/tmp/r1', 'Release 1', 'album', 2023, true) | ||
, ('r2', '/tmp/r2', 'Release 2', 'album', 2021, false); | ||
INSERT INTO releases_genres (release_id, genre) | ||
VALUES ('r1', 'Techno') | ||
, ('r1', 'Deep House') | ||
, ('r2', 'Classical'); | ||
INSERT INTO releases_labels (release_id, label) | ||
VALUES ('r1', 'Silk Music') | ||
, ('r2', 'Native State'); | ||
INSERT INTO tracks (id, source_path, title, release_id, track_number, disc_number, duration_seconds) | ||
VALUES ('t1', '/tmp/r1/01.m4a', 'Track 1', 'r1', '01', '01', 120) | ||
, ('t2', '/tmp/r1/02.m4a', 'Track 2', 'r1', '02', '01', 240) | ||
, ('t3', '/tmp/r2/01.m4a', 'Track 1', 'r2', '01', '01', 120); | ||
INSERT INTO releases_artists (release_id, artist, role) | ||
VALUES ('r1', 'Techno Man', 'main') | ||
, ('r1', 'Bass Man', 'main') | ||
, ('r2', 'Violin Woman', 'main') | ||
, ('r2', 'Conductor Woman', 'guest'); | ||
INSERT INTO tracks_artists (track_id, artist, role) | ||
VALUES ('t1', 'Techno Man', 'main') | ||
, ('t1', 'Bass Man', 'main') | ||
, ('t2', 'Techno Man', 'main') | ||
, ('t2', 'Bass Man', 'main') | ||
, ('t3', 'Violin Woman', 'main') | ||
, ('t3', 'Conductor Woman', 'guest'); | ||
""" | ||
) | ||
|
||
|
||
def test_list_albums(config: Config) -> None: | ||
seed_data(config) | ||
albums = list(list_albums(config)) | ||
assert albums == [ | ||
CachedRelease( | ||
id="r1", | ||
source_path=Path("/tmp/r1"), | ||
title="Release 1", | ||
release_type="album", | ||
release_year=2023, | ||
new=True, | ||
genres=["Deep House", "Techno"], | ||
labels=["Silk Music"], | ||
artists=[ | ||
CachedArtist(name="Techno Man", role="main"), | ||
CachedArtist(name="Bass Man", role="main"), | ||
], | ||
), | ||
CachedRelease( | ||
id="r2", | ||
source_path=Path("/tmp/r2"), | ||
title="Release 2", | ||
release_type="album", | ||
release_year=2021, | ||
new=False, | ||
genres=["Classical"], | ||
labels=["Native State"], | ||
artists=[ | ||
CachedArtist(name="Violin Woman", role="main"), | ||
CachedArtist(name="Conductor Woman", role="guest"), | ||
], | ||
), | ||
] |
Oops, something went wrong.