Pārlūkot izejas kodu

Revert to version (untested); inlude fcrepo:Version in server managed types.

Stefano Cossu 7 gadi atpakaļ
vecāks
revīzija
a11b763bac

+ 1 - 0
lakesuperior/dictionaries/srv_mgd_terms.py

@@ -23,6 +23,7 @@ srv_mgd_types = {
     nsc['fcrepo'].Container,
     nsc['fcrepo'].Pairtree,
     nsc['fcrepo'].Resource,
+    nsc['fcrepo'].Version,
     nsc['ldp'].BasicContainer,
     nsc['ldp'].Container,
     nsc['ldp'].DirectContainer,

+ 22 - 0
lakesuperior/endpoints/ldp.py

@@ -246,6 +246,28 @@ def post_version(uuid):
         return '', 201, {'Location': ver_uri}
 
 
+@ldp.route('/<path:uuid>/fcr:versions/<ver_uid>', methods=['PATCH'])
+def patch_version(uuid, ver_uid):
+    '''
+    Revert to a previous version.
+
+    NOTE: This creates a new version snapshot.
+
+    @param uuid (string) Resource UUID.
+    @param ver_uid (string) Version UID.
+    '''
+    try:
+        Ldpr.outbound_inst(uuid).revert_to_version(ver_uid)
+    except ResourceNotExistsError as e:
+        return str(e), 404
+    except InvalidResourceError as e:
+        return str(e), 409
+    except TombstoneError as e:
+        return _tombstone_response(e, uuid)
+    else:
+        return '', 204
+
+
 @ldp.route('/<path:uuid>', methods=['PUT'], strict_slashes=False)
 @ldp.route('/<path:uuid>/fcr:metadata', defaults={'force_rdf' : True},
         methods=['PUT'])

+ 49 - 17
lakesuperior/model/ldpr.py

@@ -369,19 +369,26 @@ class Ldpr(metaclass=ABCMeta):
 
         Internal URNs are replaced by global URIs using the endpoint webroot.
         '''
-        # Remove digest hash and version information.
-        self.imr.remove(nsc['premis'].hasMessageDigest)
-        self.imr.remove(nsc['fcrepo'].hasVersion)
-
-        if not self._imr_options.get('incl_srv_mgd', True):
-            for p in srv_mgd_predicates:
-                self._logger.debug('Removing predicate: {}'.format(p))
-                self.imr.remove(p)
-            for t in srv_mgd_types:
-                self._logger.debug('Removing type: {}'.format(t))
-                self.imr.remove(RDF.type, t)
-
-        out_gr = g.tbox.globalize_graph(self.imr.graph)
+        out_gr = Graph()
+
+        for t in self.imr.graph:
+            if (
+                # Do not include digest hash and version information.
+                t[1] in {
+                    nsc['premis'].hasMessageDigest,
+                    nsc['fcrepo'].hasVersion,
+                }
+            ) or (
+                # Do not include server managed triples if explicitily omitted.
+                not self._imr_options.get('incl_srv_mgd', True)
+                and t[1] in srv_mgd_predicates
+                or t in srv_mgd_types
+            ):
+                pass
+            else:
+                out_gr.add(t)
+
+        out_gr = self.imr.graph
         # Clear IMR because it's been pruned. In the rare case it is needed
         # after this method, it will be retrieved again.
         delattr(self, 'imr')
@@ -477,7 +484,7 @@ class Ldpr(metaclass=ABCMeta):
         This gets the RDF metadata. The binary retrieval is handled directly
         by the route.
         '''
-        return self.out_graph
+        return g.tbox.globalize_graph(self.out_graph)
 
 
     @atomic
@@ -546,13 +553,13 @@ class Ldpr(metaclass=ABCMeta):
         self.rdfly.modify_dataset(remove_trp)
 
 
-    def get_version(self, label):
+    def get_version(self, ver_uid):
         '''
         Get a version by label.
         '''
-        ver_graph = self.rdfly.get_version(self.urn, label)
+        ver_gr = self.rdfly.get_version(self.urn, ver_uid)
 
-        return g.tbox.globalize_graph(ver_graph)
+        return g.tbox.globalize_graph(ver_gr)
 
 
     @atomic
@@ -618,6 +625,31 @@ class Ldpr(metaclass=ABCMeta):
         return g.tbox.uuid_to_uri(ver_uuid)
 
 
+    @atomic
+    def revert_to_version(self, ver_uid):
+        '''
+        Revert to a previous version.
+
+        NOTE: this will create a new version.
+
+        @param ver_uid (string) Version UID.
+        '''
+        # Create a backup snapshot.
+        self.create_version(uuid4())
+
+        ver_gr = self.rdfly.get_version(self.urn, ver_uid)
+        revert_gr = Graph()
+        for t in ver_gr:
+            if t[1] not in srv_mgd_predicates and not(
+                t[1] == RDF.type and t[2] in srv_mgd_types
+            ):
+                revert_gr.add((self.urn, t[1], t[2]))
+
+        self.provided_imr = revert_gr.resource(self.urn)
+
+        return self._replace_rsrc()
+
+
     ## PROTECTED METHODS ##
 
     def _create_or_replace_rsrc(self, create_only=False):