#!/usr/bin/env python3.12 from typing import Optional from lyric_search.constructors import LyricsResult from lyric_search import notifier import sys import logging import traceback sys.path.insert(1,'..') from . import cache, redis_cache, genius, lrclib class Aggregate: """ Aggregate all source methods """ def __init__(self, exclude_methods=None) -> None: if not exclude_methods: exclude_methods: list = [] self.exclude_methods = exclude_methods self.redis_cache = redis_cache.RedisCache() self.notifier = notifier.DiscordNotifier() async def search(self, artist: str, song: str, plain: Optional[bool] = True) -> Optional[LyricsResult]: """ Aggregate Search Args: artist (str): Artist to search song (str): Song to search plain (bool): Search for plain lyrics (lrc otherwise) Returns: Optional[LyricsResult]: The result, if found - None otherwise. """ if not plain: logging.info("LRCs requested, limiting search to LRCLib") self.exclude_methods = ["genius", "cache"] logging.info("Performing aggregate search") cache_search = cache.Cache() genius_search = genius.Genius() lrclib_search = lrclib.LRCLib() sources: list = [ cache_search, lrclib_search, genius_search, ] if not plain: sources = [lrclib_search] # Only LRCLib supported for synced lyrics search_result: Optional[LyricsResult] = None for source in sources: if source.label.lower() in self.exclude_methods: if source.label.lower() == "cache" or not plain: logging.info("Exclude conditions rejected - source requested to exclude: %s, plain: %s", source.label, plain) else: if plain: logging.info("Skipping source: %s, excluded.", source.label) continue search_result = await source.search(artist=artist, song=song, plain=plain) if search_result: break logging.info("%s: NOT FOUND!", source.label) if not search_result: logging.info("%s - %s: all sources exhausted, not found.", artist, song) if plain: # do not record LRC fails try: await self.redis_cache.increment_found_count("failed") self.notifier.send("WARNING", f"Could not find {artist} - {song} via queried sources.") except Exception as e: traceback.print_exc() logging.info("Could not increment redis failed counter: %s", str(e)) self.notifier.send(f"ERROR @ {__file__.rsplit("/", maxsplit=1)[-1]}", f"Could not increment redis failed counter: {str(e)}") return search_result