def do_clear_mobile_push_notifications_for_ids( user_profile_ids: List[int], message_ids: List[int] ) -> None: if len(message_ids) == 0: return # This function supports clearing notifications for several users # only for the message-edit use case where we'll have a single message_id. assert len(user_profile_ids) == 1 or len(message_ids) == 1 messages_by_user = defaultdict(list) notifications_to_update = list( UserMessage.objects.filter( message_id__in=message_ids, user_profile_id__in=user_profile_ids, ) .extra( where=[UserMessage.where_active_push_notification()], ) .values_list("user_profile_id", "message_id") ) for (user_id, message_id) in notifications_to_update: messages_by_user[user_id].append(message_id) for (user_profile_id, event_message_ids) in messages_by_user.items(): queue_json_publish( "missedmessage_mobile_notifications", { "type": "remove", "user_profile_id": user_profile_id, "message_ids": event_message_ids, }, )
def get_mobile_push_notification_ids( self, user_profile: UserProfile) -> List[int]: return list( UserMessage.objects.filter(user_profile=user_profile, ).extra( where=[UserMessage.where_active_push_notification() ], ).order_by("message_id").values_list("message_id", flat=True))
def get_apns_badge_count( user_profile: UserProfile, read_messages_ids: Optional[Sequence[int]] = []) -> int: return UserMessage.objects.filter(user_profile=user_profile).extra( where=[UserMessage.where_active_push_notification()] ).exclude( # If we've just marked some messages as read, they're still # marked as having active notifications; we'll clear that flag # only after we've sent that update to the devices. So we need # to exclude them explicitly from the count. message_id__in=read_messages_ids).count()
def get_apns_badge_count_future( user_profile: UserProfile, read_messages_ids: Optional[Sequence[int]] = []) -> int: # Future implementation of get_apns_badge_count; unused but # we expect to use this once we resolve client-side bugs. return (UserMessage.objects.filter(user_profile=user_profile).extra( where=[UserMessage.where_active_push_notification()] ).exclude( # If we've just marked some messages as read, they're still # marked as having active notifications; we'll clear that flag # only after we've sent that update to the devices. So we need # to exclude them explicitly from the count. message_id__in=read_messages_ids).count())
def do_mark_all_as_read(user_profile: UserProfile) -> int: log_statsd_event("bankruptcy") # First, we clear mobile push notifications. This is safer in the # event that the below logic times out and we're killed. all_push_message_ids = ( UserMessage.objects.filter( user_profile=user_profile, ) .extra( where=[UserMessage.where_active_push_notification()], ) .values_list("message_id", flat=True)[0:10000] ) do_clear_mobile_push_notifications_for_ids([user_profile.id], all_push_message_ids) msgs = UserMessage.objects.filter(user_profile=user_profile).extra( where=[UserMessage.where_unread()], ) count = msgs.update( flags=F("flags").bitor(UserMessage.flags.read), ) event = asdict( ReadMessagesEvent( messages=[], # we don't send messages, since the client reloads anyway all=True, ) ) event_time = timezone_now() send_event(user_profile.realm, event, [user_profile.id]) do_increment_logging_stat( user_profile, COUNT_STATS["messages_read::hour"], None, event_time, increment=count ) do_increment_logging_stat( user_profile, COUNT_STATS["messages_read_interactions::hour"], None, event_time, increment=min(1, count), ) return count