ldp_nr.py 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. from rdflib import Graph
  2. from rdflib.namespace import RDF, XSD
  3. from rdflib.resource import Resource
  4. from rdflib.term import URIRef, Literal, Variable
  5. from lakesuperior.dictionaries.namespaces import ns_collection as nsc
  6. from lakesuperior.model.ldpr import Ldpr, transactional
  7. from lakesuperior.model.ldp_rs import LdpRs
  8. class LdpNr(Ldpr):
  9. '''LDP-NR (Non-RDF Source).
  10. Definition: https://www.w3.org/TR/ldp/#ldpnr
  11. '''
  12. base_types = {
  13. nsc['fcrepo'].Binary,
  14. nsc['fcrepo'].Resource,
  15. nsc['ldp'].Resource,
  16. nsc['ldp'].NonRDFSource,
  17. }
  18. @property
  19. def filename(self):
  20. return self.imr.value(nsc['ebucore'].filename)
  21. @property
  22. def local_path(self):
  23. cksum_term = self.imr.value(nsc['premis'].hasMessageDigest)
  24. cksum = str(cksum_term.identifier.replace('urn:sha1:',''))
  25. return self.nonrdfly.local_path(cksum)
  26. ## LDP METHODS ##
  27. def get(self, **kwargs):
  28. return LdpRs(self.uuid).get(**kwargs)
  29. @transactional
  30. def post(self, stream, mimetype=None, disposition=None):
  31. '''
  32. Create a new binary resource with a corresponding RDF representation.
  33. @param file (Stream) A Stream resource representing the uploaded file.
  34. '''
  35. # Persist the stream.
  36. file_uuid = self.nonrdfly.persist(stream)
  37. # Gather RDF metadata.
  38. self.provided_imr = Resource(Graph(), self.urn)
  39. for t in self.base_types:
  40. self.provided_imr.add(RDF.type, t)
  41. self._add_metadata(stream, digest=file_uuid, mimetype=mimetype,
  42. disposition=disposition)
  43. # Try to persist metadata. If it fails, delete the file.
  44. self._logger.debug('Persisting LDP-NR triples in {}'.format(self.urn))
  45. try:
  46. rsrc = self._create_rsrc()
  47. except:
  48. self.nonrdfly.delete(file_uuid)
  49. else:
  50. return rsrc
  51. def put(self, stream, **kwargs):
  52. return self.post(stream, **kwargs)
  53. ## PROTECTED METHODS ##
  54. def _add_metadata(self, stream, digest,
  55. mimetype='application/octet-stream', disposition=None):
  56. '''
  57. Add all metadata for the RDF representation of the LDP-NR.
  58. @param stream (BufferedIO) The uploaded data stream.
  59. @param mimetype (string) MIME type of the uploaded file.
  60. @param disposition (defaultdict) The `Content-Disposition` header
  61. content, parsed through `parse_rfc7240`.
  62. '''
  63. # File size.
  64. self._logger.debug('Data stream size: {}'.format(stream.limit))
  65. self.provided_imr.set(nsc['premis'].hasSize, Literal(stream.limit))
  66. # Checksum.
  67. cksum_term = URIRef('urn:sha1:{}'.format(digest))
  68. self.provided_imr.set(nsc['premis'].hasMessageDigest, cksum_term)
  69. # MIME type.
  70. self.provided_imr.set(nsc['ebucore']['hasMimeType'], Literal(mimetype))
  71. # File name.
  72. self._logger.debug('Disposition: {}'.format(disposition))
  73. try:
  74. self.provided_imr.set(nsc['ebucore']['filename'], Literal(
  75. disposition['attachment']['parameters']['filename']))
  76. except KeyError:
  77. pass