python_script.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. """Class for python_scripts in HACS."""
  2. from __future__ import annotations
  3. from typing import TYPE_CHECKING
  4. from ..enums import HacsCategory, HacsDispatchEvent
  5. from ..exceptions import HacsException
  6. from ..utils.decorator import concurrent
  7. from .base import HacsRepository
  8. if TYPE_CHECKING:
  9. from ..base import HacsBase
  10. class HacsPythonScriptRepository(HacsRepository):
  11. """python_scripts in HACS."""
  12. category = "python_script"
  13. def __init__(self, hacs: HacsBase, full_name: str):
  14. """Initialize."""
  15. super().__init__(hacs=hacs)
  16. self.data.full_name = full_name
  17. self.data.full_name_lower = full_name.lower()
  18. self.data.category = HacsCategory.PYTHON_SCRIPT
  19. self.content.path.remote = "python_scripts"
  20. self.content.path.local = self.localpath
  21. self.content.single = True
  22. @property
  23. def localpath(self):
  24. """Return localpath."""
  25. return f"{self.hacs.core.config_path}/python_scripts"
  26. async def validate_repository(self):
  27. """Validate."""
  28. # Run common validation steps.
  29. await self.common_validate()
  30. # Custom step 1: Validate content.
  31. if self.repository_manifest.content_in_root:
  32. self.content.path.remote = ""
  33. compliant = False
  34. for treefile in self.treefiles:
  35. if treefile.startswith(f"{self.content.path.remote}") and treefile.endswith(".py"):
  36. compliant = True
  37. break
  38. if not compliant:
  39. raise HacsException(
  40. f"{self.string} Repository structure for {self.ref.replace('tags/','')} is not compliant"
  41. )
  42. # Handle potential errors
  43. if self.validate.errors:
  44. for error in self.validate.errors:
  45. if not self.hacs.status.startup:
  46. self.logger.error("%s %s", self.string, error)
  47. return self.validate.success
  48. async def async_post_registration(self):
  49. """Registration."""
  50. # Set name
  51. self.update_filenames()
  52. if self.hacs.system.action:
  53. await self.hacs.validation.async_run_repository_checks(self)
  54. @concurrent(concurrenttasks=10, backoff_time=5)
  55. async def update_repository(self, ignore_issues=False, force=False):
  56. """Update."""
  57. if not await self.common_update(ignore_issues, force) and not force:
  58. return
  59. # Get python_script objects.
  60. if self.repository_manifest.content_in_root:
  61. self.content.path.remote = ""
  62. compliant = False
  63. for treefile in self.treefiles:
  64. if treefile.startswith(f"{self.content.path.remote}") and treefile.endswith(".py"):
  65. compliant = True
  66. break
  67. if not compliant:
  68. raise HacsException(
  69. f"{self.string} Repository structure for {self.ref.replace('tags/','')} is not compliant"
  70. )
  71. # Update name
  72. self.update_filenames()
  73. # Signal entities to refresh
  74. if self.data.installed:
  75. self.hacs.async_dispatch(
  76. HacsDispatchEvent.REPOSITORY,
  77. {
  78. "id": 1337,
  79. "action": "update",
  80. "repository": self.data.full_name,
  81. "repository_id": self.data.id,
  82. },
  83. )
  84. def update_filenames(self) -> None:
  85. """Get the filename to target."""
  86. for treefile in self.tree:
  87. if treefile.full_path.startswith(
  88. self.content.path.remote
  89. ) and treefile.full_path.endswith(".py"):
  90. self.data.file_name = treefile.filename