Example #1
0
def showcase_create(context, data_dict):
    '''Upload the image and continue with package creation.'''

    # force type to 'showcase'
    data_dict['type'] = 'showcase'

    # If get_uploader is available (introduced for IUploader in CKAN 2.5), use
    # it, otherwise use the default uploader.
    # https://github.com/ckan/ckan/pull/2510
    try:
        upload = uploader.get_uploader('showcase')
    except AttributeError:
        upload = uploader.Upload('showcase')

    # schema images
    imgs = ['icon', 'featured_image', 'image_1', 'image_2', 'image_3']
    for image in imgs:
        if data_dict[image]:
            upload.update_data_dict(data_dict, image,
                                image+'_upload', 'clear_'+ image + '_upload')

            upload.upload(uploader.get_max_image_size())

    pkg = toolkit.get_action('package_create')(context, data_dict)

    return pkg
Example #2
0
def image_uploaded():
    '''View function to handle uploading arbitrary images for the home page.
    Passes `'image_url': 'submitted-image-path'` to template/view function.
    '''
    data_dict = {}
    try:
        # Cleanup the data_dict for the uploader.
        req = request.form.copy()
        req.update(request.files.to_dict())
        data_dict = logic.clean_dict(
            dict_fns.unflatten(
                logic.tuplize_dict(
                    logic.parse_params(req, ignore_keys=CACHE_PARAMETERS))))

        # Upload the image.
        upload = uploader.get_uploader('home')
        upload.update_data_dict(data_dict, 'image_url', 'image_upload',
                                'clear_upload')
        upload.upload(uploader.get_max_image_size())

        image_url = ''
        # Build and return the image url.
        for key, value in data_dict.iteritems():
            if key == 'image_url' and value and not value.startswith('http')\
                    and not value.startswith('/'):
                image_path = 'uploads/home/'
                value = h.url_for_static('{0}{1}'.format(image_path, value))
                image_url = value
    except Exception as e:
        log.error(e)
    return h.redirect_to(u'ontario_theme.image_uploader', image_url=image_url)
Example #3
0
    def manage_footer_logos(self):
        data = dict(toolkit.request.POST)

        if 'save' in data:
            try:
                del data['save']

                upload = uploader.get_uploader('admin')

                # Upload footer logos
                for i in range(1, 6):
                    upload.update_data_dict(data,
                                            'footer_logo_{0}_image_url'
                                            .format(i),
                                            'footer_logo_{0}_upload'.format(i),
                                            'clear_footer_logo_{0}_upload'
                                            .format(i))
                    upload.upload(uploader.get_max_image_size())

                data = toolkit.get_action('config_option_update')({}, data)
            except toolkit.ValidationError, e:
                errors = e.error_dict
                error_summary = e.error_summary
                vars = {'data': data, 'errors': errors,
                        'error_summary': error_summary}

                return toolkit.render('admin/tayside_manage_footer_logos.html',
                                      extra_vars=vars)

            ctrl =\
                'ckanext.tayside.controllers.admin:AdminController'
            toolkit.redirect_to(controller=ctrl, action='manage_footer_logos')
Example #4
0
def showcase_create(context, data_dict):
    '''Upload the image and continue with package creation.'''

    # force type to 'showcase'
    data_dict['type'] = 'showcase'
    # If get_uploader is available (introduced for IUploader in CKAN 2.5), use
    # it, otherwise use the default uploader.
    # https://github.com/ckan/ckan/pull/2510
    try:
        upload = uploader.get_uploader('showcase')
    except AttributeError:
        upload = uploader.Upload('showcase')

    if 'image_upload' in data_dict:
        # mimetype is needed before uploading to AWS S3
        upload.mimetype = getattr(data_dict['image_upload'], 'type',
                                  'application/octet-stream')
    upload.update_data_dict(data_dict, 'image_url', 'image_upload',
                            'clear_upload')

    upload.upload(uploader.get_max_image_size())

    pkg = toolkit.get_action('package_create')(context, data_dict)

    return pkg
Example #5
0
def pages_upload(context, data_dict):

    try:
        p.toolkit.check_access('ckanext_pages_upload', context, data_dict)
    except p.toolkit.NotAuthorized:
        p.toolkit.abort(401, p.toolkit._('Not authorized to see this page'))

    if p.toolkit.check_ckan_version(min_version='2.5'):
        upload = uploader.get_uploader('page_images')
    else:
        upload = uploader.Upload('page_images')

    upload.update_data_dict(data_dict, 'image_url', 'upload', 'clear_upload')

    upload.upload(uploader.get_max_image_size())

    image_url = data_dict.get('image_url')

    if not image_mime_type_validator(upload.filepath):
        raise ValidationError(tk._('You can upload image file only'))

    if image_url:
        image_url = h.url_for_static('uploads/page_images/%s' % image_url,
                                     qualified=True)
    return image_url
Example #6
0
    def organogram_admin(self):
        if toolkit.request.method == 'POST':
            data = dict(toolkit.request.POST)

            if isinstance(data.get('organogram_file_upload'),
                          cgi.FieldStorage):
                upload = uploader.get_uploader('organogram',
                                               data['organogram_file_url'])
                upload.update_data_dict(data, 'organogram_file_url',
                                        'organogram_file_upload',
                                        'clear_upload')
                upload.upload(uploader.get_max_image_size())
                organogram_file_url = upload.filename
            else:
                organogram_file_url = data.get('organogram_file_url')

            toolkit.get_action('config_option_update')(
                {}, {
                    'ckanext.organogram.file_url': organogram_file_url
                })

        organogram_file_url = toolkit.get_action('config_option_show')(
            {}, {
                'key': 'ckanext.organogram.file_url'
            })

        extra_vars = {
            'data': {
                'organogram_file_url': organogram_file_url
            },
            'errors': {}
        }
        return toolkit.render('admin/organogram_config.html', extra_vars)
Example #7
0
def showcase_create(context, data_dict):
    '''Upload the image and continue with package creation.'''

    # force type to 'showcase'
    data_dict['type'] = 'showcase'

    # If get_uploader is available (introduced for IUploader in CKAN 2.5), use
    # it, otherwise use the default uploader.
    # https://github.com/ckan/ckan/pull/2510
    try:
        upload = uploader.get_uploader('showcase')
    except AttributeError:
        upload = uploader.Upload('showcase')

    # schema images
    imgs = ['icon', 'featured_image', 'image_1', 'image_2', 'image_3']
    for image in imgs:
        if data_dict[image]:
            upload.update_data_dict(data_dict, image,
                                    image + '_upload', 'clear_' + image + '_upload')

            upload.upload(uploader.get_max_image_size())

    pkg = toolkit.get_action('package_create')(context, data_dict)

    return pkg
Example #8
0
def showcase_update(context, data_dict):

    upload = uploader.Upload('showcase', data_dict['image_url'])
    upload.update_data_dict(data_dict, 'image_url',
                            'image_upload', 'clear_upload')

    upload.upload(uploader.get_max_image_size())

    pkg = toolkit.get_action('package_update')(context, data_dict)

    return pkg
Example #9
0
def showcase_update(context, data_dict):

    upload = uploader.get_uploader('showcase', data_dict['image_url'])

    upload.update_data_dict(data_dict, 'image_url', 'image_upload',
                            'clear_upload')

    upload.upload(uploader.get_max_image_size())

    pkg = toolkit.get_action('package_update')(context, data_dict)

    return pkg
def validate_banner_image(key, flattened_data, errors, context):
    """
    Validates banner image, save the file and update the field.
    """
    # Get previous file, so we can remove it.
    banner_image = toolkit.config.get('ckanext.qdes.banner_image', '') or ''

    # Upload image.
    upload = uploader.get_uploader('qdes-admin', banner_image)
    upload.update_data_dict(flattened_data, ('ckanext.qdes.banner_image', ),
                            ('banner_image_upload', ),
                            ('clear_banner_image_upload', ))
    upload.upload(uploader.get_max_image_size())
Example #11
0
def project_create(context, data_dict):
    """Upload the image and continue with package creation."""

    # force type to 'project'
    data_dict["type"] = "project"

    upload = uploader.Upload("project")
    upload.update_data_dict(data_dict, "image_url", "image_upload", "clear_upload")

    upload.upload(uploader.get_max_image_size())

    pkg = toolkit.get_action("package_create")(context, data_dict)

    return pkg
Example #12
0
def showcase_create(context, data_dict):
    '''Upload the image and continue with package creation.'''

    # force type to 'showcase'
    data_dict['type'] = 'showcase'

    upload = uploader.Upload('showcase')
    upload.update_data_dict(data_dict, 'image_url',
                            'image_upload', 'clear_upload')

    upload.upload(uploader.get_max_image_size())

    pkg = toolkit.get_action('package_create')(context, data_dict)

    return pkg
Example #13
0
def showcase_create(context, data_dict):
    '''Upload the image and continue with package creation.'''

    # force type to 'showcase'
    data_dict['type'] = 'showcase'
    upload = uploader.get_uploader('showcase')

    upload.update_data_dict(data_dict, 'image_url', 'image_upload',
                            'clear_upload')

    upload.upload(uploader.get_max_image_size())

    pkg = toolkit.get_action('package_create')(context, data_dict)

    return pkg
def _upload_chart_icon(chart_type, data):
    if '{0}_chart_upload'.format(chart_type) in data:
        image_upload = data.get('{0}_chart_upload'.format(chart_type))

        if isinstance(image_upload, ALLOWED_UPLOAD_TYPES):
            upload = uploader.get_uploader(
                'chart_icons', data.get('{0}_chart'.format(chart_type)))
            upload.update_data_dict(
                data, '{0}_chart'.format(chart_type),
                '{0}_chart_upload'.format(chart_type),
                '{0}_chart_clear_upload'.format(chart_type))
            upload.upload(uploader.get_max_image_size())
            return upload.filename
        else:
            return data.get('{0}_chart'.format(chart_type))
Example #15
0
def showcase_upload(context, data_dict):
    ''' Uploads images to be used in showcase content.

    '''
    toolkit.check_access('ckanext_showcase_upload', context, data_dict)

    upload = uploader.get_uploader('showcase_image')

    upload.update_data_dict(data_dict, 'image_url', 'upload', 'clear_upload')
    upload.upload(uploader.get_max_image_size())

    image_url = data_dict.get('image_url')
    if image_url and image_url[0:6] not in {'http:/', 'https:'}:
        image_url = h.url_for_static(
            'uploads/showcase_image/{}'.format(image_url), qualified=True)
    return {'url': image_url}
Example #16
0
def experience_update(context, data_dict):

    # If get_uploader is available (introduced for IUploader in CKAN 2.5), use
    # it, otherwise use the default uploader.
    # https://github.com/ckan/ckan/pull/2510
    try:
        upload = uploader.get_uploader('experience', data_dict['image_url'])
    except AttributeError:
        upload = uploader.Upload('experience', data_dict['image_url'])

    upload.update_data_dict(data_dict, 'image_url',
                            'image_upload', 'clear_upload')

    upload.upload(uploader.get_max_image_size())

    pkg = toolkit.get_action('package_update')(context, data_dict)

    return pkg
def pages_upload(context, data_dict):
    try:
        p.toolkit.check_access('ckanext_pages_upload', context, data_dict)
    except p.toolkit.NotAuthorized:
        p.toolkit.abort(401, p.toolkit._('Not authorized to see this page'))

    if p.toolkit.check_ckan_version(min_version='2.5'):
        upload = uploader.get_uploader('page_images')
    else:
        upload = uploader.Upload('page_images')

    upload.update_data_dict(data_dict, 'image_url', 'upload', 'clear_upload')
    upload.upload(uploader.get_max_image_size())
    image_url = data_dict.get('image_url')
    if image_url:
        image_url = h.url_for_static('uploads/page_images/%s' % image_url,
                                     qualified=True)
    return {'url': image_url}
Example #18
0
def showcase_update(context, data_dict):

    # If get_uploader is available (introduced for IUploader in CKAN 2.5), use
    # it, otherwise use the default uploader.
    # https://github.com/ckan/ckan/pull/2510
    try:
        upload = uploader.get_uploader('showcase', data_dict['image_url'])
    except AttributeError:
        upload = uploader.Upload('showcase', data_dict['image_url'])

    upload.update_data_dict(data_dict, 'image_url',
                            'image_upload', 'clear_upload')

    upload.upload(uploader.get_max_image_size())

    pkg = toolkit.get_action('package_update')(context, data_dict)

    return pkg
