Update HACS to 1.33.0

This commit is contained in:
root
2023-11-02 06:16:52 -07:00
parent efe293b40b
commit b8fc375552
7 changed files with 97 additions and 23 deletions

View File

@@ -19,6 +19,7 @@ from homeassistant.core import HomeAssistant
from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.helpers.discovery import async_load_platform from homeassistant.helpers.discovery import async_load_platform
from homeassistant.helpers.event import async_call_later from homeassistant.helpers.event import async_call_later
from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue
from homeassistant.helpers.start import async_at_start from homeassistant.helpers.start import async_at_start
from homeassistant.loader import async_get_integration from homeassistant.loader import async_get_integration
import voluptuous as vol import voluptuous as vol
@@ -30,6 +31,7 @@ from .enums import ConfigurationType, HacsDisabledReason, HacsStage, LovelaceMod
from .frontend import async_register_frontend from .frontend import async_register_frontend
from .utils.configuration_schema import hacs_config_combined from .utils.configuration_schema import hacs_config_combined
from .utils.data import HacsData from .utils.data import HacsData
from .utils.logger import LOGGER
from .utils.queue_manager import QueueManager from .utils.queue_manager import QueueManager
from .utils.version import version_left_higher_or_equal_then_right from .utils.version import version_left_higher_or_equal_then_right
from .websocket import async_register_websocket_commands from .websocket import async_register_websocket_commands
@@ -217,6 +219,24 @@ async def async_initialize_integration(
async def async_setup(hass: HomeAssistant, config: dict[str, Any]) -> bool: async def async_setup(hass: HomeAssistant, config: dict[str, Any]) -> bool:
"""Set up this integration using yaml.""" """Set up this integration using yaml."""
if DOMAIN in config:
async_create_issue(
hass,
DOMAIN,
"deprecated_yaml_configuration",
is_fixable=False,
issue_domain=DOMAIN,
severity=IssueSeverity.WARNING,
translation_key="deprecated_yaml_configuration",
learn_more_url="https://hacs.xyz/docs/configuration/options",
)
LOGGER.warning(
"YAML configuration of HACS is deprecated and will be "
"removed in version 2.0.0, there will be no automatic "
"import of this. "
"Please remove it from your configuration, "
"restart Home Assistant and use the UI to configure it instead."
)
return await async_initialize_integration(hass=hass, config=config) return await async_initialize_integration(hass=hass, config=config)
@@ -232,6 +252,10 @@ async def async_unload_entry(hass: HomeAssistant, config_entry: ConfigEntry) ->
"""Handle removal of an entry.""" """Handle removal of an entry."""
hacs: HacsBase = hass.data[DOMAIN] 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 # Clear out pending queue
hacs.queue.clear() hacs.queue.clear()
@@ -265,5 +289,6 @@ async def async_unload_entry(hass: HomeAssistant, config_entry: ConfigEntry) ->
async def async_reload_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> None: async def async_reload_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> None:
"""Reload the HACS config entry.""" """Reload the HACS config entry."""
await async_unload_entry(hass, config_entry) if not await async_unload_entry(hass, config_entry):
return
await async_setup_entry(hass, config_entry) await async_setup_entry(hass, config_entry)

View File

@@ -1,4 +1,8 @@
"""Adds config flow for HACS.""" """Adds config flow for HACS."""
from __future__ import annotations
from typing import TYPE_CHECKING
from aiogithubapi import GitHubDeviceAPI, GitHubException from aiogithubapi import GitHubDeviceAPI, GitHubException
from aiogithubapi.common.const import OAUTH_USER_LOGIN from aiogithubapi.common.const import OAUTH_USER_LOGIN
from awesomeversion import AwesomeVersion from awesomeversion import AwesomeVersion
@@ -11,15 +15,29 @@ from homeassistant.loader import async_get_integration
import voluptuous as vol import voluptuous as vol
from .base import HacsBase from .base import HacsBase
from .const import CLIENT_ID, DOMAIN, MINIMUM_HA_VERSION from .const import CLIENT_ID, DOMAIN, LOCALE, MINIMUM_HA_VERSION
from .enums import ConfigurationType from .enums import ConfigurationType
from .utils.configuration_schema import RELEASE_LIMIT, hacs_config_option_schema from .utils.configuration_schema import (
APPDAEMON,
COUNTRY,
DEBUG,
EXPERIMENTAL,
NETDAEMON,
RELEASE_LIMIT,
SIDEPANEL_ICON,
SIDEPANEL_TITLE,
)
from .utils.logger import LOGGER from .utils.logger import LOGGER
if TYPE_CHECKING:
from homeassistant.core import HomeAssistant
class HacsFlowHandler(config_entries.ConfigFlow, domain=DOMAIN): class HacsFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
"""Config flow for HACS.""" """Config flow for HACS."""
hass: HomeAssistant
VERSION = 1 VERSION = 1
CONNECTION_CLASS = config_entries.CONN_CLASS_CLOUD_POLL CONNECTION_CLASS = config_entries.CONN_CLASS_CLOUD_POLL
@@ -32,6 +50,7 @@ class HacsFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
self._progress_task = None self._progress_task = None
self._login_device = None self._login_device = None
self._reauth = False self._reauth = False
self._user_input = {}
async def async_step_user(self, user_input): async def async_step_user(self, user_input):
"""Handle a flow initialized by the user.""" """Handle a flow initialized by the user."""
@@ -42,10 +61,12 @@ class HacsFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
return self.async_abort(reason="single_instance_allowed") return self.async_abort(reason="single_instance_allowed")
if user_input: if user_input:
if [x for x in user_input if not user_input[x]]: if [x for x in user_input if x.startswith("acc_") and not user_input[x]]:
self._errors["base"] = "acc" self._errors["base"] = "acc"
return await self._show_config_form(user_input) return await self._show_config_form(user_input)
self._user_input = user_input
return await self.async_step_device(user_input) return await self.async_step_device(user_input)
## Initial form ## Initial form
@@ -112,24 +133,35 @@ class HacsFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
"acc_untested", default=user_input.get("acc_untested", False) "acc_untested", default=user_input.get("acc_untested", False)
): bool, ): bool,
vol.Required("acc_disable", default=user_input.get("acc_disable", False)): bool, vol.Required("acc_disable", default=user_input.get("acc_disable", False)): bool,
vol.Optional(
"experimental", default=user_input.get("experimental", False)
): bool,
} }
), ),
errors=self._errors, errors=self._errors,
) )
async def async_step_device_done(self, _user_input): async def async_step_device_done(self, user_input: dict[str, bool] | None = None):
"""Handle device steps""" """Handle device steps"""
if self._reauth: if self._reauth:
existing_entry = self.hass.config_entries.async_get_entry(self.context["entry_id"]) existing_entry = self.hass.config_entries.async_get_entry(self.context["entry_id"])
self.hass.config_entries.async_update_entry( self.hass.config_entries.async_update_entry(
existing_entry, data={"token": self.activation.access_token} existing_entry, data={**existing_entry.data, "token": self.activation.access_token}
) )
await self.hass.config_entries.async_reload(existing_entry.entry_id) await self.hass.config_entries.async_reload(existing_entry.entry_id)
return self.async_abort(reason="reauth_successful") return self.async_abort(reason="reauth_successful")
return self.async_create_entry(title="", data={"token": self.activation.access_token}) return self.async_create_entry(
title="",
data={
"token": self.activation.access_token,
},
options={
"experimental": self._user_input.get("experimental", False),
},
)
async def async_step_reauth(self, user_input=None): async def async_step_reauth(self, _user_input=None):
"""Perform reauth upon an API authentication error.""" """Perform reauth upon an API authentication error."""
return await self.async_step_reauth_confirm() return await self.async_step_reauth_confirm()
@@ -172,11 +204,21 @@ class HacsOptionsFlowHandler(config_entries.OptionsFlow):
if hacs is None or hacs.configuration is None: if hacs is None or hacs.configuration is None:
return self.async_abort(reason="not_setup") return self.async_abort(reason="not_setup")
if hacs.queue.has_pending_tasks:
return self.async_abort(reason="pending_tasks")
if hacs.configuration.config_type == ConfigurationType.YAML: if hacs.configuration.config_type == ConfigurationType.YAML:
schema = {vol.Optional("not_in_use", default=""): str} schema = {vol.Optional("not_in_use", default=""): str}
else: else:
schema = hacs_config_option_schema(self.config_entry.options) schema = {
del schema["frontend_repo"] vol.Optional(SIDEPANEL_TITLE, default=hacs.configuration.sidepanel_title): str,
del schema["frontend_repo_url"] vol.Optional(SIDEPANEL_ICON, default=hacs.configuration.sidepanel_icon): str,
vol.Optional(RELEASE_LIMIT, default=hacs.configuration.release_limit): int,
vol.Optional(COUNTRY, default=hacs.configuration.country): vol.In(LOCALE),
vol.Optional(APPDAEMON, default=hacs.configuration.appdaemon): bool,
vol.Optional(NETDAEMON, default=hacs.configuration.netdaemon): bool,
vol.Optional(DEBUG, default=hacs.configuration.debug): bool,
vol.Optional(EXPERIMENTAL, default=hacs.configuration.experimental): bool,
}
return self.async_show_form(step_id="user", data_schema=vol.Schema(schema)) return self.async_show_form(step_id="user", data_schema=vol.Schema(schema))

