67 lines
2.3 KiB
Python
67 lines
2.3 KiB
Python
"""Spook - Your homie."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import asyncio
|
|
from typing import TYPE_CHECKING
|
|
|
|
import aiohttp
|
|
import voluptuous as vol
|
|
|
|
from homeassistant.components.blueprint import DOMAIN
|
|
from homeassistant.components.blueprint.errors import FileAlreadyExists
|
|
from homeassistant.components.blueprint.importer import fetch_blueprint_from_url
|
|
from homeassistant.exceptions import HomeAssistantError
|
|
from homeassistant.helpers import config_validation as cv
|
|
|
|
from ....services import AbstractSpookAdminService
|
|
|
|
if TYPE_CHECKING:
|
|
from homeassistant.components.blueprint.models import DomainBlueprints
|
|
from homeassistant.core import ServiceCall
|
|
|
|
|
|
class SpookService(AbstractSpookAdminService):
|
|
"""Blueprint integration service to import an Blueprint from an URL."""
|
|
|
|
domain = DOMAIN
|
|
service = "import"
|
|
schema = {vol.Required("url"): cv.url}
|
|
|
|
async def async_handle_service(self, call: ServiceCall) -> None:
|
|
"""Handle the service call."""
|
|
try:
|
|
async with asyncio.timeout(10):
|
|
imported_blueprint = await fetch_blueprint_from_url(
|
|
self.hass,
|
|
call.data["url"],
|
|
)
|
|
except (TimeoutError, aiohttp.ClientError) as err:
|
|
msg = "Error fetching blueprint from URL"
|
|
raise HomeAssistantError(msg) from err
|
|
|
|
if imported_blueprint is None:
|
|
msg = "This url is not supported"
|
|
raise HomeAssistantError(msg)
|
|
|
|
domain_blueprints: dict[str, DomainBlueprints] = self.hass.data.get(DOMAIN, {})
|
|
if imported_blueprint.blueprint.domain not in domain_blueprints:
|
|
msg = f"Unsupported domain: {imported_blueprint.blueprint.domain}"
|
|
raise HomeAssistantError(msg)
|
|
|
|
imported_blueprint.blueprint.update_metadata(source_url=call.data["url"])
|
|
|
|
try:
|
|
await domain_blueprints[
|
|
imported_blueprint.blueprint.domain
|
|
].async_add_blueprint(
|
|
imported_blueprint.blueprint,
|
|
imported_blueprint.suggested_filename,
|
|
)
|
|
except FileAlreadyExists as ex:
|
|
msg = "File already exists"
|
|
raise HomeAssistantError(msg) from ex
|
|
except OSError as err:
|
|
msg = "Error writing file"
|
|
raise HomeAssistantError(msg) from err
|