mirror of
https://github.com/tcsenpai/swingmusic.git
synced 2025-06-06 03:05:35 +00:00
add route to get all tracks in path
+ add routes to save album and artist as a playlist
This commit is contained in:
parent
efb6aae927
commit
655fd8bc22
@ -83,7 +83,7 @@ def get_album_tracks_and_info():
|
||||
album.is_favorite = check_is_fav(albumhash, FavType.album)
|
||||
|
||||
return {
|
||||
"tracks": [track_serializer(t, retain_disc=True) for t in tracks],
|
||||
"tracks": [track_serializer(t, remove_disc=False) for t in tracks],
|
||||
"info": album,
|
||||
}
|
||||
|
||||
@ -210,3 +210,5 @@ def get_similar_albums():
|
||||
pass
|
||||
|
||||
return {"albums": [serialize_for_card(a) for a in albums[:limit]]}
|
||||
|
||||
|
||||
|
@ -1,22 +1,21 @@
|
||||
"""
|
||||
Contains all the artist(s) routes.
|
||||
"""
|
||||
from collections import deque
|
||||
import random
|
||||
from collections import deque
|
||||
|
||||
from flask import Blueprint, request
|
||||
|
||||
from app.db.sqlite.favorite import SQLiteFavoriteMethods as favdb
|
||||
from app.db.sqlite.lastfm.similar_artists import SQLiteLastFMSimilarArtists as fmdb
|
||||
|
||||
from app.db.sqlite.lastfm.similar_artists import \
|
||||
SQLiteLastFMSimilarArtists as fmdb
|
||||
from app.models import Album, FavType, Track
|
||||
from app.serializers.album import serialize_for_card_many
|
||||
from app.serializers.track import serialize_tracks
|
||||
from app.utils.remove_duplicates import remove_duplicates
|
||||
|
||||
from app.store.albums import AlbumStore
|
||||
from app.store.tracks import TrackStore
|
||||
from app.store.artists import ArtistStore
|
||||
from app.store.tracks import TrackStore
|
||||
from app.utils.remove_duplicates import remove_duplicates
|
||||
|
||||
api = Blueprint("artist", __name__, url_prefix="/")
|
||||
|
||||
@ -159,7 +158,7 @@ def add_albums_to_cache(artisthash: str):
|
||||
"""
|
||||
Fetches albums and adds them to the cache.
|
||||
"""
|
||||
tracks = TrackStore.get_tracks_by_artist(artisthash)
|
||||
tracks = TrackStore.get_tracks_by_artisthash(artisthash)
|
||||
|
||||
if len(tracks) == 0:
|
||||
return False
|
||||
@ -197,7 +196,7 @@ def get_artist(artisthash: str):
|
||||
if tracks_cached:
|
||||
tracks = ArtistsCache.get_tracks(artisthash)
|
||||
else:
|
||||
tracks = TrackStore.get_tracks_by_artist(artisthash)
|
||||
tracks = TrackStore.get_tracks_by_artisthash(artisthash)
|
||||
albumhashes = set(t.albumhash for t in tracks)
|
||||
hashes_from_albums = set(
|
||||
a.albumhash for a in AlbumStore.get_albums_by_artisthash(artisthash)
|
||||
@ -291,7 +290,7 @@ def get_all_artist_tracks(artisthash: str):
|
||||
"""
|
||||
Returns all artists by a given artist.
|
||||
"""
|
||||
tracks = TrackStore.get_tracks_by_artist(artisthash)
|
||||
tracks = TrackStore.get_tracks_by_artisthash(artisthash)
|
||||
|
||||
return {"tracks": serialize_tracks(tracks)}
|
||||
|
||||
|
@ -2,16 +2,18 @@
|
||||
Contains all the folder routes.
|
||||
"""
|
||||
import os
|
||||
import psutil
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
import psutil
|
||||
from flask import Blueprint, request
|
||||
from showinfm import show_in_file_manager
|
||||
|
||||
from app import settings
|
||||
from app.lib.folderslib import GetFilesAndDirs, get_folders
|
||||
from app.db.sqlite.settings import SettingsSQLMethods as db
|
||||
from app.utils.wintools import win_replace_slash, is_windows
|
||||
from app.lib.folderslib import GetFilesAndDirs, get_folders
|
||||
from app.serializers.track import track_serializer
|
||||
from app.store.tracks import TrackStore as store
|
||||
from app.utils.wintools import is_windows, win_replace_slash
|
||||
|
||||
api = Blueprint("folder", __name__, url_prefix="")
|
||||
|
||||
@ -129,3 +131,19 @@ def open_in_file_manager():
|
||||
show_in_file_manager(path)
|
||||
|
||||
return {"success": True}
|
||||
|
||||
|
||||
@api.route("/folder/tracks/all")
|
||||
def get_tracks_in_path():
|
||||
path = request.args.get("path")
|
||||
|
||||
if path is None:
|
||||
return {"error": "No path provided."}, 400
|
||||
|
||||
tracks = store.get_tracks_in_path(path)
|
||||
tracks = sorted(tracks, key=lambda i: i.last_mod)
|
||||
tracks = (track_serializer(t) for t in tracks if Path(t.filepath).exists())
|
||||
|
||||
return {
|
||||
"tracks": list(tracks)[:300],
|
||||
}
|
||||
|
@ -135,6 +135,31 @@ def create_playlist():
|
||||
return {"playlist": playlist}, 201
|
||||
|
||||
|
||||
def get_path_trackhashes(path: str):
|
||||
"""
|
||||
Returns a list of trackhashes in a folder.
|
||||
"""
|
||||
tracks = TrackStore.get_tracks_in_path(path)
|
||||
tracks = sorted(tracks, key=lambda t: t.last_mod)
|
||||
return [t.trackhash for t in tracks]
|
||||
|
||||
|
||||
def get_album_trackhashes(albumhash: str):
|
||||
"""
|
||||
Returns a list of trackhashes in an album.
|
||||
"""
|
||||
tracks = TrackStore.get_tracks_by_albumhash(albumhash)
|
||||
return [t.trackhash for t in tracks]
|
||||
|
||||
|
||||
def get_artist_trackhashes(artisthash: str):
|
||||
"""
|
||||
Returns a list of trackhashes for an artist.
|
||||
"""
|
||||
tracks = TrackStore.get_tracks_by_artisthash(artisthash)
|
||||
return [t.trackhash for t in tracks]
|
||||
|
||||
|
||||
@api.route("/playlist/<playlist_id>/add", methods=["POST"])
|
||||
def add_track_to_playlist(playlist_id: str):
|
||||
"""
|
||||
@ -145,9 +170,28 @@ def add_track_to_playlist(playlist_id: str):
|
||||
if data is None:
|
||||
return {"error": "Track hash not provided"}, 400
|
||||
|
||||
trackhash = data["track"]
|
||||
try:
|
||||
itemtype = data["itemtype"]
|
||||
except KeyError:
|
||||
itemtype = None
|
||||
|
||||
insert_count = tracks_to_playlist(int(playlist_id), [trackhash])
|
||||
try:
|
||||
itemhash = data["itemhash"]
|
||||
except KeyError:
|
||||
itemhash = None
|
||||
|
||||
if itemtype == "track":
|
||||
trackhashes = [itemhash]
|
||||
elif itemtype == "folder":
|
||||
trackhashes = get_path_trackhashes(itemhash)
|
||||
elif itemtype == "album":
|
||||
trackhashes = get_album_trackhashes(itemhash)
|
||||
elif itemtype == "artist":
|
||||
trackhashes = get_artist_trackhashes(itemhash)
|
||||
else:
|
||||
trackhashes = []
|
||||
|
||||
insert_count = tracks_to_playlist(int(playlist_id), trackhashes)
|
||||
|
||||
if insert_count == 0:
|
||||
return {"error": "Track already exists in playlist"}, 409
|
||||
@ -328,6 +372,10 @@ def remove_tracks_from_playlist(pid: int):
|
||||
return {"msg": "Done"}, 200
|
||||
|
||||
|
||||
def playlist_exists(name: str) -> bool:
|
||||
return count_playlist_by_name(name) > 0
|
||||
|
||||
|
||||
@api.route("/playlist/save-folder", methods=["POST"])
|
||||
def save_folder_as_folder():
|
||||
data = request.get_json()
|
||||
@ -342,17 +390,10 @@ def save_folder_as_folder():
|
||||
if path is None or name is None:
|
||||
return msg
|
||||
|
||||
p_count = count_playlist_by_name(name)
|
||||
|
||||
if p_count > 0:
|
||||
if playlist_exists(name):
|
||||
return {"error": "Playlist already exists"}, 409
|
||||
|
||||
tracks = TrackStore.get_tracks_in_path(path)
|
||||
|
||||
# sort tracks by last_mod
|
||||
tracks = sorted(tracks, key=lambda t: t.last_mod)
|
||||
trackhashes = [t.trackhash for t in tracks]
|
||||
|
||||
trackhashes = get_path_trackhashes(path)
|
||||
if len(trackhashes) == 0:
|
||||
return {"error": "No tracks found in folder"}, 404
|
||||
|
||||
@ -365,3 +406,67 @@ def save_folder_as_folder():
|
||||
PL.update_last_updated(playlist.id)
|
||||
|
||||
return {"playlist_id": playlist.id}, 201
|
||||
|
||||
|
||||
@api.route("/playlist/save-album", methods=["POST"])
|
||||
def save_album_as_playlist():
|
||||
data = request.get_json()
|
||||
msg = {"error": "'albumhash' and 'playlist_name' not provided"}, 400
|
||||
|
||||
if data is None:
|
||||
return msg
|
||||
|
||||
albumhash = data.get("albumhash")
|
||||
name = data.get("playlist_name")
|
||||
|
||||
if albumhash is None or name is None:
|
||||
return msg
|
||||
|
||||
if playlist_exists(name):
|
||||
return {"error": "Playlist already exists"}, 409
|
||||
|
||||
trackhashes = get_album_trackhashes(albumhash)
|
||||
if len(trackhashes) == 0:
|
||||
return {"error": "No tracks found in album"}, 404
|
||||
|
||||
playlist = insert_playlist(name)
|
||||
|
||||
if playlist is None:
|
||||
return {"error": "Playlist could not be created"}, 500
|
||||
|
||||
tracks_to_playlist(playlist.id, trackhashes)
|
||||
PL.update_last_updated(playlist.id)
|
||||
|
||||
return {"playlist_id": playlist.id}, 201
|
||||
|
||||
|
||||
@api.route("/playlist/save-artist", methods=["POST"])
|
||||
def save_artist_as_playlist():
|
||||
data = request.get_json()
|
||||
msg = {"error": "'artisthash' and 'playlist_name' not provided"}, 400
|
||||
|
||||
if data is None:
|
||||
return msg
|
||||
|
||||
artisthash = data.get("artisthash")
|
||||
name = data.get("playlist_name")
|
||||
|
||||
if artisthash is None or name is None:
|
||||
return msg
|
||||
|
||||
if playlist_exists(name):
|
||||
return {"error": "Playlist already exists"}, 409
|
||||
|
||||
trackhashes = get_artist_trackhashes(artisthash)
|
||||
if len(trackhashes) == 0:
|
||||
return {"error": "No tracks found in artist"}, 404
|
||||
|
||||
playlist = insert_playlist(name)
|
||||
|
||||
if playlist is None:
|
||||
return {"error": "Playlist could not be created"}, 500
|
||||
|
||||
tracks_to_playlist(playlist.id, trackhashes)
|
||||
PL.update_last_updated(playlist.id)
|
||||
|
||||
return {"playlist_id": playlist.id}, 201
|
||||
|
@ -96,8 +96,7 @@ class SQLitePlaylistMethods:
|
||||
def add_item_to_json_list(playlist_id: int, field: str, items: set[str]):
|
||||
"""
|
||||
Adds a string item to a json dumped list using a playlist id and field name.
|
||||
Takes the playlist ID, a field name,
|
||||
an item to add to the field, and an error to raise if the item is already in the field.
|
||||
Takes the playlist ID, a field name, an item to add to the field.
|
||||
"""
|
||||
sql = f"SELECT {field} FROM playlists WHERE id = ?"
|
||||
|
||||
@ -121,6 +120,9 @@ class SQLitePlaylistMethods:
|
||||
|
||||
@classmethod
|
||||
def add_tracks_to_playlist(cls, playlist_id: int, trackhashes: list[str]):
|
||||
"""
|
||||
Adds trackhashes to a playlist
|
||||
"""
|
||||
return cls.add_item_to_json_list(playlist_id, "trackhashes", trackhashes)
|
||||
|
||||
@staticmethod
|
||||
|
@ -1,30 +1,35 @@
|
||||
from dataclasses import asdict
|
||||
|
||||
from app.models.track import Track
|
||||
|
||||
|
||||
def track_serializer(track: Track, _remove: set = {}, retain_disc=False) -> dict:
|
||||
def track_serializer(track: Track, to_remove: set = {}, remove_disc=True) -> dict:
|
||||
album_dict = asdict(track)
|
||||
to_remove = {
|
||||
props = {
|
||||
"date",
|
||||
"genre",
|
||||
"last_mod",
|
||||
"og_title",
|
||||
"og_album",
|
||||
}.union(_remove)
|
||||
"copyright",
|
||||
"disc",
|
||||
"track",
|
||||
}.union(to_remove)
|
||||
|
||||
if not retain_disc:
|
||||
to_remove.union("disc", "track")
|
||||
if not remove_disc:
|
||||
props.remove("disc")
|
||||
props.remove("track")
|
||||
|
||||
to_remove.update(key for key in album_dict.keys() if key.startswith("is_"))
|
||||
to_remove.remove('is_favorite')
|
||||
props.update(key for key in album_dict.keys() if key.startswith("is_"))
|
||||
props.remove("is_favorite")
|
||||
|
||||
for key in to_remove:
|
||||
for key in props:
|
||||
album_dict.pop(key, None)
|
||||
|
||||
return album_dict
|
||||
|
||||
|
||||
def serialize_tracks(
|
||||
tracks: list[Track], _remove: set = {}, retain_disc=False
|
||||
tracks: list[Track], _remove: set = {}, remove_disc=True
|
||||
) -> list[dict]:
|
||||
return [track_serializer(t, _remove, retain_disc) for t in tracks]
|
||||
return [track_serializer(t, _remove, remove_disc) for t in tracks]
|
||||
|
@ -160,7 +160,7 @@ class TrackStore:
|
||||
return remove_duplicates(tracks)
|
||||
|
||||
@classmethod
|
||||
def get_tracks_by_artist(cls, artisthash: str) -> list[Track]:
|
||||
def get_tracks_by_artisthash(cls, artisthash: str) -> list[Track]:
|
||||
"""
|
||||
Returns all tracks matching the given artist. Duplicate tracks are removed.
|
||||
"""
|
||||
|
Loading…
x
Reference in New Issue
Block a user