def delete(uid, soft=True): ''' Delete a resource. @param uid (string) Resource UID. @param soft (bool) Whether to perform a soft-delete and leave a tombstone resource, or wipe any memory of the resource. ''' # If referential integrity is enforced, grab all inbound relationships # to break them. refint = app_globals.rdfly.config['referential_integrity'] inbound = True if refint else inbound repr_opts = {'incl_inbound': True} if refint else {} children = app_globals.rdfly.get_descendants(uid) if soft: rsrc = LdpFactory.from_stored(uid, repr_opts) ret = rsrc.bury_rsrc(inbound) for child_uri in children: try: child_rsrc = LdpFactory.from_stored( app_globals.rdfly.uri_to_uid(child_uri), repr_opts={'incl_children': False}) except (TombstoneError, ResourceNotExistsError): continue child_rsrc.bury_rsrc(inbound, tstone_pointer=rsrc.uri) else: ret = app_globals.rdfly.forget_rsrc(uid, inbound) for child_uri in children: child_uid = app_globals.rdfly.uri_to_uid(child_uri) ret = app_globals.rdfly.forget_rsrc(child_uid, inbound) return ret
def _containment_rel(self, create): """Find the closest parent in the path indicated by the uid and establish a containment triple. Check the path-wise parent of the new resource. If it exists, add the containment relationship with this UID. Otherwise, create a container resource as the parent. This function may recurse up the path tree until an existing container is found. E.g. if only fcres:/a exists: - If ``fcres:/a/b/c/d`` is being created, a becomes container of ``fcres:/a/b/c/d``. Also, containers are created for fcres:a/b and ``fcres:/a/b/c``. - If ``fcres:/e`` is being created, the root node becomes container of ``fcres:/e``. :param bool create: Whether the resource is being created. If false, the parent container is not updated. """ from lakesuperior.model.ldp_factory import LdpFactory if '/' in self.uid.lstrip('/'): # Traverse up the hierarchy to find the parent. path_components = self.uid.lstrip('/').split('/') cnd_parent_uid = '/' + '/'.join(path_components[:-1]) if rdfly.ask_rsrc_exists(cnd_parent_uid): parent_rsrc = LdpFactory.from_stored(cnd_parent_uid) if nsc['ldp'].Container not in parent_rsrc.types: raise InvalidResourceError( cnd_parent_uid, 'Parent {} is not a container.') parent_uid = cnd_parent_uid else: parent_rsrc = LdpFactory.new_container(cnd_parent_uid) # This will trigger this method again and recurse until an # existing container or the root node is reached. parent_rsrc.create_or_replace() parent_uid = parent_rsrc.uid else: parent_uid = ROOT_UID parent_rsrc = LdpFactory.from_stored( parent_uid, repr_opts={'incl_children': False}, handling='none') # Only update parent if the resource is new. if create: add_gr = Graph() add_gr.add( (nsc['fcres'][parent_uid], nsc['ldp'].contains, self.uri)) parent_rsrc.modify(RES_UPDATED, add_trp=add_gr) # Direct or indirect container relationship. return self._add_ldp_dc_ic_rel(parent_rsrc)
def resurrect(uid): ''' Reinstate a buried (soft-deleted) resource. @param uid (string) Resource UID. ''' return LdpFactory.from_stored(uid).resurrect_rsrc()
def resurrect(uid): """ Reinstate a buried (soft-deleted) resource. :param str uid: Resource UID. """ return LdpFactory.from_stored(uid).resurrect_rsrc()
def get_metadata(uid): """ Get metadata (admin triples) of an LDPR resource. :param string uid: Resource UID. """ return LdpFactory.from_stored(uid).metadata
def patch_version(uid, ver_uid): ''' Revert to a previous version. NOTE: This creates a new version snapshot. @param uid (string) Resource UID. @param ver_uid (string) Version UID. ''' try: LdpFactory.from_stored(uid).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, uid) else: return '', 204
def exists(uid): """ Return whether a resource exists (is stored) in the repository. :param string uid: Resource UID. """ try: exists = LdpFactory.from_stored(uid).is_stored except ResourceNotExistsError: exists = False return exists
def create_version(uid, ver_uid): ''' Create a resource version. @param uid (string) Resource UID. @param ver_uid (string) Version UID to be appended to the resource URI. NOTE: this is a "slug", i.e. the version URI is not guaranteed to be the one indicated. @return string Version UID. ''' return LdpFactory.from_stored(uid).create_version(ver_uid)
def create_version(uid, ver_uid): """ Create a resource version. :param string uid: Resource UID. :param string ver_uid: Version UID to be appended to the resource URI. NOTE: this is a "slug", i.e. the version URI is not guaranteed to be the one indicated. :rtype: str :return: Version UID. """ return LdpFactory.from_stored(uid).create_version(ver_uid)
def update_delta(uid, remove_trp, add_trp): """ Update a resource graph (LDP-RS or LDP-NR) with sets of add/remove triples. A set of triples to add and/or a set of triples to remove may be provided. :param string uid: Resource UID. :param set(tuple(rdflib.term.Identifier)) remove_trp: Triples to remove, as 3-tuples of RDFLib terms. :param set(tuple(rdflib.term.Identifier)) add_trp: Triples to add, as 3-tuples of RDFLib terms. """ rsrc = LdpFactory.from_stored(uid) remove_trp = rsrc.check_mgd_terms(remove_trp) add_trp = rsrc.check_mgd_terms(add_trp) return rsrc.modify(RES_UPDATED, remove_trp, add_trp)
def update(uid, update_str, is_metadata=False): ''' Update a resource with a SPARQL-Update string. @param uid (string) Resource UID. @param update_str (string) SPARQL-Update statements. @param is_metadata (bool) Whether the resource metadata is being updated. If False, and the resource being updated is a LDP-NR, an error is raised. ''' rsrc = LdpFactory.from_stored(uid) if LDP_NR_TYPE in rsrc.ldp_types: if is_metadata: rsrc.patch_metadata(update_str) else: raise InvalidResourceError(uid) else: rsrc.patch(update_str) return rsrc
def get(uid, repr_options={}): ''' Get an LDPR resource. The resource comes preloaded with user data and metadata as indicated by the `repr_options` argument. Any further handling of this resource is done outside of a transaction. @param uid (string) Resource UID. @param repr_options (dict(bool)) Representation options. This is a dict that is unpacked downstream in the process. The default empty dict results in default values. The accepted dict keys are: - incl_inbound: include inbound references. Default: False. - incl_children: include children URIs. Default: True. - embed_children: Embed full graph of all child resources. Default: False ''' rsrc = LdpFactory.from_stored(uid, repr_options) # Load graph before leaving the transaction. rsrc.imr return rsrc
def update(uid, update_str, is_metadata=False): """ Update a resource with a SPARQL-Update string. :param string uid: Resource UID. :param string update_str: SPARQL-Update statements. :param bool is_metadata: Whether the resource metadata are being updated. :raise InvalidResourceError: If ``is_metadata`` is False and the resource being updated is a LDP-NR. """ # FCREPO is lenient here and Hyrax requires it. rsrc = LdpFactory.from_stored(uid, handling='lenient') if LDP_NR_TYPE in rsrc.ldp_types and not is_metadata: raise InvalidResourceError( 'Cannot use this method to update an LDP-NR content.') delta = rsrc.sparql_delta(update_str) rsrc.modify(RES_UPDATED, *delta) return rsrc
def _add_ldp_dc_ic_rel(self, cont_rsrc): """ Add relationship triples from a parent direct or indirect container. :param rdflib.resource.Resouce cont_rsrc: The container resource. """ cont_p = set(cont_rsrc.metadata.predicates()) logger.info('Checking direct or indirect containment.') logger.debug('Parent predicates: {}'.format(cont_p)) add_trp = {(self.uri, nsc['fcrepo'].hasParent, cont_rsrc.uri)} if self.MBR_RSRC_URI in cont_p and self.MBR_REL_URI in cont_p: from lakesuperior.model.ldp_factory import LdpFactory s = cont_rsrc.metadata.value(cont_rsrc.uri, self.MBR_RSRC_URI) p = cont_rsrc.metadata.value(cont_rsrc_uri, self.MBR_REL_URI) if cont_rsrc.metadata[RDF.type:nsc['ldp'].DirectContainer]: logger.info('Parent is a direct container.') logger.debug('Creating DC triples.') o = self.uri elif (cont_rsrc.metadata[RDF.type:nsc['ldp'].IndirectContainer] and self.INS_CNT_REL_URI in cont_p): logger.info('Parent is an indirect container.') cont_rel_uri = cont_rsrc.metadata.value( cont_rsrc.uri, self.INS_CNT_REL_URI) o = self.provided_imr.value(self.uri, cont_rel_uri) logger.debug('Target URI: {}'.format(o)) logger.debug('Creating IC triples.') target_rsrc = LdpFactory.from_stored(rdfly.uri_to_uid(s)) target_rsrc.modify(RES_UPDATED, add_trp={(s, p, o)}) return add_trp
def get_version(uid, ver_uid): ''' Get version metadata (fcr:versions). ''' return LdpFactory.from_stored(uid).get_version(ver_uid)
def get_version_info(uid): ''' Get version metadata (fcr:versions). ''' return LdpFactory.from_stored(uid).version_info