diff --git a/ckan/config/routing.py b/ckan/config/routing.py index 96cd2071ef3..149c01bd2a7 100644 --- a/ckan/config/routing.py +++ b/ckan/config/routing.py @@ -184,6 +184,7 @@ def make_map(): 'history_ajax', ])) ) + m.connect('/dataset/{id}.{format}', action='read') m.connect('/dataset/{id}', action='read') m.connect('/dataset/{id}/resource/{resource_id}', action='resource_read') diff --git a/ckan/controllers/package.py b/ckan/controllers/package.py index ec055e6d64f..a0bc980adec 100644 --- a/ckan/controllers/package.py +++ b/ckan/controllers/package.py @@ -44,7 +44,7 @@ def search_url(params): class PackageController(BaseController): - def _package_form(self, package_type=None): + def _package_form(self, package_type=None): return lookup_package_plugin(package_type).package_form() def _form_to_db_schema(self, package_type=None): @@ -83,21 +83,21 @@ def search(self): # 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(**by): params = list(params_nopage) params.extend(by.items()) return search_url(set(params)) - - c.drill_down_url = drill_down_url - + + c.drill_down_url = drill_down_url + def remove_field(key, value): params = list(params_nopage) params.remove((key, value)) return search_url(params) c.remove_field = remove_field - + def pager_url(q=None, page=None): params = list(params_nopage) params.append(('page', page)) @@ -144,11 +144,28 @@ def pager_url(q=None, page=None): c.query_error = True c.facets = {} c.page = h.Page(collection=[]) - - return render('package/search.html') + return render('package/search.html') - def read(self, id): + def _content_type_for_format(self, fmt): + """ + Given a requested format this method determines the content-type + to set and the genshi template loader to use in order to render + it accurately. TextTemplate must be used for non-xml templates + whilst all that are some sort of XML should use MarkupTemplate. + """ + from genshi.template import MarkupTemplate, TextTemplate + types = { + "html": ("text/html; charset=utf-8", MarkupTemplate), + "rdf" : ("application/rdf+xml; charset=utf-8", MarkupTemplate), + "n3" : ("text/plain; charset=utf-8", TextTemplate), + } + if fmt in types: + return types[fmt][0], fmt, types[fmt][1] + return (types["html"][0]), "html", (types["html"][1]) + + + def read(self, id, format='html'): package_type = self._get_package_type(id.split('@')[0]) context = {'model': model, 'session': model.Session, 'user': c.user or c.author, 'extras_as_string': True, @@ -171,7 +188,7 @@ def read(self, id): abort(400, _('Invalid revision format: %r') % e.args) elif len(split) > 2: abort(400, _('Invalid revision format: %r') % 'Too many "@" symbols') - + #check if package exists try: c.pkg_dict = get_action('package_show')(context, data_dict) @@ -181,7 +198,7 @@ def read(self, id): abort(404, _('Dataset not found')) except NotAuthorized: abort(401, _('Unauthorized to read package %s') % id) - + #set a cookie so we know whether to display the welcome message c.hide_welcome_message = bool(request.cookies.get('hide_welcome_message', False)) response.set_cookie('hide_welcome_message', '1', max_age=3600) #(make cross-site?) @@ -199,13 +216,16 @@ def read(self, id): if config.get('rdf_packages'): accept_header = request.headers.get('Accept', '*/*') for content_type, exts in negotiate(autoneg_cfg, accept_header): - if "html" not in exts: + if "html" not in exts: rdf_url = '%s%s.%s' % (config['rdf_packages'], c.pkg.id, exts[0]) redirect(rdf_url, code=303) break + ctype,extension,loader = self._content_type_for_format(format) + response.headers['Content-Type'] = ctype + PackageSaver().render_package(c.pkg_dict, context) - return render('package/read.html') + return render('package/read.' + extension, loader_class=loader) def comments(self, id): package_type = self._get_package_type(id) @@ -300,11 +320,11 @@ def history(self, id): return render('package/history.html') def new(self, data=None, errors=None, error_summary=None): - + package_type = request.path.strip('/').split('/')[0] if package_type == 'group': package_type = None - + context = {'model': model, 'session': model.Session, 'user': c.user or c.author, 'extras_as_string': True, 'save': 'save' in request.params,} @@ -321,7 +341,7 @@ def new(self, data=None, errors=None, error_summary=None): data = data or clean_dict(unflatten(tuplize_dict(parse_params( request.params, ignore_keys=[CACHE_PARAMETER])))) - c.pkg_json = json.dumps(data) + c.pkg_json = json.dumps(data) errors = errors or {} error_summary = error_summary or {} @@ -438,22 +458,22 @@ def history_ajax(self, id): current_approved, approved = True, True else: current_approved = False - + data.append({'revision_id': revision['id'], 'message': revision['message'], 'timestamp': revision['timestamp'], 'author': revision['author'], 'approved': bool(revision['approved_timestamp']), 'current_approved': current_approved}) - + response.headers['Content-Type'] = 'application/json;charset=utf-8' return json.dumps(data) def _get_package_type(self, id): """ - Given the id of a package it determines the plugin to load + Given the id of a package it determines the plugin to load based on the package's type name (type). The plugin found - will be returned, or None if there is no plugin associated with + will be returned, or None if there is no plugin associated with the type. Uses a minimal context to do so. The main use of this method @@ -538,8 +558,8 @@ def _form_save_redirect(self, pkgname, action): url = url.replace('', pkgname) else: url = h.url_for(controller='package', action='read', id=pkgname) - redirect(url) - + redirect(url) + def _adjust_license_id_options(self, pkg, fs): options = fs.license_id.render_opts['options'] is_included = False @@ -574,7 +594,7 @@ def authz(self, id): def autocomplete(self): # DEPRECATED in favour of /api/2/util/dataset/autocomplete q = unicode(request.params.get('q', '')) - if not len(q): + if not len(q): return '' context = {'model': model, 'session': model.Session, diff --git a/ckan/templates/package/read.n3 b/ckan/templates/package/read.n3 new file mode 100644 index 00000000000..30d74d25844 --- /dev/null +++ b/ckan/templates/package/read.n3 @@ -0,0 +1 @@ +test \ No newline at end of file diff --git a/ckan/templates/package/read.rdf b/ckan/templates/package/read.rdf new file mode 100644 index 00000000000..d34b605416e --- /dev/null +++ b/ckan/templates/package/read.rdf @@ -0,0 +1,25 @@ + + + + ${c.pkg_dict['name']} + + ${c.pkg_dict['name']} + ${c.pkg_dict['title']} + ${c.pkg_dict['notes']} + + + + + + + + + +