rewrite album and artist search with rapidfuzz

This commit is contained in:
geoffrey45
2022-05-22 03:23:42 +03:00
parent 4040b99518
commit 4aa8576c73
5 changed files with 88 additions and 41 deletions
+8 -17
View File
@@ -23,25 +23,14 @@ def search():
""" """
query = request.args.get("q") or "Mexican girl" query = request.args.get("q") or "Mexican girl"
albums = searchlib.get_search_albums(query) albums = searchlib.SearchAlbums(query)()
artists_dicts = [] artists_dicts = searchlib.SearchArtists(query)()
artist_tracks = searchlib.get_artists(query) tracks = searchlib.SearchTracks(query)()
top_artist = artists_dicts[0]["name"]
for song in artist_tracks: _tracks = searchlib.GetTopArtistTracks(top_artist)()
for artist in song.artists: tracks = [*tracks, *[t for t in _tracks if t not in tracks]]
if query.lower() in artist.lower():
artist_obj = {
"name": artist,
"image": helpers.check_artist_image(artist),
}
if artist_obj not in artists_dicts:
artists_dicts.append(artist_obj)
_tracks = searchlib.SearchTracks(query)()
tracks = [*_tracks, *artist_tracks]
SEARCH_RESULTS.clear() SEARCH_RESULTS.clear()
SEARCH_RESULTS["tracks"] = tracks SEARCH_RESULTS["tracks"] = tracks
@@ -65,6 +54,8 @@ def search_load_more():
type = request.args.get("type") type = request.args.get("type")
start = int(request.args.get("start")) start = int(request.args.get("start"))
print(type, start)
if type == "tracks": if type == "tracks":
return { return {
"tracks": SEARCH_RESULTS["tracks"][start : start + 5], "tracks": SEARCH_RESULTS["tracks"][start : start + 5],
+11 -5
View File
@@ -1,16 +1,14 @@
""" """
This module contains mini functions for the server. This module contains mini functions for the server.
""" """
from datetime import datetime
import os import os
import random import random
import threading import threading
import time import time
from typing import Dict from datetime import datetime
from typing import List from typing import Dict, List
from app import models from app import models, settings
from app import settings
app_dir = settings.APP_DIR app_dir = settings.APP_DIR
@@ -120,7 +118,15 @@ def create_album_hash(title: str, artist: str) -> str:
""" """
return (title + artist).replace(" ", "").lower() return (title + artist).replace(" ", "").lower()
def create_new_date(): def create_new_date():
now = datetime.now() now = datetime.now()
str = now.strftime("%Y-%m-%d %H:%M:%S") str = now.strftime("%Y-%m-%d %H:%M:%S")
return str return str
def create_safe_name(name: str) -> str:
"""
Creates a url-safe name from a name.
"""
return "".join([i for i in name if i not in '/\\:*?"<>|'])
+66 -17
View File
@@ -9,6 +9,30 @@ from app.lib import albumslib
from rapidfuzz import fuzz, process from rapidfuzz import fuzz, process
ratio = fuzz.ratio
wratio = fuzz.WRatio
class Cutoff:
"""
Holds all the default cutoff values.
"""
tracks: int = 70
albums: int = 70
artists: int = 70
class Limit:
"""
Holds all the default limit values.
"""
tracks: int = 10
albums: int = 10
artists: int = 10
class SearchTracks: class SearchTracks:
def __init__(self, query) -> None: def __init__(self, query) -> None:
self.query = query self.query = query
@@ -20,9 +44,13 @@ class SearchTracks:
tracks = [track.title for track in api.TRACKS] tracks = [track.title for track in api.TRACKS]
results = process.extract( results = process.extract(
self.query, tracks, scorer=fuzz.token_set_ratio, score_cutoff=50 self.query,
tracks,
scorer=fuzz.WRatio,
score_cutoff=Cutoff.tracks,
limit=Limit.tracks,
) )
print(results)
return [api.TRACKS[i[2]] for i in results] return [api.TRACKS[i[2]] for i in results]
@@ -38,34 +66,33 @@ class SearchArtists:
artists = [track.artists for track in api.TRACKS] artists = [track.artists for track in api.TRACKS]
f_artists = [] f_artists = set()
for artist in artists: for artist in artists:
aa = artist.split(",") for a in artist:
f_artists.extend(aa) f_artists.add(a)
return f_artists return f_artists
@staticmethod
def get_valid_name(name: str) -> str:
"""
returns a valid artist name
"""
return "".join([i for i in name if i not in '/\\:*?"<>|'])
def __call__(self) -> list: def __call__(self) -> list:
""" """
Gets all artists with a given name. Gets all artists with a given name.
""" """
artists = self.get_all_artist_names() artists = self.get_all_artist_names()
results = process.extract(self.query, artists) results = process.extract(
self.query,
artists,
scorer=fuzz.WRatio,
score_cutoff=Cutoff.artists,
limit=Limit.artists,
)
f_artists = [] f_artists = []
for artist in results: for artist in results:
aa = { aa = {
"name": artist[0], "name": artist[0],
"image": self.get_valid_name(artist[0]) + ".webp", "image": helpers.create_safe_name(artist[0]) + ".webp",
} }
f_artists.append(aa) f_artists.append(aa)
@@ -90,14 +117,36 @@ class SearchAlbums:
Gets all albums with a given title. Gets all albums with a given title.
""" """
artists = SearchArtists(self.query)() albums = [a.title for a in api.ALBUMS]
a_albums = [] results = process.extract(
self.query,
albums,
scorer=fuzz.WRatio,
score_cutoff=Cutoff.albums,
limit=Limit.albums,
)
return [api.ALBUMS[i[2]] for i in results]
# get all artists that matched the query # get all artists that matched the query
# for get all albums from the artists # for get all albums from the artists
# get all albums that matched the query # get all albums that matched the query
# return [**artist_albums **albums] # return [**artist_albums **albums]
# recheck next and previous artist on play next or add to playlist
class GetTopArtistTracks:
def __init__(self, artist: str) -> None:
self.artist = artist
def __call__(self) -> List[models.Track]:
"""
Gets all tracks from a given artist.
"""
return [track for track in api.TRACKS if self.artist in track.artists]
def get_search_albums(query: str) -> List[models.Album]: def get_search_albums(query: str) -> List[models.Album]:
""" """
+1 -1
View File
@@ -18,7 +18,7 @@ class Track:
trackid: str trackid: str
title: str title: str
artists: str artists: list
albumartist: str albumartist: str
album: str album: str
folder: str folder: str
+1
View File
@@ -35,6 +35,7 @@ const emit = defineEmits(["loadMore"]);
function loadMore() { function loadMore() {
counter += 5; counter += 5;
console.log("load more", counter);
emit("loadMore", counter); emit("loadMore", counter);
} }