Beispiel #1
0
    def dictionary(self, id, resource_id):
        u'''data dictionary view: show/edit field labels and descriptions'''

        try:
            # resource_edit_base template uses these
            c.pkg_dict = get_action('package_show')(None, {'id': id})
            c.resource = get_action('resource_show')(None, {'id': resource_id})
            rec = get_action('datastore_search')(None, {
                'resource_id': resource_id,
                'limit': 0
            })
        except (ObjectNotFound, NotAuthorized):
            abort(404, _('Resource not found'))

        fields = [f for f in rec['fields'] if not f['id'].startswith('_')]

        if request.method == 'POST':
            data = dict_fns.unflatten(
                tuplize_dict(parse_params(request.params)))
            info = data.get(u'info')
            if not isinstance(info, list):
                info = []
            info = info[:len(fields)]

            get_action('datastore_create')(None, {
                'resource_id':
                resource_id,
                'force':
                True,
                'fields': [{
                    'id': f['id'],
                    'type': f['type'],
                    'info': fi if isinstance(fi, dict) else {}
                } for f, fi in izip_longest(fields, info)]
            })

            h.flash_success(
                _('Data Dictionary saved. Any type overrides will '
                  'take effect when the resource is next uploaded '
                  'to DataStore'))
            h.redirect_to(
                controller='ckanext.datastore.controller:DatastoreController',
                action='dictionary',
                id=id,
                resource_id=resource_id)

        return render('datastore/dictionary.html',
                      extra_vars={
                          'fields': fields,
                          'pkg_dict': c.pkg_dict,
                          'resource': c.resource,
                      })
Beispiel #2
0
    def geocoded_data(self, id, resource_id):
        u'''geocoded data fields view: show/edit geocoded data fields'''

        try:
            # resource_edit_base template uses these
            c.pkg_dict = get_action('package_show')(
                None, {'id': id})
            c.resource = get_action('resource_show')(
                None, {'id': resource_id})
            rec = get_action('datastore_search')(None, {
                'resource_id': resource_id,
                'limit': 0})
        except (ObjectNotFound, NotAuthorized):
            abort(404, _('Resource not found'))

        fields = get_geocoded_fields()
        resource_fields = rec.get('fields')
        address_column_options = [{"text":"","value":""}]
        for resource_field in resource_fields:
            if resource_field.get('id') == '_id':
                continue
            address_column_options.append({"text":resource_field.get('id'),"value":resource_field.get('id')})


        if request.method == 'POST':
            data = dict(request.POST)
            for field in fields:
                key = field.get('field_name')
                value = data.get(key)
                if ResourceGeocodeData.exists(resource_id=resource_id,key=key):
                    gecodefield_obj = ResourceGeocodeData.get(resource_id=resource_id,key=key)
                    gecodefield_obj.value = value
                    gecodefield_obj.commit()
                else:
                    ResourceGeocodeData.create(resource_id=resource_id,key=key, value=value)
            maybe_schedule(c.resource)

            h.redirect_to(
                controller='ckanext.geocodejob.controller:GeocodejobController',
                action='geocoded_data',
                id=id,
                resource_id=resource_id)

        geocode_data_values = ResourceGeocodeData.get_geocode_data_values(resource_id)

        return render(
            'package/geocoded_data.html',
            extra_vars={'fields': fields,
                        'address_column_options':address_column_options,
                        'geocode_data_values':geocode_data_values})
Beispiel #3
0
    def dictionary(self, id, resource_id):
        u'''data dictionary view: show/edit field labels and descriptions'''

        try:
            # resource_edit_base template uses these
            c.pkg_dict = get_action('package_show')(
                None, {'id': id})
            c.resource = get_action('resource_show')(
                None, {'id': resource_id})
            rec = get_action('datastore_search')(None, {
                'resource_id': resource_id,
                'limit': 0})
        except (ObjectNotFound, NotAuthorized):
            abort(404, _('Resource not found'))

        fields = [f for f in rec['fields'] if not f['id'].startswith('_')]

        if request.method == 'POST':
            data = dict_fns.unflatten(tuplize_dict(parse_params(
                request.params)))
            info = data.get(u'info')
            if not isinstance(info, list):
                info = []
            info = info[:len(fields)]

            get_action('datastore_create')(None, {
                'resource_id': resource_id,
                'force': True,
                'fields': [{
                    'id': f['id'],
                    'type': f['type'],
                    'info': fi if isinstance(fi, dict) else {}
                    } for f, fi in izip_longest(fields, info)]})

            h.flash_success(_('Data Dictionary saved. Any type overrides will '
                              'take effect when the resource is next uploaded '
                              'to DataStore'))
            h.redirect_to(
                controller='ckanext.datastore.controller:DatastoreController',
                action='dictionary',
                id=id,
                resource_id=resource_id)

        return render(
            'datastore/dictionary.html',
            extra_vars={
                'fields': fields,
                'pkg_dict': c.pkg_dict,
                'resource': c.resource,
            })
