Buckets:
| """HACS gives you a powerful UI to handle downloads of all your custom needs. | |
| For more details about this integration, please refer to the documentation at | |
| https://hacs.xyz/ | |
| """ | |
| from __future__ import annotations | |
| from aiogithubapi import AIOGitHubAPIException, GitHub, GitHubAPI | |
| from aiogithubapi.const import ACCEPT_HEADERS | |
| from awesomeversion import AwesomeVersion | |
| from homeassistant.components.frontend import async_remove_panel | |
| from homeassistant.components.lovelace.system_health import system_health_info | |
| from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry | |
| from homeassistant.const import Platform, __version__ as HAVERSION | |
| from homeassistant.core import HomeAssistant | |
| from homeassistant.helpers.aiohttp_client import async_get_clientsession | |
| from homeassistant.helpers.entity_registry import async_get as async_get_entity_registry | |
| from homeassistant.helpers.event import async_call_later | |
| from homeassistant.helpers.start import async_at_start | |
| from homeassistant.loader import async_get_integration | |
| from .base import HacsBase | |
| from .const import DOMAIN, HACS_SYSTEM_ID, MINIMUM_HA_VERSION, STARTUP | |
| from .data_client import HacsDataClient | |
| from .enums import HacsDisabledReason, HacsStage, LovelaceMode | |
| from .frontend import async_register_frontend | |
| from .utils.data import HacsData | |
| from .utils.queue_manager import QueueManager | |
| from .utils.version import version_left_higher_or_equal_then_right | |
| from .websocket import async_register_websocket_commands | |
| PLATFORMS = [Platform.SWITCH, Platform.UPDATE] | |
| async def _async_initialize_integration( | |
| hass: HomeAssistant, | |
| config_entry: ConfigEntry, | |
| ) -> bool: | |
| """Initialize the integration""" | |
| hass.data[DOMAIN] = hacs = HacsBase() | |
| hacs.enable_hacs() | |
| if config_entry.source == SOURCE_IMPORT: | |
| # Import is not supported | |
| hass.async_create_task(hass.config_entries.async_remove(config_entry.entry_id)) | |
| return False | |
| hacs.configuration.update_from_dict( | |
| { | |
| "config_entry": config_entry, | |
| **config_entry.data, | |
| **config_entry.options, | |
| }, | |
| ) | |
| integration = await async_get_integration(hass, DOMAIN) | |
| hacs.set_stage(None) | |
| hacs.log.info(STARTUP, integration.version) | |
| clientsession = async_get_clientsession(hass) | |
| hacs.integration = integration | |
| hacs.version = integration.version | |
| hacs.configuration.dev = integration.version == "0.0.0" | |
| hacs.hass = hass | |
| hacs.queue = QueueManager(hass=hass) | |
| hacs.data = HacsData(hacs=hacs) | |
| hacs.data_client = HacsDataClient( | |
| session=clientsession, | |
| client_name=f"HACS/{integration.version}", | |
| ) | |
| hacs.system.running = True | |
| hacs.session = clientsession | |
| 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 BaseException: # lgtm [py/catch-base-exception] pylint: disable=broad-except | |
| # If this happens, the users YAML is not valid, we assume YAML mode | |
| pass | |
| hacs.core.config_path = hacs.hass.config.path() | |
| if hacs.core.ha_version is None: | |
| hacs.core.ha_version = AwesomeVersion(HAVERSION) | |
| ## Legacy GitHub client | |
| hacs.github = GitHub( | |
| hacs.configuration.token, | |
| clientsession, | |
| headers={ | |
| "User-Agent": f"HACS/{hacs.version}", | |
| "Accept": ACCEPT_HEADERS["preview"], | |
| }, | |
| ) | |
| ## New GitHub client | |
| hacs.githubapi = GitHubAPI( | |
| token=hacs.configuration.token, | |
| session=clientsession, | |
| **{"client_name": f"HACS/{hacs.version}"}, | |
| ) | |
| async def async_startup(): | |
| """HACS startup tasks.""" | |
| hacs.enable_hacs() | |
| try: | |
| import custom_components.custom_updater | |
| except ImportError: | |
| pass | |
| else: | |
| hacs.log.critical( | |
| "HACS cannot be used with custom_updater. " | |
| "To use HACS you need to remove custom_updater from `custom_components`", | |
| ) | |
| hacs.disable_hacs(HacsDisabledReason.CONSTRAINS) | |
| return False | |
| if not version_left_higher_or_equal_then_right( | |
| hacs.core.ha_version.string, | |
| MINIMUM_HA_VERSION, | |
| ): | |
| hacs.log.critical( | |
| "You need HA version %s or newer to use this integration.", | |
| MINIMUM_HA_VERSION, | |
| ) | |
| hacs.disable_hacs(HacsDisabledReason.CONSTRAINS) | |
| return False | |
| if not await hacs.data.restore(): | |
| hacs.disable_hacs(HacsDisabledReason.RESTORE) | |
| return False | |
| hacs.set_active_categories() | |
| async_register_websocket_commands(hass) | |
| await async_register_frontend(hass, hacs) | |
| await hass.config_entries.async_forward_entry_setups(config_entry, PLATFORMS) | |
| hacs.set_stage(HacsStage.SETUP) | |
| if hacs.system.disabled: | |
| return False | |
| hacs.set_stage(HacsStage.WAITING) | |
| hacs.log.info("Setup complete, waiting for Home Assistant before startup tasks starts") | |
| # Schedule startup tasks | |
| async_at_start(hass=hass, at_start_cb=hacs.startup_tasks) | |
| return not hacs.system.disabled | |
| async def async_try_startup(_=None): | |
| """Startup wrapper for yaml config.""" | |
| try: | |
| startup_result = await async_startup() | |
| except AIOGitHubAPIException: | |
| startup_result = False | |
| if not startup_result: | |
| if hacs.system.disabled_reason != HacsDisabledReason.INVALID_TOKEN: | |
| hacs.log.info("Could not setup HACS, trying again in 15 min") | |
| async_call_later(hass, 900, async_try_startup) | |
| return | |
| hacs.enable_hacs() | |
| await async_try_startup() | |
| # Remove old (v0-v1) sensor if it exists, can be removed in v3 | |
| er = async_get_entity_registry(hass) | |
| if old_sensor := er.async_get_entity_id("sensor", DOMAIN, HACS_SYSTEM_ID): | |
| er.async_remove(old_sensor) | |
| # Mischief managed! | |
| return True | |
| async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool: | |
| """Set up this integration using UI.""" | |
| config_entry.async_on_unload(config_entry.add_update_listener(async_reload_entry)) | |
| setup_result = await _async_initialize_integration(hass=hass, config_entry=config_entry) | |
| hacs: HacsBase = hass.data[DOMAIN] | |
| return setup_result and not hacs.system.disabled | |
| async def async_unload_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool: | |
| """Handle removal of an entry.""" | |
| hacs: HacsBase = hass.data[DOMAIN] | |
| if hacs.queue.has_pending_tasks: | |
| hacs.log.warning("Pending tasks, can not unload, try again later.") | |
| return False | |
| # Clear out pending queue | |
| hacs.queue.clear() | |
| for task in hacs.recurring_tasks: | |
| # Cancel all pending tasks | |
| task() | |
| # Store data | |
| await hacs.data.async_write(force=True) | |
| try: | |
| if hass.data.get("frontend_panels", {}).get("hacs"): | |
| hacs.log.info("Removing sidepanel") | |
| async_remove_panel(hass, "hacs") | |
| except AttributeError: | |
| pass | |
| unload_ok = await hass.config_entries.async_unload_platforms(config_entry, PLATFORMS) | |
| hacs.set_stage(None) | |
| hacs.disable_hacs(HacsDisabledReason.REMOVED) | |
| hass.data.pop(DOMAIN, None) | |
| return unload_ok | |
| async def async_reload_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> None: | |
| """Reload the HACS config entry.""" | |
| if not await async_unload_entry(hass, config_entry): | |
| return | |
| await async_setup_entry(hass, config_entry) | |
Xet Storage Details
- Size:
- 7.69 kB
- Xet hash:
- 5bb738aec44af6fdb1510e3922df13a63cbbafedb0dbb65b9bb2221b65b6fc5d
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.