async def get_track(track_id: int) -> Optional[Response]: """ Returns a track's audio file. :param track_id: The ID of the track to fetch. :reqheader Authorization: An authorization token. :status 200: Audio file exists and is returned. :status 404: Track or audio file does not exist. """ trk = track.from_id(track_id, quart.g.db) if not trk: quart.abort(404) ext = os.path.splitext(trk.filepath)[1] try: resp = await quart.send_file( trk.filepath, attachment_filename=f"track{ext}", cache_timeout=604_800, ) await resp.make_conditional(quart.request.range) return resp except FileNotFoundError: logger.debug(f"Did not find track {id} on disk ({trk.filepath}).") quart.abort(404)
async def test_del_artist_from_track_doesnt_exist( db: Connection, graphql_query, snapshot, ): query = """ mutation { delArtistFromTrack(trackId: 1, artistId: 2, role: FEATURE) { track { ...TrackFields } trackArtist { role artist { ...ArtistFields } } } } """ trk = track.from_id(1, db) assert trk is not None before_artists = track.artists(trk, db) success, data = await graphql_query(query) assert success is True snapshot.assert_match(data) after_artists = track.artists(trk, db) assert before_artists == after_artists
async def test_add_artist_to_track_already_exists( db: Connection, graphql_query, snapshot, ): query = """ mutation { addArtistToTrack(trackId: 1, artistId: 2, role: MAIN) { track { ...TrackFields } trackArtist { role artist { ...ArtistFields } } } } """ trk = track.from_id(1, db) assert trk is not None before_artists = track.artists(trk, db) success, data = await graphql_query(query) assert success is True snapshot.assert_match(data) after_artists = track.artists(trk, db) assert before_artists == after_artists
def delete_playlist_entry( obj: Any, info: GraphQLResolveInfo, id: int, ) -> dict: if ety := pentry.from_id(id, info.context.db): pentry.delete(ety, info.context.db) return { "playlist": playlist.from_id(ety.playlist_id, info.context.db), "track": track.from_id(ety.track_id, info.context.db), }
def resolve_update_track( _, info: GraphQLResolveInfo, id: int, **changes, ) -> track.T: trk = track.from_id(id, info.context.db) if not trk: raise NotFound(f"Track {id} does not exist.") return track.update(trk, info.context.db, **convert_keys_case(changes))
def calculate_track_sha256s(track_ids: list[int]) -> None: """ Calculate a list of track's full SHA256s. """ with database() as conn: for id_ in track_ids: trk = track.from_id(id_, conn) if not trk or trk.sha256: continue track.calculate_track_full_sha256(trk, conn) conn.commit()
def test_handle_track_batch(factory: Factory, db: Connection): filepath1, sum1 = _create_dummy_file_with_hash(factory) trk1 = factory.track(filepath=filepath1, sha256_initial=sum1, conn=db) filepath2, sum2 = _create_dummy_file_with_hash(factory) trk2 = factory.track(filepath=filepath2, sha256_initial=sum2, conn=db) trk3 = factory.track(sha256_initial=b"0" * 32, sha256=b"0" * 32, conn=db) handle_track_batch([trk1, trk2], db) new1 = track.from_id(trk1.id, db) assert new1 is not None assert new1.sha256 == sum1 new2 = track.from_id(trk2.id, db) assert new2 is not None assert new2.sha256 == sum2 new3 = track.from_id(trk3.id, db) assert new3 is not None assert new3.sha256 == trk3.sha256
def resolve_del_artist_from_track( _, info: GraphQLResolveInfo, trackId: int, artistId: int, role: ArtistRole, ) -> dict: trk = track.from_id(trackId, info.context.db) if not trk: raise NotFound("Track does not exist.") trk = track.del_artist(trk, artistId, role, info.context.db) art = artist.from_id(artistId, info.context.db) return {"track": trk, "track_artist": {"role": role, "artist": art}}
def delete_playlist_entries( obj: Any, info: GraphQLResolveInfo, playlistId: int, trackId: int, ) -> dict: for ety in pentry.from_playlist_and_track(playlistId, trackId, info.context.db): pentry.delete(ety, info.context.db) ply = playlist.from_id(playlistId, info.context.db) if not ply: raise NotFound(f"Playlist {playlistId} does not exist.") trk = track.from_id(trackId, info.context.db) if not trk: raise NotFound(f"Track {trackId} does not exist.") return {"playlist": ply, "track": trk}
async def test_update_track_bad_release_id(db: Connection, graphql_query, snapshot): query = """ mutation { updateTrack( id: 2 releaseId: 999 ) { ...TrackFields } } """ success, data = await graphql_query(query) assert success is True snapshot.assert_match(data) trk = track.from_id(2, db) assert trk is not None assert trk.release_id != 999
async def test_del_artist_from_track(db: Connection, graphql_query, snapshot): query = """ mutation { delArtistFromTrack(trackId: 1, artistId: 2, role: MAIN) { track { ...TrackFields } trackArtist { role artist { ...ArtistFields } } } } """ success, data = await graphql_query(query) assert success is True snapshot.assert_match(data) trk = track.from_id(1, db) assert trk is not None assert 2 not in [a["artist"].id for a in track.artists(trk, db)]
async def test_update_track(db: Connection, graphql_query, snapshot): query = """ mutation { updateTrack( id: 2 title: "aa" releaseId: 3 trackNumber: "999" discNumber: "899" ) { ...TrackFields } } """ success, data = await graphql_query(query) assert success is True snapshot.assert_match(data) trk = track.from_id(2, db) assert trk is not None assert trk.title == "aa" assert trk.release_id == 3 assert trk.track_number == "999" assert trk.disc_number == "899"
def resolve_track(obj: Any, info: GraphQLResolveInfo, id: int) -> track.T: if trk := track.from_id(id, info.context.db): return trk