예제 #1
0
    def _create(cls, target_class, *args, **kwargs):
        if args:
            assert False, "Positional args aren't supported, use keyword args."

        context = {'user': ckan_factories._get_action_user_name(kwargs)}
        if 'skip_verification' not in kwargs:
            kwargs['skip_verification'] = True

        if not (kwargs.get('dataset_id') or kwargs.get('group_id')
                or kwargs.get('organization_id')):
            kwargs['dataset_id'] = ckan_factories.Dataset()['id']

        subscription_dict = \
            p.toolkit.get_action('subscribe_signup')(context, kwargs)

        # to set the 'created' time we need to edit the object
        subscription = \
            model.Session.query(ckanext.subscribe.model.Subscription) \
            .get(subscription_dict['id'])
        if kwargs.get('created'):
            subscription.created = kwargs['created']
            model.repo.commit()
        subscription_dict = \
            dictization.dictize_subscription(subscription, context)

        if kwargs['return_object']:
            return ckanext.subscribe.model.Subscription.get(
                subscription_dict['id'])
        return subscription_dict
예제 #2
0
    def _create(cls, target_class, **kwargs):
        for key in ('skip_verification', 'dataset_id'):
            assert key not in kwargs, 'wrong syntax - use Subscription instead'

        if not kwargs.get('object_id'):
            kwargs['object_id'] = ckan_factories.Dataset()['id']
            kwargs['object_type'] = 'dataset'

        return_object = kwargs.pop('return_object')

        context = {
            'user': ckan_factories._get_action_user_name(kwargs),
            'model': model,
            'session': model.Session
        }

        if p.toolkit.check_ckan_version(max_version='2.8.99'):
            model.repo.new_revision()
        subscription_obj = dictization.subscription_save(kwargs, context)
        model.repo.commit()

        if return_object:
            return subscription_obj
        subscription_dict = \
            dictization.dictize_subscription(subscription_obj, context)
        return subscription_dict
예제 #3
0
def subscribe_update(context, data_dict):
    '''Update a subscription's configuration.

    :param id: Subscription id to update
    :param frequency: Frequency of notifications to receive. One of:
        'immediate', 'daily', 'weekly' (optional, default=unchanged)

    :returns: the updated subscription
    :rtype: dictionary

    '''
    model = context['model']

    _check_access(u'subscribe_update', context, data_dict)

    id_ = p.toolkit.get_or_bust(data_dict, 'id')
    subscription = model.Session.query(Subscription).get(id_)

    for key in ('frequency',):
        if not data_dict.get(key):
            continue
        setattr(subscription, key, data_dict[key])
    model.repo.commit()

    subscription_dict = dictization.dictize_subscription(subscription, context)
    return subscription_dict
예제 #4
0
def dictize_notifications(subscription_activities):
    '''Dictizes a subscription and its activity objects

    :param subscription_activities: {subscription: [activity, ...], ...}

    :returns: [{'subscription': {...}, {'activities': [{...}, ...]}}]
    '''
    context = {'model': model, 'session': model.Session}
    notifications_dictized = []
    for subscription, activities in subscription_activities.items():
        subscription_dict = \
            dictization.dictize_subscription(subscription, context)
        activity_dicts = model_dictize.activity_list_dictize(
            activities, context)
        notifications_dictized.append({
            'subscription': subscription_dict,
            'activities': activity_dicts,
        })
    return notifications_dictized
예제 #5
0
def subscribe_verify(context, data_dict):
    '''Verify (confirm) a subscription

    :param code: Verification code, supplied in the email sent on sign-up

    :returns: the updated subscription
    :rtype: dictionary

    '''
    model = context['model']
    user = context['user']

    _check_access(u'subscribe_verify', context, data_dict)

    code = p.toolkit.get_or_bust(data_dict, 'code')
    subscription = model.Session.query(Subscription) \
        .filter_by(verification_code=code) \
        .first()
    if not subscription:
        raise p.toolkit.ValidationError(
            'That validation code is not recognized')
    if subscription.verification_code_expires < datetime.datetime.now():
        raise p.toolkit.ValidationError(
            'That validation code has expired')

    # Verify the subscription
    if p.toolkit.check_ckan_version(max_version='2.8.99'):
        rev = model.repo.new_revision()
        rev.author = user
    subscription.verified = True
    subscription.verification_code = None  # it can't be used again
    subscription.verification_code_expires = None
    if not context.get('defer_commit'):
        model.repo.commit()

    # Email the user confirmation and so they have a link to manage it
    manage_code = email_auth.create_code(subscription.email)
    email_auth.send_subscription_confirmation_email(
        manage_code, subscription=subscription)

    return dictization.dictize_subscription(subscription, context)