Beispiel #4
0
    def post(self, id, resource_id):
        u'''Data dictionary view: edit field labels and descriptions'''
        data_dict = self._prepare(id, resource_id)
        fields = data_dict[u'fields']
        data = dict_fns.unflatten(tuplize_dict(parse_params(request.form)))
        info = data.get(u'info')
        if not isinstance(info, list):
            info = []
        info = info[:len(fields)]

        get_action(u'datastore_create')(
            None, {
                u'resource_id': resource_id,
                u'force': True,
                u'fields': [{
                    u'id': f[u'id'],
                    u'type': f[u'type'],
                    u'info': fi if isinstance(fi, dict) else {}
                } for f, fi in zip_longest(fields, info)]
            }
        )

        h.flash_success(
            _(
                u'Data Dictionary saved. Any type overrides will '
                u'take effect when the resource is next uploaded '
                u'to DataStore'
            )
        )
        return h.redirect_to(
            u'datastore.dictionary', id=id, resource_id=resource_id
        )
Beispiel #5
0
def filtered_download(resource_view_id):
    params = json.loads(request.form[u'params'])
    resource_view = get_action(u'resource_view_show')(None, {
        u'id': resource_view_id
    })

    search_text = text_type(params[u'search'][u'value'])
    view_filters = resource_view.get(u'filters', {})
    user_filters = text_type(params[u'filters'])
    filters = merge_filters(view_filters, user_filters)

    datastore_search = get_action(u'datastore_search')
    unfiltered_response = datastore_search(
        None, {
            u"resource_id": resource_view[u'resource_id'],
            u"limit": 0,
            u"filters": view_filters,
        })

    cols = [f[u'id'] for f in unfiltered_response[u'fields']]
    if u'show_fields' in resource_view:
        cols = [c for c in cols if c in resource_view[u'show_fields']]

    sort_list = []
    for order in params[u'order']:
        sort_by_num = int(order[u'column'])
        sort_order = (u'desc' if order[u'dir'] == u'desc' else u'asc')
        sort_list.append(cols[sort_by_num] + u' ' + sort_order)

    cols = [c for (c, v) in zip(cols, params[u'visible']) if v]

    colsearch_dict = {}
    columns = params[u'columns']
    for column in columns:
        if column[u'search'][u'value']:
            v = column[u'search'][u'value']
            if v:
                k = column[u'name']
                # replace non-alphanumeric characters with FTS wildcard (_)
                v = re.sub(r'[^0-9a-zA-Z\-]+', '_', v)
                # append ':*' so we can do partial FTS searches
                colsearch_dict[k] = v + u':*'

    if colsearch_dict:
        search_text = json.dumps(colsearch_dict)
    else:
        search_text = re.sub(r'[^0-9a-zA-Z\-]+', '_',
                             search_text) + u':*' if search_text else ''

    return h.redirect_to(
        h.url_for(u'datastore.dump', resource_id=resource_view[u'resource_id'])
        + u'?' + urlencode({
            u'q': search_text,
            u'plain': False,
            u'language': u'simple',
            u'sort': u','.join(sort_list),
            u'filters': json.dumps(filters),
            u'format': request.form[u'format'],
            u'fields': u','.join(cols),
        }))
