1 """Mastodon platform for notify component."""
3 from __future__
import annotations
6 from typing
import Any, cast
8 from mastodon
import Mastodon
9 from mastodon.Mastodon
import MastodonAPIError
10 import voluptuous
as vol
14 PLATFORM_SCHEMA
as NOTIFY_PLATFORM_SCHEMA,
15 BaseNotificationService,
24 from .const
import CONF_BASE_URL, DEFAULT_URL, DOMAIN, LOGGER
27 ATTR_TARGET =
"target"
28 ATTR_MEDIA_WARNING =
"media_warning"
29 ATTR_CONTENT_WARNING =
"content_warning"
31 PLATFORM_SCHEMA = NOTIFY_PLATFORM_SCHEMA.extend(
33 vol.Required(CONF_ACCESS_TOKEN): cv.string,
34 vol.Required(CONF_CLIENT_ID): cv.string,
35 vol.Required(CONF_CLIENT_SECRET): cv.string,
36 vol.Optional(CONF_BASE_URL, default=DEFAULT_URL): cv.string,
40 INTEGRATION_TITLE =
"Mastodon"
46 discovery_info: DiscoveryInfoType |
None =
None,
47 ) -> MastodonNotificationService |
None:
48 """Get the Mastodon notification service."""
50 if not discovery_info:
53 import_result = await hass.config_entries.flow.async_init(
55 context={
"source": SOURCE_IMPORT},
60 import_result[
"type"] == FlowResultType.ABORT
61 and import_result[
"reason"] !=
"already_configured"
63 ir.async_create_issue(
66 f
"deprecated_yaml_import_issue_{import_result["reason
"]}",
67 breaks_in_ha_version=
"2025.2.0",
70 severity=ir.IssueSeverity.WARNING,
71 translation_key=f
"deprecated_yaml_import_issue_{import_result["reason
"]}",
72 translation_placeholders={
74 "integration_title": INTEGRATION_TITLE,
79 ir.async_create_issue(
82 f
"deprecated_yaml_{DOMAIN}",
83 breaks_in_ha_version=
"2025.2.0",
86 severity=ir.IssueSeverity.WARNING,
87 translation_key=
"deprecated_yaml",
88 translation_placeholders={
90 "integration_title": INTEGRATION_TITLE,
96 client: Mastodon = discovery_info.get(
"client")
102 """Implement the notification service for Mastodon."""
109 """Initialize the service."""
114 """Toot a message, with media perhaps."""
117 if (target_list := kwargs.get(ATTR_TARGET))
is not None:
118 target = cast(list[str], target_list)[0]
120 data = kwargs.get(ATTR_DATA)
125 content_warning =
None
128 media = data.get(ATTR_MEDIA)
130 if not self.hass.config.is_allowed_path(media):
131 LOGGER.warning(
"'%s' is not a whitelisted directory", media)
135 sensitive = data.get(ATTR_MEDIA_WARNING)
136 content_warning = data.get(ATTR_CONTENT_WARNING)
140 self.
clientclient.status_post(
142 media_ids=mediadata[
"id"],
145 spoiler_text=content_warning,
147 except MastodonAPIError:
148 LOGGER.error(
"Unable to send message")
151 self.
clientclient.status_post(
152 message, visibility=target, spoiler_text=content_warning
154 except MastodonAPIError:
155 LOGGER.error(
"Unable to send message")
159 with open(media_path,
"rb"):
160 media_type = self.
_media_type_media_type(media_path)
162 mediadata = self.
clientclient.media_post(media_path, mime_type=media_type)
163 except MastodonAPIError:
164 LOGGER.error(f
"Unable to upload image {media_path}")
169 """Get media Type."""
170 (media_type, _) = mimetypes.guess_type(media_path)
None send_message(self, str message="", **Any kwargs)
Any _upload_media(self, Any media_path=None)
Any _media_type(self, Any media_path=None)
None __init__(self, HomeAssistant hass, Mastodon client)
MastodonNotificationService|None async_get_service(HomeAssistant hass, ConfigType config, DiscoveryInfoType|None discovery_info=None)
None open(self, **Any kwargs)