MusicIndexer/src/Library.py
Шурупов Илья Викторович b6d88d435a nice
2026-02-07 15:17:59 +03:00

128 lines
3.7 KiB
Python

from __future__ import annotations
from datetime import datetime
from pathlib import Path
from typing import List, Optional, Any
class Entity:
def __init__(self):
self.id: str = None
self.mbid: str = None
self.title: str = None
self.duration_ms: int = None
self.fav: bool = False
self.rating: int = 0
self.play_count: int = 0
self.date_added: datetime = None
self.date_released: datetime = None
self.date_last_play: datetime = None
self.auto_score: float = 0
self.local_id: str = None
self.local_path: Path = None
self.resolved_percentage: float = 0
class Artist(Entity):
def __init__(self):
super().__init__()
self.tracks: List[Track] = []
self.albums: List[Album] = []
class Track(Entity):
def __init__(self):
super().__init__()
self.artists: List[Artist] = []
self.album: Album = None
self.has_lyrics: bool = False
class Album(Entity):
def __init__(self):
super().__init__()
self.tracks: List[Track] = []
self.artists: List[Artist] = []
class Playlist(Entity):
def __init__(self):
super().__init__()
self.tracks: List[Track] = []
self.created_at: datetime = None
self.description: str = None
class Library:
def __init__(self):
self.artists: List[Artist] = []
self.playlists: List[Playlist] = []
self.tracks: List[Track] = []
self.albums: List[Album] = []
self.liked_tracks: List[Track] = []
self.top_tracks: List[Track] = []
self.top_artists: List[Artist] = []
self.artist_map: dict[str, Artist] = None
self.album_map: dict[str, Album] = None
self.track_map: dict[str, Track] = None
self.name = "Unnamed"
def update_cache(self):
self.update_id_maps()
self.create_reverse_links()
self.score_albums()
self.calc_resolved_percentage()
def update_id_maps(self):
self.artist_map: dict[str, Artist] = {artist.id: artist for artist in self.artists}
self.album_map: dict[str, Album] = {album.id: album for album in self.albums}
self.track_map: dict[str, Track] = {track.id: track for track in self.tracks}
def create_reverse_links(self):
for track_id, track in self.track_map.items():
for artist in track.artists:
if track not in artist.tracks:
artist.tracks.append(track)
if track not in track.album.tracks:
track.album.tracks.append(track)
for album_id, album in self.album_map.items():
for artist in album.artists:
if album not in artist.albums:
artist.albums.append(album)
def auto_score(self):
self.score_albums()
self.score_artists()
def score_artists(self):
for track in self.tracks:
for artist in track.artists:
artist.auto_score += track.auto_score
def score_albums(self):
for track in self.tracks:
track.album.auto_score += track.auto_score
def calc_resolved_percentage(self):
for artist in self.artists:
artist_count_resolved = 0
artist_count = 0
for album in artist.albums:
album_count_resolved = 0
for track in album.tracks:
if track.local_id:
album_count_resolved += 1
album.resolved_percentage = album_count_resolved / len(album.tracks)
artist_count_resolved += album_count_resolved
artist_count += len(album.tracks)
artist.resolved_percentage = artist_count_resolved / artist_count