diff --git a/endpoints/ai.py b/endpoints/ai.py index 3e928e8..724197f 100644 --- a/endpoints/ai.py +++ b/endpoints/ai.py @@ -72,15 +72,12 @@ class AI(FastAPI): } }] } - logging.critical("Request: %s", data) async with ClientSession() as session: async with session.post(data.hook, json=hook_data, timeout=ClientTimeout(connect=5, sock_read=5), headers={ 'content-type': 'application/json; charset=utf-8',}) as request: - logging.debug("Returned: %s", - await request.json()) - await request.raise_for_status() + request.raise_for_status() return True except: traceback.print_exc() diff --git a/endpoints/lyric_search.py b/endpoints/lyric_search.py index c5b04a3..f4c5bcb 100644 --- a/endpoints/lyric_search.py +++ b/endpoints/lyric_search.py @@ -7,7 +7,6 @@ import logging import urllib.parse import regex import aiohttp - from fastapi import FastAPI, HTTPException from pydantic import BaseModel from lyric_search_new.sources import aggregate @@ -22,6 +21,7 @@ class ValidLyricRequest(BaseModel): - **lrc**: Request LRCs? - **sub**: text to search within lyrics, if found lyrics will begin at found verse [optional] - **src**: the script/utility which initiated the request + - **excluded_sources**: sources to exclude (new only) """ a: str | None = None @@ -31,6 +31,7 @@ class ValidLyricRequest(BaseModel): extra: bool | None = False lrc: bool | None = False src: str + excluded_sources: list | None = None class Config: # pylint: disable=missing-class-docstring too-few-public-methods schema_extra = { @@ -116,12 +117,14 @@ class LyricSearch(FastAPI): - **lrc**: Request LRCs? [unused] - **sub**: text to search within lyrics, if found lyrics will begin at found verse [optional, default: none] [unused] - **src**: the script/utility which initiated the request [unused] + - **excluded_sources**: sources to exclude """ if not data.a or not data.s: raise HTTPException(detail="Invalid request", status_code=500) - aggregate_search = aggregate.Aggregate(exclude_methods=None) + excluded_sources = data.excluded_sources + aggregate_search = aggregate.Aggregate(exclude_methods=excluded_sources) result = await aggregate_search.search(data.a, data.s) if not result: return { diff --git a/lyric_search_new/sources/cache.py b/lyric_search_new/sources/cache.py index 2c98cb6..3b167bd 100644 --- a/lyric_search_new/sources/cache.py +++ b/lyric_search_new/sources/cache.py @@ -50,6 +50,8 @@ class Cache: try: artist: str = artist.strip().lower() song: str = song.strip().lower() + search_params: Optional[tuple] = None + random_search: bool = False logging.info("Searching %s - %s on %s", artist, song, self.label) async with sqlite3.connect(self.cache_db, timeout=2) as db_conn: @@ -61,7 +63,11 @@ class Cache: WHERE editdist3((artist || " " || song), (? || " " || ?))\ <= 410 ORDER BY editdist3((artist || " " || song), ?) ASC LIMIT 10' search_params: tuple = (artist.strip(), song.strip(), - f"{artist.strip()} {song.strip()}") + f"{artist.strip()} {song.strip()}") + if artist == "!" and song == "!": + random_search: bool = True + search_query: str = 'SELECT id, artist, song, lyrics, src, confidence FROM lyrics ORDER BY RANDOM() LIMIT 1' + search_params = None async with await _db_cursor.execute(search_query, search_params) as db_cursor: results: list = await db_cursor.fetchall() result_tracks: list = [] @@ -70,8 +76,11 @@ class Cache: result_tracks.append((_id, f"{_artist} - {_song}")) input_track: str = f"{artist} - {song}" matcher = utils.TrackMatcher() - best_match: tuple|None = matcher.find_best_match(input_track=input_track, + 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], float(1)) if not best_match: return None (candidate, confidence) = best_match diff --git a/lyric_search_new/sources/lrclib.py b/lyric_search_new/sources/lrclib.py index 2a51c2e..b906cf9 100644 --- a/lyric_search_new/sources/lrclib.py +++ b/lyric_search_new/sources/lrclib.py @@ -23,7 +23,7 @@ class LRCLib: """LRCLib Search Module""" def __init__(self): self.label: str = "LRCLib" - self.lrclib_url: str = "https://lrclib.net/api/get" + self.lrclib_url: str = "https://lrclib.net/api/search" self.headers: dict = common.SCRAPE_HEADERS self.timeout = ClientTimeout(connect=2, sock_read=4) self.datautils = utils.DataUtils() @@ -38,7 +38,9 @@ class LRCLib: artist: str = artist.strip().lower() song: str = song.strip().lower() logging.info("Searching %s - %s on %s", - artist, song, self.label) + artist, song, self.label) + + input_track: str = f"{artist} - {song}" returned_lyrics: str = '' async with ClientSession() as client: async with client.get(self.lrclib_url, @@ -55,22 +57,35 @@ class LRCLib: raise InvalidResponseException("Search response text was invalid (len < 100 chars.)") search_data: dict|None = await request.json() + + # logging.info("Search Data:\n%s", search_data) - if not isinstance(search_data, dict): + if not isinstance(search_data, list): raise InvalidResponseException("Invalid JSON.") - - if not isinstance(search_data['artistName'], str): + + possible_matches = [(x, f"{result.get('artistName')} - {result.get('trackName')}") + for x, result in enumerate(search_data)] + + best_match = self.matcher.find_best_match(input_track, + possible_matches)[0] + if not best_match: + return + best_match_id = best_match[0] + + if not isinstance(search_data[best_match_id]['artistName'], str): raise InvalidResponseException(f"Invalid JSON: Cannot find artistName key.\n{search_data}") - if not isinstance(search_data['trackName'], str): + if not isinstance(search_data[best_match_id]['trackName'], str): raise InvalidResponseException(f"Invalid JSON: Cannot find trackName key.\n{search_data}") + + if not isinstance(search_data[best_match_id]['plainLyrics'], str): + raise InvalidResponseException(f"Invalid JSON: Cannot find plainLyrics key.\n{search_data}") - returned_artist: str = search_data['artistName'] - returned_song: str = search_data['trackName'] - returned_lyrics: str = search_data['plainLyrics'] + returned_artist: str = search_data[best_match_id]['artistName'] + returned_song: str = search_data[best_match_id]['trackName'] + returned_lyrics: str = search_data[best_match_id]['plainLyrics'] returned_lyrics = self.datautils.scrub_lyrics(returned_lyrics) - input_track: str = f"{artist} - {song}" - returned_track: str = f"{artist} - {song}" + returned_track: str = f"{returned_artist} - {returned_song}" (_matched, confidence) = self.matcher.find_best_match(input_track=input_track, candidate_tracks=[(0, returned_track)]) if not confidence: diff --git a/lyric_search_new/tests.py b/lyric_search_new/tests.py index e869403..e998528 100644 --- a/lyric_search_new/tests.py +++ b/lyric_search_new/tests.py @@ -1,13 +1,18 @@ #!/usr/bin/env python3.12 -# tests +# pylint: disable=invalid-name, missing-function-docstring, wrong-import-position import asyncio import sys +import time sys.path.insert(1, '.') -import sources.cache, sources.genius, sources.aggregate, sources.lrclib +import sources.cache, sources.genius, sources.aggregate, sources.lrclib # pylint: disable=import-error, multiple-imports -test_artist = "hopsin" -test_song = "ill mind of fssfgdfhopsin 5" +""" +tests +""" + +test_artist = "enter shikari" +test_song = "goldfish" async def test_cache(artist, song): cache = sources.cache.Cache() @@ -47,7 +52,11 @@ async def test_aggregate(artist=None, song=None): loop = asyncio.new_event_loop() +start_time = time.time() # loop.run_until_complete(test_genius()) -# loop.run_until_complete(test_lrclib()) +loop.run_until_complete(test_lrclib()) # loop.run_until_complete(test_cache(artist=test_artist, song=test_song)) -loop.run_until_complete(test_aggregate()) +# loop.run_until_complete(test_aggregate()) +end_time = time.time() +diff = (end_time - start_time) +print(f"Response returned in: {diff:.6f}s") \ No newline at end of file diff --git a/state.py b/state.py index b3c9a78..7dbf79b 100644 --- a/state.py +++ b/state.py @@ -89,11 +89,7 @@ class State(FastAPI): await _db.commit() logging.debug("[State] Updated DB") - - - - - + async def increment_counter(self, counter: str): """Increment Counter""" if not counter in self.counters.keys():