Ejemplo n.º 1
0
def notify(uid, event, user, node, timestamp, **context):
    """
    :param uid: node's id
    :param event: type of notification
    :param user: user "sending" notification
    :param node: the node
    :param timestamp: time
    :param context: optional variables specific to templates
        target_user: used with comment_replies
    :return:
    """
    node_subscribers = []
    subscription = NotificationSubscription.load(utils.to_subscription_key(uid, event))

    if subscription:
        for notification_type in constants.NOTIFICATION_TYPES:
            subscribed_users = getattr(subscription, notification_type, [])

            node_subscribers.extend(subscribed_users)

            if subscribed_users and notification_type != 'none':
                for recipient in subscribed_users:
                    event = 'comment_replies' if context.get('target_user') == recipient else event
                    send([recipient._id], notification_type, uid, event, user, node, timestamp, **context)

    return check_parent(uid, event, node_subscribers, user, node, timestamp, **context)
Ejemplo n.º 2
0
def notify(uid, event, user, node, timestamp, **context):
    """
    :param uid: node's id
    :param event: type of notification
    :param user: user "sending" notification
    :param node: the node
    :param timestamp: time
    :param context: optional variables specific to templates
        target_user: used with comment_replies
    :return:
    """
    node_subscribers = []
    subscription = NotificationSubscription.load(
        utils.to_subscription_key(uid, event))

    if subscription:
        for notification_type in constants.NOTIFICATION_TYPES:
            subscribed_users = getattr(subscription, notification_type, [])

            node_subscribers.extend(subscribed_users)

            if subscribed_users and notification_type != 'none':
                for recipient in subscribed_users:
                    event = 'comment_replies' if context.get(
                        'target_user') == recipient else event
                    send([recipient._id], notification_type, uid, event, user,
                         node, timestamp, **context)

    return check_parent(uid, event, node_subscribers, user, node, timestamp,
                        **context)
Ejemplo n.º 3
0
def get_user_subscriptions(user, event):
    user_subscription = NotificationSubscription.load(
        utils.to_subscription_key(user._id, event))
    return {
        key: getattr(user_subscription, key, [])
        for key in constants.NOTIFICATION_TYPES
    }
def add_reviews_notification_setting(notification_type, state=None):
    if state:
        OSFUser = state.get_model('osf', 'OSFUser')
        NotificationSubscription = state.get_model('osf', 'NotificationSubscription')
    else:
        from osf.models import OSFUser, NotificationSubscription

    active_users = OSFUser.objects.filter(date_confirmed__isnull=False).exclude(date_disabled__isnull=False).exclude(is_active=False).order_by('id')
    total_active_users = active_users.count()

    logger.info('About to add a global_reviews setting for {} users.'.format(total_active_users))

    total_created = 0
    for user in active_users.iterator():
        user_subscription_id = to_subscription_key(user._id, notification_type)

        subscription = NotificationSubscription.load(user_subscription_id)
        if not subscription:
            logger.info('No {} subscription found for user {}. Subscribing...'.format(notification_type, user._id))
            subscription = NotificationSubscription(_id=user_subscription_id, owner=user, event_name=notification_type)
            subscription.save()  # Need to save in order to access m2m fields
            subscription.add_user_to_subscription(user, 'email_transactional')
        else:
            logger.info('User {} already has a {} subscription'.format(user._id, notification_type))
        total_created += 1

    logger.info('Added subscriptions for {}/{} users'.format(total_created, total_active_users))
def add_global_subscriptions(dry=True):
    OSFUser = apps.get_model('osf.OSFUser')
    notification_type = 'email_transactional'
    user_events = constants.USER_SUBSCRIPTIONS_AVAILABLE

    count = 0

    with transaction.atomic():
        for user in OSFUser.objects.filter(is_registered=True, date_confirmed__isnull=False):
            changed = False
            if not user.is_active:
                continue
            for user_event in user_events:
                user_event_id = to_subscription_key(user._id, user_event)

                subscription = NotificationSubscription.load(user_event_id)
                if not subscription:
                    logger.info('No {} subscription found for user {}. Subscribing...'.format(user_event, user._id))
                    subscription = NotificationSubscription(_id=user_event_id, owner=user, event_name=user_event)
                    subscription.save()  # Need to save in order to access m2m fields
                    subscription.add_user_to_subscription(user, notification_type)
                    subscription.save()
                    changed = True
                else:
                    logger.info('User {} already has a {} subscription'.format(user._id, user_event))
            if changed:
                count += 1

        logger.info('Added subscriptions for {} users'.format(count))
        if dry:
            raise RuntimeError('Dry mode -- rolling back transaction')
