2022-03-01 01:32:50 +01:00
|
|
|
import warnings
|
|
|
|
|
|
|
|
from marshmallow import Schema, fields, pre_dump, post_dump
|
|
|
|
|
|
|
|
from platypush.context import get_plugin
|
|
|
|
|
|
|
|
from . import MediaArtistSchema, MediaCollectionSchema, MediaVideoSchema
|
|
|
|
|
|
|
|
|
|
|
|
class JellyfinSchema(Schema):
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
|
super().__init__(*args, **kwargs)
|
|
|
|
if 'id' in self.fields:
|
|
|
|
self.fields['id'].attribute = 'Id'
|
|
|
|
if 'name' in self.fields:
|
|
|
|
self.fields['name'].attribute = 'Name'
|
|
|
|
elif 'title' in self.fields:
|
|
|
|
self.fields['title'].attribute = 'Name'
|
|
|
|
|
|
|
|
@post_dump
|
|
|
|
def gen_img_url(self, data: dict, **_) -> dict:
|
|
|
|
if 'image' in self.fields:
|
|
|
|
data['image'] = (
|
2023-11-07 00:13:22 +01:00
|
|
|
get_plugin('media.jellyfin').server
|
|
|
|
+ f'/Items/{data["id"]}' # type: ignore
|
2022-03-01 01:32:50 +01:00
|
|
|
'/Images/Primary?fillHeight=333&fillWidth=222&quality=96'
|
|
|
|
)
|
|
|
|
|
|
|
|
return data
|
|
|
|
|
|
|
|
@pre_dump
|
|
|
|
def _gen_video_url(self, data, **_):
|
|
|
|
if data.get('MediaType') != 'Video':
|
|
|
|
return data
|
|
|
|
|
|
|
|
video_format = None
|
|
|
|
containers_priority = ['mp4', 'mkv', 'm4a', 'mov', 'avi']
|
|
|
|
available_containers = data.get('Container', '').split(',')
|
|
|
|
for container in containers_priority:
|
|
|
|
if container in available_containers:
|
|
|
|
video_format = container
|
|
|
|
break
|
|
|
|
|
|
|
|
if not video_format:
|
|
|
|
if not available_containers:
|
|
|
|
warnings.warn(
|
2023-11-07 00:13:22 +01:00
|
|
|
f'The media ID {data["Id"]} has no available video containers',
|
|
|
|
stacklevel=2,
|
2022-03-01 01:32:50 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
return data
|
|
|
|
|
|
|
|
video_format = available_containers[0]
|
|
|
|
|
|
|
|
plugin = get_plugin('media.jellyfin')
|
|
|
|
assert plugin, 'The media.jellyfin plugin is not configured'
|
2023-11-07 00:13:22 +01:00
|
|
|
data['url'] = (
|
2022-03-01 01:32:50 +01:00
|
|
|
f'{plugin.server}/Videos/{data["Id"]}'
|
|
|
|
f'/stream.{video_format}'
|
|
|
|
f'?Static=true&api_key={plugin._api_key}'
|
|
|
|
)
|
|
|
|
|
|
|
|
return data
|
|
|
|
|
|
|
|
|
|
|
|
class JellyfinArtistSchema(JellyfinSchema, MediaArtistSchema):
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
class JellyfinCollectionSchema(JellyfinSchema, MediaCollectionSchema):
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
|
super().__init__(*args, **kwargs)
|
|
|
|
self.fields['type'].attribute = 'CollectionType'
|
|
|
|
|
|
|
|
|
|
|
|
class JellyfinVideoSchema(JellyfinSchema, MediaVideoSchema):
|
2023-11-08 22:34:26 +01:00
|
|
|
duration = fields.Number(attribute='RunTimeTicks')
|
2022-03-01 01:32:50 +01:00
|
|
|
community_rating = fields.Number(attribute='CommunityRating')
|
|
|
|
critic_rating = fields.Number(attribute='CriticRating')
|
|
|
|
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
|
super().__init__(*args, **kwargs)
|
|
|
|
self.fields['year'].attribute = 'ProductionYear'
|
|
|
|
self.fields['has_subtitles'].attribute = 'HasSubtitles'
|
|
|
|
|
2023-11-08 22:34:26 +01:00
|
|
|
@post_dump
|
|
|
|
def _normalize_community_rating(self, data: dict, **_) -> dict:
|
|
|
|
if data.get('community_rating'):
|
|
|
|
data['community_rating'] *= 10
|
|
|
|
return data
|
|
|
|
|
|
|
|
@post_dump
|
|
|
|
def _normalize_duration(self, data: dict, **_) -> dict:
|
|
|
|
if data.get('duration'):
|
|
|
|
data['duration'] //= 1e7
|
|
|
|
return data
|
|
|
|
|
2022-03-01 01:32:50 +01:00
|
|
|
|
|
|
|
class JellyfinMovieSchema(JellyfinVideoSchema):
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
class JellyfinEpisodeSchema(JellyfinVideoSchema):
|
|
|
|
@pre_dump
|
|
|
|
def _normalize_episode_name(self, data: dict, **_) -> dict:
|
|
|
|
prefix = ''
|
|
|
|
series_name = data.get('SeriesName')
|
|
|
|
if series_name:
|
|
|
|
prefix = series_name
|
|
|
|
|
|
|
|
episode_index = data.get('IndexNumber')
|
|
|
|
if episode_index:
|
|
|
|
season_index = data.get('SeasonIndex', 1)
|
2023-11-07 00:13:22 +01:00
|
|
|
episode_index = 's{:02d}e{:02d}'.format(season_index, episode_index)
|
2022-03-01 01:32:50 +01:00
|
|
|
|
|
|
|
if episode_index:
|
|
|
|
prefix += f'{" " if prefix else ""}[{episode_index}] '
|
|
|
|
|
|
|
|
data['Name'] = prefix + data.get('Name', '')
|
|
|
|
return data
|