예제 #6
0
def subscribe_list_subscriptions(context, data_dict):
    '''For a given email address, list the subscriptions

    :param email: email address of the user to get the subscriptions for

    :rtype: list of subscription dicts
    '''
    model = context['model']

    _check_access(u'subscribe_list_subscriptions', context, data_dict)
    email = p.toolkit.get_or_bust(data_dict, 'email')

    subscription_objs = \
        model.Session.query(Subscription, model.Package, model.Group) \
        .filter_by(email=email) \
        .outerjoin(model.Package, Subscription.object_id == model.Package.id) \
        .outerjoin(model.Group, Subscription.object_id == model.Group.id) \
        .all()
    subscriptions = []
    for subscription_obj, package, group in subscription_objs:
        subscription = \
            dictization.dictize_subscription(subscription_obj, context)
        if package:
            subscription['object_name'] = package.name
            subscription['object_title'] = package.title
            subscription['object_link'] = p.toolkit.url_for(
                controller='package', action='read', id=package.name)
        elif group and not group.is_organization:
            subscription['object_name'] = group.name
            subscription['object_title'] = group.title
            subscription['object_link'] = p.toolkit.url_for(
                controller='group', action='read', id=group.name)
        elif group and group.is_organization:
            subscription['object_name'] = group.name
            subscription['object_title'] = group.title
            subscription['object_link'] = p.toolkit.url_for(
                controller='organization', action='read', id=group.name)
        subscriptions.append(subscription)
    return subscriptions
예제 #7
0
def subscribe_signup(context, data_dict):
    '''Signup to get notifications of email. Causes a email to be sent,
    containing a verification link.

    :param email: Email address to get notifications to
    :param dataset_id: Dataset name or id to get notifications about
        (specify only one of: dataset_id or group_id or organization_id)
    :param group_id: Group or organization name or id to get notifications
        about (specify only one of: dataset_id or group_id or organization_id)
    :param organization_id: Organization name or id to get notifications
        about (specify only one of: dataset_id or group_id or organization_id)
    :param frequency: Frequency of notifications to receive. One of:
        'immediate', 'daily', 'weekly' (optional, default=immediate)
    :param skip_verification: Doesn't send email - instead it marks the
        subscription as verified. Can be used by sysadmins only.
        (optional, default=False)

    :returns: the newly created subscription
    :rtype: dictionary

    '''
    model = context['model']

    _check_access(u'subscribe_signup', context, data_dict)

    data = {
        'email': data_dict['email'],
        'frequency': data_dict.get('frequency', Frequency.IMMEDIATE.value),
    }
    if data_dict.get('dataset_id'):
        data['object_type'] = 'dataset'
        dataset_obj = model.Package.get(data_dict['dataset_id'])
        data['object_id'] = dataset_obj.id
        data['object_name'] = dataset_obj.name
    else:
        group_obj = model.Group.get(data_dict.get('group_id') or
                                    data_dict.get('organization_id'))
        if group_obj.is_organization:
            data['object_type'] = 'organization'
        else:
            data['object_type'] = 'group'
        data['object_id'] = group_obj.id
        data['object_name'] = group_obj.name

    # must be unique combination of email/object_type/object_id
    existing = model.Session.query(Subscription) \
        .filter_by(email=data['email']) \
        .filter_by(object_type=data['object_type']) \
        .filter_by(object_id=data['object_id']) \
        .first()
    if existing:
        # reuse existing subscription
        subscription = existing
        subscription.frequency = data['frequency']
    else:
        # create subscription object
        if p.toolkit.check_ckan_version(max_version='2.8.99'):
            rev = model.repo.new_revision()
            rev.author = context['user']
        subscription = dictization.subscription_save(data, context)
        model.repo.commit()

    # send 'confirm your request' email
    if data_dict['skip_verification']:
        subscription.verified = True
        model.repo.commit()
    else:
        email_verification.create_code(subscription)
        try:
            email_verification.send_request_email(subscription)
        except MailerException as exc:
            log.error('Could not email manage code: {}'.format(exc))
            raise

    subscription_dict = dictization.dictize_subscription(subscription, context)
    subscription_dict['object_name'] = data['object_name']
    return subscription_dict