refactor initial not fully recovered

This commit is contained in:
Шурупов Илья Викторович 2026-01-04 19:25:42 +03:00
parent 2824bd1a0e
commit 72af96eada
16 changed files with 925 additions and 267 deletions

159
src/Library.py Normal file
View file

@ -0,0 +1,159 @@
from __future__ import annotations
import json
from datetime import datetime
from pathlib import Path
from typing import List, Optional, Any
# =========================
# Core models
# =========================
class Track:
def __init__(
self,
*,
id: str,
title: str,
artists: List[str],
album: Optional[str] = None,
duration_ms: Optional[int] = None,
added_at: Optional[datetime] = None,
spotify: Optional["SpotifyData"] = None,
local: Optional["LocalData"] = None,
):
self.id = id
self.title = title
self.artists = artists
self.album = album
self.duration_ms = duration_ms
self.added_at = added_at
self.spotify = spotify
self.local = local
class Playlist:
def __init__(
self,
*,
name: str,
tracks: Optional[List[Track]] = None,
created_at: Optional[datetime] = None,
description: Optional[str] = None,
spotify: Optional["SpotifyData"] = None,
):
self.name = name
self.tracks = tracks or []
self.created_at = created_at
self.description = description
self.spotify = spotify
class Album:
def __init__(
self,
*,
title: str,
release_date: Optional[str] = None,
tracks: Optional[List[Track]] = None,
spotify: Optional["SpotifyData"] = None,
):
self.title = title
self.release_date = release_date
self.tracks = tracks or []
self.spotify = spotify
class TrackList:
def __init__(self, *, tracks: Optional[List[Track]] = None):
self.tracks = tracks or []
def total_duration_ms(self) -> int:
return sum(t.duration_ms or 0 for t in self.tracks)
# =========================
# Spotify models
# =========================
class SpotifyArtist:
def __init__(self, *, id: str, name: str, uri: str, url: str):
self.id = id
self.name = name
self.uri = uri
self.url = url
class SpotifyAlbum:
def __init__(
self,
*,
id: str,
name: str,
release_date: str,
total_tracks: int,
uri: str,
url: str,
):
self.id = id
self.name = name
self.release_date = release_date
self.total_tracks = total_tracks
self.uri = uri
self.url = url
class SpotifyData:
def __init__(
self,
*,
id: str,
uri: str,
url: str,
href: str,
file_path: Optional[Path] = None,
popularity: Optional[int] = None,
is_playable: Optional[bool] = None,
is_local: Optional[bool] = None,
artists: Optional[List[SpotifyArtist]] = None,
album: Optional[SpotifyAlbum] = None,
external_ids: Optional[dict[str, str]] = None,
):
self.id = id
self.uri = uri
self.url = url
self.href = href
self.file_path = file_path
self.popularity = popularity
self.is_playable = is_playable
self.is_local = is_local
self.artists = artists or []
self.album = album
self.external_ids = external_ids or {}
class LocalData:
def __init__(
self,
*,
path: str,
):
self.path = path
# =========================
# Library container
# =========================
class Library:
def __init__(
self,
*,
playlists: Optional[List[Playlist]] = None,
tracks: Optional[List[Track]] = None,
tracklists: Optional[List[TrackList]] = None,
albums: Optional[List[Album]] = None,
):
self.playlists = playlists or []
self.tracks = tracks or []
self.tracklists = tracklists or []
self.albums = albums or []