From 1bb43f3b36d7b972bddeb3d23f9a8db3423f32da Mon Sep 17 00:00:00 2001 From: Michael Carroll Date: Mon, 13 Jul 2026 10:27:28 -0400 Subject: [PATCH 1/4] Add unresolved import lint exclusion --- custom_components/mass_queue/__init__.py | 1 + custom_components/mass_queue/config_flow.py | 1 + custom_components/mass_queue/controller.py | 1 + custom_components/mass_queue/schemas.py | 1 + custom_components/mass_queue/services.py | 1 + custom_components/mass_queue/utils.py | 1 + custom_components/mass_queue/websocket_commands.py | 1 + 7 files changed, 7 insertions(+) diff --git a/custom_components/mass_queue/__init__.py b/custom_components/mass_queue/__init__.py index 1546f8c..8f532b6 100644 --- a/custom_components/mass_queue/__init__.py +++ b/custom_components/mass_queue/__init__.py @@ -1,3 +1,4 @@ +# ty:ignore[unresolved-import] """Initialize component.""" from __future__ import annotations diff --git a/custom_components/mass_queue/config_flow.py b/custom_components/mass_queue/config_flow.py index 6615df2..e61cdf0 100644 --- a/custom_components/mass_queue/config_flow.py +++ b/custom_components/mass_queue/config_flow.py @@ -1,3 +1,4 @@ +# ty:ignore[unresolved-import] """Config flow for integration.""" from __future__ import annotations diff --git a/custom_components/mass_queue/controller.py b/custom_components/mass_queue/controller.py index 276c126..8f77010 100644 --- a/custom_components/mass_queue/controller.py +++ b/custom_components/mass_queue/controller.py @@ -1,3 +1,4 @@ +# ty:ignore[unresolved-import] """Controller for queues, players cache.""" from __future__ import annotations diff --git a/custom_components/mass_queue/schemas.py b/custom_components/mass_queue/schemas.py index 90bc999..a256d9b 100644 --- a/custom_components/mass_queue/schemas.py +++ b/custom_components/mass_queue/schemas.py @@ -1,3 +1,4 @@ +# ty:ignore[unresolved-import] """Schemas.""" from __future__ import annotations diff --git a/custom_components/mass_queue/services.py b/custom_components/mass_queue/services.py index dad0569..adaf13b 100644 --- a/custom_components/mass_queue/services.py +++ b/custom_components/mass_queue/services.py @@ -1,3 +1,4 @@ +# ty:ignore[unresolved-import] """Service actions for mass_queue.""" from __future__ import annotations diff --git a/custom_components/mass_queue/utils.py b/custom_components/mass_queue/utils.py index 7f1c2d8..69f63aa 100644 --- a/custom_components/mass_queue/utils.py +++ b/custom_components/mass_queue/utils.py @@ -1,3 +1,4 @@ +# ty:ignore[unresolved-import] """Utilities.""" from __future__ import annotations diff --git a/custom_components/mass_queue/websocket_commands.py b/custom_components/mass_queue/websocket_commands.py index 2f5236e..4147644 100644 --- a/custom_components/mass_queue/websocket_commands.py +++ b/custom_components/mass_queue/websocket_commands.py @@ -1,3 +1,4 @@ +# ty:ignore[unresolved-import] """Music Assistant Queue Actions Websocket Commands.""" from __future__ import annotations From e3982f42fc37d83e2def3c8938fcd0be6935a5d4 Mon Sep 17 00:00:00 2001 From: Michael Carroll Date: Mon, 13 Jul 2026 10:36:43 -0400 Subject: [PATCH 2/4] Linting --- custom_components/mass_queue/config_flow.py | 11 ++++++----- custom_components/mass_queue/controller.py | 2 +- custom_components/mass_queue/utils.py | 10 ++++++---- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/custom_components/mass_queue/config_flow.py b/custom_components/mass_queue/config_flow.py index e61cdf0..0307575 100644 --- a/custom_components/mass_queue/config_flow.py +++ b/custom_components/mass_queue/config_flow.py @@ -68,12 +68,13 @@ def _parse_zeroconf_server_info(properties: dict[str, str]) -> ServerInfoMessage ) -def get_manual_schema(user_input: dict[str, Any]) -> vol.Schema: +def get_manual_schema(user_input: dict[str, Any] | None) -> vol.Schema: """Return a schema for the manual step.""" - if type(user_input) is dict: - default_url = user_input.get(CONF_URL, DEFAULT_URL) - else: - default_url = DEFAULT_URL + default_url = ( + user_input.get(CONF_URL, DEFAULT_URL) + if type(user_input) is dict + else DEFAULT_URL + ) return vol.Schema( { vol.Required(CONF_URL, default=default_url): str, diff --git a/custom_components/mass_queue/controller.py b/custom_components/mass_queue/controller.py index 8f77010..80c3fd8 100644 --- a/custom_components/mass_queue/controller.py +++ b/custom_components/mass_queue/controller.py @@ -142,7 +142,7 @@ def update_player_queue(self, player_id: str): async def send_command(self, command: str, data: dict | None = None): """Sends command to Music Assistant and returns response.""" - data = data if data else {} + data = data or {} return await self._client.send_command(command, require_schema=None, **data) async def get_recommendations(self, providers: list | None = None): diff --git a/custom_components/mass_queue/utils.py b/custom_components/mass_queue/utils.py index 69f63aa..31cfd48 100644 --- a/custom_components/mass_queue/utils.py +++ b/custom_components/mass_queue/utils.py @@ -119,7 +119,7 @@ def get_queue_id_from_player_data(player_data): return current_media.get("queue_id") -def return_image_or_none(img_data: dict, remotely_accessible: bool): +def return_image_or_none(img_data: dict | None, remotely_accessible: bool): """Returns None if image is not present or not remotely accessible.""" if type(img_data) is dict: img = img_data.get("path") @@ -169,10 +169,12 @@ def find_image_from_artists(data: dict, remotely_accessible: bool): """Attempts to find the image via the artists key.""" artist = data.get("artist", {}) img_data = artist.get("image") or [] - img_data += artist.get("metadata") or [] + img_data += artist.get("metadata", {}) if len(img_data): return search_image_list(img_data, remotely_accessible) - return return_image_or_none(img_data, remotely_accessible) + if isinstance(img_data, dict): + return return_image_or_none(img_data, remotely_accessible) + return None def find_image(data: dict, remotely_accessible: bool = True): @@ -234,7 +236,7 @@ def process_recommendation_section_items(items: list): return [process_recommendation_section_item(item) for item in items] -def process_recommendation_section(section: dict): +def process_recommendation_section(section): """Process and reformat a single recommendation section.""" LOGGER.debug(f"Got section: {section}") section = section.to_dict() From fd0510809b39465ad1c9a0e81fad115719881372 Mon Sep 17 00:00:00 2001 From: Michael Carroll Date: Thu, 16 Jul 2026 12:40:18 -0400 Subject: [PATCH 3/4] Cache image responses to avoid redownloading --- custom_components/mass_queue/controller.py | 2 +- custom_components/mass_queue/utils.py | 8 ++++++-- custom_components/mass_queue/websocket_commands.py | 4 ++-- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/custom_components/mass_queue/controller.py b/custom_components/mass_queue/controller.py index 80c3fd8..3602cc7 100644 --- a/custom_components/mass_queue/controller.py +++ b/custom_components/mass_queue/controller.py @@ -379,7 +379,7 @@ async def process_image_single_item(self, queue_item: dict): img_data = queue_item["media_item"]["metadata"]["images"][0] url = generate_image_url_from_image_data(img_data, self._client) LOGGER.debug(f"Downloading URL {url}") - result = await download_and_encode_image(url, self._hass) + result = await download_and_encode_image(url) LOGGER.debug("Downloaded and setting") queue_item["local_image_encoded"] = result except Exception as e: # noqa: BLE001 diff --git a/custom_components/mass_queue/utils.py b/custom_components/mass_queue/utils.py index 31cfd48..a6b85b3 100644 --- a/custom_components/mass_queue/utils.py +++ b/custom_components/mass_queue/utils.py @@ -7,8 +7,10 @@ import urllib.parse from typing import TYPE_CHECKING +from aiocache import cached +from aiocache.serializers import PickleSerializer from homeassistant.config_entries import ConfigEntryState -from homeassistant.core import callback +from homeassistant.core import async_get_hass, callback from homeassistant.exceptions import ServiceValidationError from homeassistant.helpers import aiohttp_client from homeassistant.helpers import device_registry as dr @@ -290,8 +292,10 @@ async def download_single_image_from_image_data( return None -async def download_and_encode_image(url: str, hass: HomeAssistant): +@cached(serializer=PickleSerializer()) +async def download_and_encode_image(url: str): """Downloads and encodes a single image from the given URL.""" + hass = async_get_hass() session = aiohttp_client.async_get_clientsession(hass) req = await session.get(url) read = await req.content.read() diff --git a/custom_components/mass_queue/websocket_commands.py b/custom_components/mass_queue/websocket_commands.py index 4147644..b136f91 100644 --- a/custom_components/mass_queue/websocket_commands.py +++ b/custom_components/mass_queue/websocket_commands.py @@ -48,14 +48,14 @@ def api_get_entity_info( ) @websocket_api.async_response async def api_download_and_encode_image( - hass: HomeAssistant, + hass: HomeAssistant, # noqa: ARG001 connection: websocket_api.ActiveConnection, msg: dict, ) -> None: """Download images and return them as b64 encoded.""" LOGGER.debug(f"Got message: {msg}") url = msg["url"] - result = await download_and_encode_image(url, hass) + result = await download_and_encode_image(url) connection.send_result(msg["id"], result) From e5a8925f237ca013cfc43141f3cb702f77d33999 Mon Sep 17 00:00:00 2001 From: Michael Carroll Date: Thu, 16 Jul 2026 12:42:26 -0400 Subject: [PATCH 4/4] Version bump --- custom_components/mass_queue/manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/mass_queue/manifest.json b/custom_components/mass_queue/manifest.json index 591fa8c..ef6c9ae 100644 --- a/custom_components/mass_queue/manifest.json +++ b/custom_components/mass_queue/manifest.json @@ -11,6 +11,6 @@ "issue_tracker": "https://github.com/droans/mass_queue/issues", "requirements": ["music-assistant-client"], "ssdp": [], - "version": "0.10.1", + "version": "0.10.2", "zeroconf": ["_mass._tcp.local."] }