From 412c8051ef71953845576b582e0ea898edcfb448 Mon Sep 17 00:00:00 2001 From: Fabian Munkes <105975993+fmunkes@users.noreply.github.com> Date: Wed, 26 Mar 2025 23:38:32 +0100 Subject: [PATCH] Abs + Feed Parsers: release_date as datetime (#2064) --- music_assistant/helpers/podcast_parsers.py | 10 ++++-- .../providers/audiobookshelf/parsers.py | 31 +++++++++++++++++-- 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/music_assistant/helpers/podcast_parsers.py b/music_assistant/helpers/podcast_parsers.py index c4ae1473..9ed30791 100644 --- a/music_assistant/helpers/podcast_parsers.py +++ b/music_assistant/helpers/podcast_parsers.py @@ -1,5 +1,6 @@ """Podcastfeed -> Mass.""" +from datetime import datetime from typing import Any from music_assistant_models.enums import ContentType, ImageType, MediaType @@ -106,7 +107,11 @@ def parse_podcast_episode( episode_duration = episode.get("total_time", 0.0) episode_title = episode.get("title", "NO_EPISODE_TITLE") episode_cover = episode.get("episode_art_url", podcast_cover) - episode_published = episode.get("published") + + # this is unix epoch in s, and 0 if unknown + episode_published: int | None = episode.get("published") + if episode_published == 0: + episode_published = None stream_url, guid = get_stream_url_and_guid_from_episode(episode=episode) guid_or_stream_url = guid if guid is not None else stream_url @@ -139,7 +144,8 @@ def parse_podcast_episode( ) }, ) - mass_episode.metadata.release_date = episode_published + if episode_published is not None: + mass_episode.metadata.release_date = datetime.fromtimestamp(episode_published) # chapter if chapters := episode.get("chapters"): diff --git a/music_assistant/providers/audiobookshelf/parsers.py b/music_assistant/providers/audiobookshelf/parsers.py index 9ca6d1af..19ac868f 100644 --- a/music_assistant/providers/audiobookshelf/parsers.py +++ b/music_assistant/providers/audiobookshelf/parsers.py @@ -1,5 +1,8 @@ """Parser for ABS -> MASS.""" +from contextlib import suppress +from datetime import datetime + from aioaudiobookshelf.schema.library import ( LibraryItemExpandedBook as AbsLibraryItemExpandedBook, ) @@ -71,7 +74,13 @@ def parse_podcast( mass_podcast.metadata.languages = UniqueList([abs_podcast.media.metadata.language]) if abs_podcast.media.metadata.genres is not None: mass_podcast.metadata.genres = set(abs_podcast.media.metadata.genres) - mass_podcast.metadata.release_date = abs_podcast.media.metadata.release_date + + # podcast object has no published_at int, but an iso string + if abs_podcast.media.metadata.release_date is not None: + with suppress(ValueError): + mass_podcast.metadata.release_date = datetime.fromisoformat( + abs_podcast.media.metadata.release_date + ) if isinstance(abs_podcast, AbsLibraryItemExpandedPodcast | AbsLibraryItemPodcast): mass_podcast.total_episodes = len(abs_podcast.media.episodes) @@ -102,8 +111,11 @@ def parse_podcast_episode( url = f"{base_url}{episode.audio_track.content_url}" episode_id = f"{prov_podcast_id} {episode.id_}" + release_date: datetime | None = None if episode.published_at is not None: position = -episode.published_at + # abs published_at is ms epoch + release_date = datetime.fromtimestamp(episode.published_at / 1000) else: position = 0 if fallback_episode_cnt is not None: @@ -113,7 +125,6 @@ def parse_podcast_episode( provider=lookup_key, name=episode.title, duration=int(episode.duration), - publish_date=None, position=position, podcast=ItemMapping( item_id=prov_podcast_id, @@ -134,6 +145,8 @@ def parse_podcast_episode( }, ) + mass_episode.metadata.release_date = release_date + # cover image if token is not None: url_api = f"/api/items/{prov_podcast_id}/cover?token={token}" @@ -184,7 +197,19 @@ def parse_audiobook( mass_audiobook.metadata.description = abs_audiobook.media.metadata.description if abs_audiobook.media.metadata.language is not None: mass_audiobook.metadata.languages = UniqueList([abs_audiobook.media.metadata.language]) - mass_audiobook.metadata.release_date = abs_audiobook.media.metadata.published_date + + if abs_audiobook.media.metadata.published_date is not None: + with suppress(ValueError): + mass_audiobook.metadata.release_date = datetime.fromisoformat( + abs_audiobook.media.metadata.published_date + ) + elif abs_audiobook.media.metadata.published_year is not None: + with suppress(ValueError): + # ruff: noqa: DTZ001 # ignore tzinfo, this is a fallback attempt + mass_audiobook.metadata.release_date = datetime( + year=int(abs_audiobook.media.metadata.published_year), month=1, day=1 + ) + if abs_audiobook.media.metadata.genres is not None: mass_audiobook.metadata.genres = set(abs_audiobook.media.metadata.genres) -- 2.34.1