def _filter_resource_tags(package): """ Returns resource links for a package such that any resource with a unique format returns a link to the resource, and any link with a duplicate format returns a link to the package page. """ res_list = [] all_res = h.dict_list_reduce(package['resources'], 'format', unique=False) uniques = [x for x in all_res if all_res.count(x) == 1] non_uniques = set(all_res) - set(uniques) for resource in package['resources']: if resource['format'] in uniques: res_list.append({ 'format': resource['format'], 'url': h.url_for(controller='package', action='resource_read', id=package['name'], resource_id=resource['id']) }) elif resource['format'] in non_uniques: res_list.append({ 'format': resource['format'], 'url': h.url_for(controller='package', action='read', id=package['name']) }) non_uniques.remove(resource['format']) return res_list
def edit(self, id, data=None, errors=None, error_summary=None): package_type = self._get_package_type(id) context = {'model': model, 'session': model.Session, 'user': c.user, 'auth_user_obj': c.userobj, 'save': 'save' in request.params} if context['save'] and not data: return self._save_edit(id, context, package_type=package_type) try: c.pkg_dict = get_action('package_show')(dict(context, for_view=True), {'id': id}) context['for_edit'] = True old_data = get_action('package_show')(context, {'id': id}) # old data is from the database and data is passed from the # user if there is a validation error. Use users data if there. if data: old_data.update(data) data = old_data except (NotFound, NotAuthorized): abort(404, _('Dataset not found')) # are we doing a multiphase add? if data.get('state', '').startswith('draft'): c.form_action = h.url_for(controller='package', action='new') c.form_style = 'new' return self.new(data=data, errors=errors, error_summary=error_summary) c.pkg = context.get("package") c.resources_json = h.json.dumps(data.get('resources', [])) try: check_access('package_update', context) except NotAuthorized: abort(403, _('User %r not authorized to edit %s') % (c.user, id)) # convert tags if not supplied in data if data and not data.get('tag_string'): data['tag_string'] = ', '.join(h.dict_list_reduce( c.pkg_dict.get('tags', {}), 'name')) errors = errors or {} form_snippet = self._package_form(package_type=package_type) form_vars = {'data': data, 'errors': errors, 'error_summary': error_summary, 'action': 'edit', 'dataset_type': package_type, } c.errors_json = h.json.dumps(errors) self._setup_template_variables(context, {'id': id}, package_type=package_type) # we have already completed stage 1 form_vars['stage'] = ['active'] if data.get('state', '').startswith('draft'): form_vars['stage'] = ['active', 'complete'] edit_template = self._edit_template(package_type) return render(edit_template, extra_vars={'form_vars': form_vars, 'form_snippet': form_snippet, 'dataset_type': package_type})
def dict_list_or_dict_reduce(list_, key, unique=True): """ Hack to make helpers.dict_list_reduce work also if provided a dict of dicts instead of a list of dicts """ if isinstance(list_, dict): list_ = list_.values() res = dict_list_reduce(list_, key, unique) return res
def new(self, data=None, errors=None, error_summary=None): package_type = self._guess_package_type(True) context = {'model': model, 'session': model.Session, 'user': c.user or c.author, 'auth_user_obj': c.userobj, 'save': 'save' in request.params} # Package needs to have a organization group in the call to # check_access and also to save it try: check_access('package_create', context) except NotAuthorized: abort(401, _('Unauthorized to create a package')) if context['save'] and not data: return self._save_new(context, package_type=package_type) data = data or clean_dict(dict_fns.unflatten(tuplize_dict(parse_params( request.params, ignore_keys=CACHE_PARAMETERS)))) c.resources_json = h.json.dumps(data.get('resources', [])) # convert tags if not supplied in data if data and not data.get('tag_string'): data['tag_string'] = ', '.join( h.dict_list_reduce(data.get('tags', {}), 'name')) errors = errors or {} error_summary = error_summary or {} # in the phased add dataset we need to know that # we have already completed stage 1 stage = ['active'] if data.get('state') == 'draft': stage = ['active', 'complete'] elif data.get('state') == 'draft-complete': stage = ['active', 'complete', 'complete'] # if we are creating from a group then this allows the group to be # set automatically data['group_id'] = request.params.get('group') or \ request.params.get('groups__0__id') vars = {'data': data, 'errors': errors, 'error_summary': error_summary, 'action': 'new', 'stage': stage} c.errors_json = h.json.dumps(errors) self._setup_template_variables(context, {}, package_type=package_type) # TODO: This check is to maintain backwards compatibility with the # old way of creating custom forms. This behaviour is now deprecated. if hasattr(self, 'package_form'): c.form = render(self.package_form, extra_vars=vars) else: c.form = render(self._package_form(package_type=package_type), extra_vars=vars) return render(self._new_template(package_type), extra_vars={'stage': stage})
def get(self, package_type, data=None, errors=None, error_summary=None): context = self._prepare(data) if data and u'type' in data: package_type = data[u'type'] data = data or clean_dict( dict_fns.unflatten( tuplize_dict( parse_params(request.args, ignore_keys=CACHE_PARAMETERS)))) resources_json = h.json.dumps(data.get(u'resources', [])) # convert tags if not supplied in data if data and not data.get(u'tag_string'): data[u'tag_string'] = u', '.join( h.dict_list_reduce(data.get(u'tags', {}), u'name')) errors = errors or {} error_summary = error_summary or {} # in the phased add dataset we need to know that # we have already completed stage 1 stage = [u'active'] if data.get(u'state', u'').startswith(u'draft'): stage = [u'active', u'complete'] # if we are creating from a group then this allows the group to be # set automatically data[u'group_id'] = request.args.get(u'group') or request.args.get( u'groups__0__id') form_snippet = _get_pkg_template(u'package_form', package_type=package_type) form_vars = { u'data': data, u'errors': errors, u'error_summary': error_summary, u'action': u'new', u'stage': stage, u'dataset_type': package_type, u'form_style': u'new' } errors_json = h.json.dumps(errors) # TODO: remove g.resources_json = resources_json g.errors_json = errors_json _setup_template_variables(context, {}, package_type=package_type) new_template = _get_pkg_template(u'new_template', package_type) return base.render(new_template, extra_vars={ u'form_vars': form_vars, u'form_snippet': form_snippet, u'dataset_type': package_type, u'resources_json': resources_json, u'form_snippet': form_snippet, u'errors_json': errors_json })
def get_package_resource_dcatapit_format_list(pkg_resources, fallback_lang=None): resources = [] if pkg_resources: resources = h.dict_list_reduce(pkg_resources, 'format') package_res = [] for resource in resources: localized_resource_name = interfaces.get_localized_tag_name( resource, fallback_lang) package_res.append(localized_resource_name) resources = package_res return resources
def edit(self, id, data=None, errors=None, error_summary=None): context = {'model': model, 'session': model.Session, 'user': c.user or c.author, 'auth_user_obj': c.userobj, 'save': 'save' in request.params, 'moderated': config.get('moderated'), 'pending': True} try: check_access('ckanext_showcase_update', context, {"id": id}) except NotAuthorized: abort(401, _('User not authorized to edit {showcase_id}').format( showcase_id=id)) # Note! edit() is copied and modified from CKAN's package.py # to bypass CKAN's check_access for package_edit, which would # automatically fail if showcases have datasets from multiple users. # see showcase author's comments in new(). # On POST request, save the form data if context['save'] and not data: return self._save_edit(id, context, package_type='showcase') # Otherwise, render the edit form old_data = get_action('package_show')(context, {'id': id}) c.pkg_dict = old_data # old data is from the db and data is passed if validation errors. if data: old_data.update(data) data = old_data if data and not data.get('tag_string'): data['tag_string'] = ', '.join(h.dict_list_reduce( c.pkg_dict.get('tags', {}), 'name')) errors = errors or {} c.errors_json = h.json.dumps(errors) form_vars = {'data': data, 'errors': errors, 'error_summary': error_summary, 'action': 'edit', 'dataset_type': 'showcase', 'stage': 'active' } c.types = self._type_options() return render('showcase/edit.html', extra_vars={'form_vars': form_vars, 'form_snippet': 'showcase/new_package_form.html', 'dataset_type': 'showcase'})
def dge_list_reduce_resource_format_label(resources=None, field_name='format'): ''' Given an resource list, get label of resource_format :param resources: resource dict :type dict list :param field_name: field_name of resource :type string :rtype string list ''' format_list = h.dict_list_reduce(resources, field_name) dataset = sh.scheming_get_schema('dataset', 'dataset') formats = sh.scheming_field_by_name(dataset.get('resource_fields'), 'format') label_list = [] for res_format in format_list: res_format_label = sh.scheming_choices_label(formats['choices'], res_format) if res_format_label: label_list.append(res_format_label) return label_list
def copy(self, id): context = { 'model': m, 'session': m.Session, 'user': p.toolkit.c.user or p.toolkit.c.author, 'auth_user_obj': p.toolkit.c.userobj, 'save': 'save' in t.request.params, } # check permissions try: t.check_access('package_create', context) except t.NotAuthorized: t.abort(401, t._('Unauthorized to copy this package')) data_dict = {'id': id} data = t.get_action('package_show')(None, data_dict) # change dataset title and name data['name'] = '{}-copy'.format(data['name']) while True: try: _ = t.get_action('package_show')(None, { 'name_or_id': data['name'] }) except l.NotFound: break else: import random data['name'] = '{}-copy-{}'.format(data['name'], random.randint(1, 100)) data['title'] = 'Copy of {0}'.format(data['title']) # remove unnecessary attributes from the dataset remove_atts = [ 'id', 'revision_id', 'metadata_created', 'metadata_modified', 'resources', 'revision_timestamp' ] for attr in remove_atts: if attr in data: del data[attr] if data and 'type' in data: package_type = data['type'] else: package_type = self._guess_package_type(True) data = data or clean_dict( dict_fns.unflatten( tuplize_dict( parse_params(t.request.params, ignore_keys=CACHE_PARAMETERS)))) c.resources_json = h.json.dumps(data.get('resources', [])) # convert tags if not supplied in data if data and not data.get('tag_string'): data['tag_string'] = ', '.join( h.dict_list_reduce(data.get('tags', {}), 'name')) # if we are creating from a group then this allows the group to be # set automatically data['group_id'] = t.request.params.get('group') or \ t.request.params.get('groups__0__id') # in the phased add dataset we need to know that # we have already completed stage 1 stage = ['active'] if data.get('state', '').startswith('draft'): stage = ['active', 'complete'] form_snippet = self._package_form(package_type=package_type) form_vars = { 'data': data, 'errors': {}, 'error_summary': {}, 'action': 'new', 'stage': stage, 'dataset_type': package_type, } c.errors_json = h.json.dumps({}) # override form action to use built-in package controller c.form_action = t.url_for(controller='package', action='new') self._setup_template_variables(context, {}, package_type=package_type) new_template = self._new_template(package_type) extra_vars = { 'form_vars': form_vars, 'form_snippet': form_snippet, 'dataset_type': package_type } return t.render(new_template, extra_vars=extra_vars)
def process_tags(self, dataset_dict): if dataset_dict and not dataset_dict.get('tag_string'): dataset_dict['tag_string'] = ', '.join( h.dict_list_reduce(dataset_dict.get('tags', {}), 'name'))
def import_form(self, data=None, errors=None, error_summary=None): package_type = self._guess_package_type(True) context = { 'model': model, 'session': model.Session, 'user': c.user or c.author, 'auth_user_obj': c.userobj, 'save': 'save' in request.params } # Package needs to have a organization group in the call to # check_access and also to save it try: check_access('package_create', context) except NotAuthorized: abort(401, _('Unauthorized to create a package')) if context['save'] and not data: return self._save_new(context, package_type=package_type) data = data or clean_dict( dict_fns.unflatten( tuplize_dict( parse_params(request.params, ignore_keys=CACHE_PARAMETERS)))) c.resources_json = h.json.dumps(data.get('resources', [])) # convert tags if not supplied in data if data and not data.get('tag_string'): data['tag_string'] = ', '.join( h.dict_list_reduce(data.get('tags', {}), 'name')) errors = errors or {} error_summary = error_summary or {} # if we are creating from a group then this allows the group to be # set automatically data['group_id'] = request.params.get('group') or \ request.params.get('groups__0__id') form_snippet = self.package_form form_vars = { 'data': data, 'errors': errors, 'error_summary': error_summary, 'action': 'new', 'dataset_type': package_type, } c.errors_json = h.json.dumps(errors) self._setup_template_variables(context, {}, package_type=package_type) new_template = self._new_template(package_type) c.form = ckan.lib.render.deprecated_lazy_render( new_template, form_snippet, lambda: render(form_snippet, extra_vars=form_vars), 'use of c.form is deprecated. please see ' 'ckan/templates/package/base_form_page.html for an example ' 'of the new way to include the form snippet') return render(new_template, extra_vars={ 'form_vars': form_vars, 'form_snippet': form_snippet, 'dataset_type': package_type })
def new(self, data=None, errors=None, error_summary=None): if data and 'type' in data: package_type = data['type'] else: package_type = self._guess_package_type(True) context = {'model': model, 'session': model.Session, 'user': c.user or c.author, 'auth_user_obj': c.userobj, 'save': 'save' in request.params} # Package needs to have a organization group in the call to # check_access and also to save it try: check_access('package_create', context) except NotAuthorized: abort(401, _('Unauthorized to create a package')) if context['save'] and not data: return self._save_new(context, package_type=package_type) data = data or clean_dict(dict_fns.unflatten(tuplize_dict(parse_params( request.params, ignore_keys=CACHE_PARAMETERS)))) c.resources_json = h.json.dumps(data.get('resources', [])) # convert tags if not supplied in data if data and not data.get('tag_string'): data['tag_string'] = ', '.join( h.dict_list_reduce(data.get('tags', {}), 'name')) errors = errors or {} error_summary = error_summary or {} # in the phased add dataset we need to know that # we have already completed stage 1 stage = ['active'] if data.get('state', '').startswith('draft'): stage = ['active', 'complete'] # if we are creating from a group then this allows the group to be # set automatically data['group_id'] = request.params.get('group') or \ request.params.get('groups__0__id') form_snippet = self._package_form(package_type=package_type) form_vars = {'data': data, 'errors': errors, 'error_summary': error_summary, 'action': 'new', 'stage': stage, 'dataset_type': package_type, } c.errors_json = h.json.dumps(errors) self._setup_template_variables(context, {}, package_type=package_type) new_template = self._new_template(package_type) c.form = deprecated_lazy_render( new_template, form_snippet, lambda: render(form_snippet, extra_vars=form_vars), 'use of c.form is deprecated. please see ' 'ckan/templates/package/base_form_page.html for an example ' 'of the new way to include the form snippet' ) return render(new_template, extra_vars={'form_vars': form_vars, 'form_snippet': form_snippet, 'dataset_type': package_type})
def get(self, package_type, data=None, errors=None, error_summary=None): context = self._prepare(data) if data and u'type' in data: package_type = data[u'type'] data = data or clean_dict( dict_fns.unflatten( tuplize_dict( parse_params(request.args, ignore_keys=CACHE_PARAMETERS) ) ) ) resources_json = h.json.dumps(data.get(u'resources', [])) # convert tags if not supplied in data if data and not data.get(u'tag_string'): data[u'tag_string'] = u', '.join( h.dict_list_reduce(data.get(u'tags', {}), u'name') ) errors = errors or {} error_summary = error_summary or {} # in the phased add dataset we need to know that # we have already completed stage 1 stage = [u'active'] if data.get(u'state', u'').startswith(u'draft'): stage = [u'active', u'complete'] # if we are creating from a group then this allows the group to be # set automatically data[ u'group_id' ] = request.args.get(u'group') or request.args.get(u'groups__0__id') form_snippet = _get_pkg_template( u'package_form', package_type=package_type ) form_vars = { u'data': data, u'errors': errors, u'error_summary': error_summary, u'action': u'new', u'stage': stage, u'dataset_type': package_type, u'form_style': u'new' } errors_json = h.json.dumps(errors) # TODO: remove g.resources_json = resources_json g.errors_json = errors_json _setup_template_variables(context, {}, package_type=package_type) new_template = _get_pkg_template(u'new_template', package_type) return base.render( new_template, extra_vars={ u'form_vars': form_vars, u'form_snippet': form_snippet, u'dataset_type': package_type, u'resources_json': resources_json, u'form_snippet': form_snippet, u'errors_json': errors_json } )
def new(self, data=None, errors=None, error_summary=None): package_type = self._guess_package_type(True) context = { 'model': model, 'session': model.Session, 'user': c.user or c.author, 'auth_user_obj': c.userobj, 'save': 'save' in request.params } # Package needs to have a organization group in the call to # check_access and also to save it try: check_access('package_create', context) except NotAuthorized: abort(401, _('Unauthorized to create a package')) if context['save'] and not data: return self._save_new(context, package_type=package_type) data = data or clean_dict( dict_fns.unflatten( tuplize_dict( parse_params(request.params, ignore_keys=CACHE_PARAMETERS)))) c.resources_json = h.json.dumps(data.get('resources', [])) # convert tags if not supplied in data if data and not data.get('tag_string'): data['tag_string'] = ', '.join( h.dict_list_reduce(data.get('tags', {}), 'name')) errors = errors or {} error_summary = error_summary or {} # in the phased add dataset we need to know that # we have already completed stage 1 stage = ['active'] if data.get('state') == 'draft': stage = ['active', 'complete'] elif data.get('state') == 'draft-complete': stage = ['active', 'complete', 'complete'] # if we are creating from a group then this allows the group to be # set automatically data['group_id'] = request.params.get('group') or \ request.params.get('groups__0__id') vars = { 'data': data, 'errors': errors, 'error_summary': error_summary, 'action': 'new', 'stage': stage } c.errors_json = h.json.dumps(errors) self._setup_template_variables(context, {}, package_type=package_type) # TODO: This check is to maintain backwards compatibility with the # old way of creating custom forms. This behaviour is now deprecated. if hasattr(self, 'package_form'): c.form = render(self.package_form, extra_vars=vars) else: c.form = render(self._package_form(package_type=package_type), extra_vars=vars) return render(self._new_template(package_type), extra_vars={'stage': stage})
def duplicate(self, id): ''' Creates a duplicate of the record with the given id. The content of the duplicate record is the same as the original except for the title and the name. ''' context = {'model': model, 'session': model.Session, 'user': c.user or c.author, 'auth_user_obj': c.userobj} # Check if the user is authorized to create a new dataset try: check_access('package_create', context) except NotAuthorized: abort(401, _('Unauthorized to create a package')) #Get the dataset details try: data_dict = get_action('package_show')(context, {'id': id}) except NotAuthorized: abort(401, _('Unauthorized to read package %s') % '') except NotFound: abort(404, _('Dataset not found')) #Change the name and the title of the duplicate record record_name = data_dict['name'] record_title = data_dict['title'] record_title = '#Duplicate# ' + record_title name_len = len(record_name) if name_len > 87 : record_name = record_name[:-13] record_name = '__duplicate__' + record_name data_dict['name'] = record_name data_dict['title'] = record_title data_dict['edc_state'] = 'DRAFT' #Remove resources if there are any del data_dict['resources'] del data_dict['id'] del data_dict['revision_id'] data_dict.pop('revision_timestamp', None) # Create the tag_string if needed ''' 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')) #To do - Image upload issues : Use a single copy for the original and duplicate record # Create a new copy of the original record or remove the image link and let the user upload a new image. c.is_duplicate = True #Create the duplicate record pkg_dict = toolkit.get_action('package_create')(data_dict=data_dict) redirect(h.url_for(controller='package', action='edit', id=pkg_dict['id']))
def duplicate(self, id, package_type=None): ''' Creates a duplicate of the record with the given id. The content of the duplicate record is the same as the original except for the title and the name. ''' context = { 'model': model, 'session': model.Session, 'user': c.user or c.author, 'auth_user_obj': c.userobj } if (request.method == 'POST'): return self._save_new(context, package_type=package_type) # Check if the user is authorized to create a new dataset try: check_access('package_create', context) except NotAuthorized: abort(401, _('Unauthorized to create a package')) #Get the dataset details try: data_dict = get_action('package_show')(context, {'id': id}) except NotAuthorized: abort(401, _('Unauthorized to read package %s') % '') except NotFound: abort(404, _('Dataset not found')) #Change the name and the title of the duplicate record record_name = data_dict['name'] record_title = data_dict['title'] record_title = '#Duplicate# ' + record_title name_len = len(record_name) if name_len > 87: record_name = record_name[:-13] record_name = '__duplicate__' + record_name data_dict['name'] = record_name data_dict['title'] = record_title data_dict['edc_state'] = 'DRAFT' # CITZEDC755 - Remove publish date for duplicate datasets data_dict['record_publish_date'] = None #Remove resources if there are any del data_dict['resources'] del data_dict['id'] del data_dict['revision_id'] data_dict.pop('revision_timestamp', None) # Create the tag_string if needed ''' 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')) #To do - Image upload issues : Use a single copy for the original and duplicate record # Create a new copy of the original record or remove the image link and let the user upload a new image. c.is_duplicate = True errors = {} error_summary = {} # in the phased add dataset we need to know that # we have already completed stage 1 stage = ['active'] if data_dict.get('state', '').startswith('draft'): stage = ['active', 'complete'] # if we are creating from a group then this allows the group to be # set automatically data_dict['group_id'] = request.params.get('group') or \ request.params.get('groups__0__id') c.record_type = package_type or c.record_type form_snippet = self._package_form(package_type=package_type) form_vars = { 'data': data_dict, 'errors': errors, 'error_summary': error_summary, 'action': 'new', 'stage': stage, 'dataset_type': package_type, } c.errors_json = h.json.dumps(errors) self._setup_template_variables(context, {}, package_type=package_type) new_template = self._new_template(package_type) return render(new_template, extra_vars={ 'form_vars': form_vars, 'form_snippet': form_snippet, 'dataset_type': package_type })
def edit(self, id, data=None, errors=None, error_summary=None): package_type = self._get_package_type(id) context = {'model': model, 'session': model.Session, 'user': c.user or c.author, 'auth_user_obj': c.userobj, 'save': 'save' in request.params} if context['save'] and not data: return self._save_edit(id, context, package_type=package_type) try: c.pkg_dict = get_action('package_show')(context, {'id': id}) context['for_edit'] = True old_data = get_action('package_show')(context, {'id': id}) # old data is from the database and data is passed from the # user if there is a validation error. Use users data if there. if data: old_data.update(data) data = old_data except NotAuthorized: abort(401, _('Unauthorized to read package %s') % '') except NotFound: abort(404, _('Dataset not found')) # are we doing a multiphase add? if data.get('state', '').startswith('draft') and len(data.get('resources')) == 0: c.form_action = h.url_for(controller='package', action='new') c.form_style = 'new' return self.new(data=data, errors=errors, error_summary=error_summary) c.pkg = context.get("package") c.resources_json = h.json.dumps(data.get('resources', [])) try: check_access('package_update', context) except NotAuthorized: abort(401, _('User %r not authorized to edit %s') % (c.user, id)) # convert tags if not supplied in data if data and not data.get('tag_string'): data['tag_string'] = ', '.join(h.dict_list_reduce( c.pkg_dict.get('tags', {}), 'name')) errors = errors or {} form_snippet = self._package_form(package_type=package_type) form_vars = {'data': data, 'errors': errors, 'error_summary': error_summary, 'action': 'edit', 'dataset_type': package_type, } c.errors_json = h.json.dumps(errors) self._setup_template_variables(context, {'id': id}, package_type=package_type) c.related_count = c.pkg.related_count # we have already completed stage 1 form_vars['stage'] = ['active'] if data.get('state', '').startswith('draft') and len(data.get('resources')) == 0: form_vars['stage'] = ['active', 'complete'] edit_template = self._edit_template(package_type) c.form = ckan.lib.render.deprecated_lazy_render( edit_template, form_snippet, lambda: render(form_snippet, extra_vars=form_vars), 'use of c.form is deprecated. please see ' 'ckan/templates/package/edit.html for an example ' 'of the new way to include the form snippet' ) return render(edit_template, extra_vars={'form_vars': form_vars, 'form_snippet': form_snippet, 'dataset_type': package_type})
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
def edit(self, id, data=None, errors=None, error_summary=None): # custom_base.g_analitics() package_type = self._get_package_type(id) context = {'model': model, 'session': model.Session, 'user': c.user or c.author, 'auth_user_obj': c.userobj, 'save': 'save' in request.params} if context['save'] and not data: # check against csrf attacks custom_base.csrf_check(self) return self._save_edit(id, context, package_type=package_type) try: c.pkg_dict = get_action('package_show')(context, {'id': id}) context['for_edit'] = True old_data = get_action('package_show')(context, {'id': id}) # old data is from the database and data is passed from the # user if there is a validation error. Use users data if there. if data: old_data.update(data) data = old_data except NotAuthorized: abort(401, _('Unauthorized to read package %s') % '') except NotFound: abort(404, _('Dataset not found')) analytics_helpers.update_analytics_code_by_organization(c.pkg_dict['organization']['id']) # are we doing a multiphase add? if data.get('state', '').startswith('draft'): c.form_action = h.url_for(controller='package', action='new') c.form_style = 'new' return self.new(data=data, errors=errors, error_summary=error_summary) c.pkg = context.get("package") c.resources_json = h.json.dumps(data.get('resources', [])) try: check_access('package_update', context) except NotAuthorized: abort(401, _('User %r not authorized to edit %s') % (c.user, id)) # convert tags if not supplied in data if data and not data.get('tag_string'): data['tag_string'] = ', '.join(h.dict_list_reduce( c.pkg_dict.get('tags', {}), 'name')) errors = errors or {} form_snippet = self._package_form(package_type=package_type) form_vars = {'data': data, 'errors': errors, 'error_summary': error_summary, 'action': 'edit', 'dataset_type': package_type, } c.errors_json = h.json.dumps(errors) self._setup_template_variables(context, {'id': id}, package_type=package_type) # deprecated # c.related_count = c.pkg.related_count # we have already completed stage 1 form_vars['stage'] = ['active'] if data.get('state', '').startswith('draft'): form_vars['stage'] = ['active', 'complete'] edit_template = self._edit_template(package_type) # c.form = ckan.lib.render.deprecated_lazy_render( # edit_template, # form_snippet, # lambda: render(form_snippet, extra_vars=form_vars), # 'use of c.form is deprecated. please see ' # 'ckan/templates/package/edit.html for an example ' # 'of the new way to include the form snippet' # ) return render(edit_template, extra_vars={'form_vars': form_vars, 'form_snippet': form_snippet, 'dataset_type': package_type})
def duplicate(self, id, package_type=None): ''' Creates a duplicate of the record with the given id. The content of the duplicate record is the same as the original except for the title and the name. ''' context = {'model': model, 'session': model.Session, 'user': c.user or c.author, 'auth_user_obj': c.userobj} if (request.method == 'POST'): return self._save_new(context, package_type=package_type) # Check if the user is authorized to create a new dataset try: check_access('package_create', context) except NotAuthorized: abort(401, _('Unauthorized to create a package')) #Get the dataset details try: data_dict = get_action('package_show')(context, {'id': id}) except NotAuthorized: abort(401, _('Unauthorized to read package %s') % '') except NotFound: abort(404, _('Dataset not found')) #Change the name and the title of the duplicate record record_name = data_dict['name'] record_title = data_dict['title'] record_title = '#Duplicate# ' + record_title name_len = len(record_name) if name_len > 87 : record_name = record_name[:-13] record_name = '__duplicate__' + record_name data_dict['name'] = record_name data_dict['title'] = record_title data_dict['edc_state'] = 'DRAFT' # CITZEDC755 - Remove publish date for duplicate datasets data_dict['record_publish_date'] = None #Remove resources if there are any del data_dict['resources'] del data_dict['id'] del data_dict['revision_id'] data_dict.pop('revision_timestamp', None) # Create the tag_string if needed ''' 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')) #To do - Image upload issues : Use a single copy for the original and duplicate record # Create a new copy of the original record or remove the image link and let the user upload a new image. c.is_duplicate = True errors = {} error_summary = {} # in the phased add dataset we need to know that # we have already completed stage 1 stage = ['active'] if data_dict.get('state', '').startswith('draft'): stage = ['active', 'complete'] # if we are creating from a group then this allows the group to be # set automatically data_dict['group_id'] = request.params.get('group') or \ request.params.get('groups__0__id') c.record_type = package_type or c.record_type form_snippet = self._package_form(package_type=package_type) form_vars = {'data': data_dict, 'errors': errors, 'error_summary': error_summary, 'action': 'new', 'stage': stage, 'dataset_type': package_type, } c.errors_json = h.json.dumps(errors) self._setup_template_variables(context, { }, package_type=package_type) new_template = self._new_template(package_type) return render(new_template, extra_vars={'form_vars': form_vars, 'form_snippet': form_snippet, 'dataset_type': package_type})
def get( self, package_type, id, data=None, errors=None, error_summary=None ): context = self._prepare(id, data) package_type = _get_package_type(id) or package_type try: pkg_dict = get_action(u'package_show')( dict(context, for_view=True), { u'id': id } ) context[u'for_edit'] = True old_data = get_action(u'package_show')(context, {u'id': id}) # old data is from the database and data is passed from the # user if there is a validation error. Use users data if there. if data: old_data.update(data) data = old_data except (NotFound, NotAuthorized): return base.abort(404, _(u'Dataset not found')) # are we doing a multiphase add? if data.get(u'state', u'').startswith(u'draft'): g.form_action = h.url_for(u'dataset.new') g.form_style = u'new' return CreateView().get( package_type, data=data, errors=errors, error_summary=error_summary ) pkg = context.get(u"package") resources_json = h.json.dumps(data.get(u'resources', [])) try: check_access(u'package_update', context) except NotAuthorized: return base.abort( 403, _(u'User %r not authorized to edit %s') % (g.user, id) ) # convert tags if not supplied in data if data and not data.get(u'tag_string'): data[u'tag_string'] = u', '.join( h.dict_list_reduce(pkg_dict.get(u'tags', {}), u'name') ) errors = errors or {} form_snippet = _get_pkg_template( u'package_form', package_type=package_type ) form_vars = { u'data': data, u'errors': errors, u'error_summary': error_summary, u'action': u'edit', u'dataset_type': package_type, u'form_style': u'edit' } errors_json = h.json.dumps(errors) # TODO: remove g.pkg = pkg g.resources_json = resources_json g.errors_json = errors_json _setup_template_variables( context, {u'id': id}, package_type=package_type ) # we have already completed stage 1 form_vars[u'stage'] = [u'active'] if data.get(u'state', u'').startswith(u'draft'): form_vars[u'stage'] = [u'active', u'complete'] edit_template = _get_pkg_template(u'edit_template', package_type) return base.render( edit_template, extra_vars={ u'form_vars': form_vars, u'form_snippet': form_snippet, u'dataset_type': package_type, u'pkg_dict': pkg_dict, u'pkg': pkg, u'resources_json': resources_json, u'form_snippet': form_snippet, u'errors_json': errors_json } )
updated_page.get("type")) h.redirect_to(mapped_action, id=updated_page.get('name') or updated_page.get('id')) elif delete_page: h.redirect_to( controller= 'ckanext.hdx_pages.controllers.custom_page:PagesController', action='delete', id=id) else: extra_vars['data'] = logic.get_action('page_show')(context, { 'id': id }) extra_vars['data']['tag_string'] = ', '.join( h.dict_list_reduce(extra_vars['data'].get('tags', {}), 'name')) self._init_extra_vars_edit(extra_vars) return base.render('pages/edit_page.html', extra_vars=extra_vars) @check_redirect_needed def read_event(self, id): return self.read_page(id, 'event') @check_redirect_needed def read_dashboards(self, id): return self.read_page(id, 'dashboards') def read_page(self, id, type): context = { 'model': model,
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
def new(self, data=None, errors=None, error_summary=None): # Is the user a member of any orgs? If not make them join one first try: user_orgs = helpers.hdx_user_org_num(c.userobj.id) if len(user_orgs) == 0: return render('organization/request_mem_or_org.html') # If there's an org and the user is not a member of this org # redirect back to org select this_org = request.params['organization_id'] if this_org in user_orgs: return render('organization/request_mem_or_org.html') except: return render('user/login.html', extra_vars={'contribute': True}) package_type = self._guess_package_type(True) context = {'model': model, 'session': model.Session, 'user': c.user or c.author, 'save': 'save' in request.params} # Package needs to have a organization group in the call to # check_access and also to save it try: check_access('package_create', context) except NotAuthorized: abort(401, _('Unauthorized to create a package')) if context['save'] and not data: return self._save_new(context, package_type=package_type) data = data or clean_dict(dict_fns.unflatten(tuplize_dict(parse_params( request.params, ignore_keys=CACHE_PARAMETERS)))) c.resources_json = h.json.dumps(data.get('resources', [])) # convert tags if not supplied in data if data and not data.get('tag_string'): data['tag_string'] = ', '.join( h.dict_list_reduce(data.get('tags', {}), 'name')) errors = errors or {} error_summary = error_summary or {} # in the phased add dataset we need to know that # we have already completed stage 1 stage = ['inactive'] if data.get('state') == 'draft': stage = ['inactive', 'complete'] elif data.get('state') == 'draft-complete': stage = ['inactive', 'complete', 'complete'] # if we are creating from a group then this allows the group to be # set automatically data['group_id'] = request.params.get('group') or \ request.params.get('groups__0__id') vars = {'data': data, 'errors': errors, 'error_summary': error_summary, 'action': 'new', 'stage': stage, 'validation_fail': 0} c.errors_json = h.json.dumps(errors) self._setup_template_variables(context, {}, package_type=package_type) # TODO: This check is to maintain backwards compatibility with the # old way of creating custom forms. This behaviour is now deprecated. if hasattr(self, 'package_form'): c.form = render(self.package_form, extra_vars=vars) else: c.form = render(self._package_form(package_type=package_type), extra_vars=vars) if not request.is_xhr: return render(self._new_template(package_type), extra_vars={'stage': stage, 'data': data}) else: return self._finish(200, {'validation_fail': 1, 'errors': vars['errors'], 'error_summary': vars['error_summary']}, content_type='json')
class OdpatPackageController(ckan.controllers.package.PackageController): p.implements(p.IPackageController) log.info("Enter: OdpatPackageController") def edit(self, id, data=None, errors=None, error_summary=None): package_type = self._get_package_type(id) context = { 'model': model, 'session': model.Session, 'user': c.user or c.author, 'auth_user_obj': c.userobj, 'save': 'save' in request.params, 'moderated': config.get('moderated'), 'pending': True } if context['save'] and not data: return self._save_edit(id, context, package_type=package_type) try: c.pkg_dict = get_action('package_show')(context, {'id': id}) context['for_edit'] = True old_data = get_action('package_show')(context, {'id': id}) # old data is from the database and data is passed from the # user if there is a validation error. Use users data if there. if data: old_data.update(data) data = old_data except NotAuthorized: abort(401, _('Unauthorized to read package %s') % '') except NotFound: abort(404, _('Dataset not found')) # are we doing a multiphase add? if data.get('state', '').startswith('draft'): c.form_action = h.url_for(controller='package', action='new') c.form_style = 'new' return self.new(data=data, errors=errors, error_summary=error_summary) c.pkg = context.get("package") c.resources_json = h.json.dumps(data.get('resources', [])) try: check_access('package_update', context) except NotAuthorized, e: abort(401, _('User %r not authorized to edit %s') % (c.user, id)) # convert tags if not supplied in data if data and not data.get('tag_string'): data['tag_string'] = ', '.join( h.dict_list_reduce(c.pkg_dict.get('tags', {}), 'name')) # Extract extra values to main structure for simple access if data and data['extras']: for extra in data['extras']: data[extra['key']] = extra['value'] errors = errors or {} vars = { 'data': data, 'errors': errors, 'error_summary': error_summary, 'action': 'edit' } c.errors_json = h.json.dumps(errors) self._setup_template_variables(context, {'id': id}, package_type=package_type) c.related_count = c.pkg.related_count # we have already completed stage 1 vars['stage'] = ['active'] if data.get('state') == 'draft': vars['stage'] = ['active', 'complete'] elif data.get('state') == 'draft-complete': vars['stage'] = ['active', 'complete', 'complete'] # TODO: This check is to maintain backwards compatibility with the # old way of creating custom forms. This behaviour is now deprecated. if hasattr(self, 'package_form'): c.form = render(self.package_form, extra_vars=vars) else: c.form = render(self._package_form(package_type=package_type), extra_vars=vars) return render(self._edit_template(package_type), extra_vars={'stage': vars['stage']})
def get( self, package_type, id, data=None, errors=None, error_summary=None ): context = self._prepare(id, data) package_type = _get_package_type(id) or package_type try: pkg_dict = get_action(u'package_show')( dict(context, for_view=True), { u'id': id } ) context[u'for_edit'] = True old_data = get_action(u'package_show')(context, {u'id': id}) # old data is from the database and data is passed from the # user if there is a validation error. Use users data if there. if data: old_data.update(data) data = old_data except (NotFound, NotAuthorized): return base.abort(404, _(u'Dataset not found')) # are we doing a multiphase add? if data.get(u'state', u'').startswith(u'draft'): g.form_action = h.url_for(u'{}.new'.format(package_type)) g.form_style = u'new' return CreateView().get( package_type, data=data, errors=errors, error_summary=error_summary ) pkg = context.get(u"package") resources_json = h.json.dumps(data.get(u'resources', [])) try: check_access(u'package_update', context) except NotAuthorized: return base.abort( 403, _(u'User %r not authorized to edit %s') % (g.user, id) ) # convert tags if not supplied in data if data and not data.get(u'tag_string'): data[u'tag_string'] = u', '.join( h.dict_list_reduce(pkg_dict.get(u'tags', {}), u'name') ) errors = errors or {} form_snippet = _get_pkg_template( u'package_form', package_type=package_type ) form_vars = { u'data': data, u'errors': errors, u'error_summary': error_summary, u'action': u'edit', u'dataset_type': package_type, u'form_style': u'edit' } errors_json = h.json.dumps(errors) # TODO: remove g.pkg = pkg g.resources_json = resources_json g.errors_json = errors_json _setup_template_variables( context, {u'id': id}, package_type=package_type ) # we have already completed stage 1 form_vars[u'stage'] = [u'active'] if data.get(u'state', u'').startswith(u'draft'): form_vars[u'stage'] = [u'active', u'complete'] edit_template = _get_pkg_template(u'edit_template', package_type) return base.render( edit_template, extra_vars={ u'form_vars': form_vars, u'form_snippet': form_snippet, u'dataset_type': package_type, u'pkg_dict': pkg_dict, u'pkg': pkg, u'resources_json': resources_json, u'form_snippet': form_snippet, u'errors_json': errors_json } )
def copy_resources(self, id, data=None, errors=None, error_summary=None): context = { 'model': m, 'session': m.Session, 'user': p.toolkit.c.user or p.toolkit.c.author, 'auth_user_obj': p.toolkit.c.userobj, 'save': 'save' in t.request.params, } # check permissions try: t.check_access('package_create', context) except t.NotAuthorized: t.abort(401, t._('Unauthorized to copy this package')) # get package type if data and 'type' in data: package_type = data['type'] else: package_type = self._guess_package_type(True) resources = None if data is None: data = t.get_action('package_show')(None, {'id': id}) # generate new unused package name data['title'] = 'Copy of {0}'.format(data['title']) data['name'] = '{}-copy'.format(data['name']) while True: try: _ = t.get_action('package_show')(None, { 'name_or_id': data['name'] }) except l.NotFound: break else: import random data['name'] = '{}-copy-{}'.format(data['name'], random.randint(1, 100)) # remove unnecessary attributes from the dataset remove_attrs = [ 'id', 'revision_id', 'metadata_created', 'metadata_modified', 'revision_timestamp' ] for attr in remove_attrs: if attr in data: del data[attr] # process package resources resources = data.pop('resources', []) remove_attrs = ('id', 'revision_id', 'created', 'last_modified', 'package_id') for resource in resources: for attr in remove_attrs: if attr in resource: del resource[attr] c.resources_json = h.json.dumps(resources) form_snippet = 'package/copy_package_form.html' c.form_action = t.url_for( controller='ckanext.sokigo.controller:CopyController', action='copy_resources', id=id) if context['save'] and t.request.method == 'POST': data = clean_dict( dict_fns.unflatten( tuplize_dict( parse_params(t.request.POST, ignore_keys=CACHE_PARAMETERS)))) data['resources'] = resources # convert tags if not supplied in data if data and not data.get('tag_string'): data['tag_string'] = ', '.join( h.dict_list_reduce(data.get('tags', {}), 'name')) # if we are creating from a group then this allows the group to be # set automatically data['group_id'] = t.request.params.get('group') or \ t.request.params.get('groups__0__id') try: pkg_dict = t.get_action('package_create')(context, data) except l.NotAuthorized: t.abort(403, _('Unauthorized to read package %s') % '') except l.NotFound as e: t.abort(404, _('Dataset not found')) except dict_fns.DataError: t.abort(400, _(u'Integrity Error')) except SearchIndexError as e: try: exc_str = text_type(repr(e.args)) except Exception: # We don't like bare excepts exc_str = text_type(str(e)) t.abort(500, _(u'Unable to add package to search index.') + exc_str) except t.ValidationError as e: data['state'] = 'none' c.data = data c.errors_json = h.json.dumps(e.error_dict) form_vars = { 'data': data, 'errors': e.error_dict, 'error_summary': e.error_summary, 'action': 'new', 'stage': data['state'], 'dataset_type': package_type } extra_vars = { 'form_vars': form_vars, 'form_snippet': form_snippet, 'dataset_type': package_type } return t.render('package/copy.html', extra_vars=extra_vars) else: h.redirect_to(controller='package', action='read', id=pkg_dict['name']) c.data = data c.errors_json = h.json.dumps(errors) form_vars = { 'data': data, 'errors': errors or {}, 'error_summary': error_summary or {}, 'action': 'new', 'stage': data['state'], 'dataset_type': package_type } extra_vars = { 'form_vars': form_vars, 'form_snippet': form_snippet, 'dataset_type': package_type } return t.render('package/copy.html', extra_vars=extra_vars)