mirror of
https://github.com/home-assistant/core.git
synced 2025-04-25 17:57:55 +00:00
Improve type hints in mailbox (#78353)
This commit is contained in:
parent
49ab5cfc9c
commit
02c9541862
@ -3,6 +3,7 @@ from __future__ import annotations
|
|||||||
|
|
||||||
from functools import partial
|
from functools import partial
|
||||||
import logging
|
import logging
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from asterisk_mbox import ServerError
|
from asterisk_mbox import ServerError
|
||||||
|
|
||||||
@ -11,7 +12,7 @@ from homeassistant.core import HomeAssistant, callback
|
|||||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||||
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
||||||
|
|
||||||
from . import DOMAIN as ASTERISK_DOMAIN
|
from . import DOMAIN as ASTERISK_DOMAIN, AsteriskData
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -31,7 +32,7 @@ async def async_get_handler(
|
|||||||
class AsteriskMailbox(Mailbox):
|
class AsteriskMailbox(Mailbox):
|
||||||
"""Asterisk VM Sensor."""
|
"""Asterisk VM Sensor."""
|
||||||
|
|
||||||
def __init__(self, hass, name):
|
def __init__(self, hass: HomeAssistant, name: str) -> None:
|
||||||
"""Initialize Asterisk mailbox."""
|
"""Initialize Asterisk mailbox."""
|
||||||
super().__init__(hass, name)
|
super().__init__(hass, name)
|
||||||
async_dispatcher_connect(
|
async_dispatcher_connect(
|
||||||
@ -39,29 +40,30 @@ class AsteriskMailbox(Mailbox):
|
|||||||
)
|
)
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def _update_callback(self, msg):
|
def _update_callback(self, msg: str) -> None:
|
||||||
"""Update the message count in HA, if needed."""
|
"""Update the message count in HA, if needed."""
|
||||||
self.async_update()
|
self.async_update()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def media_type(self):
|
def media_type(self) -> str:
|
||||||
"""Return the supported media type."""
|
"""Return the supported media type."""
|
||||||
return CONTENT_TYPE_MPEG
|
return CONTENT_TYPE_MPEG
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def can_delete(self):
|
def can_delete(self) -> bool:
|
||||||
"""Return if messages can be deleted."""
|
"""Return if messages can be deleted."""
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def has_media(self):
|
def has_media(self) -> bool:
|
||||||
"""Return if messages have attached media files."""
|
"""Return if messages have attached media files."""
|
||||||
return True
|
return True
|
||||||
|
|
||||||
async def async_get_media(self, msgid):
|
async def async_get_media(self, msgid: str) -> bytes:
|
||||||
"""Return the media blob for the msgid."""
|
"""Return the media blob for the msgid."""
|
||||||
|
|
||||||
client = self.hass.data[ASTERISK_DOMAIN].client
|
data: AsteriskData = self.hass.data[ASTERISK_DOMAIN]
|
||||||
|
client = data.client
|
||||||
try:
|
try:
|
||||||
return await self.hass.async_add_executor_job(
|
return await self.hass.async_add_executor_job(
|
||||||
partial(client.mp3, msgid, sync=True)
|
partial(client.mp3, msgid, sync=True)
|
||||||
@ -69,13 +71,15 @@ class AsteriskMailbox(Mailbox):
|
|||||||
except ServerError as err:
|
except ServerError as err:
|
||||||
raise StreamError(err) from err
|
raise StreamError(err) from err
|
||||||
|
|
||||||
async def async_get_messages(self):
|
async def async_get_messages(self) -> list[dict[str, Any]]:
|
||||||
"""Return a list of the current messages."""
|
"""Return a list of the current messages."""
|
||||||
return self.hass.data[ASTERISK_DOMAIN].messages
|
data: AsteriskData = self.hass.data[ASTERISK_DOMAIN]
|
||||||
|
return data.messages
|
||||||
|
|
||||||
async def async_delete(self, msgid):
|
async def async_delete(self, msgid: str) -> bool:
|
||||||
"""Delete the specified messages."""
|
"""Delete the specified messages."""
|
||||||
client = self.hass.data[ASTERISK_DOMAIN].client
|
data: AsteriskData = self.hass.data[ASTERISK_DOMAIN]
|
||||||
|
client = data.client
|
||||||
_LOGGER.info("Deleting: %s", msgid)
|
_LOGGER.info("Deleting: %s", msgid)
|
||||||
await self.hass.async_add_executor_job(client.delete, msgid)
|
await self.hass.async_add_executor_job(client.delete, msgid)
|
||||||
return True
|
return True
|
||||||
|
@ -6,6 +6,7 @@ from contextlib import suppress
|
|||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
from http import HTTPStatus
|
from http import HTTPStatus
|
||||||
import logging
|
import logging
|
||||||
|
from typing import Any, Final
|
||||||
|
|
||||||
from aiohttp import web
|
from aiohttp import web
|
||||||
from aiohttp.web_exceptions import HTTPNotFound
|
from aiohttp.web_exceptions import HTTPNotFound
|
||||||
@ -13,7 +14,7 @@ import async_timeout
|
|||||||
|
|
||||||
from homeassistant.components import frontend
|
from homeassistant.components import frontend
|
||||||
from homeassistant.components.http import HomeAssistantView
|
from homeassistant.components.http import HomeAssistantView
|
||||||
from homeassistant.core import HomeAssistant, callback
|
from homeassistant.core import Event, HomeAssistant, callback
|
||||||
from homeassistant.exceptions import HomeAssistantError
|
from homeassistant.exceptions import HomeAssistantError
|
||||||
from homeassistant.helpers import config_per_platform, discovery
|
from homeassistant.helpers import config_per_platform, discovery
|
||||||
from homeassistant.helpers.entity import Entity
|
from homeassistant.helpers.entity import Entity
|
||||||
@ -21,15 +22,13 @@ from homeassistant.helpers.entity_component import EntityComponent
|
|||||||
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
||||||
from homeassistant.setup import async_prepare_setup_platform
|
from homeassistant.setup import async_prepare_setup_platform
|
||||||
|
|
||||||
# mypy: allow-untyped-defs, no-check-untyped-defs
|
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
DOMAIN = "mailbox"
|
DOMAIN: Final = "mailbox"
|
||||||
|
|
||||||
EVENT = "mailbox_updated"
|
EVENT: Final = "mailbox_updated"
|
||||||
CONTENT_TYPE_MPEG = "audio/mpeg"
|
CONTENT_TYPE_MPEG: Final = "audio/mpeg"
|
||||||
CONTENT_TYPE_NONE = "none"
|
CONTENT_TYPE_NONE: Final = "none"
|
||||||
|
|
||||||
SCAN_INTERVAL = timedelta(seconds=30)
|
SCAN_INTERVAL = timedelta(seconds=30)
|
||||||
|
|
||||||
@ -98,7 +97,9 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
|||||||
if setup_tasks:
|
if setup_tasks:
|
||||||
await asyncio.wait(setup_tasks)
|
await asyncio.wait(setup_tasks)
|
||||||
|
|
||||||
async def async_platform_discovered(platform, info):
|
async def async_platform_discovered(
|
||||||
|
platform: str, info: DiscoveryInfoType | None
|
||||||
|
) -> None:
|
||||||
"""Handle for discovered platform."""
|
"""Handle for discovered platform."""
|
||||||
await async_setup_platform(platform, discovery_info=info)
|
await async_setup_platform(platform, discovery_info=info)
|
||||||
|
|
||||||
@ -115,27 +116,27 @@ class MailboxEntity(Entity):
|
|||||||
self.mailbox = mailbox
|
self.mailbox = mailbox
|
||||||
self.message_count = 0
|
self.message_count = 0
|
||||||
|
|
||||||
async def async_added_to_hass(self):
|
async def async_added_to_hass(self) -> None:
|
||||||
"""Complete entity initialization."""
|
"""Complete entity initialization."""
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def _mailbox_updated(event):
|
def _mailbox_updated(event: Event) -> None:
|
||||||
self.async_schedule_update_ha_state(True)
|
self.async_schedule_update_ha_state(True)
|
||||||
|
|
||||||
self.hass.bus.async_listen(EVENT, _mailbox_updated)
|
self.hass.bus.async_listen(EVENT, _mailbox_updated)
|
||||||
self.async_schedule_update_ha_state(True)
|
self.async_schedule_update_ha_state(True)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def state(self):
|
def state(self) -> str:
|
||||||
"""Return the state of the binary sensor."""
|
"""Return the state of the binary sensor."""
|
||||||
return str(self.message_count)
|
return str(self.message_count)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self):
|
def name(self) -> str:
|
||||||
"""Return the name of the entity."""
|
"""Return the name of the entity."""
|
||||||
return self.mailbox.name
|
return self.mailbox.name
|
||||||
|
|
||||||
async def async_update(self):
|
async def async_update(self) -> None:
|
||||||
"""Retrieve messages from platform."""
|
"""Retrieve messages from platform."""
|
||||||
messages = await self.mailbox.async_get_messages()
|
messages = await self.mailbox.async_get_messages()
|
||||||
self.message_count = len(messages)
|
self.message_count = len(messages)
|
||||||
@ -155,29 +156,29 @@ class Mailbox:
|
|||||||
self.hass.bus.async_fire(EVENT)
|
self.hass.bus.async_fire(EVENT)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def media_type(self):
|
def media_type(self) -> str:
|
||||||
"""Return the supported media type."""
|
"""Return the supported media type."""
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def can_delete(self):
|
def can_delete(self) -> bool:
|
||||||
"""Return if messages can be deleted."""
|
"""Return if messages can be deleted."""
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def has_media(self):
|
def has_media(self) -> bool:
|
||||||
"""Return if messages have attached media files."""
|
"""Return if messages have attached media files."""
|
||||||
return False
|
return False
|
||||||
|
|
||||||
async def async_get_media(self, msgid):
|
async def async_get_media(self, msgid: str) -> bytes:
|
||||||
"""Return the media blob for the msgid."""
|
"""Return the media blob for the msgid."""
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
async def async_get_messages(self):
|
async def async_get_messages(self) -> list[dict[str, Any]]:
|
||||||
"""Return a list of the current messages."""
|
"""Return a list of the current messages."""
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
async def async_delete(self, msgid):
|
async def async_delete(self, msgid: str) -> bool:
|
||||||
"""Delete the specified messages."""
|
"""Delete the specified messages."""
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
@ -193,7 +194,7 @@ class MailboxView(HomeAssistantView):
|
|||||||
"""Initialize a basic mailbox view."""
|
"""Initialize a basic mailbox view."""
|
||||||
self.mailboxes = mailboxes
|
self.mailboxes = mailboxes
|
||||||
|
|
||||||
def get_mailbox(self, platform):
|
def get_mailbox(self, platform: str) -> Mailbox:
|
||||||
"""Retrieve the specified mailbox."""
|
"""Retrieve the specified mailbox."""
|
||||||
for mailbox in self.mailboxes:
|
for mailbox in self.mailboxes:
|
||||||
if mailbox.name == platform:
|
if mailbox.name == platform:
|
||||||
@ -209,7 +210,7 @@ class MailboxPlatformsView(MailboxView):
|
|||||||
|
|
||||||
async def get(self, request: web.Request) -> web.Response:
|
async def get(self, request: web.Request) -> web.Response:
|
||||||
"""Retrieve list of platforms."""
|
"""Retrieve list of platforms."""
|
||||||
platforms = []
|
platforms: list[dict[str, Any]] = []
|
||||||
for mailbox in self.mailboxes:
|
for mailbox in self.mailboxes:
|
||||||
platforms.append(
|
platforms.append(
|
||||||
{
|
{
|
||||||
@ -227,7 +228,7 @@ class MailboxMessageView(MailboxView):
|
|||||||
url = "/api/mailbox/messages/{platform}"
|
url = "/api/mailbox/messages/{platform}"
|
||||||
name = "api:mailbox:messages"
|
name = "api:mailbox:messages"
|
||||||
|
|
||||||
async def get(self, request, platform):
|
async def get(self, request: web.Request, platform: str) -> web.Response:
|
||||||
"""Retrieve messages."""
|
"""Retrieve messages."""
|
||||||
mailbox = self.get_mailbox(platform)
|
mailbox = self.get_mailbox(platform)
|
||||||
messages = await mailbox.async_get_messages()
|
messages = await mailbox.async_get_messages()
|
||||||
@ -240,7 +241,7 @@ class MailboxDeleteView(MailboxView):
|
|||||||
url = "/api/mailbox/delete/{platform}/{msgid}"
|
url = "/api/mailbox/delete/{platform}/{msgid}"
|
||||||
name = "api:mailbox:delete"
|
name = "api:mailbox:delete"
|
||||||
|
|
||||||
async def delete(self, request, platform, msgid):
|
async def delete(self, request: web.Request, platform: str, msgid: str) -> None:
|
||||||
"""Delete items."""
|
"""Delete items."""
|
||||||
mailbox = self.get_mailbox(platform)
|
mailbox = self.get_mailbox(platform)
|
||||||
await mailbox.async_delete(msgid)
|
await mailbox.async_delete(msgid)
|
||||||
@ -252,7 +253,9 @@ class MailboxMediaView(MailboxView):
|
|||||||
url = r"/api/mailbox/media/{platform}/{msgid}"
|
url = r"/api/mailbox/media/{platform}/{msgid}"
|
||||||
name = "api:asteriskmbox:media"
|
name = "api:asteriskmbox:media"
|
||||||
|
|
||||||
async def get(self, request, platform, msgid):
|
async def get(
|
||||||
|
self, request: web.Request, platform: str, msgid: str
|
||||||
|
) -> web.Response:
|
||||||
"""Retrieve media."""
|
"""Retrieve media."""
|
||||||
mailbox = self.get_mailbox(platform)
|
mailbox = self.get_mailbox(platform)
|
||||||
|
|
||||||
|
@ -1539,6 +1539,39 @@ _INHERITANCE_MATCH: dict[str, list[ClassTypeHintMatch]] = {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
"mailbox": [
|
||||||
|
ClassTypeHintMatch(
|
||||||
|
base_class="Mailbox",
|
||||||
|
matches=[
|
||||||
|
TypeHintMatch(
|
||||||
|
function_name="media_type",
|
||||||
|
return_type="str",
|
||||||
|
),
|
||||||
|
TypeHintMatch(
|
||||||
|
function_name="can_delete",
|
||||||
|
return_type="bool",
|
||||||
|
),
|
||||||
|
TypeHintMatch(
|
||||||
|
function_name="has_media",
|
||||||
|
return_type="bool",
|
||||||
|
),
|
||||||
|
TypeHintMatch(
|
||||||
|
function_name="async_get_media",
|
||||||
|
arg_types={1: "str"},
|
||||||
|
return_type="bytes",
|
||||||
|
),
|
||||||
|
TypeHintMatch(
|
||||||
|
function_name="async_get_messages",
|
||||||
|
return_type="list[dict[str, Any]]",
|
||||||
|
),
|
||||||
|
TypeHintMatch(
|
||||||
|
function_name="async_delete",
|
||||||
|
arg_types={1: "str"},
|
||||||
|
return_type="bool",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
"media_player": [
|
"media_player": [
|
||||||
ClassTypeHintMatch(
|
ClassTypeHintMatch(
|
||||||
base_class="Entity",
|
base_class="Entity",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user