Files
musicseerr/backend/api/v1/schemas/plex.py
T
Harvey 0f25ebc26d Plex Integration + Music Source Integration Improvements (#37)
* plex integration

* The big one - Full Music Source page rework + Playlist importing + Full Plex Integration + Discovery Options + More Like This/Surprise Me/Instant Mix + More...

* Music source track page - Play all / shuffle fixes

* lint

* format

* fix type checks

* format
2026-04-13 23:39:01 +01:00

232 lines
5.1 KiB
Python

from __future__ import annotations
from infrastructure.msgspec_fastapi import AppStruct
class PlexTrackInfo(AppStruct):
plex_id: str
title: str
track_number: int
duration_seconds: float
disc_number: int = 1
album_name: str = ""
artist_name: str = ""
codec: str | None = None
bitrate: int | None = None
audio_channels: int | None = None
container: str | None = None
part_key: str | None = None
image_url: str | None = None
class PlexAlbumSummary(AppStruct):
plex_id: str
name: str
artist_name: str = ""
year: int | None = None
track_count: int = 0
image_url: str | None = None
musicbrainz_id: str | None = None
artist_musicbrainz_id: str | None = None
last_viewed_at: int = 0
class PlexAlbumDetail(AppStruct):
plex_id: str
name: str
artist_name: str = ""
year: int | None = None
track_count: int = 0
image_url: str | None = None
musicbrainz_id: str | None = None
artist_musicbrainz_id: str | None = None
tracks: list[PlexTrackInfo] = []
genres: list[str] = []
class PlexAlbumMatch(AppStruct):
found: bool
plex_album_id: str | None = None
tracks: list[PlexTrackInfo] = []
class PlexArtistSummary(AppStruct):
plex_id: str
name: str
image_url: str | None = None
musicbrainz_id: str | None = None
class PlexLibraryStats(AppStruct):
total_tracks: int = 0
total_albums: int = 0
total_artists: int = 0
class PlexSearchResponse(AppStruct):
albums: list[PlexAlbumSummary] = []
artists: list[PlexArtistSummary] = []
tracks: list[PlexTrackInfo] = []
class PlexAlbumPage(AppStruct):
items: list[PlexAlbumSummary] = []
total: int = 0
class PlexArtistPage(AppStruct):
items: list[PlexArtistSummary] = []
total: int = 0
offset: int = 0
limit: int = 50
class PlexArtistIndexEntry(AppStruct):
name: str = ""
artists: list[PlexArtistSummary] = []
class PlexArtistIndexResponse(AppStruct):
index: list[PlexArtistIndexEntry] = []
class PlexTrackPage(AppStruct):
items: list[PlexTrackInfo] = []
total: int = 0
offset: int = 0
limit: int = 50
class PlexPlaylistSummary(AppStruct):
id: str
name: str
track_count: int = 0
duration_seconds: int = 0
is_smart: bool = False
cover_url: str = ""
updated_at: str = ""
is_imported: bool = False
class PlexHubResponse(AppStruct):
stats: PlexLibraryStats | None = None
recently_played: list[PlexAlbumSummary] = []
recently_added: list[PlexAlbumSummary] = []
all_albums_preview: list[PlexAlbumSummary] = []
genres: list[str] = []
playlists: list[PlexPlaylistSummary] = []
class PlexDiscoveryAlbum(AppStruct):
plex_id: str
name: str
artist_name: str = ""
year: int | None = None
image_url: str | None = None
class PlexDiscoveryHub(AppStruct):
title: str
hub_type: str = ""
albums: list[PlexDiscoveryAlbum] = []
class PlexDiscoveryResponse(AppStruct):
hubs: list[PlexDiscoveryHub] = []
class PlexLibrarySectionInfo(AppStruct):
key: str
title: str
class PlexPlaylistTrack(AppStruct):
id: str
track_name: str
artist_name: str = ""
album_name: str = ""
album_id: str = ""
plex_rating_key: str = ""
duration_seconds: int = 0
track_number: int = 0
disc_number: int = 1
cover_url: str = ""
class PlexPlaylistDetail(AppStruct):
id: str
name: str
track_count: int = 0
duration_seconds: int = 0
is_smart: bool = False
cover_url: str = ""
updated_at: str = ""
tracks: list[PlexPlaylistTrack] = []
class PlexImportResult(AppStruct):
musicseerr_playlist_id: str = ""
tracks_imported: int = 0
tracks_failed: int = 0
already_imported: bool = False
class PlexSessionInfo(AppStruct):
session_id: str = ""
user_name: str = ""
track_title: str = ""
artist_name: str = ""
album_name: str = ""
cover_url: str = ""
player_device: str = ""
player_platform: str = ""
player_state: str = ""
is_direct_play: bool = True
progress_ms: int = 0
duration_ms: int = 0
audio_codec: str = ""
audio_channels: int = 0
bitrate: int = 0
class PlexSessionsResponse(AppStruct):
sessions: list[PlexSessionInfo] = []
available: bool = True
class PlexHistoryEntrySchema(AppStruct):
rating_key: str = ""
track_title: str = ""
artist_name: str = ""
album_name: str = ""
cover_url: str = ""
viewed_at: str = ""
device_name: str = ""
class PlexHistoryResponse(AppStruct):
entries: list[PlexHistoryEntrySchema] = []
total: int = 0
limit: int = 0
offset: int = 0
available: bool = True
class PlexAnalyticsItem(AppStruct):
name: str = ""
subtitle: str = ""
play_count: int = 0
cover_url: str | None = None
class PlexAnalyticsResponse(AppStruct):
top_artists: list[PlexAnalyticsItem] = []
top_albums: list[PlexAnalyticsItem] = []
top_tracks: list[PlexAnalyticsItem] = []
total_listens: int = 0
listens_last_7_days: int = 0
listens_last_30_days: int = 0
total_hours: float = 0.0
is_complete: bool = True
entries_analyzed: int = 0