Example #1
0
 def download_file(self, object_type, name_or_id, filename=None):
     '''Download file from CKAN's filestore, grouped under `object_type` and
     identified by `name_or_id` inside this group.
     '''
     
     filepath = None
     if object_type == 'resources':
         up = uploader.ResourceUpload(resource={})
         filepath = up.get_path(name_or_id)
         app = fileapp.FileApp(filepath)
     elif object_type == 'source-metadata':
         up = uploader.MetadataUpload()
         filepath = up.get_path(name_or_id)
         app = fileapp.FileApp(filepath)
     elif object_type == 'metadata':
         val = get_cache('metadata').get(name_or_id)
         app = fileapp.DataApp(val, content_type='application/xml; charset=utf-8') 
     else:
         abort(404, 'Unknown object-type')
     
     # Retreive file
     try:
         status, headers, app_it = request.call_application(app)
     except:
         abort(404, 'Not Found')
     response.headers.update(dict(headers))
     response.status = status
     # Dump
     return app_it
Example #2
0
    def upload_file(self, object_type):
        
        name = request.params.get('name', '') # prefix
        upload_name = name + '-upload' if name else 'upload'

        upload = request.params.get(upload_name)
        if not isinstance(upload, cgi.FieldStorage):
            abort(400, 'Expected a file upload')
        
        result = None
        if object_type == 'resources':
            abort(400, 'Cannot handle uploading of resources here')
        elif object_type == 'source-metadata':
            up = uploader.MetadataUpload(upload.filename)
            up.update_data_dict(dict(request.params), upload_name)
            up.upload(max_size=1)
        
            link = toolkit.url_for(
                controller='ckanext.publicamundi.controllers.files:Controller',
                action='download_file', 
                object_type=up.object_type,
                name_or_id=up.filename,
                filename=upload.filename)

            size = os.stat(u.filepath).st_size

            result = dict(name=u.filename, url=link, size=size)
        else:
            abort(404, 'Unknown object-type')

        response.headers['Content-Type'] = 'application/json'
        return [to_json(result)]
Example #3
0
    def _import_metadata(self, post):
        '''Handle a submitted import_metadata form.
        Return a redirection URL.
        '''

        redirect_url = None

        #
        # Read and validate post parameters
        #

        # Note Authorization is enforced by the underlying action.
        owner_org = post.get('owner_org')
        if not owner_org:
            abort(400, 'The owner organization is not given')

        uv = {'group': owner_org}
        uv.update(request.urlvars)
        redirect_url = _url(**uv)

        dtype = post.get('dataset_type')
        if not dtype in ext_metadata.dataset_types:
            abort(400, 'Unknown metadata schema')

        rename_if_conflict = post.get('rename', '') == 'y'
        continue_on_errors = post.get('force_create', '') == 'y'

        # Examine source (an upload or a link)
        # Todo Remember orig_metadata_source (as source_url)

        source_url = None
        source = post.get('source')
        source_upload = post.get('source-upload')

        if source:
            # Assume source is provided as a URL
            source_url = source
        elif isinstance(source_upload, cgi.FieldStorage):
            # Assume source is an uploaded file
            up = uploader.MetadataUpload(source_upload.filename)
            up.update_data_dict(dict(post), 'source-upload')

            try:
                up.upload(max_size=1)
            except Exception as ex:
                log.error('Failed to save uploaded file %r: %s',
                          source_upload.filename, ex.message)
                abort(400, 'Failed to upload file')
            source_url = _url(
                controller='ckanext.publicamundi.controllers.files:Controller',
                action='download_file',
                object_type=up.object_type,
                name_or_id=up.filename,
                filename=source_upload.filename)
            source = source_upload.file
            source.seek(0, 0)
            # Provide a file-like object as source
            #source = source_upload.file
            #log.debug('\n\n source:  %s ,type: %s, up is %s , source url is %s, source_upload is %s  \n\n', source, type(source),up, source_url, source_upload)
            #log.debug('\n source_upload:  %s ,  value is %s\n\n', source_upload, source.getvalue())
            #for attr in dir(source_upload):
            #				       		log.info(" source upload.%s = %r" % (attr, getattr(source_upload, attr)))

            #for attr in dir(source):
            # 	log.info("source.%s = %r" % (attr, getattr(source, attr)))
            #source.seek(0, 0)
        else:
            # No source given
            session['error_summary'] = _(
                'No source specified: Upload or link to an XML file.')
            return redirect_url

        #
        # Invoke dataset_import action
        #

        context = {'model': model, 'session': model.Session, 'api_version': 3}

        data_dict = {
            'source': source,
            'owner_org': owner_org,
            'dtype': dtype,
            'rename_if_conflict': rename_if_conflict,
            'continue_on_errors': continue_on_errors,
        }

        try:
            result = _get_action('dataset_import')(context, data_dict)
        except ext_actions.Invalid as ex:
            log.error('Cannot import package (invalid input): %r' %
                      (ex.error_dict))
            if len(ex.error_dict) > 1:
                session['error_summary'] = _('Received invalid input (%s)' %
                                             (','.join(ex.error_dict.keys())))
                session['errors'] = ex.error_dict
            else:
                session['error_summary'] = next(ex.error_dict.itervalues())
        except (ext_actions.IdentifierConflict,
                ext_actions.NameConflict) as ex:
            log.error('Cannot import package (name/id conflict): %r' %
                      (ex.error_dict))
            session['error_summary'] = ex.error_summary
        except toolkit.ValidationError as ex:
            # The input is valid, but results in an invalid package
            log.error('Cannot import package (metadata are invalid): %r' %
                      (ex.error_dict))
            session['error_summary'] = _('The given metadata are invalid.')
            session['errors'] = ex.error_dict
        except AssertionError as ex:
            raise
        except Exception as ex:
            log.error('Cannot import package (unexpected error): %s' % (ex))
            abort(400, 'Cannot import package')
        else:
            # Success: save result and redirect to success page
            session['result'] = result

        # Done
        return redirect_url
