Implemented callback models

This commit is contained in:
Xoconoch
2025-06-10 18:46:53 -06:00
parent c1438ecb47
commit cc947fe374
24 changed files with 633 additions and 434 deletions

View File

@@ -1,8 +0,0 @@
#!/usr/bin/python3
from deezspot.models.smart import Smart
from deezspot.models.track import Track
from deezspot.models.album import Album
from deezspot.models.playlist import Playlist
from deezspot.models.preferences import Preferences
from deezspot.models.episode import Episode

View File

@@ -5,7 +5,21 @@ Callback data models for the music metadata schema.
"""
from .common import IDs, ReleaseDate
from .artist import artistObject, artistTrackObject
from .album import albumObject, albumTrackObject, albumArtistObject, trackAlbumObject
from .track import trackObject
from .playlist import playlistObject, trackPlaylistObject, albumTrackPlaylistObject, artistTrackPlaylistObject
from .artist import artistObject, albumArtistObject
from .album import albumObject, trackAlbumObject
from .track import trackObject, artistTrackObject, albumTrackObject, playlistTrackObject
from .playlist import playlistObject, trackPlaylistObject, albumTrackPlaylistObject, artistTrackPlaylistObject
from .callbacks import (
BaseStatusObject,
initializingObject,
skippedObject,
retryingObject,
realTimeObject,
errorObject,
doneObject,
summaryObject,
failedTrackObject,
trackCallbackObject,
albumCallbackObject,
playlistCallbackObject
)

View File

@@ -5,7 +5,22 @@ from typing import List, Optional, Dict, Any
from .common import IDs, ReleaseDate
@dataclass
class artistTrackAlbumObject:
"""Artist representation for a track in an album context."""
type: str = "artistTrackAlbum"
name: str = ""
ids: IDs = field(default_factory=IDs)
@dataclass
class artistAlbumObject:
"""Artist representation for an album."""
type: str = "artistAlbum"
name: str = ""
genres: List[str] = field(default_factory=list)
ids: IDs = field(default_factory=IDs)
@dataclass
class trackAlbumObject:
"""Track when nested inside an album context."""
@@ -16,18 +31,7 @@ class trackAlbumObject:
duration_ms: int = 0
genres: List[str] = field(default_factory=list)
ids: IDs = field(default_factory=IDs)
@dataclass
class albumTrackObject:
"""Album when nested inside a track context."""
type: str = "albumTrack"
album_type: str = "" # "album" | "single" | "compilation"
title: str = ""
release_date: Dict[str, Any] = field(default_factory=dict) # ReleaseDate as dict
total_tracks: int = 0
genres: List[str] = field(default_factory=list)
ids: IDs = field(default_factory=IDs)
artists: List[artistTrackAlbumObject] = field(default_factory=list)
@dataclass
@@ -36,9 +40,9 @@ class albumObject:
type: str = "album"
album_type: str = "" # "album" | "single" | "compilation"
title: str = ""
release_date: Dict[str, Any] = field(default_factory=dict) # ReleaseDate as dict
release_date: Dict[str, Any] = field(default_factory=dict)
total_tracks: int = 0
genres: List[str] = field(default_factory=list)
ids: IDs = field(default_factory=IDs)
# Nested: album's tracks without redundant album info
tracks: List[trackAlbumObject] = field(default_factory=list)
tracks: List[trackAlbumObject] = field(default_factory=list)
artists: List[artistAlbumObject] = field(default_factory=list)

View File

@@ -6,17 +6,6 @@ from typing import List, Optional
from .common import IDs
@dataclass
class artistTrackObject:
"""
An artist when nested inside a track context.
No genres, no albums—just identifying info.
"""
type: str = "artistTrack"
name: str = ""
ids: IDs = field(default_factory=IDs)
@dataclass
class albumArtistObject:
"""Album when nested inside an artist context."""
@@ -35,5 +24,4 @@ class artistObject:
name: str = ""
genres: List[str] = field(default_factory=list)
ids: IDs = field(default_factory=IDs)
# Nested: artist's albums without redundant artist info
albums: List[albumArtistObject] = field(default_factory=list)

View File

@@ -0,0 +1,133 @@
#!/usr/bin/python3
from dataclasses import dataclass, field
from typing import List, Optional, Dict, Any, Union
from .common import IDs
from .track import trackObject, albumTrackObject, playlistTrackObject
from .album import albumObject
from .playlist import playlistObject
@dataclass
class BaseStatusObject:
"""Base class for all status objects with common fields."""
ids: Optional[IDs] = None
convert_to: Optional[str] = None
bitrate: Optional[str] = None
@dataclass
class initializingObject(BaseStatusObject):
"""Status object for 'initializing' state."""
status: str = "initializing"
@dataclass
class skippedObject(BaseStatusObject):
"""Status object for 'skipped' state."""
status: str = "skipped"
reason: str = ""
@dataclass
class retryingObject(BaseStatusObject):
"""Status object for 'retrying' state."""
status: str = "retrying"
retry_count: int = 0
seconds_left: int = 0
error: str = ""
@dataclass
class realTimeObject(BaseStatusObject):
"""Status object for 'real-time' state."""
status: str = "real-time"
time_elapsed: int = 0
progress: int = 0
@dataclass
class errorObject(BaseStatusObject):
"""Status object for 'error' state."""
status: str = "error"
error: str = ""
@dataclass
class failedTrackObject:
"""Represents a failed track with a reason."""
track: trackObject = field(default_factory=trackObject)
reason: str = ""
@dataclass
class summaryObject:
"""Summary of a download operation for an album or playlist."""
successful_tracks: List[trackObject] = field(default_factory=list)
skipped_tracks: List[trackObject] = field(default_factory=list)
failed_tracks: List[failedTrackObject] = field(default_factory=list)
total_successful: int = 0
total_skipped: int = 0
total_failed: int = 0
@dataclass
class doneObject(BaseStatusObject):
"""Status object for 'done' state."""
status: str = "done"
summary: Optional[summaryObject] = None
@dataclass
class trackCallbackObject:
"""
Track callback object that combines trackObject with status-specific fields.
Used for progress reporting during track processing.
"""
track: trackObject = field(default_factory=trackObject)
status_info: Union[
initializingObject,
skippedObject,
retryingObject,
realTimeObject,
errorObject,
doneObject
] = field(default_factory=initializingObject)
current_track: Optional[int] = None
total_tracks: Optional[int] = None
parent: Optional[Union[albumTrackObject, playlistTrackObject]] = None
@dataclass
class albumCallbackObject:
"""
Album callback object that combines albumObject with status-specific fields.
Used for progress reporting during album processing.
"""
album: albumObject = field(default_factory=albumObject)
status_info: Union[
initializingObject,
skippedObject,
retryingObject,
realTimeObject,
errorObject,
doneObject
] = field(default_factory=initializingObject)
@dataclass
class playlistCallbackObject:
"""
Playlist callback object that combines playlistObject with status-specific fields.
Used for progress reporting during playlist processing.
"""
playlist: playlistObject = field(default_factory=playlistObject)
status_info: Union[
initializingObject,
skippedObject,
retryingObject,
realTimeObject,
errorObject,
doneObject
] = field(default_factory=initializingObject)

View File

@@ -4,8 +4,14 @@ from dataclasses import dataclass, field
from typing import List, Optional, Dict, Any
from .common import IDs
from .artist import artistObject
from .user import userObject
@dataclass
class artistAlbumTrackPlaylistObject:
"""Artist when nested inside a track in a playlist context."""
type: str = "artistAlbumTrackPlaylist"
name: str = ""
ids: IDs = field(default_factory=IDs)
@dataclass
class albumTrackPlaylistObject:
@@ -15,6 +21,7 @@ class albumTrackPlaylistObject:
title: str = ""
release_date: Dict[str, Any] = field(default_factory=dict) # ReleaseDate as dict
ids: IDs = field(default_factory=IDs)
artists: List[artistAlbumTrackPlaylistObject] = field(default_factory=list)
@dataclass
@@ -22,7 +29,6 @@ class artistTrackPlaylistObject:
"""Artist when nested inside a track in a playlist context."""
type: str = "artistTrackPlaylist"
name: str = ""
genres: List[str] = field(default_factory=list)
ids: IDs = field(default_factory=IDs)
@@ -33,10 +39,11 @@ class trackPlaylistObject:
title: str = ""
position: int = 0 # Position in the playlist
duration_ms: int = 0 # mandatory
# Nested objects instead of string references
artist: artistTrackPlaylistObject = field(default_factory=artistTrackPlaylistObject)
artists: List[artistTrackPlaylistObject] = field(default_factory=list)
album: albumTrackPlaylistObject = field(default_factory=albumTrackPlaylistObject)
ids: IDs = field(default_factory=IDs)
disc_number: int = 1
track_number: int = 1
@dataclass
@@ -45,7 +52,6 @@ class playlistObject:
type: str = "playlist"
title: str = ""
description: Optional[str] = None
collaborative: bool = False
owner: artistObject = field(default_factory=artistObject)
owner: userObject = field(default_factory=userObject)
tracks: List[trackPlaylistObject] = field(default_factory=list)
ids: IDs = field(default_factory=IDs)

View File

@@ -1,12 +1,48 @@
#!/usr/bin/python3
from dataclasses import dataclass, field
from typing import List, Optional
from typing import List, Optional, Dict, Any
from .common import IDs
from .album import albumTrackObject
from .artist import artistTrackObject
from .user import userObject
@dataclass
class artistAlbumTrackObject:
"""Artist when nested inside a track in an album context."""
type: str = "artistAlbumTrack"
name: str = ""
ids: IDs = field(default_factory=IDs)
@dataclass
class artistTrackObject:
"""
An artist when nested inside a track context.
No genres, no albums—just identifying info.
"""
type: str = "artistTrack"
name: str = ""
ids: IDs = field(default_factory=IDs)
@dataclass
class albumTrackObject:
"""Album when nested inside a track context."""
type: str = "albumTrack"
album_type: str = "" # "album" | "single" | "compilation"
title: str = ""
release_date: Dict[str, Any] = field(default_factory=dict) # ReleaseDate as dict
total_tracks: int = 0
genres: List[str] = field(default_factory=list)
ids: IDs = field(default_factory=IDs)
artists: List[artistAlbumTrackObject] = field(default_factory=list)
@dataclass
class playlistTrackObject:
"""Playlist when nested inside a track context."""
type: str = "playlistTrack"
title: str = ""
description: Optional[str] = None
owner: userObject = field(default_factory=userObject)
ids: IDs = field(default_factory=IDs)
@dataclass
class trackObject:
@@ -17,11 +53,6 @@ class trackObject:
track_number: int = 1
duration_ms: int = 0 # mandatory
genres: List[str] = field(default_factory=list)
# Nested album summary
album: albumTrackObject = field(default_factory=albumTrackObject)
# Nested lean artist summary (no genres/albums)
artist: artistTrackObject = field(default_factory=artistTrackObject)
ids: IDs = field(default_factory=IDs)
artists: List[artistTrackObject] = field(default_factory=list)
ids: IDs = field(default_factory=IDs)

View File

@@ -0,0 +1,14 @@
#!/usr/bin/python3
from dataclasses import dataclass, field
from typing import Optional
from .common import IDs
@dataclass
class userObject:
"""A user object representation."""
name: str = ""
type: str = "user"
ids: IDs = field(default_factory=IDs)

View File

@@ -0,0 +1,8 @@
#!/usr/bin/python3
from deezspot.models.download.smart import Smart
from deezspot.models.download.track import Track
from deezspot.models.download.album import Album
from deezspot.models.download.playlist import Playlist
from deezspot.models.download.preferences import Preferences
from deezspot.models.download.episode import Episode

View File

@@ -1,6 +1,6 @@
#!/usr/bin/python3
from deezspot.models.track import Track
from deezspot.models.download.track import Track
class Album:
def __init__(self, ids: int) -> None:

View File

@@ -1,6 +1,6 @@
#!/usr/bin/python3
from deezspot.models.track import Track
from deezspot.models.download.track import Track
class Playlist:
def __init__(self) -> None:

View File

@@ -1,8 +1,8 @@
#!/usr/bin/python3
from deezspot.models.track import Track
from deezspot.models.album import Album
from deezspot.models.playlist import Playlist
from deezspot.models.download.track import Track
from deezspot.models.download.album import Album
from deezspot.models.download.playlist import Playlist
class Smart:
def __init__(self) -> None: