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')
Exemple #2
0
def reviews_submit_notification_moderators(self, timestamp, context):
    # imports moved here to avoid AppRegistryNotReady error
    from osf.models import NotificationSubscription
    from website.profile.utils import get_profile_image_url
    from website.notifications import emails
    from website import settings

    # Get NotificationSubscription instance, which contains reference to all subscribers
    provider_subscription = NotificationSubscription.load('{}_new_pending_submissions'.format(context['reviewable'].provider._id))
    # Set message
    context['message'] = u'submitted {}.'.format(context['reviewable'].node.title)
    # Set url for profile image of the submitter
    context['profile_image_url'] = get_profile_image_url(context['referrer'])
    # Set submission url
    context['reviews_submission_url'] = '{}reviews/preprints/{}/{}'.format(settings.DOMAIN, context['reviewable'].provider._id, context['reviewable']._id)
    # Store emails to be sent to subscribers instantly (at a 5 min interval)
    emails.store_emails(provider_subscription.email_transactional.all().values_list('guids___id', flat=True),
                        'email_transactional',
                        'new_pending_submissions',
                        context['referrer'],
                        context['reviewable'].node,
                        timestamp,
                        abstract_provider=context['reviewable'].provider,
                        **context)

    # Store emails to be sent to subscribers daily
    emails.store_emails(provider_subscription.email_digest.all().values_list('guids___id', flat=True),
                        'email_digest',
                        'new_pending_submissions',
                        context['referrer'],
                        context['reviewable'].node,
                        timestamp,
                        abstract_provider=context['reviewable'].provider,
                        **context)
Exemple #3
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}
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}
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))
Exemple #6
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, [])
            if users:
                for user in users.exclude(date_disabled__isnull=False):
                    if node.has_permission(user, READ):
                        node_subscriptions[notification_type].append(user._id)
    return node_subscriptions
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, [])
            if users:
                for user in users.exclude(date_disabled__isnull=False):
                    if node.has_permission(user, 'read'):
                        node_subscriptions[notification_type].append(user._id)
    return node_subscriptions
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))
Exemple #9
0
def reviews_withdrawal_requests_notification(self, timestamp, context):
    # imports moved here to avoid AppRegistryNotReady error
    from osf.models import NotificationSubscription
    from website.notifications.emails import store_emails
    from website.profile.utils import get_profile_image_url
    from website import settings

    # Get NotificationSubscription instance, which contains reference to all subscribers
    provider_subscription = NotificationSubscription.load(
        '{}_new_pending_submissions'.format(
            context['reviewable'].provider._id))
    preprint = context['reviewable']
    preprint_word = preprint.provider.preprint_word

    # Set message
    context['message'] = u'has requested withdrawal of the {} "{}".'.format(
        preprint_word, preprint.title)
    # Set url for profile image of the submitter
    context['profile_image_url'] = get_profile_image_url(context['requester'])
    # Set submission url
    context['reviews_submission_url'] = '{}reviews/preprints/{}/{}'.format(
        settings.DOMAIN, preprint.provider._id, preprint._id)

    email_transactional_ids = list(
        provider_subscription.email_transactional.all().values_list(
            'guids___id', flat=True))
    email_digest_ids = list(
        provider_subscription.email_digest.all().values_list('guids___id',
                                                             flat=True))

    # Store emails to be sent to subscribers instantly (at a 5 min interval)
    store_emails(email_transactional_ids,
                 'email_transactional',
                 'new_pending_submissions',
                 context['requester'],
                 preprint,
                 timestamp,
                 abstract_provider=preprint.provider,
                 **context)

    # Store emails to be sent to subscribers daily
    store_emails(email_digest_ids,
                 'email_digest',
                 'new_pending_submissions',
                 context['requester'],
                 preprint,
                 timestamp,
                 abstract_provider=preprint.provider,
                 **context)
Exemple #10
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')
Exemple #11
0
def reviews_submit_notification_moderators(self, timestamp, context):
    # imports moved here to avoid AppRegistryNotReady error
    from osf.models import NotificationSubscription
    from website.profile.utils import get_profile_image_url
    from website.notifications import emails
    from website import settings

    # Get NotificationSubscription instance, which contains reference to all subscribers
    provider_subscription = NotificationSubscription.load(
        '{}_new_pending_submissions'.format(
            context['reviewable'].provider._id))
    # Set message
    context['message'] = u'submitted {}.'.format(
        context['reviewable'].node.title)
    # Set url for profile image of the submitter
    context['profile_image_url'] = get_profile_image_url(context['referrer'])
    # Set submission url
    context['reviews_submission_url'] = '{}reviews/preprints/{}/{}'.format(
        settings.DOMAIN, context['reviewable'].provider._id,
        context['reviewable']._id)
    # Store emails to be sent to subscribers instantly (at a 5 min interval)
    emails.store_emails(
        provider_subscription.email_transactional.all().values_list(
            'guids___id', flat=True),
        'email_transactional',
        'new_pending_submissions',
        context['referrer'],
        context['reviewable'].node,
        timestamp,
        abstract_provider=context['reviewable'].provider,
        **context)

    # Store emails to be sent to subscribers daily
    emails.store_emails(provider_subscription.email_digest.all().values_list(
        'guids___id', flat=True),
                        'email_digest',
                        'new_pending_submissions',
                        context['referrer'],
                        context['reviewable'].node,
                        timestamp,
                        abstract_provider=context['reviewable'].provider,
                        **context)
Exemple #12
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)}
Exemple #13
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 isinstance(node, Registration):
            sentry.log_message(
                '{!r} attempted to subscribe to registration, {}'.format(
                    user, target_id))
            raise HTTPError(http.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.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)
    }