131 lines
No EOL
3.8 KiB
Python
131 lines
No EOL
3.8 KiB
Python
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.score_tracks()
|
|
self.library.auto_score()
|
|
|
|
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 |