doc.py 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. # -*- coding: utf-8
  2. import uuid
  3. from . import base
  4. from . import dtypes
  5. from . import format
  6. from . import terminology
  7. from .tools.doc_inherit import inherit_docstring, allow_inherit_docstring
  8. @allow_inherit_docstring
  9. class BaseDocument(base.Sectionable):
  10. """
  11. A representation of an odML document in memory.
  12. Its odml attributes are: *author*, *date*, *version* and *repository*.
  13. A Document behaves very much like a section, except that it cannot hold
  14. properties.
  15. """
  16. _format = format.Document
  17. def __init__(self, author=None, date=None, version=None, repository=None, oid=None):
  18. super(BaseDocument, self).__init__()
  19. try:
  20. if oid is not None:
  21. self._id = str(uuid.UUID(oid))
  22. else:
  23. self._id = str(uuid.uuid4())
  24. except ValueError as e:
  25. print(e)
  26. self._id = str(uuid.uuid4())
  27. self._author = author
  28. self._version = version
  29. self._repository = repository
  30. # Make sure date is properly parsed into a datetime object
  31. self._date = None
  32. self.date = date
  33. # Enable setting of the file name from whence this document came.
  34. # It is for knowing while processing and will not be serialized to a file.
  35. self._origin_file_name = None
  36. def __repr__(self):
  37. return "Document %s {author = %s, %d sections}" % \
  38. (self._version, self._author, len(self._sections))
  39. @property
  40. def oid(self):
  41. """
  42. The uuid for the document. Required for entity creation and comparison,
  43. saving and loading.
  44. """
  45. return self.id
  46. @property
  47. def id(self):
  48. """
  49. The uuid for the document.
  50. """
  51. return self._id
  52. def new_id(self, oid=None):
  53. """
  54. new_id sets the id of the current object to a RFC 4122 compliant UUID.
  55. If an id was provided, it is assigned if it is RFC 4122 UUID format compliant.
  56. If no id was provided, a new UUID is generated and assigned.
  57. :param oid: UUID string as specified in RFC 4122.
  58. """
  59. if oid is not None:
  60. self._id = str(uuid.UUID(oid))
  61. else:
  62. self._id = str(uuid.uuid4())
  63. @property
  64. def author(self):
  65. """
  66. The author of the document.
  67. """
  68. return self._author
  69. @author.setter
  70. def author(self, new_value):
  71. if new_value == "":
  72. new_value = None
  73. self._author = new_value
  74. @property
  75. def version(self):
  76. """
  77. A personal version-specifier that can be used to track different
  78. versions of the same document.
  79. """
  80. return self._version
  81. @version.setter
  82. def version(self, new_value):
  83. if new_value == "":
  84. new_value = None
  85. self._version = new_value
  86. @property
  87. def date(self):
  88. """
  89. The date the document was created.
  90. """
  91. return self._date
  92. @date.setter
  93. def date(self, new_value):
  94. if not new_value:
  95. new_value = None
  96. else:
  97. new_value = dtypes.date_set(new_value)
  98. self._date = new_value
  99. @property
  100. def parent(self):
  101. """ The parent of a document is always None. """
  102. return None
  103. def finalize(self):
  104. """
  105. This needs to be called after the document is set up from parsing
  106. it will perform additional operations, that need the complete document.
  107. In particular, this method will resolve all *link* and *include*
  108. attributes accordingly.
  109. """
  110. # We could not fill out links while parsing (referenced sections where
  111. # not known), so try to set them now, where the document is complete
  112. for sec in self.itersections(recursive=True):
  113. if sec._link is not None:
  114. sec.link = sec._link
  115. if sec._include is not None:
  116. sec.include = sec._include
  117. @inherit_docstring
  118. def get_terminology_equivalent(self):
  119. if self.repository is None:
  120. return None
  121. term = terminology.load(self.repository)
  122. return term