Files
deezspot-spotizerr-dev/deezspot/models/librespot/playlist.py

205 lines
5.5 KiB
Python

#!/usr/bin/python3
from dataclasses import dataclass, field
from typing import Optional, Dict, Any, List, Union
from .types import ExternalUrls, _str, _int
from .track import Track as TrackModel
@dataclass
class UserMini:
id: Optional[str] = None
type: str = "user"
uri: Optional[str] = None
display_name: Optional[str] = None
external_urls: ExternalUrls = field(default_factory=ExternalUrls)
@staticmethod
def from_dict(obj: Any) -> "UserMini":
if not isinstance(obj, dict):
return UserMini()
return UserMini(
id=_str(obj.get("id")),
type=_str(obj.get("type")) or "user",
uri=_str(obj.get("uri")),
display_name=_str(obj.get("display_name")),
external_urls=ExternalUrls.from_dict(obj.get("external_urls", {})),
)
def to_dict(self) -> Dict[str, Any]:
out = {
"id": self.id,
"type": self.type,
"uri": self.uri,
"display_name": self.display_name,
"external_urls": self.external_urls.to_dict(),
}
return {k: v for k, v in out.items() if v not in (None, {}, [], "")}
@dataclass
class TrackStub:
id: Optional[str] = None
type: str = "track"
uri: Optional[str] = None
external_urls: ExternalUrls = field(default_factory=ExternalUrls)
@staticmethod
def from_dict(obj: Any) -> "TrackStub":
if not isinstance(obj, dict):
return TrackStub()
return TrackStub(
id=_str(obj.get("id")),
type=_str(obj.get("type")) or "track",
uri=_str(obj.get("uri")),
external_urls=ExternalUrls.from_dict(obj.get("external_urls", {})),
)
def to_dict(self) -> Dict[str, Any]:
out = {
"id": self.id,
"type": self.type,
"uri": self.uri,
"external_urls": self.external_urls.to_dict(),
}
return {k: v for k, v in out.items() if v not in (None, {}, [], "")}
@dataclass
class PlaylistItem:
added_at: Optional[str] = None
added_by: UserMini = field(default_factory=UserMini)
is_local: bool = False
track: Optional[Union[TrackModel, TrackStub]] = None
item_id: Optional[str] = None
@staticmethod
def from_dict(obj: Any) -> "PlaylistItem":
if not isinstance(obj, dict):
return PlaylistItem()
track_obj = None
trk = obj.get("track")
if isinstance(trk, dict):
if trk.get("duration_ms") is not None:
track_obj = TrackModel.from_dict(trk)
else:
track_obj = TrackStub.from_dict(trk)
return PlaylistItem(
added_at=_str(obj.get("added_at")),
added_by=UserMini.from_dict(obj.get("added_by", {})),
is_local=bool(obj.get("is_local", False)),
track=track_obj,
item_id=_str(obj.get("item_id")),
)
def to_dict(self) -> Dict[str, Any]:
out = {
"added_at": self.added_at,
"added_by": self.added_by.to_dict(),
"is_local": self.is_local,
"track": self.track.to_dict() if hasattr(self.track, 'to_dict') and self.track else None,
"item_id": self.item_id,
}
return {k: v for k, v in out.items() if v not in (None, {}, [], "")}
@dataclass
class TracksPage:
offset: int = 0
total: int = 0
items: List[PlaylistItem] = field(default_factory=list)
@staticmethod
def from_dict(obj: Any) -> "TracksPage":
if not isinstance(obj, dict):
return TracksPage(items=[])
items: List[PlaylistItem] = []
for it in obj.get("items", []) or []:
items.append(PlaylistItem.from_dict(it))
return TracksPage(
offset=_int(obj.get("offset")) or 0,
total=_int(obj.get("total")) or len(items),
items=items,
)
def to_dict(self) -> Dict[str, Any]:
return {
"offset": self.offset,
"total": self.total,
"items": [it.to_dict() for it in (self.items or [])]
}
@dataclass
class Owner:
id: Optional[str] = None
type: str = "user"
uri: Optional[str] = None
display_name: Optional[str] = None
external_urls: ExternalUrls = field(default_factory=ExternalUrls)
@staticmethod
def from_dict(obj: Any) -> "Owner":
if not isinstance(obj, dict):
return Owner()
return Owner(
id=_str(obj.get("id")),
type=_str(obj.get("type")) or "user",
uri=_str(obj.get("uri")),
display_name=_str(obj.get("display_name")),
external_urls=ExternalUrls.from_dict(obj.get("external_urls", {})),
)
def to_dict(self) -> Dict[str, Any]:
out = {
"id": self.id,
"type": self.type,
"uri": self.uri,
"display_name": self.display_name,
"external_urls": self.external_urls.to_dict(),
}
return {k: v for k, v in out.items() if v not in (None, {}, [], "")}
@dataclass
class Playlist:
name: Optional[str] = None
description: Optional[str] = None
collaborative: Optional[bool] = None
picture: Optional[str] = None
owner: Owner = field(default_factory=Owner)
snapshot_id: Optional[str] = None
length: Optional[int] = None
tracks: TracksPage = field(default_factory=lambda: TracksPage(items=[]))
type: str = "playlist"
@staticmethod
def from_dict(obj: Any) -> "Playlist":
if not isinstance(obj, dict):
return Playlist(tracks=TracksPage(items=[]))
return Playlist(
name=_str(obj.get("name")),
description=_str(obj.get("description")),
collaborative=bool(obj.get("collaborative")) if obj.get("collaborative") is not None else None,
picture=_str(obj.get("picture")),
owner=Owner.from_dict(obj.get("owner", {})),
snapshot_id=_str(obj.get("snapshot_id")),
length=_int(obj.get("length")),
tracks=TracksPage.from_dict(obj.get("tracks", {})),
type=_str(obj.get("type")) or "playlist",
)
def to_dict(self) -> Dict[str, Any]:
out = {
"name": self.name,
"description": self.description,
"collaborative": self.collaborative,
"picture": self.picture,
"owner": self.owner.to_dict(),
"snapshot_id": self.snapshot_id,
"length": self.length,
"tracks": self.tracks.to_dict(),
"type": self.type,
}
return {k: v for k, v in out.items() if v not in (None, {}, [], "")}