View File

@@ -6,7 +6,7 @@ from aiogithubapi.common.const import ACCEPT_HEADERS
NAME_SHORT = "HACS" NAME_SHORT = "HACS"
DOMAIN = "hacs" DOMAIN = "hacs"
CLIENT_ID = "395a8e669c5de9f7c6e8" CLIENT_ID = "395a8e669c5de9f7c6e8"
MINIMUM_HA_VERSION = "2022.11.0" MINIMUM_HA_VERSION = "2023.6.0"
URL_BASE = "/hacsfiles" URL_BASE = "/hacsfiles"

View File

@@ -19,5 +19,5 @@
"requirements": [ "requirements": [
"aiogithubapi>=22.10.1" "aiogithubapi>=22.10.1"
], ],
"version": "1.32.1" "version": "1.33.0"
} }

View File

@@ -16,8 +16,9 @@
"data": { "data": {
"acc_logs": "I know how to access Home Assistant logs", "acc_logs": "I know how to access Home Assistant logs",
"acc_addons": "I know that there are no add-ons in HACS", "acc_addons": "I know that there are no add-ons in HACS",
"acc_untested": "I know that everything inside HACS is custom and untested by Home Assistant", "acc_untested": "I know that everything inside HACS including HACS itself is custom and untested by Home Assistant",
"acc_disable": "I know that if I get issues with Home Assistant I should disable all my custom_components" "acc_disable": "I know that if I get issues with Home Assistant I should disable all my custom_components",
"experimental": "Enable experimental features, this is what eventually will become HACS 2.0.0, if you enable it now you do not need to do anything when 2.0.0 is released"
}, },
"description": "Before you can setup HACS you need to acknowledge the following" "description": "Before you can setup HACS you need to acknowledge the following"
}, },
@@ -30,22 +31,23 @@
} }
}, },
"progress": { "progress": {
"wait_for_device": "1. Open {url} \n2.Paste the following key to authorize HACS: \n```\n{code}\n```\n" "wait_for_device": "1. Open {url} \n2. Paste the following key to authorize HACS: \n```\n{code}\n```\n"
} }
}, },
"options": { "options": {
"abort": { "abort": {
"not_setup": "HACS is not setup.", "not_setup": "HACS is not setup.",
"release_limit_value": "The release limit needs to be between 1 and 100" "pending_tasks": "There are pending tasks. Try again later.",
"release_limit_value": "The release limit needs to be between 1 and 100."
}, },
"step": { "step": {
"user": { "user": {
"data": { "data": {
"not_in_use": "Not in use with YAML", "not_in_use": "Not in use with YAML",
"country": "Filter with country code.", "country": "Filter with country code",
"experimental": "Enable experimental features", "experimental": "Enable experimental features",
"release_limit": "Number of releases to show.", "release_limit": "Number of releases to show",
"debug": "Enable debug.", "debug": "Enable debug",
"appdaemon": "Enable AppDaemon apps discovery & tracking", "appdaemon": "Enable AppDaemon apps discovery & tracking",
"netdaemon": "[DEPRECATED] Enable NetDaemon apps discovery & tracking", "netdaemon": "[DEPRECATED] Enable NetDaemon apps discovery & tracking",
"sidepanel_icon": "Side panel icon", "sidepanel_icon": "Side panel icon",
@@ -68,7 +70,11 @@
}, },
"removed": { "removed": {
"title": "Repository removed from HACS", "title": "Repository removed from HACS",
"description": "Because {reason}, '{name}' has been removed from HACS. Please visit the [HACS Panel](/hacs/repository/{repositry_id}) to remove it." "description": "Because {reason}, `{name}` has been removed from HACS. Please visit the [HACS Panel](/hacs/repository/{repositry_id}) to remove it."
},
"deprecated_yaml_configuration": {
"title": "YAML configuration is deprecated",
"description": "YAML configuration of HACS is deprecated and will be removed in version 2.0.0, there will be no automatic import of this.\nPlease remove it from your configuration, restart Home Assistant and use the UI to configure it instead."
} }
} }
} }

View File

@@ -286,6 +286,7 @@ class HacsData:
repository.data.last_updated = repository_data.get("last_updated", 0) repository.data.last_updated = repository_data.get("last_updated", 0)
if self.hacs.system.generator: if self.hacs.system.generator:
repository.data.etag_releases = repository_data.get("etag_releases") repository.data.etag_releases = repository_data.get("etag_releases")
repository.data.open_issues = repository_data.get("open_issues", 0)
repository.data.etag_repository = repository_data.get("etag_repository") repository.data.etag_repository = repository_data.get("etag_repository")
repository.data.topics = [ repository.data.topics = [
topic for topic in repository_data.get("topics", []) if topic not in TOPIC_FILTER topic for topic in repository_data.get("topics", []) if topic not in TOPIC_FILTER

File diff suppressed because one or more lines are too long