from collections import defaultdict from typing import List, Set from smelog.factory import BoundLogger from apollo_playlists_messages.clients.gate_api import GateApiClient from apollo_playlists_messages.config import FULL_APP_NAME from apollo_playlists_messages.constants import FavoriteEntityType, MessageType from apollo_playlists_messages.utils.favorites import parse_favorites_accounts from apollo_playlists_messages.utils.output import create_messages from apollo_playlists_messages.utils.playlist_id import PlaylistId, starred_id def handler( events: List[dict], ignored_playlists: Set[str], gate_api: GateApiClient, logger: BoundLogger ) -> List[dict]: # outcome messages = [] dsp_to_playlist_ids = defaultdict(set) playlist_starred_ids = set() playlist_starred_id_to_data = {} user_playlist_starred_id_to_accounts, user_dsp_to_accounts = defaultdict(set), defaultdict(set) user_account_to_devices = {} for event in events: self_id = event["playlist"]["id"] if ignored_playlists and self_id in ignored_playlists: continue dsp, self_codes = event["dsp"], event["country_code"] playlist_data = {"event_id": event["id"], "playlist": event["playlist"]} for code in self_codes: playlist_id = PlaylistId(dsp, self_id, code) playlist_starred_id = starred_id(playlist_id) dsp_to_playlist_ids[dsp].add(playlist_id) playlist_starred_id_to_data[playlist_starred_id] = playlist_data playlist_starred_ids.add(playlist_starred_id) playlists_accounts = gate_api.get_favorites_with_accounts( ids=list(playlist_starred_ids), entity_type=FavoriteEntityType.PLAYLIST ) parse_favorites_accounts( entities=playlists_accounts, logger=logger, entity_types=(FavoriteEntityType.PLAYLIST,), type_to_id_to_accounts={FavoriteEntityType.PLAYLIST: user_playlist_starred_id_to_accounts}, type_to_dsp_to_accounts={FavoriteEntityType.PLAYLIST: user_dsp_to_accounts}, account_id_to_devices=user_account_to_devices, ) logger.info( f"{FULL_APP_NAME} detected {len(user_playlist_starred_id_to_accounts)} starred playlists, " f"{len(user_account_to_devices)} active accounts {user_account_to_devices.keys()}\n" f"to send notification for.\nStarred playlists to accounts:\n{user_playlist_starred_id_to_accounts}\n" f"Settings dsp to accounts: {user_dsp_to_accounts}" ) for dsp, playlist_ids in dsp_to_playlist_ids.items(): dsp_accounts = user_dsp_to_accounts.get(dsp) if not dsp_accounts: continue for playlist_id in playlist_ids: playlist_starred_id = starred_id(playlist_id) playlist_accounts = user_playlist_starred_id_to_accounts.get(playlist_starred_id, set()) & dsp_accounts if not playlist_accounts: continue messages.extend( create_messages( account_ids=playlist_accounts, account_id_to_devices=user_account_to_devices, message_type=MessageType.UPDATE, country_code=playlist_id.code, data={"dsp": dsp, "playlist_id": playlist_id, **playlist_starred_id_to_data[playlist_starred_id]}, logger=logger, ) ) return messages