Merge pull request #1 from sudoxnym/fix-jellyfin-setup-error-and-deprecations.2025-09-15.05-12-09

Update Jellyfin integration for latest HA API
This commit is contained in:
sudoxnym 2025-09-14 23:12:35 -06:00 committed by GitHub
commit 751c8c1d72
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 42 additions and 61 deletions

View file

@ -194,9 +194,8 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry):
for platform in PLATFORMS: for platform in PLATFORMS:
hass.data[DOMAIN][config.get(CONF_URL)][platform] = {} hass.data[DOMAIN][config.get(CONF_URL)][platform] = {}
hass.data[DOMAIN][config.get(CONF_URL)][platform]["entities"] = [] hass.data[DOMAIN][config.get(CONF_URL)][platform]["entities"] = []
hass.async_create_task(
hass.config_entries.async_forward_entry_setup(config_entry, platform) await hass.config_entries.async_forward_entry_setups(config_entry, PLATFORMS)
)
async_dispatcher_send(hass, SIGNAL_STATE_UPDATED) async_dispatcher_send(hass, SIGNAL_STATE_UPDATED)
@ -211,14 +210,7 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry):
async def async_unload_entry(hass: HomeAssistant, config_entry: ConfigEntry): async def async_unload_entry(hass: HomeAssistant, config_entry: ConfigEntry):
_LOGGER.info("Unloading jellyfin") _LOGGER.info("Unloading jellyfin")
unload_ok = all( unload_ok = await hass.config_entries.async_unload_platforms(config_entry, PLATFORMS)
await asyncio.gather(
*[
hass.config_entries.async_forward_entry_unload(config_entry, component)
for component in PLATFORMS
]
)
)
_jelly: JellyfinClientManager = hass.data[DOMAIN][config_entry.data.get(CONF_URL)]["manager"] _jelly: JellyfinClientManager = hass.data[DOMAIN][config_entry.data.get(CONF_URL)]["manager"]
await _jelly.stop() await _jelly.stop()

View file

