Files
sublime-music/sublime/adapters/subsonic/api_objects.py
2020-05-08 11:30:23 -06:00

113 lines
3.2 KiB
Python

"""
These are the API objects that are returned by Subsonic.
"""
from dataclasses import dataclass, field
from datetime import datetime, timedelta
from typing import List, Optional
import dataclasses_json
from dataclasses_json import (
config,
dataclass_json,
DataClassJsonMixin,
LetterCase,
)
from .. import api_objects as SublimeAPI
# Translation map
extra_translation_map = {
datetime: (lambda s: datetime.strptime(s, "%Y-%m-%dT%H:%M:%S.%f%z") if s else None),
timedelta: (lambda s: timedelta(seconds=s) if s else None),
}
for type_, translation_function in extra_translation_map.items():
dataclasses_json.cfg.global_config.decoders[type_] = translation_function
dataclasses_json.cfg.global_config.decoders[Optional[type_]] = translation_function
@dataclass_json(letter_case=LetterCase.CAMEL)
@dataclass
class Song(SublimeAPI.Song):
id: str
title: str
parent: str
album: str
artist: str
track: Optional[int] = None
year: Optional[int] = None
genre: Optional[str] = None
cover_art: Optional[str] = None
size: Optional[int] = None
content_type: Optional[str] = None
suffix: Optional[str] = None
transcoded_content_type: Optional[str] = None
transcoded_suffix: Optional[str] = None
duration: Optional[timedelta] = None
bit_rate: Optional[int] = None
path: Optional[str] = None
is_video: Optional[bool] = None
user_rating: Optional[int] = None
average_rating: Optional[float] = None
play_count: Optional[int] = None
disc_number: Optional[int] = None
created: Optional[datetime] = None
starred: Optional[datetime] = None
album_id: Optional[str] = None
artist_id: Optional[str] = None
type: Optional[SublimeAPI.MediaType] = None
@dataclass_json(letter_case=LetterCase.CAMEL)
@dataclass
class Playlist(SublimeAPI.Playlist):
id: str
name: str
song_count: Optional[int] = None
duration: Optional[timedelta] = None
created: Optional[datetime] = None
changed: Optional[datetime] = None
comment: Optional[str] = None
owner: Optional[str] = None
public: Optional[bool] = None
cover_art: Optional[str] = None
@dataclass_json(letter_case=LetterCase.CAMEL)
@dataclass
class PlaylistWithSongs(SublimeAPI.PlaylistDetails):
id: str
name: str
songs: List[Song] = field(default_factory=list, metadata=config(field_name="entry"))
song_count: int = field(default=0)
duration: timedelta = field(default=timedelta())
created: Optional[datetime] = None
changed: Optional[datetime] = None
comment: Optional[str] = None
owner: Optional[str] = None
public: Optional[bool] = None
cover_art: Optional[str] = None
def __post_init__(self):
self.song_count = self.song_count or len(self.songs)
self.duration = self.duration or timedelta(
seconds=sum(
s.duration.total_seconds() if s.duration else 0 for s in self.songs
)
)
@dataclass
class Playlists(DataClassJsonMixin):
playlist: List[Playlist] = field(default_factory=list)
@dataclass
class Response(DataClassJsonMixin):
"""The base Subsonic response object."""
song: Optional[Song] = None
playlists: Optional[Playlists] = None
playlist: Optional[PlaylistWithSongs] = None