Ejemplo n.º 6
0
def check_parent(uid, event, node_subscribers, user, orig_node, timestamp, **context):
    """ Check subscription object for the event on the parent project
        and send transactional email to indirect subscribers.
    """
    node = website_models.Node.load(uid)
    target_user = context.get('target_user', None)

    if node and node.parent_id:
        key = utils.to_subscription_key(node.parent_id, event)
        subscription = NotificationSubscription.load(key)

        if not subscription:
            return check_parent(node.parent_id, event, node_subscribers, user, orig_node, timestamp, **context)

        for notification_type in constants.NOTIFICATION_TYPES:
            subscribed_users = getattr(subscription, notification_type, [])

            for u in subscribed_users:
                if u not in node_subscribers and node.has_permission(u, 'read'):
                    if notification_type != 'none':
                        event = 'comment_replies' if target_user == u else event
                        send([u._id], notification_type, uid, event, user, orig_node, timestamp, **context)
                    node_subscribers.append(u)

        return check_parent(node.parent_id, event, node_subscribers, user, orig_node, timestamp, **context)

    return node_subscribers
Ejemplo n.º 7
0
def check_parent(uid, event, node_subscribers, **context):
    """ Check subscription object for the event on the parent project
        and send transactional email to indirect subscribers.
    """
    node = website_models.Node.load(uid)
    target_user = context.get('target_user', None)

    if node and node.parent_id:
        key = utils.to_subscription_key(node.parent_id, event)
        subscription = NotificationSubscription.load(key)

        if not subscription:
            return check_parent(node.parent_id, event, node_subscribers,
                                **context)

        for notification_type in constants.NOTIFICATION_TYPES:
            subscribed_users = getattr(subscription, notification_type, [])

            for u in subscribed_users:
                if u not in node_subscribers and node.has_permission(
                        u, 'read'):
                    if notification_type != 'none':
                        event = 'comment_replies' if target_user == u else event
                        send([u._id], notification_type, uid, event, **context)
                    node_subscribers.append(u)

        return check_parent(node.parent_id, event, node_subscribers, **context)

    return node_subscribers
def add_reviews_notification_setting(notification_type):
    active_users = OSFUser.objects.filter(
        date_confirmed__isnull=False).exclude(
            date_disabled__isnull=False).exclude(
                is_active=False).order_by('id')
    total_active_users = active_users.count()

    logger.info('About to add a global_reviews setting for {} users.'.format(
        total_active_users))

    total_created = 0
    for user in active_users.iterator():
        user_subscription_id = to_subscription_key(user._id, notification_type)

        subscription = NotificationSubscription.load(user_subscription_id)
        if not subscription:
            logger.info(
                'No {} subscription found for user {}. Subscribing...'.format(
                    notification_type, user._id))
            subscription = NotificationSubscription(
                _id=user_subscription_id,
                owner=user,
                event_name=notification_type)
            subscription.save()  # Need to save in order to access m2m fields
            subscription.add_user_to_subscription(user, 'email_transactional')
        else:
            logger.info('User {} already has a {} subscription'.format(
                user._id, notification_type))
        total_created += 1

    logger.info('Added subscriptions for {}/{} users'.format(
        total_created, total_active_users))
Ejemplo n.º 9
0
def get_user_subscriptions(user, event):
    if user.is_disabled:
        return {}
    user_subscription = NotificationSubscription.load(utils.to_subscription_key(user._id, event))
    if user_subscription:
        return {key: list(getattr(user_subscription, key).all().values_list('guids___id', flat=True)) for key in constants.NOTIFICATION_TYPES}
    else:
        return {key: [] for key in constants.NOTIFICATION_TYPES}
Ejemplo n.º 10
0
def get_user_subscriptions(user, event):
    if user.is_disabled:
        return {}
    user_subscription = NotificationSubscription.load(utils.to_subscription_key(user._id, event))
    if user_subscription:
        return {key: list(getattr(user_subscription, key).all().values_list('guids___id', flat=True)) for key in constants.NOTIFICATION_TYPES}
    else:
        return {key: [] for key in constants.NOTIFICATION_TYPES}
