Update HACS

This commit is contained in:
root
2023-04-13 05:55:06 -07:00
parent 80dbf737ee
commit df90dcc6cb
9 changed files with 49 additions and 57 deletions

View File

@@ -160,9 +160,9 @@ class HacsCommon:
categories: set[str] = field(default_factory=set)
renamed_repositories: dict[str, str] = field(default_factory=dict)
archived_repositories: list[str] = field(default_factory=list)
ignored_repositories: list[str] = field(default_factory=list)
skip: list[str] = field(default_factory=list)
archived_repositories: set[str] = field(default_factory=set)
ignored_repositories: set[str] = field(default_factory=set)
skip: set[str] = field(default_factory=set)
@dataclass
@@ -197,20 +197,20 @@ class HacsRepositories:
"""HACS Repositories."""
_default_repositories: set[str] = field(default_factory=set)
_repositories: list[HacsRepository] = field(default_factory=list)
_repositories: set[HacsRepository] = field(default_factory=set)
_repositories_by_full_name: dict[str, HacsRepository] = field(default_factory=dict)
_repositories_by_id: dict[str, HacsRepository] = field(default_factory=dict)
_removed_repositories: list[RemovedRepository] = field(default_factory=list)
_removed_repositories_by_full_name: dict[str, RemovedRepository] = field(default_factory=dict)
@property
def list_all(self) -> list[HacsRepository]:
"""Return a list of repositories."""
return self._repositories
return list(self._repositories)
@property
def list_removed(self) -> list[RemovedRepository]:
"""Return a list of removed repositories."""
return self._removed_repositories
return list(self._removed_repositories_by_full_name.values())
@property
def list_downloaded(self) -> list[HacsRepository]:
@@ -235,7 +235,7 @@ class HacsRepositories:
repository = registered_repo
if repository not in self._repositories:
self._repositories.append(repository)
self._repositories.add(repository)
self._repositories_by_id[repo_id] = repository
self._repositories_by_full_name[repository.data.full_name_lower] = repository
@@ -333,22 +333,15 @@ class HacsRepositories:
def is_removed(self, repository_full_name: str) -> bool:
"""Check if a repository is removed."""
return repository_full_name in (
repository.repository for repository in self._removed_repositories
)
return repository_full_name in self._removed_repositories_by_full_name
def removed_repository(self, repository_full_name: str) -> RemovedRepository:
"""Get repository by full name."""
if self.is_removed(repository_full_name):
if removed := [
repository
for repository in self._removed_repositories
if repository.repository == repository_full_name
]:
return removed[0]
if removed := self._removed_repositories_by_full_name.get(repository_full_name):
return removed
removed = RemovedRepository(repository=repository_full_name)
self._removed_repositories.append(removed)
self._removed_repositories_by_full_name[repository_full_name] = removed
return removed
@@ -553,7 +546,12 @@ class HacsBase:
raise AddonRepositoryException()
if category not in RERPOSITORY_CLASSES:
raise HacsException(f"{category} is not a valid repository category.")
self.log.warning(
"%s is not a valid repository category, %s will not be registered.",
category,
repository_full_name,
)
return
if (renamed := self.common.renamed_repositories.get(repository_full_name)) is not None:
repository_full_name = renamed
@@ -563,7 +561,7 @@ class HacsBase:
try:
await repository.async_registration(ref)
if repository.validate.errors:
self.common.skip.append(repository.data.full_name)
self.common.skip.add(repository.data.full_name)
if not self.status.startup:
self.log.error("Validation for %s failed.", repository_full_name)
if self.system.action:
@@ -582,7 +580,7 @@ class HacsBase:
)
return
except AIOGitHubAPIException as exception:
self.common.skip.append(repository.data.full_name)
self.common.skip.add(repository.data.full_name)
raise HacsException(
f"Validation for {repository_full_name} failed with {exception}."
) from exception
@@ -765,6 +763,9 @@ class HacsBase:
for category in (HacsCategory.INTEGRATION, HacsCategory.PLUGIN):
self.enable_hacs_category(HacsCategory(category))
if self.configuration.experimental and self.core.ha_version >= "2023.4.0b0":
self.enable_hacs_category(HacsCategory.TEMPLATE)
if HacsCategory.PYTHON_SCRIPT in self.hass.config.components:
self.enable_hacs_category(HacsCategory.PYTHON_SCRIPT)

View File

@@ -31,6 +31,7 @@ class HacsCategory(StrEnum):
PLUGIN = "plugin" # Kept for legacy purposes
NETDAEMON = "netdaemon"
PYTHON_SCRIPT = "python_script"
TEMPLATE = "template"
THEME = "theme"
REMOVED = "removed"

View File

