minor
This commit is contained in:
@@ -80,9 +80,9 @@ class LyricSearch(FastAPI):
|
|||||||
)
|
)
|
||||||
|
|
||||||
for endpoint, handler in self.endpoints.items():
|
for endpoint, handler in self.endpoints.items():
|
||||||
times: int = 20
|
times: int = 5
|
||||||
seconds: int = 2
|
seconds: int = 2
|
||||||
rate_limit: tuple[int, int] = (2, 3) # Default; (Times, Seconds)
|
rate_limit: tuple[int, int] = (times, seconds) # Default; (Times, Seconds)
|
||||||
_schema_include = endpoint in ["lyric/search"]
|
_schema_include = endpoint in ["lyric/search"]
|
||||||
|
|
||||||
if (
|
if (
|
||||||
|
|||||||
@@ -307,7 +307,7 @@ class Radio(FastAPI):
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
async def album_art_handler(
|
def album_art_handler(
|
||||||
self, request: Request, track_id: Optional[int] = None,
|
self, request: Request, track_id: Optional[int] = None,
|
||||||
station: Station = "main"
|
station: Station = "main"
|
||||||
) -> Response:
|
) -> Response:
|
||||||
@@ -371,6 +371,14 @@ class Radio(FastAPI):
|
|||||||
ret_obj.pop("file_path")
|
ret_obj.pop("file_path")
|
||||||
return JSONResponse(content=ret_obj)
|
return JSONResponse(content=ret_obj)
|
||||||
|
|
||||||
|
def _bg_cache_art(self, track_id: int, file_path: str):
|
||||||
|
try:
|
||||||
|
album_art = self.radio_util.get_album_art(track_id=track_id)
|
||||||
|
if not album_art:
|
||||||
|
self.radio_util.cache_album_art(track_id, file_path)
|
||||||
|
except Exception as e:
|
||||||
|
logging.error(f"Background art cache error: {e}")
|
||||||
|
|
||||||
async def radio_get_next(
|
async def radio_get_next(
|
||||||
self,
|
self,
|
||||||
data: ValidRadioNextRequest,
|
data: ValidRadioNextRequest,
|
||||||
@@ -448,13 +456,7 @@ class Radio(FastAPI):
|
|||||||
logging.info("radio_get_next Exception: %s", str(e))
|
logging.info("radio_get_next Exception: %s", str(e))
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
|
|
||||||
try:
|
background_tasks.add_task(self._bg_cache_art, next["id"], next["file_path"])
|
||||||
album_art = self.radio_util.get_album_art(track_id=next["id"])
|
|
||||||
if not album_art:
|
|
||||||
self.radio_util.cache_album_art(next["id"], next["file_path"])
|
|
||||||
except Exception as e:
|
|
||||||
logging.info("radio_get_next Exception: %s", str(e))
|
|
||||||
traceback.print_exc()
|
|
||||||
|
|
||||||
return JSONResponse(content=next)
|
return JSONResponse(content=next)
|
||||||
|
|
||||||
@@ -496,8 +498,12 @@ class Radio(FastAPI):
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
search: bool = self.radio_util.search_db(
|
loop = asyncio.get_running_loop()
|
||||||
artistsong=artistsong, artist=artist, song=song, station=data.station
|
search: bool = await loop.run_in_executor(
|
||||||
|
None,
|
||||||
|
lambda: self.radio_util.search_db(
|
||||||
|
artistsong=artistsong, artist=artist, song=song, station=data.station
|
||||||
|
)
|
||||||
)
|
)
|
||||||
if data.alsoSkip:
|
if data.alsoSkip:
|
||||||
await self.radio_util._ls_skip(data.station)
|
await self.radio_util._ls_skip(data.station)
|
||||||
@@ -764,7 +770,22 @@ class Radio(FastAPI):
|
|||||||
|
|
||||||
logging.info(f"[LRC] Starting fetch for {station}: {artist} - {title}")
|
logging.info(f"[LRC] Starting fetch for {station}: {artist} - {title}")
|
||||||
|
|
||||||
# Try SR first with timeout
|
# Try LRCLib first with timeout
|
||||||
|
try:
|
||||||
|
async with asyncio.timeout(10.0): # 10 second timeout
|
||||||
|
logging.info("[LRC] Trying LRCLib")
|
||||||
|
lrclib_result = await self.lrclib.search(artist, title, plain=False, raw=True)
|
||||||
|
if lrclib_result and lrclib_result.lyrics and isinstance(lrclib_result.lyrics, str):
|
||||||
|
logging.info("[LRC] Found from LRCLib")
|
||||||
|
return lrclib_result.lyrics, "LRCLib"
|
||||||
|
except asyncio.TimeoutError:
|
||||||
|
logging.warning("[LRC] LRCLib fetch timed out")
|
||||||
|
except Exception as e:
|
||||||
|
logging.error(f"[LRC] LRCLib fetch error: {e}")
|
||||||
|
|
||||||
|
logging.info("[LRC] LRCLib fetch completed without results")
|
||||||
|
|
||||||
|
# Try SR as fallback with timeout
|
||||||
try:
|
try:
|
||||||
async with asyncio.timeout(10.0): # 10 second timeout
|
async with asyncio.timeout(10.0): # 10 second timeout
|
||||||
lrc = await self.sr_util.get_lrc_by_artist_song(
|
lrc = await self.sr_util.get_lrc_by_artist_song(
|
||||||
@@ -778,21 +799,6 @@ class Radio(FastAPI):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.error(f"[LRC] SR fetch error: {e}")
|
logging.error(f"[LRC] SR fetch error: {e}")
|
||||||
|
|
||||||
logging.info("[LRC] SR fetch completed without results")
|
|
||||||
|
|
||||||
# Try LRCLib as fallback with timeout
|
|
||||||
try:
|
|
||||||
async with asyncio.timeout(10.0): # 10 second timeout
|
|
||||||
logging.info("[LRC] Trying LRCLib fallback")
|
|
||||||
lrclib_result = await self.lrclib.search(artist, title, plain=False)
|
|
||||||
if lrclib_result and lrclib_result.lyrics and isinstance(lrclib_result.lyrics, str):
|
|
||||||
logging.info("[LRC] Found from LRCLib")
|
|
||||||
return lrclib_result.lyrics, "LRCLib"
|
|
||||||
except asyncio.TimeoutError:
|
|
||||||
logging.warning("[LRC] LRCLib fetch timed out")
|
|
||||||
except Exception as e:
|
|
||||||
logging.error(f"[LRC] LRCLib fetch error: {e}")
|
|
||||||
|
|
||||||
logging.info("[LRC] No lyrics found from any source")
|
logging.info("[LRC] No lyrics found from any source")
|
||||||
return None, "None"
|
return None, "None"
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -804,11 +810,21 @@ class Radio(FastAPI):
|
|||||||
try:
|
try:
|
||||||
async with self.lrc_cache_locks[station]:
|
async with self.lrc_cache_locks[station]:
|
||||||
self.lrc_cache.pop(station, None)
|
self.lrc_cache.pop(station, None)
|
||||||
lrc, source = await self._fetch_and_cache_lrc(station, track_json)
|
|
||||||
if lrc:
|
lrc, source = await self._fetch_and_cache_lrc(station, track_json)
|
||||||
self.lrc_cache[station] = lrc
|
|
||||||
|
async with self.lrc_cache_locks[station]:
|
||||||
|
# Verify we are still on the same song
|
||||||
|
current_track = self.radio_util.now_playing.get(station)
|
||||||
|
if current_track and current_track.get("uuid") == track_json.get("uuid"):
|
||||||
|
if lrc:
|
||||||
|
self.lrc_cache[station] = lrc
|
||||||
|
else:
|
||||||
|
self.lrc_cache[station] = None
|
||||||
else:
|
else:
|
||||||
self.lrc_cache[station] = None
|
logging.info(f"[LRC] Discarding fetch result for {station} as track changed.")
|
||||||
|
return
|
||||||
|
|
||||||
if lrc:
|
if lrc:
|
||||||
await self.broadcast_lrc(station, lrc, source)
|
await self.broadcast_lrc(station, lrc, source)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ class LRCLib:
|
|||||||
song: str,
|
song: str,
|
||||||
plain: Optional[bool] = True,
|
plain: Optional[bool] = True,
|
||||||
duration: Optional[int] = None,
|
duration: Optional[int] = None,
|
||||||
|
raw: bool = False,
|
||||||
) -> Optional[LyricsResult]:
|
) -> Optional[LyricsResult]:
|
||||||
"""
|
"""
|
||||||
LRCLib Local Database Search
|
LRCLib Local Database Search
|
||||||
@@ -34,6 +35,7 @@ class LRCLib:
|
|||||||
song (str): the song to search
|
song (str): the song to search
|
||||||
plain (bool): return plain lyrics (True) or synced lyrics (False)
|
plain (bool): return plain lyrics (True) or synced lyrics (False)
|
||||||
duration (int): optional track duration for better matching
|
duration (int): optional track duration for better matching
|
||||||
|
raw (bool): return raw LRC string instead of parsed object (only for synced)
|
||||||
Returns:
|
Returns:
|
||||||
Optional[LyricsResult]: The result, if found - None otherwise.
|
Optional[LyricsResult]: The result, if found - None otherwise.
|
||||||
"""
|
"""
|
||||||
@@ -119,7 +121,10 @@ class LRCLib:
|
|||||||
logging.info("No synced lyrics available on %s", self.label)
|
logging.info("No synced lyrics available on %s", self.label)
|
||||||
return None
|
return None
|
||||||
returned_lyrics = best_match.synced_lyrics
|
returned_lyrics = best_match.synced_lyrics
|
||||||
lrc_obj = self.datautils.create_lrc_object(returned_lyrics)
|
if raw:
|
||||||
|
lrc_obj = returned_lyrics
|
||||||
|
else:
|
||||||
|
lrc_obj = self.datautils.create_lrc_object(returned_lyrics)
|
||||||
|
|
||||||
# Calculate match confidence
|
# Calculate match confidence
|
||||||
input_track = f"{artist} - {song}"
|
input_track = f"{artist} - {song}"
|
||||||
|
|||||||
Reference in New Issue
Block a user