Example #1
0
 def _get_config_or_raise(self, config_id: str) -> ConfigEntry:
     """Get a config entry from a URL."""
     entry = self.hass.config_entries.async_get_entry(config_id)
     if not entry:
         raise MediaSourceError(
             f"Unable to find config entry with id: {config_id}")
     return entry
Example #2
0
 def _get_device_or_raise(self, device_id: str) -> dr.DeviceEntry:
     """Get a config entry from a URL."""
     device_registry = dr.async_get(self.hass)
     device = device_registry.async_get(device_id)
     if not device:
         raise MediaSourceError(f"Unable to find device with id: {device_id}")
     return device
Example #3
0
 def _get_path_or_raise(cls, path: str | None) -> str:
     """Verify path is a valid motionEye path."""
     if not path:
         return "/"
     if PurePath(path).root == "/":
         return path
     raise MediaSourceError(
         f"motionEye media path must start with '/', received: {path}")
 def _get_camera_id_or_raise(
     cls, config: ConfigEntry, device: dr.DeviceEntry
 ) -> int:
     """Get a config entry from a URL."""
     for identifier in device.identifiers:
         data = split_motioneye_device_identifier(identifier)
         if data is not None:
             return data[2]
     raise MediaSourceError(f"Could not find camera id for device id: {device.id}")
Example #5
0
    def _get_client(self, identifier: Identifier) -> FrigateApiClient:
        """Get client for a given identifier."""
        config_entry = get_config_entry_for_frigate_instance_id(
            self.hass, identifier.frigate_instance_id)

        if config_entry:
            client: FrigateApiClient = (self.hass.data[DOMAIN].get(
                config_entry.entry_id, {}).get(ATTR_CLIENT))
            if client:
                return client

        raise MediaSourceError(
            "Could not find client for frigate instance id: %s" %
            identifier.frigate_instance_id)
 def _verify_kind_or_raise(cls, kind: str) -> None:
     """Verify kind is an expected value."""
     if kind in MEDIA_CLASS_MAP:
         return
     raise MediaSourceError(f"Unknown media type: {kind}")
Example #7
0
    async def async_browse_media(
        self, item: MediaSourceItem, media_types: tuple[str] = MEDIA_MIME_TYPES
    ) -> BrowseMediaSource:
        """Browse media."""

        if item.identifier is None:
            base = BrowseMediaSource(
                domain=DOMAIN,
                identifier="",
                media_class=MEDIA_CLASS_DIRECTORY,
                children_media_class=MEDIA_CLASS_VIDEO,
                media_content_type=MEDIA_TYPE_VIDEO,
                title=NAME,
                can_play=False,
                can_expand=True,
                thumbnail=None,
                children=[],
            )
            for config_entry in self.hass.config_entries.async_entries(DOMAIN):
                frigate_instance_id = get_frigate_instance_id_for_config_entry(
                    self.hass, config_entry
                )
                if frigate_instance_id:
                    clips_identifier = EventSearchIdentifier(
                        frigate_instance_id, FrigateMediaType.CLIPS
                    )
                    recording_identifier = RecordingIdentifier(frigate_instance_id)
                    snapshots_identifier = EventSearchIdentifier(
                        frigate_instance_id, FrigateMediaType.SNAPSHOTS
                    )
                    # Use the media class of the children to help distinguish
                    # the icons in the frontend.
                    base.children.extend(
                        [
                            BrowseMediaSource(
                                domain=DOMAIN,
                                identifier=clips_identifier,
                                media_class=MEDIA_CLASS_DIRECTORY,
                                children_media_class=clips_identifier.media_class,
                                media_content_type=clips_identifier.media_type,
                                title=f"Clips [{config_entry.title}]",
                                can_play=False,
                                can_expand=True,
                                thumbnail=None,
                                children=[],
                            ),
                            BrowseMediaSource(
                                domain=DOMAIN,
                                identifier=recording_identifier,
                                media_class=MEDIA_CLASS_DIRECTORY,
                                children_media_class=recording_identifier.media_class,
                                media_content_type=recording_identifier.media_type,
                                title=f"Recordings [{config_entry.title}]",
                                can_play=False,
                                can_expand=True,
                                thumbnail=None,
                                children=[],
                            ),
                            BrowseMediaSource(
                                domain=DOMAIN,
                                identifier=snapshots_identifier,
                                media_class=MEDIA_CLASS_DIRECTORY,
                                children_media_class=snapshots_identifier.media_class,
                                media_content_type=snapshots_identifier.media_type,
                                title=f"Snapshots [{config_entry.title}]",
                                can_play=False,
                                can_expand=True,
                                thumbnail=None,
                                children=[],
                            ),
                        ],
                    )
            return base

        identifier = Identifier.from_str(
            item.identifier,
            default_frigate_instance_id=self._get_default_frigate_instance_id(),
        )

        if isinstance(identifier, EventSearchIdentifier):
            if identifier.frigate_media_type == FrigateMediaType.CLIPS:
                media_kwargs = {"has_clip": True}
            else:
                media_kwargs = {"has_snapshot": True}
            try:
                events = await self._get_client(identifier).async_get_events(
                    after=identifier.after,
                    before=identifier.before,
                    camera=identifier.camera,
                    label=identifier.label,
                    zone=identifier.zone,
                    limit=10000 if identifier.name.endswith(".all") else ITEM_LIMIT,
                    **media_kwargs,
                )
            except FrigateApiClientError as exc:
                raise MediaSourceError from exc

            return self._browse_events(
                await self._get_event_summary_data(identifier), identifier, events
            )

        if isinstance(identifier, RecordingIdentifier):
            path = identifier.get_integration_proxy_path()
            try:
                recordings_folder = await self._get_client(identifier).async_get_path(
                    path
                )
            except FrigateApiClientError as exc:
                raise MediaSourceError from exc

            if identifier.hour is None:
                return self._browse_recording_folders(identifier, recordings_folder)
            return self._browse_recordings(identifier, recordings_folder)

        raise MediaSourceError("Invalid media source identifier: %s" % item.identifier)