From e9827723f4ccee5edc7488522527a67cb96fd199 Mon Sep 17 00:00:00 2001 From: Zvonimir Rudinski Date: Wed, 10 Dec 2025 16:43:24 +0100 Subject: [PATCH] extract jellyfin utilities --- changelog/0.1.2.md | 2 +- jellyfin/api_client.py | 106 ++----------------------------- jellyfin/utils/models/audio.py | 53 ++++++++++++++++ jellyfin/utils/models/episode.py | 52 +++++++++++++++ jellyfin/utils/models/movie.py | 43 +++++++++++++ 5 files changed, 156 insertions(+), 100 deletions(-) create mode 100644 jellyfin/utils/models/audio.py create mode 100644 jellyfin/utils/models/episode.py create mode 100644 jellyfin/utils/models/movie.py diff --git a/changelog/0.1.2.md b/changelog/0.1.2.md index c8bcb3a..6834af4 100644 --- a/changelog/0.1.2.md +++ b/changelog/0.1.2.md @@ -1,4 +1,4 @@ # 0.1.2 -- Extracted utility functions from JellyfinApiClient to JellyfinUtils +- Extracted utility functions from JellyfinApiClient to utils modules - Keep client configuration in Settings class diff --git a/jellyfin/api_client.py b/jellyfin/api_client.py index a038cab..7b585fa 100644 --- a/jellyfin/api_client.py +++ b/jellyfin/api_client.py @@ -5,11 +5,12 @@ from jellyfin.models import ( JellyfinMediaType, JellyfinMusicMediaMetadata, JellyfinMovieMediaMetadata, - JellyfinEpisodeMediaMetadata) + JellyfinEpisodeMediaMetadata +) from jellyfin.utils.config import configure_client -from jellyfin.utils.playback import get_current_playback from jellyfin.utils.image import get_image_url -from typing import Optional, Tuple +from jellyfin.utils.models import episode, movie, audio +from typing import Optional import logging import time @@ -92,101 +93,8 @@ class JellyfinApiClient: media_type = item.get('Type') if media_type == 'Audio': - return self.to_music_model(item) + return audio.to_media_item(item) elif media_type == 'Episode': - return self.to_episode_model(item) + return episode.to_media_item(item, self.client) elif media_type == 'Movie': - return self.to_movie_model(item) - - def to_music_model(self, item: dict) -> JellyfinMediaItem: - """ - Converts a Jellyfin music media item dictionary to a JellyfinMediaItem model. - - Args: - item (dict): The Jellyfin music media item dictionary. - Returns: - JellyfinMediaItem: The converted JellyfinMediaItem model. - """ - media_id = item.get('Id') - parent_id = item.get('ParentId') - premiere_date = item.get('PremiereDate') - premiere_year = datetime.fromisoformat( - premiere_date).year if premiere_date else None - - metadata = JellyfinMusicMediaMetadata( - artist=item.get('AlbumArtist'), album=f"{ - item.get('Album')} ({premiere_year})" if premiere_date else item.get('Album')) - - (start, end) = get_current_playback(item) - - return JellyfinMediaItem( - id=media_id, - name=item.get('Name'), - type=JellyfinMediaType.AUDIO, - image_url=get_image_url(parent_id), - start=start, - end=end, - metadata=metadata - ) - - def to_movie_model(self, item: dict) -> JellyfinMediaItem: - """ - Converts a Jellyfin movie media item dictionary to a JellyfinMediaItem model. - - Args: - item (dict): The Jellyfin movie media item dictionary. - Returns: - JellyfinMediaItem: The converted JellyfinMediaItem model. - """ - media_id = item.get('Id') - premiere_date = item.get('PremiereDate') - - metadata = JellyfinMovieMediaMetadata(date=datetime.fromisoformat( - premiere_date).strftime('%d/%m/%Y') if premiere_date else None) - - (start, end) = get_current_playback(item) - - return JellyfinMediaItem( - id=media_id, - name=item.get('Name'), - type=JellyfinMediaType.MOVIE, - image_url=get_image_url(media_id), - start=start, - end=end, - metadata=metadata - ) - - def to_episode_model(self, item: dict) -> JellyfinMediaItem: - """ - Converts a Jellyfin episode media item dictionary to a JellyfinMediaItem model. - - Args: - item (dict): The Jellyfin episode media item dictionary. - Returns: - JellyfinMediaItem: The converted JellyfinMediaItem model. - """ - media_id = item.get('Id') - parent = self.client.jellyfin.get_item(item.get('ParentId')) - parent_id = parent.get('ParentId') - - series_name = item.get('SeriesName') - season_number = item.get('ParentIndexNumber') - episode_number = item.get('IndexNumber') - - name = f"{series_name} S{season_number:02}E{episode_number:02}" - - metadata = JellyfinEpisodeMediaMetadata( - subtitle=item.get('Name') - ) - - (start, end) = get_current_playback(item) - - return JellyfinMediaItem( - id=media_id, - name=name, - type=JellyfinMediaType.EPISODE, - image_url=get_image_url(parent_id), - start=start, - end=end, - metadata=metadata - ) + return movie.to_media_item(item) diff --git a/jellyfin/utils/models/audio.py b/jellyfin/utils/models/audio.py new file mode 100644 index 0000000..33d3ddc --- /dev/null +++ b/jellyfin/utils/models/audio.py @@ -0,0 +1,53 @@ +from jellyfin.models import ( + JellyfinMediaItem, + JellyfinMediaType, + JellyfinMusicMediaMetadata +) +from jellyfin.utils.playback import get_current_playback +from jellyfin.utils.image import get_image_url +from datetime import datetime + + +def to_media_item( + item: dict +) -> JellyfinMediaItem: + """ + Converts a Jellyfin audio media item dictionary to a JellyfinMediaItem. + + Args: + item (dict): The Jellyfin music media item dictionary. + Returns: + JellyfinMediaItem: The converted JellyfinMediaItem model. + """ + item_id = item.get('Id') + + # Get album ID (for image) + album_id = item.get('ParentId') + + # Construct album title (with year if available) + premiere_date = item.get('PremiereDate') + premiere_year = None + album = item.get('Album') + + if premiere_date: + premiere_year = datetime.fromisoformat(premiere_date).year + album = f"{album} ({premiere_year})" + + # Construct metadata + metadata = JellyfinMusicMediaMetadata( + artist=item.get('AlbumArtist'), + album=album + ) + + # Get playback positions + (start, end) = get_current_playback(item) + + return JellyfinMediaItem( + id=item_id, + name=item.get('Name'), + type=JellyfinMediaType.AUDIO, + image_url=get_image_url(item_id), + start=start, + end=end, + metadata=metadata + ) diff --git a/jellyfin/utils/models/episode.py b/jellyfin/utils/models/episode.py new file mode 100644 index 0000000..6f3b0f0 --- /dev/null +++ b/jellyfin/utils/models/episode.py @@ -0,0 +1,52 @@ +from jellyfin.models import ( + JellyfinMediaItem, + JellyfinMediaType, + JellyfinEpisodeMediaMetadata +) +from jellyfin_apiclient_python import JellyfinClient +from jellyfin.utils.playback import get_current_playback +from jellyfin.utils.image import get_image_url + + +def to_media_item( + item: dict, + client: JellyfinClient +) -> JellyfinMediaItem: + """ + Converts a Jellyfin episode media item dictionary to a JellyfinMediaItem. + + Args: + item (dict): The Jellyfin episode media item dictionary. + client (JellyfinClient): The Jellyfin client instance. + Returns: + JellyfinMediaItem: The converted JellyfinMediaItem model. + """ + item_id = item.get('Id') + + # Construct SxxExx name + series_name = item.get('SeriesName') + season_number = item.get('ParentIndexNumber') + episode_number = item.get('IndexNumber') + name = f"{series_name} S{season_number:02}E{episode_number:02}" + + # Get TV show ID (for image) + season = client.jellyfin.get_item(item.get('ParentId')) + show_id = season.get('ParentId') + + # Construct metadata + metadata = JellyfinEpisodeMediaMetadata( + subtitle=item.get('Name'), + ) + + # Get playback positions + (start, end) = get_current_playback(item) + + return JellyfinMediaItem( + id=item_id, + name=name, + type=JellyfinMediaType.EPISODE, + image_url=get_image_url(show_id), + start=start, + end=end, + metadata=metadata + ) diff --git a/jellyfin/utils/models/movie.py b/jellyfin/utils/models/movie.py new file mode 100644 index 0000000..dee2fe2 --- /dev/null +++ b/jellyfin/utils/models/movie.py @@ -0,0 +1,43 @@ +from jellyfin.models import ( + JellyfinMediaItem, + JellyfinMediaType, + JellyfinMovieMediaMetadata +) +from jellyfin.utils.playback import get_current_playback +from jellyfin.utils.image import get_image_url +from datetime import datetime + + +def to_media_item( + item: dict +) -> JellyfinMediaItem: + """ + Converts a Jellyfin movie media item dictionary to a JellyfinMediaItem. + + Args: + item (dict): The Jellyfin movie media item dictionary. + Returns: + JellyfinMediaItem: The converted JellyfinMediaItem model. + """ + item_id = item.get('Id') + + # Construct metadata + premiere_date = item.get('PremiereDate') + date = datetime.fromisoformat(premiere_date).strftime('%d/%m/%Y') + + metadata = JellyfinMovieMediaMetadata( + date=date + ) + + # Get playback positions + (start, end) = get_current_playback(item) + + return JellyfinMediaItem( + id=item_id, + name=item.get('Name'), + type=JellyfinMediaType.MOVIE, + image_url=get_image_url(item_id), + start=start, + end=end, + metadata=metadata + )