mirror of https://github.com/home-assistant/core
130 lines
4.2 KiB
Python
130 lines
4.2 KiB
Python
"""Repairs implementation for the cloud integration."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import asyncio
|
|
from typing import Any
|
|
|
|
import voluptuous as vol
|
|
|
|
from homeassistant.components.repairs import (
|
|
ConfirmRepairFlow,
|
|
RepairsFlow,
|
|
repairs_flow_manager,
|
|
)
|
|
from homeassistant.core import HomeAssistant, callback
|
|
from homeassistant.data_entry_flow import FlowResult
|
|
from homeassistant.helpers import issue_registry as ir
|
|
|
|
from .const import DATA_CLOUD, DOMAIN
|
|
from .subscription import async_migrate_paypal_agreement, async_subscription_info
|
|
|
|
BACKOFF_TIME = 5
|
|
MAX_RETRIES = 60 # This allows for 10 minutes of retries
|
|
|
|
|
|
@callback
|
|
def async_manage_legacy_subscription_issue(
|
|
hass: HomeAssistant,
|
|
subscription_info: dict[str, Any],
|
|
) -> None:
|
|
"""Manage the legacy subscription issue.
|
|
|
|
If the provider is "legacy" create an issue,
|
|
in all other cases remove the issue.
|
|
"""
|
|
if subscription_info.get("provider") == "legacy":
|
|
ir.async_create_issue(
|
|
hass=hass,
|
|
domain=DOMAIN,
|
|
issue_id="legacy_subscription",
|
|
is_fixable=True,
|
|
severity=ir.IssueSeverity.WARNING,
|
|
translation_key="legacy_subscription",
|
|
)
|
|
return
|
|
ir.async_delete_issue(hass=hass, domain=DOMAIN, issue_id="legacy_subscription")
|
|
|
|
|
|
class LegacySubscriptionRepairFlow(RepairsFlow):
|
|
"""Handler for an issue fixing flow."""
|
|
|
|
wait_task: asyncio.Task | None = None
|
|
_data: dict[str, Any] | None = None
|
|
|
|
async def async_step_init(self, _: None = None) -> FlowResult:
|
|
"""Handle the first step of a fix flow."""
|
|
return await self.async_step_confirm_change_plan()
|
|
|
|
async def async_step_confirm_change_plan(
|
|
self,
|
|
user_input: dict[str, str] | None = None,
|
|
) -> FlowResult:
|
|
"""Handle the confirm step of a fix flow."""
|
|
if user_input is not None:
|
|
return await self.async_step_change_plan()
|
|
|
|
return self.async_show_form(
|
|
step_id="confirm_change_plan", data_schema=vol.Schema({})
|
|
)
|
|
|
|
async def async_step_change_plan(self, _: None = None) -> FlowResult:
|
|
"""Wait for the user to authorize the app installation."""
|
|
|
|
cloud = self.hass.data[DATA_CLOUD]
|
|
|
|
async def _async_wait_for_plan_change() -> None:
|
|
flow_manager = repairs_flow_manager(self.hass)
|
|
# We cannot get here without a flow manager
|
|
assert flow_manager is not None
|
|
|
|
retries = 0
|
|
while retries < MAX_RETRIES:
|
|
self._data = await async_subscription_info(cloud)
|
|
if self._data is not None and self._data["provider"] != "legacy":
|
|
break
|
|
|
|
retries += 1
|
|
await asyncio.sleep(BACKOFF_TIME)
|
|
|
|
self.hass.async_create_task(
|
|
flow_manager.async_configure(flow_id=self.flow_id)
|
|
)
|
|
|
|
if not self.wait_task:
|
|
self.wait_task = self.hass.async_create_task(
|
|
_async_wait_for_plan_change(), eager_start=False
|
|
)
|
|
migration = await async_migrate_paypal_agreement(cloud)
|
|
return self.async_external_step(
|
|
step_id="change_plan",
|
|
url=migration["url"] if migration else "https://account.nabucasa.com/",
|
|
)
|
|
|
|
await self.wait_task
|
|
|
|
if self._data is None or self._data["provider"] == "legacy":
|
|
# If we get here we waited too long.
|
|
return self.async_external_step_done(next_step_id="timeout")
|
|
|
|
return self.async_external_step_done(next_step_id="complete")
|
|
|
|
async def async_step_complete(self, _: None = None) -> FlowResult:
|
|
"""Handle the final step of a fix flow."""
|
|
return self.async_create_entry(data={})
|
|
|
|
async def async_step_timeout(self, _: None = None) -> FlowResult:
|
|
"""Handle the final step of a fix flow."""
|
|
return self.async_abort(reason="operation_took_too_long")
|
|
|
|
|
|
async def async_create_fix_flow(
|
|
hass: HomeAssistant,
|
|
issue_id: str,
|
|
data: dict[str, str | int | float | None] | None,
|
|
) -> RepairsFlow:
|
|
"""Create flow."""
|
|
if issue_id == "legacy_subscription":
|
|
return LegacySubscriptionRepairFlow()
|
|
return ConfirmRepairFlow()
|