Repository: ckan/ckan

Issue:
create jinja versions of package/read.rdf and .n3
we were relying on the templates in legacy_templates, but since those have been removed requesting rdf and n3 versions of datasets is now broken.



Discussion:
n3 was always broken/incomplete, so we should probably wait until we've got a working template.


Resolving patch:
diff --git a/ckan/controllers/package.py b/ckan/controllers/package.py
--- 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
--- a/ckan/lib/accept.py
+++ b/ckan/lib/accept.py
@@ -9,10 +9,10 @@
 accept_re = re.compile("^(?P<ct>[^;]+)[ \t]*(;[ \t]*q=(?P<q>[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
--- 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/XML or N3 format by appending
+        .rdf or .n3 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


Test patch:
diff --git a/ckan/new_tests/controllers/test_package.py b/ckan/new_tests/controllers/test_package.py
--- a/ckan/new_tests/controllers/test_package.py
+++ b/ckan/new_tests/controllers/test_package.py
@@ -178,3 +178,35 @@ def test_inexistent_resource_view_page_returns_not_found_code(self):
 
         app = self._get_test_app()
         app.get(url, status=404)
+
+
+class TestPackageRead(helpers.FunctionalTestBase):
+    @classmethod
+    def setup_class(cls):
+        super(cls, cls).setup_class()
+        helpers.reset_db()
+
+    def setup(self):
+        model.repo.rebuild_db()
+
+    def test_read_rdf(self):
+        dataset1 = factories.Dataset()
+
+        offset = url_for(controller='package', action='read',
+                         id=dataset1['name']) + ".rdf"
+        app = self._get_test_app()
+        res = app.get(offset, status=200)
+
+        assert 'dcat' in res, res
+        assert '{{' not in res, res
+
+    def test_read_n3(self):
+        dataset1 = factories.Dataset()
+
+        offset = url_for(controller='package', action='read',
+                         id=dataset1['name']) + ".n3"
+        app = self._get_test_app()
+        res = app.get(offset, status=200)
+
+        assert 'dcat' in res, res
+        assert '{{' not in res, res
diff --git a/ckan/tests/lib/test_accept.py b/ckan/tests/lib/test_accept.py
--- 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")