diff --git a/endpoints/karma.py b/endpoints/karma.py index 12bb501..26c6848 100644 --- a/endpoints/karma.py +++ b/endpoints/karma.py @@ -56,7 +56,8 @@ class KarmaDB: "SELECT keyword, score FROM karma ORDER BY score DESC LIMIT ?", (n,) ) as db_cursor: return await db_cursor.fetchall() - except: + except Exception as e: + logging.debug("Exception: %s", str(e)) traceback.print_exc() return None @@ -73,7 +74,7 @@ class KarmaDB: Optional[bool] """ - if not flag in [0, 1]: + if flag not in [0, 1]: return None modifier: str = "score + 1" if not flag else "score - 1" @@ -182,7 +183,8 @@ class Karma(FastAPI): }, ) return JSONResponse(content=top10) - except: + except Exception as e: + logging.debug("Exception: %s", str(e)) traceback.print_exc() return JSONResponse( status_code=500, @@ -214,7 +216,8 @@ class Karma(FastAPI): "count": count, } ) - except: + except Exception as e: + logging.debug("Exception: %s", str(e)) traceback.print_exc() return JSONResponse( status_code=500, @@ -239,7 +242,7 @@ class Karma(FastAPI): ): raise HTTPException(status_code=403, detail="Unauthorized") - if not data.flag in [0, 1]: + if data.flag not in [0, 1]: return JSONResponse( status_code=500, content={ diff --git a/endpoints/lastfm.py b/endpoints/lastfm.py index afcce1f..6c488ce 100644 --- a/endpoints/lastfm.py +++ b/endpoints/lastfm.py @@ -1,4 +1,5 @@ import importlib +import logging import traceback from typing import Optional, Union from fastapi import FastAPI @@ -214,7 +215,8 @@ class LastFM(FastAPI): track_info_result.get("errorText", "??"), ) return JSONResponse(content={"success": True, "result": track_info_result}) - except: + except Exception as e: + logging.debug("Exception: %s", str(e)) traceback.print_exc() return JSONResponse( status_code=500, diff --git a/endpoints/lyric_search.py b/endpoints/lyric_search.py index 30d975c..fb255e8 100644 --- a/endpoints/lyric_search.py +++ b/endpoints/lyric_search.py @@ -125,6 +125,14 @@ class LyricSearch(FastAPI): "errorText": f"Unknown request source: {data.src}", }, ) + + if data.a == "N/A" and data.s == "N/A": + return JSONResponse( + status_code=200, + content={ + 'test': 'success', + } + ) if not data.t: search_artist: Optional[str] = data.a diff --git a/endpoints/misc.py b/endpoints/misc.py index 46928ea..e46a238 100644 --- a/endpoints/misc.py +++ b/endpoints/misc.py @@ -96,9 +96,9 @@ class Misc(FastAPI): """ # Measure response time w/ test lyric search time_start: float = time.time() # Start time for response_time - test_lyrics_result = await self.redis_client.ft().search( + test_lyrics_result = await self.redis_client.ft().search( # noqa: F841 "@artist: test @song: test" - ) + ) time_end: float = time.time() # End response time test total_keys = await self.redis_client.dbsize() diff --git a/endpoints/radio.py b/endpoints/radio.py index b1ebe6e..9c528d2 100644 --- a/endpoints/radio.py +++ b/endpoints/radio.py @@ -2,7 +2,6 @@ import logging import traceback import time import random -from multiprocessing.pool import ThreadPool as Pool from .constructors import ( ValidRadioNextRequest, ValidRadioReshuffleRequest, @@ -129,14 +128,12 @@ class Radio(FastAPI): start: int = int(data.start) end: int = start + 20 search: Optional[str] = data.search - logging.info("queue request with start pos: %s & end pos: %s", start, end) if not search: queue_full: list = self.radio_util.active_playlist else: queue_full: list = self.radio_util.datatables_search(data.search) queue: list = queue_full[start:end] - logging.info("queue length: %s", len(queue)) queue_out: list[dict] = [] for x, item in enumerate(queue): queue_out.append( @@ -313,9 +310,7 @@ class Radio(FastAPI): if len(self.radio_util.active_playlist) > 1: self.radio_util.active_playlist.append(next) # Push to end of playlist else: - with Pool() as pool: - pool.apply_async(self.radio_util.load_playlist()) - pool.close() + self.loop.run_in_executor(None, self.radio_util.load_playlist) self.radio_util.now_playing = next next["start"] = time_started @@ -374,7 +369,7 @@ class Radio(FastAPI): await self.radio_util._ls_skip() return JSONResponse(content={"result": search}) - async def radio_typeahead( + def radio_typeahead( self, data: ValidRadioTypeaheadRequest, request: Request ) -> JSONResponse: """ diff --git a/lyric_search/sources/genius.py b/lyric_search/sources/genius.py index 8e59257..f7c1778 100644 --- a/lyric_search/sources/genius.py +++ b/lyric_search/sources/genius.py @@ -166,5 +166,6 @@ class Genius: await self.redis_cache.increment_found_count(self.label) await self.cache.store(matched) return matched - except: + except Exception as e: + logging.debug("Exception: %s", str(e)) traceback.print_exc() diff --git a/lyric_search/sources/lrclib.py b/lyric_search/sources/lrclib.py index 54b2167..b76db92 100644 --- a/lyric_search/sources/lrclib.py +++ b/lyric_search/sources/lrclib.py @@ -156,7 +156,9 @@ class LRCLib: time=time_diff, ) await self.redis_cache.increment_found_count(self.label) - await self.cache.store(matched) + if plain: + await self.cache.store(matched) return matched - except: + except Exception as e: + logging.debug("Exception: %s", str(e)) traceback.print_exc() diff --git a/lyric_search/sources/redis_cache.py b/lyric_search/sources/redis_cache.py index 61717df..e632dfd 100644 --- a/lyric_search/sources/redis_cache.py +++ b/lyric_search/sources/redis_cache.py @@ -14,7 +14,7 @@ from lyric_search.constructors import LyricsResult import redis.asyncio as redis from redis.commands.search.query import Query # type: ignore from redis.commands.search.indexDefinition import IndexDefinition, IndexType # type: ignore -from redis.commands.search.field import TextField, TagField # type: ignore +from redis.commands.search.field import TextField # type: ignore from redis.commands.json.path import Path # type: ignore from . import private @@ -204,8 +204,8 @@ class RedisCache: ) return search_res_out except Exception as e: + logging.debug("Exception: %s", str(e)) traceback.print_exc() - # await self.notifier.send(f"ERROR @ {__file__.rsplit("/", maxsplit=1)[-1]}", f"{str(e)}\nSearch was: {artist} - {song}; fuzzy: {fuzzy_artist} - {fuzzy_song}") return None async def redis_store(self, sqlite_id: int, lyr_result: LyricsResult) -> None: diff --git a/utils/radio_util.py b/utils/radio_util.py index df6df05..9245c83 100644 --- a/utils/radio_util.py +++ b/utils/radio_util.py @@ -3,7 +3,7 @@ import traceback import time import datetime import os -import asyncio +import random from uuid import uuid4 as uuid from typing import Union, Optional, Iterable from aiohttp import ClientSession, ClientTimeout @@ -20,13 +20,10 @@ non_alnum: Pattern = regex.compile(r"[^a-zA-Z0-9]") """ TODO: - - Album art rework - get_genre should only be called once for load_playlist, rework get_genre to (optionally) accept a list of artists, - and return (optionally) a list instead of an str - - Allow tracks to be queried again based on genre; unable to query tracks based on genre presently, - as genre was moved outside track_file_map to artist_genre_map + and return (optionally) a list instead of an str - Ask GPT when we encounter an untagged (no genre defined) artist, automation is needed for this tedious task - - etc.. + - etc.. """ @@ -93,7 +90,7 @@ class RadioUtil: """ return str(datetime.timedelta(seconds=s)).split(".", maxsplit=1)[0] - async def trackdb_typeahead(self, query: str) -> Optional[list[str]]: + def trackdb_typeahead(self, query: str) -> Optional[list[str]]: """ Query track db for typeahead Args: @@ -338,10 +335,10 @@ class RadioUtil: LIMITED GENRES """ - # db_query: str = ( - # 'SELECT distinct(LOWER(TRIM(artist)) || " - " || LOWER(TRIM(song))), (TRIM(artist) || " - " || TRIM(song))' - # "AS artistdashsong, id, artist, song, album, file_path, duration FROM tracks GROUP BY artistdashsong ORDER BY RANDOM()" - # ) + db_query: str = ( + 'SELECT distinct(LOWER(TRIM(artist)) || " - " || LOWER(TRIM(song))), (TRIM(artist) || " - " || TRIM(song))' + "AS artistdashsong, id, artist, song, album, file_path, duration FROM tracks" + ) """ LIMITED TO ONE/SMALL SUBSET OF GENRES @@ -354,8 +351,8 @@ class RadioUtil: LIMITED TO ONE/SOME ARTISTS... """ - db_query = 'SELECT distinct(artist || " - " || song) AS artistdashsong, id, artist, song, album, file_path, duration FROM tracks\ - WHERE (artist LIKE "%chunk!%") AND (NOT song LIKE "%%stripped%%" AND NOT song LIKE "%(2022)%" AND NOT song LIKE "%(live%%" AND NOT song LIKE "%%acoustic%%" AND NOT song LIKE "%%instrumental%%" AND NOT song LIKE "%%remix%%" AND NOT song LIKE "%%reimagined%%" AND NOT song LIKE "%%alternative%%" AND NOT song LIKE "%%unzipped%%") GROUP BY artistdashsong ORDER BY RANDOM()' # ORDER BY album ASC, id ASC' + # db_query = 'SELECT distinct(artist || " - " || song) AS artistdashsong, id, artist, song, album, file_path, duration FROM tracks\ + # WHERE (artist LIKE "%outline in color%") AND (NOT song LIKE "%%stripped%%" AND NOT song LIKE "%(2022)%" AND NOT song LIKE "%(live%%" AND NOT song LIKE "%%acoustic%%" AND NOT song LIKE "%%instrumental%%" AND NOT song LIKE "%%remix%%" AND NOT song LIKE "%%reimagined%%" AND NOT song LIKE "%%alternative%%" AND NOT song LIKE "%%unzipped%%") GROUP BY artistdashsong ORDER BY RANDOM()' # ORDER BY album ASC, id ASC' # db_query = 'SELECT distinct(artist || " - " || song) AS artistdashsong, id, artist, song, album, genre, file_path, duration FROM tracks\ # WHERE (artist LIKE "%sullivan king%" OR artist LIKE "%kayzo%" OR artist LIKE "%adventure club%") AND (NOT song LIKE "%%stripped%%" AND NOT song LIKE "%(2022)%" AND NOT song LIKE "%(live%%" AND NOT song LIKE "%%acoustic%%" AND NOT song LIKE "%%instrumental%%" AND NOT song LIKE "%%remix%%" AND NOT song LIKE "%%reimagined%%" AND NOT song LIKE "%%alternative%%" AND NOT song LIKE "%%unzipped%%") GROUP BY artistdashsong ORDER BY RANDOM()'# ORDER BY album ASC, id ASC' @@ -385,12 +382,33 @@ class RadioUtil: "file_path": r["file_path"], "duration": r["duration"], } - for r in results + for r in results if r not in self.active_playlist ] logging.info( "Populated active playlists with %s items", len(self.active_playlist), ) + + random.shuffle(self.active_playlist) + + """Dedupe""" + logging.info("Removing duplicate tracks...") + dedupe_processed = [] + for item in self.active_playlist: + artistsongabc: str = non_alnum.sub('', item.get('artistsong', None)) + if not artistsongabc: + logging.info("Missing artistsong: %s", item) + continue + if artistsongabc in dedupe_processed: + self.active_playlist.remove(item) + dedupe_processed.append(artistsongabc) + + logging.info( + "Duplicates removed." "New playlist size: %s", + len(self.active_playlist)) + + logging.info("Playlist: %s", [str(a.get('artistsong', '')) for a in self.active_playlist]) + if self.playback_genres: new_playlist: list[dict] = [] logging.info("Limiting playback genres") @@ -400,6 +418,8 @@ class RadioUtil: for genre in self.playback_genres: genre = genre.strip().lower() if genre in item_genres: + if item in new_playlist: + continue new_playlist.append(item) matched_genre = True continue