Skip to content

Commit

Permalink
fix getattr for the directories and stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
azuline committed Oct 10, 2023
1 parent 16ecf09 commit c5f10f0
Show file tree
Hide file tree
Showing 4 changed files with 140 additions and 17 deletions.
12 changes: 10 additions & 2 deletions migrations/20231009_01_qlEHa-bootstrap.sql
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,20 @@ CREATE INDEX releases_release_year ON releases(release_year);
CREATE TABLE releases_genres (
release_id TEXT,
genre TEXT,
genre_sanitized TEXT NOT NULL,
PRIMARY KEY (release_id, genre)
);
CREATE INDEX releases_genres_genre ON releases_genres(genre);
CREATE INDEX releases_genres_genre_sanitized ON releases_genres(genre_sanitized);

CREATE TABLE releases_labels (
release_id TEXT,
label TEXT,
label_sanitized TEXT NOT NULL,
PRIMARY KEY (release_id, label)
);
CREATE INDEX releases_labels_label ON releases_labels(label);
CREATE INDEX releases_labels_label_sanitized ON releases_labels(label_sanitized);

CREATE TABLE tracks (
id TEXT PRIMARY KEY,
Expand Down Expand Up @@ -68,20 +72,24 @@ INSERT INTO artist_role_enum (value) VALUES
CREATE TABLE releases_artists (
release_id TEXT REFERENCES releases(id) ON DELETE CASCADE,
artist TEXT,
role TEXT REFERENCES artist_role_enum(value),
artist_sanitized TEXT NOT NULL,
role TEXT REFERENCES artist_role_enum(value) NOT NULL,
PRIMARY KEY (release_id, artist)
);
CREATE INDEX releases_artists_release_id ON releases_artists(release_id);
CREATE INDEX releases_artists_artist ON releases_artists(artist);
CREATE INDEX releases_artists_artist_sanitized ON releases_artists(artist_sanitized);

CREATE TABLE tracks_artists (
track_id TEXT REFERENCES tracks(id) ON DELETE CASCADE,
artist TEXT,
role TEXT REFERENCES artist_role_enum(value),
artist_sanitized TEXT NOT NULL,
role TEXT REFERENCES artist_role_enum(value) NOT NULL,
PRIMARY KEY (track_id, artist)
);
CREATE INDEX tracks_artists_track_id ON tracks_artists(track_id);
CREATE INDEX tracks_artists_artist ON tracks_artists(artist);
CREATE INDEX tracks_artists_artist_sanitized ON tracks_artists(artist_sanitized);

CREATE TABLE collections (
id TEXT PRIMARY KEY,
Expand Down
91 changes: 91 additions & 0 deletions rose/cache/read.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,3 +85,94 @@ def list_labels(c: Config) -> Iterator[str]:
cursor = conn.execute("SELECT DISTINCT label FROM releases_labels")
for row in cursor:
yield row["label"]


def get_release(c: Config, virtual_dirname: str) -> CachedRelease | None:
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
WHERE r.virtual_dirname = ?
""",
(virtual_dirname,),
)
row = cursor.fetchone()
if not row:
return None
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))
return 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=row["genres"].split(r" \\ "),
labels=row["labels"].split(r" \\ "),
artists=artists,
)


def artist_exists(c: Config, artist_sanitized: str) -> bool:
with connect(c) as conn:
cursor = conn.execute(
"SELECT EXISTS(SELECT * FROM releases_artists WHERE artist_sanitized = ?)",
(artist_sanitized,),
)
return bool(cursor.fetchone()[0])


def genre_exists(c: Config, genre_sanitized: str) -> bool:
with connect(c) as conn:
cursor = conn.execute(
"SELECT EXISTS(SELECT * FROM releases_genres WHERE genre_sanitized = ?)",
(genre_sanitized,),
)
return bool(cursor.fetchone()[0])


def label_exists(c: Config, label_sanitized: str) -> bool:
with connect(c) as conn:
cursor = conn.execute(
"SELECT EXISTS(SELECT * FROM releases_labels WHERE label_sanitized = ?)",
(label_sanitized,),
)
return bool(cursor.fetchone()[0])
21 changes: 12 additions & 9 deletions rose/cache/update.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,27 +156,29 @@ def update_cache_for_release(c: Config, release_dir: Path) -> Path:
for genre in release.genres:
conn.execute(
"""
INSERT INTO releases_genres (release_id, genre) VALUES (?, ?)
INSERT INTO releases_genres (release_id, genre, genre_sanitized)
VALUES (?, ?, ?)
ON CONFLICT (release_id, genre) DO NOTHING
""",
(release.id, genre),
(release.id, genre, sanitize_filename(genre)),
)
for label in release.labels:
conn.execute(
"""
INSERT INTO releases_labels (release_id, label) VALUES (?, ?)
INSERT INTO releases_labels (release_id, label, label_sanitized)
VALUES (?, ?, ?)
ON CONFLICT (release_id, label) DO NOTHING
""",
(release.id, label),
(release.id, label, sanitize_filename(label)),
)
for art in release.artists:
conn.execute(
"""
INSERT INTO releases_artists (release_id, artist, role)
VALUES (?, ?, ?)
INSERT INTO releases_artists (release_id, artist, artist_sanitized, role)
VALUES (?, ?, ?, ?)
ON CONFLICT (release_id, artist) DO UPDATE SET role = ?
""",
(release.id, art.name, art.role, art.role),
(release.id, art.name, sanitize_filename(art.name), art.role, art.role),
)

# Now process the track. Release is guaranteed to exist here.
Expand Down Expand Up @@ -249,10 +251,11 @@ def update_cache_for_release(c: Config, release_dir: Path) -> Path:
for art in track.artists:
conn.execute(
"""
INSERT INTO tracks_artists (track_id, artist, role) VALUES (?, ?, ?)
INSERT INTO tracks_artists (track_id, artist, artist_sanitized, role)
VALUES (?, ?, ?, ?)
ON CONFLICT (track_id, artist) DO UPDATE SET role = ?
""",
(track.id, art.name, art.role, art.role),
(track.id, art.name, sanitize_filename(art.name), art.role, art.role),
)

return release_dir
Expand Down
33 changes: 27 additions & 6 deletions rose/virtualfs/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,16 @@

import fuse

from rose.cache.read import list_albums, list_artists, list_genres, list_labels
from rose.cache.read import (
artist_exists,
genre_exists,
get_release,
label_exists,
list_albums,
list_artists,
list_genres,
list_labels,
)
from rose.foundation.conf import Config
from rose.virtualfs.sanitize import sanitize_filename

Expand All @@ -30,23 +39,35 @@ def get_mode_type(path: str) -> Literal["dir", "file", "missing"]:
return "dir"

if path.startswith("/albums"):
if path == "/albums":
if path.count("/") == 1:
return "dir"
return "dir"
if path.count("/") == 2:
release = get_release(self.config, path.split("/")[2])
return "dir" if release else "missing"
return "missing"

if path.startswith("/artists"):
if path == "/artists":
if path.count("/") == 1:
return "dir"
if path.count("/") == 2:
exists = artist_exists(self.config, path.split("/")[2])
return "dir" if exists else "missing"
return "missing"

if path.startswith("/genres"):
if path == "/genres":
if path.count("/") == 1:
return "dir"
if path.count("/") == 2:
exists = genre_exists(self.config, path.split("/")[2])
return "dir" if exists else "missing"
return "missing"

if path.startswith("/labels"):
if path == "/labels":
if path.count("/") == 1:
return "dir"
if path.count("/") == 2:
exists = label_exists(self.config, path.split("/")[2])
return "dir" if exists else "missing"
return "missing"

return "missing"
Expand Down

0 comments on commit c5f10f0

Please sign in to comment.