from sqlalchemy.future import select from sqlalchemy.orm import contains_eager from typing import List from server.constants.favorites import Include as FavoritesInclude from server.db.models.core import Account from server.db.models.users import Device, Favorites, Settings from server.db.users.settings import q_app_versions, q_max_version, q_settings_versions async def get_favorites_with_accounts_include( app_slug: str = None, device: dict = None, user: dict = None, account: dict = None, entity: dict = None, settings: dict = None, include: List[str] = None, ) -> List[Favorites]: """Get favorites with accounts and included devices and settings. Args: app_slug: App code. device: Device filters. user: User filters. account: Account filters. entity: Entity filters. settings: Settings filters. include: Include devices and settings. Returns: List of favorites. """ q = ( select(Favorites) .outerjoin(Favorites.account) .options(contains_eager(Favorites.account)) .where(Account.is_active.is_(True)) ) if (include and FavoritesInclude.DEVICES.value in include) or device: q = q.outerjoin(Account.devices) if include and FavoritesInclude.DEVICES.value in include: q = q.options(contains_eager(Favorites.account, Account.devices)) if (include and FavoritesInclude.SETTINGS.value in include) or settings: q = q.outerjoin(Account.settings) if include and FavoritesInclude.SETTINGS.value in include: q = q.options(contains_eager(Favorites.account, Account.settings)) q = q.where(Settings.type == (settings or {}).get("type")).where(Settings.version == q_max_version(settings)) if app_slug: q = q.where(Account.app_slug == app_slug) if user: q = q.where(Account.user_id.in_(user["id"])) if account: q = q.where(Account.id.in_(account["id"])) if entity: if entity["type"]: q = q.where(Favorites.entity_type == entity["type"]) if entity["id"]: q = q.where(Favorites.entity_id.in_(entity["id"])) if device: if device["is_active"] is not None: q = q.where(Device.status == device["is_active"]) if device["os"]: q = q.where(Device.os.in_(device["os"])) if device["app_version"]: q = q_app_versions(q, device["app_version"]) if settings and settings["versions"]: q = q_settings_versions(q, settings["versions"]) return await Favorites.get_bulk_unique(q.order_by(Favorites.id, Account.id))