File: notifier.py

package info (click to toggle)
notifications-android-tv 1.2.2-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 172 kB
  • sloc: python: 410; makefile: 6; sh: 5
file content (102 lines) | stat: -rw-r--r-- 3,227 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
"""Notification class for Android TV."""

import base64
import logging
from typing import Any

import httpx

from .const import (
    DEFAULT_ICON,
    DEFAULT_TITLE,
)
from .exceptions import ConnectError, InvalidResponse
from .helpers import NotificationParams

_LOGGER = logging.getLogger(__name__)


class Notifications:
    """Notifications class for Android/Fire Tvs."""

    def __init__(
        self,
        host: str,
        port: int = 7676,
        httpx_client: httpx.AsyncClient | None = None,
    ) -> None:
        """Initialize notifier."""
        self.url = f"http://{host}:{port}"
        self.httpx_client = httpx_client

    async def async_connect(self) -> None:
        """Test connecting to server."""
        httpx_client: httpx.AsyncClient = self.httpx_client or httpx.AsyncClient(
            verify=False
        )
        try:
            async with httpx_client as client:
                await client.get(self.url, timeout=30)
        except (httpx.ConnectError, httpx.TimeoutException) as err:
            raise ConnectError(f"Connection to {self.url} failed: {err}") from err

    async def async_send(
        self,
        message: str,
        *,
        title: str | None = None,
        params: NotificationParams | None = None,
    ) -> None:
        """Send message with parameters.

        :param message: The notification message.
        :param title: (Optional) The notification title.
        :params params: (Optional) Notification parameters. Construct using NotificationParams.

        Usage:
        >>> from notifications_android_tv import Notifications
        >>> notifier = Notifications("192.168.3.88")
        >>> await notifier.async_connect()
        >>> await notifier.async_send(
                "message to be sent",
                title="Notification title",
                params=NotificationParams(
                    duration=5,
                    position=Positions.BOTTOM_RIGHT,
                    fontsize=FontSize.MEDIUM,
                )
            )
        """
        data: dict[str, Any] = {
            "msg": message,
            "title": title or DEFAULT_TITLE,
        }
        if params is not None:
            data.update(params.data_params)
            files = await params.get_images()
        else:
            icon_bytes = base64.b64decode(DEFAULT_ICON)
            files = {
                "filename": (
                    "image",
                    icon_bytes,
                    "application/octet-stream",
                    {"Expires": "0"},
                )
            }

        _LOGGER.debug("data: %s, files: %s", data, files)

        httpx_client: httpx.AsyncClient = self.httpx_client or httpx.AsyncClient(
            verify=False
        )
        try:
            async with httpx_client as client:
                response = await client.post(
                    self.url, data=data, files=files, timeout=10
                )

        except (httpx.ConnectError, httpx.TimeoutException) as err:
            raise ConnectError(f"Error communicating with {self.url}: {err}") from err
        if response.status_code != httpx.codes.OK:
            raise InvalidResponse(f"Error sending message: {response}")