Skip to content

Commit

Permalink
add tracks-all
Browse files Browse the repository at this point in the history
  • Loading branch information
azuline committed Nov 7, 2023
1 parent d7c4141 commit ccdfd04
Show file tree
Hide file tree
Showing 5 changed files with 178 additions and 60 deletions.
98 changes: 51 additions & 47 deletions rose/cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -1685,31 +1685,33 @@ def list_releases_delete_this(
return releases


def list_releases(c: Config, release_ids: list[str]) -> list[CachedRelease]:
def list_releases(c: Config, release_ids: list[str] | None = None) -> list[CachedRelease]:
"""Fetch data associated with given release IDs. Pass None to fetch all."""
query = """
SELECT
id
, source_path
, cover_image_path
, added_at
, datafile_mtime
, title
, releasetype
, year
, multidisc
, new
, genres
, labels
, artist_names
, artist_roles
FROM releases_view
"""
args = []
if release_ids is not None:
query += f" WHERE id IN ({','.join(['?']*len(release_ids))})"
args = release_ids
query += " ORDER BY source_path"
with connect(c) as conn:
cursor = conn.execute(
f"""
SELECT
id
, source_path
, cover_image_path
, added_at
, datafile_mtime
, title
, releasetype
, year
, multidisc
, new
, genres
, labels
, artist_names
, artist_roles
FROM releases_view
WHERE id IN ({','.join(['?']*len(release_ids))})
ORDER BY source_path
""",
release_ids,
)
cursor = conn.execute(query, args)
releases: list[CachedRelease] = []
for row in cursor:
releases.append(
Expand Down Expand Up @@ -1870,30 +1872,32 @@ def calculate_release_logtext(
return logtext


def list_tracks(c: Config, track_ids: list[str]) -> list[CachedTrack]:
def list_tracks(c: Config, track_ids: list[str] | None = None) -> list[CachedTrack]:
"""Fetch data associated with given track IDs. Pass None to fetch all."""
query = """
SELECT
t.id
, t.release_id
, t.source_path
, t.source_mtime
, t.title
, t.release_id
, t.tracknumber
, t.discnumber
, t.duration_seconds
, t.artist_names
, t.artist_roles
, r.multidisc
FROM tracks_view t
JOIN releases r ON r.id = t.release_id
"""
args = []
if track_ids is not None:
query += f" WHERE t.id IN ({','.join(['?']*len(track_ids))})"
args = track_ids
query += " ORDER BY r.source_path, FORMAT('%4d.%4d', t.discnumber, t.tracknumber)"
with connect(c) as conn:
cursor = conn.execute(
f"""
SELECT
t.id
, t.release_id
, t.source_path
, t.source_mtime
, t.title
, t.release_id
, t.tracknumber
, t.discnumber
, t.duration_seconds
, t.artist_names
, t.artist_roles
, r.multidisc
FROM tracks_view t
JOIN releases r ON r.id = t.release_id
WHERE t.id IN ({','.join(['?']*len(track_ids))})
ORDER BY r.source_path, FORMAT('%4d.%4d', t.discnumber, t.tracknumber)
""",
track_ids,
)
cursor = conn.execute(query, args)
rval = []
for row in cursor:
rval.append(
Expand Down
35 changes: 32 additions & 3 deletions rose/cache_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -1015,8 +1015,7 @@ def test_update_cache_playlists_on_release_rename(config: Config) -> None:

@pytest.mark.usefixtures("seeded_cache")
def test_list_releases(config: Config) -> None:
releases = list_releases(config, ["r1", "r2", "r3"])
assert releases == [
expected = [
CachedRelease(
datafile_mtime="999",
id="r1",
Expand Down Expand Up @@ -1064,6 +1063,9 @@ def test_list_releases(config: Config) -> None:
),
]

assert list_releases(config) == expected
assert list_releases(config, ["r1"]) == expected[:1]


@pytest.mark.usefixtures("seeded_cache")
def test_get_release_and_associated_tracks(config: Config) -> None:
Expand Down Expand Up @@ -1171,7 +1173,7 @@ def test_get_release_logtext(config: Config) -> None:

@pytest.mark.usefixtures("seeded_cache")
def test_list_tracks(config: Config) -> None:
assert list_tracks(config, ["t1", "t2"]) == [
expected = [
CachedTrack(
id="t1",
source_path=config.music_source_dir / "r1" / "01.m4a",
Expand All @@ -1196,8 +1198,35 @@ def test_list_tracks(config: Config) -> None:
artists=ArtistMapping(main=[Artist("Techno Man"), Artist("Bass Man")]),
release_multidisc=False,
),
CachedTrack(
id="t3",
source_path=config.music_source_dir / "r2" / "01.m4a",
source_mtime="999",
title="Track 1",
release_id="r2",
tracknumber="01",
discnumber="01",
duration_seconds=120,
artists=ArtistMapping(main=[Artist("Violin Woman")], guest=[Artist("Conductor Woman")]),
release_multidisc=False,
),
CachedTrack(
id="t4",
source_path=config.music_source_dir / "r3" / "01.m4a",
source_mtime="999",
title="Track 1",
release_id="r3",
tracknumber="01",
discnumber="01",
duration_seconds=120,
artists=ArtistMapping(),
release_multidisc=False,
),
]

assert list_tracks(config) == expected
assert list_tracks(config, ["t1", "t2"]) == expected[:2]


@pytest.mark.usefixtures("seeded_cache")
def test_get_track(config: Config) -> None:
Expand Down
4 changes: 2 additions & 2 deletions rose/releases.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
calculate_release_logtext,
get_release,
get_tracks_associated_with_release,
list_releases_delete_this,
list_releases,
lock,
release_lock_name,
update_cache_evict_nonexistent_releases,
Expand Down Expand Up @@ -70,7 +70,7 @@ def dump_release(c: Config, release_id: str) -> str:


def dump_releases(c: Config) -> str:
return json.dumps([r.dump() for r in list_releases_delete_this(c)])
return json.dumps([r.dump() for r in list_releases(c)])


def delete_release(c: Config, release_id: str) -> None:
Expand Down
19 changes: 12 additions & 7 deletions rose/tracks.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from rose.audiotags import AudioTags
from rose.cache import (
get_track,
list_tracks,
)
from rose.common import RoseExpectedError
from rose.config import Config
Expand All @@ -23,6 +24,17 @@ class TrackDoesNotExistError(RoseExpectedError):
pass


def dump_track(c: Config, track_id: str) -> str:
track = get_track(c, track_id)
if track is None:
raise TrackDoesNotExistError(f"Track {track_id} does not exist")
return json.dumps(track.dump())


def dump_tracks(c: Config) -> str:
return json.dumps([t.dump() for t in list_tracks(c)])


def run_actions_on_track(
c: Config,
track_id: str,
Expand All @@ -37,10 +49,3 @@ def run_actions_on_track(
raise TrackDoesNotExistError(f"Track {track_id} does not exist")
audiotag = AudioTags.from_file(track.source_path)
execute_metadata_actions(c, actions, [audiotag], dry_run=dry_run, confirm_yes=confirm_yes)


def dump_track(c: Config, track_id: str) -> str:
track = get_track(c, track_id)
if track is None:
raise TrackDoesNotExistError(f"Track {track_id} does not exist")
return json.dumps(track.dump())
82 changes: 81 additions & 1 deletion rose/tracks_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from rose.audiotags import AudioTags
from rose.config import Config
from rose.rule_parser import MetadataAction
from rose.tracks import dump_track, run_actions_on_track
from rose.tracks import dump_track, dump_tracks, run_actions_on_track


def test_run_action_on_track(config: Config, source_dir: Path) -> None:
Expand All @@ -18,6 +18,86 @@ def test_run_action_on_track(config: Config, source_dir: Path) -> None:
assert af.title == "Bop"


@pytest.mark.usefixtures("seeded_cache")
def test_dump_tracks(config: Config) -> None:
assert json.loads(dump_tracks(config)) == [
{
"artists": {
"composer": [],
"djmixer": [],
"guest": [],
"main": [
{"alias": False, "name": "Techno Man"},
{"alias": False, "name": "Bass Man"},
],
"producer": [],
"remixer": [],
},
"discnumber": "01",
"duration_seconds": 120,
"id": "t1",
"release_id": "r1",
"source_path": f"{config.music_source_dir}/r1/01.m4a",
"title": "Track 1",
"tracknumber": "01",
},
{
"artists": {
"composer": [],
"djmixer": [],
"guest": [],
"main": [
{"alias": False, "name": "Techno Man"},
{"alias": False, "name": "Bass Man"},
],
"producer": [],
"remixer": [],
},
"discnumber": "01",
"duration_seconds": 240,
"id": "t2",
"release_id": "r1",
"source_path": f"{config.music_source_dir}/r1/02.m4a",
"title": "Track 2",
"tracknumber": "02",
},
{
"artists": {
"composer": [],
"djmixer": [],
"guest": [{"alias": False, "name": "Conductor Woman"}],
"main": [{"alias": False, "name": "Violin Woman"}],
"producer": [],
"remixer": [],
},
"discnumber": "01",
"duration_seconds": 120,
"id": "t3",
"release_id": "r2",
"source_path": f"{config.music_source_dir}/r2/01.m4a",
"title": "Track 1",
"tracknumber": "01",
},
{
"artists": {
"composer": [],
"djmixer": [],
"guest": [],
"main": [],
"producer": [],
"remixer": [],
},
"discnumber": "01",
"duration_seconds": 120,
"id": "t4",
"release_id": "r3",
"source_path": f"{config.music_source_dir}/r3/01.m4a",
"title": "Track 1",
"tracknumber": "01",
},
]


@pytest.mark.usefixtures("seeded_cache")
def test_dump_track(config: Config) -> None:
assert json.loads(dump_track(config, "t1")) == {
Expand Down

0 comments on commit ccdfd04

Please sign in to comment.