@ -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 import PLATFORM_SCHEMA, MediaPlayerEntity
from homeassistant.components.media_player.const import ( from homeassistant.components.media_player.const import (
MEDIA_TYPE_CHANNEL, MediaType,
MEDIA_TYPE_MOVIE,
MEDIA_TYPE_MUSIC,
MEDIA_TYPE_TVSHOW,
SUPPORT_PLAY_MEDIA, SUPPORT_PLAY_MEDIA,
SUPPORT_NEXT_TRACK, SUPPORT_NEXT_TRACK,
SUPPORT_PAUSE, SUPPORT_PAUSE,
@ -230,19 +227,19 @@ class JellyfinMediaPlayer(MediaPlayerEntity):
"""Content type of current playing media.""" """Content type of current playing media."""
media_type = self.device.media_type media_type = self.device.media_type
if media_type == "Episode": if media_type == "Episode":
return MEDIA_TYPE_TVSHOW return MediaType.TVSHOW
if media_type == "Movie": if media_type == "Movie":
return MEDIA_TYPE_MOVIE return MediaType.MOVIE
if media_type == "Trailer": if media_type == "Trailer":
return MEDIA_TYPE_TRAILER return MEDIA_TYPE_TRAILER
if media_type == "Music": if media_type == "Music":
return MEDIA_TYPE_MUSIC return MediaType.MUSIC
if media_type == "Video": if media_type == "Video":
return MEDIA_TYPE_GENERIC_VIDEO return MEDIA_TYPE_GENERIC_VIDEO
if media_type == "Audio": if media_type == "Audio":
return MEDIA_TYPE_MUSIC return MediaType.MUSIC
if media_type == "TvChannel": if media_type == "TvChannel":
return MEDIA_TYPE_CHANNEL return MediaType.CHANNEL
return None return None
@property @property

View file

@ -19,6 +19,7 @@ from homeassistant.const import ( # pylint: disable=import-error
CONF_URL, CONF_URL,
) )
from homeassistant.components.media_player.const import ( from homeassistant.components.media_player.const import (
MediaType,
MEDIA_CLASS_ALBUM, MEDIA_CLASS_ALBUM,
MEDIA_CLASS_ARTIST, MEDIA_CLASS_ARTIST,
MEDIA_CLASS_CHANNEL, MEDIA_CLASS_CHANNEL,
@ -30,15 +31,6 @@ from homeassistant.components.media_player.const import (
MEDIA_CLASS_SEASON, MEDIA_CLASS_SEASON,
MEDIA_CLASS_TRACK, MEDIA_CLASS_TRACK,
MEDIA_CLASS_TV_SHOW, 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 from . import JellyfinClientManager, JellyfinDevice, autolog
@ -49,29 +41,29 @@ from .const import (
) )
PLAYABLE_MEDIA_TYPES = [ PLAYABLE_MEDIA_TYPES = [
MEDIA_TYPE_ALBUM, MediaType.ALBUM,
MEDIA_TYPE_ARTIST, MediaType.ARTIST,
MEDIA_TYPE_TRACK, MediaType.TRACK,
] ]
CONTAINER_TYPES_SPECIFIC_MEDIA_CLASS = { CONTAINER_TYPES_SPECIFIC_MEDIA_CLASS = {
MEDIA_TYPE_ALBUM: MEDIA_CLASS_ALBUM, MediaType.ALBUM: MEDIA_CLASS_ALBUM,
MEDIA_TYPE_ARTIST: MEDIA_CLASS_ARTIST, MediaType.ARTIST: MEDIA_CLASS_ARTIST,
MEDIA_TYPE_PLAYLIST: MEDIA_CLASS_PLAYLIST, MediaType.PLAYLIST: MEDIA_CLASS_PLAYLIST,
MEDIA_TYPE_SEASON: MEDIA_CLASS_SEASON, MediaType.SEASON: MEDIA_CLASS_SEASON,
MEDIA_TYPE_TVSHOW: MEDIA_CLASS_TV_SHOW, MediaType.TVSHOW: MEDIA_CLASS_TV_SHOW,
} }
CHILD_TYPE_MEDIA_CLASS = { CHILD_TYPE_MEDIA_CLASS = {
MEDIA_TYPE_SEASON: MEDIA_CLASS_SEASON, MediaType.SEASON: MEDIA_CLASS_SEASON,
MEDIA_TYPE_ALBUM: MEDIA_CLASS_ALBUM, MediaType.ALBUM: MEDIA_CLASS_ALBUM,
MEDIA_TYPE_ARTIST: MEDIA_CLASS_ARTIST, MediaType.ARTIST: MEDIA_CLASS_ARTIST,
MEDIA_TYPE_MOVIE: MEDIA_CLASS_MOVIE, MediaType.MOVIE: MEDIA_CLASS_MOVIE,
MEDIA_TYPE_PLAYLIST: MEDIA_CLASS_PLAYLIST, MediaType.PLAYLIST: MEDIA_CLASS_PLAYLIST,
MEDIA_TYPE_TRACK: MEDIA_CLASS_TRACK, MediaType.TRACK: MEDIA_CLASS_TRACK,
MEDIA_TYPE_TVSHOW: MEDIA_CLASS_TV_SHOW, MediaType.TVSHOW: MEDIA_CLASS_TV_SHOW,
MEDIA_TYPE_CHANNEL: MEDIA_CLASS_CHANNEL, MediaType.CHANNEL: MEDIA_CLASS_CHANNEL,
MEDIA_TYPE_EPISODE: MEDIA_CLASS_EPISODE, MediaType.EPISODE: MEDIA_CLASS_EPISODE,
} }
IDENTIFIER_SPLIT = "~~" IDENTIFIER_SPLIT = "~~"
@ -140,30 +132,30 @@ def async_parse_identifier(
def Type2Mediatype(type): def Type2Mediatype(type):
switcher = { switcher = {
"Movie": MEDIA_TYPE_MOVIE, "Movie": MediaType.MOVIE,
"Series": MEDIA_TYPE_TVSHOW, "Series": MediaType.TVSHOW,
"Season": MEDIA_TYPE_SEASON, "Season": MediaType.SEASON,
"Episode": MEDIA_TYPE_EPISODE, "Episode": MediaType.EPISODE,
"Music": MEDIA_TYPE_ALBUM, "Music": MediaType.ALBUM,
"Audio": MEDIA_TYPE_TRACK, "Audio": MediaType.TRACK,
"BoxSet": MEDIA_CLASS_DIRECTORY, "BoxSet": MEDIA_CLASS_DIRECTORY,
"Folder": MEDIA_CLASS_DIRECTORY, "Folder": MEDIA_CLASS_DIRECTORY,
"CollectionFolder": MEDIA_CLASS_DIRECTORY, "CollectionFolder": MEDIA_CLASS_DIRECTORY,
"Playlist": MEDIA_CLASS_DIRECTORY, "Playlist": MEDIA_CLASS_DIRECTORY,
"PlaylistsFolder": MEDIA_CLASS_DIRECTORY, "PlaylistsFolder": MEDIA_CLASS_DIRECTORY,
"ManualPlaylistsFolder": MEDIA_CLASS_DIRECTORY, "ManualPlaylistsFolder": MEDIA_CLASS_DIRECTORY,
"MusicArtist": MEDIA_TYPE_ARTIST, "MusicArtist": MediaType.ARTIST,
"MusicAlbum": MEDIA_TYPE_ALBUM, "MusicAlbum": MediaType.ALBUM,
} }
return switcher[type] return switcher[type]
def Type2Mimetype(type): def Type2Mimetype(type):
switcher = { switcher = {
"Movie": "video/mp4", "Movie": "video/mp4",
"Series": MEDIA_TYPE_TVSHOW, "Series": MediaType.TVSHOW,
"Season": MEDIA_TYPE_SEASON, "Season": MediaType.SEASON,
"Episode": "video/mp4", "Episode": "video/mp4",
"Music": MEDIA_TYPE_ALBUM, "Music": MediaType.ALBUM,
"Audio": "audio/mp3", "Audio": "audio/mp3",
"BoxSet": MEDIA_CLASS_DIRECTORY, "BoxSet": MEDIA_CLASS_DIRECTORY,
"Folder": MEDIA_CLASS_DIRECTORY, "Folder": MEDIA_CLASS_DIRECTORY,
@ -171,8 +163,8 @@ def Type2Mimetype(type):
"Playlist": MEDIA_CLASS_DIRECTORY, "Playlist": MEDIA_CLASS_DIRECTORY,
"PlaylistsFolder": MEDIA_CLASS_DIRECTORY, "PlaylistsFolder": MEDIA_CLASS_DIRECTORY,
"ManualPlaylistsFolder": MEDIA_CLASS_DIRECTORY, "ManualPlaylistsFolder": MEDIA_CLASS_DIRECTORY,
"MusicArtist": MEDIA_TYPE_ARTIST, "MusicArtist": MediaType.ARTIST,
"MusicAlbum": MEDIA_TYPE_ALBUM, "MusicAlbum": MediaType.ALBUM,
} }
return switcher[type] return switcher[type]
@ -247,7 +239,7 @@ async def async_library_items(jelly_cm: JellyfinClientManager,
can_expand=True, can_expand=True,
children=[], 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 = { query = {
"ParentId": media_content_id, "ParentId": media_content_id,
"sortBy": "SortName", "sortBy": "SortName",
@ -285,7 +277,7 @@ async def async_library_items(jelly_cm: JellyfinClientManager,
items = await jelly_cm.get_items(query) items = await jelly_cm.get_items(query)
for item in items: 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"]: if item["IsFolder"]:
library_info.children_media_class = MEDIA_CLASS_DIRECTORY library_info.children_media_class = MEDIA_CLASS_DIRECTORY
library_info.children.append(BrowseMediaSource( library_info.children.append(BrowseMediaSource(