mirror of
https://github.com/Dvorinka/swingmusic-extended.git
synced 2026-06-03 20:13:02 +00:00
add method and route to search across tracks, albums and artists.
+ break models into separate files + same for the utils and setup
This commit is contained in:
@@ -17,7 +17,6 @@ def create_api():
|
||||
CORS(app)
|
||||
|
||||
with app.app_context():
|
||||
|
||||
app.register_blueprint(album.api)
|
||||
app.register_blueprint(artist.api)
|
||||
app.register_blueprint(track.api)
|
||||
|
||||
+9
-27
@@ -6,13 +6,12 @@ from dataclasses import asdict
|
||||
|
||||
from flask import Blueprint, request
|
||||
|
||||
from app import utils
|
||||
from app.db.sqlite.albums import SQLiteAlbumMethods as adb
|
||||
from app.db.sqlite.favorite import SQLiteFavoriteMethods as favdb
|
||||
from app.db.store import Store
|
||||
from app.models import FavType, Track
|
||||
from app.utils.remove_duplicates import remove_duplicates
|
||||
|
||||
get_album_by_id = adb.get_album_by_id
|
||||
get_albums_by_albumartist = adb.get_albums_by_albumartist
|
||||
check_is_fav = favdb.check_is_favorite
|
||||
|
||||
@@ -20,8 +19,10 @@ api = Blueprint("album", __name__, url_prefix="")
|
||||
|
||||
|
||||
@api.route("/album", methods=["POST"])
|
||||
def get_album():
|
||||
"""Returns all the tracks in the given album."""
|
||||
def get_album_tracks_and_info():
|
||||
"""
|
||||
Returns all the tracks in the given album
|
||||
"""
|
||||
|
||||
data = request.get_json()
|
||||
error_msg = {"msg": "No hash provided"}
|
||||
@@ -58,7 +59,7 @@ def get_album():
|
||||
return list(genres)
|
||||
|
||||
album.genres = get_album_genres(tracks)
|
||||
tracks = utils.remove_duplicates(tracks)
|
||||
tracks = remove_duplicates(tracks)
|
||||
|
||||
album.count = len(tracks)
|
||||
album.get_date_from_tracks(tracks)
|
||||
@@ -83,7 +84,7 @@ def get_album():
|
||||
@api.route("/album/<albumhash>/tracks", methods=["GET"])
|
||||
def get_album_tracks(albumhash: str):
|
||||
"""
|
||||
Returns all the tracks in the given album.
|
||||
Returns all the tracks in the given album, sorted by disc and track number.
|
||||
"""
|
||||
tracks = Store.get_tracks_by_albumhash(albumhash)
|
||||
tracks = [asdict(t) for t in tracks]
|
||||
@@ -104,11 +105,11 @@ def get_artist_albums():
|
||||
if data is None:
|
||||
return {"msg": "No albumartist provided"}
|
||||
|
||||
albumartists: str = data["albumartists"] # type: ignore
|
||||
albumartists: str = data["albumartists"]
|
||||
limit: int = data.get("limit")
|
||||
exclude: str = data.get("exclude")
|
||||
|
||||
albumartists: list[str] = albumartists.split(",") # type: ignore
|
||||
albumartists: list[str] = albumartists.split(",")
|
||||
|
||||
albums = [
|
||||
{
|
||||
@@ -121,22 +122,3 @@ def get_artist_albums():
|
||||
albums = [a for a in albums if len(a["albums"]) > 0]
|
||||
|
||||
return {"data": albums}
|
||||
|
||||
# @album_bp.route("/album/bio", methods=["POST"])
|
||||
# def get_album_bio():
|
||||
# """Returns the album bio for the given album."""
|
||||
# data = request.get_json()
|
||||
# album_hash = data["hash"]
|
||||
# err_msg = {"bio": "No bio found"}
|
||||
|
||||
# album = instances.album_instance.find_album_by_hash(album_hash)
|
||||
|
||||
# if album is None:
|
||||
# return err_msg, 404
|
||||
|
||||
# bio = FetchAlbumBio(album["title"], album["artist"])()
|
||||
|
||||
# if bio is None:
|
||||
# return err_msg, 404
|
||||
|
||||
# return {"bio": bio}
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ from flask import Blueprint, request
|
||||
from app.db.sqlite.favorite import SQLiteFavoriteMethods as favdb
|
||||
from app.db.store import Store
|
||||
from app.models import Album, FavType, Track
|
||||
from app.utils import remove_duplicates
|
||||
from app.utils.remove_duplicates import remove_duplicates
|
||||
|
||||
api = Blueprint("artist", __name__, url_prefix="/")
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ from flask import Blueprint, request
|
||||
from app.db.sqlite.favorite import SQLiteFavoriteMethods as favdb
|
||||
from app.db.store import Store
|
||||
from app.models import FavType
|
||||
from app.utils import UseBisection
|
||||
from app.utils.bisection import UseBisection
|
||||
|
||||
api = Blueprint("favorite", __name__, url_prefix="/")
|
||||
|
||||
|
||||
+3
-2
@@ -10,8 +10,9 @@ from flask import Blueprint, request
|
||||
from app import settings
|
||||
from app.lib.folderslib import GetFilesAndDirs
|
||||
from app.db.sqlite.settings import SettingsSQLMethods as db
|
||||
from app.models import Folder
|
||||
from app.utils import create_folder_hash, is_windows, win_replace_slash
|
||||
from app.models.folder import Folder
|
||||
from app.utils.hashing import create_folder_hash
|
||||
from app.utils.wintools import win_replace_slash, is_windows
|
||||
|
||||
api = Blueprint("folder", __name__, url_prefix="/")
|
||||
|
||||
|
||||
+2
-1
@@ -11,7 +11,8 @@ from app import models, serializer
|
||||
from app.db.sqlite.playlists import SQLitePlaylistMethods
|
||||
from app.db.store import Store
|
||||
from app.lib import playlistlib
|
||||
from app.utils import create_new_date, remove_duplicates
|
||||
from app.utils.generators import create_new_date
|
||||
from app.utils.remove_duplicates import remove_duplicates
|
||||
|
||||
api = Blueprint("playlist", __name__, url_prefix="/")
|
||||
|
||||
|
||||
+27
-33
@@ -2,16 +2,15 @@
|
||||
Contains all the search routes.
|
||||
"""
|
||||
|
||||
from unidecode import unidecode
|
||||
from flask import Blueprint, request
|
||||
|
||||
from app import models, utils
|
||||
from app import models
|
||||
from app.db.store import Store
|
||||
from app.lib import searchlib
|
||||
from unidecode import unidecode
|
||||
|
||||
api = Blueprint("search", __name__, url_prefix="/")
|
||||
|
||||
|
||||
SEARCH_COUNT = 12
|
||||
"""The max amount of items to return per request"""
|
||||
|
||||
@@ -28,48 +27,36 @@ class SearchResults:
|
||||
artists: list[models.Artist] = []
|
||||
|
||||
|
||||
class DoSearch:
|
||||
"""Class containing the methods that perform searching."""
|
||||
|
||||
class Search:
|
||||
def __init__(self, query: str) -> None:
|
||||
"""
|
||||
:param :str:`query`: the search query.
|
||||
"""
|
||||
self.tracks: list[models.Track] = []
|
||||
self.query = unidecode(query)
|
||||
SearchResults.query = self.query
|
||||
|
||||
def search_tracks(self):
|
||||
"""Calls :class:`SearchTracks` which returns the tracks that fuzzily match
|
||||
"""
|
||||
Calls :class:`SearchTracks` which returns the tracks that fuzzily match
|
||||
the search terms. Then adds them to the `SearchResults` store.
|
||||
"""
|
||||
self.tracks = Store.tracks
|
||||
tracks = searchlib.SearchTracks(self.tracks, self.query)()
|
||||
tracks = searchlib.SearchTracks(self.query)()
|
||||
|
||||
if len(tracks) == 0:
|
||||
return []
|
||||
|
||||
tracks = utils.remove_duplicates(tracks)
|
||||
SearchResults.tracks = tracks
|
||||
|
||||
return tracks
|
||||
|
||||
def search_artists(self):
|
||||
"""Calls :class:`SearchArtists` which returns the artists that fuzzily match
|
||||
the search term. Then adds them to the `SearchResults` store.
|
||||
"""
|
||||
artists = [a.name for a in Store.artists]
|
||||
artists = searchlib.SearchArtists(Store.artists, self.query)()
|
||||
artists = searchlib.SearchArtists(self.query)()
|
||||
SearchResults.artists = artists
|
||||
|
||||
return artists
|
||||
|
||||
def search_albums(self):
|
||||
"""Calls :class:`SearchAlbums` which returns the albums that fuzzily match
|
||||
the search term. Then adds them to the `SearchResults` store.
|
||||
"""
|
||||
albums = Store.albums
|
||||
albums = searchlib.SearchAlbums(albums, self.query)()
|
||||
albums = searchlib.SearchAlbums(self.query)()
|
||||
SearchResults.albums = albums
|
||||
|
||||
return albums
|
||||
@@ -86,6 +73,10 @@ class DoSearch:
|
||||
|
||||
# return playlists
|
||||
|
||||
def get_top_results(self):
|
||||
finder = searchlib.SearchAll()
|
||||
return finder.search(self.query)
|
||||
|
||||
def search_all(self):
|
||||
"""Calls all the search methods."""
|
||||
self.search_tracks()
|
||||
@@ -104,7 +95,7 @@ def search_tracks():
|
||||
if not query:
|
||||
return {"error": "No query provided"}, 400
|
||||
|
||||
tracks = DoSearch(query).search_tracks()
|
||||
tracks = Search(query).search_tracks()
|
||||
|
||||
return {
|
||||
"tracks": tracks[:SEARCH_COUNT],
|
||||
@@ -122,7 +113,7 @@ def search_albums():
|
||||
if not query:
|
||||
return {"error": "No query provided"}, 400
|
||||
|
||||
tracks = DoSearch(query).search_albums()
|
||||
tracks = Search(query).search_albums()
|
||||
|
||||
return {
|
||||
"albums": tracks[:SEARCH_COUNT],
|
||||
@@ -140,7 +131,7 @@ def search_artists():
|
||||
if not query:
|
||||
return {"error": "No query provided"}, 400
|
||||
|
||||
artists = DoSearch(query).search_artists()
|
||||
artists = Search(query).search_artists()
|
||||
|
||||
return {
|
||||
"artists": artists[:SEARCH_COUNT],
|
||||
@@ -176,14 +167,17 @@ def get_top_results():
|
||||
if not query:
|
||||
return {"error": "No query provided"}, 400
|
||||
|
||||
DoSearch(query).search_all()
|
||||
results = Search(query).get_top_results()
|
||||
|
||||
max_results = 2
|
||||
# max_results = 2
|
||||
# return {
|
||||
# "tracks": SearchResults.tracks[:max_results],
|
||||
# "albums": SearchResults.albums[:max_results],
|
||||
# "artists": SearchResults.artists[:max_results],
|
||||
# "playlists": SearchResults.playlists[:max_results],
|
||||
# }
|
||||
return {
|
||||
"tracks": SearchResults.tracks[:max_results],
|
||||
"albums": SearchResults.albums[:max_results],
|
||||
"artists": SearchResults.artists[:max_results],
|
||||
"playlists": SearchResults.playlists[:max_results],
|
||||
"results": results
|
||||
}
|
||||
|
||||
|
||||
@@ -198,20 +192,20 @@ def search_load_more():
|
||||
if s_type == "tracks":
|
||||
t = SearchResults.tracks
|
||||
return {
|
||||
"tracks": t[index : index + SEARCH_COUNT],
|
||||
"tracks": t[index: index + SEARCH_COUNT],
|
||||
"more": len(t) > index + SEARCH_COUNT,
|
||||
}
|
||||
|
||||
elif s_type == "albums":
|
||||
a = SearchResults.albums
|
||||
return {
|
||||
"albums": a[index : index + SEARCH_COUNT],
|
||||
"albums": a[index: index + SEARCH_COUNT],
|
||||
"more": len(a) > index + SEARCH_COUNT,
|
||||
}
|
||||
|
||||
elif s_type == "artists":
|
||||
a = SearchResults.artists
|
||||
return {
|
||||
"artists": a[index : index + SEARCH_COUNT],
|
||||
"artists": a[index: index + SEARCH_COUNT],
|
||||
"more": len(a) > index + SEARCH_COUNT,
|
||||
}
|
||||
|
||||
+2
-1
@@ -4,9 +4,10 @@ from app import settings
|
||||
from app.logger import log
|
||||
from app.lib import populate
|
||||
from app.db.store import Store
|
||||
from app.utils import background, get_random_str
|
||||
from app.lib.watchdogg import Watcher as WatchDog
|
||||
from app.db.sqlite.settings import SettingsSQLMethods as sdb
|
||||
from app.utils.generators import get_random_str
|
||||
from app.utils.threading import background
|
||||
|
||||
api = Blueprint("settings", __name__, url_prefix="/")
|
||||
|
||||
|
||||
+25
-12
@@ -1,7 +1,9 @@
|
||||
"""
|
||||
Contains all the track routes.
|
||||
"""
|
||||
from flask import Blueprint, send_file
|
||||
import os
|
||||
|
||||
from flask import Blueprint, send_file, request
|
||||
|
||||
from app.db.store import Store
|
||||
|
||||
@@ -15,20 +17,31 @@ def send_track_file(trackhash: str):
|
||||
Falls back to track hash if id is not found.
|
||||
"""
|
||||
msg = {"msg": "File Not Found"}
|
||||
|
||||
def get_mime(filename: str) -> str:
|
||||
ext = filename.rsplit(".", maxsplit=1)[-1]
|
||||
return f"audio/{ext}"
|
||||
|
||||
filepath = request.args.get("filepath")
|
||||
|
||||
if filepath is not None and os.path.exists(filepath):
|
||||
audio_type = get_mime(filepath)
|
||||
return send_file(filepath, mimetype=audio_type)
|
||||
|
||||
if trackhash is None:
|
||||
return msg, 404
|
||||
|
||||
try:
|
||||
track = Store.get_tracks_by_trackhashes([trackhash])[0]
|
||||
except IndexError:
|
||||
track = None
|
||||
tracks = Store.get_tracks_by_trackhashes([trackhash])
|
||||
|
||||
if track is None:
|
||||
return msg, 404
|
||||
for track in tracks:
|
||||
if track is None:
|
||||
return msg, 404
|
||||
|
||||
audio_type = track.filepath.rsplit(".", maxsplit=1)[-1]
|
||||
audio_type = get_mime(track.filepath)
|
||||
|
||||
try:
|
||||
return send_file(track.filepath, mimetype=f"audio/{audio_type}")
|
||||
except FileNotFoundError:
|
||||
return msg, 404
|
||||
try:
|
||||
return send_file(track.filepath, mimetype=audio_type)
|
||||
except FileNotFoundError:
|
||||
return msg, 404
|
||||
|
||||
return msg, 404
|
||||
|
||||
Reference in New Issue
Block a user