Store runtime data inside the config entry in Spotify (#117037)

This commit is contained in:
Michael 2024-05-25 10:41:23 +02:00 committed by GitHub
parent ad638dbcc5
commit 0ea1474556
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 32 additions and 26 deletions

View File

@ -30,6 +30,7 @@ from .util import (
PLATFORMS = [Platform.MEDIA_PLAYER] PLATFORMS = [Platform.MEDIA_PLAYER]
SpotifyConfigEntry = ConfigEntry["HomeAssistantSpotifyData"]
__all__ = [ __all__ = [
"async_browse_media", "async_browse_media",
@ -50,7 +51,7 @@ class HomeAssistantSpotifyData:
session: OAuth2Session session: OAuth2Session
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: async def async_setup_entry(hass: HomeAssistant, entry: SpotifyConfigEntry) -> bool:
"""Set up Spotify from a config entry.""" """Set up Spotify from a config entry."""
implementation = await async_get_config_entry_implementation(hass, entry) implementation = await async_get_config_entry_implementation(hass, entry)
session = OAuth2Session(hass, entry, implementation) session = OAuth2Session(hass, entry, implementation)
@ -100,8 +101,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
) )
await device_coordinator.async_config_entry_first_refresh() await device_coordinator.async_config_entry_first_refresh()
hass.data.setdefault(DOMAIN, {}) entry.runtime_data = HomeAssistantSpotifyData(
hass.data[DOMAIN][entry.entry_id] = HomeAssistantSpotifyData(
client=spotify, client=spotify,
current_user=current_user, current_user=current_user,
devices=device_coordinator, devices=device_coordinator,
@ -117,6 +117,4 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Unload Spotify config entry.""" """Unload Spotify config entry."""
if unload_ok := await hass.config_entries.async_unload_platforms(entry, PLATFORMS): return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
del hass.data[DOMAIN][entry.entry_id]
return unload_ok

View File

@ -5,7 +5,7 @@ from __future__ import annotations
from enum import StrEnum from enum import StrEnum
from functools import partial from functools import partial
import logging import logging
from typing import Any from typing import TYPE_CHECKING, Any
from spotipy import Spotify from spotipy import Spotify
import yarl import yarl
@ -22,6 +22,9 @@ from homeassistant.helpers.config_entry_oauth2_flow import OAuth2Session
from .const import DOMAIN, MEDIA_PLAYER_PREFIX, MEDIA_TYPE_SHOW, PLAYABLE_MEDIA_TYPES from .const import DOMAIN, MEDIA_PLAYER_PREFIX, MEDIA_TYPE_SHOW, PLAYABLE_MEDIA_TYPES
from .util import fetch_image_url from .util import fetch_image_url
if TYPE_CHECKING:
from . import HomeAssistantSpotifyData
BROWSE_LIMIT = 48 BROWSE_LIMIT = 48
@ -140,21 +143,21 @@ async def async_browse_media(
# Check if caller is requesting the root nodes # Check if caller is requesting the root nodes
if media_content_type is None and media_content_id is None: if media_content_type is None and media_content_id is None:
children = [] config_entries = hass.config_entries.async_entries(
for config_entry_id in hass.data[DOMAIN]: DOMAIN, include_disabled=False, include_ignore=False
config_entry = hass.config_entries.async_get_entry(config_entry_id) )
assert config_entry is not None children = [
children.append(
BrowseMedia( BrowseMedia(
title=config_entry.title, title=config_entry.title,
media_class=MediaClass.APP, media_class=MediaClass.APP,
media_content_id=f"{MEDIA_PLAYER_PREFIX}{config_entry_id}", media_content_id=f"{MEDIA_PLAYER_PREFIX}{config_entry.entry_id}",
media_content_type=f"{MEDIA_PLAYER_PREFIX}library", media_content_type=f"{MEDIA_PLAYER_PREFIX}library",
thumbnail="https://brands.home-assistant.io/_/spotify/logo.png", thumbnail="https://brands.home-assistant.io/_/spotify/logo.png",
can_play=False, can_play=False,
can_expand=True, can_expand=True,
) )
) for config_entry in config_entries
]
return BrowseMedia( return BrowseMedia(
title="Spotify", title="Spotify",
media_class=MediaClass.APP, media_class=MediaClass.APP,
@ -171,9 +174,15 @@ async def async_browse_media(
# Check for config entry specifier, and extract Spotify URI # Check for config entry specifier, and extract Spotify URI
parsed_url = yarl.URL(media_content_id) parsed_url = yarl.URL(media_content_id)
if (info := hass.data[DOMAIN].get(parsed_url.host)) is None:
if (
parsed_url.host is None
or (entry := hass.config_entries.async_get_entry(parsed_url.host)) is None
or not isinstance(entry.runtime_data, HomeAssistantSpotifyData)
):
raise BrowseError("Invalid Spotify account specified") raise BrowseError("Invalid Spotify account specified")
media_content_id = parsed_url.name media_content_id = parsed_url.name
info = entry.runtime_data
result = await async_browse_media_internal( result = await async_browse_media_internal(
hass, hass,

View File

@ -22,7 +22,6 @@ from homeassistant.components.media_player import (
MediaType, MediaType,
RepeatMode, RepeatMode,
) )
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_ID from homeassistant.const import CONF_ID
from homeassistant.core import HomeAssistant, callback from homeassistant.core import HomeAssistant, callback
from homeassistant.exceptions import HomeAssistantError from homeassistant.exceptions import HomeAssistantError
@ -30,7 +29,7 @@ from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.util.dt import utcnow from homeassistant.util.dt import utcnow
from . import HomeAssistantSpotifyData from . import HomeAssistantSpotifyData, SpotifyConfigEntry
from .browse_media import async_browse_media_internal from .browse_media import async_browse_media_internal
from .const import DOMAIN, MEDIA_PLAYER_PREFIX, PLAYABLE_MEDIA_TYPES, SPOTIFY_SCOPES from .const import DOMAIN, MEDIA_PLAYER_PREFIX, PLAYABLE_MEDIA_TYPES, SPOTIFY_SCOPES
from .util import fetch_image_url from .util import fetch_image_url
@ -70,12 +69,12 @@ SPOTIFY_DJ_PLAYLIST = {"uri": "spotify:playlist:37i9dQZF1EYkqdzj48dyYq", "name":
async def async_setup_entry( async def async_setup_entry(
hass: HomeAssistant, hass: HomeAssistant,
entry: ConfigEntry, entry: SpotifyConfigEntry,
async_add_entities: AddEntitiesCallback, async_add_entities: AddEntitiesCallback,
) -> None: ) -> None:
"""Set up Spotify based on a config entry.""" """Set up Spotify based on a config entry."""
spotify = SpotifyMediaPlayer( spotify = SpotifyMediaPlayer(
hass.data[DOMAIN][entry.entry_id], entry.runtime_data,
entry.data[CONF_ID], entry.data[CONF_ID],
entry.title, entry.title,
) )