Ejemplo n.º 11
0
def check_node(node, event):
    """Return subscription for a particular node and event."""
    node_subscriptions = {key: [] for key in constants.NOTIFICATION_TYPES}
    if node:
        subscription = NotificationSubscription.load(utils.to_subscription_key(node._id, event))
        for notification_type in node_subscriptions:
            users = getattr(subscription, notification_type, [])
            for user in users:
                if node.has_permission(user, 'read'):
                    node_subscriptions[notification_type].append(user._id)
    return node_subscriptions
Ejemplo n.º 12
0
def check_node(node, event):
    """Return subscription for a particular node and event."""
    node_subscriptions = {key: [] for key in constants.NOTIFICATION_TYPES}
    if node:
        subscription = NotificationSubscription.load(utils.to_subscription_key(node._id, event))
        for notification_type in node_subscriptions:
            users = getattr(subscription, notification_type, [])
            for user in users:
                if node.has_permission(user, 'read'):
                    node_subscriptions[notification_type].append(user._id)
    return node_subscriptions
Ejemplo n.º 13
0
def notify(uid, event, **context):
    node_subscribers = []
    subscription = NotificationSubscription.load(utils.to_subscription_key(uid, event))

    if subscription:
        for notification_type in constants.NOTIFICATION_TYPES:
            subscribed_users = getattr(subscription, notification_type, [])

            node_subscribers.extend(subscribed_users)

            if subscribed_users and notification_type != 'none':
                event = 'comment_replies' if context.get('target_user') else event
                send([u._id for u in subscribed_users], notification_type, uid, event, **context)

    return check_parent(uid, event, node_subscribers, **context)
Ejemplo n.º 14
0
def add_global_subscriptions():

    notification_type = 'email_transactional'
    user_events = constants.USER_SUBSCRIPTIONS_AVAILABLE

    for user in models.User.find():
        if user.is_active and user.is_registered:
            for user_event in user_events:
                user_event_id = to_subscription_key(user._id, user_event)

                subscription = NotificationSubscription.load(user_event_id)
                if not subscription:
                    subscription = NotificationSubscription(_id=user_event_id, owner=user, event_name=user_event)
                    subscription.add_user_to_subscription(user, notification_type)
                    subscription.save()
                    logger.info('No subscription found. {} created.'.format(subscription))
                else:
                    logger.info('Subscription {} found.'.format(subscription))
Ejemplo n.º 15
0
def notify(uid, event, **context):
    node_subscribers = []
    subscription = NotificationSubscription.load(
        utils.to_subscription_key(uid, event))

    if subscription:
        for notification_type in constants.NOTIFICATION_TYPES:
            subscribed_users = getattr(subscription, notification_type, [])

            node_subscribers.extend(subscribed_users)

            if subscribed_users and notification_type != 'none':
                for user in subscribed_users:
                    event = 'comment_replies' if context.get(
                        'target_user') == user else event
                    send([user._id], notification_type, uid, event, **context)

    return check_parent(uid, event, node_subscribers, **context)
Ejemplo n.º 16
0
def add_global_subscriptions():

    notification_type = 'email_transactional'
    user_events = constants.USER_SUBSCRIPTIONS_AVAILABLE

    for user in models.User.find():
        if user.is_active and user.is_registered:
            for user_event in user_events:
                user_event_id = to_subscription_key(user._id, user_event)

                subscription = NotificationSubscription.load(user_event_id)
                if not subscription:
                    subscription = NotificationSubscription(
                        _id=user_event_id, owner=user, event_name=user_event)
                    subscription.add_user_to_subscription(
                        user, notification_type)
                    subscription.save()
                    logger.info('No subscription found. {} created.'.format(
                        subscription))
                else:
                    logger.info('Subscription {} found.'.format(subscription))
Ejemplo n.º 17
0
def add_global_subscriptions(dry=True):
    OSFUser = apps.get_model('osf.OSFUser')
    notification_type = 'email_transactional'
    user_events = constants.USER_SUBSCRIPTIONS_AVAILABLE

    count = 0

    with transaction.atomic():
        for user in OSFUser.objects.filter(is_registered=True,
                                           date_confirmed__isnull=False):
            changed = False
            if not user.is_active:
                continue
            for user_event in user_events:
                user_event_id = to_subscription_key(user._id, user_event)

                subscription = NotificationSubscription.load(user_event_id)
                if not subscription:
                    logger.info(
                        'No {} subscription found for user {}. Subscribing...'.
                        format(user_event, user._id))
                    subscription = NotificationSubscription(
                        _id=user_event_id, owner=user, event_name=user_event)
                    subscription.save(
                    )  # Need to save in order to access m2m fields
                    subscription.add_user_to_subscription(
                        user, notification_type)
                    subscription.save()
                    changed = True
                else:
                    logger.info('User {} already has a {} subscription'.format(
                        user._id, user_event))
            if changed:
                count += 1

        logger.info('Added subscriptions for {} users'.format(count))
        if dry:
            raise RuntimeError('Dry mode -- rolling back transaction')