@@ -1,10 +1,9 @@
""""Starting setup task: Frontend"."""
from __future__ import annotations
import os
from typing import TYPE_CHECKING
from aiohttp import web
from homeassistant.components.http import HomeAssistantView
from homeassistant.core import HomeAssistant, callback
from .const import DOMAIN, URL_BASE
@@ -26,11 +25,13 @@ def async_register_frontend(hass: HomeAssistant, hacs: HacsBase) -> None:
hacs.async_setup_frontend_endpoint_themes()
# Register frontend
if hacs.configuration.frontend_repo_url:
if hacs.configuration.dev and (frontend_path := os.getenv("HACS_FRONTEND_DIR")):
hacs.log.warning(
"<HacsFrontend> Frontend development mode enabled. Do not run in production!"
)
hass.http.register_view(HacsFrontendDev())
hass.http.register_static_path(
f"{URL_BASE}/frontend", f"{frontend_path}/hacs_frontend", cache_headers=False
)
elif hacs.configuration.experimental:
hacs.log.info("<HacsFrontend> Using experimental frontend")
hass.http.register_static_path(
@@ -72,23 +73,3 @@ def async_register_frontend(hass: HomeAssistant, hacs: HacsBase) -> None:
# Setup plugin endpoint if needed
hacs.async_setup_frontend_endpoint_plugin()
class HacsFrontendDev(HomeAssistantView):
"""Dev View Class for HACS."""
requires_auth = False
name = "hacs_files:frontend"
url = r"/hacsfiles/frontend/{requested_file:.+}"
async def get(self, request, requested_file): # pylint: disable=unused-argument
"""Handle HACS Web requests."""
hacs: HacsBase = request.app["hass"].data.get(DOMAIN)
requested = requested_file.split("/")[-1]
request = await hacs.session.get(f"{hacs.configuration.frontend_repo_url}/{requested}")
if request.status == 200:
result = await request.read()
response = web.Response(body=result)
response.headers["Content-Type"] = "application/javascript"
return response

View File

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

View File

@@ -8,6 +8,7 @@ from .integration import HacsIntegrationRepository
from .netdaemon import HacsNetdaemonRepository
from .plugin import HacsPluginRepository
from .python_script import HacsPythonScriptRepository
from .template import HacsTemplateRepository
from .theme import HacsThemeRepository
RERPOSITORY_CLASSES: dict[HacsCategory, HacsRepository] = {
@@ -17,4 +18,5 @@ RERPOSITORY_CLASSES: dict[HacsCategory, HacsRepository] = {
HacsCategory.APPDAEMON: HacsAppdaemonRepository,
HacsCategory.NETDAEMON: HacsNetdaemonRepository,
HacsCategory.PLUGIN: HacsPluginRepository,
HacsCategory.TEMPLATE: HacsTemplateRepository,
}

View File

@@ -91,6 +91,8 @@ TOPIC_FILTER = (
"sensor",
"smart-home",
"smarthome",
"template",
"templates",
"theme",
"themes",
)
@@ -772,6 +774,8 @@ class HacsRepository:
await self.hacs.hass.services.async_call("frontend", "reload_themes", {})
except BaseException: # lgtm [py/catch-base-exception] pylint: disable=broad-except
pass
elif self.data.category == "template":
await self.hacs.hass.services.async_call("homeassistant", "reload_custom_templates", {})
await async_remove_store(self.hacs.hass, f"hacs/{self.data.id}.hacs")
@@ -796,6 +800,8 @@ class HacsRepository:
try:
if self.data.category == "python_script":
local_path = f"{self.content.path.local}/{self.data.name}.py"
elif self.data.category == "template":
local_path = f"{self.content.path.local}/{self.data.file_name}"
elif self.data.category == "theme":
path = (
f"{self.hacs.core.config_path}/"
@@ -823,7 +829,7 @@ class HacsRepository:
return False
self.logger.debug("%s Removing %s", self.string, local_path)
if self.data.category in ["python_script"]:
if self.data.category in ["python_script", "template"]:
os.remove(local_path)
else:
shutil.rmtree(local_path)
@@ -1093,7 +1099,7 @@ class HacsRepository:
if self.data.archived and not ignore_issues:
self.validate.errors.append("Repository is archived.")
if self.data.full_name not in self.hacs.common.archived_repositories:
self.hacs.common.archived_repositories.append(self.data.full_name)
self.hacs.common.archived_repositories.add(self.data.full_name)
raise HacsRepositoryArchivedException(f"{self} Repository is archived.")
# Make sure the repository is not in the blacklist.

View File

@@ -68,7 +68,7 @@
},
"removed": {
"title": "Repository removed from HACS",
"description": "{name} has been removed from HACS for {reason} 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."
}
}
}

View File

@@ -207,8 +207,8 @@ class HacsData:
self.logger.info("<HacsData restore> Restore started")
# Hacs
self.hacs.common.archived_repositories = []
self.hacs.common.ignored_repositories = []
self.hacs.common.archived_repositories = set()
self.hacs.common.ignored_repositories = set()
self.hacs.common.renamed_repositories = {}
# Clear out doubble renamed values
@@ -219,14 +219,14 @@ class HacsData:
self.hacs.common.renamed_repositories[entry] = value
# Clear out doubble archived values
for entry in hacs.get("archived_repositories", []):
for entry in hacs.get("archived_repositories", set()):
if entry not in self.hacs.common.archived_repositories:
self.hacs.common.archived_repositories.append(entry)
self.hacs.common.archived_repositories.add(entry)
# Clear out doubble ignored values
for entry in hacs.get("ignored_repositories", []):
for entry in hacs.get("ignored_repositories", set()):
if entry not in self.hacs.common.ignored_repositories:
self.hacs.common.ignored_repositories.append(entry)
self.hacs.common.ignored_repositories.add(entry)
try:
await self.register_unknown_repositories(repositories)

View File

@@ -17,4 +17,5 @@ def is_safe(hacs: HacsBase, path: str | Path) -> bool:
Path(f"{hacs.core.config_path}/{hacs.configuration.python_script_path}").as_posix(),
Path(f"{hacs.core.config_path}/{hacs.configuration.theme_path}").as_posix(),
Path(f"{hacs.core.config_path}/custom_components/").as_posix(),
Path(f"{hacs.core.config_path}/custom_templates/").as_posix(),
)