Advertisement
Guest User

Untitled

a guest
Jun 13th, 2024
4
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 7.01 KB | None | 0 0
  1. """Hub for Immich integration."""
  2. from __future__ import annotations
  3.  
  4. import logging
  5. from urllib.parse import urljoin
  6.  
  7. import aiohttp
  8.  
  9. from homeassistant.exceptions import HomeAssistantError
  10.  
  11. _HEADER_API_KEY = "x-api-key"
  12. _LOGGER = logging.getLogger(__name__)
  13.  
  14. _ALLOWED_MIME_TYPES = ["image/png", "image/jpeg"]
  15.  
  16.  
  17. class ImmichHub:
  18.     """Immich API hub."""
  19.  
  20.     def __init__(self, host: str, api_key: str) -> None:
  21.         """Initialize."""
  22.         self.host = host
  23.         self.api_key = api_key
  24.  
  25.     async def authenticate(self) -> bool:
  26.         """Test if we can authenticate with the host."""
  27.         try:
  28.             async with aiohttp.ClientSession() as session:
  29.                 url = urljoin(self.host, "/api/auth/validateToken")
  30.                 headers = {"Accept": "application/json", _HEADER_API_KEY: self.api_key}
  31.  
  32.                 async with session.post(url=url, headers=headers) as response:
  33.                     if response.status != 200:
  34.                         raw_result = await response.text()
  35.                         _LOGGER.error("Error from API: body=%s", raw_result)
  36.                         return False
  37.  
  38.                     auth_result = await response.json()
  39.  
  40.                     if not auth_result.get("authStatus"):
  41.                         raw_result = await response.text()
  42.                         _LOGGER.error("Error from API: body=%s", raw_result)
  43.                         return False
  44.  
  45.                     return True
  46.         except aiohttp.ClientError as exception:
  47.             _LOGGER.error("Error connecting to the API: %s", exception)
  48.             raise CannotConnect from exception
  49.  
  50.     async def get_my_user_info(self) -> dict:
  51.         """Get user info."""
  52.         try:
  53.             async with aiohttp.ClientSession() as session:
  54.                 url = urljoin(self.host, "/api/users/me")
  55.                 headers = {"Accept": "application/json", _HEADER_API_KEY: self.api_key}
  56.  
  57.                 async with session.get(url=url, headers=headers) as response:
  58.                     if response.status != 200:
  59.                         raw_result = await response.text()
  60.                         _LOGGER.error("Error from API: body=%s", raw_result)
  61.                         raise ApiError()
  62.  
  63.                     user_info: dict = await response.json()
  64.  
  65.                     return user_info
  66.         except aiohttp.ClientError as exception:
  67.             _LOGGER.error("Error connecting to the API: %s", exception)
  68.             raise CannotConnect from exception
  69.  
  70.     async def download_asset(self, asset_id: str) -> bytes | None:
  71.         """Download the asset."""
  72.         try:
  73.             async with aiohttp.ClientSession() as session:
  74.                 url = urljoin(self.host, f"/api/assets/{asset_id}/original")
  75.                 headers = {_HEADER_API_KEY: self.api_key}
  76.  
  77.                 async with session.get(url=url, headers=headers) as response:
  78.                     if response.status != 200:
  79.                         _LOGGER.error("Error from API: status=%d", response.status)
  80.                         return None
  81.  
  82.                     if response.content_type not in _ALLOWED_MIME_TYPES:
  83.                         _LOGGER.error(
  84.                             "MIME type is not supported: %s", response.content_type
  85.                         )
  86.                         return None
  87.  
  88.                     return await response.read()
  89.         except aiohttp.ClientError as exception:
  90.             _LOGGER.error("Error connecting to the API: %s", exception)
  91.             raise CannotConnect from exception
  92.  
  93.     async def list_favorite_images(self) -> list[dict]:
  94.         """List all favorite images."""
  95.         try:
  96.             async with aiohttp.ClientSession() as session:
  97.                 url = urljoin(self.host, "/api/search/metadata")
  98.                 headers = {"Accept": "application/json", _HEADER_API_KEY: self.api_key}
  99.                 data = {"isFavorite": "true"}
  100.                
  101.                 async with session.post(url=url, headers=headers, data=data) as response:
  102.                     if response.status != 200:
  103.                         raw_result = await response.text()
  104.                         _LOGGER.error("Error from API: body=%s", raw_result)
  105.                         raise ApiError()
  106.                     favorites = await response.json()          
  107.                     assets: list[dict] = favorites["assets"]["items"]
  108.  
  109.  
  110.  
  111.                     filtered_assets: list[dict] = [
  112.                         asset for asset in assets if asset["type"] == "IMAGE"
  113.                     ]
  114.  
  115.                     return filtered_assets
  116.         except aiohttp.ClientError as exception:
  117.             _LOGGER.error("Error connecting to the API: %s", exception)
  118.             raise CannotConnect from exception
  119.  
  120.     async def list_all_albums(self) -> list[dict]:
  121.         """List all albums."""
  122.         try:
  123.             async with aiohttp.ClientSession() as session:
  124.                 url = urljoin(self.host, "/api/albums")
  125.                 headers = {"Accept": "application/json", _HEADER_API_KEY: self.api_key}
  126.  
  127.                 async with session.get(url=url, headers=headers) as response:
  128.                     if response.status != 200:
  129.                         raw_result = await response.text()
  130.                         _LOGGER.error("Error from API: body=%s", raw_result)
  131.                         raise ApiError()
  132.  
  133.                     album_list: list[dict] = await response.json()
  134.  
  135.                     return album_list
  136.         except aiohttp.ClientError as exception:
  137.             _LOGGER.error("Error connecting to the API: %s", exception)
  138.             raise CannotConnect from exception
  139.  
  140.     async def list_album_images(self, album_id: str) -> list[dict]:
  141.         """List all images in an album."""
  142.         try:
  143.             async with aiohttp.ClientSession() as session:
  144.                 url = urljoin(self.host, f"/api/albums/{album_id}")
  145.                 headers = {"Accept": "application/json", _HEADER_API_KEY: self.api_key}
  146.  
  147.                 async with session.get(url=url, headers=headers) as response:
  148.                     if response.status != 200:
  149.                         raw_result = await response.text()
  150.                         _LOGGER.error("Error from API: body=%s", raw_result)
  151.                         raise ApiError()
  152.  
  153.                     album_info: dict = await response.json()
  154.                     assets: list[dict] = album_info["assets"]
  155.  
  156.                     filtered_assets: list[dict] = [
  157.                         asset for asset in assets if asset["type"] == "IMAGE"
  158.                     ]
  159.  
  160.                     return filtered_assets
  161.         except aiohttp.ClientError as exception:
  162.             _LOGGER.error("Error connecting to the API: %s", exception)
  163.             raise CannotConnect from exception
  164.  
  165.  
  166. class CannotConnect(HomeAssistantError):
  167.     """Error to indicate we cannot connect."""
  168.  
  169.  
  170. class InvalidAuth(HomeAssistantError):
  171.     """Error to indicate there is invalid auth."""
  172.  
  173.  
  174. class ApiError(HomeAssistantError):
  175.     """Error to indicate that the API returned an error."""
  176.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement