def resource_edit(self, id, resource_id, data=None, errors=None, error_summary=None): custom_base.g_analitics() if request.method == 'POST' and not data: #check against csrf attacks custom_base.csrf_check(self) data = data or \ clean_dict(dict_fns.unflatten(tuplize_dict(parse_params( request.POST)))) # we don't want to include save as it is part of the form del data['save'] context = {'model': model, 'session': model.Session, 'api_version': 3, 'for_edit': True, 'user': c.user or c.author, 'auth_user_obj': c.userobj} data['package_id'] = id try: if resource_id: data['id'] = resource_id get_action('resource_update')(context, data) else: get_action('resource_create')(context, data) except ValidationError, e: errors = e.error_dict error_summary = e.error_summary return self.resource_edit(id, resource_id, data, errors, error_summary) except NotAuthorized: abort(401, _('Unauthorized to edit this resource'))
def index(self): custom_base.g_analitics() group_type = self._guess_group_type() page = h.get_page_number(request.params) or 1 items_per_page = 21 context = {'model': model, 'session': model.Session, 'user': c.user or c.author, 'for_view': True, 'with_private': False} q = c.q = request.params.get('q', '') sort_by = c.sort_by_selected = request.params.get('sort') empty_string = "" # default sort by number of organization's datasets if sort_by is None or sort_by == empty_string: sort_by = 'package_count desc' try: self._check_access('site_read', context) except NotAuthorized: abort(401, _('Not authorized to see this page')) # pass user info to context as needed to view private datasets of # orgs correctly if c.userobj: context['user_id'] = c.userobj.id context['user_is_admin'] = c.userobj.sysadmin data_dict_global_results = { 'all_fields': False, 'q': q, 'sort': sort_by, 'type': group_type or 'group', } global_results = self._action('group_list')(context, data_dict_global_results) data_dict_page_results = { 'all_fields': True, 'q': q, 'sort': sort_by, 'type': group_type or 'group', 'limit': items_per_page, 'offset': items_per_page * (page - 1), } page_results = self._action('group_list')(context, data_dict_page_results) c.page = h.Page( collection=global_results, page=page, url=h.pager_url, items_per_page=items_per_page, ) c.page.items = page_results return render(self._index_template(group_type), extra_vars={'group_type': group_type})
def read(self, id, limit=20): custom_base.g_analitics() group_type = self._ensure_controller_matches_group_type( id.split('@')[0]) context = {'model': model, 'session': model.Session, 'user': c.user or c.author, 'schema': self._db_to_form_schema(group_type=group_type), 'for_view': True} data_dict = {'id': id} # unicode format (decoded from utf8) c.q = request.params.get('q', '') try: # Do not query for the group datasets when dictizing, as they will # be ignored and get requested on the controller anyway data_dict['include_datasets'] = False c.group_dict = self._action('group_show')(context, data_dict) c.group = context['group'] except NotFound: abort(404, _('Group not found')) except NotAuthorized: abort(401, _('Unauthorized to read group %s') % id) self._read(id, limit, group_type) return render(self._read_template(c.group_dict['type']), extra_vars={'group_type': group_type})
def resource_download(self, id, resource_id, filename=None): custom_base.g_analitics() """ Provides a direct download by either redirecting the user to the url stored or downloading an uploaded file directly. """ context = {'model': model, 'session': model.Session, 'user': c.user or c.author, 'auth_user_obj': c.userobj} try: rsc = get_action('resource_show')(context, {'id': resource_id}) get_action('package_show')(context, {'id': id}) # removes the host to make it relative if config.get('ckan.upload_file_url'): url = rsc['url'] if config.get('ckan.upload_file_url') in url: url = url.split(config.get('ckan.upload_file_url')) rsc['url'] = url[1] #c.resource['url'] = rsc['url'] except NotFound: abort(404, _('Resource not found')) except NotAuthorized: abort(401, _('Unauthorized to read resource %s') % id) if rsc.get('url_type') == 'upload': upload = uploader.ResourceUpload(rsc) filepath = upload.get_path(rsc['id']) fileapp = paste.fileapp.FileApp(filepath) try: status, headers, app_iter = request.call_application(fileapp) except OSError: abort(404, _('Resource data not found')) response.headers.update(dict(headers)) content_type, content_enc = mimetypes.guess_type( rsc.get('url', '')) if content_type: response.headers['Content-Type'] = content_type response.status = status return app_iter elif not 'url' in rsc: abort(404, _('No download is available')) redirect(rsc['url'])
def resource_download(self, id, resource_id, filename=None): custom_base.g_analitics() """ Provides a direct download by either redirecting the user to the url stored or downloading an uploaded file directly. """ context = {'model': model, 'session': model.Session, 'user': c.user or c.author, 'auth_user_obj': c.userobj} try: rsc = get_action('resource_show')(context, {'id': resource_id}) get_action('package_show')(context, {'id': id}) # removes the host to make it relative if config.get('ckan.upload_file_url'): url = rsc['url'] if config.get('ckan.upload_file_url') in url: url = url.split(config.get('ckan.upload_file_url')) rsc['url'] = url[1] #c.resource['url'] = rsc['url'] except NotFound: abort(404, _('Resource not found')) except NotAuthorized: abort(401, _('Unauthorized to read resource %s') % id) if rsc.get('url_type') == 'upload': upload = uploader.ResourceUpload(rsc) filepath = upload.get_path(rsc['id']) fileapp = paste.fileapp.FileApp(filepath) try: status, headers, app_iter = request.call_application(fileapp) except OSError: abort(404, _('Resource data not found')) response.headers.update(dict(headers)) content_type, content_enc = mimetypes.guess_type( rsc.get('url', '')) if content_type: response.headers['Content-Type'] = content_type response.status = status return app_iter elif not 'url' in rsc: abort(404, _('No download is available')) h.redirect_to(rsc['url'])
def read(self, id): custom_base.g_analitics() context = {'model': model, 'session': model.Session, 'user': c.user, 'for_view': True, 'auth_user_obj': c.userobj} data_dict = {'id': id, 'include_tracking': True} # interpret @<revision_id> or @<date> suffix split = id.split('@') if len(split) == 2: data_dict['id'], revision_ref = split if model.is_id(revision_ref): context['revision_id'] = revision_ref else: try: date = h.date_str_to_datetime(revision_ref) context['revision_date'] = date except TypeError, e: abort(400, _('Invalid revision format: %r') % e.args) except ValueError, e: abort(400, _('Invalid revision format: %r') % e.args)
def read(self, id, format='html'): custom_base.g_analitics() if not format == 'html': ctype, extension = \ self._content_type_from_extension(format) if not ctype: # An unknown format, we'll carry on in case it is a # revision specifier and re-constitute the original id id = "%s.%s" % (id, format) ctype, format = "text/html; charset=utf-8", "html" else: ctype, format = self._content_type_from_accept() response.headers['Content-Type'] = ctype context = {'model': model, 'session': model.Session, 'user': c.user or c.author, 'for_view': True, 'auth_user_obj': c.userobj} data_dict = {'id': id, 'include_tracking': True} # interpret @<revision_id> or @<date> suffix split = id.split('@') if len(split) == 2: data_dict['id'], revision_ref = split if model.is_id(revision_ref): context['revision_id'] = revision_ref else: try: date = h.date_str_to_datetime(revision_ref) context['revision_date'] = date except TypeError, e: abort(400, _('Invalid revision format: %r') % e.args) except ValueError, e: abort(400, _('Invalid revision format: %r') % e.args)
def resource_read(self, id, resource_id): custom_base.g_analitics() context = {'model': model, 'session': model.Session, 'user': c.user or c.author, 'auth_user_obj': c.userobj, 'for_view': True} try: c.package = get_action('package_show')(context, {'id': id}) except NotFound: abort(404, _('Dataset not found')) except NotAuthorized: abort(401, _('Unauthorized to read dataset %s') % id) c.upload_file_url = config.get('ckan.upload_file_url') c.upload_file_url_sec = config.get('ckan.upload_file_url_sec') for resource in c.package.get('resources', []): if resource['id'] == resource_id: url = resource['url'] # check if the resource is local and can be previewed if 'dataset' in url: resource['is_local_resource'] = True else: resource['is_local_resource'] = False # removes the host to make it relative if config.get('ckan.upload_file_url'): if config.get('ckan.upload_file_url') in url: url = url.split(config.get('ckan.upload_file_url')) resource['url'] = url[1] if config.get('ckan.upload_file_url_sec') in url: url = url.split(config.get('ckan.upload_file_url_sec')) resource['url'] = url[1] # resource['url'] = url[1] c.resource = resource break if not c.resource: abort(404, _('Resource not found')) # required for nav menu c.pkg = context['package'] c.pkg_dict = c.package dataset_type = c.pkg.type or 'dataset' # get package license info license_id = c.package.get('license_id') try: c.package['isopen'] = model.Package.\ get_license_register()[license_id].isopen() except KeyError: c.package['isopen'] = False # TODO: find a nicer way of doing this c.datastore_api = '%s/api/action' % \ config.get('ckan.site_url', '').rstrip('/') #deprecated #c.related_count = c.pkg.related_count c.resource['can_be_previewed'] = self._resource_preview( {'resource': c.resource, 'package': c.package}) resource_views = get_action('resource_view_list')( context, {'id': resource_id}) c.resource['has_views'] = len(resource_views) > 0 current_resource_view = None view_id = request.GET.get('view_id') if c.resource['can_be_previewed'] and not view_id: current_resource_view = None elif c.resource['has_views']: if view_id: current_resource_view = [rv for rv in resource_views if rv['id'] == view_id] if len(current_resource_view) == 1: current_resource_view = current_resource_view[0] else: abort(404, _('Resource view not found')) else: current_resource_view = resource_views[0] vars = {'resource_views': resource_views, 'current_resource_view': current_resource_view, 'dataset_type': dataset_type} template = self._resource_template(dataset_type) return render(template, extra_vars=vars)
def resource_view(self, id, resource_id, view_id=None): custom_base.g_analitics() ''' Embedded page for a resource view. Depending on the type, different views are loaded. This could be an img tag where the image is loaded directly or an iframe that embeds a webpage or a recline preview. ''' context = {'model': model, 'session': model.Session, 'user': c.user or c.author, 'auth_user_obj': c.userobj} try: package = get_action('package_show')(context, {'id': id}) except NotFound: abort(404, _('Dataset not found')) except NotAuthorized: abort(401, _('Unauthorized to read dataset %s') % id) try: resource = get_action('resource_show')( context, {'id': resource_id}) # removes the host to make it relative if config.get('ckan.upload_file_url'): url = resource['url'] if config.get('ckan.upload_file_url') in url: url = url.split(config.get('ckan.upload_file_url')) resource['url'] = url[1] except NotFound: abort(404, _('Resource not found')) except NotAuthorized: abort(401, _('Unauthorized to read resource %s') % resource_id) view = None if request.params.get('resource_view', ''): try: view = json.loads(request.params.get('resource_view', '')) except ValueError: abort(409, _('Bad resource view data')) elif view_id: try: view = get_action('resource_view_show')( context, {'id': view_id}) except NotFound: abort(404, _('Resource view not found')) except NotAuthorized: abort(401, _('Unauthorized to read resource view %s') % view_id) if not view or not isinstance(view, dict): abort(404, _('Resource view not supplied')) return h.rendered_resource_view(view, resource, package, embed=True)
def new_resource(self, id, data=None, errors=None, error_summary=None): custom_base.g_analitics() ''' FIXME: This is a temporary action to allow styling of the forms. ''' if request.method == 'POST' and not data: #check against csrf attacks custom_base.csrf_check(self) save_action = request.params.get('save') data = data or \ clean_dict(dict_fns.unflatten(tuplize_dict(parse_params( request.POST)))) # we don't want to include save as it is part of the form del data['save'] resource_id = data['id'] del data['id'] context = {'model': model, 'session': model.Session, 'user': c.user or c.author, 'auth_user_obj': c.userobj} # see if we have any data that we are trying to save data_provided = False for key, value in data.iteritems(): if ((value or isinstance(value, cgi.FieldStorage)) and key != 'resource_type'): data_provided = True break if not data_provided and save_action != "go-dataset-complete": if save_action == 'go-dataset': # go to final stage of adddataset redirect(h.url_for(controller='package', action='edit', id=id)) # see if we have added any resources try: data_dict = get_action('package_show')(context, {'id': id}) except NotAuthorized: abort(401, _('Unauthorized to update dataset')) except NotFound: abort(404, _('The dataset {id} could not be found.' ).format(id=id)) if not len(data_dict['resources']): # no data so keep on page msg = _('You must add at least one data resource') # On new templates do not use flash message if g.legacy_templates: h.flash_error(msg) redirect(h.url_for(controller='package', action='new_resource', id=id)) else: errors = {} error_summary = {_('Error'): msg} return self.new_resource(id, data, errors, error_summary) # XXX race condition if another user edits/deletes data_dict = get_action('package_show')(context, {'id': id}) get_action('package_update')( dict(context, allow_state_change=True), dict(data_dict, state='active')) redirect(h.url_for(controller='package', action='read', id=id)) data['package_id'] = id try: if resource_id: data['id'] = resource_id get_action('resource_update')(context, data) else: get_action('resource_create')(context, data) except ValidationError, e: errors = e.error_dict error_summary = e.error_summary return self.new_resource(id, data, errors, error_summary) except NotAuthorized: abort(401, _('Unauthorized to create a resource'))
def search(self): custom_base.g_analitics() from ckan.lib.search import SearchError package_type = self._guess_package_type() try: context = {'model': model, 'user': c.user or c.author, 'auth_user_obj': c.userobj} check_access('site_read', context) except NotAuthorized: abort(401, _('Not authorized to see this page')) # unicode format (decoded from utf8) q = c.q = request.params.get('q', u'') c.query_error = False page = self._get_page_number(request.params) limit = g.datasets_per_page # most search operations should reset the page counter: params_nopage = [(k, v) for k, v in request.params.items() if k != 'page'] def drill_down_url(alternative_url=None, **by): return h.add_url_param(alternative_url=alternative_url, controller='package', action='search', new_params=by) c.drill_down_url = drill_down_url def remove_field(key, value=None, replace=None): return h.remove_url_param(key, value=value, replace=replace, controller='package', action='search') c.remove_field = remove_field sort_by = request.params.get('sort', None) params_nosort = [(k, v) for k, v in params_nopage if k != 'sort'] def _sort_by(fields): """ Sort by the given list of fields. Each entry in the list is a 2-tuple: (fieldname, sort_order) eg - [('metadata_modified', 'desc'), ('name', 'asc')] If fields is empty, then the default ordering is used. """ params = params_nosort[:] if fields: sort_string = ', '.join('%s %s' % f for f in fields) params.append(('sort', sort_string)) return search_url(params, package_type) c.sort_by = _sort_by if not sort_by: c.sort_by_fields = [] else: c.sort_by_fields = [field.split()[0] for field in sort_by.split(',')] def pager_url(q=None, page=None): params = list(params_nopage) params.append(('page', page)) return search_url(params, package_type) c.search_url_params = urlencode(_encode_params(params_nopage)) try: c.fields = [] # c.fields_grouped will contain a dict of params containing # a list of values eg {'tags':['tag1', 'tag2']} c.fields_grouped = {} search_extras = {} fq = '' for (param, value) in request.params.items(): if param not in ['q', 'page', 'sort'] \ and len(value) and not param.startswith('_'): if not param.startswith('ext_'): c.fields.append((param, value)) fq += ' %s:"%s"' % (param, value) if param not in c.fields_grouped: c.fields_grouped[param] = [value] else: c.fields_grouped[param].append(value) else: search_extras[param] = value context = {'model': model, 'session': model.Session, 'user': c.user or c.author, 'for_view': True, 'auth_user_obj': c.userobj} if package_type and package_type != 'dataset': # Only show datasets of this particular type fq += ' +dataset_type:{type}'.format(type=package_type) else: # Unless changed via config options, don't show non standard # dataset types on the default search page if not asbool( config.get('ckan.search.show_all_types', 'False')): fq += ' +dataset_type:dataset' facets = OrderedDict() default_facet_titles = { 'organization': _('Organizations'), # 'groups': _('Groups'), 'tags': _('Tags'), 'res_format': _('Formats'), 'license_id': _('Licenses'), } #remove the group facet from search if 'groups' in g.facets: g.facets.remove('groups') for facet in g.facets: if facet in default_facet_titles: facets[facet] = default_facet_titles[facet] else: facets[facet] = facet # Facet titles for plugin in p.PluginImplementations(p.IFacets): facets = plugin.dataset_facets(facets, package_type) c.facet_titles = facets data_dict = { 'q': q, 'fq': fq.strip(), 'facet.field': facets.keys(), 'rows': limit, 'start': (page - 1) * limit, 'sort': sort_by, 'extras': search_extras } query = get_action('package_search')(context, data_dict) c.sort_by_selected = query['sort'] c.page = h.Page( collection=query['results'], page=page, url=pager_url, item_count=query['count'], items_per_page=limit ) c.facets = query['facets'] c.search_facets = query['search_facets'] c.page.items = query['results'] except SearchError, se: log.error('Dataset search error: %r', se.args) c.query_error = True c.facets = {} c.search_facets = {} c.page = h.Page(collection=[])
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')) # 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) 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 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')) # 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 resource_read(self, id, resource_id): custom_base.g_analitics() context = {'model': model, 'session': model.Session, 'user': c.user or c.author, 'auth_user_obj': c.userobj, 'for_view': True} try: c.package = get_action('package_show')(context, {'id': id}) except NotFound: abort(404, _('Dataset not found')) except NotAuthorized: abort(401, _('Unauthorized to read dataset %s') % id) c.upload_file_url = config.get('ckan.upload_file_url') c.upload_file_url_sec = config.get('ckan.upload_file_url_sec') for resource in c.package.get('resources', []): if resource['id'] == resource_id: url = resource['url'] # check if the resource is local and can be previewed if 'dataset' in url: resource['is_local_resource'] = True else: resource['is_local_resource'] = False # removes the host to make it relative if config.get('ckan.upload_file_url'): if config.get('ckan.upload_file_url') in url: url = url.split(config.get('ckan.upload_file_url')) resource['url'] = url[1] if config.get('ckan.upload_file_url_sec') in url: url = url.split(config.get('ckan.upload_file_url_sec')) resource['url'] = url[1] # resource['url'] = url[1] c.resource = resource break if not c.resource: abort(404, _('Resource not found')) # required for nav menu c.pkg = context['package'] c.pkg_dict = c.package dataset_type = c.pkg.type or 'dataset' # get package license info license_id = c.package.get('license_id') try: c.package['isopen'] = model.Package.\ get_license_register()[license_id].isopen() except KeyError: c.package['isopen'] = False # TODO: find a nicer way of doing this c.datastore_api = '%s/api/action' % \ config.get('ckan.site_url', '').rstrip('/') c.related_count = c.pkg.related_count c.resource['can_be_previewed'] = self._resource_preview( {'resource': c.resource, 'package': c.package}) resource_views = get_action('resource_view_list')( context, {'id': resource_id}) c.resource['has_views'] = len(resource_views) > 0 current_resource_view = None view_id = request.GET.get('view_id') if c.resource['can_be_previewed'] and not view_id: current_resource_view = None elif c.resource['has_views']: if view_id: current_resource_view = [rv for rv in resource_views if rv['id'] == view_id] if len(current_resource_view) == 1: current_resource_view = current_resource_view[0] else: abort(404, _('Resource view not found')) else: current_resource_view = resource_views[0] vars = {'resource_views': resource_views, 'current_resource_view': current_resource_view, 'dataset_type': dataset_type} template = self._resource_template(dataset_type) return render(template, extra_vars=vars)
def new_resource(self, id, data=None, errors=None, error_summary=None): custom_base.g_analitics() ''' FIXME: This is a temporary action to allow styling of the forms. ''' if request.method == 'POST' and not data: #check against csrf attacks custom_base.csrf_check(self) save_action = request.params.get('save') data = data or \ clean_dict(dict_fns.unflatten(tuplize_dict(parse_params( request.POST)))) # we don't want to include save as it is part of the form del data['save'] resource_id = data['id'] del data['id'] context = {'model': model, 'session': model.Session, 'user': c.user or c.author, 'auth_user_obj': c.userobj} # see if we have any data that we are trying to save data_provided = False for key, value in data.iteritems(): if ((value or isinstance(value, cgi.FieldStorage)) and key != 'resource_type'): data_provided = True break if not data_provided and save_action != "go-dataset-complete": if save_action == 'go-dataset': # go to final stage of adddataset h.redirect_to(controller='package', action='edit', id=id) # see if we have added any resources try: data_dict = get_action('package_show')(context, {'id': id}) except NotAuthorized: abort(401, _('Unauthorized to update dataset')) except NotFound: abort(404, _('The dataset {id} could not be found.' ).format(id=id)) if not len(data_dict['resources']): # no data so keep on page msg = _('You must add at least one data resource') # On new templates do not use flash message if g.legacy_templates: h.flash_error(msg) h.redirect_to(controller='package', action='new_resource', id=id) else: errors = {} error_summary = {_('Error'): msg} return self.new_resource(id, data, errors, error_summary) # XXX race condition if another user edits/deletes data_dict = get_action('package_show')(context, {'id': id}) get_action('package_update')( dict(context, allow_state_change=True), dict(data_dict, state='active')) h.redirect_to(controller='package', action='read', id=id) data['package_id'] = id try: if resource_id: data['id'] = resource_id get_action('resource_update')(context, data) else: get_action('resource_create')(context, data) except ValidationError, e: errors = e.error_dict error_summary = e.error_summary return self.new_resource(id, data, errors, error_summary) except NotAuthorized: abort(401, _('Unauthorized to create a resource'))
def search(self): custom_base.g_analitics() from ckan.lib.search import SearchError, SearchQueryError package_type = self._guess_package_type() try: context = {'model': model, 'user': c.user, 'auth_user_obj': c.userobj} check_access('site_read', context) except NotAuthorized: abort(403, _('Not authorized to see this page')) # unicode format (decoded from utf8) q = c.q = request.params.get('q', u'') c.query_error = False page = h.get_page_number(request.params) limit = int(config.get('ckan.datasets_per_page', 20)) # most search operations should reset the page counter: params_nopage = [(k, v) for k, v in request.params.items() if k != 'page'] def drill_down_url(alternative_url=None, **by): return h.add_url_param(alternative_url=alternative_url, controller='package', action='search', new_params=by) c.drill_down_url = drill_down_url def remove_field(key, value=None, replace=None): return h.remove_url_param(key, value=value, replace=replace, controller='package', action='search') c.remove_field = remove_field sort_by = request.params.get('sort', None) params_nosort = [(k, v) for k, v in params_nopage if k != 'sort'] def _sort_by(fields): """ Sort by the given list of fields. Each entry in the list is a 2-tuple: (fieldname, sort_order) eg - [('metadata_modified', 'desc'), ('name', 'asc')] If fields is empty, then the default ordering is used. """ params = params_nosort[:] if fields: sort_string = ', '.join('%s %s' % f for f in fields) params.append(('sort', sort_string)) return search_url(params, package_type) c.sort_by = _sort_by if not sort_by: c.sort_by_fields = [] else: c.sort_by_fields = [field.split()[0] for field in sort_by.split(',')] def pager_url(q=None, page=None): params = list(params_nopage) params.append(('page', page)) return search_url(params, package_type) c.search_url_params = urlencode(_encode_params(params_nopage)) try: c.fields = [] # c.fields_grouped will contain a dict of params containing # a list of values eg {'tags':['tag1', 'tag2']} c.fields_grouped = {} search_extras = {} fq = '' for (param, value) in request.params.items(): if param not in ['q', 'page', 'sort'] \ and len(value) and not param.startswith('_'): if not param.startswith('ext_'): c.fields.append((param, value)) fq += ' %s:"%s"' % (param, value) if param not in c.fields_grouped: c.fields_grouped[param] = [value] else: c.fields_grouped[param].append(value) else: search_extras[param] = value context = {'model': model, 'session': model.Session, 'user': c.user, 'for_view': True, 'auth_user_obj': c.userobj} if package_type and package_type != 'dataset': # Only show datasets of this particular type fq += ' +dataset_type:{type}'.format(type=package_type) else: # Unless changed via config options, don't show non standard # dataset types on the default search page if not asbool( config.get('ckan.search.show_all_types', 'False')): fq += ' +dataset_type:dataset' facets = OrderedDict() default_facet_titles = { 'organization': _('Organizations'), 'groups': _('Groups'), 'tags': _('Tags'), 'res_format': _('Formats'), 'license_id': _('Licenses'), } for facet in h.facets(): if facet in default_facet_titles: facets[facet] = default_facet_titles[facet] else: facets[facet] = facet # Facet titles for plugin in p.PluginImplementations(p.IFacets): facets = plugin.dataset_facets(facets, package_type) c.facet_titles = facets data_dict = { 'q': q, 'fq': fq.strip(), 'facet.field': facets.keys(), 'rows': limit, 'start': (page - 1) * limit, 'sort': sort_by, 'extras': search_extras, 'include_private': asbool(config.get( 'ckan.search.default_include_private', True)), } query = get_action('package_search')(context, data_dict) c.sort_by_selected = query['sort'] c.page = h.Page( collection=query['results'], page=page, url=pager_url, item_count=query['count'], items_per_page=limit ) c.search_facets = query['search_facets'] c.page.items = query['results'] except SearchQueryError, se: # User's search parameters are invalid, in such a way that is not # achievable with the web interface, so return a proper error to # discourage spiders which are the main cause of this. log.info('Dataset search query rejected: %r', se.args) abort(400, _('Invalid search query: {error_message}') .format(error_message=str(se)))
def index(self): custom_base.g_analitics() group_type = self._guess_group_type() page = self._get_page_number(request.params) or 1 items_per_page = 21 context = { 'model': model, 'session': model.Session, 'user': c.user or c.author, 'for_view': True, 'with_private': False } q = c.q = request.params.get('q', '') sort_by = c.sort_by_selected = request.params.get('sort') # default sort by number of organization's datasets if sort_by is None: sort_by = 'package_count desc' try: self._check_access('site_read', context) except NotAuthorized: abort(401, _('Not authorized to see this page')) # pass user info to context as needed to view private datasets of # orgs correctly if c.userobj: context['user_id'] = c.userobj.id context['user_is_admin'] = c.userobj.sysadmin data_dict_global_results = { 'all_fields': False, 'q': q, 'sort': sort_by, 'type': group_type or 'group', } global_results = self._action('group_list')(context, data_dict_global_results) data_dict_page_results = { 'all_fields': True, 'q': q, 'sort': sort_by, 'type': group_type or 'group', 'limit': items_per_page, 'offset': items_per_page * (page - 1), } page_results = self._action('group_list')(context, data_dict_page_results) c.page = h.Page( collection=global_results, page=page, url=h.pager_url, items_per_page=items_per_page, ) c.page.items = page_results return render(self._index_template(group_type), extra_vars={'group_type': group_type})