repository.py 9.7 KB

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