Example #4
0
    def _import_metadata(self, post):
        '''Handle a submitted import_metadata form.
        Return a redirection URL.
        '''

        redirect_url = None

        #
        # Read and validate post parameters
        #

        # Note Authorization is enforced by the underlying action.
        owner_org = post.get('owner_org')
        if not owner_org:
            abort(400, 'The owner organization is not given')

        redirect_url = _url('', group=owner_org)

        dtype = post.get('dataset_type')
        if not dtype in dataset_types:
            abort(400, 'Unknown metadata schema')

        rename_if_conflict = post.get('rename', '') == 'y'
        continue_on_errors = post.get('force_create', '') == 'y'

        # Examine source (an upload or a link)
        # Todo Remember orig_metadata_source (as source_url)

        source_url = None
        source = post.get('source')
        source_upload = post.get('source-upload')
        if source:
            # Assume source is provided as a URL
            source_url = source
        elif isinstance(source_upload, cgi.FieldStorage):
            # Assume source is an uploaded file
            up = uploader.MetadataUpload(source_upload.filename)
            up.update_data_dict(dict(post), 'source-upload')
            try:
                up.upload(max_size=1)
            except Exception as ex:
                log.error('Failed to save uploaded file %r: %s',
                          source_upload.filename, ex.message)
                abort(400, 'Failed to upload file')
            source_url = _url(
                controller='ckanext.publicamundi.controllers.files:Controller',
                action='download_file',
                object_type=up.object_type,
                name_or_id=up.filename,
                filename=source_upload.filename)
            # Provide a file-like object as source
            source = source_upload.file
            source.seek(0, 0)
        else:
            # No source given
            session['error_summary'] = _(
                'No source specified: Upload or link to an XML file.')
            return redirect_url

        #
        # Invoke dataset_import action
        #

        context = {'model': model, 'session': model.Session, 'api_version': 3}

        data_dict = {
            'source': source,
            'owner_org': owner_org,
            'dtype': dtype,
            'rename_if_conflict': rename_if_conflict,
            'continue_on_errors': continue_on_errors,
        }

        try:
            result = _get_action('dataset_import')(context, data_dict)
        except (ext_actions.InvalidParameter, ext_actions.NameConflict) as ex:
            log.error('Cannot import package: %s' % (ex))
            session['error_summary'] = ex.message
        except toolkit.ValidationError as ex:
            # Parameters are valid, but result in an invalid package
            log.error('Cannot import, resulting package is invalid: %s' % (ex))
            session['error_summary'] = _('The given metadata are invalid.')
            session['errors'] = ex.error_dict
        except toolkit.Invalid as ex:
            # Parameters are valid, but source XML file is not parse-able
            log.error('Cannot import package, source is invalid: %s' % (ex))
            session['error_summary'] = ex.error
        except AssertionError as ex:
            # Re-raise failed assertions
            raise
        except Exception as ex:
            log.error('Cannot import package (unexpected error): %s' % (ex))
            abort(400, 'Cannot import package')
        else:
            # Success: save result and redirect to success page
            session['result'] = result

        # Done
        return redirect_url