Skip to content

Commit

Permalink
implement albums vfs
Browse files Browse the repository at this point in the history
  • Loading branch information
azuline committed Oct 10, 2023
1 parent cddd03d commit cb56571
Show file tree
Hide file tree
Showing 8 changed files with 356 additions and 71 deletions.
5 changes: 4 additions & 1 deletion migrations/20231009_01_qlEHa-bootstrap.sql
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ INSERT INTO release_type_enum (value) VALUES
CREATE TABLE releases (
id TEXT PRIMARY KEY,
source_path TEXT NOT NULL UNIQUE,
virtual_dirname TEXT NOT NULL UNIQUE,
title TEXT NOT NULL,
release_type TEXT NOT NULL REFERENCES release_type_enum(value),
release_year INTEGER,
Expand All @@ -43,11 +44,13 @@ CREATE INDEX releases_labels_label ON releases_labels(label);
CREATE TABLE tracks (
id TEXT PRIMARY KEY,
source_path TEXT NOT NULL UNIQUE,
virtual_filename TEXT NOT NULL,
title TEXT NOT NULL,
release_id TEXT NOT NULL REFERENCES releases(id),
track_number TEXT NOT NULL,
disc_number TEXT NOT NULL,
duration_seconds INTEGER NOT NULL
duration_seconds INTEGER NOT NULL,
UNIQUE (release_id, virtual_filename)
);
CREATE INDEX tracks_source_path ON tracks(source_path);
CREATE INDEX tracks_release_id ON tracks(release_id);
Expand Down
3 changes: 3 additions & 0 deletions rose/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,6 @@
stream_handler = logging.StreamHandler(sys.stdout)
stream_handler.setFormatter(stream_formatter)
logger.addHandler(stream_handler)
file_handler = logging.FileHandler("/home/blissful/rose.log")
file_handler.setFormatter(stream_formatter)
logger.addHandler(file_handler)
36 changes: 36 additions & 0 deletions rose/cache/dataclasses.py
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]
66 changes: 66 additions & 0 deletions rose/cache/read.py
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,
)
80 changes: 80 additions & 0 deletions rose/cache/read_test.py
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"),
],
),
]
Loading

0 comments on commit cb56571

Please sign in to comment.