MusicIndexer/Flow.py
Шурупов Илья Викторович b6c59e81ad tmp
2026-02-07 11:24:59 +03:00

134 lines
No EOL
4.5 KiB
Python

from tqdm import tqdm
import src.lyrics.lyrics as Lyrics
from Env import client_id, client_secret, local_library_path
from Env import work_dir
from src.Library import *
from src.LibrarySerializer import LibrarySaver, LibraryLoader
from src.backends.spotify.SpotifyWebAPI import fetch_all
from src.backends.spotify.ParseSpotify import Parser
from src.backends.local.LocalLibraryIndexer import update_local_library
from src.backends.local.ParseLocal import LocalParser
from src.backends.itunes.ParseItunesXml import ParseItunesXml
from src.mappers.RemoteLibraryResolver import resolve_remote_tracks
from src.StatGenerator import log_stats
class Flow:
spotify_library : Library = None
local_library : Library = None
@staticmethod
def fetch_spotify(self):
fetch_all(client_id, client_secret, work_dir)
@staticmethod
def fetch_local():
update_local_library(local_library_path, work_dir)
@staticmethod
def parse_spotify_library():
parser = Parser()
library_parsed = parser.parse(
work_dir / "spotify" / "playlistTracks.json",
work_dir / "spotify" / "tracks.json",
work_dir / "spotify" / "top_tracks.json",
work_dir / "spotify" / "top_artists.json",
)
LibrarySaver(library_parsed).save(work_dir / "spotify_library.json")
@staticmethod
def parse_itunes_library():
parser = ParseItunesXml()
library_parsed = parser.parse(
work_dir / "itunes" / "Library.xml",
work_dir / "itunes" / "Library.json"
)
LibrarySaver(library_parsed).save(work_dir / "itunes_library.json")
@staticmethod
def parse_local_library():
parser = LocalParser()
library_parsed = parser.parse(work_dir / "local" / "local_library.json")
LibrarySaver(library_parsed).save(work_dir / "local_library.json")
def fetch_and_save_lyrics(self):
"""
Fetches and writes lyrics for tracks that don't have lyrics yet.
Displays stats and uses a progress bar.
"""
# ---------- Step 1: Collect tracks without lyrics ----------
tracks_missing_lyrics = [
track for track in self.local_library.tracks
if len(track.artists) > 0 and not track.has_lyrics
]
total_tracks = len(self.local_library.tracks)
missing_count = len(tracks_missing_lyrics)
print(f"[INFO] Total tracks in library: {total_tracks}")
print(f"[INFO] Tracks missing lyrics: {missing_count}")
if missing_count == 0:
print("[INFO] No tracks need lyrics. Exiting.")
return
# ---------- Step 2: Fetch and write lyrics with progress bar ----------
for track in tqdm(tracks_missing_lyrics, desc="Fetching lyrics", unit="track"):
artist_name = track.artists[0].title
album_title = track.album.title if track.album else "Unknown Album"
print(f"\n[INFO] Processing: '{track.title}' by '{artist_name}' on '{album_title}'")
lyrics_text = Lyrics.fetch_lyrics(artist_name, album_title, track.title, track.duration_ms)
if lyrics_text:
print("[SUCCESS] Lyrics found, writing to file...")
file_path = local_library_path / track.local_path
try:
Lyrics.write_lyrics(file_path, lyrics_text)
print(f"[SUCCESS] Lyrics written for '{track.title}'")
except Exception as e:
print(f"[ERROR] Failed to write lyrics for '{track.title}': {e}")
else:
print(f"[WARNING] Lyrics not found for '{track.title}'")
def load_libraries(self):
self.spotify_library = LibraryLoader().load(work_dir / "spotify_library.json")
self.local_library = LibraryLoader().load(work_dir / "local_library.json")
def save_libraries(self):
LibrarySaver(self.spotify_library).save(work_dir / "spotify_library.json")
LibrarySaver(self.local_library).save(work_dir / "local_library.json")
def map_local_to_spotify(self):
resolve_remote_tracks(client_id, client_secret, self.local_library, self.spotify_library, work_dir)
def log_stats(self):
log_stats(work_dir / "remote_to_local_map.json", work_dir / "stats", self.local_library, self.spotify_library)
def run(self, arg):
self.fetch_local()
# self.do_fetch_spotify()
self.parse_local_library()
self.parse_spotify_library()
self.load_libraries()
# self.map_local_to_spotify()
return True