diff --git a/lyric_search/constructors.py b/lyric_search/constructors.py index 106955e..31f8526 100644 --- a/lyric_search/constructors.py +++ b/lyric_search/constructors.py @@ -17,4 +17,26 @@ class LyricsResult: src: str lyrics: Union[str, list] confidence: int - time: float = 0.00 \ No newline at end of file + time: float = 0.00 + + +""" +Generic +""" +class InvalidLyricSearchResponseException(Exception): + pass + +""" +Genius +""" +class InvalidGeniusResponseException( + InvalidLyricSearchResponseException): + pass + +""" +LRCLib +""" + +class InvalidLRCLibResponseException( + InvalidLyricSearchResponseException): + pass \ No newline at end of file diff --git a/lyric_search/sources/genius.py b/lyric_search/sources/genius.py index 68ea638..2265d4a 100644 --- a/lyric_search/sources/genius.py +++ b/lyric_search/sources/genius.py @@ -9,16 +9,12 @@ from bs4 import BeautifulSoup, ResultSet # type: ignore import html as htm from . import private, common, cache, redis_cache from lyric_search import utils -from lyric_search.constructors import LyricsResult +from lyric_search.constructors import ( + LyricsResult, InvalidGeniusResponseException) logger = logging.getLogger() log_level = logging.getLevelName(logger.level) -class InvalidResponseException(Exception): - """ - InvalidResponseException - """ - class Genius: """ Genius Search Module @@ -60,23 +56,23 @@ class Genius: text: Optional[str] = await request.text() if not text: - raise InvalidResponseException("No search response.") + raise InvalidGeniusResponseException("No search response.") if len(text) < 100: - raise InvalidResponseException("Search response text was invalid (len < 100 chars.)") + raise InvalidGeniusResponseException("Search response text was invalid (len < 100 chars.)") search_data = await request.json() if not isinstance(search_data, dict): - raise InvalidResponseException("Invalid JSON.") + raise InvalidGeniusResponseException("Invalid JSON.") if not isinstance(search_data['response'], dict): - raise InvalidResponseException(f"Invalid JSON: Cannot find response key.\n{search_data}") + raise InvalidGeniusResponseException(f"Invalid JSON: Cannot find response key.\n{search_data}") if not isinstance(search_data['response']['sections'], list): - raise InvalidResponseException(f"Invalid JSON: Cannot find response->sections key.\n{search_data}") + raise InvalidGeniusResponseException(f"Invalid JSON: Cannot find response->sections key.\n{search_data}") if not isinstance(search_data['response']['sections'][0]['hits'], list): - raise InvalidResponseException("Invalid JSON: Cannot find response->sections[0]->hits key.") + raise InvalidGeniusResponseException("Invalid JSON: Cannot find response->sections[0]->hits key.") possible_matches: list = search_data['response']['sections'][0]['hits'] to_scrape: list[tuple] = [ @@ -98,10 +94,10 @@ class Genius: scrape_text: Optional[str] = await scrape_request.text() if not scrape_text: - raise InvalidResponseException("No scrape response.") + raise InvalidGeniusResponseException("No scrape response.") if len(scrape_text) < 100: - raise InvalidResponseException("Scrape response was invalid (len < 100 chars.)") + raise InvalidGeniusResponseException("Scrape response was invalid (len < 100 chars.)") html = BeautifulSoup(htm.unescape(scrape_text).replace('
', '\n'), "html.parser") diff --git a/lyric_search/sources/lrclib.py b/lyric_search/sources/lrclib.py index de8c11b..089a3d0 100644 --- a/lyric_search/sources/lrclib.py +++ b/lyric_search/sources/lrclib.py @@ -8,15 +8,11 @@ from aiohttp import ClientTimeout, ClientSession from lyric_search import utils from lyric_search.constructors import LyricsResult from . import common, cache, redis_cache +from constructors import InvalidLRCLibResponseException logger = logging.getLogger() log_level = logging.getLevelName(logger.level) -class InvalidResponseException(Exception): - """ - Invalid Response Exception - """ - class LRCLib: """LRCLib Search Module""" def __init__(self) -> None: @@ -62,18 +58,18 @@ class LRCLib: text: Optional[str] = await request.text() if not text: - raise InvalidResponseException("No search response.") + raise InvalidLRCLibResponseException("No search response.") if len(text) < 100: - raise InvalidResponseException("Search response text was invalid (len < 100 chars.)") + raise InvalidLRCLibResponseException("Search response text was invalid (len < 100 chars.)") search_data: Optional[Union[list, dict]] = await request.json() if not isinstance(search_data, list|dict): - raise InvalidResponseException("No JSON search data.") + raise InvalidLRCLibResponseException("No JSON search data.") # logging.info("Search Data:\n%s", search_data) if not isinstance(search_data, list): - raise InvalidResponseException("Invalid JSON.") + raise InvalidLRCLibResponseException("Invalid JSON.") if plain: possible_matches = [(x, f"{result.get('artistName')} - {result.get('trackName')}") @@ -92,21 +88,21 @@ class LRCLib: 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}") + raise InvalidLRCLibResponseException(f"Invalid JSON: Cannot find artistName key.\n{search_data}") if not isinstance(search_data[best_match_id]['trackName'], str): - raise InvalidResponseException(f"Invalid JSON: Cannot find trackName key.\n{search_data}") + raise InvalidLRCLibResponseException(f"Invalid JSON: Cannot find trackName key.\n{search_data}") returned_artist: str = search_data[best_match_id]['artistName'] returned_song: str = search_data[best_match_id]['trackName'] if plain: if not isinstance(search_data[best_match_id]['plainLyrics'], str): - raise InvalidResponseException(f"Invalid JSON: Cannot find plainLyrics key.\n{search_data}") + raise InvalidLRCLibResponseException(f"Invalid JSON: Cannot find plainLyrics key.\n{search_data}") returned_lyrics: str = search_data[best_match_id]['plainLyrics'] returned_lyrics = self.datautils.scrub_lyrics(returned_lyrics) else: if not isinstance(search_data[best_match_id]['syncedLyrics'], str): - raise InvalidResponseException(f"Invalid JSON: Cannot find syncedLyrics key.\n{search_data}") + raise InvalidLRCLibResponseException(f"Invalid JSON: Cannot find syncedLyrics key.\n{search_data}") returned_lyrics: str = search_data[best_match_id]['syncedLyrics'] lrc_obj = self.datautils.create_lrc_object(returned_lyrics) returned_track: str = f"{returned_artist} - {returned_song}" diff --git a/mypy.ini b/mypy.ini index 090d8ad..a7f647e 100644 --- a/mypy.ini +++ b/mypy.ini @@ -1,2 +1 @@ -[mypy] -ignore_errors = import-untyped \ No newline at end of file +[mypy] \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 8ce37ec..6fef5d5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -22,4 +22,6 @@ dependencies = [ "websockets>=14.2", "typing-inspect>=0.9.0", "http3>=0.6.7", -] \ No newline at end of file +] +[tool.mypy] +disable_error_code = import-untyped \ No newline at end of file diff --git a/utils/constructors.py b/utils/constructors.py new file mode 100644 index 0000000..8771623 --- /dev/null +++ b/utils/constructors.py @@ -0,0 +1,6 @@ +""" +LastFM +""" + +class InvalidLastFMResponseException(Exception): + pass \ No newline at end of file diff --git a/lastfm_wrapper.py b/utils/lastfm_wrapper.py similarity index 93% rename from lastfm_wrapper.py rename to utils/lastfm_wrapper.py index 66edad6..b2d987e 100644 --- a/lastfm_wrapper.py +++ b/utils/lastfm_wrapper.py @@ -4,6 +4,7 @@ from typing import Optional, Union import regex from aiohttp import ClientSession, ClientTimeout from constants import Constants +from .constructors import InvalidLastFMResponseException class LastFM: """LastFM Endpoints""" @@ -182,12 +183,20 @@ class LastFM: timeout=ClientTimeout(connect=3, sock_read=8)) as request: request.raise_for_status() data: dict = await request.json() + if not data.get('profile'): + raise InvalidLastFMResponseException("Data did not contain 'profile' key.") + + _id: int = data.get('id', None) + name: str = data.get('name', None) + profile: str = data.get('profile', '') + profile = regex.sub(r"(\[(\/{0,})(u|b|i)])", "", profile) + members: list = data.get('members', None) ret_obj: dict = { - 'id': data.get('id'), - 'name': data.get('name'), - 'profile': regex.sub(r"(\[(\/{0,})(u|b|i)])", "", data.get('profile')), - 'members': data.get('members'), + 'id': _id, + 'name': name, + 'profile': profile, + 'members': members, } return ret_obj except: