Exemplo n.º 1
0
    def new(object, action):
        """
        Sends notifications for a new object, saves it as `first_unread_object`
        or in `unread_objects` (depending on the type's mode) and increments
        the unread count.

        Must be called whenever a new object is created or moved to the scope
        of a SubscriptionType (e.g. when a topic is moved to another forum).

        :param object: The added object.
        :param action: The action which lead to the creation of the object.
                       It is used to select the SubscriptionTypes that need to
                       be considered and the action's :meth:`notify` method is
                       called.
        """
        #XXX: if `object` is removed before the task is run, subscriptions are
        #     marked as notified though the user didn't receive a notification

        if isinstance(action, basestring):
            action = SubscriptionAction.by_name(action)

        #: store ids of Subscription objects for which we need to notify
        subscriptions = []

        for t in SubscriptionType.by_action(action):
            subjects = t.get_subjects(object)
            if not subjects:
                continue
            subject_ids = [getattr(s, 'id', s) for s in subjects]

            base_cond = (Subscription.type_name == t.name)
            if t.subject_type is not None:
                base_cond &= Subscription.subject_id.in_(subject_ids)

            if t.mode == 'sequent':
                #: increment unread count where there already are unread objects
                cond = base_cond & (Subscription.count > 0)
                q = db.update(Subscription.__table__, cond,
                              {'count': Subscription.count + 1})
                db.session.execute(q)
                db.session.commit()

                #: then set the first unread object and notify the user
                #: where there were no new objects since the last visit
                cond = base_cond & (Subscription.count == 0)
                for s in Subscription.query.filter(cond):
                    subscriptions.append(s.id)
                    s.first_unread_object_id = object.id
                    s.count = 1
                db.session.commit()

            if t.mode == 'multiple':
                for s in Subscription.query.filter(base_cond):
                    subscriptions.append(s.id)
                    s.unread_object_ids.add(object.id)
                    s.count = len(s.unread_object_ids)
                db.session.commit()

        from inyoka.core import tasks
        tasks.send_notifications(object, action.name, subscriptions)
Exemplo n.º 2
0
def send_notifications(object, action_name, subscriptions):
    action = SubscriptionAction.by_name(action_name)
    if action is None:
        raise ValueError('no action found with %r' % action_name)
    notifications = defaultdict(lambda: defaultdict(list))

    for s in subscriptions:
        try:
            s = Subscription.query.get(s)
        except NoResultFound:
            raise ValueError('no subscription found with id %r' % s)
        notifications[s.user][s.type.name].append(s.subject)

    for user in notifications:
        action.notify(user, object, notifications[user])
Exemplo n.º 3
0
def send_notifications(object, action_name, subscriptions):
    action = SubscriptionAction.by_name(action_name)
    if action is None:
        raise ValueError('no action found with %r' % action_name)
    notifications = defaultdict(lambda: defaultdict(list))

    for s in subscriptions:
        try:
            s = Subscription.query.get(s)
        except NoResultFound:
            raise ValueError('no subscription found with id %r' % s)
        notifications[s.user][s.type.name].append(s.subject)

    for user in notifications:
        action.notify(user, object, notifications[user])