Ejemplo n.º 18
0
def get_user_subscriptions(user, event):
    user_subscription = NotificationSubscription.load(utils.to_subscription_key(user._id, event))
    return {key: getattr(user_subscription, key, []) for key in constants.NOTIFICATION_TYPES}
Ejemplo n.º 19
0
def configure_subscription(auth):
    user = auth.user
    json_data = request.get_json()
    target_id = json_data.get('id')
    event = json_data.get('event')
    notification_type = json_data.get('notification_type')
    path = json_data.get('path')
    provider = json_data.get('provider')

    if not event or (notification_type not in NOTIFICATION_TYPES
                     and notification_type != 'adopt_parent'):
        raise HTTPError(
            http_status.HTTP_400_BAD_REQUEST,
            data=dict(
                message_long=
                'Must provide an event and notification type for subscription.'
            ))

    node = AbstractNode.load(target_id)
    if 'file_updated' in event and path is not None and provider is not None:
        wb_path = path.lstrip('/')
        event = wb_path + '_file_updated'
    event_id = utils.to_subscription_key(target_id, event)

    if not node:
        # if target_id is not a node it currently must be the current user
        if not target_id == user._id:
            sentry.log_message('{!r} attempted to subscribe to either a bad '
                               'id or non-node non-self id, {}'.format(
                                   user, target_id))
            raise HTTPError(http_status.HTTP_404_NOT_FOUND)

        if notification_type == 'adopt_parent':
            sentry.log_message(
                '{!r} attempted to adopt_parent of a none node id, {}'.format(
                    user, target_id))
            raise HTTPError(http_status.HTTP_400_BAD_REQUEST)
        owner = user
    else:
        if not node.has_permission(user, READ):
            sentry.log_message(
                '{!r} attempted to subscribe to private node, {}'.format(
                    user, target_id))
            raise HTTPError(http_status.HTTP_403_FORBIDDEN)

        if isinstance(node, Registration):
            sentry.log_message(
                '{!r} attempted to subscribe to registration, {}'.format(
                    user, target_id))
            raise HTTPError(http_status.HTTP_400_BAD_REQUEST)

        if notification_type != 'adopt_parent':
            owner = node
        else:
            if 'file_updated' in event and len(event) > len('file_updated'):
                pass
            else:
                parent = node.parent_node
                if not parent:
                    sentry.log_message('{!r} attempted to adopt_parent of '
                                       'the parentless project, {!r}'.format(
                                           user, node))
                    raise HTTPError(http_status.HTTP_400_BAD_REQUEST)

            # If adopt_parent make sure that this subscription is None for the current User
            subscription = NotificationSubscription.load(event_id)
            if not subscription:
                return {}  # We're done here

            subscription.remove_user_from_subscription(user)
            return {}

    subscription = NotificationSubscription.load(event_id)

    if not subscription:
        subscription = NotificationSubscription(_id=event_id,
                                                owner=owner,
                                                event_name=event)
        subscription.save()

    if node and node._id not in user.notifications_configured:
        user.notifications_configured[node._id] = True
        user.save()

    subscription.add_user_to_subscription(user, notification_type)

    subscription.save()

    return {
        'message':
        'Successfully subscribed to {} list on {}'.format(
            notification_type, event_id)
    }
Ejemplo n.º 20
0
 def test_to_subscription_key(self):
     key = utils.to_subscription_key('xyz', 'comments')
     assert_equal(key, 'xyz_comments')
