Skip to content

Add playback state #3

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
125 changes: 124 additions & 1 deletion src/spotifyaio/models.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,21 @@
"""Models for Spotify."""
from __future__ import annotations

from dataclasses import dataclass, field
from enum import StrEnum

from mashumaro import field_options
from mashumaro.mixins.orjson import DataClassORJSONMixin


class DeviceType(StrEnum):
"""Device type."""

COMPUTER = "Computer"
SMARTPHONE = "Smartphone"
SPEAKER = "Speaker"


@dataclass
class Device(DataClassORJSONMixin):
"""Device model."""
Expand All @@ -14,12 +25,124 @@ class Device(DataClassORJSONMixin):
is_private_session: bool
name: str
supports_volume: bool
device_type: str = field(metadata=field_options(alias="type"))
device_type: DeviceType = field(metadata=field_options(alias="type"))
volume_percent: int


class RepeatMode(StrEnum):
"""Repeat mode."""

OFF = "off"
TRACK = "track"
CONTEXT = "context"


class ContextType(StrEnum):
"""Context type."""

ALBUM = "album"
ARTIST = "artist"
PLAYLIST = "playlist"
COLLECTION = "collection"
SHOW = "show"


@dataclass
class Context(DataClassORJSONMixin):
"""Context model."""

external_urls: dict[str, str]
href: str
context_type: ContextType = field(metadata=field_options(alias="type"))
uri: str


class AlbumType(StrEnum):
"""Album type."""

ALBUM = "album"
SINGLE = "single"
COMPILATION = "compilation"


@dataclass
class Image(DataClassORJSONMixin):
"""Image model."""

height: int
width: int
url: str


class ReleaseDatePrecision(StrEnum):
"""Release date precision."""

YEAR = "year"
MONTH = "month"
DAY = "day"


@dataclass
class SimplifiedArtist(DataClassORJSONMixin):
"""Simplified artist model."""

artist_id: str = field(metadata=field_options(alias="id"))
name: str
uri: str


@dataclass
class Album(DataClassORJSONMixin):
"""Album model."""

album_type: AlbumType
total_tracks: int
album_id: str = field(metadata=field_options(alias="id"))
images: list[Image]
name: str
release_date: str
release_date_precision: ReleaseDatePrecision
uri: str
artists: list[SimplifiedArtist]


@dataclass
class Artist(DataClassORJSONMixin):
"""Artist model."""

artist_id: str = field(metadata=field_options(alias="id"))
name: str
uri: str


@dataclass
class Track(DataClassORJSONMixin):
"""Track model."""

track_id: str = field(metadata=field_options(alias="id"))
album: Album
artists: list[Artist]
disc_number: int
duration_ms: int
explicit: bool
external_ids: dict[str, str]
external_urls: dict[str, str]
href: str
is_local: bool
track_number: int
object_type: str = field(metadata=field_options(alias="type"))
uri: str


@dataclass
class PlaybackState(DataClassORJSONMixin):
"""Playback state model."""

device: Device
shuffle: bool = field(metadata=field_options(alias="shuffle_state"))
repeat_mode: RepeatMode = field(metadata=field_options(alias="repeat_state"))
context: Context | None
progress_ms: int | None
is_playing: bool
item: Track | None
currently_playing_type: str | None
72 changes: 71 additions & 1 deletion tests/__snapshots__/test_playback.ambr
Original file line number Diff line number Diff line change
@@ -1,14 +1,84 @@
# serializer version: 1
# name: test_get_devices
dict({
'context': dict({
'context_type': <ContextType.COLLECTION: 'collection'>,
'external_urls': dict({
'spotify': 'https://open.spotify.com/collection/tracks',
}),
'href': 'https://api.spotify.com/v1/me/tracks',
'uri': 'spotify:user:1112264649:collection',
}),
'currently_playing_type': 'track',
'device': dict({
'device_id': '21dac6b0e0a1f181870fdc9749b2656466557687',
'device_type': 'Computer',
'device_type': <DeviceType.COMPUTER: 'Computer'>,
'is_active': True,
'is_private_session': False,
'name': 'DESKTOP-BKC5SIK',
'supports_volume': True,
'volume_percent': 69,
}),
'is_playing': True,
'item': dict({
'album': dict({
'album_id': '1iasbpTobDPa5BmsK0Rz1f',
'album_type': <AlbumType.SINGLE: 'single'>,
'artists': list([
dict({
'artist_id': '6cmp7ut7okJAgJOSaMAVf3',
'name': 'Machinae Supremacy',
'uri': 'spotify:artist:6cmp7ut7okJAgJOSaMAVf3',
}),
]),
'images': list([
dict({
'height': 640,
'url': 'https://i.scdn.co/image/ab67616d0000b273326db007f167499d23171722',
'width': 640,
}),
dict({
'height': 300,
'url': 'https://i.scdn.co/image/ab67616d00001e02326db007f167499d23171722',
'width': 300,
}),
dict({
'height': 64,
'url': 'https://i.scdn.co/image/ab67616d00004851326db007f167499d23171722',
'width': 64,
}),
]),
'name': 'WARRIORS, Pt. 1 (Final Stage)',
'release_date': '2023-10-20',
'release_date_precision': <ReleaseDatePrecision.DAY: 'day'>,
'total_tracks': 1,
'uri': 'spotify:album:1iasbpTobDPa5BmsK0Rz1f',
}),
'artists': list([
dict({
'artist_id': '6cmp7ut7okJAgJOSaMAVf3',
'name': 'Machinae Supremacy',
'uri': 'spotify:artist:6cmp7ut7okJAgJOSaMAVf3',
}),
]),
'disc_number': 1,
'duration_ms': 268525,
'explicit': False,
'external_ids': dict({
'isrc': 'QZTB52388870',
}),
'external_urls': dict({
'spotify': 'https://open.spotify.com/track/1FyXbzOlq3dkxaB6iRsETv',
}),
'href': 'https://api.spotify.com/v1/tracks/1FyXbzOlq3dkxaB6iRsETv',
'is_local': False,
'object_type': 'track',
'track_id': '1FyXbzOlq3dkxaB6iRsETv',
'track_number': 1,
'uri': 'spotify:track:1FyXbzOlq3dkxaB6iRsETv',
}),
'progress_ms': 225564,
'repeat_mode': <RepeatMode.OFF: 'off'>,
'shuffle': False,
})
# ---