|
1 | 1 | """Store client for supervisor.""" |
2 | 2 |
|
| 3 | +import re |
3 | 4 | from typing import Any |
4 | 5 |
|
5 | 6 | from .client import _SupervisorComponentClient |
6 | 7 | from .const import ResponseType |
| 8 | +from .exceptions import ( |
| 9 | + AddonNotSupportedArchitectureError, |
| 10 | + AddonNotSupportedError, |
| 11 | + AddonNotSupportedHomeAssistantVersionError, |
| 12 | + AddonNotSupportedMachineTypeError, |
| 13 | + SupervisorBadRequestError, |
| 14 | +) |
7 | 15 | from .models.addons import ( |
8 | 16 | Repository, |
9 | 17 | StoreAddon, |
|
15 | 23 | StoreInfo, |
16 | 24 | ) |
17 | 25 |
|
| 26 | +RE_ADDON_UNAVAILABLE_ARCHITECTURE = re.compile( |
| 27 | + r"^Add\-on (?P<addon>\w+) not supported on this platform, " |
| 28 | + r"supported architectures: (?P<architectures>.*)$" |
| 29 | +) |
| 30 | +RE_ADDON_UNAVAILABLE_MACHINE_TYPE = re.compile( |
| 31 | + r"^Add\-on (?P<addon>\w+) not supported on this machine, " |
| 32 | + r"supported machine types: (?P<machine_types>.*)$" |
| 33 | +) |
| 34 | +RE_ADDON_UNAVAILABLE_HOME_ASSISTANT = re.compile( |
| 35 | + r"^Add\-on (?P<addon>\w+) not supported on this system, " |
| 36 | + r"requires Home Assistant version (?P<version>\S+) or greater$" |
| 37 | +) |
| 38 | + |
18 | 39 |
|
19 | 40 | class StoreClient(_SupervisorComponentClient): |
20 | 41 | """Handles store access in Supervisor.""" |
@@ -48,6 +69,37 @@ async def addon_documentation(self, addon: str) -> str: |
48 | 69 | ) |
49 | 70 | return result.data |
50 | 71 |
|
| 72 | + async def addon_availability(self, addon: str) -> None: |
| 73 | + """Determine if latest version of addon can be installed on this system. |
| 74 | +
|
| 75 | + No return means it can be. If not, raises one of the following errors: |
| 76 | + - AddonUnavailableHomeAssistantVersionError |
| 77 | + - AddonUnavailableArchitectureError |
| 78 | + - AddonUnavailableMachineTypeError |
| 79 | +
|
| 80 | + If Supervisor adds a new reason an add-on can be restricted from being |
| 81 | + installed on some systems in the future, older versions of this client |
| 82 | + will raise the generic AddonNotSupportedError for that reason. |
| 83 | + """ |
| 84 | + try: |
| 85 | + await self._client.get( |
| 86 | + f"store/addons/{addon}/availability", response_type=ResponseType.NONE |
| 87 | + ) |
| 88 | + except SupervisorBadRequestError as err: |
| 89 | + if match := RE_ADDON_UNAVAILABLE_ARCHITECTURE.match(str(err)): |
| 90 | + raise AddonNotSupportedArchitectureError( |
| 91 | + match.group("addon"), match.group("architectures"), err.job_id |
| 92 | + ) from None |
| 93 | + if match := RE_ADDON_UNAVAILABLE_HOME_ASSISTANT.match(str(err)): |
| 94 | + raise AddonNotSupportedHomeAssistantVersionError( |
| 95 | + match.group("addon"), match.group("version"), err.job_id |
| 96 | + ) from None |
| 97 | + if match := RE_ADDON_UNAVAILABLE_MACHINE_TYPE.match(str(err)): |
| 98 | + raise AddonNotSupportedMachineTypeError( |
| 99 | + match.group("addon"), match.group("machine_types"), err.job_id |
| 100 | + ) from None |
| 101 | + raise AddonNotSupportedError(str(err), err.job_id) from None |
| 102 | + |
51 | 103 | async def install_addon( |
52 | 104 | self, addon: str, options: StoreAddonInstall | None = None |
53 | 105 | ) -> None: |
|
0 commit comments