Browse Source

fcr:content URI to force non-RDF content download.

Stefano Cossu 7 years ago
parent
commit
4e85ccf220

+ 13 - 4
doc/notes/fcrepo4_deltas.md

@@ -167,13 +167,22 @@ specs should not notice any difference.
 The following are improvements in performance or usability that can only be taken
 The following are improvements in performance or usability that can only be taken
 advantage of if client code is adjusted.
 advantage of if client code is adjusted.
 
 
-### LDP-NR metadata by content negotiation
+### LDP-NR content and metadata
 
 
 FCREPO4 relies on the `/fcr:metadata` identifier to retrieve RDF metadata about
 FCREPO4 relies on the `/fcr:metadata` identifier to retrieve RDF metadata about
 an LDP-NR. LAKEsuperior supports this as a legacy option, but encourages the
 an LDP-NR. LAKEsuperior supports this as a legacy option, but encourages the
-use of content negotiation to do the same. Any request to an LDP-NR with an
-`Accept` header set to one of the supported RDF serialization formats will
-yield the RDF metadata of the resource instead of the binary contents.
+use of content negotiation to do the same while offering explicit endpoints
+for RDF and non-RDF content retrieval.
+
+Any request to an LDP-NR with an `Accept` header set to one of the supported
+RDF serialization formats will yield the RDF metadata of the resource instead
+of the binary contents.
+
+The `fcr:metadata` URI returns the RDF metadata of a LDP-NR.
+
+The `fcr:content` URI returns the non-RDF content.
+
+The two optionsabove return an HTTP error if requested for a LDP-RS.
 
 
 ### "Include" and "Omit" options for children
 ### "Include" and "Omit" options for children
 
 

+ 13 - 6
lakesuperior/endpoints/ldp.py

@@ -107,9 +107,11 @@ def log_request_end(rsp):
 
 
 @ldp.route('/<path:uid>', methods=['GET'], strict_slashes=False)
 @ldp.route('/<path:uid>', methods=['GET'], strict_slashes=False)
 @ldp.route('/', defaults={'uid': '/'}, methods=['GET'], strict_slashes=False)
 @ldp.route('/', defaults={'uid': '/'}, methods=['GET'], strict_slashes=False)
-@ldp.route('/<path:uid>/fcr:metadata', defaults={'force_rdf' : True},
+@ldp.route('/<path:uid>/fcr:metadata', defaults={'out_fmt' : 'rdf'},
+        methods=['GET'])
+@ldp.route('/<path:uid>/fcr:content', defaults={'out_fmt' : 'non_rdf'},
         methods=['GET'])
         methods=['GET'])
-def get_resource(uid, force_rdf=False):
+def get_resource(uid, out_fmt=None):
     '''
     '''
     https://www.w3.org/TR/ldp/#ldpr-HTTP_GET
     https://www.w3.org/TR/ldp/#ldpr-HTTP_GET
 
 
@@ -137,16 +139,21 @@ def get_resource(uid, force_rdf=False):
     except TombstoneError as e:
     except TombstoneError as e:
         return _tombstone_response(e, uid)
         return _tombstone_response(e, uid)
     else:
     else:
+        if out_fmt is None:
+            out_fmt = (
+                    'rdf'
+                    if isinstance(rsrc, LdpRs) or is_accept_hdr_rdf_parsable()
+                    else 'non_rdf')
         out_headers.update(_headers_from_metadata(rsrc))
         out_headers.update(_headers_from_metadata(rsrc))
         uri = g.tbox.uid_to_uri(uid)
         uri = g.tbox.uid_to_uri(uid)
-        if (
-                isinstance(rsrc, LdpRs)
-                or is_accept_hdr_rdf_parsable()
-                or force_rdf):
+        if out_fmt == 'rdf':
             ggr = g.tbox.globalize_graph(rsrc.out_graph)
             ggr = g.tbox.globalize_graph(rsrc.out_graph)
             ggr.namespace_manager = nsm
             ggr.namespace_manager = nsm
             return _negotiate_content(ggr, out_headers, uid=uid, uri=uri)
             return _negotiate_content(ggr, out_headers, uid=uid, uri=uri)
         else:
         else:
+            if not getattr(rsrc, 'filename', False):
+                return ('{} has no binary content.'.format(rsrc.uid), 404)
+
             logger.info('Streaming out binary content.')
             logger.info('Streaming out binary content.')
             rsp = make_response(send_file(
             rsp = make_response(send_file(
                     rsrc.local_path, as_attachment=True,
                     rsrc.local_path, as_attachment=True,

+ 7 - 0
lakesuperior/endpoints/templates/resource.html

@@ -23,6 +23,13 @@
 </nav>
 </nav>
 {% endblock %}
 {% endblock %}
 {% block content %}
 {% block content %}
+{% if gr[gr.identifier : nsc['rdf'].type : nsc['ldp'].NonRDFSource] %}
+<div class="pull-right">
+    <a href="{{ gr.identifier }}/fcr:content" class="btn btn-success btn-lg">
+        <span class="glyphicon glyphicon-download" aria-hidden="true"></span>
+        Download Content</a>
+</div>
+{% endif %}
 {% set created_ts = arrow.get(
 {% set created_ts = arrow.get(
     gr.value(gr.identifier, nsc['fcrepo'].created)).replace(
     gr.value(gr.identifier, nsc['fcrepo'].created)).replace(
     tzinfo='local') %}
     tzinfo='local') %}