Example #19
0
def config_option_update(context, data_dict):
    # https://github.com/ckan/ckan/blob/master/ckan/logic/action/update.py#L1198

    # Handle featured image
    if 'ckanext.lacounts.featured_image' in data_dict:
        upload = uploader.get_uploader('admin')
        upload.update_data_dict(data_dict, 'ckanext.lacounts.featured_image',
                                'featured_image_upload',
                                'clear_featured_image_upload')
        upload.upload(uploader.get_max_image_size())
        value = data_dict['ckanext.lacounts.featured_image']
        if value \
           and not value.startswith('http') \
           and not value.startswith('/'):
            image_path = 'uploads/admin/'
            value = h.url_for_static('{0}{1}'.format(image_path, value))
        data_dict['ckanext.lacounts.featured_image'] = value

    return update_core.config_option_update(context, data_dict)
Example #20
0
def showcase_upload(context, data_dict):
    ''' Uploads images to be used in showcase content.

    '''
    toolkit.check_access('ckanext_showcase_upload', context, data_dict)

    try:
        upload = uploader.get_uploader('showcase_image')
    except AttributeError:
        upload = uploader.Upload('showcase_image')

    upload.update_data_dict(data_dict, 'image_url', 'upload', 'clear_upload')
    upload.upload(uploader.get_max_image_size())

    image_url = data_dict.get('image_url')
    if image_url:
        image_url = h.url_for_static(
            'uploads/showcase_image/{}'.format(image_url), qualified=True)
    return {'url': image_url}
Example #21
0
 def app_add(self):
     if c.userobj is None:
         tk.redirect_to(
             tk.url_for(controller='user',
                        action='login',
                        came_from=full_current_url()))
     form = CreateAppForm(tk.request.POST)
     data_dict = clean_dict(
         dict_fns.unflatten(tuplize_dict(parse_params(tk.request.params))))
     upload = uploader.get_uploader('apps')
     if tk.request.POST:
         if form.validate():
             # Upload[load image
             upload.update_data_dict(data_dict, 'image_url', 'image_upload',
                                     'clear_upload')
             try:
                 upload.upload(uploader.get_max_image_size())
             except logic.ValidationError as err:
                 flash_error(err.error_dict['image_upload'][0])
             else:
                 app = App()
                 form.populate_obj(app)
                 app.author_id = c.userobj.id
                 app.content = strip_tags(app.content)
                 app.status = "pending"
                 app.image_url = data_dict.get('image_url')
                 app.save()
                 log.debug("App data is valid. Content: %s",
                           strip_tags(app.name))
                 flash_success(tk._('You successfully create app'))
                 jobs.enqueue(
                     send_notifications_on_change_app_status,
                     [app, 'pending',
                      tk.request.environ.get('CKAN_LANG')])
                 tk.redirect_to(app.get_absolute_url())
         else:
             flash_error(tk._('You have errors in form'))
             log.info("Validate errors: %s", form.errors)
     context = {'form': form, 'active_boards': Board.filter_active()}
     log.debug('ForumController.thread_add context: %s', context)
     return self.__render('create_app.html', context)
Example #22
0
def package_update(context, data_dict):

    '''Update a dataset (package).

    You must be authorized to edit the dataset and the groups that it belongs
    to.

    Plugins may change the parameters of this function depending on the value
    of the dataset's ``type`` attribute, see the ``IDatasetForm`` plugin
    interface.

    For further parameters see ``package_create()``.

    :param id: the name or id of the dataset to update
    :type id: string

    :returns: the updated dataset (if 'return_package_dict' is True in the
              context, which is the default. Otherwise returns just the
              dataset id)
    :rtype: dictionary

    '''


    model = context['model']
    user = context['user']
    name_or_id = data_dict.get("id") or data_dict['name']

    pkg = model.Package.get(name_or_id)

    if pkg is None:
        raise NotFound(_('Package was not found.'))
    context["package"] = pkg
    data_dict["id"] = pkg.id

    # FIXME: first modifications to package_updade begin here:
    # tag strings are reconstructed because validators are stripping
    # tags passed and only taking taks as tag_string values
    # image upload support has also been added here
    old_data = get_action('package_show')(context, {'id': pkg.id})

    '''
    Constructing the tag_string from the given tags.
    There must be at least one tag, otherwise the tag_string will be empty and a validation error
    will be raised.
    '''
    if not data_dict.get('tag_string'):
        data_dict['tag_string'] = ', '.join(
                h.dict_list_reduce(data_dict.get('tags', {}), 'name'))


    for key, value in old_data.iteritems() :
        if key not in data_dict :
            data_dict[key] = value

    #data_dict['resources'] = data_dict.get('resources', old_data.get('resources'))


#     iso_topic_cat = data_dict.get('iso_topic_string', [])
#     if isinstance(iso_topic_cat, basestring):
#         iso_topic_cat = [iso_topic_cat]
#
#     data_dict['iso_topic_string'] = ','.join(iso_topic_cat)


    #Set the package last modified date
    data_dict['record_last_modified'] = str(datetime.date.today())

    # If the Created Date has not yet been set, then set it
    if data_dict['edc_state'] == 'DRAFT' and not data_dict.get('record_create_date'):
        data_dict['record_create_date'] = str(datetime.date.today())

    # If the Publish Date has not yet been set, then set it
    if data_dict['edc_state'] == 'PUBLISHED' and not data_dict.get('record_publish_date'):
        data_dict['record_publish_date'] = str(datetime.date.today())

    # If the Archive Date has not yet been set, then set it
    if data_dict['edc_state'] == 'ARCHIVED' and not data_dict.get('record_archive_date'):
        data_dict['record_archive_date'] = str(datetime.date.today())

    _check_access('package_update', context, data_dict)

    # get the schema
    package_plugin = lib_plugins.lookup_package_plugin(pkg.type)
    if 'schema' in context:
        schema = context['schema']
    else:
        schema = package_plugin.update_package_schema()

    image_url = old_data.get('image_url', None)

    upload = uploader.Upload('edc', image_url)
    upload.update_data_dict(data_dict, 'image_url', 'image_upload', 'clear_upload')

    #Adding image display url for the uploaded image
    image_url = data_dict.get('image_url')
    data_dict['image_display_url'] = image_url

    if image_url and not image_url.startswith('http'):
        image_url = munge.munge_filename(image_url)
        data_dict['image_display_url'] = h.url_for_static('uploads/edc/%s' % data_dict.get('image_url'), qualified=True)

    if 'api_version' not in context:
        # check_data_dict() is deprecated. If the package_plugin has a
        # check_data_dict() we'll call it, if it doesn't have the method we'll
        # do nothing.
        check_data_dict = getattr(package_plugin, 'check_data_dict', None)
        if check_data_dict:
            try:
                package_plugin.check_data_dict(data_dict, schema)
            except TypeError:
                # Old plugins do not support passing the schema so we need
                # to ensure they still work.
                package_plugin.check_data_dict(data_dict)
    # FIXME: modifications to package_update end here^

    data, errors = _validate(data_dict, schema, context)
#     log.debug('package_update validate_errs=%r user=%s package=%s data=%r',
#               errors, context.get('user'),
#               context.get('package').name if context.get('package') else '',
#               data)

    if errors:
        model.Session.rollback()
        raise ValidationError(errors)

    rev = model.repo.new_revision()
    rev.author = user
    if 'message' in context:
        rev.message = context['message']
    else:
        rev.message = _(u'REST API: Update object %s') % data.get("name")



    #avoid revisioning by updating directly
    model.Session.query(model.Package).filter_by(id=pkg.id).update(
        {"metadata_modified": datetime.datetime.utcnow()})
    model.Session.refresh(pkg)

    pkg = model_save.package_dict_save(data, context)

    context_org_update = context.copy()
    context_org_update['ignore_auth'] = True
    context_org_update['defer_commit'] = True
    _get_action('package_owner_org_update')(context_org_update,
                                            {'id': pkg.id,
                                             'organization_id': pkg.owner_org})

    for item in plugins.PluginImplementations(plugins.IPackageController):
        item.edit(pkg)

        item.after_update(context, data)


    upload.upload(uploader.get_max_image_size())

    #TODO the next two blocks are copied from ckan/ckan/logic/action/update.py
    # This codebase is currently hard to maintain because large chunks of the
    # CKAN action API and the CKAN controllers are simply overriden. This is
    # probably worse than just forking CKAN would have been, because in that
    # case at least we could track changes. - @deniszgonjanin

    # Needed to let extensions know the new resources ids
    model.Session.flush()
    if data.get('resources'):
        for index, resource in enumerate(data['resources']):
            resource['id'] = pkg.resources[index].id

    # Create default views for resources if necessary
    if data.get('resources'):
        logic.get_action('package_create_default_resource_views')(
            {'model': context['model'], 'user': context['user'],
             'ignore_auth': True},
            {'package': data})

    if not context.get('defer_commit'):
        model.repo.commit()

    log.debug('Updated object %s' % pkg.name)

    return_id_only = context.get('return_id_only', False)

    # Make sure that a user provided schema is not used on package_show
    context.pop('schema', None)

    # we could update the dataset so we should still be able to read it.
    context['ignore_auth'] = True
    output = data_dict['id'] if return_id_only \
            else _get_action('package_show')(context, {'id': data_dict['id']})


    '''
    Send state change notifications if required; Added by Khalegh Mamakani
    Using a thread to run the job in the background so that package_update will not wait for notifications sending.
    '''

    old_state = old_data.get('edc_state')

    context = {'model': model, 'session': model.Session,
               'user': c.user or c.author, 'auth_user_obj': c.userobj}

    dataset_url = config.get('ckan.site_url') + h.url_for(controller='package', action="read", id = data_dict['name'])
    import threading

    notify_thread = threading.Thread(target=check_record_state, args=(context, old_state, data_dict, g.site_title, g.site_url, dataset_url) )
    notify_thread.start()

    return output