Ejemplo n.º 21
0
def configure_subscription(auth):
    user = auth.user
    json_data = request.get_json()
    target_id = json_data.get('id')
    event = json_data.get('event')
    notification_type = json_data.get('notification_type')

    if not event or (notification_type not in NOTIFICATION_TYPES
                     and notification_type != 'adopt_parent'):
        raise HTTPError(
            http.BAD_REQUEST,
            data=dict(
                message_long=
                "Must provide an event and notification type for subscription."
            ))

    node = Node.load(target_id)
    event_id = utils.to_subscription_key(target_id, event)

    if not node:
        # if target_id is not a node it currently must be the current user
        if not target_id == user._id:
            sentry.log_message('{!r} attempted to subscribe to either a bad '
                               'id or non-node non-self id, {}'.format(
                                   user, target_id))
            raise HTTPError(http.NOT_FOUND)

        if notification_type == 'adopt_parent':
            sentry.log_message(
                '{!r} attempted to adopt_parent of a none node id, {}'.format(
                    user, target_id))
            raise HTTPError(http.BAD_REQUEST)
        owner = user
    else:
        if not node.has_permission(user, 'read'):
            sentry.log_message(
                '{!r} attempted to subscribe to private node, {}'.format(
                    user, target_id))
            raise HTTPError(http.FORBIDDEN)

        if notification_type != 'adopt_parent':
            owner = node
        else:
            parent = node.parent_node
            if not parent:
                sentry.log_message('{!r} attempted to adopt_parent of '
                                   'the parentless project, {!r}'.format(
                                       user, node))
                raise HTTPError(http.BAD_REQUEST)

            # If adopt_parent make sure that this subscription is None for the current User
            subscription = NotificationSubscription.load(event_id)
            if not subscription:
                return {}  # We're done here

            subscription.remove_user_from_subscription(user)
            return {}

    subscription = NotificationSubscription.load(event_id)

    if not subscription:
        subscription = NotificationSubscription(_id=event_id,
                                                owner=owner,
                                                event_name=event)

    subscription.add_user_to_subscription(user, notification_type)

    subscription.save()

    return {
        'message':
        'Successfully subscribed to {} list on {}'.format(
            notification_type, event_id)
    }
Ejemplo n.º 22
0
def configure_subscription(auth):
    user = auth.user
    json_data = request.get_json()
    target_id = json_data.get('id')
    event = json_data.get('event')
    notification_type = json_data.get('notification_type')
    path = json_data.get('path')
    provider = json_data.get('provider')

    if not event or (notification_type not in NOTIFICATION_TYPES and notification_type != 'adopt_parent'):
        raise HTTPError(http.BAD_REQUEST, data=dict(
            message_long='Must provide an event and notification type for subscription.')
        )

    node = AbstractNode.load(target_id)
    if 'file_updated' in event and path is not None and provider is not None:
        wb_path = path.lstrip('/')
        event = wb_path + '_file_updated'
    event_id = utils.to_subscription_key(target_id, event)

    if not node:
        # if target_id is not a node it currently must be the current user
        if not target_id == user._id:
            sentry.log_message(
                '{!r} attempted to subscribe to either a bad '
                'id or non-node non-self id, {}'.format(user, target_id)
            )
            raise HTTPError(http.NOT_FOUND)

        if notification_type == 'adopt_parent':
            sentry.log_message(
                '{!r} attempted to adopt_parent of a none node id, {}'.format(user, target_id)
            )
            raise HTTPError(http.BAD_REQUEST)
        owner = user
    else:
        if not node.has_permission(user, 'read'):
            sentry.log_message('{!r} attempted to subscribe to private node, {}'.format(user, target_id))
            raise HTTPError(http.FORBIDDEN)

        if notification_type != 'adopt_parent':
            owner = node
        else:
            if 'file_updated' in event and len(event) > len('file_updated'):
                pass
            else:
                parent = node.parent_node
                if not parent:
                    sentry.log_message(
                        '{!r} attempted to adopt_parent of '
                        'the parentless project, {!r}'.format(user, node)
                    )
                    raise HTTPError(http.BAD_REQUEST)

            # If adopt_parent make sure that this subscription is None for the current User
            subscription = NotificationSubscription.load(event_id)
            if not subscription:
                return {}  # We're done here

            subscription.remove_user_from_subscription(user)
            return {}

    subscription = NotificationSubscription.load(event_id)

    if not subscription:
        subscription = NotificationSubscription(_id=event_id, owner=owner, event_name=event)
        subscription.save()

    if node and node._id not in user.notifications_configured:
        user.notifications_configured[node._id] = True
        user.save()

    subscription.add_user_to_subscription(user, notification_type)

    subscription.save()

    return {'message': 'Successfully subscribed to {} list on {}'.format(notification_type, event_id)}