from dataclasses import dataclass, field, asdict from typing import Dict, Any, List from apollo_utils.core.constants.dsp import DSP from smelog.factory import BoundLogger from charts_messages.config import EVENT from charts_messages.constants import TTL, MessageMetaViews, SUBJECT, NO_SETTINGS_HANDLER, UNIQUE_CHECK_KEY, \ CHART_UPDATE_SUBJECT from charts_messages.utils import get_message_meta_type, get_user_settings_handler def create_base_message_data( account: Dict[str, Any], track: Dict[str, Any], chart: Dict[str, str] ): track["chart"] = chart return { "recipient": { "devices": account["devices"] }, "content": track } @dataclass class BodyMeta: dsp: str country_code: str type: str views: list = field(default_factory=list) subject: str = SUBJECT @dataclass class FullBodyMessage: ttl: int event_id: int account_id: int meta: BodyMeta data: dict = field(default_factory=dict) def create_message( event_id: int, chart: Dict[str, Any], track: Dict[str, Dict[str, Any]], account: Dict[str, Any], ttl: int = TTL ) -> Dict[str, Any]: message_data = create_base_message_data( account=account, track=track, chart=chart ) message = FullBodyMessage( ttl=ttl, event_id=event_id, account_id=account["account_id"], meta=BodyMeta( dsp=chart["dsp"], country_code=chart["country_code"], views=[MessageMetaViews.PUSH.value, MessageMetaViews.FEED.value], type=get_message_meta_type() ), data=message_data ) return asdict(message) def get_user_messages( logger: BoundLogger, event_id: int, chart: Dict[str, Any], tracks: Dict[str, Dict[str, Any]], accounts_to_notify: Dict[str, List[Dict[str, Any]]] ) -> List[Dict[str, Any]]: """ Args: logger: event_id: chart: tracks: accounts_to_notify: Returns: """ result = [] for isrc, track in tracks.items(): accounts = accounts_to_notify.get(isrc) if not accounts: logger.info(f"Users that are interested about track: {isrc}\n" f"has their notifications OFF") continue for account in accounts: result.append( create_message( event_id=event_id, chart=chart, track=track, account=account ) ) return result def create_chart_update_message( event_id: int, chart: Dict[str, Any], account: Dict[str, Any], ttl: int = TTL ) -> Dict[str, Any]: chart["type"] = "regional" if chart["dsp"] == DSP.SPOTIFY.value else None message_data = { "recipient": { "devices": [ { "id": device["id"], "expo_token": device["expo_token"] } for device in account["devices"]] }, "content": { "chart": chart } } account_id = account["account_id"] message = asdict(FullBodyMessage( ttl=ttl, event_id=event_id, account_id=account_id, meta=BodyMeta( dsp=chart["dsp"], country_code=chart["country_code"], views=[MessageMetaViews.PUSH.value, MessageMetaViews.FEED.value], type=get_message_meta_type(), subject=CHART_UPDATE_SUBJECT ), data=message_data )) message[UNIQUE_CHECK_KEY] = f"{event_id}-{account_id}" return message def get_chart_update_messages_for_users( event: Dict[str, Any], user_settings: List[Dict[str, Any]], logger: BoundLogger, ) -> List[Dict[str, Any]]: result = [] for user in user_settings: event_id = event["id"] event_meta = event["meta"] users_settings = user["settings"] users_settings_version = user["settings"]["version"] user_account_id = user["account_id"] logger.info(f"User id: {user_account_id}" f"Settings version: {users_settings_version}") handler = get_user_settings_handler(users_settings_version) logger.info(f"User id: {user_account_id}" f"User settings handler by settings version: {handler.__name__}") if handler == NO_SETTINGS_HANDLER: logger.info(f"No handler for user with id: {user_account_id} and settings version {users_settings_version}") continue if not handler(chart=event_meta, user_settings_data=users_settings["data"]): logger.info(f"User with id {user_account_id} does not want to get chart {EVENT} notifications" f"for country code: {event_meta.get('country_code')}" f"user settings data: {users_settings['data']}") continue result.append(create_chart_update_message(event_id, event_meta, user)) return result