Example #23
0
def logic_action_create_package_create(context, data_dict):
    '''Create a new dataset (package).

    You must be authorized to create new datasets. If you specify any groups
    for the new dataset, you must also be authorized to edit these groups.

    Plugins may change the parameters of this function depending on the value
    of the ``type`` parameter, see the
    :py:class:`~ckan.plugins.interfaces.IDatasetForm` plugin interface.

    :param name: the name of the new dataset, must be between 2 and 100
        characters long and contain only lowercase alphanumeric characters,
        ``-`` and ``_``, e.g. ``'warandpeace'``
    :type name: string
    :param title: the title of the dataset (optional, default: same as
        ``name``)
    :type title: string
    :param author: the name of the dataset's author (optional)
    :type author: string
    :param author_email: the email address of the dataset's author (optional)
    :type author_email: string
    :param maintainer: the name of the dataset's maintainer (optional)
    :type maintainer: string
    :param maintainer_email: the email address of the dataset's maintainer
        (optional)
    :type maintainer_email: string
    :param license_id: the id of the dataset's license, see
        :py:func:`~ckan.logic.action.get.license_list` for available values
        (optional)
    :type license_id: license id string
    :param notes: a description of the dataset (optional)
    :type notes: string
    :param url: a URL for the dataset's source (optional)
    :type url: string
    :param version: (optional)
    :type version: string, no longer than 100 characters
    :param state: the current state of the dataset, e.g. ``'active'`` or
        ``'deleted'``, only active datasets show up in search results and
        other lists of datasets, this parameter will be ignored if you are not
        authorized to change the state of the dataset (optional, default:
        ``'active'``)
    :type state: string
    :param type: the type of the dataset (optional),
        :py:class:`~ckan.plugins.interfaces.IDatasetForm` plugins
        associate themselves with different dataset types and provide custom
        dataset handling behaviour for these types
    :type type: string
    :param resources: the dataset's resources, see
        :py:func:`resource_create` for the format of resource dictionaries
        (optional)
    :type resources: list of resource dictionaries
    :param tags: the dataset's tags, see :py:func:`tag_create` for the format
        of tag dictionaries (optional)
    :type tags: list of tag dictionaries
    :param extras: the dataset's extras (optional), extras are arbitrary
        (key: value) metadata items that can be added to datasets, each extra
        dictionary should have keys ``'key'`` (a string), ``'value'`` (a
        string)
    :type extras: list of dataset extra dictionaries
    :param relationships_as_object: see :py:func:`package_relationship_create`
        for the format of relationship dictionaries (optional)
    :type relationships_as_object: list of relationship dictionaries
    :param relationships_as_subject: see :py:func:`package_relationship_create`
        for the format of relationship dictionaries (optional)
    :type relationships_as_subject: list of relationship dictionaries
    :param groups: the groups to which the dataset belongs (optional), each
        group dictionary should have one or more of the following keys which
        identify an existing group:
        ``'id'`` (the id of the group, string), or ``'name'`` (the name of the
        group, string),  to see which groups exist
        call :py:func:`~ckan.logic.action.get.group_list`
    :type groups: list of dictionaries
    :param owner_org: the id of the dataset's owning organization, see
        :py:func:`~ckan.logic.action.get.organization_list` or
        :py:func:`~ckan.logic.action.get.organization_list_for_user` for
        available values (optional)
    :type owner_org: string

    :returns: the newly created dataset (unless 'return_id_only' is set to True
              in the context, in which case just the dataset id will
              be returned)
    :rtype: dictionary

    '''

    import ckan.lib.plugins as lib_plugins
    import datetime
    import ckan.lib.dictization.model_save as model_save
    import ckan.plugins as plugins
    import ckan.lib.uploader as uploader
    _check_access = ckan.logic.check_access
    model = context['model']
    user = context['user']

    if 'type' not in data_dict:
        package_plugin = lib_plugins.lookup_package_plugin()
        try:
            # use first type as default if user didn't provide type
            package_type = package_plugin.package_types()[0]
        except (AttributeError, IndexError):
            package_type = 'dataset'
            # in case a 'dataset' plugin was registered w/o fallback
            package_plugin = lib_plugins.lookup_package_plugin(package_type)
        data_dict['type'] = package_type
    else:
        package_plugin = lib_plugins.lookup_package_plugin(data_dict['type'])

    if 'schema' in context:
        schema = context['schema']
    else:
        schema = package_plugin.create_package_schema()

    upload = uploader.Upload('package', '')
    upload.update_data_dict(data_dict, 'image_url', 'image_upload',
                            'clear_upload')

    _check_access('package_create', context, data_dict)

    if 'api_version' not in context:
        # check_data_dict() is deprecated. If the package_plugin has a
        # check_data_dict() we'll call it, if it doesn't have the method we'll
        # do nothing.
        check_data_dict = getattr(package_plugin, 'check_data_dict', None)
        if check_data_dict:
            try:
                check_data_dict(data_dict, schema)
            except TypeError:
                # Old plugins do not support passing the schema so we need
                # to ensure they still work
                package_plugin.check_data_dict(data_dict)

    data, errors = lib_plugins.plugin_validate(package_plugin, context,
                                               data_dict, schema,
                                               'package_create')
    log.debug('package_create validate_errs=%r user=%s package=%s data=%r',
              errors, context.get('user'), data.get('name'), data_dict)

    if errors:
        model.Session.rollback()
        raise ckan.logic.ValidationError(errors)

    rev = model.repo.new_revision()
    rev.author = user
    if 'message' in context:
        rev.message = context['message']
    else:
        rev.message = _(u'REST API: Create object %s') % data.get("name")

    admins = []
    if user:
        user_obj = model.User.by_name(user.decode('utf8'))
        if user_obj:
            admins = [user_obj]
            data['creator_user_id'] = user_obj.id

    upload.upload(uploader.get_max_image_size())
    generateThumbs(upload.filepath)

    if 'raw_image_url' in data_dict:
        data['extras'].append({
            'key': 'image_url',
            'value': data_dict['raw_image_url']
        })
        generateThumbs(
            config.get('ckan.storage_path') + '/storage/uploads/package/' +
            data_dict['raw_image_url'])

    pkg = model_save.package_dict_save(data, context)

    model.setup_default_user_roles(pkg, admins)
    # Needed to let extensions know the package and resources ids
    model.Session.flush()
    data['id'] = pkg.id
    if data.get('resources'):
        for index, resource in enumerate(data['resources']):
            resource['id'] = pkg.resources[index].id

    context_org_update = context.copy()
    context_org_update['ignore_auth'] = True
    context_org_update['defer_commit'] = True
    ckan.logic.get_action('package_owner_org_update')(
        context_org_update, {
            'id': pkg.id,
            'organization_id': pkg.owner_org
        })

    for item in plugins.PluginImplementations(plugins.IPackageController):
        item.create(pkg)

        item.after_create(context, data)

    # Make sure that a user provided schema is not used in create_views
    # and on package_show
    context.pop('schema', None)

    # Create default views for resources if necessary
    if data.get('resources'):
        ckan.logic.get_action('package_create_default_resource_views')(
            {
                'model': context['model'],
                'user': context['user'],
                'ignore_auth': True
            }, {
                'package': data
            })

    if not context.get('defer_commit'):
        model.repo.commit()

    ## need to let rest api create
    context["package"] = pkg
    ## this is added so that the rest controller can make a new location
    context["id"] = pkg.id
    log.debug('Created object %s' % pkg.name)

    return_id_only = context.get('return_id_only', False)

    output = context['id'] if return_id_only \
        else ckan.logic.get_action('package_show')(context, {'id': context['id']})

    return output
Example #24
0
def _group_or_org_update(context, data_dict, is_org=False):
    model = context['model']
    user = context['user']
    session = context['session']
    id = _get_or_bust(data_dict, 'id')

    group = model.Group.get(id)
    context["group"] = group
    if group is None:
        raise NotFound('Group was not found.')

    data_dict['type'] = group.type

    # get the schema
    group_plugin = lib_plugins.lookup_group_plugin(group.type)
    try:
        schema = group_plugin.form_to_db_schema_options({
            'type':
            'update',
            'api':
            'api_version' in context,
            'context':
            context
        })
    except AttributeError:
        schema = group_plugin.form_to_db_schema()

    upload = uploader.get_uploader('group', group.image_url)
    upload.update_data_dict(data_dict, 'image_url', 'image_upload',
                            'clear_upload')

    if is_org:
        _check_access('organization_update', context, data_dict)
    else:
        _check_access('group_update', context, data_dict)

    if 'api_version' not in context:
        # old plugins do not support passing the schema so we need
        # to ensure they still work
        try:
            group_plugin.check_data_dict(data_dict, schema)
        except TypeError:
            group_plugin.check_data_dict(data_dict)

    data, errors = lib_plugins.plugin_validate(
        group_plugin, context, data_dict, schema,
        'organization_update' if is_org else 'group_update')
    log.debug('group_update validate_errs=%r user=%s group=%s data_dict=%r',
              errors, context.get('user'),
              context.get('group').name if context.get('group') else '',
              data_dict)

    if errors:
        session.rollback()
        raise ValidationError(errors)

    rev = model.repo.new_revision()
    rev.author = user

    if 'message' in context:
        rev.message = context['message']
    else:
        rev.message = _(u'REST API: Update object %s') % data.get("name")

    group = model_save.group_dict_save(data,
                                       context,
                                       prevent_packages_update=is_org)

    if is_org:
        plugin_type = plugins.IOrganizationController
    else:
        plugin_type = plugins.IGroupController

    for item in plugins.PluginImplementations(plugin_type):
        item.edit(group)

    if is_org:
        activity_type = 'changed organization'
    else:
        activity_type = 'changed group'

    activity_dict = {
        'user_id': model.User.by_name(user.decode('utf8')).id,
        'object_id': group.id,
        'activity_type': activity_type,
    }
    # Handle 'deleted' groups.
    # When the user marks a group as deleted this comes through here as
    # a 'changed' group activity. We detect this and change it to a 'deleted'
    # activity.
    if group.state == u'deleted':
        if session.query(ckan.model.Activity).filter_by(
                object_id=group.id, activity_type='deleted').all():
            # A 'deleted group' activity for this group has already been
            # emitted.
            # FIXME: What if the group was deleted and then activated again?
            activity_dict = None
        else:
            # We will emit a 'deleted group' activity.
            activity_dict['activity_type'] = 'deleted group'
    if activity_dict is not None:
        activity_dict['data'] = {
            'group': dictization.table_dictize(group, context)
        }
        activity_create_context = {
            'model': model,
            'user': user,
            'defer_commit': True,
            'ignore_auth': True,
            'session': session
        }
        _get_action('activity_create')(activity_create_context, activity_dict)
        # TODO: Also create an activity detail recording what exactly changed
        # in the group.

    upload.upload(uploader.get_max_image_size())

    if not context.get('defer_commit'):
        model.repo.commit()

    return model_dictize.group_dictize(group, context)
Example #25
0
    def orgportals_subdashboards_edit(self, org_name, subdashboard=None, data=None, errors=None, error_summary=None):

        if subdashboard:
            subdashboard = subdashboard[1:]

        data_dict = {
            'org_name': org_name,
            'subdashboard_name': subdashboard
        }
        _subdashboard = get_action('orgportals_subdashboards_show')({}, data_dict)

        if _subdashboard is None and len(subdashboard) > 0:
            p.toolkit.abort(404, _('Subdashboard not found.'))

        if _subdashboard is None:
            _subdashboard = {}

        if p.toolkit.request.method == 'POST' and not data:
            data = dict(p.toolkit.request.POST)

            media_items = []
            for k, v in data.items():
                item = {}

                if k.startswith('media_type'):
                    id = k.split('_')[-1]
                    if data['media_type_{}'.format(id)] == 'chart':

                        item['order'] = int(id)
                        item['media_type'] = data['media_type_{}'.format(id)]
                        item['media_size'] = data['media_size_{}'.format(id)]
                        item['chart_resourceview'] = data['chart_resourceview_{}'.format(id)]
                        item['chart_subheader'] = data['chart_subheader_{}'.format(id)]

                        media_items.append(item)
                    elif data['media_type_{}'.format(id)] == 'youtube_video':
                        item['order'] = int(id)
                        item['media_type'] = data['media_type_{}'.format(id)]
                        item['video_source'] = data['video_source_{}'.format(id)]
                        item['video_title'] = data['video_title_{}'.format(id)]
                        item['video_size'] = data['video_size_{}'.format(id)]
                        item['video_title_url'] = data.get('video_title_url_{}'.format(id), item['video_source'])

                        media_items.append(item)
                    elif data['media_type_{}'.format(id)] == 'image':

                        item['order'] = int(id)
                        item['media_type'] = data['media_type_{}'.format(id)]
                        item['image_title'] = data['media_image_title_{}'.format(id)]
                        item['image_size'] = data.get('media_image_size_{}'.format(id), 'single')
                        item['image_title_url'] = data.get('media_image_title_url_{}'.format(id), '')

                        image_url = data['media_image_url_{}'.format(id)]

                        # Upload images for topics
                        if h.uploads_enabled():
                            image_upload = data['media_image_upload_{}'.format(id)]

                            if isinstance(image_upload, cgi.FieldStorage):
                                upload = uploader.get_uploader('portal', image_url)
                                upload.update_data_dict(data, 'media_image_url_{}'.format(id), 'media_image_upload_{}'.format(id), 'image_clear_upload_{}'.format(id))
                                upload.upload(uploader.get_max_image_size())
                                image_url = upload.filename

                        item['image_url'] = image_url
                        media_items.append(item)

            _subdashboard['media'] = json.dumps(media_items)
            _subdashboard['map'] = []
            _subdashboard['map_main_property'] = []

            for k, v in sorted(data.items()):
                if k.startswith('map_main_property'):
                    _subdashboard['map_main_property'].append(v)
                elif k.startswith('map_') and not k.startswith('map_enabled'):
                    _subdashboard['map'].append(v)

            _subdashboard['map'] = ';'.join(_subdashboard['map'])
            _subdashboard['map_main_property'] = ';'.join(_subdashboard['map_main_property'])

            _subdashboard.update(data)
            _subdashboard['org_name'] = org_name
            _subdashboard['subdashboard_name'] = subdashboard

            try:
                junk = p.toolkit.get_action('orgportals_subdashboards_update')(
                    data_dict=_subdashboard
                )
            except p.toolkit.ValidationError, e:
                errors = e.error_dict
                error_summary = e.error_summary
                return self.orgportals_subdashboards_edit(org_name,'/' + subdashboard, data,
                                       errors, error_summary)

            p.toolkit.redirect_to(p.toolkit.url_for('orgportals_subdashboards_index', org_name=org_name))
