updating to latest
This commit is contained in:
230
custom_components/hacs/helpers/functions/information.py
Normal file
230
custom_components/hacs/helpers/functions/information.py
Normal file
@@ -0,0 +1,230 @@
|
||||
"""Return repository information if any."""
|
||||
import json
|
||||
|
||||
from aiogithubapi import AIOGitHubAPIException, AIOGitHubAPINotModifiedException, GitHub
|
||||
from aiogithubapi.const import ACCEPT_HEADERS
|
||||
|
||||
from custom_components.hacs.exceptions import HacsException, HacsNotModifiedException
|
||||
from custom_components.hacs.helpers.functions.template import render_template
|
||||
from custom_components.hacs.share import get_hacs
|
||||
|
||||
|
||||
def info_file(repository):
|
||||
"""get info filename."""
|
||||
if repository.data.render_readme:
|
||||
for filename in ["readme", "readme.md", "README", "README.md", "README.MD"]:
|
||||
if filename in repository.treefiles:
|
||||
return filename
|
||||
return ""
|
||||
for filename in ["info", "info.md", "INFO", "INFO.md", "INFO.MD"]:
|
||||
if filename in repository.treefiles:
|
||||
return filename
|
||||
return ""
|
||||
|
||||
|
||||
async def get_info_md_content(repository):
|
||||
"""Get the content of info.md"""
|
||||
filename = info_file(repository)
|
||||
if not filename:
|
||||
return ""
|
||||
try:
|
||||
info = await repository.repository_object.get_contents(filename, repository.ref)
|
||||
if info is None:
|
||||
return ""
|
||||
info = info.content.replace("<svg", "<disabled").replace("</svg", "</disabled")
|
||||
return render_template(info, repository)
|
||||
except (
|
||||
ValueError,
|
||||
AIOGitHubAPIException,
|
||||
Exception, # pylint: disable=broad-except
|
||||
):
|
||||
if repository.hacs.system.action:
|
||||
raise HacsException("::error:: No info file found")
|
||||
return ""
|
||||
|
||||
|
||||
async def get_repository(session, token, repository_full_name, etag=None):
|
||||
"""Return a repository object or None."""
|
||||
hacs = get_hacs()
|
||||
try:
|
||||
github = GitHub(
|
||||
token,
|
||||
session,
|
||||
headers={
|
||||
"User-Agent": f"HACS/{hacs.version}",
|
||||
"Accept": ACCEPT_HEADERS["preview"],
|
||||
},
|
||||
)
|
||||
repository = await github.get_repo(repository_full_name, etag)
|
||||
return repository, github.client.last_response.etag
|
||||
except AIOGitHubAPINotModifiedException as exception:
|
||||
raise HacsNotModifiedException(exception) from exception
|
||||
except (ValueError, AIOGitHubAPIException, Exception) as exception:
|
||||
raise HacsException(exception) from exception
|
||||
|
||||
|
||||
async def get_tree(repository, ref):
|
||||
"""Return the repository tree."""
|
||||
try:
|
||||
tree = await repository.get_tree(ref)
|
||||
return tree
|
||||
except (ValueError, AIOGitHubAPIException) as exception:
|
||||
raise HacsException(exception)
|
||||
|
||||
|
||||
async def get_releases(repository, prerelease=False, returnlimit=5):
|
||||
"""Return the repository releases."""
|
||||
try:
|
||||
releases = await repository.get_releases(prerelease, returnlimit)
|
||||
return releases
|
||||
except (ValueError, AIOGitHubAPIException) as exception:
|
||||
raise HacsException(exception)
|
||||
|
||||
|
||||
def get_frontend_version():
|
||||
"""get the frontend version from the manifest."""
|
||||
manifest = read_hacs_manifest()
|
||||
frontend = 0
|
||||
for requirement in manifest.get("requirements", []):
|
||||
if requirement.startswith("hacs_frontend"):
|
||||
frontend = requirement.split("==")[1]
|
||||
break
|
||||
return frontend
|
||||
|
||||
|
||||
def read_hacs_manifest():
|
||||
"""Reads the HACS manifest file and returns the contents."""
|
||||
hacs = get_hacs()
|
||||
content = {}
|
||||
with open(f"{hacs.core.config_path}/custom_components/hacs/manifest.json") as manifest:
|
||||
content = json.loads(manifest.read())
|
||||
return content
|
||||
|
||||
|
||||
async def get_integration_manifest(repository):
|
||||
"""Return the integration manifest."""
|
||||
if repository.data.content_in_root:
|
||||
manifest_path = "manifest.json"
|
||||
else:
|
||||
manifest_path = f"{repository.content.path.remote}/manifest.json"
|
||||
if not manifest_path in [x.full_path for x in repository.tree]:
|
||||
raise HacsException(f"No file found '{manifest_path}'")
|
||||
try:
|
||||
manifest = await repository.repository_object.get_contents(manifest_path, repository.ref)
|
||||
manifest = json.loads(manifest.content)
|
||||
except (Exception, BaseException) as exception: # pylint: disable=broad-except
|
||||
raise HacsException(f"Could not read manifest.json [{exception}]")
|
||||
|
||||
try:
|
||||
repository.integration_manifest = manifest
|
||||
repository.data.authors = manifest["codeowners"]
|
||||
repository.data.domain = manifest["domain"]
|
||||
repository.data.manifest_name = manifest["name"]
|
||||
repository.data.config_flow = manifest.get("config_flow", False)
|
||||
|
||||
if repository.hacs.system.action:
|
||||
if manifest.get("documentation") is None:
|
||||
raise HacsException("::error:: manifest.json is missing documentation")
|
||||
if manifest.get("homeassistant") is not None:
|
||||
raise HacsException(
|
||||
"::error:: The homeassistant key in manifest.json is no longer valid"
|
||||
)
|
||||
# if manifest.get("issue_tracker") is None:
|
||||
# raise HacsException("The 'issue_tracker' is missing in manifest.json")
|
||||
|
||||
# Set local path
|
||||
repository.content.path.local = repository.localpath
|
||||
|
||||
except KeyError as exception:
|
||||
raise HacsException(f"Missing expected key {exception} in '{manifest_path}'")
|
||||
|
||||
|
||||
def find_file_name(repository):
|
||||
"""Get the filename to target."""
|
||||
if repository.data.category == "plugin":
|
||||
get_file_name_plugin(repository)
|
||||
elif repository.data.category == "integration":
|
||||
get_file_name_integration(repository)
|
||||
elif repository.data.category == "theme":
|
||||
get_file_name_theme(repository)
|
||||
elif repository.data.category == "appdaemon":
|
||||
get_file_name_appdaemon(repository)
|
||||
elif repository.data.category == "python_script":
|
||||
get_file_name_python_script(repository)
|
||||
|
||||
if repository.hacs.system.action:
|
||||
repository.logger.info(f"filename {repository.data.file_name}")
|
||||
repository.logger.info(f"location {repository.content.path.remote}")
|
||||
|
||||
|
||||
def get_file_name_plugin(repository):
|
||||
"""Get the filename to target."""
|
||||
tree = repository.tree
|
||||
releases = repository.releases.objects
|
||||
|
||||
if repository.data.content_in_root:
|
||||
possible_locations = [""]
|
||||
else:
|
||||
possible_locations = ["release", "dist", ""]
|
||||
|
||||
# Handler for plug requirement 3
|
||||
if repository.data.filename:
|
||||
valid_filenames = [repository.data.filename]
|
||||
else:
|
||||
valid_filenames = [
|
||||
f"{repository.data.name.replace('lovelace-', '')}.js",
|
||||
f"{repository.data.name}.js",
|
||||
f"{repository.data.name}.umd.js",
|
||||
f"{repository.data.name}-bundle.js",
|
||||
]
|
||||
|
||||
for location in possible_locations:
|
||||
if location == "release":
|
||||
if not releases:
|
||||
continue
|
||||
release = releases[0]
|
||||
if not release.assets:
|
||||
continue
|
||||
asset = release.assets[0]
|
||||
for filename in valid_filenames:
|
||||
if filename == asset.name:
|
||||
repository.data.file_name = filename
|
||||
repository.content.path.remote = "release"
|
||||
break
|
||||
|
||||
else:
|
||||
for filename in valid_filenames:
|
||||
if f"{location+'/' if location else ''}{filename}" in [x.full_path for x in tree]:
|
||||
repository.data.file_name = filename.split("/")[-1]
|
||||
repository.content.path.remote = location
|
||||
break
|
||||
|
||||
|
||||
def get_file_name_integration(repository):
|
||||
"""Get the filename to target."""
|
||||
|
||||
|
||||
def get_file_name_theme(repository):
|
||||
"""Get the filename to target."""
|
||||
tree = repository.tree
|
||||
|
||||
for treefile in tree:
|
||||
if treefile.full_path.startswith(
|
||||
repository.content.path.remote
|
||||
) and treefile.full_path.endswith(".yaml"):
|
||||
repository.data.file_name = treefile.filename
|
||||
|
||||
|
||||
def get_file_name_appdaemon(repository):
|
||||
"""Get the filename to target."""
|
||||
|
||||
|
||||
def get_file_name_python_script(repository):
|
||||
"""Get the filename to target."""
|
||||
tree = repository.tree
|
||||
|
||||
for treefile in tree:
|
||||
if treefile.full_path.startswith(
|
||||
repository.content.path.remote
|
||||
) and treefile.full_path.endswith(".py"):
|
||||
repository.data.file_name = treefile.filename
|
||||
Reference in New Issue
Block a user