Formating

This commit is contained in:
ludeeus
2019-06-16 10:27:05 +02:00
parent af8505d8a3
commit f87e491989
22 changed files with 444 additions and 193 deletions

View File

@ -49,7 +49,7 @@ DOMAIN = "{}".format(NAME_SHORT.lower())
# TODO: Remove this when minimum HA version is > 0.93
REQUIREMENTS = ["aiofiles"]
_LOGGER = logging.getLogger('custom_components.hacs')
_LOGGER = logging.getLogger("custom_components.hacs")
CONFIG_SCHEMA = vol.Schema(
{DOMAIN: vol.Schema({vol.Required("token"): cv.string})}, extra=vol.ALLOW_EXTRA
@ -65,7 +65,7 @@ async def async_setup(hass, config): # pylint: disable=unused-argument
# Configure HACS
await configure_hacs(hass, github_token, config_dir)
# Check if custom_updater exists
# Check if custom_updater exists
for location in CUSTOM_UPDATER_LOCATIONS:
if os.path.exists(location.format(config_dir)):
msg = CUSTOM_UPDATER_WARNING.format(location.format(config_dir))
@ -73,12 +73,14 @@ async def async_setup(hass, config): # pylint: disable=unused-argument
return False
# Check if HA is the required version.
if parse_version(HAVERSION) < parse_version('0.92.0'):
if parse_version(HAVERSION) < parse_version("0.92.0"):
_LOGGER.critical("You need HA version 92 or newer to use this integration.")
return False
# Add sensor
hass.async_create_task(discovery.async_load_platform(hass, "sensor", DOMAIN, {}, config[DOMAIN]))
hass.async_create_task(
discovery.async_load_platform(hass, "sensor", DOMAIN, {}, config[DOMAIN])
)
# Setup startup tasks
hass.bus.async_listen_once(EVENT_HOMEASSISTANT_START, hacs().startup_tasks())
@ -95,7 +97,7 @@ async def async_setup(hass, config): # pylint: disable=unused-argument
# Add to sidepanel
# TODO: Remove this check when minimum HA version is > 0.94
if parse_version(HAVERSION) < parse_version('0.93.9'):
if parse_version(HAVERSION) < parse_version("0.93.9"):
await hass.components.frontend.async_register_built_in_panel(
"iframe",
IFRAME["title"],
@ -127,7 +129,9 @@ async def configure_hacs(hass, github_token, hass_config_dir):
hacs.migration = HacsMigration()
hacs.storage = HacsStorage()
hacs.aiogithub = AIOGitHub(github_token, hass.loop, async_create_clientsession(hass))
hacs.aiogithub = AIOGitHub(
github_token, hass.loop, async_create_clientsession(hass)
)
hacs.hass = hass
hacs.config_dir = hass_config_dir

View File

@ -9,12 +9,13 @@ from aiohttp import ClientError
import backoff
_LOGGER = logging.getLogger('custom_components.hacs.aiogithub')
_LOGGER = logging.getLogger("custom_components.hacs.aiogithub")
class AIOGitHubException(BaseException):
"""Raise this when something is off."""
class AIOGitHub(object):
"""Base Github API implementation."""
@ -70,7 +71,9 @@ class AIOGitHub(object):
repositories = []
for repository in response:
repositories.append(AIOGithubRepository(repository, self.token, self.loop, self.session))
repositories.append(
AIOGithubRepository(repository, self.token, self.loop, self.session)
)
return repositories
@ -103,7 +106,6 @@ class AIOGithubRepository(AIOGitHub):
self.attributes = attributes
self._last_commit = None
@property
def id(self):
return self.attributes.get("id")
@ -165,7 +167,9 @@ class AIOGithubRepository(AIOGitHub):
@backoff.on_exception(backoff.expo, ClientError, max_tries=3)
async def get_releases(self, latest=False):
"""Retrun a list of repository release objects."""
endpoint = "/repos/" + self.full_name + "/releases/" + "latest" if latest else ""
endpoint = (
"/repos/" + self.full_name + "/releases/" + "latest" if latest else ""
)
url = self.baseapi + endpoint
async with async_timeout.timeout(20, loop=self.loop):
@ -198,7 +202,8 @@ class AIOGithubRepository(AIOGitHub):
if response.get("message"):
raise AIOGitHubException("No commits")
self._last_commit = response['sha'][0:7]
self._last_commit = response["sha"][0:7]
class AIOGithubRepositoryContent(AIOGitHub):
"""Repository Conetent Github API implementation."""
@ -225,15 +230,20 @@ class AIOGithubRepositoryContent(AIOGitHub):
@property
def content(self):
return base64.b64decode(bytearray(self.attributes.get("content"), "utf-8")).decode()
return base64.b64decode(
bytearray(self.attributes.get("content"), "utf-8")
).decode()
@property
def download_url(self):
return self.attributes.get("download_url") or self.attributes.get("browser_download_url")
return self.attributes.get("download_url") or self.attributes.get(
"browser_download_url"
)
class AIOGithubRepositoryRelease(AIOGitHub):
"""Repository Release Github API implementation."""
def __init__(self, attributes):
"""Initialize."""
self.attributes = attributes
@ -248,7 +258,9 @@ class AIOGithubRepositoryRelease(AIOGitHub):
@property
def published_at(self):
return datetime.strptime(self.attributes.get("published_at"), "%Y-%m-%dT%H:%M:%SZ")
return datetime.strptime(
self.attributes.get("published_at"), "%Y-%m-%dT%H:%M:%SZ"
)
@property
def draft(self):

View File

@ -73,9 +73,7 @@ ERROR = [
################################
DEFAULT_REPOSITORIES = {
"integration": [
"StyraHem/ShellyForHASS"
],
"integration": ["StyraHem/ShellyForHASS"],
"plugin": [
"maykar/compact-custom-header",
"maykar/lovelace-swipe-navigation",
@ -87,5 +85,5 @@ DEFAULT_REPOSITORIES = {
"finity69x2/fan-control-entity-row",
"thomasloven/lovelace-card-mod",
"thomasloven/lovelace-markdown-mod",
]
],
}

View File

@ -1,8 +1,10 @@
"""Custom Exceptions."""
class HacsBaseException(Exception):
"""Super basic."""
class HacsUserScrewupException(HacsBaseException):
"""Raise this when the user does something they should not do."""
@ -14,6 +16,7 @@ class HacsNotSoBasicException(HacsBaseException):
class HacsDataFileMissing(HacsBaseException):
"""Raise this storage datafile is missing."""
class HacsDataNotExpected(HacsBaseException):
"""Raise this when data returned from storage is not ok."""
@ -21,17 +24,22 @@ class HacsDataNotExpected(HacsBaseException):
class HacsRepositoryInfo(HacsBaseException):
"""Raise this when repository info is missing/wrong."""
class HacsRequirement(HacsBaseException):
"""Raise this when repository is missing a requirement."""
class HacsMissingManifest(HacsBaseException):
"""Raise this when manifest is missing."""
def __init__(self, message="The manifest file is missing in the repository."):
super().__init__(message)
self.message = message
class HacsBlacklistException(HacsBaseException):
"""Raise this when the repository is currently in the blacklist."""
def __init__(self, message="The repository is currently in the blacklist."):
super().__init__(message)
self.message = message

View File

@ -4,7 +4,7 @@ import logging
from aiohttp import web
from ...blueprints import HacsViewBase
_LOGGER = logging.getLogger('custom_components.hacs.frontend')
_LOGGER = logging.getLogger("custom_components.hacs.frontend")
class HacsAPIView(HacsViewBase):
@ -16,7 +16,9 @@ class HacsAPIView(HacsViewBase):
"""Initilize."""
self.url = self.url_path["api"] + r"/{element}/{action}"
async def get(self, request, element, action=None): # pylint: disable=unused-argument
async def get(
self, request, element, action=None
): # pylint: disable=unused-argument
"""Serve HacsAPIView."""
_LOGGER.debug("GET API call for %s with %s", element, action)
@ -26,43 +28,47 @@ class HacsAPIView(HacsViewBase):
await repository.install()
await self.storage.set()
if action == "172733314":
raise web.HTTPFound(self.url_path['settings'])
raise web.HTTPFound("{}/{}".format(self.url_path['repository'], repository.repository_id))
raise web.HTTPFound(self.url_path["settings"])
raise web.HTTPFound(
"{}/{}".format(self.url_path["repository"], repository.repository_id)
)
# Update a repository
elif element == "repository_update_repository":
repository = self.repositories[action]
await repository.update()
await self.storage.set()
raise web.HTTPFound("{}/{}".format(self.url_path['repository'], repository.repository_id))
raise web.HTTPFound(
"{}/{}".format(self.url_path["repository"], repository.repository_id)
)
# Update a repository
elif element == "repository_update_settings":
repository = self.repositories[action]
await repository.update()
await self.storage.set()
raise web.HTTPFound(self.url_path['settings'])
raise web.HTTPFound(self.url_path["settings"])
# Uninstall a element from the repository view
elif element == "repository_uninstall":
repository = self.repositories[action]
await repository.uninstall()
await self.storage.set()
raise web.HTTPFound(self.url_path['store'])
raise web.HTTPFound(self.url_path["store"])
# Remove a custom repository from the settings view
elif element == "repository_remove":
repository = self.repositories[action]
await repository.remove()
await self.storage.set()
raise web.HTTPFound(self.url_path['settings'])
raise web.HTTPFound(self.url_path["settings"])
# Hide a repository.
elif element == "repository_hide":
repository = self.repositories[action]
repository.hide = True
await self.storage.set()
raise web.HTTPFound(self.url_path['store'])
raise web.HTTPFound(self.url_path["store"])
# Unhide a repository.
elif element == "repository_unhide":
@ -70,21 +76,17 @@ class HacsAPIView(HacsViewBase):
repository.hide = False
await repository.update()
await self.storage.set()
raise web.HTTPFound(self.url_path['settings'])
raise web.HTTPFound(self.url_path["settings"])
# Remove a custom repository from the settings view
elif element == "repositories_reload":
self.hass.async_create_task(self.update_repositories("Run it!"))
raise web.HTTPFound(self.url_path['settings'])
raise web.HTTPFound(self.url_path["settings"])
# Show content of hacs
elif element == "hacs" and action == "inspect":
jsons = {}
skip = [
"content_objects",
"last_release_object",
"repository",
]
skip = ["content_objects", "last_release_object", "repository"]
for repository in self.repositories:
repository = self.repositories[repository]
jsons[repository.repository_id] = {}
@ -97,13 +99,16 @@ class HacsAPIView(HacsViewBase):
elif element == "log" and action == "get":
from ...handler.log import get_log_file_content
content = self.base_content
content += await get_log_file_content(self.config_dir)
return web.Response(body=content, content_type="text/html", charset="utf-8")
raise web.HTTPFound(self.url_path['error'])
raise web.HTTPFound(self.url_path["error"])
async def post(self, request, element, action=None): # pylint: disable=unused-argument
async def post(
self, request, element, action=None
): # pylint: disable=unused-argument
"""Prosess POST API actions."""
_LOGGER.debug("GET POST call for %s with %s", element, action)
@ -111,16 +116,20 @@ class HacsAPIView(HacsViewBase):
if element == "repository_register":
repository_name = postdata["custom_url"]
if 'repository_type' in postdata:
if "repository_type" in postdata:
repository_type = postdata["repository_type"]
_LOGGER.debug("GET POST call for %s with %s", repository_name, repository_type)
_LOGGER.debug(
"GET POST call for %s with %s", repository_name, repository_type
)
# Stip first part if it's an URL.
if "https://github" in repository_name:
repository_name = repository_name.split("https://github.com/")[-1]
if "https://www.github" in repository_name:
repository_name = repository_name.split("https://www.github.com/")[-1]
repository_name = repository_name.split("https://www.github.com/")[
-1
]
# Strip whitespace
repository_name = repository_name.split()[0]
@ -129,11 +138,21 @@ class HacsAPIView(HacsViewBase):
if repository_name != "":
if repository_name in self.blacklist:
self.blacklist.remove(repository_name)
repository, result = await self.register_new_repository(repository_type, repository_name)
repository, result = await self.register_new_repository(
repository_type, repository_name
)
if result:
await self.storage.set()
raise web.HTTPFound("{}/{}".format(self.url_path['repository'], repository.repository_id))
raise web.HTTPFound(
"{}/{}".format(
self.url_path["repository"], repository.repository_id
)
)
message = "Could not add {} at this time, check the log for more details.".format(repository_name)
message = "Could not add {} at this time, check the log for more details.".format(
repository_name
)
raise web.HTTPFound("{}?message={}".format(self.url_path['settings'], message))
raise web.HTTPFound(
"{}?message={}".format(self.url_path["settings"], message)
)

View File

@ -10,7 +10,8 @@ from aiohttp import web
from ...blueprints import HacsViewBase
from ...const import ERROR, ISSUE_URL
_LOGGER = logging.getLogger('custom_components.hacs..frontend')
_LOGGER = logging.getLogger("custom_components.hacs..frontend")
class HacsErrorView(HacsViewBase):
"""Serve error."""
@ -30,31 +31,34 @@ class HacsErrorView(HacsViewBase):
stack_trace = list()
for trace in trace_back:
stack_trace.append("File : {} , Line : {}, Func.Name : {}, Message : {}", format(
trace[0], trace[1], trace[2], trace[3]
))
stack_trace.append(
"File : {} , Line : {}, Func.Name : {}, Message : {}",
format(trace[0], trace[1], trace[2], trace[3]),
)
# HARD styling
stacks = ""
for stack in stack_trace:
stacks += stack
stacks = stacks.replace("File :", "</br>---------------------------------------------------------------</br><b>File :</b>")
stacks = stacks.replace(
"File :",
"</br>---------------------------------------------------------------</br><b>File :</b>",
)
stacks = stacks.replace(", Line :", "</br><b>Line :</b>")
stacks = stacks.replace(", Func.Name :", "</br><b>Func.Name :</b>")
stacks = stacks.replace(", Message :", "</br><b>Message :</b>")[86:-1]
if ex_type is not None:
codeblock = """
<p><b>Exception type:</b> {}</p>
<p><b>Exception message:</b> {}</p>
<code class="codeblock errorview"">{}</code>
""".format(ex_type.__name__, ex_value, stacks)
""".format(
ex_type.__name__, ex_value, stacks
)
else:
codeblock = ""
# Generate content
content = self.base_content
content += """
@ -74,7 +78,9 @@ class HacsErrorView(HacsViewBase):
<div class='center-align' style='margin-top: 100px'>
<img src='https://i.pinimg.com/originals/ec/85/67/ec856744fac64a5a9e407733f190da5a.png'>
</div>
""".format(random.choice(ERROR), codeblock, ISSUE_URL, self.url_path["api"])
""".format(
random.choice(ERROR), codeblock, ISSUE_URL, self.url_path["api"]
)
except Exception as exception:
message = "GREAT!, even the error page is broken... ({})".format(exception)

View File

@ -5,7 +5,7 @@ from aiohttp import web
from ...blueprints import HacsViewBase
from ...const import NO_ELEMENTS
_LOGGER = logging.getLogger('custom_components.hacs.frontend')
_LOGGER = logging.getLogger("custom_components.hacs.frontend")
class HacsOverviewView(HacsViewBase):
@ -32,14 +32,22 @@ class HacsOverviewView(HacsViewBase):
else:
for repository in self.repositories_list_name:
if not repository.track or repository.hide or not repository.installed:
if (
not repository.track
or repository.hide
or not repository.installed
):
continue
if repository.pending_restart:
card_icon = "<i class='fas fa-cube card-status pending-restart'></i>"
card_icon = (
"<i class='fas fa-cube card-status pending-restart'></i>"
)
elif repository.pending_update:
card_icon = "<i class='fas fa-cube card-status pending-update'></i>"
card_icon = (
"<i class='fas fa-cube card-status pending-update'></i>"
)
elif repository.installed:
card_icon = "<i class='fas fa-cube card-status installed'></i>"
@ -58,7 +66,15 @@ class HacsOverviewView(HacsViewBase):
</span>
</div>
</a>
""".format(self.url_path["repository"], repository.repository_id, repository.topics, repository.authors, card_icon, repository.name, repository.description)
""".format(
self.url_path["repository"],
repository.repository_id,
repository.topics,
repository.authors,
card_icon,
repository.name,
repository.description,
)
if repository.repository_type == "integration":
integrations.append(card)
@ -95,4 +111,4 @@ class HacsOverviewView(HacsViewBase):
_LOGGER.error(exception)
raise web.HTTPFound(self.url_path["error"])
return web.Response(body=content, content_type="text/html", charset="utf-8")
return web.Response(body=content, content_type="text/html", charset="utf-8")

View File

@ -6,7 +6,7 @@ from aiohttp import web
from aiohttp.web_exceptions import HTTPNotFound
from ...blueprints import HacsViewBase
_LOGGER = logging.getLogger('custom_components.hacs.frontend')
_LOGGER = logging.getLogger("custom_components.hacs.frontend")
class HacsPluginView(HacsViewBase):
@ -25,8 +25,8 @@ class HacsPluginView(HacsViewBase):
file = "{}/www/community/{}".format(self.config_dir, requested_file)
# Serve .gz if it exist
if os.path.exists(file + '.gz'):
file += '.gz'
if os.path.exists(file + ".gz"):
file += ".gz"
response = None
if os.path.exists(file):
@ -38,7 +38,9 @@ class HacsPluginView(HacsViewBase):
raise HTTPNotFound()
except Exception as error: # pylint: disable=broad-except
_LOGGER.debug("there was an issue trying to serve %s - %s", requested_file, error)
_LOGGER.debug(
"there was an issue trying to serve %s - %s", requested_file, error
)
raise HTTPNotFound()
return response

View File

@ -4,7 +4,7 @@ import logging
from aiohttp import web
from ...blueprints import HacsViewBase
_LOGGER = logging.getLogger('custom_components.hacs.frontend')
_LOGGER = logging.getLogger("custom_components.hacs.frontend")
LOVELACE_EXAMLE_URL = """
<pre id="LovelaceExample" class="yaml">
@ -23,6 +23,7 @@ LOVELACE_EXAMLE_URL_TYPE = """
</pre>
"""
class HacsRepositoryView(HacsViewBase):
"""Serve HacsRepositoryView."""
@ -53,11 +54,12 @@ class HacsRepositoryView(HacsViewBase):
</div>
</div>
</div>
""".format(message)
""".format(
message
)
else:
custom_message = ""
if repository.pending_restart:
pending_restart = """
<div class='container''>
@ -79,20 +81,14 @@ class HacsRepositoryView(HacsViewBase):
if repository.additional_info:
if repository.info is None:
info = "</br>" + await self.aiogithub.render_markdown(repository.additional_info)
info = info.replace("<h3>", "<h6>").replace(
"</h3>", "</h6>"
)
info = info.replace("<h2>", "<h5>").replace(
"</h2>", "</h5>"
)
info = info.replace("<h1>", "<h4>").replace(
"</h1>", "</h4>"
info = "</br>" + await self.aiogithub.render_markdown(
repository.additional_info
)
info = info.replace("<h3>", "<h6>").replace("</h3>", "</h6>")
info = info.replace("<h2>", "<h5>").replace("</h2>", "</h5>")
info = info.replace("<h1>", "<h4>").replace("</h1>", "</h4>")
info = info.replace("<code>", "<code class='codeinfo'>")
info = info.replace(
"<table>", "<table class='white-text'>"
)
info = info.replace("<table>", "<table class='white-text'>")
info = info.replace(
'<a href="http', '<a target="_blank" href="http'
)
@ -104,13 +100,14 @@ class HacsRepositoryView(HacsViewBase):
else:
info = ""
if repository.authors:
authors = "<p>Author(s): "
for author in repository.authors:
if "@" in author:
author = author.split("@")[-1]
authors += "<a href='https://github.com/{author}' target='_blank' style='color: var(--primary-color) !important; margin: 2'> @{author}</a>".format(author=author)
authors += "<a href='https://github.com/{author}' target='_blank' style='color: var(--primary-color) !important; margin: 2'> @{author}</a>".format(
author=author
)
authors += "</p>"
else:
authors = ""
@ -126,13 +123,21 @@ class HacsRepositoryView(HacsViewBase):
To learn more about how to configure this,
click the "REPOSITORY" link below to get to the repository for this integration.
</i>
""".format(repository.local_path)
""".format(
repository.local_path
)
else:
if repository.javascript_type is None:
llnote = LOVELACE_EXAMLE_URL.format(repository.name, repository.name.replace("lovelace-", ""))
llnote = LOVELACE_EXAMLE_URL.format(
repository.name, repository.name.replace("lovelace-", "")
)
jsnote = MISSING_JS_TYPE
else:
llnote = LOVELACE_EXAMLE_URL_TYPE.format(repository.name, repository.name.replace("lovelace-", ""), repository.javascript_type)
llnote = LOVELACE_EXAMLE_URL_TYPE.format(
repository.name,
repository.name.replace("lovelace-", ""),
repository.javascript_type,
)
jsnote = ""
note = """
</br><i>
@ -150,7 +155,9 @@ class HacsRepositoryView(HacsViewBase):
To learn more about how to configure this,
click the "REPOSITORY" link below button to get to the repository for this plugin.
</i>
""".format(repository.local_path, llnote, jsnote)
""".format(
repository.local_path, llnote, jsnote
)
if not repository.installed:
main_action = "INSTALL"
@ -167,7 +174,9 @@ class HacsRepositoryView(HacsViewBase):
name = repository.name.split("lovelace-")[-1]
else:
name = repository.name
open_plugin = "<a href='/community_plugin/{}/{}.js' target='_blank' style='color: var(--primary-color) !important'>OPEN PLUGIN</a>".format(repository.name, name)
open_plugin = "<a href='/community_plugin/{}/{}.js' target='_blank' style='color: var(--primary-color) !important'>OPEN PLUGIN</a>".format(
repository.name, name
)
else:
open_plugin = ""
@ -178,37 +187,52 @@ class HacsRepositoryView(HacsViewBase):
if repository.hide:
hide_option = """
<li><a class="dropdown-list-item" href="{}/repository_unhide/{}" onclick="ShowProgressBar()">Unhide</a></li>
""".format(self.url_path["api"], repository.repository_id)
""".format(
self.url_path["api"], repository.repository_id
)
else:
hide_option = """
<li><a class="dropdown-list-item" href="{}/repository_hide/{}" onclick="ShowProgressBar()">Hide</a></li>
""".format(self.url_path["api"], repository.repository_id)
""".format(
self.url_path["api"], repository.repository_id
)
content = self.base_content
if repository.version_installed is not None:
inst_ver = "<p><b>Installed version:</b> {}</p>".format(repository.version_installed)
inst_ver = "<p><b>Installed version:</b> {}</p>".format(
repository.version_installed
)
else:
if repository.installed_commit is not None:
inst_ver = "<p><b>Installed commit:</b> {}</p>".format(repository.installed_commit)
inst_ver = "<p><b>Installed commit:</b> {}</p>".format(
repository.installed_commit
)
else:
inst_ver = ""
if repository.last_release_tag is not None:
last_ver = "<p><b>Available version:</b> {}</p>".format(repository.last_release_tag)
last_ver = "<p><b>Available version:</b> {}</p>".format(
repository.last_release_tag
)
else:
last_ver = "<p><b>Available commit:</b> {}</p>".format(repository.last_commit)
last_ver = "<p><b>Available commit:</b> {}</p>".format(
repository.last_commit
)
last_up = ""
if repository.pending_update and repository.version_installed is not None:
changelog = "<a href='https://github.com/{}/releases' target='_blank' style='color: var(--primary-color) !important'>CHANGELOG</a>".format(repository.repository_name)
changelog = "<a href='https://github.com/{}/releases' target='_blank' style='color: var(--primary-color) !important'>CHANGELOG</a>".format(
repository.repository_name
)
else:
changelog = ""
if repository.installed:
uninstall = "<a href='{}/repository_uninstall/{}' style='float: right; color: var(--google-red-500) !important; font-weight: bold;' onclick='ShowProgressBar()'>UNINSTALL</a>".format(self.url_path['api'], repository.repository_id)
uninstall = "<a href='{}/repository_uninstall/{}' style='float: right; color: var(--google-red-500) !important; font-weight: bold;' onclick='ShowProgressBar()'>UNINSTALL</a>".format(
self.url_path["api"], repository.repository_id
)
else:
uninstall = ""
@ -258,9 +282,30 @@ class HacsRepositoryView(HacsViewBase):
</div>
</div>
</div>
""".format(custom_message, pending_restart, repository.name, self.url_path["api"], repository.repository_id, hide_option, repository.repository_name,
repository.name, repository.description, inst_ver, last_ver, last_up, info, authors, note, self.url_path["api"],
repository.repository_id, main_action, changelog, repository.repository_name, open_plugin, uninstall)
""".format(
custom_message,
pending_restart,
repository.name,
self.url_path["api"],
repository.repository_id,
hide_option,
repository.repository_name,
repository.name,
repository.description,
inst_ver,
last_ver,
last_up,
info,
authors,
note,
self.url_path["api"],
repository.repository_id,
main_action,
changelog,
repository.repository_name,
open_plugin,
uninstall,
)
except Exception as exception:
_LOGGER.error(exception)

View File

@ -7,7 +7,7 @@ from homeassistant.const import __version__ as HAVERSION
from ...blueprints import HacsViewBase
from ...const import ISSUE_URL, NAME_LONG
_LOGGER = logging.getLogger('custom_components.hacs.frontend')
_LOGGER = logging.getLogger("custom_components.hacs.frontend")
class HacsSettingsView(HacsViewBase):
@ -74,7 +74,12 @@ class HacsSettingsView(HacsViewBase):
</div>
</div>
</div>
""".format(hacs.version_installed, hacs.last_release_tag, self.url_path["api"], hacs.last_release_tag)
""".format(
hacs.version_installed,
hacs.last_release_tag,
self.url_path["api"],
hacs.last_release_tag,
)
else:
hacs_update = ""
@ -93,11 +98,12 @@ class HacsSettingsView(HacsViewBase):
</div>
</div>
</div>
""".format(message)
""".format(
message
)
else:
custom_message = ""
# Repos:
for repository in self.repositories_list_repo:
if repository.hide and repository.repository_id != "172733314":
@ -107,7 +113,12 @@ class HacsSettingsView(HacsViewBase):
<i title="Unhide" class="fas fa-plus-circle" style="padding-right: 8px"></i></a>
{}
<span class="repository-list-badge">{}</span>
""".format(self.url_path["api"], repository.repository_id, repository.repository_name, repository.repository_type)
""".format(
self.url_path["api"],
repository.repository_id,
repository.repository_name,
repository.repository_type,
)
line += "</div></li>"
hidden.append(line)
@ -117,22 +128,30 @@ class HacsSettingsView(HacsViewBase):
line = '<li class="collection-item hacscolor hacslist"><div>'
line += """
<a href="{}/{}"><span class="repository-list-badge">{}</span> {}</a>
""".format(self.url_path["repository"], repository.repository_id, repository.repository_type, repository.repository_name)
""".format(
self.url_path["repository"],
repository.repository_id,
repository.repository_type,
repository.repository_name,
)
if repository.installed:
remove = """
<i title="Remove is not possible when {} is installed." class="secondary-content fas fa-trash-alt disabledaction"></i>
""".format(repository.repository_type)
""".format(
repository.repository_type
)
else:
remove = """
<a href={}/repository_remove/{} onclick="ShowProgressBar()" class="secondary-content" style="color: var(--primary-color)">
<i title="Remove." class="fas fa-trash-alt"></i>
</a>
""".format(self.url_path["api"], repository.repository_id)
""".format(
self.url_path["api"], repository.repository_id
)
line += remove
line += "</div></li>"
repository_lines.append(line)
# Generate content to display
@ -143,7 +162,9 @@ class HacsSettingsView(HacsViewBase):
{}
{}
</div>
""".format(hacs_restart, hacs_update, custom_message)
""".format(
hacs_restart, hacs_update, custom_message
)
# HACS card
content += """
@ -155,7 +176,12 @@ class HacsSettingsView(HacsViewBase):
<b>Home Assistant version:</b> {}</br>
</div>
</div>
""".format(NAME_LONG, hacs.version_installed, " <b>(RESTART PENDING!)</b>" if hacs.pending_restart else "", HAVERSION)
""".format(
NAME_LONG,
hacs.version_installed,
" <b>(RESTART PENDING!)</b>" if hacs.pending_restart else "",
HAVERSION,
)
# The buttons, must have buttons
content += """
@ -173,7 +199,9 @@ class HacsSettingsView(HacsViewBase):
OPEN LOG
</a>
</div>
""".format(self.url_path["api"], ISSUE_URL, self.url_path["api"])
""".format(
self.url_path["api"], ISSUE_URL, self.url_path["api"]
)
## Integration URL's
content += """
@ -205,7 +233,9 @@ class HacsSettingsView(HacsViewBase):
</form>
</div>
</div>
""".format(self.url_path["api"])
""".format(
self.url_path["api"]
)
## Hidden repositories
if hidden:

View File

@ -6,7 +6,7 @@ from aiohttp import web
from aiohttp.web import HTTPNotFound
from ...blueprints import HacsViewBase
_LOGGER = logging.getLogger('custom_components.hacs.frontend')
_LOGGER = logging.getLogger("custom_components.hacs.frontend")
class HacsStaticView(HacsViewBase):
@ -21,10 +21,11 @@ class HacsStaticView(HacsViewBase):
async def get(self, request, requested_file): # pylint: disable=unused-argument
"""Serve static files."""
servefile = "{}/custom_components/hacs/frontend/elements/{}".format(
self.config_dir, requested_file)
self.config_dir, requested_file
)
if os.path.exists(servefile + '.gz'):
return web.FileResponse(servefile + '.gz')
if os.path.exists(servefile + ".gz"):
return web.FileResponse(servefile + ".gz")
else:
if os.path.exists(servefile):
return web.FileResponse(servefile)

View File

@ -4,7 +4,7 @@ import logging
from aiohttp import web
from ...blueprints import HacsViewBase
_LOGGER = logging.getLogger('custom_components.hacs.frontend')
_LOGGER = logging.getLogger("custom_components.hacs.frontend")
class HacsStoreView(HacsViewBase):
@ -41,10 +41,14 @@ class HacsStoreView(HacsViewBase):
continue
if repository.pending_restart:
card_icon = "<i class='fas fa-cube card-status pending-restart'></i>"
card_icon = (
"<i class='fas fa-cube card-status pending-restart'></i>"
)
elif repository.pending_update:
card_icon = "<i class='fas fa-cube card-status pending-update'></i>"
card_icon = (
"<i class='fas fa-cube card-status pending-update'></i>"
)
elif repository.installed:
card_icon = "<i class='fas fa-cube card-status installed'></i>"
@ -63,7 +67,15 @@ class HacsStoreView(HacsViewBase):
</span>
</div>
</a>
""".format(self.url_path["repository"], repository.repository_id, repository.topics, repository.authors, card_icon, repository.name, repository.description)
""".format(
self.url_path["repository"],
repository.repository_id,
repository.topics,
repository.authors,
card_icon,
repository.name,
repository.description,
)
if repository.repository_type == "integration":
integrations.append(card)

View File

@ -8,11 +8,12 @@ from homeassistant.helpers.event import async_track_time_interval
from .aiogithub import AIOGitHubException
from .const import DEFAULT_REPOSITORIES
_LOGGER = logging.getLogger('custom_components.hacs.hacs')
_LOGGER = logging.getLogger("custom_components.hacs.hacs")
class HacsBase:
"""The base class of HACS, nested thoughout the project."""
const = None
migration = None
storage = None
@ -26,12 +27,23 @@ class HacsBase:
repositories = {}
url_path = {}
for endpoint in ["api", "error", "overview", "static", "store", "settings", "repository"]:
url_path[endpoint] = "/community_{}-{}".format(str(uuid.uuid4()), str(uuid.uuid4()))
for endpoint in [
"api",
"error",
"overview",
"static",
"store",
"settings",
"repository",
]:
url_path[endpoint] = "/community_{}-{}".format(
str(uuid.uuid4()), str(uuid.uuid4())
)
async def startup_tasks(self):
"""Run startup_tasks."""
from .hacsrepositoryintegration import HacsRepositoryIntegration
self.data["task_running"] = True
_LOGGER.info("Runing startup tasks.")
@ -40,10 +52,14 @@ class HacsBase:
self.data["hacs"]["endpoints"] = self.url_path
# For installed repositories only.
async_track_time_interval(self.hass, self.recuring_tasks_installed, timedelta(minutes=30))
async_track_time_interval(
self.hass, self.recuring_tasks_installed, timedelta(minutes=30)
)
# For the rest.
async_track_time_interval(self.hass, self.update_repositories, timedelta(minutes=500))
async_track_time_interval(
self.hass, self.update_repositories, timedelta(minutes=500)
)
# Check for updates to HACS.
repository = await self.aiogithub.get_repo("custom-components/hacs")
@ -109,12 +125,17 @@ class HacsBase:
for repository in self.repositories:
try:
repository = self.repositories[repository]
if not repository.track or repository.repository_name in self.blacklist:
if (
not repository.track
or repository.repository_name in self.blacklist
):
continue
if repository.hide and repository.repository_id != "172733314":
continue
if now is not None:
_LOGGER.info("Running update for %s", repository.repository_name)
_LOGGER.info(
"Running update for %s", repository.repository_name
)
await repository.update()
except AIOGitHubException as exception:
_LOGGER.error("%s - %s", repository.repository_name, exception)
@ -135,18 +156,22 @@ class HacsBase:
await repository.update()
else:
try:
await self.register_new_repository(repository_type, repository.full_name, repository)
await self.register_new_repository(
repository_type, repository.full_name, repository
)
except AIOGitHubException as exception:
_LOGGER.error("%s - %s", repository.full_name, exception)
await self.storage.set()
self.data["task_running"] = False
await self.storage.set()
async def get_repositories(self):
"""Get defined repositories."""
repositories = {}
# Get org repositories
repositories["integration"] = await self.aiogithub.get_org_repos("custom-components")
repositories["integration"] = await self.aiogithub.get_org_repos(
"custom-components"
)
repositories["plugin"] = await self.aiogithub.get_org_repos("custom-cards")
# Additional repositories (Not implemented)
@ -157,7 +182,9 @@ class HacsBase:
return repositories["integration"], repositories["plugin"]
async def recuring_tasks_installed(self, notarealarg): # pylint: disable=unused-argument
async def recuring_tasks_installed(
self, notarealarg
): # pylint: disable=unused-argument
"""Recuring tasks for installed repositories."""
self.data["task_running"] = True
_LOGGER.info("Running scheduled update of installed repositories")

View File

@ -5,7 +5,7 @@ from shutil import copy2
from .hacsbase import HacsBase
from .const import STORAGE_VERSION
_LOGGER = logging.getLogger('custom_components.hacs.migration')
_LOGGER = logging.getLogger("custom_components.hacs.migration")
class HacsMigration(HacsBase):
@ -51,7 +51,9 @@ class HacsMigration(HacsBase):
if repodata.get("isinstalled"):
# Register new repository
_LOGGER.info("Migrating %s", repodata["repo"])
repository, setup_result = await self.register_new_repository(repodata["element_type"], repodata["repo"])
repository, setup_result = await self.register_new_repository(
repodata["element_type"], repodata["repo"]
)
repository.version_installed = repodata["installed_version"]
repository.installed = True

View File

@ -1,5 +1,5 @@
"""Blueprint for HacsRepositoryBase."""
# pylint: disable=too-many-instance-attributes,invalid-name,broad-except,wildcard-import
# pylint: disable=too-many-instance-attributes,invalid-name,broad-except,wildcard-import,no-member
from asyncio import sleep
from datetime import datetime
import logging
@ -9,11 +9,16 @@ import shutil
from .aiogithub import AIOGitHubException
from .hacsbase import HacsBase
from .exceptions import HacsRepositoryInfo, HacsUserScrewupException, HacsBaseException, HacsBlacklistException
from .exceptions import (
HacsRepositoryInfo,
HacsUserScrewupException,
HacsBaseException,
HacsBlacklistException,
)
from .handler.download import async_download_file, async_save_file
from .const import DEFAULT_REPOSITORIES, VERSION
_LOGGER = logging.getLogger('custom_components.hacs.repository')
_LOGGER = logging.getLogger("custom_components.hacs.repository")
class HacsRepositoryBase(HacsBase):
@ -70,10 +75,12 @@ class HacsRepositoryBase(HacsBase):
"""Return local path."""
local_path = None
if self.repository_type == "integration":
if self.domain is None: # pylint: disable=no-member
if self.domain is None:
local_path = None
else:
local_path = "{}/custom_components/{}".format(self.config_dir, self.domain) # pylint: disable=no-member
local_path = "{}/custom_components/{}".format(
self.config_dir, self.domain
)
elif self.repository_type == "plugin":
local_path = "{}/www/community/{}".format(self.config_dir, self.name)
@ -87,7 +94,9 @@ class HacsRepositoryBase(HacsBase):
@property
def description(self):
"""Description."""
return "" if self.repository.description is None else self.repository.description
return (
"" if self.repository.description is None else self.repository.description
)
@property
def ref(self):
@ -156,35 +165,53 @@ class HacsRepositoryBase(HacsBase):
except AIOGitHubException:
pass
async def download_repository_directory_content(self, repository_directory_path, local_directory, ref):
async def download_repository_directory_content(
self, repository_directory_path, local_directory, ref
):
"""Download the content of a directory."""
try:
# Get content
if self.content_path == "release":
contents = self.content_objects
else:
contents = await self.repository.get_contents(repository_directory_path, ref)
contents = await self.repository.get_contents(
repository_directory_path, ref
)
for content_object in contents:
if content_object.type == "dir":
await self.download_repository_directory_content(content_object.path, local_directory, ref)
await self.download_repository_directory_content(
content_object.path, local_directory, ref
)
continue
if self.repository_type == "plugin" and not content_object.name.endswith(".js"):
if (
self.repository_type == "plugin"
and not content_object.name.endswith(".js")
):
# For plugins we currently only need .js files
continue
_LOGGER.debug("Downloading %s", content_object.name)
filecontent = await async_download_file(self.hass, content_object.download_url)
filecontent = await async_download_file(
self.hass, content_object.download_url
)
if filecontent is None:
_LOGGER.debug("There was an error downloading the file %s", content_object.name)
_LOGGER.debug(
"There was an error downloading the file %s",
content_object.name,
)
continue
# Save the content of the file.
if self.repository_name == "custom-components/hacs":
local_directory = "{}/{}".format(self.config_dir, content_object.path)
local_directory = local_directory.split("/{}".format(content_object.name))[0]
local_directory = "{}/{}".format(
self.config_dir, content_object.path
)
local_directory = local_directory.split(
"/{}".format(content_object.name)
)[0]
_LOGGER.debug(content_object.path)
_LOGGER.debug(local_directory)
@ -200,7 +227,7 @@ class HacsRepositoryBase(HacsBase):
async def install(self):
"""Run install tasks."""
start_time = datetime.now()
_LOGGER.info('(%s) - Starting installation', self.repository_name)
_LOGGER.info("(%s) - Starting installation", self.repository_name)
try:
# Run update
await self.update() # pylint: disable=no-member
@ -209,7 +236,9 @@ class HacsRepositoryBase(HacsBase):
await self.check_local_directory()
# Download files
await self.download_repository_directory_content(self.content_path, self.local_path, self.ref)
await self.download_repository_directory_content(
self.content_path, self.local_path, self.ref
)
except HacsBaseException as exception:
_LOGGER.debug("(%s) - %s", self.repository_name, exception)
@ -221,8 +250,11 @@ class HacsRepositoryBase(HacsBase):
self.installed_commit = self.last_commit
if self.repository_type == "integration":
self.pending_restart = True
_LOGGER.info('(%s) - installation completed in %s seconds', self.repository_name, (datetime.now() - start_time).seconds)
_LOGGER.info(
"(%s) - installation completed in %s seconds",
self.repository_name,
(datetime.now() - start_time).seconds,
)
async def remove(self):
"""Run remove tasks."""
@ -260,21 +292,33 @@ class HacsRepositoryBase(HacsBase):
pathlib.Path(local_path).mkdir(parents=True, exist_ok=True)
except Exception as exception:
_LOGGER.debug("(%s) - Creating directory %s failed with %s", self.repository_name, local_path, exception)
_LOGGER.debug(
"(%s) - Creating directory %s failed with %s",
self.repository_name,
local_path,
exception,
)
return
async def remove_local_directory(self):
"""Check the local directory."""
try:
if os.path.exists(self.local_path):
_LOGGER.debug("(%s) - Removing %s", self.repository_name, self.local_path)
_LOGGER.debug(
"(%s) - Removing %s", self.repository_name, self.local_path
)
shutil.rmtree(self.local_path)
while os.path.exists(self.local_path):
await sleep(1)
except Exception as exception:
_LOGGER.debug("(%s) - Removing directory %s failed with %s", self.repository_name, self.local_path, exception)
_LOGGER.debug(
"(%s) - Removing directory %s failed with %s",
self.repository_name,
self.local_path,
exception,
)
return
async def set_additional_info(self):
@ -293,12 +337,10 @@ class HacsRepositoryBase(HacsBase):
# We kinda expect this one to fail
self.additional_info = ""
async def set_repository(self):
"""Set the AIOGitHub repository object."""
self.repository = await self.aiogithub.get_repo(self.repository_name)
async def set_repository_releases(self):
"""Set attributes for releases."""
if self.repository is None:
@ -313,19 +355,19 @@ class HacsRepositoryBase(HacsBase):
self.last_release_object = temp
self.last_release_tag = temp.tag_name
async def validate_repository_name(self):
"""Validate the given repository_name."""
if "/" not in self.repository_name:
raise HacsUserScrewupException(
"GitHub repository name "
"'{}' is not the correct format".format(self.repository_name))
"'{}' is not the correct format".format(self.repository_name)
)
elif len(self.repository_name.split('/')) > 2:
elif len(self.repository_name.split("/")) > 2:
raise HacsUserScrewupException(
"GitHub repository name "
"'{}' is not the correct format".format(self.repository_name))
"'{}' is not the correct format".format(self.repository_name)
)
async def return_last_update(self):
"""Return a last update string."""

View File

@ -6,7 +6,7 @@ from .aiogithub import AIOGitHubException
from .blueprints import HacsRepositoryBase
from .exceptions import HacsRequirement
_LOGGER = logging.getLogger('custom_components.hacs.repository')
_LOGGER = logging.getLogger("custom_components.hacs.repository")
class HacsRepositoryPlugin(HacsRepositoryBase):
@ -60,7 +60,6 @@ class HacsRepositoryPlugin(HacsRepositoryBase):
pass
await self.set_repository_content()
async def set_repository_content(self):
"""Set repository content attributes."""
if self.content_path is None or self.content_path == "":

View File

@ -6,7 +6,7 @@ import json
from .blueprints import HacsRepositoryBase
from .exceptions import HacsRequirement
_LOGGER = logging.getLogger('custom_components.hacs.repository')
_LOGGER = logging.getLogger("custom_components.hacs.repository")
class HacsRepositoryIntegration(HacsRepositoryBase):
@ -43,7 +43,8 @@ class HacsRepositoryIntegration(HacsRepositoryBase):
self.content_path = first[0].path
self.content_objects = await self.repository.get_contents(
self.content_path, self.ref)
self.content_path, self.ref
)
if not isinstance(self.content_objects, list):
raise HacsRequirement("Repository structure does not meet the requirements")

View File

@ -8,7 +8,7 @@ from .hacsbase import HacsBase
from .exceptions import HacsNotSoBasicException, HacsRequirement
from .const import STORENAME, GENERIC_ERROR, STORAGE_VERSION
_LOGGER = logging.getLogger('custom_components.hacs.storage')
_LOGGER = logging.getLogger("custom_components.hacs.storage")
class HacsStorage(HacsBase):
@ -16,16 +16,16 @@ class HacsStorage(HacsBase):
async def get(self):
"""Read HACS data to storage."""
from .blueprints import (
HacsRepositoryIntegration,
HacsRepositoryPlugin,)
from .blueprints import HacsRepositoryIntegration, HacsRepositoryPlugin
datastore = "{}/.storage/{}".format(self.config_dir, STORENAME)
_LOGGER.debug("Reading from datastore %s.", datastore)
self.data["task_running"] = True
try:
async with aiofiles.open(
datastore, mode='r', encoding="utf-8", errors="ignore") as datafile:
datastore, mode="r", encoding="utf-8", errors="ignore"
) as datafile:
store_data = await datafile.read()
store_data = json.loads(store_data)
datafile.close()
@ -45,7 +45,9 @@ class HacsStorage(HacsBase):
repository = store_data["repositories"][repository]
if not repository.get("custom"):
continue
repository, status = await self.register_new_repository(repository["repository_type"], repository["repository_name"])
repository, status = await self.register_new_repository(
repository["repository_type"], repository["repository_name"]
)
if status:
await self.restore(store_data, repository)
@ -65,9 +67,13 @@ class HacsStorage(HacsBase):
else:
_LOGGER.info("Loading %s", repository.full_name)
if repository_type == "integration":
repository = HacsRepositoryIntegration(repository.full_name, repository)
repository = HacsRepositoryIntegration(
repository.full_name, repository
)
elif repository_type == "plugin":
repository = HacsRepositoryPlugin(repository.full_name, repository)
repository = HacsRepositoryPlugin(
repository.full_name, repository
)
else:
raise HacsNotSoBasicException(GENERIC_ERROR)
@ -76,7 +82,9 @@ class HacsStorage(HacsBase):
await repository.setup_repository()
except (HacsRequirement, AIOGitHubException) as exception:
if not self.data["task_running"]:
_LOGGER.error("%s - %s", repository.repository_name, exception)
_LOGGER.error(
"%s - %s", repository.repository_name, exception
)
self.blacklist.append(repository.repository_name)
continue
@ -90,7 +98,6 @@ class HacsStorage(HacsBase):
self.data["task_running"] = False
return store_data
async def set(self):
"""Write HACS data to storage."""
if self.data["task_running"]:
@ -123,7 +130,8 @@ class HacsStorage(HacsBase):
try:
async with aiofiles.open(
datastore, mode='w', encoding="utf-8", errors="ignore") as outfile:
datastore, mode="w", encoding="utf-8", errors="ignore"
) as outfile:
await outfile.write(json.dumps(data, indent=4))
outfile.close()

View File

@ -5,6 +5,7 @@ from .hacsbase import HacsBase
class HacsViewBase(HomeAssistantView, HacsBase):
"""Base View Class for HACS."""
requires_auth = False
@property
@ -18,7 +19,9 @@ class HacsViewBase(HomeAssistantView, HacsBase):
{}
<div id="main" class="hacs-content">
{}
""".format(self.imports, self.header, self.progress_bar)
""".format(
self.imports, self.header, self.progress_bar
)
@property
def imports(self):
@ -29,7 +32,9 @@ class HacsViewBase(HomeAssistantView, HacsBase):
<script src="{static}/materialize.min.js.gz"></script>
<link rel="stylesheet" href="{static}/hacs.css">
<script src="{static}/hacs.js"></script>
""".format(static=self.url_path["static"])
""".format(
static=self.url_path["static"]
)
@property
def header(self):
@ -46,7 +51,9 @@ class HacsViewBase(HomeAssistantView, HacsBase):
</div>
</nav>
</div>
""".format(self.url_path["overview"], self.url_path["store"], self.url_path["settings"])
""".format(
self.url_path["overview"], self.url_path["store"], self.url_path["settings"]
)
@property
def progress_bar(self):
@ -61,7 +68,9 @@ class HacsViewBase(HomeAssistantView, HacsBase):
<div class="progress hacs-bar-background" id="progressbar" style="display: {}">
<div class="indeterminate hacs-bar"></div>
</div>
""".format(display, display)
""".format(
display, display
)
@property
def footer(self):

View File

@ -10,7 +10,7 @@ import backoff
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from ..exceptions import HacsNotSoBasicException
_LOGGER = logging.getLogger('custom_components.hacs.download')
_LOGGER = logging.getLogger("custom_components.hacs.download")
@backoff.on_exception(backoff.expo, Exception, max_tries=3)
@ -39,7 +39,11 @@ async def async_download_file(hass, url):
else:
result = await request.text()
else:
raise HacsNotSoBasicException("Got status code {} when trying to download {}".format(request.status, url))
raise HacsNotSoBasicException(
"Got status code {} when trying to download {}".format(
request.status, url
)
)
return result
@ -48,23 +52,25 @@ async def async_save_file(location, content):
"""Save files."""
if "-bundle" in location:
location = location.replace("-bundle", "")
if "lovelace-" in location.split('/')[-1]:
search = location.split('/')[-1]
if "lovelace-" in location.split("/")[-1]:
search = location.split("/")[-1]
replace = search.replace("lovelace-", "")
location = location.replace(search, replace)
_LOGGER.debug("Saving %s", location)
mode = 'w'
mode = "w"
encoding = "utf-8"
errors="ignore"
errors = "ignore"
if not isinstance(content, str):
mode = 'wb'
mode = "wb"
encoding = None
errors = None
try:
async with aiofiles.open(location, mode=mode, encoding=encoding, errors=errors) as outfile:
async with aiofiles.open(
location, mode=mode, encoding=encoding, errors=errors
) as outfile:
await outfile.write(content)
outfile.close()
@ -73,7 +79,7 @@ async def async_save_file(location, content):
_LOGGER.debug(msg)
# Create gz for .js files
if location.endswith('.js') or location.endswith('.css'):
with open(location, 'rb') as f_in:
with gzip.open(location + '.gz', 'wb') as f_out:
if location.endswith(".js") or location.endswith(".css"):
with open(location, "rb") as f_in:
with gzip.open(location + ".gz", "wb") as f_out:
shutil.copyfileobj(f_in, f_out)

View File

@ -5,7 +5,7 @@ import aiofiles
from ..const import STARTUP
_LOGGER = logging.getLogger('custom_components.hacs.log')
_LOGGER = logging.getLogger("custom_components.hacs.log")
async def get_log_file_content(config_dir):
@ -16,7 +16,8 @@ async def get_log_file_content(config_dir):
try:
async with aiofiles.open(
log_file, mode='r', encoding="utf-8", errors="ignore") as localfile:
log_file, mode="r", encoding="utf-8", errors="ignore"
) as localfile:
logfile = await localfile.readlines()
localfile.close()
for line in logfile:
@ -27,7 +28,9 @@ async def get_log_file_content(config_dir):
line = line.replace(" WARNING ", "")
line = line.replace(" ERROR ", "")
line = line.replace(" CRITICAL ", "")
interesting += "<pre style='margin: 0; white-space: pre-wrap'>{}</pre>".format(line)
interesting += "<pre style='margin: 0; white-space: pre-wrap'>{}</pre>".format(
line
)
except Exception as exception:
_LOGGER.error(exception)
return interesting

View File

@ -4,7 +4,8 @@ from . import hacs
async def async_setup_platform(
hass, config, async_add_entities, discovery_info=None): # pylint: disable=unused-argument
hass, config, async_add_entities, discovery_info=None
): # pylint: disable=unused-argument
"""Setup sensor platform."""
async_add_entities([HACSSensor()])