diff --git a/.coveragerc b/.coveragerc index bf493a6a0a8..511c57a2ce9 100644 --- a/.coveragerc +++ b/.coveragerc @@ -483,11 +483,6 @@ omit = homeassistant/components/habitica/__init__.py homeassistant/components/habitica/const.py homeassistant/components/habitica/sensor.py - homeassistant/components/hangouts/__init__.py - homeassistant/components/hangouts/hangouts_bot.py - homeassistant/components/hangouts/hangups_utils.py - homeassistant/components/hangouts/intents.py - homeassistant/components/hangouts/notify.py homeassistant/components/harman_kardon_avr/media_player.py homeassistant/components/harmony/const.py homeassistant/components/harmony/data.py diff --git a/homeassistant/brands/google.json b/homeassistant/brands/google.json index 5f37de46180..de27fa7c515 100644 --- a/homeassistant/brands/google.json +++ b/homeassistant/brands/google.json @@ -14,7 +14,6 @@ "google", "nest", "cast", - "hangouts", "dialogflow" ] } diff --git a/homeassistant/components/hangouts/__init__.py b/homeassistant/components/hangouts/__init__.py deleted file mode 100644 index 6b0e10705c0..00000000000 --- a/homeassistant/components/hangouts/__init__.py +++ /dev/null @@ -1,160 +0,0 @@ -"""Support for Hangouts.""" -import logging - -from hangups.auth import GoogleAuthError -import voluptuous as vol - -from homeassistant import config_entries -from homeassistant.components.conversation.util import create_matcher -from homeassistant.config_entries import ConfigEntry -from homeassistant.const import EVENT_HOMEASSISTANT_STOP -from homeassistant.core import HomeAssistant -from homeassistant.helpers import dispatcher, intent -import homeassistant.helpers.config_validation as cv -from homeassistant.helpers.typing import ConfigType - -# We need an import from .config_flow, without it .config_flow is never loaded. -from .config_flow import HangoutsFlowHandler # noqa: F401 -from .const import ( - CONF_BOT, - CONF_DEFAULT_CONVERSATIONS, - CONF_ERROR_SUPPRESSED_CONVERSATIONS, - CONF_INTENTS, - CONF_MATCHERS, - CONF_REFRESH_TOKEN, - CONF_SENTENCES, - DOMAIN, - EVENT_HANGOUTS_CONNECTED, - EVENT_HANGOUTS_CONVERSATIONS_CHANGED, - EVENT_HANGOUTS_CONVERSATIONS_RESOLVED, - INTENT_HELP, - INTENT_SCHEMA, - MESSAGE_SCHEMA, - SERVICE_RECONNECT, - SERVICE_SEND_MESSAGE, - SERVICE_UPDATE, - TARGETS_SCHEMA, -) -from .hangouts_bot import HangoutsBot -from .intents import HelpIntent - -_LOGGER = logging.getLogger(__name__) - -CONFIG_SCHEMA = vol.Schema( - { - DOMAIN: vol.Schema( - { - vol.Optional(CONF_INTENTS, default={}): vol.Schema( - {cv.string: INTENT_SCHEMA} - ), - vol.Optional(CONF_DEFAULT_CONVERSATIONS, default=[]): [TARGETS_SCHEMA], - vol.Optional(CONF_ERROR_SUPPRESSED_CONVERSATIONS, default=[]): [ - TARGETS_SCHEMA - ], - } - ) - }, - extra=vol.ALLOW_EXTRA, -) - - -async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: - """Set up the Hangouts bot component.""" - if (conf := config.get(DOMAIN)) is None: - hass.data[DOMAIN] = { - CONF_INTENTS: {}, - CONF_DEFAULT_CONVERSATIONS: [], - CONF_ERROR_SUPPRESSED_CONVERSATIONS: [], - } - return True - - hass.data[DOMAIN] = { - CONF_INTENTS: conf[CONF_INTENTS], - CONF_DEFAULT_CONVERSATIONS: conf[CONF_DEFAULT_CONVERSATIONS], - CONF_ERROR_SUPPRESSED_CONVERSATIONS: conf[CONF_ERROR_SUPPRESSED_CONVERSATIONS], - } - - if ( - hass.data[DOMAIN][CONF_INTENTS] - and INTENT_HELP not in hass.data[DOMAIN][CONF_INTENTS] - ): - hass.data[DOMAIN][CONF_INTENTS][INTENT_HELP] = {CONF_SENTENCES: ["HELP"]} - - for data in hass.data[DOMAIN][CONF_INTENTS].values(): - matchers = [] - for sentence in data[CONF_SENTENCES]: - matchers.append(create_matcher(sentence)) - - data[CONF_MATCHERS] = matchers - - hass.async_create_task( - hass.config_entries.flow.async_init( - DOMAIN, context={"source": config_entries.SOURCE_IMPORT} - ) - ) - - return True - - -async def async_setup_entry(hass: HomeAssistant, config: ConfigEntry) -> bool: - """Set up a config entry.""" - try: - bot = HangoutsBot( - hass, - config.data.get(CONF_REFRESH_TOKEN), - hass.data[DOMAIN][CONF_INTENTS], - hass.data[DOMAIN][CONF_DEFAULT_CONVERSATIONS], - hass.data[DOMAIN][CONF_ERROR_SUPPRESSED_CONVERSATIONS], - ) - hass.data[DOMAIN][CONF_BOT] = bot - except GoogleAuthError as exception: - _LOGGER.error("Hangouts failed to log in: %s", str(exception)) - return False - - dispatcher.async_dispatcher_connect( - hass, EVENT_HANGOUTS_CONNECTED, bot.async_handle_update_users_and_conversations - ) - - dispatcher.async_dispatcher_connect( - hass, EVENT_HANGOUTS_CONVERSATIONS_CHANGED, bot.async_resolve_conversations - ) - - dispatcher.async_dispatcher_connect( - hass, - EVENT_HANGOUTS_CONVERSATIONS_RESOLVED, - bot.async_update_conversation_commands, - ) - - config.async_on_unload( - hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, bot.async_handle_hass_stop) - ) - - await bot.async_connect() - - hass.services.async_register( - DOMAIN, - SERVICE_SEND_MESSAGE, - bot.async_handle_send_message, - schema=MESSAGE_SCHEMA, - ) - hass.services.async_register( - DOMAIN, - SERVICE_UPDATE, - bot.async_handle_update_users_and_conversations, - schema=vol.Schema({}), - ) - - hass.services.async_register( - DOMAIN, SERVICE_RECONNECT, bot.async_handle_reconnect, schema=vol.Schema({}) - ) - - intent.async_register(hass, HelpIntent(hass)) - - return True - - -async def async_unload_entry(hass: HomeAssistant, _: ConfigEntry) -> bool: - """Unload a config entry.""" - bot = hass.data[DOMAIN].pop(CONF_BOT) - await bot.async_disconnect() - return True diff --git a/homeassistant/components/hangouts/config_flow.py b/homeassistant/components/hangouts/config_flow.py deleted file mode 100644 index 598c7fbd9cb..00000000000 --- a/homeassistant/components/hangouts/config_flow.py +++ /dev/null @@ -1,111 +0,0 @@ -"""Config flow to configure Google Hangouts.""" -import functools - -from hangups import get_auth -import voluptuous as vol - -from homeassistant import config_entries -from homeassistant.const import CONF_EMAIL, CONF_PASSWORD - -from .const import CONF_2FA, CONF_AUTH_CODE, CONF_REFRESH_TOKEN, DOMAIN -from .hangups_utils import ( - Google2FAError, - GoogleAuthError, - HangoutsCredentials, - HangoutsRefreshToken, -) - - -class HangoutsFlowHandler(config_entries.ConfigFlow, domain=DOMAIN): - """Config flow Google Hangouts.""" - - VERSION = 1 - - def __init__(self): - """Initialize Google Hangouts config flow.""" - self._credentials = None - self._refresh_token = None - - async def async_step_user(self, user_input=None): - """Handle a flow start.""" - errors = {} - - self._async_abort_entries_match() - - if user_input is not None: - user_email = user_input[CONF_EMAIL] - user_password = user_input[CONF_PASSWORD] - user_auth_code = user_input.get(CONF_AUTH_CODE) - manual_login = user_auth_code is not None - - user_pin = None - self._credentials = HangoutsCredentials( - user_email, user_password, user_pin, user_auth_code - ) - self._refresh_token = HangoutsRefreshToken(None) - try: - await self.hass.async_add_executor_job( - functools.partial( - get_auth, - self._credentials, - self._refresh_token, - manual_login=manual_login, - ) - ) - - return await self.async_step_final() - except GoogleAuthError as err: - if isinstance(err, Google2FAError): - return await self.async_step_2fa() - msg = str(err) - if msg == "Unknown verification code input": - errors["base"] = "invalid_2fa_method" - else: - errors["base"] = "invalid_login" - - return self.async_show_form( - step_id="user", - data_schema=vol.Schema( - { - vol.Required(CONF_EMAIL): str, - vol.Required(CONF_PASSWORD): str, - vol.Optional(CONF_AUTH_CODE): str, - } - ), - errors=errors, - ) - - async def async_step_2fa(self, user_input=None): - """Handle the 2fa step, if needed.""" - errors = {} - - if user_input is not None: - self._credentials.set_verification_code(user_input[CONF_2FA]) - try: - await self.hass.async_add_executor_job( - get_auth, self._credentials, self._refresh_token - ) - - return await self.async_step_final() - except GoogleAuthError: - errors["base"] = "invalid_2fa" - - return self.async_show_form( - step_id=CONF_2FA, - data_schema=vol.Schema({vol.Required(CONF_2FA): str}), - errors=errors, - ) - - async def async_step_final(self): - """Handle the final step, create the config entry.""" - return self.async_create_entry( - title=self._credentials.get_email(), - data={ - CONF_EMAIL: self._credentials.get_email(), - CONF_REFRESH_TOKEN: self._refresh_token.get(), - }, - ) - - async def async_step_import(self, _): - """Handle a flow import.""" - return await self.async_step_user() diff --git a/homeassistant/components/hangouts/const.py b/homeassistant/components/hangouts/const.py deleted file mode 100644 index 3a78e9bbe80..00000000000 --- a/homeassistant/components/hangouts/const.py +++ /dev/null @@ -1,80 +0,0 @@ -"""Constants for Google Hangouts Component.""" -import voluptuous as vol - -from homeassistant.components.notify import ATTR_DATA, ATTR_MESSAGE, ATTR_TARGET -import homeassistant.helpers.config_validation as cv - -DOMAIN = "hangouts" - -CONF_2FA = "2fa" -CONF_AUTH_CODE = "authorization_code" -CONF_REFRESH_TOKEN = "refresh_token" -CONF_BOT = "bot" - -CONF_CONVERSATIONS = "conversations" -CONF_DEFAULT_CONVERSATIONS = "default_conversations" -CONF_ERROR_SUPPRESSED_CONVERSATIONS = "error_suppressed_conversations" - -CONF_INTENTS = "intents" -CONF_INTENT_TYPE = "intent_type" -CONF_SENTENCES = "sentences" -CONF_MATCHERS = "matchers" - -INTENT_HELP = "HangoutsHelp" - -EVENT_HANGOUTS_CONNECTED = "hangouts_connected" -EVENT_HANGOUTS_DISCONNECTED = "hangouts_disconnected" -EVENT_HANGOUTS_USERS_CHANGED = "hangouts_users_changed" -EVENT_HANGOUTS_CONVERSATIONS_CHANGED = "hangouts_conversations_changed" -EVENT_HANGOUTS_CONVERSATIONS_RESOLVED = "hangouts_conversations_resolved" -EVENT_HANGOUTS_MESSAGE_RECEIVED = "hangouts_message_received" - -CONF_CONVERSATION_ID = "id" -CONF_CONVERSATION_NAME = "name" - -SERVICE_SEND_MESSAGE = "send_message" -SERVICE_UPDATE = "update" -SERVICE_RECONNECT = "reconnect" - - -TARGETS_SCHEMA = vol.All( - vol.Schema( - { - vol.Exclusive(CONF_CONVERSATION_ID, "id or name"): cv.string, - vol.Exclusive(CONF_CONVERSATION_NAME, "id or name"): cv.string, - } - ), - cv.has_at_least_one_key(CONF_CONVERSATION_ID, CONF_CONVERSATION_NAME), -) -MESSAGE_SEGMENT_SCHEMA = vol.Schema( - { - vol.Required("text"): cv.string, - vol.Optional("is_bold"): cv.boolean, - vol.Optional("is_italic"): cv.boolean, - vol.Optional("is_strikethrough"): cv.boolean, - vol.Optional("is_underline"): cv.boolean, - vol.Optional("parse_str"): cv.boolean, - vol.Optional("link_target"): cv.string, - } -) -MESSAGE_DATA_SCHEMA = vol.Schema( - {vol.Optional("image_file"): cv.string, vol.Optional("image_url"): cv.string} -) - -MESSAGE_SCHEMA = vol.Schema( - { - vol.Required(ATTR_TARGET): [TARGETS_SCHEMA], - vol.Required(ATTR_MESSAGE): [MESSAGE_SEGMENT_SCHEMA], - vol.Optional(ATTR_DATA): MESSAGE_DATA_SCHEMA, - } -) - -INTENT_SCHEMA = vol.All( - # Basic Schema - vol.Schema( - { - vol.Required(CONF_SENTENCES): vol.All(cv.ensure_list, [cv.string]), - vol.Optional(CONF_CONVERSATIONS): [TARGETS_SCHEMA], - } - ) -) diff --git a/homeassistant/components/hangouts/hangouts_bot.py b/homeassistant/components/hangouts/hangouts_bot.py deleted file mode 100644 index c3c363ef55e..00000000000 --- a/homeassistant/components/hangouts/hangouts_bot.py +++ /dev/null @@ -1,361 +0,0 @@ -"""The Hangouts Bot.""" -from __future__ import annotations - -import asyncio -from contextlib import suppress -from http import HTTPStatus -import io -import logging - -import aiohttp -import hangups -from hangups import ChatMessageEvent, ChatMessageSegment, Client, get_auth, hangouts_pb2 - -from homeassistant.core import ServiceCall, callback -from homeassistant.helpers import dispatcher, intent -from homeassistant.helpers.aiohttp_client import async_get_clientsession - -from .const import ( - ATTR_DATA, - ATTR_MESSAGE, - ATTR_TARGET, - CONF_CONVERSATION_ID, - CONF_CONVERSATION_NAME, - CONF_CONVERSATIONS, - CONF_MATCHERS, - DOMAIN, - EVENT_HANGOUTS_CONNECTED, - EVENT_HANGOUTS_CONVERSATIONS_CHANGED, - EVENT_HANGOUTS_CONVERSATIONS_RESOLVED, - EVENT_HANGOUTS_DISCONNECTED, - EVENT_HANGOUTS_MESSAGE_RECEIVED, - INTENT_HELP, -) -from .hangups_utils import HangoutsCredentials, HangoutsRefreshToken - -_LOGGER = logging.getLogger(__name__) - - -class HangoutsBot: - """The Hangouts Bot.""" - - def __init__( - self, hass, refresh_token, intents, default_convs, error_suppressed_convs - ): - """Set up the client.""" - self.hass = hass - self._connected = False - - self._refresh_token = refresh_token - - self._intents = intents - self._conversation_intents = None - - self._client = None - self._user_list = None - self._conversation_list = None - self._default_convs = default_convs - self._default_conv_ids = None - self._error_suppressed_convs = error_suppressed_convs - self._error_suppressed_conv_ids = None - - dispatcher.async_dispatcher_connect( - self.hass, - EVENT_HANGOUTS_MESSAGE_RECEIVED, - self._async_handle_conversation_message, - ) - - def _resolve_conversation_id(self, obj): - if CONF_CONVERSATION_ID in obj: - return obj[CONF_CONVERSATION_ID] - if CONF_CONVERSATION_NAME in obj: - conv = self._resolve_conversation_name(obj[CONF_CONVERSATION_NAME]) - if conv is not None: - return conv.id_ - return None - - def _resolve_conversation_name(self, name): - for conv in self._conversation_list.get_all(): - if conv.name == name: - return conv - return None - - @callback - def async_update_conversation_commands(self): - """Refresh the commands for every conversation.""" - self._conversation_intents = {} - - for intent_type, data in self._intents.items(): - if data.get(CONF_CONVERSATIONS): - conversations = [] - for conversation in data.get(CONF_CONVERSATIONS): - conv_id = self._resolve_conversation_id(conversation) - if conv_id is not None: - conversations.append(conv_id) - data[f"_{CONF_CONVERSATIONS}"] = conversations - elif self._default_conv_ids: - data[f"_{CONF_CONVERSATIONS}"] = self._default_conv_ids - else: - data[f"_{CONF_CONVERSATIONS}"] = [ - conv.id_ for conv in self._conversation_list.get_all() - ] - - for conv_id in data[f"_{CONF_CONVERSATIONS}"]: - if conv_id not in self._conversation_intents: - self._conversation_intents[conv_id] = {} - - self._conversation_intents[conv_id][intent_type] = data - - with suppress(ValueError): - self._conversation_list.on_event.remove_observer( - self._async_handle_conversation_event - ) - self._conversation_list.on_event.add_observer( - self._async_handle_conversation_event - ) - - @callback - def async_resolve_conversations(self, _): - """Resolve the list of default and error suppressed conversations.""" - self._default_conv_ids = [] - self._error_suppressed_conv_ids = [] - - for conversation in self._default_convs: - conv_id = self._resolve_conversation_id(conversation) - if conv_id is not None: - self._default_conv_ids.append(conv_id) - - for conversation in self._error_suppressed_convs: - conv_id = self._resolve_conversation_id(conversation) - if conv_id is not None: - self._error_suppressed_conv_ids.append(conv_id) - dispatcher.async_dispatcher_send( - self.hass, EVENT_HANGOUTS_CONVERSATIONS_RESOLVED - ) - - async def _async_handle_conversation_event(self, event): - if isinstance(event, ChatMessageEvent): - dispatcher.async_dispatcher_send( - self.hass, - EVENT_HANGOUTS_MESSAGE_RECEIVED, - event.conversation_id, - event.user_id, - event, - ) - - async def _async_handle_conversation_message(self, conv_id, user_id, event): - """Handle a message sent to a conversation.""" - user = self._user_list.get_user(user_id) - if user.is_self: - return - message = event.text - - _LOGGER.debug("Handling message '%s' from %s", message, user.full_name) - - intents = self._conversation_intents.get(conv_id) - if intents is not None: - is_error = False - try: - intent_result = await self._async_process(intents, message, conv_id) - except (intent.UnknownIntent, intent.IntentHandleError) as err: - is_error = True - intent_result = intent.IntentResponse() - intent_result.async_set_speech(str(err)) - - if intent_result is None: - is_error = True - intent_result = intent.IntentResponse() - intent_result.async_set_speech("Sorry, I didn't understand that") - - message = ( - intent_result.as_dict().get("speech", {}).get("plain", {}).get("speech") - ) - - if (message is not None) and not ( - is_error and conv_id in self._error_suppressed_conv_ids - ): - await self._async_send_message( - [{"text": message, "parse_str": True}], - [{CONF_CONVERSATION_ID: conv_id}], - None, - ) - - async def _async_process(self, intents, text, conv_id): - """Detect a matching intent.""" - for intent_type, data in intents.items(): - for matcher in data.get(CONF_MATCHERS, []): - if not (match := matcher.match(text)): - continue - if intent_type == INTENT_HELP: - return await intent.async_handle( - self.hass, - DOMAIN, - intent_type, - {"conv_id": {"value": conv_id}}, - text, - ) - - return await intent.async_handle( - self.hass, - DOMAIN, - intent_type, - {"conv_id": {"value": conv_id}} - | { - key: {"value": value} - for key, value in match.groupdict().items() - }, - text, - ) - - async def async_connect(self): - """Login to the Google Hangouts.""" - session = await self.hass.async_add_executor_job( - get_auth, - HangoutsCredentials(None, None, None), - HangoutsRefreshToken(self._refresh_token), - ) - - self._client = Client(session) - self._client.on_connect.add_observer(self._on_connect) - self._client.on_disconnect.add_observer(self._on_disconnect) - - self.hass.loop.create_task(self._client.connect()) - - def _on_connect(self): - _LOGGER.debug("Connected!") - self._connected = True - dispatcher.async_dispatcher_send(self.hass, EVENT_HANGOUTS_CONNECTED) - - async def _on_disconnect(self): - """Handle disconnecting.""" - if self._connected: - _LOGGER.debug("Connection lost! Reconnect") - await self.async_connect() - else: - dispatcher.async_dispatcher_send(self.hass, EVENT_HANGOUTS_DISCONNECTED) - - async def async_disconnect(self): - """Disconnect the client if it is connected.""" - if self._connected: - self._connected = False - await self._client.disconnect() - - async def async_handle_hass_stop(self, _): - """Run once when Home Assistant stops.""" - await self.async_disconnect() - - async def _async_send_message(self, message, targets, data): - conversations = [] - for target in targets: - conversation = None - if CONF_CONVERSATION_ID in target: - conversation = self._conversation_list.get(target[CONF_CONVERSATION_ID]) - elif CONF_CONVERSATION_NAME in target: - conversation = self._resolve_conversation_name( - target[CONF_CONVERSATION_NAME] - ) - if conversation is not None: - conversations.append(conversation) - - if not conversations: - return False - - messages = [] - for segment in message: - if messages: - messages.append( - ChatMessageSegment( - "", segment_type=hangouts_pb2.SEGMENT_TYPE_LINE_BREAK - ) - ) - if "parse_str" in segment and segment["parse_str"]: - messages.extend(ChatMessageSegment.from_str(segment["text"])) - else: - if "parse_str" in segment: - del segment["parse_str"] - messages.append(ChatMessageSegment(**segment)) - - image_file = None - if data: - if data.get("image_url"): - uri = data.get("image_url") - try: - websession = async_get_clientsession(self.hass) - async with websession.get(uri, timeout=5) as response: - if response.status != HTTPStatus.OK: - _LOGGER.error( - "Fetch image failed, %s, %s", response.status, response - ) - image_file = None - else: - image_data = await response.read() - image_file = io.BytesIO(image_data) - image_file.name = "image.png" - except (asyncio.TimeoutError, aiohttp.ClientError) as error: - _LOGGER.error("Failed to fetch image, %s", type(error)) - image_file = None - elif data.get("image_file"): - uri = data.get("image_file") - if self.hass.config.is_allowed_path(uri): - try: - # pylint: disable=consider-using-with - image_file = open(uri, "rb") - except OSError as error: - _LOGGER.error( - "Image file I/O error(%s): %s", error.errno, error.strerror - ) - else: - _LOGGER.error('Path "%s" not allowed', uri) - - if not messages: - return False - for conv in conversations: - await conv.send_message(messages, image_file) - - async def _async_list_conversations(self): - ( - self._user_list, - self._conversation_list, - ) = await hangups.build_user_conversation_list(self._client) - conversations = {} - for i, conv in enumerate(self._conversation_list.get_all()): - users_in_conversation = [] - for user in conv.users: - users_in_conversation.append(user.full_name) - conversations[str(i)] = { - CONF_CONVERSATION_ID: str(conv.id_), - CONF_CONVERSATION_NAME: conv.name, - "users": users_in_conversation, - } - - self.hass.states.async_set( - f"{DOMAIN}.conversations", - len(self._conversation_list.get_all()), - attributes=conversations, - ) - dispatcher.async_dispatcher_send( - self.hass, EVENT_HANGOUTS_CONVERSATIONS_CHANGED, conversations - ) - - async def async_handle_send_message(self, service: ServiceCall) -> None: - """Handle the send_message service.""" - await self._async_send_message( - service.data[ATTR_MESSAGE], - service.data[ATTR_TARGET], - service.data.get(ATTR_DATA, {}), - ) - - async def async_handle_update_users_and_conversations( - self, service: ServiceCall | None = None - ) -> None: - """Handle the update_users_and_conversations service.""" - await self._async_list_conversations() - - async def async_handle_reconnect(self, service: ServiceCall | None = None) -> None: - """Handle the reconnect service.""" - await self.async_disconnect() - await self.async_connect() - - def get_intents(self, conv_id): - """Return the intents for a specific conversation.""" - return self._conversation_intents.get(conv_id) diff --git a/homeassistant/components/hangouts/hangups_utils.py b/homeassistant/components/hangouts/hangups_utils.py deleted file mode 100644 index d2556ac15a0..00000000000 --- a/homeassistant/components/hangouts/hangups_utils.py +++ /dev/null @@ -1,96 +0,0 @@ -"""Utils needed for Google Hangouts.""" - -from hangups import CredentialsPrompt, GoogleAuthError, RefreshTokenCache - - -class Google2FAError(GoogleAuthError): - """A Google authentication request failed.""" - - -class HangoutsCredentials(CredentialsPrompt): - """Google account credentials. - - This implementation gets the user data as params. - """ - - def __init__(self, email, password, pin=None, auth_code=None): - """Google account credentials. - - :param email: Google account email address. - :param password: Google account password. - :param pin: Google account verification code. - """ - self._email = email - self._password = password - self._pin = pin - self._auth_code = auth_code - - def get_email(self): - """Return email. - - :return: Google account email address. - """ - return self._email - - def get_password(self): - """Return password. - - :return: Google account password. - """ - return self._password - - def get_verification_code(self): - """Return the verification code. - - :return: Google account verification code. - """ - if self._pin is None: - raise Google2FAError() - return self._pin - - def set_verification_code(self, pin): - """Set the verification code. - - :param pin: Google account verification code. - """ - self._pin = pin - - def get_authorization_code(self): - """Return the oauth authorization code. - - :return: Google oauth code. - """ - return self._auth_code - - def set_authorization_code(self, code): - """Set the google oauth authorization code. - - :param code: Oauth code returned after authentication with google. - """ - self._auth_code = code - - -class HangoutsRefreshToken(RefreshTokenCache): - """Memory-based cache for refresh token.""" - - def __init__(self, token): - """Memory-based cache for refresh token. - - :param token: Initial refresh token. - """ - super().__init__("") - self._token = token - - def get(self): - """Get cached refresh token. - - :return: Cached refresh token. - """ - return self._token - - def set(self, refresh_token): - """Cache a refresh token. - - :param refresh_token: Refresh token to cache. - """ - self._token = refresh_token diff --git a/homeassistant/components/hangouts/intents.py b/homeassistant/components/hangouts/intents.py deleted file mode 100644 index 5e4c6ff206b..00000000000 --- a/homeassistant/components/hangouts/intents.py +++ /dev/null @@ -1,31 +0,0 @@ -"""Intents for the Hangouts component.""" -from homeassistant.helpers import intent -import homeassistant.helpers.config_validation as cv - -from .const import CONF_BOT, DOMAIN, INTENT_HELP - - -class HelpIntent(intent.IntentHandler): - """Handle Help intents.""" - - intent_type = INTENT_HELP - slot_schema = {"conv_id": cv.string} - - def __init__(self, hass): - """Set up the intent.""" - self.hass = hass - - async def async_handle(self, intent_obj): - """Handle the intent.""" - slots = self.async_validate_slots(intent_obj.slots) - conv_id = slots["conv_id"]["value"] - - intents = self.hass.data[DOMAIN][CONF_BOT].get_intents(conv_id) - response = intent_obj.create_response() - help_text = "I understand the following sentences:" - for intent_data in intents.values(): - for sentence in intent_data["sentences"]: - help_text += f"\n'{sentence}'" - response.async_set_speech(help_text) - - return response diff --git a/homeassistant/components/hangouts/manifest.json b/homeassistant/components/hangouts/manifest.json deleted file mode 100644 index b8b1004bb78..00000000000 --- a/homeassistant/components/hangouts/manifest.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "domain": "hangouts", - "name": "Google Chat", - "config_flow": true, - "documentation": "https://www.home-assistant.io/integrations/hangouts", - "requirements": ["hangups==0.4.18"], - "codeowners": [], - "iot_class": "cloud_push", - "loggers": ["hangups", "urwid"] -} diff --git a/homeassistant/components/hangouts/notify.py b/homeassistant/components/hangouts/notify.py deleted file mode 100644 index 77dcec8111a..00000000000 --- a/homeassistant/components/hangouts/notify.py +++ /dev/null @@ -1,57 +0,0 @@ -"""Support for Hangouts notifications.""" -import voluptuous as vol - -from homeassistant.components.notify import ( - ATTR_DATA, - ATTR_MESSAGE, - ATTR_TARGET, - PLATFORM_SCHEMA, - BaseNotificationService, -) - -from .const import ( - CONF_DEFAULT_CONVERSATIONS, - DOMAIN, - SERVICE_SEND_MESSAGE, - TARGETS_SCHEMA, -) - -PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( - {vol.Required(CONF_DEFAULT_CONVERSATIONS): [TARGETS_SCHEMA]} -) - - -def get_service(hass, config, discovery_info=None): - """Get the Hangouts notification service.""" - return HangoutsNotificationService(config.get(CONF_DEFAULT_CONVERSATIONS)) - - -class HangoutsNotificationService(BaseNotificationService): - """Send Notifications to Hangouts conversations.""" - - def __init__(self, default_conversations): - """Set up the notification service.""" - self._default_conversations = default_conversations - - def send_message(self, message="", **kwargs): - """Send the message to the Google Hangouts server.""" - target_conversations = None - if ATTR_TARGET in kwargs: - target_conversations = [] - for target in kwargs.get(ATTR_TARGET): - target_conversations.append({"id": target}) - else: - target_conversations = self._default_conversations - - messages = [] - if "title" in kwargs: - messages.append({"text": kwargs["title"], "is_bold": True}) - - messages.append({"text": message, "parse_str": True}) - service_data = {ATTR_TARGET: target_conversations, ATTR_MESSAGE: messages} - if kwargs[ATTR_DATA]: - service_data[ATTR_DATA] = kwargs[ATTR_DATA] - - return self.hass.services.call( - DOMAIN, SERVICE_SEND_MESSAGE, service_data=service_data - ) diff --git a/homeassistant/components/hangouts/services.yaml b/homeassistant/components/hangouts/services.yaml deleted file mode 100644 index 041c21b5c25..00000000000 --- a/homeassistant/components/hangouts/services.yaml +++ /dev/null @@ -1,32 +0,0 @@ -update: - name: Update - description: Updates the list of conversations. - -send_message: - name: Send message - description: Send a notification to a specific target. - fields: - target: - name: Target - description: List of targets with id or name. - required: true - example: '[{"id": "UgxrXzVrARmjx_C6AZx4AaABAagBo-6UCw"}, {"name": "Test Conversation"}]' - selector: - object: - message: - name: Message - description: List of message segments, only the "text" field is required in every segment. - required: true - example: '[{"text":"test", "is_bold": false, "is_italic": false, "is_strikethrough": false, "is_underline": false, "parse_str": false, "link_target": "http://google.com"}]' - selector: - object: - data: - name: Data - description: Other options ['image_file' / 'image_url'] - example: '{ "image_file": "file" }' - selector: - object: - -reconnect: - name: Reconnect - description: Reconnect the bot. diff --git a/homeassistant/components/hangouts/strings.json b/homeassistant/components/hangouts/strings.json deleted file mode 100644 index fcc2da456bb..00000000000 --- a/homeassistant/components/hangouts/strings.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "config": { - "abort": { - "already_configured": "[%key:common::config_flow::abort::already_configured_service%]", - "unknown": "[%key:common::config_flow::error::unknown%]" - }, - "error": { - "invalid_login": "Invalid Login, please try again.", - "invalid_2fa": "Invalid 2 Factor Authentication, please try again.", - "invalid_2fa_method": "Invalid 2FA Method (verify on Phone)." - }, - "step": { - "user": { - "data": { - "email": "[%key:common::config_flow::data::email%]", - "password": "[%key:common::config_flow::data::password%]", - "authorization_code": "Authorization Code (required for manual authentication)" - }, - "title": "Google Chat Login" - }, - "2fa": { - "data": { - "2fa": "2FA PIN" - }, - "title": "2-Factor-Authentication" - } - } - } -} diff --git a/homeassistant/components/hangouts/translations/bg.json b/homeassistant/components/hangouts/translations/bg.json deleted file mode 100644 index 8d8dae90ce0..00000000000 --- a/homeassistant/components/hangouts/translations/bg.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "config": { - "abort": { - "already_configured": "Google Hangouts \u0432\u0435\u0447\u0435 \u0435 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u0430\u043d", - "unknown": "\u0412\u044a\u0437\u043d\u0438\u043a\u043d\u0430 \u043d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u0430 \u0433\u0440\u0435\u0448\u043a\u0430." - }, - "error": { - "invalid_2fa": "\u041d\u0435\u0432\u0430\u043b\u0438\u0434\u043d\u0430 2-\u0444\u0430\u043a\u0442\u043e\u0440\u043d\u0430 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u043a\u0430\u0446\u0438\u044f, \u043c\u043e\u043b\u044f, \u043e\u043f\u0438\u0442\u0430\u0439\u0442\u0435 \u043e\u0442\u043d\u043e\u0432\u043e.", - "invalid_2fa_method": "\u041d\u0435\u0432\u0430\u043b\u0438\u0434\u0435\u043d \u043c\u0435\u0442\u043e\u0434 2FA (\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043d\u0430 \u0442\u0435\u043b\u0435\u0444\u043e\u043d\u0430).", - "invalid_login": "\u041d\u0435\u0432\u0430\u043b\u0438\u0434\u043d\u043e \u0432\u043b\u0438\u0437\u0430\u043d\u0435, \u043c\u043e\u043b\u044f, \u043e\u043f\u0438\u0442\u0430\u0439\u0442\u0435 \u043e\u0442\u043d\u043e\u0432\u043e." - }, - "step": { - "2fa": { - "data": { - "2fa": "2FA PIN" - }, - "title": "\u0414\u0432\u0443-\u0444\u0430\u043a\u0442\u043e\u0440\u043d\u0430 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u043a\u0430\u0446\u0438\u044f" - }, - "user": { - "data": { - "authorization_code": "\u041a\u043e\u0434 \u0437\u0430 \u043e\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044f (\u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c \u0437\u0430 \u0440\u044a\u0447\u043d\u043e \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u043a\u0438\u0440\u0430\u043d\u0435)", - "email": "\u0418\u043c\u0435\u0439\u043b", - "password": "\u041f\u0430\u0440\u043e\u043b\u0430" - }, - "title": "\u0412\u0445\u043e\u0434 \u0432 Google Hangouts" - } - } - } -} \ No newline at end of file diff --git a/homeassistant/components/hangouts/translations/ca.json b/homeassistant/components/hangouts/translations/ca.json deleted file mode 100644 index 8b629201cc1..00000000000 --- a/homeassistant/components/hangouts/translations/ca.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "config": { - "abort": { - "already_configured": "El servei ja est\u00e0 configurat", - "unknown": "Error inesperat" - }, - "error": { - "invalid_2fa": "La verificaci\u00f3 en dos passos no \u00e9s v\u00e0lida, torna-ho a provar.", - "invalid_2fa_method": "M\u00e8tode 2FA inv\u00e0lid (verifica-ho al m\u00f2bil).", - "invalid_login": "L'inici de sessi\u00f3 no \u00e9s v\u00e0lid, torna-ho a provar." - }, - "step": { - "2fa": { - "data": { - "2fa": "PIN 2FA" - }, - "description": "Buit", - "title": "Verificaci\u00f3 en dos passos" - }, - "user": { - "data": { - "authorization_code": "Codi d'autoritzaci\u00f3 (necessari per a l'autenticaci\u00f3 manual)", - "email": "Correu electr\u00f2nic", - "password": "Contrasenya" - }, - "description": "Buit", - "title": "Inici de sessi\u00f3 de Google Chat" - } - } - } -} \ No newline at end of file diff --git a/homeassistant/components/hangouts/translations/cs.json b/homeassistant/components/hangouts/translations/cs.json deleted file mode 100644 index 11bef6d1d1a..00000000000 --- a/homeassistant/components/hangouts/translations/cs.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "config": { - "abort": { - "already_configured": "Slu\u017eba je ji\u017e nastavena", - "unknown": "Neo\u010dek\u00e1van\u00e1 chyba" - }, - "error": { - "invalid_2fa": "Dfoufaktorov\u00e9 ov\u011b\u0159en\u00ed se nezda\u0159ilo. Zkuste to znovu.", - "invalid_2fa_method": "Neplatn\u00e1 metoda 2FA (ov\u011b\u0159en\u00ed na telefonu).", - "invalid_login": "Neplatn\u00e9 p\u0159ihla\u0161ovac\u00ed jm\u00e9no, pros\u00edm zkuste to znovu." - }, - "step": { - "2fa": { - "data": { - "2fa": "Dvoufaktorov\u00fd ov\u011b\u0159ovac\u00ed k\u00f3d" - }, - "description": "Pr\u00e1zdn\u00e9", - "title": "Dvoufaktorov\u00e9 ov\u011b\u0159en\u00ed" - }, - "user": { - "data": { - "authorization_code": "Autoriza\u010dn\u00ed k\u00f3d (vy\u017eadov\u00e1n pro ru\u010dn\u00ed ov\u011b\u0159en\u00ed)", - "email": "E-mail", - "password": "Heslo" - }, - "description": "Pr\u00e1zdn\u00e9", - "title": "P\u0159ihl\u00e1\u0161en\u00ed do slu\u017eby Google Hangouts" - } - } - } -} \ No newline at end of file diff --git a/homeassistant/components/hangouts/translations/da.json b/homeassistant/components/hangouts/translations/da.json deleted file mode 100644 index e490c33805d..00000000000 --- a/homeassistant/components/hangouts/translations/da.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "config": { - "abort": { - "already_configured": "Google Hangouts er allerede konfigureret", - "unknown": "Ukendt fejl opstod" - }, - "error": { - "invalid_2fa": "Ugyldig tofaktor-godkendelse, pr\u00f8v igen.", - "invalid_2fa_method": "Ugyldig 2FA-metode (Bekr\u00e6ft p\u00e5 telefon).", - "invalid_login": "Ugyldig login, pr\u00f8v venligst igen." - }, - "step": { - "2fa": { - "data": { - "2fa": "2FA pin" - }, - "title": "Tofaktor-godkendelse" - }, - "user": { - "data": { - "authorization_code": "Godkendelseskode (kr\u00e6vet til manuel godkendelse)", - "email": "Emailadresse", - "password": "Adgangskode" - }, - "title": "Google Hangouts login" - } - } - } -} \ No newline at end of file diff --git a/homeassistant/components/hangouts/translations/de.json b/homeassistant/components/hangouts/translations/de.json deleted file mode 100644 index 53225644a2d..00000000000 --- a/homeassistant/components/hangouts/translations/de.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "config": { - "abort": { - "already_configured": "Der Dienst ist bereits konfiguriert", - "unknown": "Unerwarteter Fehler" - }, - "error": { - "invalid_2fa": "Ung\u00fcltige 2-Faktor Authentifizierung, bitte versuche es erneut.", - "invalid_2fa_method": "Ung\u00fcltige 2FA Methode (mit Telefon verifizieren)", - "invalid_login": "Ung\u00fcltiges Login, bitte versuche es erneut." - }, - "step": { - "2fa": { - "data": { - "2fa": "2FA PIN" - }, - "description": "Leer", - "title": "2-Faktor-Authentifizierung" - }, - "user": { - "data": { - "authorization_code": "Autorisierungscode (f\u00fcr die manuelle Authentifizierung erforderlich)", - "email": "E-Mail", - "password": "Passwort" - }, - "description": "Leer", - "title": "Google Chat Anmeldung" - } - } - } -} \ No newline at end of file diff --git a/homeassistant/components/hangouts/translations/el.json b/homeassistant/components/hangouts/translations/el.json deleted file mode 100644 index 4b453c5bbaa..00000000000 --- a/homeassistant/components/hangouts/translations/el.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "config": { - "abort": { - "already_configured": "\u0397 \u03c5\u03c0\u03b7\u03c1\u03b5\u03c3\u03af\u03b1 \u03ad\u03c7\u03b5\u03b9 \u03ae\u03b4\u03b7 \u03c1\u03c5\u03b8\u03bc\u03b9\u03c3\u03c4\u03b5\u03af", - "unknown": "\u0391\u03c0\u03c1\u03cc\u03c3\u03bc\u03b5\u03bd\u03bf \u03c3\u03c6\u03ac\u03bb\u03bc\u03b1" - }, - "error": { - "invalid_2fa": "\u039c\u03b7 \u03ad\u03b3\u03ba\u03c5\u03c1\u03bf\u03c2 \u03ad\u03bb\u03b5\u03b3\u03c7\u03bf\u03c2 \u03c4\u03b1\u03c5\u03c4\u03cc\u03c4\u03b7\u03c4\u03b1\u03c2 2 \u03c0\u03b1\u03c1\u03b1\u03b3\u03cc\u03bd\u03c4\u03c9\u03bd, \u03b4\u03bf\u03ba\u03b9\u03bc\u03ac\u03c3\u03c4\u03b5 \u03be\u03b1\u03bd\u03ac.", - "invalid_2fa_method": "\u039c\u03b7 \u03ad\u03b3\u03ba\u03c5\u03c1\u03b7 \u03bc\u03ad\u03b8\u03bf\u03b4\u03bf\u03c2 2FA (\u03b5\u03c0\u03b1\u03bb\u03ae\u03b8\u03b5\u03c5\u03c3\u03b7 \u03c3\u03c4\u03bf \u03c4\u03b7\u03bb\u03ad\u03c6\u03c9\u03bd\u03bf).", - "invalid_login": "\u039c\u03b7 \u03ad\u03b3\u03ba\u03c5\u03c1\u03b7 \u03c3\u03cd\u03bd\u03b4\u03b5\u03c3\u03b7, \u03b4\u03bf\u03ba\u03b9\u03bc\u03ac\u03c3\u03c4\u03b5 \u03be\u03b1\u03bd\u03ac." - }, - "step": { - "2fa": { - "data": { - "2fa": "\u039a\u03c9\u03b4\u03b9\u03ba\u03cc\u03c2 PIN \u03c0\u03b9\u03c3\u03c4\u03bf\u03c0\u03bf\u03af\u03b7\u03c3\u03b7\u03c2 2 \u03c0\u03b1\u03c1\u03b1\u03b3\u03cc\u03bd\u03c4\u03c9\u03bd" - }, - "description": "\u039a\u03b5\u03bd\u03cc", - "title": "\u03a0\u03b9\u03c3\u03c4\u03bf\u03c0\u03bf\u03af\u03b7\u03c3\u03b7 2 \u03c0\u03b1\u03c1\u03b1\u03b3\u03cc\u03bd\u03c4\u03c9\u03bd" - }, - "user": { - "data": { - "authorization_code": "\u039a\u03c9\u03b4\u03b9\u03ba\u03cc\u03c2 \u03b5\u03be\u03bf\u03c5\u03c3\u03b9\u03bf\u03b4\u03cc\u03c4\u03b7\u03c3\u03b7\u03c2 (\u03b1\u03c0\u03b1\u03b9\u03c4\u03b5\u03af\u03c4\u03b1\u03b9 \u03b3\u03b9\u03b1 \u03c7\u03b5\u03b9\u03c1\u03bf\u03ba\u03af\u03bd\u03b7\u03c4\u03bf \u03ad\u03bb\u03b5\u03b3\u03c7\u03bf \u03c4\u03b1\u03c5\u03c4\u03cc\u03c4\u03b7\u03c4\u03b1\u03c2)", - "email": "Email", - "password": "\u039a\u03c9\u03b4\u03b9\u03ba\u03cc\u03c2 \u03c0\u03c1\u03cc\u03c3\u03b2\u03b1\u03c3\u03b7\u03c2" - }, - "description": "\u039a\u03b5\u03bd\u03cc", - "title": "\u03a3\u03cd\u03bd\u03b4\u03b5\u03c3\u03b7 Google Hangouts" - } - } - } -} \ No newline at end of file diff --git a/homeassistant/components/hangouts/translations/en.json b/homeassistant/components/hangouts/translations/en.json deleted file mode 100644 index 4829e843c6c..00000000000 --- a/homeassistant/components/hangouts/translations/en.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "config": { - "abort": { - "already_configured": "Service is already configured", - "unknown": "Unexpected error" - }, - "error": { - "invalid_2fa": "Invalid 2 Factor Authentication, please try again.", - "invalid_2fa_method": "Invalid 2FA Method (verify on Phone).", - "invalid_login": "Invalid Login, please try again." - }, - "step": { - "2fa": { - "data": { - "2fa": "2FA PIN" - }, - "title": "2-Factor-Authentication" - }, - "user": { - "data": { - "authorization_code": "Authorization Code (required for manual authentication)", - "email": "Email", - "password": "Password" - }, - "title": "Google Chat Login" - } - } - } -} \ No newline at end of file diff --git a/homeassistant/components/hangouts/translations/es-419.json b/homeassistant/components/hangouts/translations/es-419.json deleted file mode 100644 index a8ae41ec21e..00000000000 --- a/homeassistant/components/hangouts/translations/es-419.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "config": { - "abort": { - "already_configured": "Google Hangouts ya est\u00e1 configurado", - "unknown": "Se produjo un error desconocido." - }, - "error": { - "invalid_2fa": "Autenticaci\u00f3n de 2 factores no v\u00e1lida, intente nuevamente.", - "invalid_2fa_method": "M\u00e9todo 2FA no v\u00e1lido (verificar en el tel\u00e9fono).", - "invalid_login": "Inicio de sesi\u00f3n no v\u00e1lido, por favor, int\u00e9ntalo de nuevo." - }, - "step": { - "2fa": { - "data": { - "2fa": "Pin 2FA" - }, - "title": "Autenticaci\u00f3n de 2 factores" - }, - "user": { - "data": { - "authorization_code": "C\u00f3digo de autorizaci\u00f3n (requerido para la autenticaci\u00f3n manual)", - "email": "Direcci\u00f3n de correo electr\u00f3nico", - "password": "Contrase\u00f1a" - }, - "title": "Inicio de sesi\u00f3n de Google Hangouts" - } - } - } -} \ No newline at end of file diff --git a/homeassistant/components/hangouts/translations/es.json b/homeassistant/components/hangouts/translations/es.json deleted file mode 100644 index 29fe36ea23c..00000000000 --- a/homeassistant/components/hangouts/translations/es.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "config": { - "abort": { - "already_configured": "El servicio ya est\u00e1 configurado", - "unknown": "Error inesperado" - }, - "error": { - "invalid_2fa": "Autenticaci\u00f3n de 2 factores no v\u00e1lida, por favor, int\u00e9ntalo de nuevo.", - "invalid_2fa_method": "M\u00e9todo 2FA no v\u00e1lido (verificar en el tel\u00e9fono).", - "invalid_login": "Inicio de sesi\u00f3n no v\u00e1lido, por favor, int\u00e9ntalo de nuevo." - }, - "step": { - "2fa": { - "data": { - "2fa": "PIN 2FA" - }, - "title": "Autenticaci\u00f3n de 2 factores" - }, - "user": { - "data": { - "authorization_code": "C\u00f3digo de autorizaci\u00f3n (requerido para la autenticaci\u00f3n manual)", - "email": "Correo electr\u00f3nico", - "password": "Contrase\u00f1a" - }, - "title": "Inicio de sesi\u00f3n de Google Chat" - } - } - } -} \ No newline at end of file diff --git a/homeassistant/components/hangouts/translations/et.json b/homeassistant/components/hangouts/translations/et.json deleted file mode 100644 index 96ed8b998ec..00000000000 --- a/homeassistant/components/hangouts/translations/et.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "config": { - "abort": { - "already_configured": "Teenus on juba seadistatud", - "unknown": "Tundmatu viga" - }, - "error": { - "invalid_2fa": "Vale 2-teguriline autentimine, proovi uuesti.", - "invalid_2fa_method": "Kehtetu kaheastmelise tuvastuse meetod (kontrolli telefonistl).", - "invalid_login": "Vale kasutajanimi, palun proovi uuesti." - }, - "step": { - "2fa": { - "data": { - "2fa": "Kaheastmelise tuvastuse PIN" - }, - "description": "", - "title": "Kaheastmeline autentimine" - }, - "user": { - "data": { - "authorization_code": "Autoriseerimiskood (vajalik k\u00e4sitsi autentimiseks)", - "email": "E-posti aadress", - "password": "Salas\u00f5na" - }, - "description": "", - "title": "Google Chat'i sisselogimine" - } - } - } -} \ No newline at end of file diff --git a/homeassistant/components/hangouts/translations/fi.json b/homeassistant/components/hangouts/translations/fi.json deleted file mode 100644 index e93642a952d..00000000000 --- a/homeassistant/components/hangouts/translations/fi.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "config": { - "abort": { - "unknown": "Tapahtui tuntematon virhe." - }, - "error": { - "invalid_2fa": "Virheellinen kaksitekij\u00e4todennus, yrit\u00e4 uudelleen.", - "invalid_2fa_method": "Virheellinen 2FA-menetelm\u00e4 (tarkista puhelimessa).", - "invalid_login": "Virheellinen kirjautuminen, yrit\u00e4 uudelleen." - }, - "step": { - "2fa": { - "data": { - "2fa": "2FA-pin" - }, - "description": "Tyhj\u00e4", - "title": "Kaksivaiheinen tunnistus" - }, - "user": { - "data": { - "email": "S\u00e4hk\u00f6postiosoite", - "password": "Salasana" - }, - "description": "Tyhj\u00e4", - "title": "Google Hangouts -kirjautuminen" - } - } - } -} \ No newline at end of file diff --git a/homeassistant/components/hangouts/translations/fr.json b/homeassistant/components/hangouts/translations/fr.json deleted file mode 100644 index 78a2517d29a..00000000000 --- a/homeassistant/components/hangouts/translations/fr.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "config": { - "abort": { - "already_configured": "Le service est d\u00e9j\u00e0 configur\u00e9", - "unknown": "Erreur inattendue" - }, - "error": { - "invalid_2fa": "Authentification \u00e0 deux facteurs non valide, veuillez r\u00e9essayer.", - "invalid_2fa_method": "M\u00e9thode 2FA non valide (v\u00e9rifiez sur le t\u00e9l\u00e9phone).", - "invalid_login": "Identifiant non valide, veuillez r\u00e9essayer." - }, - "step": { - "2fa": { - "data": { - "2fa": "Code NIP d'authentification \u00e0 2 facteurs" - }, - "description": "Vide", - "title": "Authentification \u00e0 2 facteurs" - }, - "user": { - "data": { - "authorization_code": "Code d'autorisation (requis pour l'authentification manuelle)", - "email": "Courriel", - "password": "Mot de passe" - }, - "description": "Vide", - "title": "Connexion \u00e0 Google Chat" - } - } - } -} \ No newline at end of file diff --git a/homeassistant/components/hangouts/translations/he.json b/homeassistant/components/hangouts/translations/he.json deleted file mode 100644 index ad696cad365..00000000000 --- a/homeassistant/components/hangouts/translations/he.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "config": { - "abort": { - "already_configured": "\u05e9\u05d9\u05e8\u05d5\u05ea \u05d6\u05d4 \u05db\u05d1\u05e8 \u05de\u05d5\u05d2\u05d3\u05e8", - "unknown": "\u05e9\u05d2\u05d9\u05d0\u05d4 \u05d1\u05dc\u05ea\u05d9 \u05e6\u05e4\u05d5\u05d9\u05d4" - }, - "error": { - "invalid_2fa": "\u05d0\u05d9\u05de\u05d5\u05ea \u05d3\u05d5 \u05e9\u05dc\u05d1\u05d9 \u05dc\u05d0 \u05d7\u05d5\u05e7\u05d9, \u05d1\u05d1\u05e7\u05e9\u05d4 \u05e0\u05e1\u05d4 \u05e9\u05d5\u05d1.", - "invalid_2fa_method": "\u05d3\u05e8\u05da \u05dc\u05d0\u05d9\u05de\u05d5\u05ea \u05d3\u05d5 \u05e9\u05dc\u05d1\u05d9 \u05dc\u05d0 \u05d7\u05d5\u05e7\u05d9\u05ea (\u05d0\u05de\u05ea \u05d1\u05d8\u05dc\u05e4\u05d5\u05df).", - "invalid_login": "\u05db\u05e0\u05d9\u05e1\u05d4 \u05dc\u05d0 \u05d7\u05d5\u05e7\u05d9\u05ea, \u05e0\u05e1\u05d4 \u05e9\u05d5\u05d1." - }, - "step": { - "2fa": { - "data": { - "2fa": "\u05e7\u05d5\u05d3 \u05d0\u05d9\u05de\u05d5\u05ea \u05d3\u05d5 \u05e9\u05dc\u05d1\u05d9" - }, - "title": "\u05d0\u05d9\u05de\u05d5\u05ea \u05d3\u05d5 \u05e9\u05dc\u05d1\u05d9" - }, - "user": { - "data": { - "email": "\u05d3\u05d5\u05d0\"\u05dc", - "password": "\u05e1\u05d9\u05e1\u05de\u05d4" - }, - "title": "\u05d4\u05ea\u05d7\u05d1\u05e8\u05d5\u05ea \u05dc\u05e6'\u05d0\u05d8 \u05e9\u05dc \u05d2\u05d5\u05d2\u05dc" - } - } - } -} \ No newline at end of file diff --git a/homeassistant/components/hangouts/translations/hr.json b/homeassistant/components/hangouts/translations/hr.json deleted file mode 100644 index 59b98ae9ae9..00000000000 --- a/homeassistant/components/hangouts/translations/hr.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "config": { - "step": { - "user": { - "data": { - "email": "Email", - "password": "Lozinka" - } - } - } - } -} \ No newline at end of file diff --git a/homeassistant/components/hangouts/translations/hu.json b/homeassistant/components/hangouts/translations/hu.json deleted file mode 100644 index 1ea997aa098..00000000000 --- a/homeassistant/components/hangouts/translations/hu.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "config": { - "abort": { - "already_configured": "A szolg\u00e1ltat\u00e1s m\u00e1r konfigur\u00e1lva van", - "unknown": "V\u00e1ratlan hiba t\u00f6rt\u00e9nt" - }, - "error": { - "invalid_2fa": "\u00c9rv\u00e9nytelen K\u00e9tfaktoros hiteles\u00edt\u00e9s, pr\u00f3b\u00e1ld \u00fajra.", - "invalid_2fa_method": "\u00c9rv\u00e9nytelen 2FA M\u00f3dszer (Ellen\u0151rz\u00e9s a Telefonon).", - "invalid_login": "\u00c9rv\u00e9nytelen bejelentkez\u00e9s, pr\u00f3b\u00e1ld \u00fajra." - }, - "step": { - "2fa": { - "data": { - "2fa": "2FA PIN" - }, - "description": "\u00dcres", - "title": "K\u00e9tfaktoros Hiteles\u00edt\u00e9s" - }, - "user": { - "data": { - "authorization_code": "Enged\u00e9lyez\u00e9si k\u00f3d (k\u00e9zi hiteles\u00edt\u00e9shez sz\u00fcks\u00e9ges)", - "email": "E-mail", - "password": "Jelsz\u00f3" - }, - "description": "\u00dcres", - "title": "Google Chat bejelentkez\u00e9s" - } - } - } -} \ No newline at end of file diff --git a/homeassistant/components/hangouts/translations/id.json b/homeassistant/components/hangouts/translations/id.json deleted file mode 100644 index 2336b211c9e..00000000000 --- a/homeassistant/components/hangouts/translations/id.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "config": { - "abort": { - "already_configured": "Layanan sudah dikonfigurasi", - "unknown": "Kesalahan yang tidak diharapkan" - }, - "error": { - "invalid_2fa": "Autentikasi 2 Faktor Tidak Valid, coba lagi.", - "invalid_2fa_method": "Metode 2FA Tidak Valid (Verifikasikan di Ponsel).", - "invalid_login": "Info Masuk Tidak Valid, coba lagi." - }, - "step": { - "2fa": { - "data": { - "2fa": "PIN 2FA" - }, - "description": "Kosong", - "title": "Autentikasi Dua Faktor" - }, - "user": { - "data": { - "authorization_code": "Kode Otorisasi (diperlukan untuk autentikasi manual)", - "email": "Email", - "password": "Kata Sandi" - }, - "description": "Kosong", - "title": "Info Masuk Google Chat" - } - } - } -} \ No newline at end of file diff --git a/homeassistant/components/hangouts/translations/it.json b/homeassistant/components/hangouts/translations/it.json deleted file mode 100644 index 76d81a184d9..00000000000 --- a/homeassistant/components/hangouts/translations/it.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "config": { - "abort": { - "already_configured": "Il servizio \u00e8 gi\u00e0 configurato", - "unknown": "Errore imprevisto" - }, - "error": { - "invalid_2fa": "Autenticazione a 2 fattori non valida, riprova.", - "invalid_2fa_method": "Metodo 2FA non valido (verifica sul telefono).", - "invalid_login": "Accesso non valido, riprova." - }, - "step": { - "2fa": { - "data": { - "2fa": "2FA PIN" - }, - "description": "Vuoto", - "title": "Autenticazione a due fattori" - }, - "user": { - "data": { - "authorization_code": "Codice di autorizzazione (necessario per l'autenticazione manuale)", - "email": "Email", - "password": "Password" - }, - "description": "Vuoto", - "title": "Accesso a Google Chat" - } - } - } -} \ No newline at end of file diff --git a/homeassistant/components/hangouts/translations/ja.json b/homeassistant/components/hangouts/translations/ja.json deleted file mode 100644 index 14637ee1155..00000000000 --- a/homeassistant/components/hangouts/translations/ja.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "config": { - "abort": { - "already_configured": "\u30b5\u30fc\u30d3\u30b9\u306f\u3059\u3067\u306b\u8a2d\u5b9a\u3055\u308c\u3066\u3044\u307e\u3059", - "unknown": "\u4e88\u671f\u3057\u306a\u3044\u30a8\u30e9\u30fc" - }, - "error": { - "invalid_2fa": "2\u8981\u7d20\u8a8d\u8a3c\u304c\u7121\u52b9\u3067\u3059\u3002\u3082\u3046\u4e00\u5ea6\u304a\u8a66\u3057\u304f\u3060\u3055\u3044\u3002", - "invalid_2fa_method": "2\u8981\u7d20\u8a8d\u8a3c\u304c\u7121\u52b9(\u96fb\u8a71\u3067\u78ba\u8a8d)", - "invalid_login": "\u30ed\u30b0\u30a4\u30f3\u3067\u304d\u307e\u305b\u3093\u3001\u3082\u3046\u4e00\u5ea6\u304a\u8a66\u3057\u304f\u3060\u3055\u3044\u3002" - }, - "step": { - "2fa": { - "data": { - "2fa": "2\u8981\u7d20 PIN" - }, - "description": "\u7a7a", - "title": "2\u8981\u7d20\u8a8d\u8a3c" - }, - "user": { - "data": { - "authorization_code": "\u8a8d\u8a3c\u30b3\u30fc\u30c9(\u624b\u52d5\u8a8d\u8a3c\u6642\u306b\u5fc5\u8981)", - "email": "E\u30e1\u30fc\u30eb", - "password": "\u30d1\u30b9\u30ef\u30fc\u30c9" - }, - "description": "\u7a7a", - "title": "Google \u30cf\u30f3\u30b0\u30a2\u30a6\u30c8 \u30ed\u30b0\u30a4\u30f3" - } - } - } -} \ No newline at end of file diff --git a/homeassistant/components/hangouts/translations/ko.json b/homeassistant/components/hangouts/translations/ko.json deleted file mode 100644 index 56c3c577a89..00000000000 --- a/homeassistant/components/hangouts/translations/ko.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "config": { - "abort": { - "already_configured": "\uc11c\ube44\uc2a4\uac00 \uc774\ubbf8 \uad6c\uc131\ub418\uc5c8\uc2b5\ub2c8\ub2e4", - "unknown": "\uc608\uc0c1\uce58 \ubabb\ud55c \uc624\ub958\uac00 \ubc1c\uc0dd\ud588\uc2b5\ub2c8\ub2e4" - }, - "error": { - "invalid_2fa": "2\ub2e8\uacc4 \uc778\uc99d\uc774 \uc798\ubabb\ub418\uc5c8\uc2b5\ub2c8\ub2e4. \ub2e4\uc2dc \uc2dc\ub3c4\ud574\uc8fc\uc138\uc694.", - "invalid_2fa_method": "2\ub2e8\uacc4 \uc778\uc99d \ubc29\ubc95\uc774 \uc798\ubabb\ub418\uc5c8\uc2b5\ub2c8\ub2e4. (\uc804\ud654\uae30\uc5d0\uc11c \ud655\uc778)", - "invalid_login": "\ub85c\uadf8\uc778\uc774 \uc798\ubabb\ub418\uc5c8\uc2b5\ub2c8\ub2e4. \ub2e4\uc2dc \uc2dc\ub3c4\ud574\uc8fc\uc138\uc694." - }, - "step": { - "2fa": { - "data": { - "2fa": "2\ub2e8\uacc4 \uc778\uc99d PIN" - }, - "description": "\uc8c4\uc1a1\ud569\ub2c8\ub2e4. \uad00\ub828 \ub0b4\uc6a9\uc774 \uc544\uc9c1 \uc5c5\ub370\uc774\ud2b8 \ub418\uc9c0 \uc54a\uc558\uc2b5\ub2c8\ub2e4. \ucd94\ud6c4\uc5d0 \ubc18\uc601\ub420 \uc608\uc815\uc774\ub2c8 \uc870\uae08\ub9cc \uae30\ub2e4\ub824\uc8fc\uc138\uc694.", - "title": "2\ub2e8\uacc4 \uc778\uc99d" - }, - "user": { - "data": { - "authorization_code": "\uc778\uc99d \ucf54\ub4dc (\uc218\ub3d9 \uc778\uc99d\uc5d0 \ud544\uc694)", - "email": "\uc774\uba54\uc77c", - "password": "\ube44\ubc00\ubc88\ud638" - }, - "description": "\uc8c4\uc1a1\ud569\ub2c8\ub2e4. \uad00\ub828 \ub0b4\uc6a9\uc774 \uc544\uc9c1 \uc5c5\ub370\uc774\ud2b8 \ub418\uc9c0 \uc54a\uc558\uc2b5\ub2c8\ub2e4. \ucd94\ud6c4\uc5d0 \ubc18\uc601\ub420 \uc608\uc815\uc774\ub2c8 \uc870\uae08\ub9cc \uae30\ub2e4\ub824\uc8fc\uc138\uc694.", - "title": "Google \ud589\uc544\uc6c3 \ub85c\uadf8\uc778" - } - } - } -} \ No newline at end of file diff --git a/homeassistant/components/hangouts/translations/lb.json b/homeassistant/components/hangouts/translations/lb.json deleted file mode 100644 index a91f2e7b040..00000000000 --- a/homeassistant/components/hangouts/translations/lb.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "config": { - "abort": { - "already_configured": "Service ass scho konfigur\u00e9iert", - "unknown": "Onerwaarte Feeler" - }, - "error": { - "invalid_2fa": "Ong\u00eblteg 2-Faktor Authentifikatioun, prob\u00e9iert w.e.g. nach emol.", - "invalid_2fa_method": "Ong\u00eblteg 2FA Methode (Iwwerpr\u00e9ift et um Telefon)", - "invalid_login": "Ong\u00ebltege Login, prob\u00e9iert w.e.g. nach emol." - }, - "step": { - "2fa": { - "data": { - "2fa": "2FA Pin" - }, - "description": "Eidel", - "title": "2-Faktor-Authentifikatioun" - }, - "user": { - "data": { - "authorization_code": "Autorisatioun's Code (n\u00e9ideg fir eng manuell Authentifikatioun)", - "email": "E-Mail", - "password": "Passwuert" - }, - "description": "Eidel", - "title": "Google Hangouts Login" - } - } - } -} \ No newline at end of file diff --git a/homeassistant/components/hangouts/translations/lt.json b/homeassistant/components/hangouts/translations/lt.json deleted file mode 100644 index 13dbbf8bdbc..00000000000 --- a/homeassistant/components/hangouts/translations/lt.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "config": { - "step": { - "2fa": { - "data": { - "2fa": "2FA PIN" - }, - "title": "2 veiksni\u0173 autentifikavimas" - } - } - } -} \ No newline at end of file diff --git a/homeassistant/components/hangouts/translations/nb.json b/homeassistant/components/hangouts/translations/nb.json deleted file mode 100644 index 11a4fc139b8..00000000000 --- a/homeassistant/components/hangouts/translations/nb.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "config": { - "abort": { - "unknown": "Uventet feil" - } - } -} \ No newline at end of file diff --git a/homeassistant/components/hangouts/translations/nl.json b/homeassistant/components/hangouts/translations/nl.json deleted file mode 100644 index 826bc560045..00000000000 --- a/homeassistant/components/hangouts/translations/nl.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "config": { - "abort": { - "already_configured": "Dienst is al geconfigureerd", - "unknown": "Onverwachte fout" - }, - "error": { - "invalid_2fa": "Ongeldige twee-factor-authenticatie, probeer het opnieuw.", - "invalid_2fa_method": "Ongeldige 2FA-methode (verifi\u00ebren op telefoon).", - "invalid_login": "Ongeldige aanmelding, probeer het opnieuw." - }, - "step": { - "2fa": { - "data": { - "2fa": "2FA pin" - }, - "description": "Leeg", - "title": "Twee-factor-authenticatie" - }, - "user": { - "data": { - "authorization_code": "Autorisatiecode (vereist voor handmatige authenticatie)", - "email": "E-mail", - "password": "Wachtwoord" - }, - "description": "Leeg", - "title": "Google Chat-login" - } - } - } -} \ No newline at end of file diff --git a/homeassistant/components/hangouts/translations/nn.json b/homeassistant/components/hangouts/translations/nn.json deleted file mode 100644 index 883a53441af..00000000000 --- a/homeassistant/components/hangouts/translations/nn.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "config": { - "abort": { - "already_configured": "Google Hangouts er allereie konfigurert", - "unknown": "Det hende ein ukjent feil" - }, - "error": { - "invalid_2fa": "Ugyldig to-faktor-autentisering. Ver vennleg og pr\u00f8v igjen.", - "invalid_2fa_method": "Ugyldig 2FA-metode (godkjenn p\u00e5 telefonen).", - "invalid_login": "Ugyldig innlogging. Pr\u00f8v igjen." - }, - "step": { - "2fa": { - "data": { - "2fa": "2FA PIN" - }, - "title": "To-faktor-autentisering" - }, - "user": { - "data": { - "email": "Epostadresse", - "password": "Passord" - }, - "title": "Google Hangouts Login" - } - } - } -} \ No newline at end of file diff --git a/homeassistant/components/hangouts/translations/no.json b/homeassistant/components/hangouts/translations/no.json deleted file mode 100644 index 751d54c852e..00000000000 --- a/homeassistant/components/hangouts/translations/no.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "config": { - "abort": { - "already_configured": "Tjenesten er allerede konfigurert", - "unknown": "Uventet feil" - }, - "error": { - "invalid_2fa": "Ugyldig totrinnsbekreftelse, vennligst pr\u00f8v igjen.", - "invalid_2fa_method": "Ugyldig 2FA-metode (bekreft p\u00e5 telefon).", - "invalid_login": "Ugyldig innlogging, vennligst pr\u00f8v igjen." - }, - "step": { - "2fa": { - "data": { - "2fa": "2FA PIN" - }, - "description": "", - "title": "Totrinnsbekreftelse" - }, - "user": { - "data": { - "authorization_code": "Godkjenningskode (kreves for manuell godkjenning)", - "email": "E-post", - "password": "Passord" - }, - "description": "", - "title": "Google Chat-p\u00e5logging" - } - } - } -} \ No newline at end of file diff --git a/homeassistant/components/hangouts/translations/pl.json b/homeassistant/components/hangouts/translations/pl.json deleted file mode 100644 index 4dafdc5d996..00000000000 --- a/homeassistant/components/hangouts/translations/pl.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "config": { - "abort": { - "already_configured": "Us\u0142uga jest ju\u017c skonfigurowana", - "unknown": "Nieoczekiwany b\u0142\u0105d" - }, - "error": { - "invalid_2fa": "Nieprawid\u0142owe uwierzytelnienie dwusk\u0142adnikowe, spr\u00f3buj ponownie", - "invalid_2fa_method": "Nieprawid\u0142owa metoda uwierzytelniania dwusk\u0142adnikowego (u\u017cyj weryfikacji przez telefon)", - "invalid_login": "Nieprawid\u0142owy login, spr\u00f3buj ponownie" - }, - "step": { - "2fa": { - "data": { - "2fa": "Kod uwierzytelniania dwusk\u0142adnikowego" - }, - "description": "Pusty", - "title": "Uwierzytelnianie dwusk\u0142adnikowe" - }, - "user": { - "data": { - "authorization_code": "Kod autoryzacji (wymagany do r\u0119cznego uwierzytelnienia)", - "email": "Adres e-mail", - "password": "Has\u0142o" - }, - "description": "Pusty", - "title": "Logowanie do Google Chat" - } - } - } -} \ No newline at end of file diff --git a/homeassistant/components/hangouts/translations/pt-BR.json b/homeassistant/components/hangouts/translations/pt-BR.json deleted file mode 100644 index 9e4d04cd989..00000000000 --- a/homeassistant/components/hangouts/translations/pt-BR.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "config": { - "abort": { - "already_configured": "O servi\u00e7o j\u00e1 est\u00e1 configurado", - "unknown": "Erro inesperado" - }, - "error": { - "invalid_2fa": "Autentica\u00e7\u00e3o de 2 fatores inv\u00e1lida, por favor, tente novamente.", - "invalid_2fa_method": "M\u00e9todo 2FA inv\u00e1lido (verificar no telefone).", - "invalid_login": "Login inv\u00e1lido, por favor, tente novamente." - }, - "step": { - "2fa": { - "data": { - "2fa": "C\u00f3digo 2FA" - }, - "description": "Vazio", - "title": "Autentica\u00e7\u00e3o de 2 Fatores" - }, - "user": { - "data": { - "authorization_code": "C\u00f3digo de Autoriza\u00e7\u00e3o (requerido para autentica\u00e7\u00e3o manual)", - "email": "Email", - "password": "Senha" - }, - "description": "Vazio", - "title": "Login no Google Chat" - } - } - } -} \ No newline at end of file diff --git a/homeassistant/components/hangouts/translations/pt.json b/homeassistant/components/hangouts/translations/pt.json deleted file mode 100644 index b4feb91c76d..00000000000 --- a/homeassistant/components/hangouts/translations/pt.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "config": { - "abort": { - "already_configured": "Google Hangouts j\u00e1 est\u00e1 configurado", - "unknown": "Erro inesperado" - }, - "error": { - "invalid_2fa": "Autentica\u00e7\u00e3o por 2 fatores inv\u00e1lida, por favor, tente novamente.", - "invalid_2fa_method": "M\u00e9todo 2FA inv\u00e1lido (verificar no telefone).", - "invalid_login": "Login inv\u00e1lido, por favor, tente novamente." - }, - "step": { - "2fa": { - "data": { - "2fa": "Pin 2FA" - }, - "description": "Vazio", - "title": "Autentica\u00e7\u00e3o de 2 Fatores" - }, - "user": { - "data": { - "email": "E-mail", - "password": "Palavra-passe" - }, - "description": "Vazio", - "title": "Login Google Hangouts" - } - } - } -} \ No newline at end of file diff --git a/homeassistant/components/hangouts/translations/ro.json b/homeassistant/components/hangouts/translations/ro.json deleted file mode 100644 index 682d561929c..00000000000 --- a/homeassistant/components/hangouts/translations/ro.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "config": { - "abort": { - "already_configured": "Google Hangouts este deja configurat", - "unknown": "Sa produs o eroare necunoscut\u0103." - }, - "error": { - "invalid_2fa_method": "Metoda 2FA invalid\u0103 (Verifica\u021bi pe telefon).", - "invalid_login": "Conectare invalid\u0103, \u00eencerca\u021bi din nou." - }, - "step": { - "2fa": { - "data": { - "2fa": "2FA Pin" - } - }, - "user": { - "data": { - "email": "Adresa de email", - "password": "Parol\u0103" - }, - "description": "Gol", - "title": "Conectare Google Hangouts" - } - } - } -} \ No newline at end of file diff --git a/homeassistant/components/hangouts/translations/ru.json b/homeassistant/components/hangouts/translations/ru.json deleted file mode 100644 index 781e1e25eef..00000000000 --- a/homeassistant/components/hangouts/translations/ru.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "config": { - "abort": { - "already_configured": "\u042d\u0442\u0430 \u0441\u043b\u0443\u0436\u0431\u0430 \u0443\u0436\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0430 \u0432 Home Assistant.", - "unknown": "\u041d\u0435\u043f\u0440\u0435\u0434\u0432\u0438\u0434\u0435\u043d\u043d\u0430\u044f \u043e\u0448\u0438\u0431\u043a\u0430." - }, - "error": { - "invalid_2fa": "\u041d\u0435\u0432\u0435\u0440\u043d\u0430\u044f \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044f, \u043f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0439\u0442\u0435 \u0441\u043d\u043e\u0432\u0430.", - "invalid_2fa_method": "\u041d\u0435\u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0434\u0432\u0443\u0445\u0444\u0430\u043a\u0442\u043e\u0440\u043d\u043e\u0439 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 (\u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u043d\u0430 \u0442\u0435\u043b\u0435\u0444\u043e\u043d\u0435).", - "invalid_login": "\u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u043b\u043e\u0433\u0438\u043d, \u043f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0439\u0442\u0435 \u0441\u043d\u043e\u0432\u0430." - }, - "step": { - "2fa": { - "data": { - "2fa": "\u041f\u0438\u043d-\u043a\u043e\u0434 \u0434\u043b\u044f \u0434\u0432\u0443\u0445\u0444\u0430\u043a\u0442\u043e\u0440\u043d\u043e\u0439 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438" - }, - "description": "\u043f\u0443\u0441\u0442\u043e", - "title": "\u0414\u0432\u0443\u0445\u0444\u0430\u043a\u0442\u043e\u0440\u043d\u0430\u044f \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f" - }, - "user": { - "data": { - "authorization_code": "\u041a\u043e\u0434 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 (\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0440\u0443\u0447\u043d\u043e\u0439 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438)", - "email": "\u0410\u0434\u0440\u0435\u0441 \u044d\u043b\u0435\u043a\u0442\u0440\u043e\u043d\u043d\u043e\u0439 \u043f\u043e\u0447\u0442\u044b", - "password": "\u041f\u0430\u0440\u043e\u043b\u044c" - }, - "description": "\u043f\u0443\u0441\u0442\u043e", - "title": "Google Chat" - } - } - } -} \ No newline at end of file diff --git a/homeassistant/components/hangouts/translations/sk.json b/homeassistant/components/hangouts/translations/sk.json deleted file mode 100644 index 45123261c43..00000000000 --- a/homeassistant/components/hangouts/translations/sk.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "config": { - "step": { - "user": { - "data": { - "email": "Email", - "password": "Heslo" - } - } - } - } -} \ No newline at end of file diff --git a/homeassistant/components/hangouts/translations/sl.json b/homeassistant/components/hangouts/translations/sl.json deleted file mode 100644 index 853dfa1487a..00000000000 --- a/homeassistant/components/hangouts/translations/sl.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "config": { - "abort": { - "already_configured": "Google Hangouts je \u017ee konfiguriran", - "unknown": "Pri\u0161lo je do neznane napake" - }, - "error": { - "invalid_2fa": "Neveljavna 2FA avtorizacija, prosimo, poskusite znova.", - "invalid_2fa_method": "Neveljavna 2FA Metoda (Preverite na Telefonu).", - "invalid_login": "Neveljavna Prijava, prosimo, poskusite znova." - }, - "step": { - "2fa": { - "data": { - "2fa": "2FA Pin" - }, - "description": "prazno", - "title": "Dvofaktorska avtorizacija" - }, - "user": { - "data": { - "authorization_code": "Koda pooblastila (potrebna za ro\u010dno overjanje)", - "email": "E-po\u0161tni naslov", - "password": "Geslo" - }, - "description": "prazno", - "title": "Prijava za Google Hangouts" - } - } - } -} \ No newline at end of file diff --git a/homeassistant/components/hangouts/translations/sv.json b/homeassistant/components/hangouts/translations/sv.json deleted file mode 100644 index f9e5ec14c54..00000000000 --- a/homeassistant/components/hangouts/translations/sv.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "config": { - "abort": { - "already_configured": "Google Hangouts \u00e4r redan inst\u00e4llt", - "unknown": "Ett ok\u00e4nt fel intr\u00e4ffade" - }, - "error": { - "invalid_2fa": "Ogiltig 2FA autentisering, f\u00f6rs\u00f6k igen.", - "invalid_2fa_method": "Ogiltig 2FA-metod (Verifiera med telefon).", - "invalid_login": "Ogiltig inloggning, f\u00f6rs\u00f6k igen." - }, - "step": { - "2fa": { - "data": { - "2fa": "2FA Pinkod" - }, - "description": "Missing english translation", - "title": "Tv\u00e5faktorsautentisering" - }, - "user": { - "data": { - "authorization_code": "Auktoriseringskod (kr\u00e4vs vid manuell verifiering)", - "email": "E-postadress", - "password": "L\u00f6senord" - }, - "description": "Missing english translation", - "title": "Google Hangouts-inloggning" - } - } - } -} \ No newline at end of file diff --git a/homeassistant/components/hangouts/translations/th.json b/homeassistant/components/hangouts/translations/th.json deleted file mode 100644 index bcc59392e2e..00000000000 --- a/homeassistant/components/hangouts/translations/th.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "config": { - "step": { - "2fa": { - "title": "\u0e23\u0e2b\u0e31\u0e2a\u0e23\u0e31\u0e1a\u0e23\u0e2d\u0e07\u0e04\u0e27\u0e32\u0e21\u0e16\u0e39\u0e01\u0e15\u0e49\u0e2d\u0e07\u0e2a\u0e2d\u0e07\u0e1b\u0e31\u0e08\u0e08\u0e31\u0e22" - }, - "user": { - "data": { - "email": "\u0e17\u0e35\u0e48\u0e2d\u0e22\u0e39\u0e48\u0e2d\u0e35\u0e40\u0e21\u0e25", - "password": "\u0e23\u0e2b\u0e31\u0e2a\u0e1c\u0e48\u0e32\u0e19" - }, - "description": "\u0e27\u0e48\u0e32\u0e07\u0e40\u0e1b\u0e25\u0e48\u0e32" - } - } - } -} \ No newline at end of file diff --git a/homeassistant/components/hangouts/translations/tr.json b/homeassistant/components/hangouts/translations/tr.json deleted file mode 100644 index 5ddf2a64cbb..00000000000 --- a/homeassistant/components/hangouts/translations/tr.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "config": { - "abort": { - "already_configured": "Hizmet zaten yap\u0131land\u0131r\u0131lm\u0131\u015f", - "unknown": "Beklenmeyen hata" - }, - "error": { - "invalid_2fa": "Ge\u00e7ersiz 2 Fakt\u00f6rl\u00fc Kimlik Do\u011frulama, l\u00fctfen tekrar deneyin.", - "invalid_2fa_method": "Ge\u00e7ersiz 2FA Y\u00f6ntemi (Telefonda do\u011frulay\u0131n).", - "invalid_login": "Ge\u00e7ersiz Giri\u015f, l\u00fctfen tekrar deneyin." - }, - "step": { - "2fa": { - "data": { - "2fa": "2FA PIN'i" - }, - "description": "Bo\u015f", - "title": "2-Fakt\u00f6rl\u00fc Kimlik Do\u011frulama" - }, - "user": { - "data": { - "authorization_code": "Yetkilendirme Kodu (manuel kimlik do\u011frulama i\u00e7in gereklidir)", - "email": "E-posta", - "password": "Parola" - }, - "description": "Bo\u015f", - "title": "Google Sohbet Giri\u015fi" - } - } - } -} \ No newline at end of file diff --git a/homeassistant/components/hangouts/translations/uk.json b/homeassistant/components/hangouts/translations/uk.json deleted file mode 100644 index 93eb699d37c..00000000000 --- a/homeassistant/components/hangouts/translations/uk.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "config": { - "abort": { - "already_configured": "\u0426\u044f \u0441\u043b\u0443\u0436\u0431\u0430 \u0432\u0436\u0435 \u0434\u043e\u0434\u0430\u043d\u0430 \u0432 Home Assistant.", - "unknown": "\u041d\u0435\u043e\u0447\u0456\u043a\u0443\u0432\u0430\u043d\u0430 \u043f\u043e\u043c\u0438\u043b\u043a\u0430" - }, - "error": { - "invalid_2fa": "\u041d\u0435\u0432\u0456\u0440\u043d\u0430 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0456\u044f, \u0431\u0443\u0434\u044c \u043b\u0430\u0441\u043a\u0430, \u0441\u043f\u0440\u043e\u0431\u0443\u0439\u0442\u0435 \u0437\u043d\u043e\u0432\u0443.", - "invalid_2fa_method": "\u041d\u0435\u043f\u0440\u0438\u043f\u0443\u0441\u0442\u0438\u043c\u0438\u0439 \u0441\u043f\u043e\u0441\u0456\u0431 \u0434\u0432\u043e\u0444\u0430\u043a\u0442\u043e\u0440\u043d\u043e\u0457 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0456\u043a\u0430\u0446\u0456\u0457 (\u043f\u0435\u0440\u0435\u0432\u0456\u0440\u0438\u0442\u0438 \u043d\u0430 \u0442\u0435\u043b\u0435\u0444\u043e\u043d\u0456).", - "invalid_login": "\u041d\u0435\u0432\u0456\u0440\u043d\u0438\u0439 \u043b\u043e\u0433\u0456\u043d, \u0431\u0443\u0434\u044c \u043b\u0430\u0441\u043a\u0430, \u0441\u043f\u0440\u043e\u0431\u0443\u0439\u0442\u0435 \u0437\u043d\u043e\u0432\u0443." - }, - "step": { - "2fa": { - "data": { - "2fa": "\u041f\u0456\u043d-\u043a\u043e\u0434 \u0434\u043b\u044f \u0434\u0432\u043e\u0444\u0430\u043a\u0442\u043e\u0440\u043d\u043e\u0457 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0456\u043a\u0430\u0446\u0456\u0457" - }, - "description": "\u043f\u043e\u0440\u043e\u0436\u043d\u044c\u043e", - "title": "\u0414\u0432\u043e\u0444\u0430\u043a\u0442\u043e\u0440\u043d\u0430 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0456\u043a\u0430\u0446\u0456\u044f" - }, - "user": { - "data": { - "authorization_code": "\u041a\u043e\u0434 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0456\u0457 (\u0432\u0438\u043c\u0430\u0433\u0430\u0454\u0442\u044c\u0441\u044f \u0434\u043b\u044f \u0440\u0443\u0447\u043d\u043e\u0457 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0456\u043a\u0430\u0446\u0456\u0457)", - "email": "\u0410\u0434\u0440\u0435\u0441\u0430 \u0435\u043b\u0435\u043a\u0442\u0440\u043e\u043d\u043d\u043e\u0457 \u043f\u043e\u0448\u0442\u0438", - "password": "\u041f\u0430\u0440\u043e\u043b\u044c" - }, - "description": "\u043f\u043e\u0440\u043e\u0436\u043d\u044c\u043e", - "title": "Google Hangouts" - } - } - } -} \ No newline at end of file diff --git a/homeassistant/components/hangouts/translations/vi.json b/homeassistant/components/hangouts/translations/vi.json deleted file mode 100644 index d794a0b5afa..00000000000 --- a/homeassistant/components/hangouts/translations/vi.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "config": { - "error": { - "invalid_2fa_method": "Ph\u01b0\u01a1ng ph\u00e1p 2FA kh\u00f4ng h\u1ee3p l\u1ec7 (X\u00e1c minh tr\u00ean \u0111i\u1ec7n tho\u1ea1i)." - } - } -} \ No newline at end of file diff --git a/homeassistant/components/hangouts/translations/zh-Hans.json b/homeassistant/components/hangouts/translations/zh-Hans.json deleted file mode 100644 index 46d1de99c73..00000000000 --- a/homeassistant/components/hangouts/translations/zh-Hans.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "config": { - "abort": { - "already_configured": "Google Hangouts \u5df2\u914d\u7f6e\u5b8c\u6210", - "unknown": "\u53d1\u751f\u672a\u77e5\u9519\u8bef\u3002" - }, - "error": { - "invalid_2fa": "\u53cc\u91cd\u8ba4\u8bc1\u5931\u8d25\uff0c\u8bf7\u91cd\u8bd5\u3002", - "invalid_2fa_method": "\u65e0\u6548\u7684\u53cc\u91cd\u8ba4\u8bc1\u65b9\u6cd5\uff08\u7535\u8bdd\u9a8c\u8bc1\uff09\u3002", - "invalid_login": "\u767b\u9646\u5931\u8d25\uff0c\u8bf7\u518d\u8bd5\u4e00\u6b21\u3002" - }, - "step": { - "2fa": { - "data": { - "2fa": "2FA Pin" - }, - "description": "\u65e0", - "title": "\u53cc\u91cd\u8ba4\u8bc1" - }, - "user": { - "data": { - "email": "\u7535\u5b50\u90ae\u4ef6\u5730\u5740", - "password": "\u5bc6\u7801" - }, - "description": "\u65e0", - "title": "\u767b\u5f55 Google Hangouts" - } - } - } -} \ No newline at end of file diff --git a/homeassistant/components/hangouts/translations/zh-Hant.json b/homeassistant/components/hangouts/translations/zh-Hant.json deleted file mode 100644 index f9884d5e214..00000000000 --- a/homeassistant/components/hangouts/translations/zh-Hant.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "config": { - "abort": { - "already_configured": "\u670d\u52d9\u5df2\u7d93\u8a2d\u5b9a\u5b8c\u6210", - "unknown": "\u672a\u9810\u671f\u932f\u8aa4" - }, - "error": { - "invalid_2fa": "\u96d9\u91cd\u8a8d\u8b49\u7121\u6548\uff0c\u8acb\u518d\u8a66\u4e00\u6b21\u3002", - "invalid_2fa_method": "\u5169\u968e\u6bb5\u8a8d\u8b49\u65b9\u5f0f\u7121\u6548\uff08\u65bc\u96fb\u8a71\u4e0a\u9a57\u8b49\uff09\u3002", - "invalid_login": "\u767b\u5165\u5931\u6557\uff0c\u8acb\u518d\u8a66\u4e00\u6b21\u3002" - }, - "step": { - "2fa": { - "data": { - "2fa": "\u5169\u968e\u6bb5\u8a8d\u8b49\u78bc" - }, - "description": "\u7a7a\u767d", - "title": "\u96d9\u91cd\u8a8d\u8b49" - }, - "user": { - "data": { - "authorization_code": "\u9a57\u8b49\u78bc\uff08\u624b\u52d5\u9a57\u8b49\u5fc5\u9808\uff09", - "email": "\u96fb\u5b50\u90f5\u4ef6", - "password": "\u5bc6\u78bc" - }, - "description": "\u7a7a\u767d", - "title": "\u767b\u5165 Google Chat" - } - } - } -} \ No newline at end of file diff --git a/homeassistant/generated/config_flows.py b/homeassistant/generated/config_flows.py index 33579c6b5ee..4d7ed69257d 100644 --- a/homeassistant/generated/config_flows.py +++ b/homeassistant/generated/config_flows.py @@ -162,7 +162,6 @@ FLOWS = { "growatt_server", "guardian", "habitica", - "hangouts", "harmony", "heos", "here_travel_time", diff --git a/homeassistant/generated/integrations.json b/homeassistant/generated/integrations.json index b407decbd34..ebd7d4f934e 100644 --- a/homeassistant/generated/integrations.json +++ b/homeassistant/generated/integrations.json @@ -2022,12 +2022,6 @@ "iot_class": "local_polling", "name": "Google Cast" }, - "hangouts": { - "integration_type": "hub", - "config_flow": true, - "iot_class": "cloud_push", - "name": "Google Chat" - }, "dialogflow": { "integration_type": "hub", "config_flow": true, diff --git a/requirements_all.txt b/requirements_all.txt index 396e0a9206e..bf2e3bf419d 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -847,9 +847,6 @@ ha-philipsjs==2.9.0 # homeassistant.components.habitica habitipy==0.2.0 -# homeassistant.components.hangouts -hangups==0.4.18 - # homeassistant.components.cloud hass-nabucasa==0.56.0 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index a66569a76bc..5b6f2b2668c 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -639,9 +639,6 @@ ha-philipsjs==2.9.0 # homeassistant.components.habitica habitipy==0.2.0 -# homeassistant.components.hangouts -hangups==0.4.18 - # homeassistant.components.cloud hass-nabucasa==0.56.0 diff --git a/tests/components/hangouts/__init__.py b/tests/components/hangouts/__init__.py deleted file mode 100644 index 81174356c2e..00000000000 --- a/tests/components/hangouts/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""Tests for the Hangouts Component.""" diff --git a/tests/components/hangouts/test_config_flow.py b/tests/components/hangouts/test_config_flow.py deleted file mode 100644 index 5df675a0f05..00000000000 --- a/tests/components/hangouts/test_config_flow.py +++ /dev/null @@ -1,132 +0,0 @@ -"""Tests for the Google Hangouts config flow.""" - -from unittest.mock import patch - -from homeassistant import data_entry_flow -from homeassistant.components.hangouts import config_flow -from homeassistant.const import CONF_EMAIL, CONF_PASSWORD - -EMAIL = "test@test.com" -PASSWORD = "1232456" - - -async def test_flow_works(hass, aioclient_mock): - """Test config flow without 2fa.""" - flow = config_flow.HangoutsFlowHandler() - - flow.hass = hass - - with patch("homeassistant.components.hangouts.config_flow.get_auth"): - result = await flow.async_step_user( - {CONF_EMAIL: EMAIL, CONF_PASSWORD: PASSWORD} - ) - assert result["type"] == data_entry_flow.FlowResultType.CREATE_ENTRY - assert result["title"] == EMAIL - - -async def test_flow_works_with_authcode(hass, aioclient_mock): - """Test config flow without 2fa.""" - flow = config_flow.HangoutsFlowHandler() - - flow.hass = hass - - with patch("homeassistant.components.hangouts.config_flow.get_auth"): - result = await flow.async_step_user( - { - CONF_EMAIL: EMAIL, - CONF_PASSWORD: PASSWORD, - "authorization_code": "c29tZXJhbmRvbXN0cmluZw==", - } - ) - assert result["type"] == data_entry_flow.FlowResultType.CREATE_ENTRY - assert result["title"] == EMAIL - - -async def test_flow_works_with_2fa(hass, aioclient_mock): - """Test config flow with 2fa.""" - from homeassistant.components.hangouts.hangups_utils import Google2FAError - - flow = config_flow.HangoutsFlowHandler() - - flow.hass = hass - - with patch( - "homeassistant.components.hangouts.config_flow.get_auth", - side_effect=Google2FAError, - ): - result = await flow.async_step_user( - {CONF_EMAIL: EMAIL, CONF_PASSWORD: PASSWORD} - ) - assert result["type"] == data_entry_flow.FlowResultType.FORM - assert result["step_id"] == "2fa" - - with patch("homeassistant.components.hangouts.config_flow.get_auth"): - result = await flow.async_step_2fa({"2fa": 123456}) - assert result["type"] == data_entry_flow.FlowResultType.CREATE_ENTRY - assert result["title"] == EMAIL - - -async def test_flow_with_unknown_2fa(hass, aioclient_mock): - """Test config flow with invalid 2fa method.""" - from homeassistant.components.hangouts.hangups_utils import GoogleAuthError - - flow = config_flow.HangoutsFlowHandler() - - flow.hass = hass - - with patch( - "homeassistant.components.hangouts.config_flow.get_auth", - side_effect=GoogleAuthError("Unknown verification code input"), - ): - result = await flow.async_step_user( - {CONF_EMAIL: EMAIL, CONF_PASSWORD: PASSWORD} - ) - assert result["type"] == data_entry_flow.FlowResultType.FORM - assert result["errors"]["base"] == "invalid_2fa_method" - - -async def test_flow_invalid_login(hass, aioclient_mock): - """Test config flow with invalid 2fa method.""" - from homeassistant.components.hangouts.hangups_utils import GoogleAuthError - - flow = config_flow.HangoutsFlowHandler() - - flow.hass = hass - - with patch( - "homeassistant.components.hangouts.config_flow.get_auth", - side_effect=GoogleAuthError, - ): - result = await flow.async_step_user( - {CONF_EMAIL: EMAIL, CONF_PASSWORD: PASSWORD} - ) - assert result["type"] == data_entry_flow.FlowResultType.FORM - assert result["errors"]["base"] == "invalid_login" - - -async def test_flow_invalid_2fa(hass, aioclient_mock): - """Test config flow with 2fa.""" - from homeassistant.components.hangouts.hangups_utils import Google2FAError - - flow = config_flow.HangoutsFlowHandler() - - flow.hass = hass - - with patch( - "homeassistant.components.hangouts.config_flow.get_auth", - side_effect=Google2FAError, - ): - result = await flow.async_step_user( - {CONF_EMAIL: EMAIL, CONF_PASSWORD: PASSWORD} - ) - assert result["type"] == data_entry_flow.FlowResultType.FORM - assert result["step_id"] == "2fa" - - with patch( - "homeassistant.components.hangouts.config_flow.get_auth", - side_effect=Google2FAError, - ): - result = await flow.async_step_2fa({"2fa": 123456}) - - assert result["type"] == data_entry_flow.FlowResultType.FORM - assert result["errors"]["base"] == "invalid_2fa"