Coverage for custom_components/supernotify/methods/media_player_image.py: 91%
34 statements
« prev ^ index » next coverage.py v7.10.6, created at 2025-10-18 09:29 +0000
« prev ^ index » next coverage.py v7.10.6, created at 2025-10-18 09:29 +0000
1import logging
2import re
3import urllib.parse
4from typing import Any
6from custom_components.supernotify import METHOD_MEDIA
7from custom_components.supernotify.delivery_method import DeliveryMethod
8from custom_components.supernotify.envelope import Envelope
10RE_VALID_MEDIA_PLAYER = r"media_player\.[A-Za-z0-9_]+"
12_LOGGER = logging.getLogger(__name__)
15class MediaPlayerImageDeliveryMethod(DeliveryMethod):
16 method = METHOD_MEDIA
18 def __init__(self, *args: Any, **kwargs: Any) -> None:
19 kwargs["default_action"] = "media_player.play_media"
20 super().__init__(*args, **kwargs)
22 def select_target(self, target: str) -> bool:
23 return re.fullmatch(RE_VALID_MEDIA_PLAYER, target) is not None
25 def validate_action(self, action: str | None) -> bool:
26 return action is None or action == "media_player.play_media"
28 async def deliver(self, envelope: Envelope) -> bool:
29 _LOGGER.info("SUPERNOTIFY notify_media: %s", envelope.data)
31 data: dict[str, Any] = envelope.data or {}
32 media_players: list[str] = envelope.targets or []
33 if not media_players:
34 _LOGGER.debug("SUPERNOTIFY skipping media show, no targets")
35 return False
37 snapshot_url = data.get("snapshot_url")
38 if snapshot_url is None:
39 _LOGGER.debug("SUPERNOTIFY skipping media player, no image url")
40 return False
41 # absolutize relative URL for external URl, probably preferred by Alexa Show etc
42 snapshot_url = urllib.parse.urljoin(self.context.hass_external_url, snapshot_url)
44 action_data: dict[str, Any] = {
45 "media_content_id": snapshot_url,
46 "media_content_type": "image",
47 "entity_id": media_players,
48 }
49 if data and data.get("data"):
50 action_data["extra"] = data.get("data", {})
52 return await self.call_action(envelope, action_data=action_data)