"""Album-related Immich bot commands: albums, favorites, summary.""" from __future__ import annotations import asyncio import logging from typing import Any import aiohttp from notify_bridge_core.providers.immich.asset_utils import get_public_url from ...database.models import ServiceProvider, TelegramBot from ...services import make_immich_provider from ..handler import _get_notification_trackers_for_providers, _render_cmd_template from .common import _format_assets, build_asset_dict _LOGGER = logging.getLogger(__name__) async def _cmd_albums( bot: TelegramBot, providers_map: dict[int, ServiceProvider], locale: str, ) -> dict[str, Any]: provider_ids = set(providers_map.keys()) trackers = await _get_notification_trackers_for_providers(provider_ids) if not trackers: return {"albums": []} albums_data: list[dict] = [] async with aiohttp.ClientSession() as http: for tracker in trackers: provider = providers_map.get(tracker.provider_id) if not provider or provider.type != "immich": continue immich = make_immich_provider(http, provider) album_ids = tracker.collection_ids or [] if not album_ids: continue ext_domain = (provider.config.get("external_domain") or provider.config.get("url", "")).rstrip("/") album_results = await asyncio.gather( *[immich.client.get_album(aid) for aid in album_ids], return_exceptions=True, ) link_results = await asyncio.gather( *[immich.client.get_shared_links(aid) for aid in album_ids], return_exceptions=True, ) for album_id, result, links in zip(album_ids, album_results, link_results): if isinstance(result, Exception): _LOGGER.warning("Failed to fetch album %s: %s", album_id, result) albums_data.append({ "name": f"{album_id[:8]}...", "asset_count": "?", "id": album_id, }) elif result: pub_url = "" if not isinstance(links, Exception) and ext_domain: pub_url = get_public_url(ext_domain, links) or "" albums_data.append({ "name": result.name, "asset_count": result.asset_count, "id": album_id, "public_url": pub_url, }) return {"albums": albums_data} async def cmd_favorites( bot: TelegramBot, providers_map: dict[int, ServiceProvider], all_album_ids: list[str], count: int, locale: str, response_mode: str, client: Any, cmd_templates: dict[str, dict[str, str]], ) -> str | list[dict[str, Any]]: """Handle /favorites command with concurrent album fetching.""" album_ids = all_album_ids[:10] if not album_ids: return _format_assets([], "favorites", "", locale, response_mode, client, cmd_templates) results = await asyncio.gather( *[client.get_album(aid) for aid in album_ids], return_exceptions=True, ) fav_assets: list[dict[str, Any]] = [] for album_id, result in zip(album_ids, results): if isinstance(result, Exception): _LOGGER.warning("Failed to fetch album %s: %s", album_id, result) continue if result: for aid, asset in list(result.assets.items())[:50]: if asset.is_favorite and len(fav_assets) < count: fav_assets.append(build_asset_dict(asset)) if len(fav_assets) >= count: break return _format_assets(fav_assets, "favorites", "", locale, response_mode, client, cmd_templates) async def cmd_summary( client: Any, all_album_ids: list[str], locale: str, cmd_templates: dict[str, dict[str, str]], external_domain: str = "", ) -> str: """Handle /summary command with concurrent album fetching.""" if not all_album_ids: return _render_cmd_template(cmd_templates, "summary", locale, {"albums": []}) album_results = await asyncio.gather( *[client.get_album(aid) for aid in all_album_ids], return_exceptions=True, ) link_results = await asyncio.gather( *[client.get_shared_links(aid) for aid in all_album_ids], return_exceptions=True, ) ext = external_domain.rstrip("/") albums_data: list[dict] = [] for album_id, result, links in zip(all_album_ids, album_results, link_results): if isinstance(result, Exception): _LOGGER.warning("Failed to fetch album %s: %s", album_id, result) continue if result: pub_url = "" if not isinstance(links, Exception) and ext: pub_url = get_public_url(ext, links) or "" albums_data.append({ "name": result.name, "asset_count": result.asset_count, "id": album_id, "public_url": pub_url, }) return _render_cmd_template(cmd_templates, "summary", locale, {"albums": albums_data})