diff --git a/ckan/controllers/package.py b/ckan/controllers/package.py index 47a00438833..fea392f8bb4 100644 --- a/ckan/controllers/package.py +++ b/ckan/controllers/package.py @@ -313,10 +313,10 @@ def pager_url(q=None, page=None): extra_vars={'dataset_type': package_type}) def _content_type_from_extension(self, ext): - ct, mu, ext = accept.parse_extension(ext) + ct, ext = accept.parse_extension(ext) if not ct: - return None, None, None, - return ct, ext, (NewTextTemplate, MarkupTemplate)[mu] + return None, None + return ct, ext def _content_type_from_accept(self): """ @@ -325,8 +325,8 @@ def _content_type_from_accept(self): it accurately. TextTemplate must be used for non-xml templates whilst all that are some sort of XML should use MarkupTemplate. """ - ct, mu, ext = accept.parse_header(request.headers.get('Accept', '')) - return ct, ext, (NewTextTemplate, MarkupTemplate)[mu] + ct, ext = accept.parse_header(request.headers.get('Accept', '')) + return ct, ext def resources(self, id): package_type = self._get_package_type(id.split('@')[0]) @@ -358,16 +358,15 @@ def resources(self, id): def read(self, id, format='html'): if not format == 'html': - ctype, extension, loader = \ + 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, loader = "text/html; charset=utf-8", "html", \ - MarkupTemplate + ctype, format = "text/html; charset=utf-8", "html" else: - ctype, format, loader = self._content_type_from_accept() + ctype, format = self._content_type_from_accept() response.headers['Content-Type'] = ctype @@ -427,7 +426,7 @@ def read(self, id, format='html'): template = template[:template.index('.') + 1] + format try: - return render(template, loader_class=loader, + return render(template, extra_vars={'dataset_type': package_type}) except ckan.lib.render.TemplateNotFound: msg = _("Viewing {package_type} datasets in {format} format is " diff --git a/ckan/lib/accept.py b/ckan/lib/accept.py index 447797b4033..f6f53f2b001 100644 --- a/ckan/lib/accept.py +++ b/ckan/lib/accept.py @@ -9,10 +9,10 @@ accept_re = re.compile("^(?P[^;]+)[ \t]*(;[ \t]*q=(?P[0-9.]+)){0,1}$") accept_types = { - # Name : ContentType, Is Markup?, Extension - "text/html": ("text/html; charset=utf-8", True, 'html'), - "text/n3": ("text/n3; charset=utf-8", False, 'n3'), - "application/rdf+xml": ("application/rdf+xml; charset=utf-8", True, 'rdf'), + # Name : ContentType, Extension + "text/html": ("text/html; charset=utf-8", 'html'), + "text/n3": ("text/n3; charset=utf-8", 'n3'), + "application/rdf+xml": ("application/rdf+xml; charset=utf-8", 'rdf'), } accept_by_extension = { "rdf": "application/rdf+xml", @@ -28,7 +28,7 @@ def parse_extension(file_ext): ext = accept_by_extension.get(file_ext, None) if ext: return accept_types[ext] - return (None, None, None,) + return (None, None) def parse_header(accept_header=''): diff --git a/ckan/plugins/interfaces.py b/ckan/plugins/interfaces.py index 0b0a058e499..ff033fa0233 100644 --- a/ckan/plugins/interfaces.py +++ b/ckan/plugins/interfaces.py @@ -963,8 +963,8 @@ def read_template(self): ``'package/read.html'``. If the user requests the dataset in a format other than HTML - (CKAN supports returning datasets in RDF or N3 format by appending .rdf - or .n3 to the dataset read URL, see + (CKAN supports returning datasets in RDF format by appending .rdf + to the dataset read URL, see :doc:`/maintaining/linked-data-and-rdf`) then CKAN will try to render a template file with the same path as returned by this function, but a different filename extension, e.g. ``'package/read.rdf'``. If your diff --git a/ckan/templates/package/read.n3 b/ckan/templates/package/read.n3 new file mode 100644 index 00000000000..ca2751e7f65 --- /dev/null +++ b/ckan/templates/package/read.n3 @@ -0,0 +1,45 @@ +@prefix : . +@prefix dcat: . +@prefix dct: . +@prefix foaf: . +@prefix owl: . +@prefix rdf: . + +<{{ h.url_for(controller='package',action='read',id=c.pkg_dict['name'], qualified=True)}}> +a dcat:Dataset; + dct:description "{{c.pkg_dict['notes']}}"; + dct:identifier "{{c.pkg_dict['name']}}"; + dct:relation [ + rdf:value ""; + :label "change_note" ], + [ + rdf:value ""; + :label "definition_note" ], + [ + rdf:value ""; + :label "editorial_note" ], + [ + rdf:value ""; + :label "example_note" ], + [ + rdf:value ""; + :label "history_note" ], + [ + rdf:value ""; + :label "scope_note" ], + [ + rdf:value ""; + :label "skos_note" ], + [ + rdf:value ""; + :label "temporal_granularity" ], + [ + rdf:value ""; + :label "type_of_dataset" ], + [ + rdf:value ""; + :label "update_frequency" ]; + dct:title "{{c.pkg_dict['title']}}"; + :label "{{c.pkg_dict['name']}}"; + = ; + foaf:homepage <{{ h.url_for(controller='package',action='read',id=c.pkg_dict['name'], qualified=True)}}> . \ 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..a080454c80e --- /dev/null +++ b/ckan/templates/package/read.rdf @@ -0,0 +1,72 @@ + + + + + {{c.pkg_dict['notes']}} + {% for tag_dict in c.pkg_dict['tags'] %} + {{ tag_dict["name"] }} + {% endfor %} + + {{c.pkg_dict['name']}} + + {{c.pkg_dict['name']}} + {{c.pkg_dict['title']}} + {% for rsc_dict in c.pkg_dict['resources'] %} + + + + {% if rsc_dict.get('format')%} + + + {{rsc_dict.get('format')}} + {{rsc_dict.get('format')}} + + + {% endif %} + {% if rsc_dict.get('name')%}{{rsc_dict.get('name')}}{% endif %} + + + {% endfor %} + {% if c.pkg_dict.get('author', None) %} + + + {{ c.pkg_dict['author'] }} + {% if c.pkg_dict.get('maintainer_email', None)%} + + {% endif %} + + + {% endif %} + {% if c.pkg_dict.get('maintainer', None)%} + + + {{ c.pkg_dict['maintainer'] }} + {% if c.pkg_dict.get('maintainer_email', None) %} + + {% endif %} + + + {% endif %} + + {% if c.pkg_dict.get('license_url', None) %} + + {% endif %} + + {% for extra_dict in c.pkg_dict.get('extras',None) %} + + + {{extra_dict.get('key','')}} + {{extra_dict.get('value','')}} + + + {% endfor %} + + \ No newline at end of file diff --git a/ckan/tests/functional/test_package.py b/ckan/tests/functional/test_package.py index 12a1a5a7239..31ae40556b6 100644 --- a/ckan/tests/functional/test_package.py +++ b/ckan/tests/functional/test_package.py @@ -238,6 +238,18 @@ def check_link(res, controller, id): assert 'decoy' not in res, res assert 'decoy"' not in res, res + def test_read_rdf(self): + name = 'annakarenina' + offset = url_for(controller='package', action='read', id=name) + ".rdf" + res = self.app.get(offset, status=200) + assert 'dcat' in res, res + + def test_read_n3(self): + name = 'annakarenina' + offset = url_for(controller='package', action='read', id=name) + ".n3" + res = self.app.get(offset, status=200) + assert 'dcat' in res, res + def test_read_plugin_hook(self): plugins.load('test_package_controller_plugin') plugin = plugins.get_plugin('test_package_controller_plugin') diff --git a/ckan/tests/lib/test_accept.py b/ckan/tests/lib/test_accept.py index 13c065e4b8c..68fc4dd1831 100644 --- a/ckan/tests/lib/test_accept.py +++ b/ckan/tests/lib/test_accept.py @@ -4,55 +4,47 @@ class TestAccept: def test_accept_invalid(self): - ct, markup, ext = accept.parse_header(None) + ct, ext = accept.parse_header(None) assert_equal( ct, "text/html; charset=utf-8") - assert_equal( markup, True) assert_equal( ext, "html") def test_accept_invalid2(self): - ct, markup, ext = accept.parse_header("") + ct, ext = accept.parse_header("") assert_equal( ct, "text/html; charset=utf-8") - assert_equal( markup, True) assert_equal( ext, "html") def test_accept_invalid3(self): - ct, markup, ext = accept.parse_header("wombles") + ct, ext = accept.parse_header("wombles") assert_equal( ct, "text/html; charset=utf-8") - assert_equal( markup, True) assert_equal( ext, "html") def test_accept_valid(self): a = "text/turtle,application/turtle,application/rdf+xml,text/plain;q=0.8,*/*;q=.5" - ct, markup, ext = accept.parse_header(a) + ct, ext = accept.parse_header(a) assert_equal( ct, "application/rdf+xml; charset=utf-8") - assert_equal( markup, True) assert_equal( ext, "rdf") def test_accept_valid2(self): a = "text/turtle,application/turtle,application/rdf+xml;q=0.9,text/plain;q=0.8,*/*;q=.5" - ct, markup, ext = accept.parse_header(a) + ct, ext = accept.parse_header(a) assert_equal( ct, "application/rdf+xml; charset=utf-8") - assert_equal( markup, True) assert_equal( ext, "rdf") def test_accept_valid4(self): a = "application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5" - ct, markup, ext = accept.parse_header(a) + ct, ext = accept.parse_header(a) assert_equal( ct, "text/html; charset=utf-8") - assert_equal( markup, True) assert_equal( ext, "html") def test_accept_valid5(self): a = "application/rdf+xml;q=0.5,application/xhtml+xml,text/html;q=0.9" - ct, markup, ext = accept.parse_header(a) + ct, ext = accept.parse_header(a) assert_equal( ct, "text/html; charset=utf-8") - assert_equal( markup, True) assert_equal( ext, "html") def test_accept_valid6(self): a = "application/rdf+xml;q=0.9,application/xhtml+xml,text/html;q=0.5" - ct, markup, ext = accept.parse_header(a) + ct, ext = accept.parse_header(a) assert_equal( ct, "application/rdf+xml; charset=utf-8") - assert_equal( markup, True) assert_equal( ext, "rdf")