refactor: add LRCData class
This commit is contained in:
@@ -13,9 +13,11 @@ albums or is played from different players.
|
||||
from typing import Optional
|
||||
from loguru import logger
|
||||
|
||||
|
||||
from .base import BaseFetcher
|
||||
from ..models import TrackMeta, LyricResult, CacheStatus
|
||||
from ..cache import CacheEngine
|
||||
from ..lrc import LRCData
|
||||
|
||||
|
||||
class CacheSearchFetcher(BaseFetcher):
|
||||
@@ -80,6 +82,6 @@ class CacheSearchFetcher(BaseFetcher):
|
||||
)
|
||||
return LyricResult(
|
||||
status=status,
|
||||
lyrics=best["lyrics"],
|
||||
lyrics=LRCData(best["lyrics"]),
|
||||
source=self.source_name,
|
||||
)
|
||||
|
||||
@@ -17,7 +17,7 @@ from mutagen.flac import FLAC
|
||||
|
||||
from .base import BaseFetcher
|
||||
from ..models import TrackMeta, LyricResult
|
||||
from ..lrc import detect_sync_status, normalize_tags, get_audio_path, get_sidecar_path
|
||||
from ..lrc import get_audio_path, get_sidecar_path, LRCData
|
||||
|
||||
|
||||
class LocalFetcher(BaseFetcher):
|
||||
@@ -48,11 +48,15 @@ class LocalFetcher(BaseFetcher):
|
||||
with open(lrc_path, "r", encoding="utf-8") as f:
|
||||
content = f.read().strip()
|
||||
if content:
|
||||
content = normalize_tags(content)
|
||||
status = detect_sync_status(content)
|
||||
logger.info(f"Local: found .lrc sidecar ({status.value})")
|
||||
lrc = LRCData(content)
|
||||
status = lrc.detect_sync_status()
|
||||
logger.info(
|
||||
f"Local: found .lrc sidecar ({status.value}) for {audio_path.name}"
|
||||
)
|
||||
return LyricResult(
|
||||
status=status, lyrics=content, source=self.source_name
|
||||
status=status,
|
||||
lyrics=lrc,
|
||||
source=self.source_name,
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(f"Local: error reading {lrc_path}: {e}")
|
||||
@@ -81,12 +85,14 @@ class LocalFetcher(BaseFetcher):
|
||||
break
|
||||
|
||||
if lyrics:
|
||||
lyrics = normalize_tags(lyrics.strip())
|
||||
status = detect_sync_status(lyrics)
|
||||
logger.info(f"Local: found embedded lyrics ({status.value})")
|
||||
lrc = LRCData(lyrics)
|
||||
status = lrc.detect_sync_status()
|
||||
logger.info(
|
||||
f"Local: found embedded lyrics ({status.value}) for {audio_path.name}"
|
||||
)
|
||||
return LyricResult(
|
||||
status=status,
|
||||
lyrics=lyrics,
|
||||
lyrics=lrc,
|
||||
source=f"{self.source_name} (embedded)",
|
||||
)
|
||||
else:
|
||||
|
||||
@@ -15,7 +15,7 @@ from urllib.parse import urlencode
|
||||
|
||||
from .base import BaseFetcher
|
||||
from ..models import TrackMeta, LyricResult, CacheStatus
|
||||
from ..lrc import normalize_tags
|
||||
from ..lrc import LRCData
|
||||
from ..config import (
|
||||
HTTP_TIMEOUT,
|
||||
TTL_UNSYNCED,
|
||||
@@ -79,20 +79,16 @@ class LrclibFetcher(BaseFetcher):
|
||||
unsynced = data.get("plainLyrics")
|
||||
|
||||
if isinstance(synced, str) and synced.strip():
|
||||
lyrics = normalize_tags(synced.strip())
|
||||
logger.info(
|
||||
f"LRCLIB: got synced lyrics ({len(lyrics.splitlines())} lines)"
|
||||
)
|
||||
lyrics = LRCData(synced)
|
||||
logger.info(f"LRCLIB: got synced lyrics ({len(lyrics)} lines)")
|
||||
return LyricResult(
|
||||
status=CacheStatus.SUCCESS_SYNCED,
|
||||
lyrics=lyrics,
|
||||
source=self.source_name,
|
||||
)
|
||||
elif isinstance(unsynced, str) and unsynced.strip():
|
||||
lyrics = normalize_tags(unsynced.strip())
|
||||
logger.info(
|
||||
f"LRCLIB: got unsynced lyrics ({len(lyrics.splitlines())} lines)"
|
||||
)
|
||||
lyrics = LRCData(unsynced)
|
||||
logger.info(f"LRCLIB: got unsynced lyrics ({len(lyrics)} lines)")
|
||||
return LyricResult(
|
||||
status=CacheStatus.SUCCESS_UNSYNCED,
|
||||
lyrics=lyrics,
|
||||
|
||||
@@ -16,7 +16,7 @@ from urllib.parse import urlencode
|
||||
|
||||
from .base import BaseFetcher
|
||||
from ..models import TrackMeta, LyricResult, CacheStatus
|
||||
from ..lrc import normalize_tags
|
||||
from ..lrc import LRCData
|
||||
from ..config import (
|
||||
HTTP_TIMEOUT,
|
||||
TTL_UNSYNCED,
|
||||
@@ -82,20 +82,16 @@ class LrclibSearchFetcher(BaseFetcher):
|
||||
unsynced = best.get("plainLyrics")
|
||||
|
||||
if isinstance(synced, str) and synced.strip():
|
||||
lyrics = normalize_tags(synced.strip())
|
||||
logger.info(
|
||||
f"LRCLIB-search: got synced lyrics ({len(lyrics.splitlines())} lines)"
|
||||
)
|
||||
lyrics = LRCData(synced)
|
||||
logger.info(f"LRCLIB-search: got synced lyrics ({len(lyrics)} lines)")
|
||||
return LyricResult(
|
||||
status=CacheStatus.SUCCESS_SYNCED,
|
||||
lyrics=lyrics,
|
||||
source=self.source_name,
|
||||
)
|
||||
elif isinstance(unsynced, str) and unsynced.strip():
|
||||
lyrics = normalize_tags(unsynced.strip())
|
||||
logger.info(
|
||||
f"LRCLIB-search: got unsynced lyrics ({len(lyrics.splitlines())} lines)"
|
||||
)
|
||||
lyrics = LRCData(unsynced)
|
||||
logger.info(f"LRCLIB-search: got unsynced lyrics ({len(lyrics)} lines)")
|
||||
return LyricResult(
|
||||
status=CacheStatus.SUCCESS_UNSYNCED,
|
||||
lyrics=lyrics,
|
||||
|
||||
@@ -18,7 +18,7 @@ from loguru import logger
|
||||
|
||||
from .base import BaseFetcher
|
||||
from ..models import TrackMeta, LyricResult, CacheStatus
|
||||
from ..lrc import detect_sync_status, normalize_tags
|
||||
from ..lrc import LRCData
|
||||
from ..config import (
|
||||
HTTP_TIMEOUT,
|
||||
TTL_NOT_FOUND,
|
||||
@@ -181,15 +181,13 @@ class NeteaseFetcher(BaseFetcher):
|
||||
return LyricResult(status=CacheStatus.NOT_FOUND, ttl=TTL_NOT_FOUND)
|
||||
|
||||
# Determine sync status
|
||||
lrc = normalize_tags(lrc)
|
||||
status = detect_sync_status(lrc)
|
||||
lrcdata = LRCData(lrc)
|
||||
status = lrcdata.detect_sync_status()
|
||||
logger.info(
|
||||
f"Netease: got {status.value} lyrics for song_id={song_id} "
|
||||
f"({len(lrc.splitlines())} lines)"
|
||||
)
|
||||
return LyricResult(
|
||||
status=status, lyrics=lrc.strip(), source=self.source_name
|
||||
f"({len(lrcdata)} lines)"
|
||||
)
|
||||
return LyricResult(status=status, lyrics=lrcdata, source=self.source_name)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Netease: lyric fetch failed for song_id={song_id}: {e}")
|
||||
|
||||
@@ -17,7 +17,7 @@ from loguru import logger
|
||||
|
||||
from .base import BaseFetcher
|
||||
from ..models import TrackMeta, LyricResult, CacheStatus
|
||||
from ..lrc import detect_sync_status, normalize_tags
|
||||
from ..lrc import LRCData
|
||||
from ..config import (
|
||||
HTTP_TIMEOUT,
|
||||
TTL_NOT_FOUND,
|
||||
@@ -142,15 +142,13 @@ class QQMusicFetcher(BaseFetcher):
|
||||
logger.debug(f"QQMusic: empty lyrics for mid={mid}")
|
||||
return LyricResult(status=CacheStatus.NOT_FOUND, ttl=TTL_NOT_FOUND)
|
||||
|
||||
lrc = normalize_tags(lrc)
|
||||
status = detect_sync_status(lrc)
|
||||
lrcdata = LRCData(lrc)
|
||||
status = lrcdata.detect_sync_status()
|
||||
logger.info(
|
||||
f"QQMusic: got {status.value} lyrics for mid={mid} "
|
||||
f"({len(lrc.splitlines())} lines)"
|
||||
)
|
||||
return LyricResult(
|
||||
status=status, lyrics=lrc.strip(), source=self.source_name
|
||||
f"({len(lrcdata)} lines)"
|
||||
)
|
||||
return LyricResult(status=status, lyrics=lrcdata, source=self.source_name)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"QQMusic: lyric fetch failed for mid={mid}: {e}")
|
||||
|
||||
@@ -28,7 +28,7 @@ from loguru import logger
|
||||
|
||||
from .base import BaseFetcher
|
||||
from ..models import TrackMeta, LyricResult, CacheStatus
|
||||
from ..lrc import normalize_tags
|
||||
from ..lrc import LRCData
|
||||
from ..config import (
|
||||
HTTP_TIMEOUT,
|
||||
SPOTIFY_APP_VERSION,
|
||||
@@ -358,7 +358,7 @@ class SpotifyFetcher(BaseFetcher):
|
||||
# Unsynced: emit with zero timestamps
|
||||
lrc_lines.append(f"[00:00.00]{words}")
|
||||
|
||||
content = normalize_tags("\n".join(lrc_lines))
|
||||
content = LRCData("\n".join(lrc_lines))
|
||||
status = (
|
||||
CacheStatus.SUCCESS_SYNCED
|
||||
if is_synced
|
||||
|
||||
Reference in New Issue
Block a user