manifest.py 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. import logging
  2. from typing import Optional
  3. from .client import ManifestClient
  4. from .exceptions import ManifestFetchError
  5. from .index import ManifestIndex, latest_features_txt_url
  6. from .models import BoardArtifact
  7. class ManifestJSON:
  8. """Facade over cached manifest data for version and firmware-server lookups."""
  9. def __init__(self, url: str, cache_dir: str):
  10. self._client = ManifestClient(url=url, cache_dir=cache_dir)
  11. self._index: Optional[ManifestIndex] = None
  12. self.logger = logging.getLogger(__name__)
  13. @property
  14. def is_available(self) -> bool:
  15. return self._index is not None
  16. def refresh(self) -> None:
  17. try:
  18. manifest = self._client.fetch()
  19. self._index = ManifestIndex.build(manifest)
  20. self.logger.info(
  21. "Manifest index built with releases for %d vehicles",
  22. len(self._index.releases_by_vehicle),
  23. )
  24. except ManifestFetchError:
  25. if self._index is not None:
  26. self.logger.warning(
  27. "Manifest refresh failed, continuing with stale index"
  28. )
  29. return
  30. raise
  31. def get_releases(self, vehicle_id: str) -> list:
  32. if not self.is_available:
  33. return []
  34. return self._index.get_releases(vehicle_id)
  35. def get_board_artifacts(
  36. self,
  37. vehicle_id: str,
  38. release_type: str,
  39. version_number: str,
  40. board_id: str,
  41. ) -> list[BoardArtifact]:
  42. if not self.is_available:
  43. return []
  44. return self._index.get_board_artifacts(
  45. vehicle_id=vehicle_id,
  46. release_type=release_type,
  47. version_number=version_number,
  48. board_id=board_id,
  49. )
  50. def get_features_txt_url(
  51. self,
  52. vehicle_id: str,
  53. release_type: str,
  54. version_number: str,
  55. board_id: str,
  56. ) -> Optional[str]:
  57. if release_type == "tag":
  58. return latest_features_txt_url(vehicle_id, board_id)
  59. if not self.is_available:
  60. return None
  61. return self._index.get_features_txt_url(
  62. vehicle_id=vehicle_id,
  63. release_type=release_type,
  64. version_number=version_number,
  65. board_id=board_id,
  66. )