forked from platypush/platypush
[media.jellyfin] Added support for photo items.
This commit is contained in:
parent
e30ae16ef7
commit
9716b1da35
2 changed files with 76 additions and 29 deletions
|
@ -10,6 +10,7 @@ from platypush.schemas.media.jellyfin import (
|
||||||
JellyfinCollectionSchema,
|
JellyfinCollectionSchema,
|
||||||
JellyfinEpisodeSchema,
|
JellyfinEpisodeSchema,
|
||||||
JellyfinMovieSchema,
|
JellyfinMovieSchema,
|
||||||
|
JellyfinPhotoSchema,
|
||||||
JellyfinTrackSchema,
|
JellyfinTrackSchema,
|
||||||
JellyfinVideoSchema,
|
JellyfinVideoSchema,
|
||||||
)
|
)
|
||||||
|
@ -153,29 +154,24 @@ class MediaJellyfinPlugin(Plugin):
|
||||||
for result in search_results:
|
for result in search_results:
|
||||||
if result['Type'] == 'Movie':
|
if result['Type'] == 'Movie':
|
||||||
result = JellyfinMovieSchema().dump(result)
|
result = JellyfinMovieSchema().dump(result)
|
||||||
result['type'] = 'movie' # type: ignore
|
|
||||||
elif result['Type'] == 'Video':
|
elif result['Type'] == 'Video':
|
||||||
result = JellyfinVideoSchema().dump(result)
|
result = JellyfinVideoSchema().dump(result)
|
||||||
result['type'] = 'video' # type: ignore
|
elif result['Type'] == 'Photo':
|
||||||
|
result = JellyfinPhotoSchema().dump(result)
|
||||||
elif result['Type'] == 'Episode':
|
elif result['Type'] == 'Episode':
|
||||||
result = JellyfinEpisodeSchema().dump(result)
|
result = JellyfinEpisodeSchema().dump(result)
|
||||||
result['type'] = 'episode' # type: ignore
|
|
||||||
elif result['Type'] == 'Audio':
|
elif result['Type'] == 'Audio':
|
||||||
result = JellyfinTrackSchema().dump(result)
|
result = JellyfinTrackSchema().dump(result)
|
||||||
result['type'] = 'audio' # type: ignore
|
|
||||||
elif result['Type'] == 'MusicArtist':
|
elif result['Type'] == 'MusicArtist':
|
||||||
result = JellyfinArtistSchema().dump(result)
|
result = JellyfinArtistSchema().dump(result)
|
||||||
result['type'] = 'artist' # type: ignore
|
|
||||||
elif result['Type'] == 'MusicAlbum':
|
elif result['Type'] == 'MusicAlbum':
|
||||||
result = JellyfinAlbumSchema().dump(result)
|
result = JellyfinAlbumSchema().dump(result)
|
||||||
result['type'] = 'album' # type: ignore
|
|
||||||
elif result['Type'] == 'Series':
|
elif result['Type'] == 'Series':
|
||||||
serialized_results += self._flatten_series_result(result)
|
serialized_results += self._flatten_series_result(result)
|
||||||
for r in serialized_results:
|
for r in serialized_results:
|
||||||
r['type'] = 'episode'
|
r['type'] = 'episode'
|
||||||
elif result.get('IsFolder'):
|
elif result.get('IsFolder'):
|
||||||
result = JellyfinCollectionSchema().dump(result)
|
result = JellyfinCollectionSchema().dump(result)
|
||||||
result['type'] = 'collection' # type: ignore
|
|
||||||
|
|
||||||
if isinstance(result, dict) and result.get('type'):
|
if isinstance(result, dict) and result.get('type'):
|
||||||
serialized_results.append(result)
|
serialized_results.append(result)
|
||||||
|
|
|
@ -17,27 +17,28 @@ class JellyfinSchema(Schema):
|
||||||
self.fields['id'].attribute = 'Id'
|
self.fields['id'].attribute = 'Id'
|
||||||
if 'path' in self.fields:
|
if 'path' in self.fields:
|
||||||
self.fields['path'].attribute = 'Path'
|
self.fields['path'].attribute = 'Path'
|
||||||
if 'created_at' in self.fields:
|
|
||||||
self.fields['created_at'].attribute = 'DateCreated'
|
|
||||||
if 'name' in self.fields:
|
if 'name' in self.fields:
|
||||||
self.fields['name'].attribute = 'Name'
|
self.fields['name'].attribute = 'Name'
|
||||||
elif 'title' in self.fields:
|
if 'title' in self.fields:
|
||||||
self.fields['title'].attribute = 'Name'
|
self.fields['title'].attribute = 'Name'
|
||||||
|
|
||||||
@post_dump
|
@property
|
||||||
def gen_img_url(self, data: dict, **_) -> dict:
|
def _plugin(self):
|
||||||
if 'image' in self.fields and data.get('id') and not data.get('image'):
|
p = get_plugin('media.jellyfin')
|
||||||
plugin = get_plugin('media.jellyfin')
|
assert p, 'The media.jellyfin plugin is not configured'
|
||||||
assert plugin, 'The media.jellyfin plugin is not configured'
|
return p
|
||||||
data['image'] = (
|
|
||||||
plugin.server + f'/Items/{data["id"]}' # type: ignore
|
|
||||||
'/Images/Primary?fillHeight=333&fillWidth=222&quality=96'
|
|
||||||
)
|
|
||||||
|
|
||||||
return data
|
@property
|
||||||
|
def _server(self):
|
||||||
|
return self._plugin.server
|
||||||
|
|
||||||
|
@property
|
||||||
|
def _api_key(self):
|
||||||
|
return self._plugin._api_key # pylint: disable=protected-access
|
||||||
|
|
||||||
@pre_dump
|
@pre_dump
|
||||||
def _gen_video_url(self, data, **_):
|
def _gen_video_url(self, data, **_):
|
||||||
|
data = data or {}
|
||||||
if data.get('MediaType') != 'Video':
|
if data.get('MediaType') != 'Video':
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
@ -59,26 +60,34 @@ class JellyfinSchema(Schema):
|
||||||
|
|
||||||
video_format = list(available_containers)[0]
|
video_format = list(available_containers)[0]
|
||||||
|
|
||||||
plugin = get_plugin('media.jellyfin')
|
|
||||||
assert plugin, 'The media.jellyfin plugin is not configured'
|
|
||||||
data['url'] = (
|
data['url'] = (
|
||||||
f'{plugin.server}/Videos/{data["Id"]}'
|
f'{self._server}/Videos/{data["Id"]}'
|
||||||
f'/stream.{video_format}'
|
f'/stream.{video_format}'
|
||||||
f'?Static=true&api_key={plugin._api_key}'
|
f'?Static=true&api_key={self._api_key}'
|
||||||
)
|
)
|
||||||
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
@pre_dump
|
@pre_dump
|
||||||
def _gen_audio_url(self, data, **_):
|
def _gen_audio_url(self, data, **_):
|
||||||
|
data = data or {}
|
||||||
if data.get('MediaType') != 'Audio':
|
if data.get('MediaType') != 'Audio':
|
||||||
return data
|
return data
|
||||||
|
|
||||||
plugin = get_plugin('media.jellyfin')
|
|
||||||
assert plugin, 'The media.jellyfin plugin is not configured'
|
|
||||||
data['url'] = (
|
data['url'] = (
|
||||||
f'{plugin.server}/Audio/{data["Id"]}'
|
f'{self._server}/Audio/{data["Id"]}'
|
||||||
f'/stream?Static=true&api_key={plugin._api_key}'
|
f'/stream?Static=true&api_key={self._api_key}'
|
||||||
|
)
|
||||||
|
|
||||||
|
return data
|
||||||
|
|
||||||
|
@post_dump
|
||||||
|
def gen_img_url(self, data: dict, **_) -> dict:
|
||||||
|
data = data or {}
|
||||||
|
if 'image' in self.fields and data.get('id') and not data.get('image'):
|
||||||
|
data['image'] = (
|
||||||
|
self._server + f'/Items/{data["id"]}' # type: ignore
|
||||||
|
'/Images/Primary?fillHeight=333&fillWidth=222&quality=96'
|
||||||
)
|
)
|
||||||
|
|
||||||
return data
|
return data
|
||||||
|
@ -91,11 +100,13 @@ class JellyfinSchema(Schema):
|
||||||
|
|
||||||
|
|
||||||
class JellyfinArtistSchema(JellyfinSchema, MediaArtistSchema, MediaCollectionSchema):
|
class JellyfinArtistSchema(JellyfinSchema, MediaArtistSchema, MediaCollectionSchema):
|
||||||
|
type = fields.Constant('artist')
|
||||||
item_type = fields.Constant('artist')
|
item_type = fields.Constant('artist')
|
||||||
collection_type = fields.Constant('music')
|
collection_type = fields.Constant('music')
|
||||||
|
|
||||||
|
|
||||||
class JellyfinTrackSchema(JellyfinSchema):
|
class JellyfinTrackSchema(JellyfinSchema):
|
||||||
|
type = fields.Constant('audio')
|
||||||
item_type = fields.Constant('track')
|
item_type = fields.Constant('track')
|
||||||
id = fields.String(attribute='Id')
|
id = fields.String(attribute='Id')
|
||||||
url = fields.URL()
|
url = fields.URL()
|
||||||
|
@ -138,6 +149,7 @@ class JellyfinTrackSchema(JellyfinSchema):
|
||||||
|
|
||||||
class JellyfinAlbumSchema(JellyfinSchema, MediaCollectionSchema):
|
class JellyfinAlbumSchema(JellyfinSchema, MediaCollectionSchema):
|
||||||
id = fields.String(attribute='Id')
|
id = fields.String(attribute='Id')
|
||||||
|
type = fields.Constant('album')
|
||||||
item_type = fields.Constant('album')
|
item_type = fields.Constant('album')
|
||||||
collection_type = fields.Constant('music')
|
collection_type = fields.Constant('music')
|
||||||
name = fields.String(attribute='Name')
|
name = fields.String(attribute='Name')
|
||||||
|
@ -163,12 +175,16 @@ class JellyfinCollectionSchema(JellyfinSchema, MediaCollectionSchema):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
self.fields['type'].attribute = 'CollectionType'
|
self.fields['type'].attribute = 'CollectionType'
|
||||||
|
|
||||||
|
type = fields.Constant('collection')
|
||||||
|
item_type = fields.Constant('collection')
|
||||||
collection_type = fields.String(attribute='CollectionType')
|
collection_type = fields.String(attribute='CollectionType')
|
||||||
image = fields.String()
|
image = fields.String()
|
||||||
created_at = DateTime(attribute='DateCreated')
|
created_at = DateTime(attribute='DateCreated')
|
||||||
|
|
||||||
|
|
||||||
class JellyfinVideoSchema(JellyfinSchema, MediaVideoSchema):
|
class JellyfinVideoSchema(JellyfinSchema, MediaVideoSchema):
|
||||||
|
type = fields.Constant('video')
|
||||||
|
item_type = fields.Constant('video')
|
||||||
path = fields.String(attribute='Path')
|
path = fields.String(attribute='Path')
|
||||||
duration = fields.Number(attribute='RunTimeTicks')
|
duration = fields.Number(attribute='RunTimeTicks')
|
||||||
community_rating = fields.Number(attribute='CommunityRating')
|
community_rating = fields.Number(attribute='CommunityRating')
|
||||||
|
@ -233,10 +249,14 @@ class JellyfinVideoSchema(JellyfinSchema, MediaVideoSchema):
|
||||||
|
|
||||||
|
|
||||||
class JellyfinMovieSchema(JellyfinVideoSchema):
|
class JellyfinMovieSchema(JellyfinVideoSchema):
|
||||||
pass
|
type = fields.Constant('movie')
|
||||||
|
item_type = fields.Constant('movie')
|
||||||
|
|
||||||
|
|
||||||
class JellyfinEpisodeSchema(JellyfinVideoSchema):
|
class JellyfinEpisodeSchema(JellyfinVideoSchema):
|
||||||
|
type = fields.Constant('episode')
|
||||||
|
item_type = fields.Constant('episode')
|
||||||
|
|
||||||
@pre_dump
|
@pre_dump
|
||||||
def _normalize_episode_name(self, data: dict, **_) -> dict:
|
def _normalize_episode_name(self, data: dict, **_) -> dict:
|
||||||
prefix = ''
|
prefix = ''
|
||||||
|
@ -254,3 +274,34 @@ class JellyfinEpisodeSchema(JellyfinVideoSchema):
|
||||||
|
|
||||||
data['Name'] = prefix + data.get('Name', '')
|
data['Name'] = prefix + data.get('Name', '')
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
class JellyfinPhotoSchema(JellyfinSchema):
|
||||||
|
id = fields.String(attribute='Id')
|
||||||
|
name = fields.String(attribute='Name')
|
||||||
|
url = fields.URL()
|
||||||
|
type = fields.Constant('photo')
|
||||||
|
item_type = fields.Constant('photo')
|
||||||
|
path = fields.String(attribute='Path')
|
||||||
|
created_at = DateTime(attribute='PremiereDate')
|
||||||
|
width = fields.Number(attribute='Width')
|
||||||
|
height = fields.Number(attribute='Height')
|
||||||
|
camera_make = fields.String(attribute='CameraMake')
|
||||||
|
camera_model = fields.String(attribute='CameraModel')
|
||||||
|
software = fields.String(attribute='Software')
|
||||||
|
exposure_time = fields.Float(attribute='ExposureTime')
|
||||||
|
focal_length = fields.Float(attribute='FocalLength')
|
||||||
|
image_orientation = fields.String(attribute='ImageOrientation')
|
||||||
|
aperture = fields.Float(attribute='Aperture')
|
||||||
|
iso = fields.Number(attribute='IsoSpeedRating')
|
||||||
|
|
||||||
|
@pre_dump
|
||||||
|
def _gen_photo_url(self, data, **_):
|
||||||
|
data = data or {}
|
||||||
|
base_url = f'{self._server}/Items/{data["Id"]}'
|
||||||
|
data['preview_url'] = (
|
||||||
|
f'{base_url}/Images/Primary?api_key={self._api_key}'
|
||||||
|
f'&fillHeight=489&fillWidth=367&quality=96'
|
||||||
|
)
|
||||||
|
data['url'] = f'{base_url}/Download?api_key={self._api_key}'
|
||||||
|
return data
|
||||||
|
|
Loading…
Reference in a new issue