Example #26
0
def _group_or_org_update(context, data_dict, is_org=False):
    model = context['model']
    user = context['user']
    session = context['session']
    id = _get_or_bust(data_dict, 'id')

    group = model.Group.get(id)
    context["group"] = group
    if group is None:
        raise NotFound('Group was not found.')

    # get the schema
    group_plugin = lib_plugins.lookup_group_plugin(group.type)
    try:
        schema = group_plugin.form_to_db_schema_options({'type':'update',
                                               'api':'api_version' in context,
                                               'context': context})
    except AttributeError:
        schema = group_plugin.form_to_db_schema()

    upload = uploader.Upload('group', group.image_url)
    upload.update_data_dict(data_dict, 'image_url',
                           'image_upload', 'clear_upload')

    if is_org:
        _check_access('organization_update', context, data_dict)
    else:
        _check_access('group_update', context, data_dict)

    if 'api_version' not in context:
        # old plugins do not support passing the schema so we need
        # to ensure they still work
        try:
            group_plugin.check_data_dict(data_dict, schema)
        except TypeError:
            group_plugin.check_data_dict(data_dict)

    data, errors = lib_plugins.plugin_validate(
        group_plugin, context, data_dict, schema,
        'organization_update' if is_org else 'group_update')
    log.debug('group_update validate_errs=%r user=%s group=%s data_dict=%r',
              errors, context.get('user'),
              context.get('group').name if context.get('group') else '',
              data_dict)

    if errors:
        session.rollback()
        raise ValidationError(errors)

    rev = model.repo.new_revision()
    rev.author = user

    if 'message' in context:
        rev.message = context['message']
    else:
        rev.message = _(u'REST API: Update object %s') % data.get("name")

    # when editing an org we do not want to update the packages if using the
    # new templates.
    if ((not is_org)
            and not converters.asbool(
                config.get('ckan.legacy_templates', False))
            and 'api_version' not in context):
        context['prevent_packages_update'] = True
    group = model_save.group_dict_save(data, context)

    if is_org:
        plugin_type = plugins.IOrganizationController
    else:
        plugin_type = plugins.IGroupController

    for item in plugins.PluginImplementations(plugin_type):
        item.edit(group)

    if is_org:
        activity_type = 'changed organization'
    else:
        activity_type = 'changed group'

    activity_dict = {
            'user_id': model.User.by_name(user.decode('utf8')).id,
            'object_id': group.id,
            'activity_type': activity_type,
            }
    # Handle 'deleted' groups.
    # When the user marks a group as deleted this comes through here as
    # a 'changed' group activity. We detect this and change it to a 'deleted'
    # activity.
    if group.state == u'deleted':
        if session.query(ckan.model.Activity).filter_by(
                object_id=group.id, activity_type='deleted').all():
            # A 'deleted group' activity for this group has already been
            # emitted.
            # FIXME: What if the group was deleted and then activated again?
            activity_dict = None
        else:
            # We will emit a 'deleted group' activity.
            activity_dict['activity_type'] = 'deleted group'
    if activity_dict is not None:
        activity_dict['data'] = {
                'group': dictization.table_dictize(group, context)
                }
        activity_create_context = {
            'model': model,
            'user': user,
            'defer_commit': True,
            'ignore_auth': True,
            'session': session
        }
        # DGU checks if activity streams are enabled first, to avoid Auth Audit
        # issue #1421
        if converters.asbool(
                config.get('ckan.activity_streams_enabled', 'true')):
            _get_action('activity_create')(activity_create_context, activity_dict)
        # TODO: Also create an activity detail recording what exactly changed
        # in the group.

    upload.upload(uploader.get_max_image_size())
    if not context.get('defer_commit'):
        model.repo.commit()


    return model_dictize.group_dictize(group, context)
Example #27
0
def _group_or_org_create(context, data_dict, is_org=False):
    model = context['model']
    user = context['user']
    session = context['session']
    data_dict['is_organization'] = is_org

    upload = uploader.Upload('group')
    upload.update_data_dict(data_dict, 'image_url',
                            'image_upload', 'clear_upload')
    # get the schema
    group_type = data_dict.get('type')
    group_plugin = lib_plugins.lookup_group_plugin(group_type)
    try:
        schema = group_plugin.form_to_db_schema_options({
            'type': 'create', 'api': 'api_version' in context,
            'context': context})
    except AttributeError:
        schema = group_plugin.form_to_db_schema()

    if 'api_version' not in context:
        # old plugins do not support passing the schema so we need
        # to ensure they still work
        try:
            group_plugin.check_data_dict(data_dict, schema)
        except TypeError:
            group_plugin.check_data_dict(data_dict)

    data, errors = lib_plugins.plugin_validate(
        group_plugin, context, data_dict, schema,
        'organization_create' if is_org else 'group_create')
    log.debug('group_create validate_errs=%r user=%s group=%s data_dict=%r',
              errors, context.get('user'), data_dict.get('name'), data_dict)

    if errors:
        session.rollback()
        raise ValidationError(errors)

    rev = model.repo.new_revision()
    rev.author = user

    if 'message' in context:
        rev.message = context['message']
    else:
        rev.message = _(u'REST API: Create object %s') % data.get("name")

    group = model_save.group_dict_save(data, context)

    if user:
        admins = [model.User.by_name(user.decode('utf8'))]
    else:
        admins = []
    model.setup_default_user_roles(group, admins)
    # Needed to let extensions know the group id
    session.flush()

    if is_org:
        plugin_type = plugins.IOrganizationController
    else:
        plugin_type = plugins.IGroupController

    for item in plugins.PluginImplementations(plugin_type):
        item.create(group)

    if is_org:
        activity_type = 'new organization'
    else:
        activity_type = 'new group'

    user_id = model.User.by_name(user.decode('utf8')).id

    activity_dict = {
        'user_id': user_id,
        'object_id': group.id,
        'activity_type': activity_type,
    }
    activity_dict['data'] = {
        'group': ckan.lib.dictization.table_dictize(group, context)
    }
    activity_create_context = {
        'model': model,
        'user': user,
        'defer_commit': True,
        'ignore_auth': True,
        'session': session
    }
    logic.get_action('activity_create')(activity_create_context, activity_dict)

    upload.upload(uploader.get_max_image_size())
    if not context.get('defer_commit'):
        model.repo.commit()
    context["group"] = group
    context["id"] = group.id

    # creator of group/org becomes an admin
    # this needs to be after the repo.commit or else revisions break
    member_dict = {
        'id': group.id,
        'object': user_id,
        'object_type': 'user',
        'capacity': 'admin',
    }
    member_create_context = {
        'model': model,
        'user': user,
        'ignore_auth': True,  # we are not a member of the group at this point
        'session': session
    }
    logic.get_action('member_create')(member_create_context, member_dict)

    log.debug('Created object %s' % group.name)
    return model_dictize.group_dictize(group, context)
Example #28
0
def user_update(context, data_dict):
    '''Update a user account.

    Normal users can only update their own user accounts. Sysadmins can update
    any user account. Can not modify exisiting user's name.

    .. note:: Update methods may delete parameters not explicitly provided in the
        data_dict. If you want to edit only a specific attribute use `user_patch`
        instead.

    For further parameters see
    :py:func:`~ckan.logic.action.create.user_create`.

    :param id: the name or id of the user to update
    :type id: string

    :returns: the updated user account
    :rtype: dictionary

    '''
    model = context['model']
    user = author = context['user']
    session = context['session']
    schema = context.get('schema') or schema_.default_update_user_schema()
    id = _get_or_bust(data_dict, 'id')

    user_obj = model.User.get(id)
    context['user_obj'] = user_obj
    if user_obj is None:
        raise NotFound('User was not found.')

    _check_access('user_update', context, data_dict)

    upload = uploader.get_uploader('user')
    upload.update_data_dict(data_dict, 'image_url',
                            'image_upload', 'clear_upload')

    data, errors = _validate(data_dict, schema, context)
    if errors:
        session.rollback()
        raise ValidationError(errors)

    # user schema prevents non-sysadmins from providing password_hash
    if 'password_hash' in data:
        data['_password'] = data.pop('password_hash')

    user = model_save.user_dict_save(data, context)

    activity_dict = {
            'user_id': user.id,
            'object_id': user.id,
            'activity_type': 'changed user',
            }
    activity_create_context = {
        'model': model,
        'user': author,
        'defer_commit': True,
        'ignore_auth': True,
        'session': session
    }
    _get_action('activity_create')(activity_create_context, activity_dict)
    # TODO: Also create an activity detail recording what exactly changed in
    # the user.

    upload.upload(uploader.get_max_image_size())

    if not context.get('defer_commit'):
        model.repo.commit()

    author_obj = model.User.get(context.get('user'))
    include_plugin_extras = False
    if author_obj:
        include_plugin_extras = author_obj.sysadmin and 'plugin_extras' in data
    user_dict = model_dictize.user_dictize(
        user, context, include_plugin_extras=include_plugin_extras)

    return user_dict
Example #29
0
def hdx_group_or_org_create(context, data_dict, is_org=False):
    # Overriding default so that orgs can have multiple images

    model = context['model']
    user = context['user']
    session = context['session']
    data_dict['is_organization'] = is_org

    if is_org:
        check_access('organization_create', context, data_dict)
    else:
        check_access('group_create', context, data_dict)

    # get the schema
    group_type = data_dict.get('type')
    group_plugin = lib_plugins.lookup_group_plugin(group_type)
    try:
        schema = group_plugin.form_to_db_schema_options({
            'type': 'create', 'api': 'api_version' in context,
            'context': context})
    except AttributeError:
        schema = group_plugin.form_to_db_schema()

    # try:
    #     customization = json.loads(group.extras['customization'])
    # except:
    customization = {'image_sq': '', 'image_rect': ''}

    try:
        data_dict['customization'] = json.loads(data_dict['customization'])
    except:
        data_dict['customization'] = {}

    if 'image_sq_upload' in data_dict and data_dict['image_sq_upload'] != '' and data_dict['image_sq_upload'] != None:
        # If old image was uploaded remove it
        if customization['image_sq']:
            remove_image(customization['image_sq'])

        upload1 = uploader.Upload('group', customization['image_sq'])
        upload1.update_data_dict(data_dict, 'image_sq',
                                 'image_sq_upload', 'clear_upload')

    if 'image_rect_upload' in data_dict and data_dict['image_rect_upload'] != '' and data_dict[
        'image_rect_upload'] != None:
        if customization['image_rect']:
            remove_image(customization['image_rect'])
        upload2 = uploader.Upload('group', customization['image_rect'])
        upload2.update_data_dict(data_dict, 'image_rect',
                                 'image_rect_upload', 'clear_upload')

    storage_path = uploader.get_storage_path()
    ##Rearrange things the way we need them
    try:
        if data_dict['image_sq'] != '' and data_dict['image_sq'] != None:
            data_dict['customization']['image_sq'] = data_dict['image_sq']
        else:
            data_dict['customization']['image_sq'] = customization['image_sq']
    except KeyError:
        data_dict['customization']['image_sq'] = ''

    try:
        if data_dict['image_rect'] != '' and data_dict['image_rect'] != None:
            data_dict['customization']['image_rect'] = data_dict['image_rect']
        else:
            data_dict['customization']['image_rect'] = customization['image_rect']
    except KeyError:
        data_dict['customization']['image_rect'] = ''

    data_dict['customization'] = json.dumps(data_dict['customization'])

    if 'api_version' not in context:
        # old plugins do not support passing the schema so we need
        # to ensure they still work
        try:
            group_plugin.check_data_dict(data_dict, schema)
        except TypeError:
            group_plugin.check_data_dict(data_dict)

    data, errors = lib_plugins.plugin_validate(
        group_plugin, context, data_dict, schema,
        'organization_create' if is_org else 'group_create')
    log.debug('group_create validate_errs=%r user=%s group=%s data_dict=%r',
              errors, context.get('user'), data_dict.get('name'), data_dict)

    if errors:
        session.rollback()
        raise ValidationError(errors)

    rev = model.repo.new_revision()
    rev.author = user

    if 'message' in context:
        rev.message = context['message']
    else:
        rev.message = _(u'REST API: Create object %s') % data.get("name")

    group = model_save.group_dict_save(data, context)

    # Needed to let extensions know the group id
    session.flush()

    if is_org:
        plugin_type = plugins.IOrganizationController
    else:
        plugin_type = plugins.IGroupController

    for item in plugins.PluginImplementations(plugin_type):
        item.create(group)

    if is_org:
        activity_type = 'new organization'
    else:
        activity_type = 'new group'

    user_id = model.User.by_name(user.decode('utf8')).id

    activity_dict = {
        'user_id': user_id,
        'object_id': group.id,
        'activity_type': activity_type,
    }
    activity_dict['data'] = {
        'group': ckan.lib.dictization.table_dictize(group, context)
    }
    activity_create_context = {
        'model': model,
        'user': user,
        'defer_commit': True,
        'ignore_auth': True,
        'session': session
    }
    logic.get_action('activity_create')(activity_create_context, activity_dict)

    try:
        upload1.upload(uploader.get_max_image_size())
    except:
        pass

    try:
        upload2.upload(uploader.get_max_image_size())
    except:
        pass

    if not context.get('defer_commit'):
        model.repo.commit()
    context["group"] = group
    context["id"] = group.id

    # creator of group/org becomes an admin
    # this needs to be after the repo.commit or else revisions break
    member_dict = {
        'id': group.id,
        'object': user_id,
        'object_type': 'user',
        'capacity': 'admin',
    }
    member_create_context = {
        'model': model,
        'user': user,
        'ignore_auth': True,  # we are not a member of the group at this point
        'session': session
    }
    logic.get_action('member_create')(member_create_context, member_dict)

    log.debug('Created object %s' % group.name)
    return model_dictize.group_dictize(group, context)
