Files
homeAssistant/custom_components/hacs/operational/setup.py
2021-11-04 01:18:18 -04:00

174 lines
5.3 KiB
Python

"""Setup HACS."""
from aiogithubapi import AIOGitHubAPIException, GitHub, GitHubAPI
from aiogithubapi.const import ACCEPT_HEADERS
from homeassistant.components.lovelace.system_health import system_health_info
from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry
from homeassistant.const import EVENT_HOMEASSISTANT_STARTED, __version__ as HAVERSION
from homeassistant.core import CoreState, HomeAssistant
from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.helpers.aiohttp_client import async_create_clientsession
from homeassistant.helpers.event import async_call_later
from homeassistant.loader import async_get_integration
from custom_components.hacs.const import DOMAIN, STARTUP
from custom_components.hacs.enums import (
ConfigurationType,
HacsStage,
LovelaceMode,
)
from custom_components.hacs.hacsbase.data import HacsData
from custom_components.hacs.share import get_hacs
from custom_components.hacs.tasks.manager import HacsTaskManager
async def _async_common_setup(hass: HomeAssistant):
"""Common setup stages."""
integration = await async_get_integration(hass, DOMAIN)
hacs = get_hacs()
hacs.enable_hacs()
await hacs.async_set_stage(None)
hacs.log.info(STARTUP.format(version=integration.version))
hacs.integration = integration
hacs.version = integration.version
hacs.hass = hass
hacs.data = HacsData()
hacs.system.running = True
hacs.session = async_create_clientsession(hass)
hacs.tasks = HacsTaskManager(hacs=hacs, hass=hass)
hacs.core.lovelace_mode = LovelaceMode.YAML
try:
lovelace_info = await system_health_info(hacs.hass)
hacs.core.lovelace_mode = LovelaceMode(lovelace_info.get("mode", "yaml"))
except Exception: # pylint: disable=broad-except
# If this happens, the users YAML is not valid, we assume YAML mode
pass
hacs.log.debug(f"Configuration type: {hacs.configuration.config_type}")
hacs.core.config_path = hacs.hass.config.path()
hacs.core.ha_version = HAVERSION
await hacs.tasks.async_load()
# Setup session for API clients
session = async_create_clientsession(hacs.hass)
## Legacy GitHub client
hacs.github = GitHub(
hacs.configuration.token,
session,
headers={
"User-Agent": f"HACS/{hacs.version}",
"Accept": ACCEPT_HEADERS["preview"],
},
)
## New GitHub client
hacs.githubapi = GitHubAPI(
token=hacs.configuration.token,
session=session,
**{"client_name": f"HACS/{hacs.version}"},
)
hass.data[DOMAIN] = hacs
async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool:
"""Set up this integration using UI."""
hacs = get_hacs()
if config_entry.source == SOURCE_IMPORT:
hass.async_create_task(hass.config_entries.async_remove(config_entry.entry_id))
return False
if hass.data.get(DOMAIN) is not None:
return False
hacs.configuration.update_from_dict(
{
"config_entry": config_entry,
"config_type": ConfigurationType.CONFIG_ENTRY,
**config_entry.data,
**config_entry.options,
}
)
await _async_common_setup(hass)
return await async_startup_wrapper_for_config_entry()
async def async_setup(hass, config):
"""Set up this integration using yaml."""
hacs = get_hacs()
if DOMAIN not in config:
return True
if hacs.configuration.config_type == ConfigurationType.CONFIG_ENTRY:
return True
hacs.configuration.update_from_dict(
{
"config_type": ConfigurationType.YAML,
**config[DOMAIN],
"config": config[DOMAIN],
}
)
await _async_common_setup(hass)
await async_startup_wrapper_for_yaml()
return True
async def async_startup_wrapper_for_config_entry():
"""Startup wrapper for ui config."""
hacs = get_hacs()
try:
startup_result = await async_hacs_startup()
except AIOGitHubAPIException:
startup_result = False
if not startup_result:
raise ConfigEntryNotReady(hacs.system.disabled_reason)
hacs.enable_hacs()
return startup_result
async def async_startup_wrapper_for_yaml(_=None):
"""Startup wrapper for yaml config."""
hacs = get_hacs()
try:
startup_result = await async_hacs_startup()
except AIOGitHubAPIException:
startup_result = False
if not startup_result:
hacs.log.info("Could not setup HACS, trying again in 15 min")
async_call_later(hacs.hass, 900, async_startup_wrapper_for_yaml)
return
hacs.enable_hacs()
async def async_hacs_startup():
"""HACS startup tasks."""
hacs = get_hacs()
await hacs.async_set_stage(HacsStage.SETUP)
if hacs.system.disabled:
return False
await hacs.async_set_stage(HacsStage.STARTUP)
if hacs.system.disabled:
return False
# Setup startup tasks
if hacs.hass.state == CoreState.running:
async_call_later(hacs.hass, 5, hacs.startup_tasks)
else:
hacs.hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STARTED, hacs.startup_tasks)
# Mischief managed!
await hacs.async_set_stage(HacsStage.WAITING)
hacs.log.info("Setup complete, waiting for Home Assistant before startup tasks starts")
return not hacs.system.disabled