from src.Library import * from typing import Any, Iterable import json from datetime import datetime from pathlib import Path def get_artists_str(artists_pack): track_artists = [artist['name'] for artist in artists_pack] artists = " ".join(track_artists) return artists class Parser: def __init__(self): self.track_map: dict[str, Track] = {} self.artist_map: dict[str, Artist] = {} self.album_map: dict[str, Album] = {} self.library = Library() def parse(self, playlists: Path, tracks: Path, top_tracks: Path, top_artists: Path) -> Library: self.library = Library() self.parse_tracks(json.loads(tracks.read_text())) self.parse_playlists(json.loads(playlists.read_text())) self.parse_top_artists(json.loads(top_artists.read_text())) self.parse_top_tracks(json.loads(top_tracks.read_text())) self.library.update_cache() self.library.name = "Spotify" self.library.auto_score() self.score_tracks() return self.library def parse_playlists(self, data): for name, tracks in data.items(): playlist = Playlist() playlist.title = name for track in tracks: track_data = track.get("track") if track_data: track_id = track_data.get("id") playlist.tracks.append(self.parse_track(track_data, track.get("added_at"))) self.library.playlists.append(playlist) def parse_top_tracks(self, data): for track in data: if track.get("id") in self.track_map: self.library.top_tracks.append(self.track_map.get(track.get("id"))) def parse_top_artists(self, data): for artist in data: if artist.get("id") in self.artist_map: self.library.top_artists.append(self.artist_map.get(artist.get("id"))) def parse_tracks(self, data): for track in data: self.parse_track(track.get("track"), track.get("added_at")) for track in data: self.library.liked_tracks.append(self.track_map.get(track.get("track").get("id"))) def parse_track(self, data: dict[str, Any], added_time : datetime) -> Track: track_id = data.get("id") if track_id in self.track_map: return self.track_map[track_id] track = Track() self.track_map[track_id] = track track.id = track_id track.title = data.get("name") track.artists = [] + self.parse_album(data.get("album")).artists track.album = self.parse_album(data.get("album")) track.duration_ms = data.get("duration_ms") self.library.tracks.append(track) return track def parse_album(self, data): album_id = data.get("id") if album_id in self.album_map: return self.album_map[album_id] album = Album() self.album_map[album_id] = album album.id = data.get("id") album.title = data.get("name") album.artists = [self.parse_artist(artist) for artist in data.get("artists")] self.library.albums.append(album) return album def parse_artist(self, data: dict[str, Any]) -> Artist: artist_id = data.get("id") if artist_id in self.artist_map: return self.artist_map[artist_id] artist = Artist() self.artist_map[artist_id] = artist artist.id = data.get("id") artist.title = data.get("name") if artist.title is None: artist.title = "err_no_title" self.library.artists.append(artist) return artist def score_tracks(self): for idx, track in enumerate(self.library.top_tracks): score = len(self.library.top_tracks) - idx track.auto_score = score