Example #30
0
def hdx_group_or_org_update(context, data_dict, is_org=False):
    # Overriding default so that orgs can have multiple images
    model = context['model']
    user = context['user']
    session = context['session']
    id = _get_or_bust(data_dict, 'id')

    group = model.Group.get(id)
    context["group"] = group
    if group is None:
        raise NotFound('Group was not found.')

    if is_org:
        check_access('organization_update', context, data_dict)
    else:
        check_access('group_update', context, data_dict)

    # get the schema
    group_plugin = lib_plugins.lookup_group_plugin(group.type)
    try:
        schema = group_plugin.form_to_db_schema_options({'type': 'update',
                                                         'api': 'api_version' in context,
                                                         'context': context})
    except AttributeError:
        schema = group_plugin.form_to_db_schema()

    try:
        customization = json.loads(group.extras['customization'])
    except:
        customization = {'image_sq': '', 'image_rect': ''}

    try:
        data_dict['customization'] = json.loads(data_dict['customization'])
    except:
        data_dict['customization'] = {}

    # If we're removing the image
    if 'clear_image_sq' in data_dict and data_dict['clear_image_sq']:
        remove_image(customization['image_sq'])
        data_dict['customization']['image_sq'] = ''
        customization['image_rect'] = ''

    if 'clear_image_rect' in data_dict and data_dict['clear_image_rect']:
        remove_image(customization['image_rect'])
        data_dict['customization']['image_rect'] = ''
        customization['image_rect'] = ''

    if 'image_sq_upload' in data_dict and data_dict['image_sq_upload'] != '' and data_dict['image_sq_upload'] != None:
        # Although weird, the FieldStorage instance has a boolean value of False so we need to compare to None

        # If old image was uploaded remove it
        if customization['image_sq']:
            remove_image(customization['image_sq'])

        upload1 = uploader.Upload('group', customization['image_sq'])
        upload1.update_data_dict(data_dict, 'image_sq',
                                 'image_sq_upload', 'clear_upload')

    if 'image_rect_upload' in data_dict and data_dict['image_rect_upload'] != '' \
            and data_dict['image_rect_upload'] != None:
        # Although weird, the FieldStorage instance has a boolean value of False so we need to compare to None

        if customization['image_rect']:
            remove_image(customization['image_rect'])
        upload2 = uploader.Upload('group', customization['image_rect'])
        upload2.update_data_dict(data_dict, 'image_rect',
                                 'image_rect_upload', 'clear_upload')

    storage_path = uploader.get_storage_path()
    ##Rearrange things the way we need them
    try:
        if data_dict['image_sq'] != '' and data_dict['image_sq'] != None:
            data_dict['customization']['image_sq'] = data_dict['image_sq']
        else:
            data_dict['customization']['image_sq'] = customization['image_sq']
    except KeyError:
        data_dict['customization']['image_sq'] = ''

    try:
        if data_dict['image_rect'] != '' and data_dict['image_rect'] != None:
            data_dict['customization']['image_rect'] = data_dict['image_rect']
        else:
            data_dict['customization']['image_rect'] = customization['image_rect']
    except KeyError:
        data_dict['customization']['image_rect'] = ''

    data_dict['customization'] = json.dumps(data_dict['customization'])

    if 'api_version' not in context:
        # old plugins do not support passing the schema so we need
        # to ensure they still work
        try:
            group_plugin.check_data_dict(data_dict, schema)
        except TypeError:
            group_plugin.check_data_dict(data_dict)

    data, errors = _validate(data_dict, schema, context)
    log.debug('group_update validate_errs=%r user=%s group=%s data_dict=%r',
              errors, context.get('user'),
              context.get('group').name if context.get('group') else '',
              data_dict)

    if errors:
        session.rollback()
        raise ValidationError(errors)

    rev = model.repo.new_revision()
    rev.author = user

    if 'message' in context:
        rev.message = context['message']
    else:
        rev.message = _(u'REST API: Update object %s') % data.get("name")

    # when editing an org we do not want to update the packages if using the
    # new templates.
    if ((not is_org)
        and not converters.asbool(
            config.get('ckan.legacy_templates', False))
        and 'api_version' not in context):
        context['prevent_packages_update'] = True
    group = model_save.group_dict_save(data, context)

    if is_org:
        plugin_type = plugins.IOrganizationController
    else:
        plugin_type = plugins.IGroupController

    for item in plugins.PluginImplementations(plugin_type):
        item.edit(group)

    if is_org:
        activity_type = 'changed organization'
    else:
        activity_type = 'changed group'

    activity_dict = {
        'user_id': model.User.by_name(user.decode('utf8')).id,
        'object_id': group.id,
        'activity_type': activity_type,
    }
    # Handle 'deleted' groups.
    # When the user marks a group as deleted this comes through here as
    # a 'changed' group activity. We detect this and change it to a 'deleted'
    # activity.
    if group.state == u'deleted':
        if session.query(ckan.model.Activity).filter_by(
                object_id=group.id, activity_type='deleted').all():
            # A 'deleted group' activity for this group has already been
            # emitted.
            # FIXME: What if the group was deleted and then activated again?
            activity_dict = None
        else:
            # We will emit a 'deleted group' activity.
            activity_dict['activity_type'] = 'deleted group'
    if activity_dict is not None:
        activity_dict['data'] = {
            'group': dictization.table_dictize(group, context)
        }
        activity_create_context = {
            'model': model,
            'user': user,
            'defer_commit': True,
            'ignore_auth': True,
            'session': session
        }
        get_action('activity_create')(activity_create_context, activity_dict)
        # TODO: Also create an activity detail recording what exactly changed
        # in the group.

    try:
        upload1.upload(uploader.get_max_image_size())
    except:
        pass

    try:
        upload2.upload(uploader.get_max_image_size())
    except:
        pass

    if not context.get('defer_commit'):
        model.repo.commit()

    return model_dictize.group_dictize(group, context)
Example #31
0
def action_user_update(context, data_dict):
    ''' Modified from CKAN: user_update

    Update a user account.

    Normal users can only update their own user accounts. Sysadmins can update
    any user account.

    For further parameters see ``user_create()``.

    :param id: the name or id of the user to update
    :type id: string

    :returns: the updated user account
    :rtype: dictionary

    '''
    model = context['model']
    user = context['user']
    session = context['session']
    schema = context.get('schema') or logic.schema.default_update_user_schema()
    # Modify the schema by adding translation related keys
    add_translation_modify_schema(schema)

    upload = uploader.Upload('user')
    upload.update_data_dict(data_dict, 'image_url', 'image_upload',
                            'clear_upload')

    ignore_missing = toolkit.get_validator('ignore_missing')
    convert_to_extras = toolkit.get_converter('convert_to_extras')

    schema['job_title'] = [ignore_missing, unicode, convert_to_extras]
    schema['telephone_number'] = [ignore_missing, unicode, convert_to_extras]
    schema['main_organization'] = [ignore_missing, unicode, convert_to_extras]

    schema['image_url'] = [ignore_missing, unicode, convert_to_extras]

    schema['linkedin'] = [ignore_missing, unicode, convert_to_extras]
    schema['facebook'] = [ignore_missing, unicode, convert_to_extras]
    schema['twitter'] = [ignore_missing, unicode, convert_to_extras]

    schema['blog'] = [ignore_missing, to_list_json, convert_to_extras]
    schema['www_page'] = [ignore_missing, to_list_json, convert_to_extras]

    # Add the localized keys for the localized fields to the schema
    schema = add_languages_modify(schema, _localized_fields)

    not_empty = toolkit.get_validator('not_empty')
    schema['fullname'] = [not_empty, unicode]

    id = logic.get_or_bust(data_dict, 'id')

    user_obj = model.User.get(id)
    context['user_obj'] = user_obj
    if user_obj is None:
        raise NotFound('User was not found.')

    # If the translations are not in the data_dict, the user has not added any translations or the user has deleted all translations.
    # Therefore, the translations are not sent with the POST so we need to empty and update the translations here.
    if 'translations' not in data_dict:
        data_dict['translations'] = []

    toolkit.check_access('user_update', context, data_dict)

    data, errors = validate(data_dict, schema, context)
    if errors:
        session.rollback()
        raise ValidationError(errors)

    for extra in data['extras'] if 'extras' in data else []:
        user_obj.extras[extra['key']] = extra['value']

    user = model_save.user_dict_save(data, context)

    activity_dict = {
        'user_id': user.id,
        'object_id': user.id,
        'activity_type': 'changed user'
    }

    activity_create_context = {
        'model': model,
        'user': user,
        'defer_commit': True,
        'ignore_auth': True,
        'session': session
    }

    toolkit.get_action('activity_create')(activity_create_context,
                                          activity_dict)

    # Attempt to update drupal user
    _update_drupal_user(context, data_dict)

    # TODO: Also create an activity detail recording what exactly changed in
    # the user.

    upload.upload(uploader.get_max_image_size())
    if not context.get('defer_commit'):
        model.repo.commit()
    user_data = user_dictize(user, context)

    for key, value in user.extras.iteritems():
        if key in user_data:
            log.warning(
                "Trying to override user data with extra variable '%s'", key)
            continue
        user_data[key] = value
    return user_data
