From 4f0ef340b42c4964e3c175a0dfc6ac9ad6fe55d1 Mon Sep 17 00:00:00 2001 From: Zvonimir Rudinski Date: Wed, 10 Dec 2025 01:41:08 +0100 Subject: [PATCH] calculate start and end --- discord/models.py | 2 ++ discord/rpc.py | 4 +++- jellyfin/api_client.py | 27 +++++++++++++++++++++++++++ jellyfin/models.py | 2 ++ jellyfin/utils.py | 12 +++++++++--- 5 files changed, 43 insertions(+), 4 deletions(-) diff --git a/discord/models.py b/discord/models.py index 6eebeeb..2e789dd 100644 --- a/discord/models.py +++ b/discord/models.py @@ -7,4 +7,6 @@ class DiscordRPCUpdatePayload(BaseModel): subtitle: str image_url: str details: str + start: int + end: int activity_type: ActivityType diff --git a/discord/rpc.py b/discord/rpc.py index 510aef7..619b1ee 100644 --- a/discord/rpc.py +++ b/discord/rpc.py @@ -24,7 +24,9 @@ class DiscordRPC: details=payload.title, state=payload.subtitle, large_image=payload.image_url, - large_text=payload.details + large_text=payload.details, + start=payload.start, + end=payload.end ) self.logger.info("Discord RPC presence updated.") diff --git a/jellyfin/api_client.py b/jellyfin/api_client.py index fe05c5f..85209f4 100644 --- a/jellyfin/api_client.py +++ b/jellyfin/api_client.py @@ -64,14 +64,33 @@ class JellyfinApiClient: raise ValueError(f"Unsupported media type: {media_type}") + def get_playback_info(self, media: dict): + media_id = media.get('Id') + playback_info = self.client.jellyfin.get_userdata_for_item(media_id) + + runtime_ticks = media.get('RunTimeTicks', 0) + total_runtime_seconds = runtime_ticks // 10_000_000 + + playback_position_ticks = playback_info.get('PlaybackPositionTicks', 0) + playback_position_seconds = playback_position_ticks // 10_000_000 + + start = int(datetime.now().timestamp()) - playback_position_seconds + end = start + total_runtime_seconds + + return (start, end) + def to_music_model(self, item: dict) -> JellyfinMediaItem: media_id = item.get('Id') + (start, end) = self.get_playback_info(item) + return JellyfinMediaItem( id=media_id, name=item.get('Name'), type=JellyfinMediaType.AUDIO, image_url=self.get_image_url(media_id), + start=start, + end=end, metadata={ 'artist': item.get('AlbumArtist'), } @@ -81,11 +100,15 @@ class JellyfinApiClient: media_id = item.get('Id') premiere_date = item.get('PremiereDate') + (start, end) = self.get_playback_info(item) + return JellyfinMediaItem( id=media_id, name=item.get('Name'), type=JellyfinMediaType.MOVIE, image_url=self.get_image_url(media_id), + start=start, + end=end, metadata={ 'date': datetime.fromisoformat(premiere_date).strftime('%d/%m/%Y') if premiere_date else None } @@ -99,11 +122,15 @@ class JellyfinApiClient: subtitle=f"S{season_number:02}E{episode_number:02} of {seris_name}" + (start, end) = self.get_playback_info(item) + return JellyfinMediaItem( id=media_id, name=item.get('Name'), type=JellyfinMediaType.EPISODE, image_url=self.get_image_url(media_id), + start=start, + end=end, metadata={ 'subtitle': subtitle, } diff --git a/jellyfin/models.py b/jellyfin/models.py index 071b54a..ea2bf6d 100644 --- a/jellyfin/models.py +++ b/jellyfin/models.py @@ -11,4 +11,6 @@ class JellyfinMediaItem(BaseModel): name: str type: JellyfinMediaType image_url: str + start: int + end: int metadata: dict diff --git a/jellyfin/utils.py b/jellyfin/utils.py index 01881df..e5221ba 100644 --- a/jellyfin/utils.py +++ b/jellyfin/utils.py @@ -10,7 +10,9 @@ def to_rpc_payload(media_item: JellyfinMediaItem) -> DiscordRPCUpdatePayload: subtitle=f"by {media_item.metadata.get('artist', 'Unknown Artist')}", image_url=media_item.image_url, details=media_item.name, - activity_type=ActivityType.LISTENING + activity_type=ActivityType.LISTENING, + start=media_item.start, + end=media_item.end ) elif media_item.type == JellyfinMediaType.MOVIE: return DiscordRPCUpdatePayload( @@ -19,7 +21,9 @@ def to_rpc_payload(media_item: JellyfinMediaItem) -> DiscordRPCUpdatePayload: subtitle=media_item.metadata.get('date'), image_url=media_item.image_url, details=media_item.name, - activity_type=ActivityType.WATCHING + activity_type=ActivityType.WATCHING, + start=media_item.start, + end=media_item.end ) elif media_item.type == JellyfinMediaType.EPISODE: return DiscordRPCUpdatePayload( @@ -28,5 +32,7 @@ def to_rpc_payload(media_item: JellyfinMediaItem) -> DiscordRPCUpdatePayload: subtitle=media_item.metadata.get('subtitle'), image_url=media_item.image_url, details=media_item.name, - activity_type=ActivityType.WATCHING + activity_type=ActivityType.WATCHING, + start=media_item.start, + end=media_item.end )