From ec80a33298ed341ee731349f04b54e3fa75db6d9 Mon Sep 17 00:00:00 2001 From: codey Date: Wed, 5 Feb 2025 20:23:06 -0500 Subject: [PATCH] misc/version bump --- base.py | 5 ++- endpoints/lastfm.py | 25 ++++++----- endpoints/lyric_search.py | 34 ++------------- endpoints/misc.py | 2 +- endpoints/rand_msg.py | 1 - endpoints/xc.py | 64 +++++++++++++++-------------- endpoints/yt.py | 6 +-- lastfm_wrapper.py | 10 ++--- lyric_search/sources/cache.py | 59 +++++++++++++------------- lyric_search/sources/redis_cache.py | 8 ++-- 10 files changed, 97 insertions(+), 117 deletions(-) diff --git a/base.py b/base.py index 6b6d39a..e63ba36 100644 --- a/base.py +++ b/base.py @@ -16,12 +16,12 @@ logger.setLevel(logging.INFO) loop = asyncio.get_event_loop() app = FastAPI(title="codey.lol API", - version="0.1a", + version="1.0", contact={ 'name': 'codey' }, + redirect_slashes=False, loop=loop) -app.loop = loop constants = importlib.import_module("constants").Constants() util = importlib.import_module("util").Utilities(app, constants) @@ -82,6 +82,7 @@ End Blacklisted Routes """ Actionable Routes """ + randmsg_endpoint = importlib.import_module("endpoints.rand_msg").RandMsg(app, util, constants, glob_state) transcription_endpoints = importlib.import_module("endpoints.transcriptions").Transcriptions(app, util, constants, glob_state) ai_endpoints = importlib.import_module("endpoints.ai").AI(app, util, constants, glob_state) diff --git a/endpoints/lastfm.py b/endpoints/lastfm.py index bda2eb4..b270c9e 100644 --- a/endpoints/lastfm.py +++ b/endpoints/lastfm.py @@ -64,22 +64,22 @@ class LastFM(FastAPI): self.lastfm = importlib.import_module("lastfm_wrapper").LastFM() self.endpoints = { - "get_artist_by_name": self.artist_by_name_handler, - "get_artist_albums": self.artist_album_handler, - "get_release": self.release_detail_handler, - "get_release_tracklist": self.release_tracklist_handler, - "get_track_info": self.track_info_handler, + "lastfm/get_artist_by_name": self.artist_by_name_handler, + "lastfm/get_artist_albums": self.artist_album_handler, + "lastfm/get_release": self.release_detail_handler, + "lastfm/get_release_tracklist": self.release_tracklist_handler, + "lastfm/get_track_info": self.track_info_handler, #tbd } for endpoint, handler in self.endpoints.items(): app.add_api_route(f"/{endpoint}", handler, methods=["POST"], - include_in_schema=False) + include_in_schema=True) async def artist_by_name_handler(self, data: ValidArtistSearchRequest): """ - /get_artist_by_name/ Get artist info + - **a**: Artist to search """ artist = data.a.strip() if not artist: @@ -102,8 +102,8 @@ class LastFM(FastAPI): async def artist_album_handler(self, data: ValidArtistSearchRequest): """ - /get_artist_albums/ Get artist's albums/releases + - **a**: Artist to search """ artist = data.a.strip() if not artist: @@ -130,8 +130,9 @@ class LastFM(FastAPI): async def release_detail_handler(self, data: ValidAlbumDetailRequest): """ - /get_release/ Get details of a particular release by an artist + - **a**: Artist to search + - **a2**: Release title to search (subject to change) """ artist = data.a.strip() release = data.a2.strip() @@ -158,8 +159,9 @@ class LastFM(FastAPI): async def release_tracklist_handler(self, data: ValidAlbumDetailRequest): """ - /get_release_tracklist/ Get track list for a particular release by an artist + - **a**: Artist to search + - **a2**: Release title to search (subject to change) """ artist = data.a.strip() release = data.a2.strip() @@ -182,8 +184,9 @@ class LastFM(FastAPI): async def track_info_handler(self, data: ValidTrackInfoRequest): """ - /get_track_info/ Get track info from Last.FM given an artist/track + - **a**: Artist to search + - **t**: Track title to search """ try: artist = data.a diff --git a/endpoints/lyric_search.py b/endpoints/lyric_search.py index a31ebc9..1ee7009 100644 --- a/endpoints/lyric_search.py +++ b/endpoints/lyric_search.py @@ -59,15 +59,6 @@ class ValidTypeAheadRequest(BaseModel): pre_query: str|None = None query: str - -class ValidLyricSearchLogRequest(BaseModel): - """ - - **webradio**: whether or not to include requests generated automatically by the radio page on codey.lol, defaults to False - """ - - webradio: bool = False - - class CacheUtils: """Lyrics Cache DB Utils""" def __init__(self): @@ -103,8 +94,8 @@ class LyricSearch(FastAPI): self.endpoints = { "typeahead/artist": self.artist_typeahead_handler, "typeahead/song": self.song_typeahead_handler, - "lyric_search": self.lyric_search_handler, - # "lyric_cache_list": self.lyric_cache_list_handler, + "lyric_search": self.lyric_search_handler, # Preserving old endpoint path temporarily + "lyric/search": self.lyric_search_handler, } self.acceptable_request_sources = [ @@ -122,17 +113,8 @@ class LyricSearch(FastAPI): self.lrc_regex = regex.compile(r'\[([0-9]{2}:[0-9]{2})\.[0-9]{1,3}\](\s(.*)){0,}') for endpoint, handler in self.endpoints.items(): - _schema_include = endpoint in ["lyric_search"] + _schema_include = endpoint in ["lyric/search"] app.add_api_route(f"/{endpoint}", handler, methods=["POST"], include_in_schema=_schema_include) - - # async def lyric_cache_list_handler(self): - # """ - # Get currently cached lyrics entries - # """ - # return { - # 'err': False, - # 'data': await self.lyrics_engine.listCacheEntries() - # } async def artist_typeahead_handler(self, data: ValidTypeAheadRequest): """Artist Type Ahead Handler""" @@ -160,16 +142,6 @@ class LyricSearch(FastAPI): typeahead_list = [str(r.get('song')) for r in typeahead_result] return typeahead_list - # async def lyric_search_log_handler(self, data: ValidLyricSearchLogRequest): - # """Lyric Search Log Handler""" - # include_radio = data.webradio - # await self.glob_state.increment_counter('lyrichistory_requests') - # last_10k_sings = await self.lyrics_engine.getHistory(limit=10000, webradio=include_radio) - # return { - # 'err': False, - # 'history': last_10k_sings - # } - async def lyric_search_handler(self, data: ValidLyricRequest): """ Search for lyrics diff --git a/endpoints/misc.py b/endpoints/misc.py index 8076eca..b8eb375 100644 --- a/endpoints/misc.py +++ b/endpoints/misc.py @@ -57,7 +57,7 @@ class Misc(FastAPI): #TODO: change URL below to dynamically populate based on listener async with ClientSession() as session: - async with await session.post("http://127.0.0.1:52111/xc/", json=json_payload, + async with await session.post("http://127.0.0.1:52111/xc", json=json_payload, headers=headers, timeout=ClientTimeout(connect=3, sock_read=2)) as request: request.raise_for_status() request_json = await request.json() diff --git a/endpoints/rand_msg.py b/endpoints/rand_msg.py index be0c2ad..2b6541d 100644 --- a/endpoints/rand_msg.py +++ b/endpoints/rand_msg.py @@ -28,7 +28,6 @@ class RandMsg(FastAPI): async def randmsg_handler(self, data: RandMsgRequest = None): """ - /randmsg Get a randomly generated message """ random.seed() diff --git a/endpoints/xc.py b/endpoints/xc.py index f77cc09..130c2f8 100644 --- a/endpoints/xc.py +++ b/endpoints/xc.py @@ -54,36 +54,40 @@ class XC(FastAPI): /xc Handle XC Commands """ - key = data.key - bid = data.bid - cmd = data.cmd - cmd_data = data.data - req_type = 0 - - if bid in [1]: - req_type = 2 - - if not self.util.check_key(path=request.url.path, req_type=req_type, key=key): - raise HTTPException(status_code=403, detail="Unauthorized") - BID_ADDR_MAP = { - 0: '10.10.10.101:5991', # Thomas/Aces - 1: '10.10.10.100:5992' # MS & Waleed Combo - } + try: + key = data.key + bid = data.bid + cmd = data.cmd + cmd_data = data.data + req_type = 0 - if not bid in BID_ADDR_MAP: - return { - 'err': True, - 'errorText': 'Invalid bot id' - } + if bid in [1]: + req_type = 2 - bot_api_url = f'http://{BID_ADDR_MAP[bid]}/' - async with ClientSession() as session: - async with await session.post(f"{bot_api_url}{cmd}", json=cmd_data, headers={ - 'Content-Type': 'application/json; charset=utf-8' - }, timeout=ClientTimeout(connect=5, sock_read=5)) as request: - response = await request.json() - return { - 'success': True, - 'response': response - } \ No newline at end of file + if not self.util.check_key(path=request.url.path, req_type=req_type, key=key): + raise HTTPException(status_code=403, detail="Unauthorized") + + BID_ADDR_MAP = { + 0: '10.10.10.101:5991', # Thomas/Aces + 1: '10.10.10.100:5992' # MS & Waleed Combo + } + + if not bid in BID_ADDR_MAP: + return { + 'err': True, + 'errorText': 'Invalid bot id' + } + + bot_api_url = f'http://{BID_ADDR_MAP[bid]}/' + async with ClientSession() as session: + async with await session.post(f"{bot_api_url}{cmd}", json=cmd_data, headers={ + 'Content-Type': 'application/json; charset=utf-8' + }, timeout=ClientTimeout(connect=5, sock_read=5)) as request: + response = await request.json() + return { + 'success': True, + 'response': response + } + except: + pass \ No newline at end of file diff --git a/endpoints/yt.py b/endpoints/yt.py index 6d42c24..c254613 100644 --- a/endpoints/yt.py +++ b/endpoints/yt.py @@ -22,18 +22,18 @@ class YT(FastAPI): self.ytsearch = importlib.import_module("youtube_search_async").YoutubeSearch() self.endpoints = { - "yt_video_search": self.yt_video_search_handler, + "yt/search": self.yt_video_search_handler, #tbd } for endpoint, handler in self.endpoints.items(): app.add_api_route(f"/{endpoint}", handler, methods=["POST"], - include_in_schema=False) + include_in_schema=True) async def yt_video_search_handler(self, data: ValidYTSearchRequest): """ - /yt_video_search Search for YT Video by Title (closest match returned) + - **t**: Title to search """ title = data.t diff --git a/lastfm_wrapper.py b/lastfm_wrapper.py index 565a4e3..aa345d4 100644 --- a/lastfm_wrapper.py +++ b/lastfm_wrapper.py @@ -26,7 +26,7 @@ class LastFM: } async with ClientSession() as session: - async with session.get(f"{self.api_base_url}artist.getinfo&artist={artist}&api_key={self.creds.get('key')}&autocorrect=1&format=json", + async with await session.get(f"{self.api_base_url}artist.getinfo&artist={artist}&api_key={self.creds.get('key')}&autocorrect=1&format=json", timeout=ClientTimeout(connect=3, sock_read=8)) as request: assert request.status in [200, 204] data = await request.json() @@ -57,7 +57,7 @@ class LastFM: } async with ClientSession() as session: - async with session.get(f"{self.api_base_url}track.getInfo&api_key={self.creds.get('key')}&autocorrect=1&artist={artist}&track={track}&format=json", + async with await session.get(f"{self.api_base_url}track.getInfo&api_key={self.creds.get('key')}&autocorrect=1&artist={artist}&track={track}&format=json", timeout=ClientTimeout(connect=3, sock_read=8)) as request: assert request.status in [200, 204] data = await request.json() @@ -107,7 +107,7 @@ class LastFM: } async with ClientSession() as session: - async with session.get(f"{self.api_base_url}artist.gettopalbums&artist={artist}&api_key={self.creds.get('key')}&autocorrect=1&format=json", + async with await session.get(f"{self.api_base_url}artist.gettopalbums&artist={artist}&api_key={self.creds.get('key')}&autocorrect=1&format=json", timeout=ClientTimeout(connect=3, sock_read=8)) as request: assert request.status in [200, 204] data = await request.json() @@ -154,7 +154,7 @@ class LastFM: } async with ClientSession() as session: - async with session.get(f"{self.api_base_url}artists/{artist_id}?key={self.creds.get('key')}&secret={self.creds.get('secret')}", + async with await session.get(f"{self.api_base_url}artists/{artist_id}?key={self.creds.get('key')}&secret={self.creds.get('secret')}", timeout=ClientTimeout(connect=3, sock_read=8)) as request: assert request.status in [200, 204] data = await request.json() @@ -205,7 +205,7 @@ class LastFM: } async with ClientSession() as session: - async with session.get(f"{self.api_base_url}album.getinfo&artist={artist}&album={album}&api_key={self.creds.get('key')}&autocorrect=1&format=json", + async with await session.get(f"{self.api_base_url}album.getinfo&artist={artist}&album={album}&api_key={self.creds.get('key')}&autocorrect=1&format=json", timeout=ClientTimeout(connect=3, sock_read=8)) as request: assert request.status in [200, 204] data = await request.json() diff --git a/lyric_search/sources/cache.py b/lyric_search/sources/cache.py index f4d8bd4..40dc708 100644 --- a/lyric_search/sources/cache.py +++ b/lyric_search/sources/cache.py @@ -242,37 +242,40 @@ class Cache: logging.debug("Checking redis cache for %s...", f"{artist} - {song}") - redis_result = await self.redis_cache.search(artist=artist, + try: + redis_result = await self.redis_cache.search(artist=artist, song=song) - if redis_result: - result_tracks: list = [] - for returned in redis_result: - (key, track) = returned - result_tracks.append((key, f"{track['artist']} - {track['song']}")) - - if not random_search: - best_match: tuple|None = matcher.find_best_match(input_track=input_track, - candidate_tracks=result_tracks) - else: - best_match = (result_tracks[0], 100) - - - if best_match: - (candidate, confidence) = best_match - matched = self.get_matched(redis_results=redis_result, matched_candidate=candidate, - confidence=confidence) - - if matched: - time_end: float = time.time() - time_diff: float = time_end - time_start - matched.confidence = confidence - matched.time = time_diff + if redis_result: + result_tracks: list = [] + for returned in redis_result: + (key, track) = returned + result_tracks.append((key, f"{track['artist']} - {track['song']}")) + + if not random_search: + best_match: tuple|None = matcher.find_best_match(input_track=input_track, + candidate_tracks=result_tracks) + else: + best_match = (result_tracks[0], 100) + + + if best_match: + (candidate, confidence) = best_match + matched = self.get_matched(redis_results=redis_result, matched_candidate=candidate, + confidence=confidence) + + if matched: + time_end: float = time.time() + time_diff: float = time_end - time_start + matched.confidence = confidence + matched.time = time_diff - logging.info("Found %s on redis cache, skipping SQLite...", - f"{artist} - {song}") - await self.redis_cache.increment_found_count(self.label) - return matched + logging.info("Found %s on redis cache, skipping SQLite...", + f"{artist} - {song}") + await self.redis_cache.increment_found_count(self.label) + return matched + except: + pass """SQLite: Fallback""" diff --git a/lyric_search/sources/redis_cache.py b/lyric_search/sources/redis_cache.py index ceaaa2b..6b0edbb 100644 --- a/lyric_search/sources/redis_cache.py +++ b/lyric_search/sources/redis_cache.py @@ -136,6 +136,8 @@ class RedisCache: artist = kwargs.get('artist', '') song = kwargs.get('song', '') lyrics = kwargs.get('lyrics') + fuzzy_artist = None + fuzzy_song = None is_random_search = artist == "!" and song == "!" if lyrics: @@ -176,11 +178,7 @@ class RedisCache: return search_res_out except Exception as e: traceback.print_exc() - if fuzzy_artist and fuzzy_song: - await self.notifier.send(f"ERROR @ {__file__.rsplit("/", maxsplit=1)[-1]}", f"{str(e)}\nSearch was: {artist} - {song}; fuzzy: {fuzzy_artist} - {fuzzy_song}") - else: - await self.notifier.send(f"ERROR @ {__file__.rsplit("/", maxsplit=1)[-1]}", f"{str(e)}\nSearch was: {artist} - {song}; fuzzy: {fuzzy_artist} - {fuzzy_song}") - + # await self.notifier.send(f"ERROR @ {__file__.rsplit("/", maxsplit=1)[-1]}", f"{str(e)}\nSearch was: {artist} - {song}; fuzzy: {fuzzy_artist} - {fuzzy_song}") async def redis_store(self, sqlite_id: int, lyr_result: LyricsResult) -> None: """ Store lyrics to redis cache