Example #32
0
def _group_or_org_create(context, data_dict, is_org=False):
    model = context["model"]
    user = context["user"]
    session = context["session"]
    data_dict["is_organization"] = is_org

    upload = uploader.Upload("group")
    upload.update_data_dict(data_dict, "image_url", "image_upload", "clear_upload")
    # get the schema
    group_type = data_dict.get("type")
    group_plugin = lib_plugins.lookup_group_plugin(group_type)
    try:
        schema = group_plugin.form_to_db_schema_options(
            {"type": "create", "api": "api_version" in context, "context": context}
        )
    except AttributeError:
        schema = group_plugin.form_to_db_schema()

    if "api_version" not in context:
        # old plugins do not support passing the schema so we need
        # to ensure they still work
        try:
            group_plugin.check_data_dict(data_dict, schema)
        except TypeError:
            group_plugin.check_data_dict(data_dict)

    data, errors = lib_plugins.plugin_validate(
        group_plugin, context, data_dict, schema, "organization_create" if is_org else "group_create"
    )
    log.debug(
        "group_create validate_errs=%r user=%s group=%s data_dict=%r",
        errors,
        context.get("user"),
        data_dict.get("name"),
        data_dict,
    )

    if errors:
        session.rollback()
        raise ValidationError(errors)

    rev = model.repo.new_revision()
    rev.author = user

    if "message" in context:
        rev.message = context["message"]
    else:
        rev.message = _(u"REST API: Create object %s") % data.get("name")

    group = model_save.group_dict_save(data, context)

    if user:
        admins = [model.User.by_name(user.decode("utf8"))]
    else:
        admins = []
    model.setup_default_user_roles(group, admins)
    # Needed to let extensions know the group id
    session.flush()

    if is_org:
        plugin_type = plugins.IOrganizationController
    else:
        plugin_type = plugins.IGroupController

    for item in plugins.PluginImplementations(plugin_type):
        item.create(group)

    if is_org:
        activity_type = "new organization"
    else:
        activity_type = "new group"

    user_id = model.User.by_name(user.decode("utf8")).id

    activity_dict = {"user_id": user_id, "object_id": group.id, "activity_type": activity_type}
    activity_dict["data"] = {"group": ckan.lib.dictization.table_dictize(group, context)}
    activity_create_context = {
        "model": model,
        "user": user,
        "defer_commit": True,
        "ignore_auth": True,
        "session": session,
    }
    logic.get_action("activity_create")(activity_create_context, activity_dict)

    upload.upload(uploader.get_max_image_size())
    if not context.get("defer_commit"):
        model.repo.commit()
    context["group"] = group
    context["id"] = group.id

    # creator of group/org becomes an admin
    # this needs to be after the repo.commit or else revisions break
    member_dict = {"id": group.id, "object": user_id, "object_type": "user", "capacity": "admin"}
    member_create_context = {
        "model": model,
        "user": user,
        "ignore_auth": True,  # we are not a member of the group at this point
        "session": session,
    }
    logic.get_action("member_create")(member_create_context, member_dict)

    log.debug("Created object %s" % group.name)
    return model_dictize.group_dictize(group, context)
Example #33
0
def config_option_update(context, data_dict):
    '''

    .. versionadded:: 2.4

    Allows to modify some CKAN runtime-editable config options

    It takes arbitrary key, value pairs and checks the keys against the
    config options update schema. If some of the provided keys are not present
    in the schema a :py:class:`~ckan.plugins.logic.ValidationError` is raised.
    The values are then validated against the schema, and if validation is
    passed, for each key, value config option:

    * It is stored on the ``system_info`` database table
    * The Pylons ``config`` object is updated.
    * The ``app_globals`` (``g``) object is updated (this only happens for
      options explicitly defined in the ``app_globals`` module.

    The following lists a ``key`` parameter, but this should be replaced by
    whichever config options want to be updated, eg::

        get_action('config_option_update)({}, {
            'ckan.site_title': 'My Open Data site',
            'ckan.homepage_layout': 2,
        })

    :param key: a configuration option key (eg ``ckan.site_title``). It must
        be present on the ``update_configuration_schema``
    :type key: string

    :returns: a dictionary with the options set
    :rtype: dictionary

    .. note:: You can see all available runtime-editable configuration options
        calling
        the :py:func:`~ckan.logic.action.get.config_option_list` action

    .. note:: Extensions can modify which configuration options are
        runtime-editable.
        For details, check :doc:`/extensions/remote-config-update`.

    .. warning:: You should only add config options that you are comfortable
        they can be edited during runtime, such as ones you've added in your
        own extension, or have reviewed the use of in core CKAN.

    '''
    model = context['model']

    _check_access('config_option_update', context, data_dict)

    schema = schema_.update_configuration_schema()

    available_options = schema.keys()

    provided_options = data_dict.keys()

    unsupported_options = set(provided_options) - set(available_options)
    if unsupported_options:
        msg = 'Configuration option(s) \'{0}\' can not be updated'.format(
              ' '.join(list(unsupported_options)))

        raise ValidationError(msg, error_summary={'message': msg})

    upload = uploader.get_uploader('admin')
    upload.update_data_dict(data_dict, 'ckan.site_logo',
                            'logo_upload', 'clear_logo_upload')
    upload.upload(uploader.get_max_image_size())
    data, errors = _validate(data_dict, schema, context)
    if errors:
        model.Session.rollback()
        raise ValidationError(errors)

    for key, value in data.iteritems():

        # Set full Logo url
        if key == 'ckan.site_logo' and value and not value.startswith('http')\
                and not value.startswith('/'):
            image_path = 'uploads/admin/'

            value = h.url_for_static('{0}{1}'.format(image_path, value))

        # Save value in database
        model.set_system_info(key, value)

        # Update CKAN's `config` object
        config[key] = value

        # Only add it to the app_globals (`g`) object if explicitly defined
        # there
        globals_keys = app_globals.app_globals_from_config_details.keys()
        if key in globals_keys:
            app_globals.set_app_global(key, value)

    # Update the config update timestamp
    model.set_system_info('ckan.config_update', str(time.time()))

    log.info('Updated config options: {0}'.format(data))

    return data
Example #34
0
def _group_or_org_create(context, data_dict, is_org=False):
    model = context['model']
    user = context['user']
    session = context['session']
    data_dict['is_organization'] = is_org

    upload = uploader.Upload('group')
    upload.update_data_dict(data_dict, 'image_url', 'image_upload',
                            'clear_upload')
    # get the schema
    group_plugin = lib_plugins.lookup_group_plugin(
        group_type=data_dict.get('type'))
    try:
        schema = group_plugin.form_to_db_schema_options({
            'type':
            'create',
            'api':
            'api_version' in context,
            'context':
            context
        })
    except AttributeError:
        schema = group_plugin.form_to_db_schema()

    if 'api_version' not in context:
        # old plugins do not support passing the schema so we need
        # to ensure they still work
        try:
            group_plugin.check_data_dict(data_dict, schema)
        except TypeError:
            group_plugin.check_data_dict(data_dict)

    data, errors = _validate(data_dict, schema, context)
    log.debug('group_create validate_errs=%r user=%s group=%s data_dict=%r',
              errors, context.get('user'), data_dict.get('name'), data_dict)

    if errors:
        session.rollback()
        raise ValidationError(errors)

    rev = model.repo.new_revision()
    rev.author = user

    if 'message' in context:
        rev.message = context['message']
    else:
        rev.message = _(u'REST API: Create object %s') % data.get("name")

    group = model_save.group_dict_save(data, context)

    if user:
        admins = [model.User.by_name(user.decode('utf8'))]
    else:
        admins = []
    model.setup_default_user_roles(group, admins)
    # Needed to let extensions know the group id
    session.flush()

    if is_org:
        plugin_type = plugins.IOrganizationController
    else:
        plugin_type = plugins.IGroupController

    for item in plugins.PluginImplementations(plugin_type):
        item.create(group)

    if is_org:
        activity_type = 'new organization'
    else:
        activity_type = 'new group'

    user_id = model.User.by_name(user.decode('utf8')).id

    activity_dict = {
        'user_id': user_id,
        'object_id': group.id,
        'activity_type': activity_type,
    }
    activity_dict['data'] = {
        'group': ckan.lib.dictization.table_dictize(group, context)
    }
    activity_create_context = {
        'model': model,
        'user': user,
        'defer_commit': True,
        'ignore_auth': True,
        'session': session
    }
    logic.get_action('activity_create')(activity_create_context, activity_dict)

    upload.upload(uploader.get_max_image_size())
    if not context.get('defer_commit'):
        model.repo.commit()
    context["group"] = group
    context["id"] = group.id

    # creator of group/org becomes an admin
    # this needs to be after the repo.commit or else revisions break
    member_dict = {
        'id': group.id,
        'object': user_id,
        'object_type': 'user',
        'capacity': 'admin',
    }
    member_create_context = {
        'model': model,
        'user': user,
        'ignore_auth': True,  # we are not a member of the group at this point
        'session': session
    }
    logic.get_action('member_create')(member_create_context, member_dict)

    log.debug('Created object %s' % group.name)
    return model_dictize.group_dictize(group, context)
Example #35
0
def _group_or_org_update(context, data_dict, is_org=False):
    model = context["model"]
    user = context["user"]
    session = context["session"]
    id = _get_or_bust(data_dict, "id")

    group = model.Group.get(id)
    context["group"] = group
    if group is None:
        raise NotFound("Group was not found.")

    data_dict["type"] = group.type

    # get the schema
    group_plugin = lib_plugins.lookup_group_plugin(group.type)
    try:
        schema = group_plugin.form_to_db_schema_options(
            {"type": "update", "api": "api_version" in context, "context": context}
        )
    except AttributeError:
        schema = group_plugin.form_to_db_schema()

    upload = uploader.get_uploader("group", group.image_url)
    upload.update_data_dict(data_dict, "image_url", "image_upload", "clear_upload")

    if is_org:
        _check_access("organization_update", context, data_dict)
    else:
        _check_access("group_update", context, data_dict)

    if "api_version" not in context:
        # old plugins do not support passing the schema so we need
        # to ensure they still work
        try:
            group_plugin.check_data_dict(data_dict, schema)
        except TypeError:
            group_plugin.check_data_dict(data_dict)

    data, errors = lib_plugins.plugin_validate(
        group_plugin, context, data_dict, schema, "organization_update" if is_org else "group_update"
    )
    log.debug(
        "group_update validate_errs=%r user=%s group=%s data_dict=%r",
        errors,
        context.get("user"),
        context.get("group").name if context.get("group") else "",
        data_dict,
    )

    if errors:
        session.rollback()
        raise ValidationError(errors)

    rev = model.repo.new_revision()
    rev.author = user

    if "message" in context:
        rev.message = context["message"]
    else:
        rev.message = _(u"REST API: Update object %s") % data.get("name")

    group = model_save.group_dict_save(data, context, prevent_packages_update=is_org)

    if is_org:
        plugin_type = plugins.IOrganizationController
    else:
        plugin_type = plugins.IGroupController

    for item in plugins.PluginImplementations(plugin_type):
        item.edit(group)

    if is_org:
        activity_type = "changed organization"
    else:
        activity_type = "changed group"

    activity_dict = {
        "user_id": model.User.by_name(user.decode("utf8")).id,
        "object_id": group.id,
        "activity_type": activity_type,
    }
    # Handle 'deleted' groups.
    # When the user marks a group as deleted this comes through here as
    # a 'changed' group activity. We detect this and change it to a 'deleted'
    # activity.
    if group.state == u"deleted":
        if session.query(ckan.model.Activity).filter_by(object_id=group.id, activity_type="deleted").all():
            # A 'deleted group' activity for this group has already been
            # emitted.
            # FIXME: What if the group was deleted and then activated again?
            activity_dict = None
        else:
            # We will emit a 'deleted group' activity.
            activity_dict["activity_type"] = "deleted group"
    if activity_dict is not None:
        activity_dict["data"] = {"group": dictization.table_dictize(group, context)}
        activity_create_context = {
            "model": model,
            "user": user,
            "defer_commit": True,
            "ignore_auth": True,
            "session": session,
        }
        _get_action("activity_create")(activity_create_context, activity_dict)
        # TODO: Also create an activity detail recording what exactly changed
        # in the group.

    upload.upload(uploader.get_max_image_size())

    if not context.get("defer_commit"):
        model.repo.commit()

    return model_dictize.group_dictize(group, context)