def delete(content_type, content_item_id, comment_id):
    context = {'model': model, 'user': c.user}
    data_dict = {'id': content_item_id}

    # Auth check to make sure the user can see this content item
    helpers.check_content_access(content_type, context, data_dict)

    try:
        # Load the content item
        helpers.get_content_item(content_type, context, data_dict)
    except:
        abort(403)

    try:
        data_dict = {
            'id': comment_id,
            'content_type': content_type,
            'content_item_id': content_item_id
        }
        get_action('comment_delete')(context, data_dict)
    except Exception as e:
        log.debug(e)
        if e.error_dict and e.error_dict.get('message'):
            msg = e.error_dict['message']
        else:
            msg = str(e)
        h.flash_error(msg)

    return h.redirect_to(
        helpers.get_redirect_url(
            content_type,
            content_item_id if content_type == 'datarequest' else c.pkg.name,
            'comment_' + str(comment_id)))
Beispiel #7
0
    def filtered_download(self, resource_view_id):
        params = json.loads(request.params['params'])
        resource_view = get_action(u'resource_view_show')(
            None, {
                u'id': resource_view_id
            })

        search_text = text_type(params['search']['value'])
        view_filters = resource_view.get(u'filters', {})
        user_filters = text_type(params['filters'])
        filters = merge_filters(view_filters, user_filters)

        datastore_search = get_action(u'datastore_search')
        unfiltered_response = datastore_search(
            None, {
                u"resource_id": resource_view[u'resource_id'],
                u"limit": 0,
                u"filters": view_filters,
            })

        cols = [f['id'] for f in unfiltered_response['fields']]
        if u'show_fields' in resource_view:
            cols = [c for c in cols if c in resource_view['show_fields']]

        sort_list = []
        for order in params['order']:
            sort_by_num = int(order['column'])
            sort_order = (u'desc' if order['dir'] == u'desc' else u'asc')
            sort_list.append(cols[sort_by_num] + u' ' + sort_order)

        cols = [c for (c, v) in zip(cols, params['visible']) if v]

        h.redirect_to(
            h.url_for(
                controller=u'ckanext.datastore.controller:DatastoreController',
                action=u'dump',
                resource_id=resource_view[u'resource_id']) + u'?' +
            urlencode({
                u'q': search_text,
                u'sort': u','.join(sort_list),
                u'filters': json.dumps(filters),
                u'format': request.params['format'],
                u'fields': u','.join(cols),
            }))
Beispiel #8
0
    def filtered_download(self, resource_view_id):
        params = json.loads(request.params['params'])
        resource_view = get_action(u'resource_view_show')(
            None, {u'id': resource_view_id})

        search_text = text_type(params['search']['value'])
        view_filters = resource_view.get(u'filters', {})
        user_filters = text_type(params['filters'])
        filters = merge_filters(view_filters, user_filters)

        datastore_search = get_action(u'datastore_search')
        unfiltered_response = datastore_search(None, {
            u"resource_id": resource_view[u'resource_id'],
            u"limit": 0,
            u"filters": view_filters,
        })

        cols = [f['id'] for f in unfiltered_response['fields']]
        if u'show_fields' in resource_view:
            cols = [c for c in cols if c in resource_view['show_fields']]

        sort_list = []
        for order in params['order']:
            sort_by_num = int(order['column'])
            sort_order = (
                u'desc' if order['dir'] == u'desc'
                else u'asc')
            sort_list.append(cols[sort_by_num] + u' ' + sort_order)

        cols = [c for (c, v) in zip(cols, params['visible']) if v]

        h.redirect_to(
            h.url_for(
                controller=u'ckanext.datastore.controller:DatastoreController',
                action=u'dump',
                resource_id=resource_view[u'resource_id'])
            + u'?' + urlencode({
                u'q': search_text,
                u'sort': u','.join(sort_list),
                u'filters': json.dumps(filters),
                u'format': request.params['format'],
                u'fields': u','.join(cols),
                }))
Beispiel #9
0
    def dictionary(self, id, resource_id):
        u'''data dictionary view: show/edit field labels and descriptions'''

        try:
            # resource_edit_base template uses these
            c.pkg_dict = get_action('package_show')(None, {'id': id})
            c.resource = get_action('resource_show')(None, {'id': resource_id})
            rec = get_action('datastore_search')(None, {
                'resource_id': resource_id,
                'limit': 0
            })
        except (ObjectNotFound, NotAuthorized):
            abort(404, _('Resource not found'))

        fields = [f for f in rec['fields'] if not f['id'].startswith('_')]

        if request.method == 'POST':
            get_action('datastore_create')(None, {
                'resource_id':
                resource_id,
                'force':
                True,
                'fields': [{
                    'id': f['id'],
                    'type': f['type'],
                    'info': {
                        'label': request.POST.get('f{0}label'.format(i)),
                        'notes': request.POST.get('f{0}notes'.format(i)),
                    }
                } for i, f in enumerate(fields, 1)]
            })

            h.redirect_to(
                controller='ckanext.datastore.controller:DatastoreController',
                action='dictionary',
                id=id,
                resource_id=resource_id)

        return render('datastore/dictionary.html',
                      extra_vars={'fields': fields})
