Add theme installation and refactor install paths
All checks were successful
continuous-integration/drone/push Build is passing

A more object oriented approach would be good, but I'm lazy right now
This commit is contained in:
IamTheFij 2024-09-16 15:56:47 -07:00
parent 0c11152e29
commit 5f0b0ce8b5
2 changed files with 60 additions and 6 deletions

View File

@ -83,6 +83,13 @@ def parse_args():
dest="component", dest="component",
help="Component name from a forked type.", help="Component name from a forked type.",
) )
package_type_group.add_argument(
"--theme",
action="store_const",
dest="type",
const=PackageType.THEME,
help="The package is a theme.",
)
add_parser.add_argument( add_parser.add_argument(
"--version", "-v", type=str, help="The version of the package." "--version", "-v", type=str, help="The version of the package."

View File

@ -40,6 +40,18 @@ class PackageType(StrEnum):
INTEGRATION = auto() INTEGRATION = auto()
PLUGIN = auto() PLUGIN = auto()
FORK = auto() FORK = auto()
THEME = auto()
def get_install_path(hass_config_path: Path, package_type: PackageType) -> Path:
if package_type == PackageType.PLUGIN:
return hass_config_path / "www" / "js"
elif package_type in (PackageType.INTEGRATION, PackageType.FORK):
return hass_config_path / "custom_components"
elif package_type == PackageType.THEME:
return hass_config_path / "themes"
else:
raise NotImplementedError(f"Unknown package type {package_type}")
class Package: class Package:
@ -200,6 +212,9 @@ class Package:
response.raise_for_status() response.raise_for_status()
return response.json() return response.json()
def get_install_path(self, hass_config_path: Path) -> Path:
return get_install_path(hass_config_path, self.package_type)
def install_plugin(self, hass_config_path: Path): def install_plugin(self, hass_config_path: Path):
"""Installs the plugin package.""" """Installs the plugin package."""
@ -240,7 +255,7 @@ class Package:
else: else:
raise ValueError(f"No valid filename found for package {self.name}") raise ValueError(f"No valid filename found for package {self.name}")
js_path = hass_config_path / "www" / "js" js_path = self.get_install_path(hass_config_path)
js_path.mkdir(parents=True, exist_ok=True) js_path.mkdir(parents=True, exist_ok=True)
js_path.joinpath(filename).write_text(plugin.text) js_path.joinpath(filename).write_text(plugin.text)
@ -262,6 +277,22 @@ class Package:
yaml.dump(resources, resources_file.open("w")) yaml.dump(resources, resources_file.open("w"))
def install_theme_component(self, hass_config_path: Path):
filename = self.get_hacs_json().get("filename")
if not filename:
raise ValueError(f"No filename found for theme {self.name}")
filename = cast(str, filename)
url = f"https://raw.githubusercontent.com/{self.owner}/{self.name}/{self.version}/themes/{filename}"
theme = requests.get(url)
theme.raise_for_status()
themes_path = self.get_install_path(hass_config_path)
themes_path.mkdir(parents=True, exist_ok=True)
themes_path.joinpath(filename).write_text(theme.text)
yaml.dump(self.to_yaml(), themes_path.joinpath(f"{filename}.unhacs").open("w"))
def install_integration(self, hass_config_path: Path): def install_integration(self, hass_config_path: Path):
"""Installs the integration package.""" """Installs the integration package."""
zipball_url = get_tag_zip(self.url, self.version) zipball_url = get_tag_zip(self.url, self.version)
@ -275,13 +306,13 @@ class Package:
source, dest = None, None source, dest = None, None
for custom_component in tmpdir.glob("custom_components/*"): for custom_component in tmpdir.glob("custom_components/*"):
source = custom_component source = custom_component
dest = hass_config_path / "custom_components" / custom_component.name dest = self.get_install_path(hass_config_path) / custom_component.name
break break
else: else:
hacs_json = json.loads((tmpdir / "hacs.json").read_text()) hacs_json = json.loads((tmpdir / "hacs.json").read_text())
if hacs_json.get("content_in_root"): if hacs_json.get("content_in_root"):
source = tmpdir source = tmpdir
dest = hass_config_path / "custom_components" / self.name dest = self.get_install_path(hass_config_path) / self.name
if not source or not dest: if not source or not dest:
raise ValueError("No custom_components directory found") raise ValueError("No custom_components directory found")
@ -320,7 +351,7 @@ class Package:
manifest["version"] = "0.0.0" manifest["version"] = "0.0.0"
json.dump(manifest, manifest_file.open("w")) json.dump(manifest, manifest_file.open("w"))
dest = hass_config_path / "custom_components" / source.name dest = self.get_install_path(hass_config_path) / source.name
if not source or not dest: if not source or not dest:
raise ValueError("No custom_components directory found") raise ValueError("No custom_components directory found")
@ -339,6 +370,8 @@ class Package:
self.install_integration(hass_config_path) self.install_integration(hass_config_path)
elif self.package_type == PackageType.FORK: elif self.package_type == PackageType.FORK:
self.install_fork_component(hass_config_path) self.install_fork_component(hass_config_path)
elif self.package_type == PackageType.THEME:
self.install_theme_component(hass_config_path)
else: else:
raise NotImplementedError(f"Unknown package type {self.package_type}") raise NotImplementedError(f"Unknown package type {self.package_type}")
@ -400,13 +433,16 @@ def get_installed_packages(
package_types: Iterable[PackageType] = ( package_types: Iterable[PackageType] = (
PackageType.INTEGRATION, PackageType.INTEGRATION,
PackageType.PLUGIN, PackageType.PLUGIN,
PackageType.THEME,
), ),
) -> list[Package]: ) -> list[Package]:
# Integration packages # Integration packages
packages: list[Package] = [] packages: list[Package] = []
if PackageType.INTEGRATION in package_types: if PackageType.INTEGRATION in package_types:
for custom_component in (hass_config_path / "custom_components").glob("*"): for custom_component in get_install_path(
hass_config_path, PackageType.INTEGRATION
).glob("*"):
unhacs = custom_component / "unhacs.yaml" unhacs = custom_component / "unhacs.yaml"
if unhacs.exists(): if unhacs.exists():
package = Package.from_yaml(yaml.safe_load(unhacs.open())) package = Package.from_yaml(yaml.safe_load(unhacs.open()))
@ -415,13 +451,24 @@ def get_installed_packages(
# Plugin packages # Plugin packages
if PackageType.PLUGIN in package_types: if PackageType.PLUGIN in package_types:
for js_unhacs in (hass_config_path / "www" / "js").glob("*-unhacs.yaml"): for js_unhacs in get_install_path(hass_config_path, PackageType.PLUGIN).glob(
"*-unhacs.yaml"
):
package = Package.from_yaml(yaml.safe_load(js_unhacs.open())) package = Package.from_yaml(yaml.safe_load(js_unhacs.open()))
package.path = js_unhacs.with_name( package.path = js_unhacs.with_name(
js_unhacs.name.removesuffix("-unhacs.yaml") js_unhacs.name.removesuffix("-unhacs.yaml")
) )
packages.append(package) packages.append(package)
# Theme packages
if PackageType.THEME in package_types:
for js_unhacs in get_install_path(hass_config_path, PackageType.THEME).glob(
"*.unhacs"
):
package = Package.from_yaml(yaml.safe_load(js_unhacs.open()))
package.path = js_unhacs.with_name(js_unhacs.name.removesuffix(".unhacs"))
packages.append(package)
return packages return packages