Example #36
0
def _group_or_org_update(
        context: Context, data_dict: DataDict, is_org: bool = False):
    model = context['model']
    session = context['session']
    id = _get_or_bust(data_dict, 'id')

    group = model.Group.get(id)
    if group is None:
        raise NotFound('Group was not found.')
    context["group"] = group

    data_dict['type'] = group.type

    # get the schema
    group_plugin = lib_plugins.lookup_group_plugin(group.type)
    try:
        schema = group_plugin.form_to_db_schema_options({'type': 'update',
                                               'api': 'api_version' in context,
                                               'context': context})
    except AttributeError:
        schema = group_plugin.form_to_db_schema()

    upload = uploader.get_uploader('group')
    upload.update_data_dict(data_dict, 'image_url',
                            'image_upload', 'clear_upload')

    if is_org:
        _check_access('organization_update', context, data_dict)
    else:
        _check_access('group_update', context, data_dict)

    if 'api_version' not in context:
        # old plugins do not support passing the schema so we need
        # to ensure they still work
        try:
            group_plugin.check_data_dict(data_dict, schema)
        except TypeError:
            group_plugin.check_data_dict(data_dict)

    data, errors = lib_plugins.plugin_validate(
        group_plugin, context, data_dict, schema,
        'organization_update' if is_org else 'group_update')

    group = context.get('group')
    log.debug('group_update validate_errs=%r user=%s group=%s data_dict=%r',
              errors, context.get('user'), group.name if group else '',
              data_dict)

    if errors:
        session.rollback()
        raise ValidationError(errors)

    contains_packages = 'packages' in data_dict

    group = model_save.group_dict_save(
        data, context,
        prevent_packages_update=is_org or not contains_packages
    )

    if is_org:
        plugin_type = plugins.IOrganizationController
    else:
        plugin_type = plugins.IGroupController

    for item in plugins.PluginImplementations(plugin_type):
        item.edit(group)

    upload.upload(uploader.get_max_image_size())

    if not context.get('defer_commit'):
        model.repo.commit()

    return model_dictize.group_dictize(group, context)
Example #37
0
    def orgportals_pages_edit(self, org_name, page=None, data=None, errors=None, error_summary=None):

        if page:
            page = page[1:]
        data_dict = {
            'org_name': org_name,
            'page_name': page
        }
        _page = get_action('orgportals_pages_show')({}, data_dict)

        if _page is None and len(page) > 0:
            p.toolkit.abort(404, _('Page not found.'))

        if _page is None:
            _page = {}

        if p.toolkit.request.method == 'POST' and not data:
            if 'type' not in _page:
                _page['type'] = 'custom'

            data = dict(p.toolkit.request.POST)

            # Upload images for portal pages
            if 'image_upload' in dict(p.toolkit.request.params):
                image_upload =  dict(p.toolkit.request.params)['image_upload']

                if isinstance(image_upload, cgi.FieldStorage):
                    upload = uploader.get_uploader('portal', data['image_url'])
                    upload.update_data_dict(data, 'image_url', 'image_upload', 'clear_upload')
                    upload.upload(uploader.get_max_image_size())
                    image_url = upload.filename
                else:
                    image_url = data['image_url']
            else:
                image_url = None

            if 'type' in _page and _page['type'] == 'data':
                _page['map'] = []
                _page['map_main_property'] = []

                for k, v in sorted(data.items()):
                    if k.startswith('map_main_property'):
                        _page['map_main_property'].append(v)
                    elif k.startswith('map_') and not k.startswith('map_enabled'):
                        _page['map'].append(v)

                _page['map'] = ';'.join(_page['map'])
                _page['map_main_property'] = ';'.join(_page['map_main_property'])

                topics = []

                for k, v in data.items():
                    item = {}

                    if k.startswith('topic_title'):
                        id = k[-1]
                        item['title'] = data['topic_title_{}'.format(id)]
                        item['enabled'] = data['topic_enabled_{}'.format(id)]
                        item['subdashboard'] = data['topic_subdashboard_{}'.format(id)]
                        item['order'] = data['topic_order_{}'.format(id)]

                        image_url = data['topic_image_url_{}'.format(id)]

                        # Upload images for topics
                        if h.uploads_enabled():
                            image_upload = data['topic_image_upload_{}'.format(id)]

                            if isinstance(image_upload, cgi.FieldStorage):
                                upload = uploader.get_uploader('portal', image_url)
                                upload.update_data_dict(data, 'topic_image_url_{}'.format(id), 'topic_image_upload_{}'.format(id), 'topic_clear_upload_{}'.format(id))
                                upload.upload(uploader.get_max_image_size())
                                image_url = upload.filename

                        item['image_url'] = image_url

                        topics.append(item)

                _page['topics'] = json.dumps(topics)

            _page.update(data)
            _page['org_name'] = org_name
            _page['id'] = org_name
            _page['page_name'] = page
            _page['image_url'] = image_url

            try:
                junk = p.toolkit.get_action('orgportals_pages_update')(
                    {'user': p.toolkit.c.user or p.toolkit.c.author},
                    data_dict=_page
                )
            except p.toolkit.ValidationError, e:

                errors = e.error_dict
                error_summary = e.error_summary
                return self.orgportals_pages_edit(org_name,'/' + page, data,
                                       errors, error_summary)
            p.toolkit.redirect_to(p.toolkit.url_for('orgportals_pages_index', org_name=org_name))
Example #38
0
def user_update(context: Context, data_dict: DataDict) -> ActionResult.UserUpdate:
    '''Update a user account.

    Normal users can only update their own user accounts. Sysadmins can update
    any user account. Can not modify exisiting user's name.

    .. note:: Update methods may delete parameters not explicitly provided in the
        data_dict. If you want to edit only a specific attribute use `user_patch`
        instead.

    For further parameters see
    :py:func:`~ckan.logic.action.create.user_create`.

    :param id: the name or id of the user to update
    :type id: string

    :returns: the updated user account
    :rtype: dictionary

    '''
    model = context['model']
    user = context['user']
    session = context['session']
    schema = context.get('schema') or schema_.default_update_user_schema()
    id = _get_or_bust(data_dict, 'id')

    user_obj = model.User.get(id)
    if user_obj is None:
        raise NotFound('User was not found.')
    context['user_obj'] = user_obj

    _check_access('user_update', context, data_dict)

    upload = uploader.get_uploader('user')
    upload.update_data_dict(data_dict, 'image_url',
                            'image_upload', 'clear_upload')

    data, errors = _validate(data_dict, schema, context)
    if errors:
        session.rollback()
        raise ValidationError(errors)

    # user schema prevents non-sysadmins from providing password_hash
    if 'password_hash' in data:
        data['_password'] = data.pop('password_hash')

    user = model_save.user_dict_save(data, context)

    upload.upload(uploader.get_max_image_size())

    if not context.get('defer_commit'):
        with logic.guard_against_duplicated_email(data_dict['email']):
            model.repo.commit()

    author_obj = model.User.get(context.get('user'))
    include_plugin_extras = False
    if author_obj:
        include_plugin_extras = author_obj.sysadmin and 'plugin_extras' in data
    user_dict = model_dictize.user_dictize(
        user, context, include_plugin_extras=include_plugin_extras)

    return user_dict
Example #39
0
def config_option_update(context, data_dict):
    '''

    .. versionadded:: 2.4

    Allows to modify some CKAN runtime-editable config options

    It takes arbitrary key, value pairs and checks the keys against the
    config options update schema. If some of the provided keys are not present
    in the schema a :py:class:`~ckan.plugins.logic.ValidationError` is raised.
    The values are then validated against the schema, and if validation is
    passed, for each key, value config option:

    * It is stored on the ``system_info`` database table
    * The Pylons ``config`` object is updated.
    * The ``app_globals`` (``g``) object is updated (this only happens for
      options explicitly defined in the ``app_globals`` module.

    The following lists a ``key`` parameter, but this should be replaced by
    whichever config options want to be updated, eg::

        get_action('config_option_update)({}, {
            'ckan.site_title': 'My Open Data site',
            'ckan.homepage_layout': 2,
        })

    :param key: a configuration option key (eg ``ckan.site_title``). It must
        be present on the ``update_configuration_schema``
    :type key: string

    :returns: a dictionary with the options set
    :rtype: dictionary

    .. note:: You can see all available runtime-editable configuration options
        calling
        the :py:func:`~ckan.logic.action.get.config_option_list` action

    .. note:: Extensions can modify which configuration options are
        runtime-editable.
        For details, check :doc:`/extensions/remote-config-update`.

    .. warning:: You should only add config options that you are comfortable
        they can be edited during runtime, such as ones you've added in your
        own extension, or have reviewed the use of in core CKAN.

    '''
    model = context['model']

    _check_access('config_option_update', context, data_dict)

    schema = schema_.update_configuration_schema()

    available_options = schema.keys()

    provided_options = data_dict.keys()

    unsupported_options = set(provided_options) - set(available_options)
    if unsupported_options:
        msg = 'Configuration option(s) \'{0}\' can not be updated'.format(
              ' '.join(list(unsupported_options)))

        raise ValidationError(msg, error_summary={'message': msg})

    upload = uploader.get_uploader('admin')
    upload.update_data_dict(data_dict, 'ckan.site_logo',
                            'logo_upload', 'clear_logo_upload')
    upload.upload(uploader.get_max_image_size())
    data, errors = _validate(data_dict, schema, context)
    if errors:
        model.Session.rollback()
        raise ValidationError(errors)

    for key, value in data.iteritems():

        # Set full Logo url
        if key =='ckan.site_logo' and value and not value.startswith('http'):
            value = h.url_for_static('uploads/admin/{0}'.format(value))

        # Save value in database
        model.set_system_info(key, value)

        # Update CKAN's `config` object
        config[key] = value

        # Only add it to the app_globals (`g`) object if explicitly defined
        # there
        globals_keys = app_globals.app_globals_from_config_details.keys()
        if key in globals_keys:
            app_globals.set_app_global(key, value)

    # Update the config update timestamp
    model.set_system_info('ckan.config_update', str(time.time()))

    log.info('Updated config options: {0}'.format(data))

    return data
Example #40
0
def package_update(context, data_dict):
    '''Update a dataset (package).

    You must be authorized to edit the dataset and the groups that it belongs
    to.

    Plugins may change the parameters of this function depending on the value
    of the dataset's ``type`` attribute, see the ``IDatasetForm`` plugin
    interface.

    For further parameters see ``package_create()``.

    :param id: the name or id of the dataset to update
    :type id: string

    :returns: the updated dataset (if 'return_package_dict' is True in the
              context, which is the default. Otherwise returns just the
              dataset id)
    :rtype: dictionary

    '''

    model = context['model']
    user = context['user']
    name_or_id = data_dict.get("id") or data_dict['name']

    pkg = model.Package.get(name_or_id)

    if pkg is None:
        raise NotFound(_('Package was not found.'))
    context["package"] = pkg
    data_dict["id"] = pkg.id

    # FIXME: first modifications to package_updade begin here:
    # tag strings are reconstructed because validators are stripping
    # tags passed and only taking taks as tag_string values
    # image upload support has also been added here
    old_data = get_action('package_show')(context, {'id': pkg.id})
    '''
    Constructing the tag_string from the given tags.
    There must be at least one tag, otherwise the tag_string will be empty and a validation error
    will be raised.
    '''
    if not data_dict.get('tag_string'):
        data_dict['tag_string'] = ', '.join(
            h.dict_list_reduce(data_dict.get('tags', {}), 'name'))

    for key, value in old_data.iteritems():
        if key not in data_dict:
            data_dict[key] = value

    # data_dict['resources'] = data_dict.get('resources', old_data.get('resources'))


#     iso_topic_cat = data_dict.get('iso_topic_string', [])
#     if isinstance(iso_topic_cat, basestring):
#         iso_topic_cat = [iso_topic_cat]
#
#     data_dict['iso_topic_string'] = ','.join(iso_topic_cat)

