repository.py 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. """Register info websocket commands."""
  2. from __future__ import annotations
  3. from typing import TYPE_CHECKING, Any
  4. from homeassistant.components import websocket_api
  5. from homeassistant.core import HomeAssistant
  6. import homeassistant.helpers.config_validation as cv
  7. import voluptuous as vol
  8. from ..const import DOMAIN
  9. from ..enums import HacsDispatchEvent
  10. from ..utils.version import version_left_higher_then_right
  11. if TYPE_CHECKING:
  12. from ..base import HacsBase
  13. @websocket_api.websocket_command(
  14. {
  15. vol.Required("type"): "hacs/repository/info",
  16. vol.Required("repository_id"): str,
  17. }
  18. )
  19. @websocket_api.require_admin
  20. @websocket_api.async_response
  21. async def hacs_repository_info(
  22. hass: HomeAssistant,
  23. connection: websocket_api.ActiveConnection,
  24. msg: dict[str, Any],
  25. ) -> None:
  26. """Return information about HACS."""
  27. hacs: HacsBase = hass.data.get(DOMAIN)
  28. repository = hacs.repositories.get_by_id(msg["repository_id"])
  29. if repository is None:
  30. connection.send_error(msg["id"], "repository_not_found", "Repository not found")
  31. return
  32. if not repository.updated_info:
  33. await repository.update_repository(ignore_issues=True, force=True)
  34. repository.updated_info = True
  35. connection.send_message(
  36. websocket_api.result_message(
  37. msg["id"],
  38. {
  39. "additional_info": repository.additional_info,
  40. "authors": repository.data.authors,
  41. "available_version": repository.display_available_version,
  42. "beta": repository.data.show_beta,
  43. "can_download": repository.can_download,
  44. "category": repository.data.category,
  45. "config_flow": repository.data.config_flow,
  46. "country": repository.repository_manifest.country,
  47. "custom": not hacs.repositories.is_default(str(repository.data.id)),
  48. "default_branch": repository.data.default_branch,
  49. "description": repository.data.description,
  50. "domain": repository.data.domain,
  51. "downloads": repository.data.downloads,
  52. "file_name": repository.data.file_name,
  53. "full_name": repository.data.full_name,
  54. "hide_default_branch": repository.repository_manifest.hide_default_branch,
  55. "homeassistant": repository.repository_manifest.homeassistant,
  56. "id": repository.data.id,
  57. "installed_version": repository.display_installed_version,
  58. "installed": repository.data.installed,
  59. "issues": repository.data.open_issues,
  60. "last_updated": repository.data.last_updated,
  61. "local_path": repository.content.path.local,
  62. "name": repository.display_name,
  63. "new": repository.data.new,
  64. "pending_upgrade": repository.pending_update,
  65. "releases": repository.data.published_tags,
  66. "ref": repository.ref,
  67. "selected_tag": repository.data.selected_tag,
  68. "stars": repository.data.stargazers_count,
  69. "state": repository.state,
  70. "status": repository.display_status,
  71. "topics": repository.data.topics,
  72. "version_or_commit": repository.display_version_or_commit,
  73. },
  74. )
  75. )
  76. @websocket_api.websocket_command(
  77. {
  78. vol.Required("type"): "hacs/repository/ignore",
  79. vol.Required("repository"): str,
  80. }
  81. )
  82. @websocket_api.require_admin
  83. @websocket_api.async_response
  84. async def hacs_repository_ignore(
  85. hass: HomeAssistant,
  86. connection: websocket_api.ActiveConnection,
  87. msg: dict[str, Any],
  88. ):
  89. """Ignore a repository."""
  90. hacs: HacsBase = hass.data.get(DOMAIN)
  91. repository = hacs.repositories.get_by_id(msg["repository"])
  92. hacs.common.ignored_repositories.append(repository.data.full_name)
  93. await hacs.data.async_write()
  94. connection.send_message(websocket_api.result_message(msg["id"]))
  95. @websocket_api.websocket_command(
  96. {
  97. vol.Required("type"): "hacs/repository/state",
  98. vol.Required("repository"): cv.string,
  99. vol.Required("state"): cv.string,
  100. }
  101. )
  102. @websocket_api.require_admin
  103. @websocket_api.async_response
  104. async def hacs_repository_state(
  105. hass: HomeAssistant,
  106. connection: websocket_api.ActiveConnection,
  107. msg: dict[str, Any],
  108. ):
  109. """Set the state of a repository"""
  110. hacs: HacsBase = hass.data.get(DOMAIN)
  111. repository = hacs.repositories.get_by_id(msg["repository"])
  112. repository.state = msg["state"]
  113. await hacs.data.async_write()
  114. connection.send_message(websocket_api.result_message(msg["id"], {}))
  115. @websocket_api.websocket_command(
  116. {
  117. vol.Required("type"): "hacs/repository/version",
  118. vol.Required("repository"): cv.string,
  119. vol.Required("version"): cv.string,
  120. }
  121. )
  122. @websocket_api.require_admin
  123. @websocket_api.async_response
  124. async def hacs_repository_version(
  125. hass: HomeAssistant,
  126. connection: websocket_api.ActiveConnection,
  127. msg: dict[str, Any],
  128. ):
  129. """Set the version of a repository"""
  130. hacs: HacsBase = hass.data.get(DOMAIN)
  131. repository = hacs.repositories.get_by_id(msg["repository"])
  132. if msg["version"] == repository.data.default_branch:
  133. repository.data.selected_tag = None
  134. else:
  135. repository.data.selected_tag = msg["version"]
  136. await repository.update_repository(force=True)
  137. repository.state = None
  138. await hacs.data.async_write()
  139. connection.send_message(websocket_api.result_message(msg["id"], {}))
  140. @websocket_api.websocket_command(
  141. {
  142. vol.Required("type"): "hacs/repository/beta",
  143. vol.Required("repository"): cv.string,
  144. vol.Required("show_beta"): cv.boolean,
  145. }
  146. )
  147. @websocket_api.require_admin
  148. @websocket_api.async_response
  149. async def hacs_repository_beta(
  150. hass: HomeAssistant,
  151. connection: websocket_api.ActiveConnection,
  152. msg: dict[str, Any],
  153. ):
  154. """Show or hide beta versions of a repository"""
  155. hacs: HacsBase = hass.data.get(DOMAIN)
  156. repository = hacs.repositories.get_by_id(msg["repository"])
  157. repository.data.show_beta = msg["show_beta"]
  158. await repository.update_repository(force=True)
  159. repository.state = None
  160. await hacs.data.async_write()
  161. connection.send_message(websocket_api.result_message(msg["id"], {}))
  162. @websocket_api.websocket_command(
  163. {
  164. vol.Required("type"): "hacs/repository/download",
  165. vol.Required("repository"): cv.string,
  166. vol.Optional("version"): cv.string,
  167. }
  168. )
  169. @websocket_api.require_admin
  170. @websocket_api.async_response
  171. async def hacs_repository_download(
  172. hass: HomeAssistant,
  173. connection: websocket_api.ActiveConnection,
  174. msg: dict[str, Any],
  175. ):
  176. """Set the version of a repository"""
  177. hacs: HacsBase = hass.data.get(DOMAIN)
  178. repository = hacs.repositories.get_by_id(msg["repository"])
  179. was_installed = repository.data.installed
  180. if version := msg.get("version"):
  181. repository.data.selected_tag = version
  182. await repository.update_repository(force=True)
  183. await repository.async_install()
  184. repository.state = None
  185. if not was_installed:
  186. hacs.async_dispatch(HacsDispatchEvent.RELOAD, {"force": True})
  187. await hacs.async_recreate_entities()
  188. await hacs.data.async_write()
  189. connection.send_message(websocket_api.result_message(msg["id"], {}))
  190. @websocket_api.websocket_command(
  191. {
  192. vol.Required("type"): "hacs/repository/remove",
  193. vol.Required("repository"): cv.string,
  194. }
  195. )
  196. @websocket_api.require_admin
  197. @websocket_api.async_response
  198. async def hacs_repository_remove(
  199. hass: HomeAssistant,
  200. connection: websocket_api.ActiveConnection,
  201. msg: dict[str, Any],
  202. ):
  203. """Remove a repository."""
  204. hacs: HacsBase = hass.data.get(DOMAIN)
  205. repository = hacs.repositories.get_by_id(msg["repository"])
  206. repository.data.new = False
  207. await repository.update_repository(ignore_issues=True, force=True)
  208. await repository.uninstall()
  209. await hacs.data.async_write()
  210. connection.send_message(websocket_api.result_message(msg["id"], {}))
  211. @websocket_api.websocket_command(
  212. {
  213. vol.Required("type"): "hacs/repository/refresh",
  214. vol.Required("repository"): cv.string,
  215. }
  216. )
  217. @websocket_api.require_admin
  218. @websocket_api.async_response
  219. async def hacs_repository_refresh(
  220. hass: HomeAssistant,
  221. connection: websocket_api.ActiveConnection,
  222. msg: dict[str, Any],
  223. ):
  224. """Refresh a repository."""
  225. hacs: HacsBase = hass.data.get(DOMAIN)
  226. repository = hacs.repositories.get_by_id(msg["repository"])
  227. await repository.update_repository(ignore_issues=True, force=True)
  228. await hacs.data.async_write()
  229. connection.send_message(websocket_api.result_message(msg["id"], {}))
  230. @websocket_api.websocket_command(
  231. {
  232. vol.Required("type"): "hacs/repository/release_notes",
  233. vol.Required("repository"): cv.string,
  234. }
  235. )
  236. @websocket_api.require_admin
  237. @websocket_api.async_response
  238. async def hacs_repository_release_notes(
  239. hass: HomeAssistant,
  240. connection: websocket_api.ActiveConnection,
  241. msg: dict[str, Any],
  242. ):
  243. """Return release notes."""
  244. hacs: HacsBase = hass.data.get(DOMAIN)
  245. repository = hacs.repositories.get_by_id(msg["repository"])
  246. connection.send_message(
  247. websocket_api.result_message(
  248. msg["id"],
  249. [
  250. {
  251. "name": x.name,
  252. "body": x.body,
  253. "tag": x.tag_name,
  254. }
  255. for x in repository.releases.objects
  256. if not repository.data.installed_version
  257. or version_left_higher_then_right(x.tag_name, repository.data.installed_version)
  258. ],
  259. )
  260. )