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
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)]
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
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