From 179d0ed206df0e81928bc5dbb64805ed06edbca2 Mon Sep 17 00:00:00 2001 From: sudoxnym <76703581+sudoxnym@users.noreply.github.com> Date: Mon, 15 Sep 2025 00:04:29 -0600 Subject: [PATCH] Restore Jellyfin config flow handler and support older entry helpers --- custom_components/jellyfin/__init__.py | 27 +++++--- custom_components/jellyfin/config_flow.py | 3 +- custom_components/jellyfin/media_player.py | 15 ++--- custom_components/jellyfin/media_source.py | 74 ++++++++++------------ 4 files changed, 58 insertions(+), 61 deletions(-) diff --git a/custom_components/jellyfin/__init__.py b/custom_components/jellyfin/__init__.py index 7bb0205..0c0f01f 100644 --- a/custom_components/jellyfin/__init__.py +++ b/custom_components/jellyfin/__init__.py @@ -194,9 +194,14 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry): for platform in PLATFORMS: hass.data[DOMAIN][config.get(CONF_URL)][platform] = {} hass.data[DOMAIN][config.get(CONF_URL)][platform]["entities"] = [] - hass.async_create_task( - hass.config_entries.async_forward_entry_setup(config_entry, platform) - ) + + if hasattr(hass.config_entries, "async_forward_entry_setups"): + await hass.config_entries.async_forward_entry_setups(config_entry, PLATFORMS) + else: + for platform in PLATFORMS: + hass.async_create_task( + hass.config_entries.async_forward_entry_setup(config_entry, platform) + ) async_dispatcher_send(hass, SIGNAL_STATE_UPDATED) @@ -211,14 +216,16 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry): async def async_unload_entry(hass: HomeAssistant, config_entry: ConfigEntry): _LOGGER.info("Unloading jellyfin") - unload_ok = all( - await asyncio.gather( - *[ - hass.config_entries.async_forward_entry_unload(config_entry, component) - for component in PLATFORMS - ] + if hasattr(hass.config_entries, "async_unload_platforms"): + unload_ok = await hass.config_entries.async_unload_platforms( + config_entry, PLATFORMS ) - ) + else: + unload_ok = True + for platform in PLATFORMS: + unload_ok = unload_ok and await hass.config_entries.async_forward_entry_unload( + config_entry, platform + ) _jelly: JellyfinClientManager = hass.data[DOMAIN][config_entry.data.get(CONF_URL)]["manager"] await _jelly.stop() diff --git a/custom_components/jellyfin/config_flow.py b/custom_components/jellyfin/config_flow.py index 027d0b0..0c83108 100644 --- a/custom_components/jellyfin/config_flow.py +++ b/custom_components/jellyfin/config_flow.py @@ -7,7 +7,7 @@ import voluptuous as vol from homeassistant import config_entries, exceptions from homeassistant.core import callback -from homeassistant.const import ( # pylint: disable=import-error +from homeassistant.const import ( # pylint: disable=import-error CONF_URL, CONF_VERIFY_SSL, CONF_USERNAME, @@ -47,6 +47,7 @@ class JellyfinFlowHandler(config_entries.ConfigFlow): self._url = None self._ssl = DEFAULT_SSL self._verify_ssl = DEFAULT_VERIFY_SSL + self._is_import = False async def async_step_import(self, user_input=None): """Handle configuration by yaml file.""" diff --git a/custom_components/jellyfin/media_player.py b/custom_components/jellyfin/media_player.py index aa2e828..2bca00c 100644 --- a/custom_components/jellyfin/media_player.py +++ b/custom_components/jellyfin/media_player.py @@ -4,10 +4,7 @@ from typing import Mapping, MutableMapping, Optional, Sequence, Iterable, List, from homeassistant.components.media_player import PLATFORM_SCHEMA, MediaPlayerEntity from homeassistant.components.media_player.const import ( - MEDIA_TYPE_CHANNEL, - MEDIA_TYPE_MOVIE, - MEDIA_TYPE_MUSIC, - MEDIA_TYPE_TVSHOW, + MediaType, SUPPORT_PLAY_MEDIA, SUPPORT_NEXT_TRACK, SUPPORT_PAUSE, @@ -230,19 +227,19 @@ class JellyfinMediaPlayer(MediaPlayerEntity): """Content type of current playing media.""" media_type = self.device.media_type if media_type == "Episode": - return MEDIA_TYPE_TVSHOW + return MediaType.TVSHOW if media_type == "Movie": - return MEDIA_TYPE_MOVIE + return MediaType.MOVIE if media_type == "Trailer": return MEDIA_TYPE_TRAILER if media_type == "Music": - return MEDIA_TYPE_MUSIC + return MediaType.MUSIC if media_type == "Video": return MEDIA_TYPE_GENERIC_VIDEO if media_type == "Audio": - return MEDIA_TYPE_MUSIC + return MediaType.MUSIC if media_type == "TvChannel": - return MEDIA_TYPE_CHANNEL + return MediaType.CHANNEL return None @property diff --git a/custom_components/jellyfin/media_source.py b/custom_components/jellyfin/media_source.py index 7d72005..57e8c3f 100644 --- a/custom_components/jellyfin/media_source.py +++ b/custom_components/jellyfin/media_source.py @@ -19,6 +19,7 @@ from homeassistant.const import ( # pylint: disable=import-error CONF_URL, ) from homeassistant.components.media_player.const import ( + MediaType, MEDIA_CLASS_ALBUM, MEDIA_CLASS_ARTIST, MEDIA_CLASS_CHANNEL, @@ -30,15 +31,6 @@ from homeassistant.components.media_player.const import ( MEDIA_CLASS_SEASON, MEDIA_CLASS_TRACK, MEDIA_CLASS_TV_SHOW, - MEDIA_TYPE_ALBUM, - MEDIA_TYPE_ARTIST, - MEDIA_TYPE_CHANNEL, - MEDIA_TYPE_EPISODE, - MEDIA_TYPE_MOVIE, - MEDIA_TYPE_PLAYLIST, - MEDIA_TYPE_SEASON, - MEDIA_TYPE_TRACK, - MEDIA_TYPE_TVSHOW, ) from . import JellyfinClientManager, JellyfinDevice, autolog @@ -49,29 +41,29 @@ from .const import ( ) PLAYABLE_MEDIA_TYPES = [ - MEDIA_TYPE_ALBUM, - MEDIA_TYPE_ARTIST, - MEDIA_TYPE_TRACK, + MediaType.ALBUM, + MediaType.ARTIST, + MediaType.TRACK, ] CONTAINER_TYPES_SPECIFIC_MEDIA_CLASS = { - MEDIA_TYPE_ALBUM: MEDIA_CLASS_ALBUM, - MEDIA_TYPE_ARTIST: MEDIA_CLASS_ARTIST, - MEDIA_TYPE_PLAYLIST: MEDIA_CLASS_PLAYLIST, - MEDIA_TYPE_SEASON: MEDIA_CLASS_SEASON, - MEDIA_TYPE_TVSHOW: MEDIA_CLASS_TV_SHOW, + MediaType.ALBUM: MEDIA_CLASS_ALBUM, + MediaType.ARTIST: MEDIA_CLASS_ARTIST, + MediaType.PLAYLIST: MEDIA_CLASS_PLAYLIST, + MediaType.SEASON: MEDIA_CLASS_SEASON, + MediaType.TVSHOW: MEDIA_CLASS_TV_SHOW, } CHILD_TYPE_MEDIA_CLASS = { - MEDIA_TYPE_SEASON: MEDIA_CLASS_SEASON, - MEDIA_TYPE_ALBUM: MEDIA_CLASS_ALBUM, - MEDIA_TYPE_ARTIST: MEDIA_CLASS_ARTIST, - MEDIA_TYPE_MOVIE: MEDIA_CLASS_MOVIE, - MEDIA_TYPE_PLAYLIST: MEDIA_CLASS_PLAYLIST, - MEDIA_TYPE_TRACK: MEDIA_CLASS_TRACK, - MEDIA_TYPE_TVSHOW: MEDIA_CLASS_TV_SHOW, - MEDIA_TYPE_CHANNEL: MEDIA_CLASS_CHANNEL, - MEDIA_TYPE_EPISODE: MEDIA_CLASS_EPISODE, + MediaType.SEASON: MEDIA_CLASS_SEASON, + MediaType.ALBUM: MEDIA_CLASS_ALBUM, + MediaType.ARTIST: MEDIA_CLASS_ARTIST, + MediaType.MOVIE: MEDIA_CLASS_MOVIE, + MediaType.PLAYLIST: MEDIA_CLASS_PLAYLIST, + MediaType.TRACK: MEDIA_CLASS_TRACK, + MediaType.TVSHOW: MEDIA_CLASS_TV_SHOW, + MediaType.CHANNEL: MEDIA_CLASS_CHANNEL, + MediaType.EPISODE: MEDIA_CLASS_EPISODE, } IDENTIFIER_SPLIT = "~~" @@ -140,30 +132,30 @@ def async_parse_identifier( def Type2Mediatype(type): switcher = { - "Movie": MEDIA_TYPE_MOVIE, - "Series": MEDIA_TYPE_TVSHOW, - "Season": MEDIA_TYPE_SEASON, - "Episode": MEDIA_TYPE_EPISODE, - "Music": MEDIA_TYPE_ALBUM, - "Audio": MEDIA_TYPE_TRACK, + "Movie": MediaType.MOVIE, + "Series": MediaType.TVSHOW, + "Season": MediaType.SEASON, + "Episode": MediaType.EPISODE, + "Music": MediaType.ALBUM, + "Audio": MediaType.TRACK, "BoxSet": MEDIA_CLASS_DIRECTORY, "Folder": MEDIA_CLASS_DIRECTORY, "CollectionFolder": MEDIA_CLASS_DIRECTORY, "Playlist": MEDIA_CLASS_DIRECTORY, "PlaylistsFolder": MEDIA_CLASS_DIRECTORY, "ManualPlaylistsFolder": MEDIA_CLASS_DIRECTORY, - "MusicArtist": MEDIA_TYPE_ARTIST, - "MusicAlbum": MEDIA_TYPE_ALBUM, + "MusicArtist": MediaType.ARTIST, + "MusicAlbum": MediaType.ALBUM, } return switcher[type] def Type2Mimetype(type): switcher = { "Movie": "video/mp4", - "Series": MEDIA_TYPE_TVSHOW, - "Season": MEDIA_TYPE_SEASON, + "Series": MediaType.TVSHOW, + "Season": MediaType.SEASON, "Episode": "video/mp4", - "Music": MEDIA_TYPE_ALBUM, + "Music": MediaType.ALBUM, "Audio": "audio/mp3", "BoxSet": MEDIA_CLASS_DIRECTORY, "Folder": MEDIA_CLASS_DIRECTORY, @@ -171,8 +163,8 @@ def Type2Mimetype(type): "Playlist": MEDIA_CLASS_DIRECTORY, "PlaylistsFolder": MEDIA_CLASS_DIRECTORY, "ManualPlaylistsFolder": MEDIA_CLASS_DIRECTORY, - "MusicArtist": MEDIA_TYPE_ARTIST, - "MusicAlbum": MEDIA_TYPE_ALBUM, + "MusicArtist": MediaType.ARTIST, + "MusicAlbum": MediaType.ALBUM, } return switcher[type] @@ -247,7 +239,7 @@ async def async_library_items(jelly_cm: JellyfinClientManager, can_expand=True, children=[], ) - elif media_content_type in [MEDIA_CLASS_DIRECTORY, MEDIA_TYPE_ARTIST, MEDIA_TYPE_ALBUM, MEDIA_TYPE_PLAYLIST, MEDIA_TYPE_TVSHOW, MEDIA_TYPE_SEASON]: + elif media_content_type in [MEDIA_CLASS_DIRECTORY, MediaType.ARTIST, MediaType.ALBUM, MediaType.PLAYLIST, MediaType.TVSHOW, MediaType.SEASON]: query = { "ParentId": media_content_id, "sortBy": "SortName", @@ -285,7 +277,7 @@ async def async_library_items(jelly_cm: JellyfinClientManager, items = await jelly_cm.get_items(query) for item in items: - if media_content_type in [None, "library", MEDIA_CLASS_DIRECTORY, MEDIA_TYPE_ARTIST, MEDIA_TYPE_ALBUM, MEDIA_TYPE_PLAYLIST, MEDIA_TYPE_TVSHOW, MEDIA_TYPE_SEASON]: + if media_content_type in [None, "library", MEDIA_CLASS_DIRECTORY, MediaType.ARTIST, MediaType.ALBUM, MediaType.PLAYLIST, MediaType.TVSHOW, MediaType.SEASON]: if item["IsFolder"]: library_info.children_media_class = MEDIA_CLASS_DIRECTORY library_info.children.append(BrowseMediaSource(