def update_notifications(self): notifications = [ ntf.as_dict() for ntf in InAppNotification.objects( owner=self.auth_context.org, dismissed_by__ne=self.auth_context.user.id) ] log.info("Emitting notifications list") self.send('notifications', notifications)
def add_notification_override(request): """ Tags: notifications --- Add a notification override with the specified properties --- notification: in: path type: string required: true """ auth_context = auth_context_from_request(request) params = params_from_request(request) ntf_id = params.get("notification_id") if not ntf_id: raise RequiredParameterMissingError("notification_id") try: ntf = Notification.objects.get(id=ntf_id, owner=auth_context.owner) ntf.channel.dismiss(auth_context.user) except Notification.DoesNotExist: raise NotFoundError() try: np = UserNotificationPolicy.objects.get(owner=auth_context.owner, user_id=auth_context.user.id) except UserNotificationPolicy.DoesNotExist: np = UserNotificationPolicy(owner=auth_context.owner, user_id=auth_context.user.id) if not np.has_overriden(ntf): override = NotificationOverride() override.rid = ntf.rid override.rtype = ntf.rtype override.channel = ntf.channel.ctype np.overrides.append(override) np.save() # Dismiss relevant notifications in order to not show up again. InAppNotification.objects( owner=auth_context.owner, rid=ntf.rid, rtype=ntf.rtype, dismissed_by__ne=auth_context.user.id).update( push__dismissed_by=auth_context.user.id) return Response('OK', 200)
def _modify_and_notify(self, notification, modifier): user = notification.user old_notifications = [ json.loads(obj.to_json()) for obj in InAppNotification.objects(user=user, dismissed=False) ] modifier(notification) new_notifications = [ json.loads(obj.to_json()) for obj in InAppNotification.objects(user=user, dismissed=False) ] patch = jsonpatch.JsonPatch.from_diff(old_notifications, new_notifications).patch if patch: data = json.dumps({ "user": user.id, "patch": patch }, cls=NotificationsEncoder) amqp_publish_user(notification.organization, routing_key='patch_notifications', data=data)
def modify(notification): if notification.unique: similar = InAppNotification.objects( user=notification.user, organization=notification.organization, machine=notification.machine, tag=notification.tag, cloud=notification.cloud, model_id=notification.model_id) if similar: # unfortunately, queryset does not support pop() first = similar[0] first.update_from(notification) first.save() for item in [item for item in similar if item != first]: item.dismissed = True item.save() else: notification.save() else: notification.save()
def send(self, users=None, dismiss=False): # FIXME Imported here due to circular dependency issues. from mist.api.notifications.models import InAppNotification from mist.api.notifications.models import UserNotificationPolicy # Get the list of `InAppNotifications`s in the current context before # any update takes place. owner_old_ntfs = list(InAppNotification.objects(owner=self.ntf.owner)) if not users: users = self.ntf.owner.members elif not isinstance(users, list): users = [users] # Save/update/dismiss notifications. if dismiss: dismissed_by = set(self.ntf.dismissed_by) old_dismissed_by = list(dismissed_by) dismissed_by |= set(user.id for user in users) self.ntf.dismissed_by = list(dismissed_by) # Is anyone listening? if not amqp_owner_listening(self.ntf.owner.id): return # Initialize AMQP connection to reuse for multiple messages. amqp_conn = Connection(config.AMQP_URI) # Re-fetch all notifications in order to calculate the diff between # the two lists. owner_new_ntfs = list(InAppNotification.objects(owner=self.ntf.owner)) # Apply each user's notification policy on the above lists to get rid # of notifications users are not interested in. for user in users: user_old_ntfs, user_new_ntfs = [], [] try: np = UserNotificationPolicy.objects.get(user_id=user.id) except UserNotificationPolicy.DoesNotExist: log.debug('No UserNotificationPolicy found for %s', user) user_old_ntfs = [ ntf.as_dict() for ntf in owner_old_ntfs if not ( self.ntf.id == ntf.id and user.id in old_dismissed_by) ] user_new_ntfs = [ ntf.as_dict() for ntf in owner_new_ntfs if not (self.ntf.id == ntf.id and user.id in dismissed_by) ] else: user_old_ntfs = [ ntf.as_dict() for ntf in owner_old_ntfs if not np.has_blocked(ntf) and not ( self.ntf.id == ntf.id and user.id in old_dismissed_by) ] user_new_ntfs = [ ntf.as_dict() for ntf in owner_new_ntfs if not np.has_blocked(ntf) and not (self.ntf.id == ntf.id and user.id in dismissed_by) ] # Now we can save the dismissed notification self.ntf.save() # Calculate diff. patch = jsonpatch.JsonPatch.from_diff(user_old_ntfs, user_new_ntfs).patch if patch: amqp_publish_user(self.ntf.owner.id, routing_key='patch_notifications', connection=amqp_conn, data={ 'user': user.id, 'patch': patch }) # Finally, try to close the AMQP connection. try: amqp_conn.close() except Exception as exc: log.exception(repr(exc))
def migrate_notifications(collection): """Migrate all non-dismissed in-app notifications""" total = collection.find().count() failed = 0 migrated = 0 print print 'Will migrate %d notifications' % total print for old_ntf in collection.find({ 'dismissed': False, 'migrated': { '$exists': False } }): try: print 'Migrating', old_ntf['_id'], try: owner = Organization.objects.get(id=old_ntf['organization']) except Exception: print '[ERROR]' failed += 1 traceback.print_exc() continue ntf = InAppNotification() ntf.owner = owner ntf.subject = old_ntf['summary'] ntf.text_body = old_ntf['body'] ntf.html_body = old_ntf['html_body'] ntf.rid = old_ntf['machine']['_ref'].id ntf.rtype = 'machine' ntf.created_at = old_ntf['created_date'] ntf.save() except Exception: print '[ERROR]' failed += 1 traceback.print_exc() else: try: collection.update_one({'_id': old_ntf['_id']}, {'$set': { 'migrated': True }}) except Exception: print '[ERROR]' failed += 1 traceback.print_exc() try: ntf.delete() except: pass else: print '[OK]' migrated += 1 print print 'Migrated: %d/%d' % (migrated, total) print 'Failed: %d' % failed print print 'Completed %s' % ('with errors!' if failed else 'successfully!') print