def unflag(content_type, content_item_id, comment_id):
    """
    Remove the 'flagged' attribute on a comment
    :param content_type: string 'dataset' or 'datarequest'
    :param content_item_id: string
    :param comment_id: string ID of the comment to unflag
    :return:
    """
    context = {'model': model, 'user': c.user}

    # Using the comment model rather than the update action because update action updates modified timestamp
    comment = comment_model.Comment.get(comment_id)

    if not comment \
            or not comment.flagged \
            or not authz.auth_is_loggedin_user() \
            or not helpers.user_can_manage_comments(content_type, content_item_id):
        abort(403)

    comment.flagged = False

    model.Session.add(comment)
    model.Session.commit()

    h.flash_success(_('Comment un-flagged'))

    data_dict = {'id': content_item_id}

    if content_type == 'datarequest':
        c.datarequest = get_action('show_datarequest')(context, data_dict)
        return h.redirect_to(
            str('/datarequest/comment/%s#comment_%s' %
                (content_item_id, comment_id)))
    else:
        c.pkg_dict = get_action('package_show')(context, data_dict)
        c.pkg = context['package']
        return h.redirect_to(
            str('/dataset/%s#comment_%s' % (content_item_id, comment_id)))

    return helpers.render_content_template(content_type)
 def post(self, dataset_id, resource_id, id):
     context = {'model': model, 'session': model.Session, 'user': c.user}
     try:
         get_action('resource_acl_delete')(context, {'id': id})
         h.flash_notice(_('Resource ACL has been deleted.'))
         return h.redirect_to(
             'resourceauthorizer.resource_acl',
             dataset_id=dataset_id,
             resource_id=resource_id
         )
     except NotAuthorized:
         abort(403)
     except NotFound:
         abort(404)
def edit(content_type, content_item_id, comment_id):
    context = {'model': model, 'user': c.user}
    data_dict = {'id': content_item_id}

    # Auth check to make sure the user can see this content item
    helpers.check_content_access(content_type, context, data_dict)

    try:
        # Load the content item
        helpers.get_content_item(content_type, context, data_dict)
    except:
        abort(403)

    if request.method == 'POST':
        data_dict = clean_dict(
            unflatten(
                tuplize_dict(
                    parse_params(
                        request_helpers.RequestHelper(
                            request).get_post_params()))))
        data_dict['id'] = comment_id
        data_dict['content_type'] = content_type
        data_dict['content_item_id'] = content_item_id
        success = False
        try:
            get_action('comment_update')(context, data_dict)
            success = True
        except ValidationError as ve:
            log.debug(ve)
            if ve.error_dict and ve.error_dict.get('message'):
                msg = ve.error_dict['message']
            else:
                msg = str(ve)
            h.flash_error(msg)
        except Exception as e:
            log.debug(e)
            abort(403)

        return h.redirect_to(
            helpers.get_redirect_url(
                content_type, content_item_id
                if content_type == 'datarequest' else c.pkg.name, 'comment_' +
                str(comment_id) if success else 'edit_' + str(comment_id)))

    return helpers.render_content_template(content_type)
