From 4b6dd0eb8ffa14839a800bd0120c4e558bfec613 Mon Sep 17 00:00:00 2001 From: Andrew Jackson Date: Mon, 22 Sep 2025 15:01:09 +0100 Subject: [PATCH] Add optional language to Mastodon post action (#151072) --- homeassistant/components/mastodon/const.py | 1 + homeassistant/components/mastodon/services.py | 4 + .../components/mastodon/services.yaml | 203 ++++++++++++++++++ .../components/mastodon/strings.json | 4 + tests/components/mastodon/test_services.py | 19 ++ 5 files changed, 231 insertions(+) diff --git a/homeassistant/components/mastodon/const.py b/homeassistant/components/mastodon/const.py index 8a77eebcf7a..9c46f07029b 100644 --- a/homeassistant/components/mastodon/const.py +++ b/homeassistant/components/mastodon/const.py @@ -18,3 +18,4 @@ ATTR_CONTENT_WARNING = "content_warning" ATTR_MEDIA_WARNING = "media_warning" ATTR_MEDIA = "media" ATTR_MEDIA_DESCRIPTION = "media_description" +ATTR_LANGUAGE = "language" diff --git a/homeassistant/components/mastodon/services.py b/homeassistant/components/mastodon/services.py index 0815fee34ec..c5347079a5f 100644 --- a/homeassistant/components/mastodon/services.py +++ b/homeassistant/components/mastodon/services.py @@ -15,6 +15,7 @@ from homeassistant.exceptions import HomeAssistantError, ServiceValidationError from .const import ( ATTR_CONTENT_WARNING, + ATTR_LANGUAGE, ATTR_MEDIA, ATTR_MEDIA_DESCRIPTION, ATTR_MEDIA_WARNING, @@ -42,6 +43,7 @@ SERVICE_POST_SCHEMA = vol.Schema( vol.Required(ATTR_STATUS): str, vol.Optional(ATTR_VISIBILITY): vol.In([x.lower() for x in StatusVisibility]), vol.Optional(ATTR_CONTENT_WARNING): str, + vol.Optional(ATTR_LANGUAGE): str, vol.Optional(ATTR_MEDIA): str, vol.Optional(ATTR_MEDIA_DESCRIPTION): str, vol.Optional(ATTR_MEDIA_WARNING): bool, @@ -82,6 +84,7 @@ def setup_services(hass: HomeAssistant) -> None: else None ) spoiler_text: str | None = call.data.get(ATTR_CONTENT_WARNING) + language: str | None = call.data.get(ATTR_LANGUAGE) media_path: str | None = call.data.get(ATTR_MEDIA) media_description: str | None = call.data.get(ATTR_MEDIA_DESCRIPTION) media_warning: str | None = call.data.get(ATTR_MEDIA_WARNING) @@ -93,6 +96,7 @@ def setup_services(hass: HomeAssistant) -> None: status=status, visibility=visibility, spoiler_text=spoiler_text, + language=language, media_path=media_path, media_description=media_description, sensitive=media_warning, diff --git a/homeassistant/components/mastodon/services.yaml b/homeassistant/components/mastodon/services.yaml index 206dc36c1a2..9db51f783b2 100644 --- a/homeassistant/components/mastodon/services.yaml +++ b/homeassistant/components/mastodon/services.yaml @@ -21,6 +21,209 @@ post: content_warning: selector: text: + language: + required: false + selector: + language: + languages: + - "aa" + - "ab" + - "ae" + - "af" + - "ak" + - "am" + - "an" + - "ar" + - "as" + - "ast" + - "av" + - "ay" + - "az" + - "ba" + - "be" + - "bg" + - "bi" + - "bm" + - "bn" + - "bo" + - "br" + - "bs" + - "ca" + - "ce" + - "ch" + - "chr" + - "ckb" + - "cnr" + - "co" + - "cr" + - "cs" + - "cu" + - "cv" + - "cy" + - "da" + - "de" + - "dv" + - "dz" + - "ee" + - "el" + - "en" + - "eo" + - "es" + - "et" + - "eu" + - "fa" + - "ff" + - "fi" + - "fj" + - "fo" # codespell:ignore fo + - "fr" + - "fy" + - "ga" + - "gd" + - "gl" + - "gu" + - "gv" + - "ha" + - "he" + - "hi" + - "ho" + - "hr" + - "ht" + - "hu" + - "hy" + - "hz" + - "ia" + - "id" + - "ie" + - "ig" + - "ii" + - "ik" + - "io" + - "is" + - "it" + - "iu" + - "ja" + - "jbo" + - "jv" + - "ka" + - "kab" + - "kg" + - "ki" + - "kj" + - "kk" + - "kl" + - "km" + - "kn" + - "ko" + - "kr" + - "ks" + - "ku" + - "kv" + - "kw" + - "ky" + - "la" + - "lb" + - "lfn" + - "lg" + - "li" + - "ln" + - "lo" + - "lt" + - "lu" + - "lv" + - "mg" + - "mh" + - "mi" + - "mk" + - "ml" + - "mn" + - "mr" + - "ms" + - "mt" + - "my" + - "na" + - "nb" + - "nd" # codespell:ignore nd + - "ne" + - "ng" + - "nl" + - "nn" + - "no" + - "nr" + - "nv" + - "ny" + - "oc" + - "oj" + - "om" + - "or" + - "os" + - "pa" + - "pi" + - "pl" + - "ps" + - "pt" + - "qu" + - "rm" + - "rn" + - "ro" + - "ru" + - "rw" + - "sa" + - "sc" + - "sco" + - "sd" + - "se" + - "sg" + - "si" + - "sk" + - "sl" + - "sma" + - "smj" + - "sn" + - "so" + - "sq" + - "sr" + - "ss" + - "st" + - "su" + - "sv" + - "sw" + - "szl" + - "ta" + - "te" # codespell:ignore te + - "tg" + - "th" + - "ti" + - "tk" + - "tl" + - "tn" + - "to" + - "tok" + - "tr" + - "ts" + - "tt" + - "tw" + - "ty" + - "ug" + - "uk" + - "ur" + - "uz" + - "ve" + - "vi" + - "vo" + - "wa" + - "wo" + - "xal" + - "xh" + - "yi" + - "yo" + - "za" + - "zgh" + - "zh" + - "zh-CN" + - "zh-HK" + - "zh-TW" + - "zu" media: selector: text: diff --git a/homeassistant/components/mastodon/strings.json b/homeassistant/components/mastodon/strings.json index c37f9b2e941..5b8ce59fbd7 100644 --- a/homeassistant/components/mastodon/strings.json +++ b/homeassistant/components/mastodon/strings.json @@ -79,6 +79,10 @@ "name": "Content warning", "description": "A content warning will be shown before the status text is shown (default: no content warning)." }, + "language": { + "name": "Language", + "description": "The language of the post (default: Mastodon account preference)." + }, "media": { "name": "Media", "description": "Attach an image or video to the post." diff --git a/tests/components/mastodon/test_services.py b/tests/components/mastodon/test_services.py index b08f886422f..7902db010ca 100644 --- a/tests/components/mastodon/test_services.py +++ b/tests/components/mastodon/test_services.py @@ -7,6 +7,7 @@ import pytest from homeassistant.components.mastodon.const import ( ATTR_CONTENT_WARNING, + ATTR_LANGUAGE, ATTR_MEDIA, ATTR_MEDIA_DESCRIPTION, ATTR_STATUS, @@ -34,6 +35,7 @@ from tests.common import MockConfigEntry "status": "test toot", "spoiler_text": None, "visibility": None, + "language": None, "media_ids": None, "sensitive": None, }, @@ -44,6 +46,7 @@ from tests.common import MockConfigEntry "status": "test toot", "spoiler_text": None, "visibility": "private", + "language": None, "media_ids": None, "sensitive": None, }, @@ -58,6 +61,7 @@ from tests.common import MockConfigEntry "status": "test toot", "spoiler_text": "Spoiler", "visibility": "private", + "language": None, "media_ids": None, "sensitive": None, }, @@ -66,12 +70,14 @@ from tests.common import MockConfigEntry { ATTR_STATUS: "test toot", ATTR_CONTENT_WARNING: "Spoiler", + ATTR_LANGUAGE: "nl", ATTR_MEDIA: "/image.jpg", }, { "status": "test toot", "spoiler_text": "Spoiler", "visibility": None, + "language": "nl", "media_ids": "1", "sensitive": None, }, @@ -80,6 +86,7 @@ from tests.common import MockConfigEntry { ATTR_STATUS: "test toot", ATTR_CONTENT_WARNING: "Spoiler", + ATTR_LANGUAGE: "en", ATTR_MEDIA: "/image.jpg", ATTR_MEDIA_DESCRIPTION: "A test image", }, @@ -87,10 +94,22 @@ from tests.common import MockConfigEntry "status": "test toot", "spoiler_text": "Spoiler", "visibility": None, + "language": "en", "media_ids": "1", "sensitive": None, }, ), + ( + {ATTR_STATUS: "test toot", ATTR_LANGUAGE: "invalid-lang"}, + { + "status": "test toot", + "language": "invalid-lang", + "spoiler_text": None, + "visibility": None, + "media_ids": None, + "sensitive": None, + }, + ), ], ) async def test_service_post(