# Set the package last modified date
    data_dict['record_last_modified'] = str(datetime.date.today())

    # If the Created Date has not yet been set, then set it
    if data_dict['edc_state'] == 'DRAFT' and not data_dict.get(
            'record_create_date'):
        data_dict['record_create_date'] = str(datetime.date.today())

    # If the Publish Date has not yet been set, then set it
    if data_dict['edc_state'] == 'PUBLISHED' and not data_dict.get(
            'record_publish_date'):
        data_dict['record_publish_date'] = str(datetime.date.today())

    # If the Archive Date has not yet been set, then set it
    if data_dict['edc_state'] == 'ARCHIVED' and not data_dict.get(
            'record_archive_date'):
        data_dict['record_archive_date'] = str(datetime.date.today())

    _check_access('package_update', context, data_dict)

    # get the schema
    package_plugin = lib_plugins.lookup_package_plugin(pkg.type)
    if 'schema' in context:
        schema = context['schema']
    else:
        schema = package_plugin.update_package_schema()

    image_url = old_data.get('image_url', None)

    upload = uploader.Upload('edc', image_url)
    upload.update_data_dict(data_dict, 'image_url', 'image_upload',
                            'clear_upload')

    # Adding image display url for the uploaded image
    image_url = data_dict.get('image_url')
    data_dict['image_display_url'] = image_url

    if image_url and not image_url.startswith('http'):
        image_url = munge.munge_filename(image_url)
        data_dict['image_display_url'] = h.url_for_static(
            'uploads/edc/%s' % data_dict.get('image_url'), qualified=True)

    if 'api_version' not in context:
        # check_data_dict() is deprecated. If the package_plugin has a
        # check_data_dict() we'll call it, if it doesn't have the method we'll
        # do nothing.
        check_data_dict = getattr(package_plugin, 'check_data_dict', None)
        if check_data_dict:
            try:
                package_plugin.check_data_dict(data_dict, schema)
            except TypeError:
                # Old plugins do not support passing the schema so we need
                # to ensure they still work.
                package_plugin.check_data_dict(data_dict)
    # FIXME: modifications to package_update end here^

    data, errors = lib_plugins.plugin_validate(package_plugin, context,
                                               data_dict, schema,
                                               'package_update')
    log.debug('package_update validate_errs=%r user=%s package=%s data=%r',
              errors, context.get('user'),
              context.get('package').name if context.get('package') else '',
              data)

    if errors:
        model.Session.rollback()
        raise ValidationError(errors)

    rev = model.repo.new_revision()
    rev.author = user
    if 'message' in context:
        rev.message = context['message']
    else:
        rev.message = _(u'REST API: Update object %s') % data.get("name")

    # avoid revisioning by updating directly
    model.Session.query(model.Package).filter_by(id=pkg.id).update(
        {"metadata_modified": datetime.datetime.utcnow()})
    model.Session.refresh(pkg)

    pkg = model_save.package_dict_save(data, context)

    context_org_update = context.copy()
    context_org_update['ignore_auth'] = True
    context_org_update['defer_commit'] = True
    _get_action('package_owner_org_update')(context_org_update, {
        'id': pkg.id,
        'organization_id': pkg.owner_org
    })

    for item in plugins.PluginImplementations(plugins.IPackageController):
        item.edit(pkg)

        item.after_update(context, data)

    upload.upload(uploader.get_max_image_size())

    # TODO the next two blocks are copied from ckan/ckan/logic/action/update.py
    # This codebase is currently hard to maintain because large chunks of the
    # CKAN action API and the CKAN controllers are simply overriden. This is
    # probably worse than just forking CKAN would have been, because in that
    # case at least we could track changes. - @deniszgonjanin

    # Needed to let extensions know the new resources ids
    model.Session.flush()
    if data.get('resources'):
        for index, resource in enumerate(data['resources']):
            resource['id'] = pkg.resources[index].id

    # Create default views for resources if necessary
    if data.get('resources'):
        logic.get_action('package_create_default_resource_views')(
            {
                'model': context['model'],
                'user': context['user'],
                'ignore_auth': True
            }, {
                'package': data
            })

    if not context.get('defer_commit'):
        model.repo.commit()

    log.debug('Updated object %s' % pkg.name)

    return_id_only = context.get('return_id_only', False)

    # Make sure that a user provided schema is not used on package_show
    context.pop('schema', None)

    # we could update the dataset so we should still be able to read it.
    context['ignore_auth'] = True
    output = data_dict['id'] if return_id_only \
        else _get_action('package_show')(context, {'id': data_dict['id']})
    '''
    Send state change notifications if required; Added by Khalegh Mamakani
    Using a thread to run the job in the background so that package_update will not wait for notifications sending.
    '''

    old_state = old_data.get('edc_state')

    context = {
        'model': model,
        'session': model.Session,
        'user': c.user or c.author,
        'auth_user_obj': c.userobj
    }

    dataset_url = config.get('ckan.site_url') + h.url_for(
        controller='package', action="read", id=data_dict['name'])
    import threading

    notify_thread = threading.Thread(target=check_record_state,
                                     args=(context, old_state, data_dict,
                                           g.site_title, g.site_url,
                                           dataset_url))
    notify_thread.start()

    return output
Example #41
0
File: logic.py Project: haphut/ytp
def action_user_update(context, data_dict):
    ''' Modified from CKAN: user_update

    Update a user account.

    Normal users can only update their own user accounts. Sysadmins can update
    any user account.

    For further parameters see ``user_create()``.

    :param id: the name or id of the user to update
    :type id: string

    :returns: the updated user account
    :rtype: dictionary

    '''
    model = context['model']
    user = context['user']
    session = context['session']
    schema = context.get('schema') or logic.schema.default_update_user_schema()
    # Modify the schema by adding translation related keys
    add_translation_modify_schema(schema)

    upload = uploader.Upload('user')
    upload.update_data_dict(data_dict, 'image_url', 'image_upload', 'clear_upload')

    ignore_missing = toolkit.get_validator('ignore_missing')
    convert_to_extras = toolkit.get_converter('convert_to_extras')

    schema['job_title'] = [ignore_missing, unicode, convert_to_extras]
    schema['telephone_number'] = [ignore_missing, unicode, convert_to_extras]
    schema['main_organization'] = [ignore_missing, unicode, convert_to_extras]

    schema['image_url'] = [ignore_missing, unicode, convert_to_extras]

    schema['linkedin'] = [ignore_missing, unicode, convert_to_extras]
    schema['facebook'] = [ignore_missing, unicode, convert_to_extras]
    schema['twitter'] = [ignore_missing, unicode, convert_to_extras]

    schema['blog'] = [ignore_missing, to_list_json, convert_to_extras]
    schema['www_page'] = [ignore_missing, to_list_json, convert_to_extras]

    # Add the localized keys for the localized fields to the schema
    schema = add_languages_modify(schema, _localized_fields)

    not_empty = toolkit.get_validator('not_empty')
    schema['fullname'] = [not_empty, unicode]

    id = logic.get_or_bust(data_dict, 'id')

    user_obj = model.User.get(id)
    context['user_obj'] = user_obj
    if user_obj is None:
        raise NotFound('User was not found.')

    # If the translations are not in the data_dict, the user has not added any translations or the user has deleted all translations.
    # Therefore, the translations are not sent with the POST so we need to empty and update the translations here.
    if 'translations' not in data_dict:
        data_dict['translations'] = []

    toolkit.check_access('user_update', context, data_dict)

    data, errors = validate(data_dict, schema, context)
    if errors:
        session.rollback()
        raise ValidationError(errors)

    for extra in data['extras'] if 'extras' in data else []:
        user_obj.extras[extra['key']] = extra['value']

    user = model_save.user_dict_save(data, context)

    activity_dict = {'user_id': user.id,
                     'object_id': user.id,
                     'activity_type': 'changed user'}

    activity_create_context = {'model': model,
                               'user': user,
                               'defer_commit': True,
                               'ignore_auth': True,
                               'session': session}

    toolkit.get_action('activity_create')(activity_create_context, activity_dict)

    # Attempt to update drupal user
    _update_drupal_user(context, data_dict)

    # TODO: Also create an activity detail recording what exactly changed in
    # the user.

    upload.upload(uploader.get_max_image_size())
    if not context.get('defer_commit'):
        model.repo.commit()
    user_data = user_dictize(user, context)

    for key, value in user.extras.iteritems():
        if key in user_data:
            log.warning("Trying to override user data with extra variable '%s'", key)
            continue
        user_data[key] = value
    return user_data
Example #42
0
def logic_action_update_package_update(context, data_dict):
    '''Update a dataset (package).

    You must be authorized to edit the dataset and the groups that it belongs
    to.

    It is recommended to call
    :py:func:`ckan.logic.action.get.package_show`, make the desired changes to
    the result, and then call ``package_update()`` with it.

    Plugins may change the parameters of this function depending on the value
    of the dataset's ``type`` attribute, see the
    :py:class:`~ckan.plugins.interfaces.IDatasetForm` plugin interface.

    For further parameters see
    :py:func:`~ckan.logic.action.create.package_create`.

    :param id: the name or id of the dataset to update
    :type id: string

    :returns: the updated dataset (if ``'return_package_dict'`` is ``True`` in
              the context, which is the default. Otherwise returns just the
              dataset id)
    :rtype: dictionary

    '''
    import ckan.lib.plugins as lib_plugins
    import datetime
    import ckan.lib.dictization.model_save as model_save
    import ckan.plugins as plugins
    import ckan.lib.uploader as uploader
    _check_access = ckan.logic.check_access

    model = context['model']
    user = context['user']
    name_or_id = data_dict.get("id") or data_dict['name']

    pkg = model.Package.get(name_or_id)
    if pkg is None:
        raise NotFound(_('Package was not found.'))
    context["package"] = pkg
    data_dict["id"] = pkg.id
    data_dict['type'] = pkg.type

    upload = uploader.Upload('package', '')
    upload.update_data_dict(data_dict, 'image_url', 'image_upload',
                            'clear_upload')

    _check_access('package_update', context, data_dict)

    # get the schema
    package_plugin = lib_plugins.lookup_package_plugin(pkg.type)
    if 'schema' in context:
        schema = context.pop('schema')
    else:
        schema = package_plugin.update_package_schema()

    if 'api_version' not in context:
        # check_data_dict() is deprecated. If the package_plugin has a
        # check_data_dict() we'll call it, if it doesn't have the method we'll
        # do nothing.
        check_data_dict = getattr(package_plugin, 'check_data_dict', None)
        if check_data_dict:
            try:
                package_plugin.check_data_dict(data_dict, schema)
            except TypeError:
                # Old plugins do not support passing the schema so we need
                # to ensure they still work.
                package_plugin.check_data_dict(data_dict)

    data, errors = lib_plugins.plugin_validate(package_plugin, context,
                                               data_dict, schema,
                                               'package_update')
    log.debug('package_update validate_errs=%r user=%s package=%s data=%r',
              errors, context.get('user'),
              context.get('package').name if context.get('package') else '',
              data)

    if errors:
        model.Session.rollback()
        raise ckan.logic.ValidationError(errors)

    rev = model.repo.new_revision()
    rev.author = user
    if 'message' in context:
        rev.message = context['message']
    else:
        rev.message = _(u'REST API: Update object %s') % data.get("name")

    #avoid revisioning by updating directly
    model.Session.query(model.Package).filter_by(id=pkg.id).update(
        {"metadata_modified": datetime.datetime.utcnow()})
    model.Session.refresh(pkg)

    upload.upload(uploader.get_max_image_size())
    generateThumbs(upload.filepath)
    pkg = model_save.package_dict_save(data, context)

    context_org_update = context.copy()
    context_org_update['ignore_auth'] = True
    context_org_update['defer_commit'] = True
    ckan.logic.get_action('package_owner_org_update')(
        context_org_update, {
            'id': pkg.id,
            'organization_id': pkg.owner_org
        })

    # Needed to let extensions know the new resources ids
    model.Session.flush()
    if data.get('resources'):
        for index, resource in enumerate(data['resources']):
            resource['id'] = pkg.resources[index].id

    for item in plugins.PluginImplementations(plugins.IPackageController):
        item.edit(pkg)

        item.after_update(context, data)

    # Create default views for resources if necessary
    if data.get('resources'):
        ckan.logic.get_action('package_create_default_resource_views')(
            {
                'model': context['model'],
                'user': context['user'],
                'ignore_auth': True
            }, {
                'package': data
            })

    if not context.get('defer_commit'):
        model.repo.commit()

    log.debug('Updated object %s' % pkg.name)

    return_id_only = context.get('return_id_only', False)

    # Make sure that a user provided schema is not used on package_show
    context.pop('schema', None)

    # we could update the dataset so we should still be able to read it.
    context['ignore_auth'] = True
    output = data_dict['id'] if return_id_only \
            else ckan.logic.get_action('package_show')(context, {'id': data_dict['id']})

    return output