Coverage for custom_components/supernotify/context.py: 90%

42 statements  

« prev     ^ index     » next       coverage.py v7.10.6, created at 2025-11-21 23:31 +0000

1from __future__ import annotations 

2 

3import logging 

4from pathlib import Path 

5from typing import TYPE_CHECKING, Any 

6 

7from homeassistant.helpers.typing import ConfigType 

8 

9if TYPE_CHECKING: 

10 from .archive import NotificationArchive 

11 from .scenario import ScenarioRegistry 

12 from .snoozer import Snoozer 

13from homeassistant.helpers import condition as condition 

14 

15from . import ( 

16 CONF_CAMERA, 

17) 

18from .common import ensure_list 

19 

20if TYPE_CHECKING: 

21 from homeassistant.helpers.typing import ConfigType 

22 

23 from .delivery import DeliveryRegistry 

24 from .hass_api import HomeAssistantAPI 

25 from .people import PeopleRegistry 

26 from .transport import Transport 

27 

28 

29_LOGGER = logging.getLogger(__name__) 

30 

31 

32class Context: 

33 def __init__( 

34 self, 

35 hass_api: HomeAssistantAPI, 

36 people_registry: PeopleRegistry, 

37 scenario_registry: ScenarioRegistry, 

38 delivery_registry: DeliveryRegistry, 

39 archive: NotificationArchive, 

40 snoozer: Snoozer, 

41 links: list[str] | None = None, 

42 recipients: list[dict[str, Any]] | None = None, 

43 mobile_actions: ConfigType | None = None, 

44 template_path: str | None = None, 

45 media_path: str | None = None, 

46 cameras: list[ConfigType] | None = None, 

47 **kwargs: Any, 

48 ) -> None: 

49 self.delivery_registry: DeliveryRegistry = delivery_registry 

50 self.snoozer: Snoozer = snoozer 

51 self.people_registry: PeopleRegistry = people_registry 

52 self.scenario_registry: ScenarioRegistry = scenario_registry 

53 self.archive: NotificationArchive = archive 

54 self.hass_api: HomeAssistantAPI = hass_api 

55 self.links: list[dict[str, Any]] = ensure_list(links) 

56 

57 self._recipients: list[dict[str, Any]] = ensure_list(recipients) 

58 self.mobile_actions: ConfigType = mobile_actions or {} 

59 self.template_path: Path | None = Path(template_path) if template_path else None 

60 self.media_path: Path | None = Path(media_path) if media_path else None 

61 

62 self.cameras: dict[str, Any] = {c[CONF_CAMERA]: c for c in cameras} if cameras else {} 

63 self.snoozer = snoozer 

64 if kwargs: 

65 _LOGGER.warning("SUPERNOTIFY Context threw away kwargs:", kwargs) 

66 

67 async def initialize(self) -> None: 

68 if self.template_path and not self.template_path.exists(): 

69 _LOGGER.warning("SUPERNOTIFY template path not found at %s", self.template_path) 

70 self.template_path = None 

71 

72 if self.media_path and not self.media_path.exists(): 

73 _LOGGER.info("SUPERNOTIFY media path not found at %s", self.media_path) 

74 try: 

75 self.media_path.mkdir(parents=True, exist_ok=True) 

76 except Exception as e: 

77 _LOGGER.warning("SUPERNOTIFY media path %s cannot be created: %s", self.media_path, e) 

78 self.hass_api.raise_issue( 

79 "media_path", 

80 "media_path", 

81 {"path": str(self.media_path), "error": str(e)}, 

82 learn_more_url="https://supernotify.rhizomatics.org.uk/#getting-started", 

83 ) 

84 self.media_path = None 

85 if self.media_path is not None: 

86 _LOGGER.info("SUPERNOTIFY abs media path: %s", self.media_path.absolute()) 

87 

88 def configure_for_tests(self, transport_instances: list[Transport] | None = None) -> None: 

89 self.delivery_registry._transport_instances = transport_instances