Update HACS

This commit is contained in:
root
2022-05-23 17:48:47 -07:00
parent 3bdb8638a8
commit 1d83dd0c31
163 changed files with 862 additions and 11844 deletions

View File

@@ -5,7 +5,7 @@ from typing import TYPE_CHECKING
from aiogithubapi import AIOGitHubAPIException
from ..enums import HacsCategory
from ..enums import HacsCategory, HacsDispatchEvent
from ..exceptions import HacsException
from ..utils.decorator import concurrent
from .base import HacsRepository
@@ -66,7 +66,7 @@ class HacsAppdaemonRepository(HacsRepository):
# Get appdaemon objects.
if self.repository_manifest:
if self.data.content_in_root:
if self.repository_manifest.content_in_root:
self.content.path.remote = ""
if self.content.path.remote == "apps":
@@ -81,8 +81,8 @@ class HacsAppdaemonRepository(HacsRepository):
# Signal entities to refresh
if self.data.installed:
self.hacs.hass.bus.async_fire(
"hacs/repository",
self.hacs.async_dispatch(
HacsDispatchEvent.REPOSITORY,
{
"id": 1337,
"action": "update",

View File

@@ -8,7 +8,7 @@ import os
import pathlib
import shutil
import tempfile
from typing import TYPE_CHECKING, Any, List, Optional
from typing import TYPE_CHECKING, Any, List
import zipfile
from aiogithubapi import (
@@ -20,10 +20,9 @@ from aiogithubapi.const import BASE_API_URL
from aiogithubapi.objects.repository import AIOGitHubAPIRepository
import attr
from homeassistant.helpers import device_registry as dr
from homeassistant.helpers.json import JSONEncoder
from ..const import DOMAIN
from ..enums import ConfigurationType, HacsCategory, RepositoryFile
from ..enums import ConfigurationType, HacsDispatchEvent, RepositoryFile
from ..exceptions import (
HacsException,
HacsNotModifiedException,
@@ -43,7 +42,6 @@ from ..utils.validate import Validate
from ..utils.version import (
version_left_higher_or_equal_then_right,
version_left_higher_then_right,
version_to_download,
)
from ..utils.workarounds import DOMAIN_OVERRIDES
@@ -51,6 +49,38 @@ if TYPE_CHECKING:
from ..base import HacsBase
TOPIC_FILTER = (
"custom-card",
"custom-component",
"custom-components",
"customcomponents",
"hacktoberfest",
"hacs-default",
"hacs-integration",
"hacs",
"hass",
"hassio",
"home-assistant",
"home-automation",
"homeassistant-components",
"homeassistant-integration",
"homeassistant-sensor",
"homeassistant",
"homeautomation",
"integration",
"lovelace",
"python",
"sensor",
"theme",
"themes",
"custom-cards",
"home-assistant-frontend",
"home-assistant-hacs",
"home-assistant-custom",
"lovelace-ui",
)
class FileInformation:
"""FileInformation."""
@@ -67,52 +97,34 @@ class RepositoryData:
archived: bool = False
authors: List[str] = []
category: str = ""
content_in_root: bool = False
country: List[str] = []
config_flow: bool = False
default_branch: str = None
description: str = ""
domain: str = ""
domains: List[str] = []
domain: str = None
downloads: int = 0
etag_repository: str = None
file_name: str = ""
filename: str = ""
first_install: bool = False
fork: bool = False
full_name: str = ""
hacs: str = None # Minimum HACS version
hide: bool = False
hide_default_branch: bool = False
homeassistant: str = None # Minimum Home Assistant version
id: int = 0
iot_class: str = None
installed: bool = False
installed_commit: str = None
installed_version: str = None
open_issues: int = 0
installed: bool = False
last_commit: str = None
last_version: str = None
last_fetched: datetime = None
last_updated: str = 0
last_version: str = None
manifest_name: str = None
new: bool = True
last_fetched: datetime = None
persistent_directory: str = None
open_issues: int = 0
published_tags: List[str] = []
pushed_at: str = ""
releases: bool = False
render_readme: bool = False
published_tags: List[str] = []
selected_tag: str = None
show_beta: bool = False
stargazers_count: int = 0
topics: List[str] = []
zip_release: bool = False
_storage_data: Optional[dict] = None
@property
def stars(self):
"""Return the stargazers count."""
return self.stargazers_count or 0
@property
def name(self):
@@ -123,57 +135,13 @@ class RepositoryData:
def to_json(self):
"""Export to json."""
return attr.asdict(
self,
filter=lambda attr, _: attr.name != "_storage_data" and attr.name != "last_fetched",
)
def memorize_storage(self, data) -> None:
"""Memorize the storage data."""
self._storage_data = data
def export_data(self) -> Optional[dict]:
"""Export to json if the data has changed.
Returns the data to export if the data needs
to be written.
Returns None if the data has not changed.
"""
export = json.loads(json.dumps(self.to_json(), cls=JSONEncoder))
return None if self._storage_data == export else export
return attr.asdict(self, filter=lambda attr, value: attr.name != "last_fetched")
@staticmethod
def create_from_dict(source: dict):
"""Set attributes from dicts."""
data = RepositoryData()
for key in source:
if key not in data.__dict__:
continue
if key == "pushed_at":
if source[key] == "":
continue
if "Z" in source[key]:
setattr(
data,
key,
datetime.strptime(source[key], "%Y-%m-%dT%H:%M:%SZ"),
)
else:
setattr(
data,
key,
datetime.strptime(source[key], "%Y-%m-%dT%H:%M:%S"),
)
elif key == "id":
setattr(data, key, str(source[key]))
elif key == "country":
if isinstance(source[key], str):
setattr(data, key, [source[key]])
else:
setattr(data, key, source[key])
else:
setattr(data, key, source[key])
data.update_data(source)
return data
def update_data(self, data: dict):
@@ -199,6 +167,9 @@ class RepositoryData:
setattr(self, key, [data[key]])
else:
setattr(self, key, data[key])
elif key == "topics":
setattr(self, key, [topic for topic in data[key] if topic not in TOPIC_FILTER])
else:
setattr(self, key, data[key])
@@ -207,19 +178,17 @@ class RepositoryData:
class HacsManifest:
"""HacsManifest class."""
name: str = None
content_in_root: bool = False
zip_release: bool = False
filename: str = None
manifest: dict = {}
hacs: str = None
hide_default_branch: bool = False
domains: List[str] = []
country: List[str] = []
homeassistant: str = None
filename: str = None
hacs: str = None # Minimum HACS version
hide_default_branch: bool = False
homeassistant: str = None # Minimum Home Assistant version
manifest: dict = {}
name: str = None
persistent_directory: str = None
iot_class: str = None
render_readme: bool = False
zip_release: bool = False
def to_dict(self):
"""Export to json."""
@@ -232,38 +201,25 @@ class HacsManifest:
raise HacsException("Missing manifest data")
manifest_data = HacsManifest()
manifest_data.manifest = {
k: v
for k, v in manifest.items()
if k in manifest_data.__dict__ and v != manifest_data.__getattribute__(k)
}
manifest_data.manifest = manifest
if country := manifest.get("country"):
if isinstance(country, str):
manifest["country"] = [country]
for key in manifest:
setattr(manifest_data, key, manifest[key])
for key, value in manifest_data.manifest.items():
if key == "country" and isinstance(value, str):
setattr(manifest_data, key, [value])
elif key in manifest_data.__dict__:
setattr(manifest_data, key, value)
return manifest_data
class RepositoryStatus:
"""Repository status."""
hide = False
installed = False
last_updated = None
new = True
selected_tag = None
show_beta = False
track = True
updated_info = False
first_install = True
class RepositoryReleases:
"""RepositoyReleases."""
last_release = None
last_release_object = None
last_release_object_downloads = None
published_tags = []
objects: list[GitHubReleaseModel] = []
releases = False
@@ -273,8 +229,8 @@ class RepositoryReleases:
class RepositoryPath:
"""RepositoryPath."""
local = None
remote = None
local: str | None = None
remote: str | None = None
class RepositoryContent:
@@ -297,7 +253,7 @@ class HacsRepository:
self.content = RepositoryContent()
self.content.path = RepositoryPath()
self.repository_object: AIOGitHubAPIRepository | None = None
self.status = RepositoryStatus()
self.updated_info = False
self.state = None
self.force_branch = False
self.integration_manifest = {}
@@ -326,9 +282,10 @@ class HacsRepository:
return self.repository_manifest.name
if self.data.category == "integration":
if self.integration_manifest:
if "name" in self.integration_manifest:
return self.integration_manifest["name"]
if self.data.manifest_name is not None:
return self.data.manifest_name
if "name" in self.integration_manifest:
return self.integration_manifest["name"]
return self.data.full_name.split("/")[-1].replace("-", " ").replace("_", " ").title()
@@ -338,9 +295,10 @@ class HacsRepository:
if self.data.installed:
return False
configuration = self.hacs.configuration.country.lower()
manifest = [entry.lower() for entry in self.repository_manifest.country or []]
if configuration == "all":
return False
manifest = [entry.lower() for entry in self.repository_manifest.country or []]
if not manifest:
return False
return configuration not in manifest
@@ -444,11 +402,11 @@ class HacsRepository:
@property
def can_download(self) -> bool:
"""Return True if we can download."""
if self.data.homeassistant is not None:
if self.repository_manifest.homeassistant is not None:
if self.data.releases:
if not version_left_higher_or_equal_then_right(
self.hacs.core.ha_version.string,
self.data.homeassistant,
self.repository_manifest.homeassistant,
):
return False
return True
@@ -461,8 +419,8 @@ class HacsRepository:
@property
def should_try_releases(self) -> bool:
"""Return a boolean indicating whether to download releases or not."""
if self.data.zip_release:
if self.data.filename.endswith(".zip"):
if self.repository_manifest.zip_release:
if self.repository_manifest.filename.endswith(".zip"):
if self.ref != self.data.default_branch:
return True
if self.ref == self.data.default_branch:
@@ -511,9 +469,6 @@ class HacsRepository:
# Set topics
self.data.topics = self.data.topics
# Set stargazers_count
self.data.stargazers_count = self.data.stargazers_count
# Set description
self.data.description = self.data.description
@@ -597,7 +552,7 @@ class HacsRepository:
return
temp_dir = await self.hacs.hass.async_add_executor_job(tempfile.mkdtemp)
temp_file = f"{temp_dir}/{self.data.filename}"
temp_file = f"{temp_dir}/{self.repository_manifest.filename}"
result = await self.hacs.async_save_file(temp_file, filecontent)
with zipfile.ZipFile(temp_file, "r") as zip_file:
@@ -622,10 +577,9 @@ class HacsRepository:
"""Download the content of a directory."""
if self.hacs.configuration.experimental:
if (
not self.data.zip_release
not self.repository_manifest.zip_release
and not self.data.file_name
and self.data.category == HacsCategory.INTEGRATION
and self.content.path.remote
and self.content.path.remote is not None
):
self.logger.info("%s Trying experimental download", self.string)
try:
@@ -635,16 +589,16 @@ class HacsRepository:
self.logger.exception(exception)
contents = self.gather_files_to_download()
if self.data.filename:
self.logger.debug("%s %s", self.string, self.data.filename)
if self.repository_manifest.filename:
self.logger.debug("%s %s", self.string, self.repository_manifest.filename)
if not contents:
raise HacsException("No content to download")
download_queue = QueueManager(hass=self.hacs.hass)
for content in contents:
if self.data.content_in_root and self.data.filename:
if content.name != self.data.filename:
if self.repository_manifest.content_in_root and self.repository_manifest.filename:
if content.name != self.repository_manifest.filename:
continue
download_queue.add(self.dowload_repository_content(content))
@@ -670,7 +624,7 @@ class HacsRepository:
raise HacsException(f"[{self}] Failed to download zipball")
temp_dir = await self.hacs.hass.async_add_executor_job(tempfile.mkdtemp)
temp_file = f"{temp_dir}/{self.data.filename}"
temp_file = f"{temp_dir}/{self.repository_manifest.filename}"
result = await self.hacs.async_save_file(temp_file, filecontent)
if not result:
raise HacsException("Could not save ZIP file")
@@ -702,7 +656,7 @@ class HacsRepository:
raise_exception=False,
repository=self.data.full_name,
path=RepositoryFile.HACS_JSON,
**{"params": {"ref": ref or version_to_download(self)}},
**{"params": {"ref": ref or self.version_to_download()}},
)
if response:
return json.loads(decode_content(response.data.content))
@@ -715,7 +669,7 @@ class HacsRepository:
def _info_file_variants() -> tuple[str, ...]:
name: str = (
"readme"
if self.data.render_readme or self.hacs.configuration.experimental
if self.repository_manifest.render_readme or self.hacs.configuration.experimental
else "info"
)
return (
@@ -779,8 +733,8 @@ class HacsRepository:
self.data.installed_version = None
self.data.installed_commit = None
self.hacs.hass.bus.async_fire(
"hacs/repository",
self.hacs.async_dispatch(
HacsDispatchEvent.REPOSITORY,
{
"id": 1337,
"action": "uninstall",
@@ -844,6 +798,7 @@ class HacsRepository:
async def async_pre_registration(self) -> None:
"""Run pre registration steps."""
@concurrent(concurrenttasks=10)
async def async_registration(self, ref=None) -> None:
"""Run registration steps."""
await self.async_pre_registration()
@@ -867,6 +822,8 @@ class HacsRepository:
async def async_post_registration(self) -> None:
"""Run post registration steps."""
if not self.hacs.system.action:
return
await self.hacs.validation.async_run_repository_checks(self)
async def async_pre_install(self) -> None:
@@ -881,10 +838,22 @@ class HacsRepository:
async def async_install(self) -> None:
"""Run install steps."""
await self._async_pre_install()
self.hacs.async_dispatch(
HacsDispatchEvent.REPOSITORY_DOWNLOAD_PROGRESS,
{"repository": self.data.full_name, "progress": 30},
)
self.logger.info("%s Running installation steps", self.string)
await self.async_install_repository()
self.hacs.async_dispatch(
HacsDispatchEvent.REPOSITORY_DOWNLOAD_PROGRESS,
{"repository": self.data.full_name, "progress": 90},
)
self.logger.info("%s Installation steps completed", self.string)
await self._async_post_install()
self.hacs.async_dispatch(
HacsDispatchEvent.REPOSITORY_DOWNLOAD_PROGRESS,
{"repository": self.data.full_name, "progress": False},
)
async def async_post_installation(self) -> None:
"""Run post install steps."""
@@ -894,8 +863,8 @@ class HacsRepository:
self.logger.info("%s Running post installation steps", self.string)
await self.async_post_installation()
self.data.new = False
self.hacs.hass.bus.async_fire(
"hacs/repository",
self.hacs.async_dispatch(
HacsDispatchEvent.REPOSITORY,
{
"id": 1337,
"action": "install",
@@ -916,21 +885,28 @@ class HacsRepository:
if not self.can_download:
raise HacsException("The version of Home Assistant is not compatible with this version")
version = version_to_download(self)
version = self.version_to_download()
if version == self.data.default_branch:
self.ref = version
else:
self.ref = f"tags/{version}"
self.hacs.async_dispatch(
HacsDispatchEvent.REPOSITORY_DOWNLOAD_PROGRESS,
{"repository": self.data.full_name, "progress": 40},
)
if self.data.installed and self.data.category == "netdaemon":
persistent_directory = BackupNetDaemon(hacs=self.hacs, repository=self)
await self.hacs.hass.async_add_executor_job(persistent_directory.create)
elif self.data.persistent_directory:
if os.path.exists(f"{self.content.path.local}/{self.data.persistent_directory}"):
elif self.repository_manifest.persistent_directory:
if os.path.exists(
f"{self.content.path.local}/{self.repository_manifest.persistent_directory}"
):
persistent_directory = Backup(
hacs=self.hacs,
local_path=f"{self.content.path.local}/{self.data.persistent_directory}",
local_path=f"{self.content.path.local}/{self.repository_manifest.persistent_directory}",
backup_path=tempfile.gettempdir() + "/hacs_persistent_directory/",
)
await self.hacs.hass.async_add_executor_job(persistent_directory.create)
@@ -942,11 +918,21 @@ class HacsRepository:
self.hacs.log.debug("%s Local path is set to %s", self.string, self.content.path.local)
self.hacs.log.debug("%s Remote path is set to %s", self.string, self.content.path.remote)
if self.data.zip_release and version != self.data.default_branch:
self.hacs.async_dispatch(
HacsDispatchEvent.REPOSITORY_DOWNLOAD_PROGRESS,
{"repository": self.data.full_name, "progress": 50},
)
if self.repository_manifest.zip_release and version != self.data.default_branch:
await self.download_zip_files(self.validate)
else:
await self.download_content()
self.hacs.async_dispatch(
HacsDispatchEvent.REPOSITORY_DOWNLOAD_PROGRESS,
{"repository": self.data.full_name, "progress": 70},
)
if self.validate.errors:
for error in self.validate.errors:
self.logger.error("%s %s", self.string, error)
@@ -955,6 +941,11 @@ class HacsRepository:
await self.hacs.hass.async_add_executor_job(backup.cleanup)
raise HacsException("Could not download, see log for details")
self.hacs.async_dispatch(
HacsDispatchEvent.REPOSITORY_DOWNLOAD_PROGRESS,
{"repository": self.data.full_name, "progress": 80},
)
if self.data.installed and not self.content.single:
await self.hacs.hass.async_add_executor_job(backup.cleanup)
@@ -1068,7 +1059,7 @@ class HacsRepository:
self.data.releases = False
if not self.force_branch:
self.ref = version_to_download(self)
self.ref = self.version_to_download()
if self.data.releases:
for release in self.releases.objects or []:
if release.tag_name == self.ref:
@@ -1141,8 +1132,8 @@ class HacsRepository:
if files:
return files
if self.data.content_in_root:
if not self.data.filename:
if self.repository_manifest.content_in_root:
if not self.repository_manifest.filename:
if category == "theme":
tree = filter_content_return_one_of_type(self.tree, "", "yaml", "full_path")
@@ -1171,7 +1162,7 @@ class HacsRepository:
else:
_content_path = content.path
if not self.data.content_in_root:
if not self.repository_manifest.content_in_root:
_content_path = _content_path.replace(f"{self.content.path.remote}", "")
local_directory = f"{self.content.path.local}/{_content_path}"
@@ -1197,7 +1188,6 @@ class HacsRepository:
"""Remove the entity device."""
if (
self.hacs.configuration == ConfigurationType.YAML
or not self.hacs.core.ha_version >= "2022.4.0.dev0"
or not self.hacs.configuration.experimental
):
return
@@ -1209,3 +1199,21 @@ class HacsRepository:
return
device_registry.async_remove_device(device_id=device.id)
def version_to_download(self) -> str:
"""Determine which version to download."""
if self.data.last_version is not None:
if self.data.selected_tag is not None:
if self.data.selected_tag == self.data.last_version:
self.data.selected_tag = None
return self.data.last_version
return self.data.selected_tag
return self.data.last_version
if self.data.selected_tag is not None:
if self.data.selected_tag == self.data.default_branch:
return self.data.default_branch
if self.data.selected_tag in self.data.published_tags:
return self.data.selected_tag
return self.data.default_branch or "main"

View File

@@ -6,12 +6,11 @@ from typing import TYPE_CHECKING, Any
from homeassistant.loader import async_get_custom_components
from ..enums import HacsCategory, HacsGitHubRepo, RepositoryFile
from ..enums import HacsCategory, HacsDispatchEvent, HacsGitHubRepo, RepositoryFile
from ..exceptions import AddonRepositoryException, HacsException
from ..utils.decode import decode_content
from ..utils.decorator import concurrent
from ..utils.filters import get_first_directory_in_directory
from ..utils.version import version_to_download
from .base import HacsRepository
if TYPE_CHECKING:
@@ -50,7 +49,7 @@ class HacsIntegrationRepository(HacsRepository):
await self.common_validate()
# Custom step 1: Validate content.
if self.data.content_in_root:
if self.repository_manifest.content_in_root:
self.content.path.remote = ""
if self.content.path.remote == "custom_components":
@@ -100,7 +99,7 @@ class HacsIntegrationRepository(HacsRepository):
if not await self.common_update(ignore_issues, force) and not force:
return
if self.data.content_in_root:
if self.repository_manifest.content_in_root:
self.content.path.remote = ""
if self.content.path.remote == "custom_components":
@@ -129,8 +128,8 @@ class HacsIntegrationRepository(HacsRepository):
# Signal entities to refresh
if self.data.installed:
self.hacs.hass.bus.async_fire(
"hacs/repository",
self.hacs.async_dispatch(
HacsDispatchEvent.REPOSITORY,
{
"id": 1337,
"action": "update",
@@ -150,7 +149,7 @@ class HacsIntegrationRepository(HacsRepository):
"""Get the content of the manifest.json file."""
manifest_path = (
"manifest.json"
if self.data.content_in_root
if self.repository_manifest.content_in_root
else f"{self.content.path.remote}/{RepositoryFile.MAINIFEST_JSON}"
)
@@ -161,7 +160,7 @@ class HacsIntegrationRepository(HacsRepository):
method=self.hacs.githubapi.repos.contents.get,
repository=self.data.full_name,
path=manifest_path,
**{"params": {"ref": ref or version_to_download(self)}},
**{"params": {"ref": ref or self.version_to_download()}},
)
if response:
return json.loads(decode_content(response.data.content))

View File

@@ -3,7 +3,7 @@ from __future__ import annotations
from typing import TYPE_CHECKING
from ..enums import HacsCategory
from ..enums import HacsCategory, HacsDispatchEvent
from ..exceptions import HacsException
from ..utils import filters
from ..utils.decorator import concurrent
@@ -36,7 +36,7 @@ class HacsNetdaemonRepository(HacsRepository):
# Custom step 1: Validate content.
if self.repository_manifest:
if self.data.content_in_root:
if self.repository_manifest.content_in_root:
self.content.path.remote = ""
if self.content.path.remote == "apps":
@@ -70,7 +70,7 @@ class HacsNetdaemonRepository(HacsRepository):
# Get appdaemon objects.
if self.repository_manifest:
if self.data.content_in_root:
if self.repository_manifest.content_in_root:
self.content.path.remote = ""
if self.content.path.remote == "apps":
@@ -84,8 +84,8 @@ class HacsNetdaemonRepository(HacsRepository):
# Signal entities to refresh
if self.data.installed:
self.hacs.hass.bus.async_fire(
"hacs/repository",
self.hacs.async_dispatch(
HacsDispatchEvent.REPOSITORY,
{
"id": 1337,
"action": "update",

View File

@@ -4,6 +4,7 @@ from __future__ import annotations
import json
from typing import TYPE_CHECKING
from ..enums import HacsCategory, HacsDispatchEvent
from ..exceptions import HacsException
from ..utils.decorator import concurrent
from .base import HacsRepository
@@ -21,7 +22,7 @@ class HacsPluginRepository(HacsRepository):
self.data.full_name = full_name
self.data.full_name_lower = full_name.lower()
self.data.file_name = None
self.data.category = "plugin"
self.data.category = HacsCategory.PLUGIN
self.content.path.local = self.localpath
@property
@@ -71,8 +72,8 @@ class HacsPluginRepository(HacsRepository):
# Signal entities to refresh
if self.data.installed:
self.hacs.hass.bus.async_fire(
"hacs/repository",
self.hacs.async_dispatch(
HacsDispatchEvent.REPOSITORY,
{
"id": 1337,
"action": "update",
@@ -94,11 +95,13 @@ class HacsPluginRepository(HacsRepository):
def update_filenames(self) -> None:
"""Get the filename to target."""
possible_locations = ("",) if self.data.content_in_root else ("release", "dist", "")
possible_locations = (
("",) if self.repository_manifest.content_in_root else ("release", "dist", "")
)
# Handler for plug requirement 3
if self.data.filename:
valid_filenames = (self.data.filename,)
if self.repository_manifest.filename:
valid_filenames = (self.repository_manifest.filename,)
else:
valid_filenames = (
f"{self.data.name.replace('lovelace-', '')}.js",

View File

@@ -3,7 +3,7 @@ from __future__ import annotations
from typing import TYPE_CHECKING
from ..enums import HacsCategory
from ..enums import HacsCategory, HacsDispatchEvent
from ..exceptions import HacsException
from ..utils.decorator import concurrent
from .base import HacsRepository
@@ -38,7 +38,7 @@ class HacsPythonScriptRepository(HacsRepository):
await self.common_validate()
# Custom step 1: Validate content.
if self.data.content_in_root:
if self.repository_manifest.content_in_root:
self.content.path.remote = ""
compliant = False
@@ -70,7 +70,7 @@ class HacsPythonScriptRepository(HacsRepository):
return
# Get python_script objects.
if self.data.content_in_root:
if self.repository_manifest.content_in_root:
self.content.path.remote = ""
compliant = False
@@ -88,8 +88,8 @@ class HacsPythonScriptRepository(HacsRepository):
# Signal entities to refresh
if self.data.installed:
self.hacs.hass.bus.async_fire(
"hacs/repository",
self.hacs.async_dispatch(
HacsDispatchEvent.REPOSITORY,
{
"id": 1337,
"action": "update",

View File

@@ -3,7 +3,7 @@ from __future__ import annotations
from typing import TYPE_CHECKING
from ..enums import HacsCategory
from ..enums import HacsCategory, HacsDispatchEvent
from ..exceptions import HacsException
from ..utils.decorator import concurrent
from .base import HacsRepository
@@ -53,7 +53,7 @@ class HacsThemeRepository(HacsRepository):
f"Repository structure for {self.ref.replace('tags/','')} is not compliant"
)
if self.data.content_in_root:
if self.repository_manifest.content_in_root:
self.content.path.remote = ""
# Handle potential errors
@@ -76,7 +76,7 @@ class HacsThemeRepository(HacsRepository):
return
# Get theme objects.
if self.data.content_in_root:
if self.repository_manifest.content_in_root:
self.content.path.remote = ""
# Update name
@@ -85,8 +85,8 @@ class HacsThemeRepository(HacsRepository):
# Signal entities to refresh
if self.data.installed:
self.hacs.hass.bus.async_fire(
"hacs/repository",
self.hacs.async_dispatch(
HacsDispatchEvent.REPOSITORY,
{
"id": 1337,
"action": "update",