mirror of
https://github.com/hacs/integration.git
synced 2025-07-23 02:55:44 +00:00
Move websocket setup to task (#2304)
This commit is contained in:
@ -17,7 +17,7 @@ coverage:
|
||||
paths:
|
||||
- custom_components/hacs/validate/
|
||||
tasks:
|
||||
target: 100%
|
||||
target: 70%
|
||||
paths:
|
||||
- custom_components/hacs/tasks/
|
||||
repositories:
|
||||
|
@ -1 +0,0 @@
|
||||
"""Initialize HACS API"""
|
@ -1,25 +0,0 @@
|
||||
"""API Handler for acknowledge_critical_repository"""
|
||||
from homeassistant.components import websocket_api
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
import voluptuous as vol
|
||||
|
||||
from custom_components.hacs.helpers.functions.store import (
|
||||
async_load_from_store,
|
||||
async_save_to_store,
|
||||
)
|
||||
|
||||
|
||||
@websocket_api.async_response
|
||||
@websocket_api.websocket_command(
|
||||
{vol.Required("type"): "hacs/critical", vol.Optional("repository"): cv.string}
|
||||
)
|
||||
async def acknowledge_critical_repository(hass, connection, msg):
|
||||
"""Handle get media player cover command."""
|
||||
repository = msg["repository"]
|
||||
|
||||
critical = await async_load_from_store(hass, "critical")
|
||||
for repo in critical:
|
||||
if repository == repo["repository"]:
|
||||
repo["acknowledged"] = True
|
||||
await async_save_to_store(hass, "critical", critical)
|
||||
connection.send_message(websocket_api.result_message(msg["id"], critical))
|
@ -1,24 +0,0 @@
|
||||
"""API Handler for check_local_path"""
|
||||
from homeassistant.components import websocket_api
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
import voluptuous as vol
|
||||
|
||||
from custom_components.hacs.helpers.functions.path_exsist import async_path_exsist
|
||||
|
||||
|
||||
@websocket_api.async_response
|
||||
@websocket_api.websocket_command(
|
||||
{vol.Required("type"): "hacs/check_path", vol.Optional("path"): cv.string}
|
||||
)
|
||||
async def check_local_path(_hass, connection, msg):
|
||||
"""Handle get media player cover command."""
|
||||
path = msg.get("path")
|
||||
exist = {"exist": False}
|
||||
|
||||
if path is None:
|
||||
return
|
||||
|
||||
if await async_path_exsist(path):
|
||||
exist["exist"] = True
|
||||
|
||||
connection.send_message(websocket_api.result_message(msg["id"], exist))
|
@ -1,15 +0,0 @@
|
||||
"""API Handler for get_critical_repositories"""
|
||||
from homeassistant.components import websocket_api
|
||||
import voluptuous as vol
|
||||
|
||||
from custom_components.hacs.helpers.functions.store import async_load_from_store
|
||||
|
||||
|
||||
@websocket_api.async_response
|
||||
@websocket_api.websocket_command({vol.Required("type"): "hacs/get_critical"})
|
||||
async def get_critical_repositories(hass, connection, msg):
|
||||
"""Handle get media player cover command."""
|
||||
critical = await async_load_from_store(hass, "critical")
|
||||
if not critical:
|
||||
critical = []
|
||||
connection.send_message(websocket_api.result_message(msg["id"], critical))
|
@ -1,28 +0,0 @@
|
||||
"""API Handler for hacs_config"""
|
||||
from homeassistant.components import websocket_api
|
||||
import voluptuous as vol
|
||||
|
||||
from custom_components.hacs.share import get_hacs
|
||||
|
||||
|
||||
@websocket_api.async_response
|
||||
@websocket_api.websocket_command({vol.Required("type"): "hacs/config"})
|
||||
async def hacs_config(_hass, connection, msg):
|
||||
"""Handle get media player cover command."""
|
||||
hacs = get_hacs()
|
||||
config = hacs.configuration
|
||||
|
||||
content = {}
|
||||
content["frontend_mode"] = config.frontend_mode
|
||||
content["frontend_compact"] = config.frontend_compact
|
||||
content["onboarding_done"] = config.onboarding_done
|
||||
content["version"] = hacs.version
|
||||
content["frontend_expected"] = hacs.frontend.version_expected
|
||||
content["frontend_running"] = hacs.frontend.version_running
|
||||
content["dev"] = config.dev
|
||||
content["debug"] = config.debug
|
||||
content["country"] = config.country
|
||||
content["experimental"] = config.experimental
|
||||
content["categories"] = hacs.common.categories
|
||||
|
||||
connection.send_message(websocket_api.result_message(msg["id"], content))
|
@ -1,15 +0,0 @@
|
||||
"""API Handler for hacs_removed"""
|
||||
from homeassistant.components import websocket_api
|
||||
import voluptuous as vol
|
||||
|
||||
from custom_components.hacs.share import list_removed_repositories
|
||||
|
||||
|
||||
@websocket_api.async_response
|
||||
@websocket_api.websocket_command({vol.Required("type"): "hacs/removed"})
|
||||
async def hacs_removed(_hass, connection, msg):
|
||||
"""Get information about removed repositories."""
|
||||
content = []
|
||||
for repo in list_removed_repositories():
|
||||
content.append(repo.to_json())
|
||||
connection.send_message(websocket_api.result_message(msg["id"], content))
|
@ -1,65 +0,0 @@
|
||||
"""API Handler for hacs_repositories"""
|
||||
from homeassistant.components import websocket_api
|
||||
import voluptuous as vol
|
||||
|
||||
from custom_components.hacs.share import get_hacs
|
||||
|
||||
|
||||
@websocket_api.async_response
|
||||
@websocket_api.websocket_command({vol.Required("type"): "hacs/repositories"})
|
||||
async def hacs_repositories(_hass, connection, msg):
|
||||
"""Handle get media player cover command."""
|
||||
hacs = get_hacs()
|
||||
repositories = hacs.repositories
|
||||
content = []
|
||||
for repo in repositories:
|
||||
if (
|
||||
repo.data.category in hacs.common.categories
|
||||
and not repo.ignored_by_country_configuration
|
||||
):
|
||||
data = {
|
||||
"additional_info": repo.information.additional_info,
|
||||
"authors": repo.data.authors,
|
||||
"available_version": repo.display_available_version,
|
||||
"beta": repo.data.show_beta,
|
||||
"can_install": repo.can_install,
|
||||
"category": repo.data.category,
|
||||
"country": repo.data.country,
|
||||
"config_flow": repo.data.config_flow,
|
||||
"custom": repo.custom,
|
||||
"default_branch": repo.data.default_branch,
|
||||
"description": repo.data.description,
|
||||
"domain": repo.data.domain,
|
||||
"downloads": repo.data.downloads,
|
||||
"file_name": repo.data.file_name,
|
||||
"first_install": repo.status.first_install,
|
||||
"full_name": repo.data.full_name,
|
||||
"hide": repo.data.hide,
|
||||
"hide_default_branch": repo.data.hide_default_branch,
|
||||
"homeassistant": repo.data.homeassistant,
|
||||
"id": repo.data.id,
|
||||
"info": repo.information.info,
|
||||
"installed_version": repo.display_installed_version,
|
||||
"installed": repo.data.installed,
|
||||
"issues": repo.data.open_issues,
|
||||
"javascript_type": repo.information.javascript_type,
|
||||
"last_updated": repo.data.last_updated,
|
||||
"local_path": repo.content.path.local,
|
||||
"main_action": repo.main_action,
|
||||
"name": repo.display_name,
|
||||
"new": repo.data.new,
|
||||
"pending_upgrade": repo.pending_upgrade,
|
||||
"releases": repo.data.published_tags,
|
||||
"selected_tag": repo.data.selected_tag,
|
||||
"stars": repo.data.stargazers_count,
|
||||
"state": repo.state,
|
||||
"status_description": repo.display_status_description,
|
||||
"status": repo.display_status,
|
||||
"topics": repo.data.topics,
|
||||
"updated_info": repo.status.updated_info,
|
||||
"version_or_commit": repo.display_version_or_commit,
|
||||
}
|
||||
|
||||
content.append(data)
|
||||
|
||||
connection.send_message(websocket_api.result_message(msg["id"], content))
|
@ -1,113 +0,0 @@
|
||||
"""API Handler for hacs_repository"""
|
||||
from aiogithubapi import AIOGitHubAPIException
|
||||
from homeassistant.components import websocket_api
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
import voluptuous as vol
|
||||
|
||||
from custom_components.hacs.share import get_hacs
|
||||
from custom_components.hacs.utils.logger import getLogger
|
||||
|
||||
|
||||
@websocket_api.async_response
|
||||
@websocket_api.websocket_command(
|
||||
{
|
||||
vol.Required("type"): "hacs/repository",
|
||||
vol.Optional("action"): cv.string,
|
||||
vol.Optional("repository"): cv.string,
|
||||
}
|
||||
)
|
||||
async def hacs_repository(hass, connection, msg):
|
||||
"""Handle get media player cover command."""
|
||||
hacs = get_hacs()
|
||||
logger = getLogger()
|
||||
data = {}
|
||||
repository = None
|
||||
|
||||
repo_id = msg.get("repository")
|
||||
action = msg.get("action")
|
||||
if repo_id is None or action is None:
|
||||
return
|
||||
|
||||
try:
|
||||
repository = hacs.get_by_id(repo_id)
|
||||
logger.debug(f"Running {action} for {repository.data.full_name}")
|
||||
|
||||
if action == "update":
|
||||
await repository.update_repository(ignore_issues=True, force=True)
|
||||
repository.status.updated_info = True
|
||||
|
||||
elif action == "install":
|
||||
repository.data.new = False
|
||||
was_installed = repository.data.installed
|
||||
await repository.async_install()
|
||||
if not was_installed:
|
||||
hass.bus.async_fire("hacs/reload", {"force": True})
|
||||
|
||||
elif action == "not_new":
|
||||
repository.data.new = False
|
||||
|
||||
elif action == "uninstall":
|
||||
repository.data.new = False
|
||||
await repository.update_repository(True)
|
||||
await repository.uninstall()
|
||||
|
||||
elif action == "hide":
|
||||
repository.data.hide = True
|
||||
|
||||
elif action == "unhide":
|
||||
repository.data.hide = False
|
||||
|
||||
elif action == "show_beta":
|
||||
repository.data.show_beta = True
|
||||
await repository.update_repository()
|
||||
|
||||
elif action == "hide_beta":
|
||||
repository.data.show_beta = False
|
||||
await repository.update_repository()
|
||||
|
||||
elif action == "toggle_beta":
|
||||
repository.data.show_beta = not repository.data.show_beta
|
||||
await repository.update_repository()
|
||||
|
||||
elif action == "delete":
|
||||
repository.data.show_beta = False
|
||||
repository.remove()
|
||||
|
||||
elif action == "release_notes":
|
||||
data = [
|
||||
{
|
||||
"name": x.attributes["name"],
|
||||
"body": x.attributes["body"],
|
||||
"tag": x.attributes["tag_name"],
|
||||
}
|
||||
for x in repository.releases.objects
|
||||
]
|
||||
|
||||
elif action == "set_version":
|
||||
if msg["version"] == repository.data.default_branch:
|
||||
repository.data.selected_tag = None
|
||||
else:
|
||||
repository.data.selected_tag = msg["version"]
|
||||
await repository.update_repository()
|
||||
|
||||
hass.bus.async_fire("hacs/reload", {"force": True})
|
||||
|
||||
else:
|
||||
logger.error(f"WS action '{action}' is not valid")
|
||||
|
||||
await hacs.data.async_write()
|
||||
message = None
|
||||
except AIOGitHubAPIException as exception:
|
||||
message = exception
|
||||
except AttributeError as exception:
|
||||
message = f"Could not use repository with ID {repo_id} ({exception})"
|
||||
except (Exception, BaseException) as exception: # pylint: disable=broad-except
|
||||
message = exception
|
||||
|
||||
if message is not None:
|
||||
logger.error(message)
|
||||
hass.bus.async_fire("hacs/error", {"message": str(message)})
|
||||
|
||||
if repository:
|
||||
repository.state = None
|
||||
connection.send_message(websocket_api.result_message(msg["id"], data))
|
@ -1,124 +0,0 @@
|
||||
"""API Handler for hacs_repository_data"""
|
||||
import sys
|
||||
|
||||
from aiogithubapi import AIOGitHubAPIException
|
||||
from homeassistant.components import websocket_api
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
import voluptuous as vol
|
||||
|
||||
from custom_components.hacs.exceptions import HacsException
|
||||
from custom_components.hacs.helpers.functions.misc import extract_repository_from_url
|
||||
from custom_components.hacs.helpers.functions.register_repository import (
|
||||
register_repository,
|
||||
)
|
||||
from custom_components.hacs.share import get_hacs
|
||||
from custom_components.hacs.utils.logger import getLogger
|
||||
|
||||
_LOGGER = getLogger()
|
||||
|
||||
|
||||
@websocket_api.async_response
|
||||
@websocket_api.websocket_command(
|
||||
{
|
||||
vol.Required("type"): "hacs/repository/data",
|
||||
vol.Optional("action"): cv.string,
|
||||
vol.Optional("repository"): cv.string,
|
||||
vol.Optional("data"): cv.string,
|
||||
}
|
||||
)
|
||||
async def hacs_repository_data(hass, connection, msg):
|
||||
"""Handle get media player cover command."""
|
||||
hacs = get_hacs()
|
||||
repo_id = msg.get("repository")
|
||||
action = msg.get("action")
|
||||
data = msg.get("data")
|
||||
|
||||
if repo_id is None:
|
||||
return
|
||||
|
||||
if action == "add":
|
||||
repo_id = extract_repository_from_url(repo_id)
|
||||
if repo_id is None:
|
||||
return
|
||||
|
||||
if repo_id in hacs.common.skip:
|
||||
hacs.common.skip.remove(repo_id)
|
||||
|
||||
if hacs.common.renamed_repositories.get(repo_id):
|
||||
repo_id = hacs.common.renamed_repositories[repo_id]
|
||||
|
||||
if not hacs.get_by_name(repo_id):
|
||||
try:
|
||||
registration = await register_repository(repo_id, data.lower())
|
||||
if registration is not None:
|
||||
raise HacsException(registration)
|
||||
except (
|
||||
Exception,
|
||||
BaseException,
|
||||
) as exception: # pylint: disable=broad-except
|
||||
hass.bus.async_fire(
|
||||
"hacs/error",
|
||||
{
|
||||
"action": "add_repository",
|
||||
"exception": str(sys.exc_info()[0].__name__),
|
||||
"message": str(exception),
|
||||
},
|
||||
)
|
||||
else:
|
||||
hass.bus.async_fire(
|
||||
"hacs/error",
|
||||
{
|
||||
"action": "add_repository",
|
||||
"message": f"Repository '{repo_id}' exists in the store.",
|
||||
},
|
||||
)
|
||||
|
||||
repository = hacs.get_by_name(repo_id)
|
||||
else:
|
||||
repository = hacs.get_by_id(repo_id)
|
||||
|
||||
if repository is None:
|
||||
hass.bus.async_fire("hacs/repository", {})
|
||||
return
|
||||
|
||||
_LOGGER.debug("Running %s for %s", action, repository.data.full_name)
|
||||
try:
|
||||
if action == "set_state":
|
||||
repository.state = data
|
||||
|
||||
elif action == "set_version":
|
||||
repository.data.selected_tag = data
|
||||
await repository.update_repository()
|
||||
|
||||
repository.state = None
|
||||
|
||||
elif action == "install":
|
||||
was_installed = repository.data.installed
|
||||
repository.data.selected_tag = data
|
||||
await repository.update_repository()
|
||||
await repository.async_install()
|
||||
repository.state = None
|
||||
if not was_installed:
|
||||
hass.bus.async_fire("hacs/reload", {"force": True})
|
||||
|
||||
elif action == "add":
|
||||
repository.state = None
|
||||
|
||||
else:
|
||||
repository.state = None
|
||||
_LOGGER.error("WS action '%s' is not valid", action)
|
||||
|
||||
message = None
|
||||
except AIOGitHubAPIException as exception:
|
||||
message = exception
|
||||
except AttributeError as exception:
|
||||
message = f"Could not use repository with ID {repo_id} ({exception})"
|
||||
except (Exception, BaseException) as exception: # pylint: disable=broad-except
|
||||
message = exception
|
||||
|
||||
if message is not None:
|
||||
_LOGGER.error(message)
|
||||
hass.bus.async_fire("hacs/error", {"message": str(message)})
|
||||
|
||||
await hacs.data.async_write()
|
||||
connection.send_message(websocket_api.result_message(msg["id"], {}))
|
@ -1,54 +0,0 @@
|
||||
"""API Handler for hacs_settings"""
|
||||
from homeassistant.components import websocket_api
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
import voluptuous as vol
|
||||
|
||||
from custom_components.hacs.share import get_hacs
|
||||
from custom_components.hacs.utils.logger import getLogger
|
||||
|
||||
_LOGGER = getLogger()
|
||||
|
||||
|
||||
@websocket_api.async_response
|
||||
@websocket_api.websocket_command(
|
||||
{
|
||||
vol.Required("type"): "hacs/settings",
|
||||
vol.Optional("action"): cv.string,
|
||||
vol.Optional("categories"): cv.ensure_list,
|
||||
}
|
||||
)
|
||||
async def hacs_settings(hass, connection, msg):
|
||||
"""Handle get media player cover command."""
|
||||
hacs = get_hacs()
|
||||
|
||||
action = msg["action"]
|
||||
_LOGGER.debug("WS action '%s'", action)
|
||||
|
||||
if action == "set_fe_grid":
|
||||
hacs.configuration.frontend_mode = "Grid"
|
||||
|
||||
elif action == "onboarding_done":
|
||||
hacs.configuration.onboarding_done = True
|
||||
|
||||
elif action == "set_fe_table":
|
||||
hacs.configuration.frontend_mode = "Table"
|
||||
|
||||
elif action == "set_fe_compact_true":
|
||||
hacs.configuration.frontend_compact = False
|
||||
|
||||
elif action == "set_fe_compact_false":
|
||||
hacs.configuration.frontend_compact = True
|
||||
|
||||
elif action == "clear_new":
|
||||
for repo in hacs.repositories:
|
||||
if repo.data.new and repo.data.category in msg.get("categories", []):
|
||||
_LOGGER.debug(
|
||||
"Clearing new flag from '%s'",
|
||||
repo.data.full_name,
|
||||
)
|
||||
repo.data.new = False
|
||||
else:
|
||||
_LOGGER.error("WS action '%s' is not valid", action)
|
||||
hass.bus.async_fire("hacs/config", {})
|
||||
await hacs.data.async_write()
|
||||
connection.send_message(websocket_api.result_message(msg["id"], {}))
|
@ -1,24 +0,0 @@
|
||||
"""API Handler for hacs_status"""
|
||||
from homeassistant.components import websocket_api
|
||||
import voluptuous as vol
|
||||
|
||||
from custom_components.hacs.share import get_hacs
|
||||
|
||||
|
||||
@websocket_api.async_response
|
||||
@websocket_api.websocket_command({vol.Required("type"): "hacs/status"})
|
||||
async def hacs_status(_hass, connection, msg):
|
||||
"""Handle get media player cover command."""
|
||||
hacs = get_hacs()
|
||||
content = {
|
||||
"startup": hacs.status.startup,
|
||||
"background_task": hacs.status.background_task,
|
||||
"lovelace_mode": hacs.core.lovelace_mode,
|
||||
"reloading_data": hacs.status.reloading_data,
|
||||
"upgrading_all": hacs.status.upgrading_all,
|
||||
"disabled": hacs.system.disabled,
|
||||
"disabled_reason": hacs.system.disabled_reason,
|
||||
"has_pending_tasks": hacs.queue.has_pending_tasks,
|
||||
"stage": hacs.stage,
|
||||
}
|
||||
connection.send_message(websocket_api.result_message(msg["id"], content))
|
@ -1,21 +1,22 @@
|
||||
"""Register WS API endpoints for HACS."""
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
|
||||
from aiogithubapi import AIOGitHubAPIException
|
||||
from homeassistant.components import websocket_api
|
||||
from homeassistant.components.websocket_api import async_register_command
|
||||
from homeassistant.core import HomeAssistant
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
import voluptuous as vol
|
||||
|
||||
from ..api.acknowledge_critical_repository import acknowledge_critical_repository
|
||||
from ..api.check_local_path import check_local_path
|
||||
from ..api.get_critical_repositories import get_critical_repositories
|
||||
from ..api.hacs_config import hacs_config
|
||||
from ..api.hacs_removed import hacs_removed
|
||||
from ..api.hacs_repositories import hacs_repositories
|
||||
from ..api.hacs_repository import hacs_repository
|
||||
from ..api.hacs_repository_data import hacs_repository_data
|
||||
from ..api.hacs_settings import hacs_settings
|
||||
from ..api.hacs_status import hacs_status
|
||||
from ..base import HacsBase
|
||||
from ..enums import HacsStage
|
||||
from ..exceptions import HacsException
|
||||
from ..helpers.functions.misc import extract_repository_from_url
|
||||
from ..helpers.functions.register_repository import register_repository
|
||||
from ..helpers.functions.store import async_load_from_store, async_save_to_store
|
||||
from ..share import get_hacs, list_removed_repositories
|
||||
from .base import HacsTask
|
||||
|
||||
|
||||
@ -30,13 +31,441 @@ class Task(HacsTask):
|
||||
stages = [HacsStage.SETUP]
|
||||
|
||||
async def async_execute(self) -> None:
|
||||
"""Execute this task."""
|
||||
async_register_command(self.hass, hacs_settings)
|
||||
async_register_command(self.hass, hacs_config)
|
||||
async_register_command(self.hass, hacs_repositories)
|
||||
async_register_command(self.hass, hacs_repository)
|
||||
async_register_command(self.hass, hacs_repository_data)
|
||||
async_register_command(self.hass, check_local_path)
|
||||
async_register_command(self.hass, hacs_status)
|
||||
async_register_command(self.hass, hacs_removed)
|
||||
async_register_command(self.hass, acknowledge_critical_repository)
|
||||
async_register_command(self.hass, get_critical_repositories)
|
||||
|
||||
|
||||
@websocket_api.websocket_command(
|
||||
{
|
||||
vol.Required("type"): "hacs/critical",
|
||||
vol.Optional("repository"): cv.string,
|
||||
}
|
||||
)
|
||||
@websocket_api.require_admin
|
||||
@websocket_api.async_response
|
||||
async def acknowledge_critical_repository(hass, connection, msg):
|
||||
"""Handle get media player cover command."""
|
||||
repository = msg["repository"]
|
||||
|
||||
critical = await async_load_from_store(hass, "critical")
|
||||
for repo in critical:
|
||||
if repository == repo["repository"]:
|
||||
repo["acknowledged"] = True
|
||||
await async_save_to_store(hass, "critical", critical)
|
||||
connection.send_message(websocket_api.result_message(msg["id"], critical))
|
||||
|
||||
|
||||
@websocket_api.websocket_command(
|
||||
{
|
||||
vol.Required("type"): "hacs/get_critical",
|
||||
}
|
||||
)
|
||||
@websocket_api.require_admin
|
||||
@websocket_api.async_response
|
||||
async def get_critical_repositories(hass, connection, msg):
|
||||
"""Handle get media player cover command."""
|
||||
critical = await async_load_from_store(hass, "critical")
|
||||
if not critical:
|
||||
critical = []
|
||||
connection.send_message(websocket_api.result_message(msg["id"], critical))
|
||||
|
||||
|
||||
@websocket_api.websocket_command(
|
||||
{
|
||||
vol.Required("type"): "hacs/config",
|
||||
}
|
||||
)
|
||||
@websocket_api.require_admin
|
||||
@websocket_api.async_response
|
||||
async def hacs_config(_hass, connection, msg):
|
||||
"""Handle get media player cover command."""
|
||||
hacs = get_hacs()
|
||||
connection.send_message(
|
||||
websocket_api.result_message(
|
||||
msg["id"],
|
||||
{
|
||||
"frontend_mode": hacs.configuration.frontend_mode,
|
||||
"frontend_compact": hacs.configuration.frontend_compact,
|
||||
"onboarding_done": hacs.configuration.onboarding_done,
|
||||
"version": hacs.version,
|
||||
"frontend_expected": hacs.frontend.version_expected,
|
||||
"frontend_running": hacs.frontend.version_running,
|
||||
"dev": hacs.configuration.dev,
|
||||
"debug": hacs.configuration.debug,
|
||||
"country": hacs.configuration.country,
|
||||
"experimental": hacs.configuration.experimental,
|
||||
"categories": hacs.common.categories,
|
||||
},
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@websocket_api.websocket_command(
|
||||
{
|
||||
vol.Required("type"): "hacs/removed",
|
||||
}
|
||||
)
|
||||
@websocket_api.require_admin
|
||||
@websocket_api.async_response
|
||||
async def hacs_removed(_hass, connection, msg):
|
||||
"""Get information about removed repositories."""
|
||||
content = []
|
||||
for repo in list_removed_repositories():
|
||||
content.append(repo.to_json())
|
||||
connection.send_message(websocket_api.result_message(msg["id"], content))
|
||||
|
||||
|
||||
@websocket_api.websocket_command(
|
||||
{
|
||||
vol.Required("type"): "hacs/repositories",
|
||||
vol.Optional("categories"): [str],
|
||||
}
|
||||
)
|
||||
@websocket_api.require_admin
|
||||
@websocket_api.async_response
|
||||
async def hacs_repositories(_hass, connection, msg):
|
||||
"""Handle get media player cover command."""
|
||||
hacs = get_hacs()
|
||||
connection.send_message(
|
||||
websocket_api.result_message(
|
||||
msg["id"],
|
||||
[
|
||||
{
|
||||
"additional_info": repo.information.additional_info,
|
||||
"authors": repo.data.authors,
|
||||
"available_version": repo.display_available_version,
|
||||
"beta": repo.data.show_beta,
|
||||
"can_install": repo.can_install,
|
||||
"category": repo.data.category,
|
||||
"config_flow": repo.data.config_flow,
|
||||
"country": repo.data.country,
|
||||
"custom": repo.custom,
|
||||
"default_branch": repo.data.default_branch,
|
||||
"description": repo.data.description,
|
||||
"domain": repo.data.domain,
|
||||
"downloads": repo.data.downloads,
|
||||
"file_name": repo.data.file_name,
|
||||
"first_install": repo.status.first_install,
|
||||
"full_name": repo.data.full_name,
|
||||
"hide_default_branch": repo.data.hide_default_branch,
|
||||
"hide": repo.data.hide,
|
||||
"homeassistant": repo.data.homeassistant,
|
||||
"id": repo.data.id,
|
||||
"info": repo.information.info,
|
||||
"installed_version": repo.display_installed_version,
|
||||
"installed": repo.data.installed,
|
||||
"issues": repo.data.open_issues,
|
||||
"javascript_type": repo.information.javascript_type,
|
||||
"last_updated": repo.data.last_updated,
|
||||
"local_path": repo.content.path.local,
|
||||
"main_action": repo.main_action,
|
||||
"name": repo.display_name,
|
||||
"new": repo.data.new,
|
||||
"pending_upgrade": repo.pending_upgrade,
|
||||
"releases": repo.data.published_tags,
|
||||
"selected_tag": repo.data.selected_tag,
|
||||
"stars": repo.data.stargazers_count,
|
||||
"state": repo.state,
|
||||
"status_description": repo.display_status_description,
|
||||
"status": repo.display_status,
|
||||
"topics": repo.data.topics,
|
||||
"updated_info": repo.status.updated_info,
|
||||
"version_or_commit": repo.display_version_or_commit,
|
||||
}
|
||||
for repo in hacs.repositories
|
||||
if repo.data.category in (msg.get("categories") or hacs.common.categories)
|
||||
and not repo.ignored_by_country_configuration
|
||||
],
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@websocket_api.websocket_command(
|
||||
{
|
||||
vol.Required("type"): "hacs/repository/data",
|
||||
vol.Optional("action"): cv.string,
|
||||
vol.Optional("repository"): cv.string,
|
||||
vol.Optional("data"): cv.string,
|
||||
}
|
||||
)
|
||||
@websocket_api.require_admin
|
||||
@websocket_api.async_response
|
||||
async def hacs_repository_data(hass, connection, msg):
|
||||
"""Handle get media player cover command."""
|
||||
hacs = get_hacs()
|
||||
repo_id = msg.get("repository")
|
||||
action = msg.get("action")
|
||||
data = msg.get("data")
|
||||
|
||||
if repo_id is None:
|
||||
return
|
||||
|
||||
if action == "add":
|
||||
repo_id = extract_repository_from_url(repo_id)
|
||||
if repo_id is None:
|
||||
return
|
||||
|
||||
if repo_id in hacs.common.skip:
|
||||
hacs.common.skip.remove(repo_id)
|
||||
|
||||
if hacs.common.renamed_repositories.get(repo_id):
|
||||
repo_id = hacs.common.renamed_repositories[repo_id]
|
||||
|
||||
if not hacs.get_by_name(repo_id):
|
||||
try:
|
||||
registration = await register_repository(repo_id, data.lower())
|
||||
if registration is not None:
|
||||
raise HacsException(registration)
|
||||
except (
|
||||
Exception,
|
||||
BaseException,
|
||||
) as exception: # pylint: disable=broad-except
|
||||
hass.bus.async_fire(
|
||||
"hacs/error",
|
||||
{
|
||||
"action": "add_repository",
|
||||
"exception": str(sys.exc_info()[0].__name__),
|
||||
"message": str(exception),
|
||||
},
|
||||
)
|
||||
else:
|
||||
hass.bus.async_fire(
|
||||
"hacs/error",
|
||||
{
|
||||
"action": "add_repository",
|
||||
"message": f"Repository '{repo_id}' exists in the store.",
|
||||
},
|
||||
)
|
||||
|
||||
repository = hacs.get_by_name(repo_id)
|
||||
else:
|
||||
repository = hacs.get_by_id(repo_id)
|
||||
|
||||
if repository is None:
|
||||
hass.bus.async_fire("hacs/repository", {})
|
||||
return
|
||||
|
||||
hacs.log.debug("Running %s for %s", action, repository.data.full_name)
|
||||
try:
|
||||
if action == "set_state":
|
||||
repository.state = data
|
||||
|
||||
elif action == "set_version":
|
||||
repository.data.selected_tag = data
|
||||
await repository.update_repository()
|
||||
|
||||
repository.state = None
|
||||
|
||||
elif action == "install":
|
||||
was_installed = repository.data.installed
|
||||
repository.data.selected_tag = data
|
||||
await repository.update_repository()
|
||||
await repository.async_install()
|
||||
repository.state = None
|
||||
if not was_installed:
|
||||
hass.bus.async_fire("hacs/reload", {"force": True})
|
||||
|
||||
elif action == "add":
|
||||
repository.state = None
|
||||
|
||||
else:
|
||||
repository.state = None
|
||||
hacs.log.error("WS action '%s' is not valid", action)
|
||||
|
||||
message = None
|
||||
except AIOGitHubAPIException as exception:
|
||||
message = exception
|
||||
except AttributeError as exception:
|
||||
message = f"Could not use repository with ID {repo_id} ({exception})"
|
||||
except (Exception, BaseException) as exception: # pylint: disable=broad-except
|
||||
message = exception
|
||||
|
||||
if message is not None:
|
||||
hacs.log.error(message)
|
||||
hass.bus.async_fire("hacs/error", {"message": str(message)})
|
||||
|
||||
await hacs.data.async_write()
|
||||
connection.send_message(websocket_api.result_message(msg["id"], {}))
|
||||
|
||||
|
||||
@websocket_api.websocket_command(
|
||||
{
|
||||
vol.Required("type"): "hacs/repository",
|
||||
vol.Optional("action"): cv.string,
|
||||
vol.Optional("repository"): cv.string,
|
||||
}
|
||||
)
|
||||
@websocket_api.require_admin
|
||||
@websocket_api.async_response
|
||||
async def hacs_repository(hass, connection, msg):
|
||||
"""Handle get media player cover command."""
|
||||
hacs = get_hacs()
|
||||
data = {}
|
||||
repository = None
|
||||
|
||||
repo_id = msg.get("repository")
|
||||
action = msg.get("action")
|
||||
if repo_id is None or action is None:
|
||||
return
|
||||
|
||||
try:
|
||||
repository = hacs.get_by_id(repo_id)
|
||||
hacs.log.debug(f"Running {action} for {repository.data.full_name}")
|
||||
|
||||
if action == "update":
|
||||
await repository.update_repository(ignore_issues=True, force=True)
|
||||
repository.status.updated_info = True
|
||||
|
||||
elif action == "install":
|
||||
repository.data.new = False
|
||||
was_installed = repository.data.installed
|
||||
await repository.async_install()
|
||||
if not was_installed:
|
||||
hass.bus.async_fire("hacs/reload", {"force": True})
|
||||
|
||||
elif action == "not_new":
|
||||
repository.data.new = False
|
||||
|
||||
elif action == "uninstall":
|
||||
repository.data.new = False
|
||||
await repository.update_repository(True)
|
||||
await repository.uninstall()
|
||||
|
||||
elif action == "hide":
|
||||
repository.data.hide = True
|
||||
|
||||
elif action == "unhide":
|
||||
repository.data.hide = False
|
||||
|
||||
elif action == "show_beta":
|
||||
repository.data.show_beta = True
|
||||
await repository.update_repository()
|
||||
|
||||
elif action == "hide_beta":
|
||||
repository.data.show_beta = False
|
||||
await repository.update_repository()
|
||||
|
||||
elif action == "toggle_beta":
|
||||
repository.data.show_beta = not repository.data.show_beta
|
||||
await repository.update_repository()
|
||||
|
||||
elif action == "delete":
|
||||
repository.data.show_beta = False
|
||||
repository.remove()
|
||||
|
||||
elif action == "release_notes":
|
||||
data = [
|
||||
{
|
||||
"name": x.attributes["name"],
|
||||
"body": x.attributes["body"],
|
||||
"tag": x.attributes["tag_name"],
|
||||
}
|
||||
for x in repository.releases.objects
|
||||
]
|
||||
|
||||
elif action == "set_version":
|
||||
if msg["version"] == repository.data.default_branch:
|
||||
repository.data.selected_tag = None
|
||||
else:
|
||||
repository.data.selected_tag = msg["version"]
|
||||
await repository.update_repository()
|
||||
|
||||
hass.bus.async_fire("hacs/reload", {"force": True})
|
||||
|
||||
else:
|
||||
hacs.log.error(f"WS action '{action}' is not valid")
|
||||
|
||||
await hacs.data.async_write()
|
||||
message = None
|
||||
except AIOGitHubAPIException as exception:
|
||||
message = exception
|
||||
except AttributeError as exception:
|
||||
message = f"Could not use repository with ID {repo_id} ({exception})"
|
||||
except (Exception, BaseException) as exception: # pylint: disable=broad-except
|
||||
message = exception
|
||||
|
||||
if message is not None:
|
||||
hacs.log.error(message)
|
||||
hass.bus.async_fire("hacs/error", {"message": str(message)})
|
||||
|
||||
if repository:
|
||||
repository.state = None
|
||||
connection.send_message(websocket_api.result_message(msg["id"], data))
|
||||
|
||||
|
||||
@websocket_api.websocket_command(
|
||||
{
|
||||
vol.Required("type"): "hacs/settings",
|
||||
vol.Optional("action"): cv.string,
|
||||
vol.Optional("categories"): cv.ensure_list,
|
||||
}
|
||||
)
|
||||
@websocket_api.require_admin
|
||||
@websocket_api.async_response
|
||||
async def hacs_settings(hass, connection, msg):
|
||||
"""Handle get media player cover command."""
|
||||
hacs = get_hacs()
|
||||
|
||||
action = msg["action"]
|
||||
hacs.log.debug("WS action '%s'", action)
|
||||
|
||||
if action == "set_fe_grid":
|
||||
hacs.configuration.frontend_mode = "Grid"
|
||||
|
||||
elif action == "onboarding_done":
|
||||
hacs.configuration.onboarding_done = True
|
||||
|
||||
elif action == "set_fe_table":
|
||||
hacs.configuration.frontend_mode = "Table"
|
||||
|
||||
elif action == "set_fe_compact_true":
|
||||
hacs.configuration.frontend_compact = False
|
||||
|
||||
elif action == "set_fe_compact_false":
|
||||
hacs.configuration.frontend_compact = True
|
||||
|
||||
elif action == "clear_new":
|
||||
for repo in hacs.repositories:
|
||||
if repo.data.new and repo.data.category in msg.get("categories", []):
|
||||
hacs.log.debug(
|
||||
"Clearing new flag from '%s'",
|
||||
repo.data.full_name,
|
||||
)
|
||||
repo.data.new = False
|
||||
else:
|
||||
hacs.log.error("WS action '%s' is not valid", action)
|
||||
hass.bus.async_fire("hacs/config", {})
|
||||
await hacs.data.async_write()
|
||||
connection.send_message(websocket_api.result_message(msg["id"], {}))
|
||||
|
||||
|
||||
@websocket_api.websocket_command({vol.Required("type"): "hacs/status"})
|
||||
@websocket_api.require_admin
|
||||
@websocket_api.async_response
|
||||
async def hacs_status(_hass, connection, msg):
|
||||
"""Handle get media player cover command."""
|
||||
hacs = get_hacs()
|
||||
connection.send_message(
|
||||
websocket_api.result_message(
|
||||
msg["id"],
|
||||
{
|
||||
"startup": hacs.status.startup,
|
||||
"background_task": hacs.status.background_task,
|
||||
"lovelace_mode": hacs.core.lovelace_mode,
|
||||
"reloading_data": hacs.status.reloading_data,
|
||||
"upgrading_all": hacs.status.upgrading_all,
|
||||
"disabled": hacs.system.disabled,
|
||||
"disabled_reason": hacs.system.disabled_reason,
|
||||
"has_pending_tasks": hacs.queue.has_pending_tasks,
|
||||
"stage": hacs.stage,
|
||||
},
|
||||
)
|
||||
)
|
||||
|
@ -3,28 +3,23 @@ import os
|
||||
from homeassistant.core import HomeAssistant
|
||||
import pytest
|
||||
|
||||
from custom_components.hacs.api.acknowledge_critical_repository import (
|
||||
from custom_components.hacs.tasks.setup_websocket_api import (
|
||||
acknowledge_critical_repository,
|
||||
)
|
||||
from custom_components.hacs.api.check_local_path import check_local_path
|
||||
from custom_components.hacs.api.get_critical_repositories import (
|
||||
get_critical_repositories,
|
||||
hacs_config,
|
||||
hacs_removed,
|
||||
hacs_repositories,
|
||||
hacs_repository,
|
||||
hacs_repository_data,
|
||||
hacs_settings,
|
||||
hacs_status,
|
||||
)
|
||||
from custom_components.hacs.api.hacs_config import hacs_config
|
||||
from custom_components.hacs.api.hacs_removed import hacs_removed
|
||||
from custom_components.hacs.api.hacs_repositories import hacs_repositories
|
||||
from custom_components.hacs.api.hacs_repository import hacs_repository
|
||||
from custom_components.hacs.api.hacs_repository_data import hacs_repository_data
|
||||
from custom_components.hacs.api.hacs_settings import hacs_settings
|
||||
from custom_components.hacs.api.hacs_status import hacs_status
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_check_local_path(hacs, connection, tmpdir):
|
||||
hacs.hass = HomeAssistant()
|
||||
os.makedirs(tmpdir, exist_ok=True)
|
||||
check_local_path(hacs.hass, connection, {"path": tmpdir, "id": 1})
|
||||
check_local_path(hacs.hass, connection, {"id": 1})
|
||||
get_critical_repositories(hacs.hass, connection, {"id": 1})
|
||||
hacs_config(hacs.hass, connection, {"id": 1})
|
||||
hacs_removed(hacs.hass, connection, {"id": 1})
|
||||
|
@ -17,4 +17,4 @@ async def test_setup_websocket_api(hacs: HacsBase):
|
||||
"custom_components.hacs.tasks.setup_websocket_api.async_register_command"
|
||||
) as mock_async_register_command:
|
||||
await task.execute_task()
|
||||
assert mock_async_register_command.call_count == 10
|
||||
assert mock_async_register_command.call_count == 9
|
||||
|
Reference in New Issue
Block a user