Beispiel #13
0
 def _redirect_to_this_controller(self, *args, **kw):
     kw['controller'] = request.environ['pylons.routes_dict']['controller']
     return h.redirect_to(*args, **kw)
 def post(self, dataset_id, resource_id):
     context = {'model': model, 'session': model.Session, 'user': c.user}
     try:
         check_access('resource_acl_create', context, {
             'resource_id': resource_id
         })
     except NotAuthorized:
         abort(403, _('Unauthorized to create resource acl %s') % '')
     try:
         pkg_dict = get_action('package_show')(None, {'id': dataset_id})
         resource = get_action('resource_show')(None, {'id': resource_id})
         permissions = [{
             'text': u'None',
             'value': 'none'
         }, {
             'text': u'Read',
             'value': 'read'
         }]
         data_dict = clean_dict(
             dict_fns.unflatten( 
                 tuplize_dict(parse_params(request.form))))
         acl = data_dict.get('id')
         if acl is None:
             data = {
                 'resource_id': resource_id,
                 'permission': data_dict['permission']
             }
             if data_dict['organization']:
                 group = model.Group.get(data_dict['organization'])
                 if not group:
                     message = _(u'Organization {org} does not exist.').format(
                         org=data_dict['organization'])
                     raise ValidationError(
                         {
                             'message': message
                         }, error_summary=message)
                 data['auth_type'] = 'org'
                 data['auth_id'] = group.id
             elif data_dict['username']:
                 user = model.User.get(data_dict['username'])
                 if not user:
                     message = _(u'User {username} does not exist.').format(
                         username=data_dict['username'])
                     raise ValidationError(
                         {
                             'message': message
                         }, error_summary=message)
                 data['auth_type'] = 'user'
                 data['auth_id'] = user.id
             get_action('resource_acl_create')(None, data)
         else:
             data = {'id': acl, 'permission': data_dict['permission']}
             get_action('resource_acl_patch')(None, data)
         return h.redirect_to(
             'resourceauthorizer.resource_acl',
             dataset_id=dataset_id,
             resource_id=resource_id
         )
     except NotAuthorized:
         abort(403)
     except NotFound:
         abort(404)
     except ValidationError as e:
         h.flash_error(e.error_summary)
def _add_or_reply(comment_type, content_item_id, content_type, parent_id=None):
    """
    Allows the user to add a comment to an existing dataset or datarequest
    :param comment_type: Either 'new' or 'reply'
    :param content_item_id:
    :param content_type: string 'dataset' or 'datarequest'
    :return:
    """
    content_type = 'dataset' if 'content_type' not in vars() else content_type

    context = {'model': model, 'user': c.user}

    data_dict = {'id': content_item_id}

    # Auth check to make sure the user can see this content item
    helpers.check_content_access(content_type, context, data_dict)

    try:
        # Load the content item
        helpers.get_content_item(content_type, context, data_dict)
    except:
        abort(403)

    if request.method == 'POST':
        data_dict = clean_dict(
            unflatten(
                tuplize_dict(
                    parse_params(
                        request_helpers.RequestHelper(
                            request).get_post_params()))))
        data_dict['parent_id'] = c.parent.id if 'parent' in dir(c) else None

        data_dict['url'] = '/%s/%s' % (content_type,
                                       content_item_id if content_type
                                       == 'datarequest' else c.pkg.name)

        success = False
        try:
            res = get_action('comment_create')(context, data_dict)
            success = True
        except ValidationError as ve:
            log.debug(ve)
            if ve.error_dict and ve.error_dict.get('message'):
                msg = ve.error_dict['message']
            else:
                msg = str(ve)
            h.flash_error(msg)
        except Exception as e:
            log.debug(e)
            abort(403)

        if success:
            email_notifications.notify_admins_and_comment_notification_recipients(
                helpers.get_org_id(content_type),
                toolkit.c.userobj,
                'notification-new-comment',
                content_type,
                helpers.get_content_item_id(content_type),
                res['thread_id'],
                res['parent_id'] if comment_type == 'reply' else None,
                res['id'],
                c.pkg_dict['title']
                if content_type == 'dataset' else c.datarequest['title'],
                res['content']  # content is the comment that has been cleaned up in the action comment_create
            )

            if notification_helpers.comment_notification_recipients_enabled():
                if comment_type == 'reply':
                    # Add the user who submitted the reply to comment notifications for this thread
                    notification_helpers.add_commenter_to_comment_notifications(
                        toolkit.c.userobj.id, res['thread_id'],
                        res['parent_id'])
                else:
                    # Add the user who submitted the comment notifications for this new thread
                    notification_helpers.add_commenter_to_comment_notifications(
                        toolkit.c.userobj.id, res['thread_id'], res['id'])

        return h.redirect_to(
            helpers.get_redirect_url(
                content_type, content_item_id if content_type == 'datarequest'
                else c.pkg.name, 'comment_' + str(res['id']) if success else
                ('comment_form' if comment_type == 'new' else 'reply_' +
                 str(parent_id))))

    return helpers.render_content_template(content_type)