logs-py 4.0.7__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (251) hide show
  1. LOGS/Auxiliary/CheckClassName.py +1075 -0
  2. LOGS/Auxiliary/Constants.py +99 -0
  3. LOGS/Auxiliary/CustomEntityClassGenerator.py +254 -0
  4. LOGS/Auxiliary/CustomFieldClassGenerator.py +115 -0
  5. LOGS/Auxiliary/CustomFieldValueTypeChecker.py +168 -0
  6. LOGS/Auxiliary/CustomSectionClassGenerator.py +113 -0
  7. LOGS/Auxiliary/CustomTypeClassGenerator.py +147 -0
  8. LOGS/Auxiliary/DateTimeConverter.py +66 -0
  9. LOGS/Auxiliary/Decorators.py +109 -0
  10. LOGS/Auxiliary/Exceptions.py +341 -0
  11. LOGS/Auxiliary/LOGSErrorResponse.py +89 -0
  12. LOGS/Auxiliary/MinimalModelGenerator.py +236 -0
  13. LOGS/Auxiliary/ParameterHelper.py +56 -0
  14. LOGS/Auxiliary/ReplaceMessage.py +13 -0
  15. LOGS/Auxiliary/Tools.py +432 -0
  16. LOGS/Auxiliary/__init__.py +15 -0
  17. LOGS/Converter/Conversion.py +248 -0
  18. LOGS/Converter/Converter.py +96 -0
  19. LOGS/Converter/ConverterParameter.py +88 -0
  20. LOGS/Converter/DateTimeRange.py +58 -0
  21. LOGS/Converter/ExportParameters.py +89 -0
  22. LOGS/Converter/__init__.py +13 -0
  23. LOGS/Entities/Attachment.py +84 -0
  24. LOGS/Entities/AttachmentMinimal.py +8 -0
  25. LOGS/Entities/AttachmentRequestParameter.py +42 -0
  26. LOGS/Entities/Attachments.py +53 -0
  27. LOGS/Entities/AutoloadFileInfo.py +12 -0
  28. LOGS/Entities/AutoloadStatusError.py +7 -0
  29. LOGS/Entities/AxisNaming.py +33 -0
  30. LOGS/Entities/AxisZoom.py +33 -0
  31. LOGS/Entities/Bridge.py +165 -0
  32. LOGS/Entities/BridgeClientInfo.py +93 -0
  33. LOGS/Entities/BridgeMinimal.py +8 -0
  34. LOGS/Entities/BridgeRequestParameter.py +49 -0
  35. LOGS/Entities/BridgeType.py +7 -0
  36. LOGS/Entities/Bridges.py +12 -0
  37. LOGS/Entities/CustomField.py +243 -0
  38. LOGS/Entities/CustomFieldMinimal.py +8 -0
  39. LOGS/Entities/CustomFieldModels.py +111 -0
  40. LOGS/Entities/CustomFieldRequestParameter.py +69 -0
  41. LOGS/Entities/CustomFieldSearchQuery.py +40 -0
  42. LOGS/Entities/CustomFields.py +12 -0
  43. LOGS/Entities/CustomType.py +212 -0
  44. LOGS/Entities/CustomTypeMinimal.py +8 -0
  45. LOGS/Entities/CustomTypeRequestParameter.py +60 -0
  46. LOGS/Entities/CustomTypeSection.py +63 -0
  47. LOGS/Entities/CustomTypes.py +12 -0
  48. LOGS/Entities/DataFormat.py +97 -0
  49. LOGS/Entities/DataFormatInstrument.py +18 -0
  50. LOGS/Entities/DataFormatInstrumentMinimal.py +8 -0
  51. LOGS/Entities/DataFormatInstrumentRequestParameter.py +17 -0
  52. LOGS/Entities/DataFormatInstruments.py +16 -0
  53. LOGS/Entities/DataFormatMinimal.py +18 -0
  54. LOGS/Entities/DataFormatRequestParameter.py +21 -0
  55. LOGS/Entities/DataFormats.py +12 -0
  56. LOGS/Entities/DataSource.py +218 -0
  57. LOGS/Entities/DataSourceConnectionStatus.py +12 -0
  58. LOGS/Entities/DataSourceMinimal.py +8 -0
  59. LOGS/Entities/DataSourceRequestParameter.py +57 -0
  60. LOGS/Entities/DataSourceStatus.py +108 -0
  61. LOGS/Entities/DataSourceStatusIterator.py +16 -0
  62. LOGS/Entities/DataSourceStatusRequestParameter.py +31 -0
  63. LOGS/Entities/DataSources.py +12 -0
  64. LOGS/Entities/Dataset.py +439 -0
  65. LOGS/Entities/DatasetBase.py +196 -0
  66. LOGS/Entities/DatasetCreator.py +148 -0
  67. LOGS/Entities/DatasetInfo.py +147 -0
  68. LOGS/Entities/DatasetMatchTypes.py +157 -0
  69. LOGS/Entities/DatasetMatching.py +196 -0
  70. LOGS/Entities/DatasetMinimal.py +8 -0
  71. LOGS/Entities/DatasetModels.py +33 -0
  72. LOGS/Entities/DatasetRequestParameter.py +92 -0
  73. LOGS/Entities/DatasetTemplate.py +23 -0
  74. LOGS/Entities/DatasetUploadParameter.py +14 -0
  75. LOGS/Entities/Datasets.py +142 -0
  76. LOGS/Entities/Datatrack.py +179 -0
  77. LOGS/Entities/DatatrackFormattedTable.py +25 -0
  78. LOGS/Entities/DatatrackGeneric.py +34 -0
  79. LOGS/Entities/DatatrackImage.py +25 -0
  80. LOGS/Entities/DatatrackNumericArray.py +30 -0
  81. LOGS/Entities/DatatrackNumericMatrix.py +98 -0
  82. LOGS/Entities/Entities.py +71 -0
  83. LOGS/Entities/EntitiesRequestParameter.py +18 -0
  84. LOGS/Entities/EntityOriginWriteModelWithId.py +15 -0
  85. LOGS/Entities/FileEntry.py +138 -0
  86. LOGS/Entities/FileExcludePattern.py +8 -0
  87. LOGS/Entities/FormatMetaData.py +56 -0
  88. LOGS/Entities/FormattedTable/DatatypeFormattedTable.py +135 -0
  89. LOGS/Entities/FormattedTable/DatatypeFormattedTableCell.py +108 -0
  90. LOGS/Entities/FormattedTable/DatatypeFormattedTableSettings.py +11 -0
  91. LOGS/Entities/FormattedTable/__init__.py +9 -0
  92. LOGS/Entities/HierarchyLeaf.py +15 -0
  93. LOGS/Entities/HierarchyNode.py +40 -0
  94. LOGS/Entities/ILiteraryTypedEntity.py +19 -0
  95. LOGS/Entities/InventoryItem.py +102 -0
  96. LOGS/Entities/InventoryItemMinimal.py +25 -0
  97. LOGS/Entities/InventoryItemRequestParameter.py +58 -0
  98. LOGS/Entities/InventoryItems.py +12 -0
  99. LOGS/Entities/LabNotebook.py +33 -0
  100. LOGS/Entities/LabNotebookEntries.py +16 -0
  101. LOGS/Entities/LabNotebookEntry.py +106 -0
  102. LOGS/Entities/LabNotebookEntryContent/BasicAttribute.py +15 -0
  103. LOGS/Entities/LabNotebookEntryContent/EntityAttribute.py +85 -0
  104. LOGS/Entities/LabNotebookEntryContent/EntryContentBlockquote.py +13 -0
  105. LOGS/Entities/LabNotebookEntryContent/EntryContentBulletList.py +17 -0
  106. LOGS/Entities/LabNotebookEntryContent/EntryContentCallout.py +40 -0
  107. LOGS/Entities/LabNotebookEntryContent/EntryContentContentPlaceholderNode.py +31 -0
  108. LOGS/Entities/LabNotebookEntryContent/EntryContentConverter.py +207 -0
  109. LOGS/Entities/LabNotebookEntryContent/EntryContentDocument.py +8 -0
  110. LOGS/Entities/LabNotebookEntryContent/EntryContentEntity.py +13 -0
  111. LOGS/Entities/LabNotebookEntryContent/EntryContentEntityMention.py +31 -0
  112. LOGS/Entities/LabNotebookEntryContent/EntryContentHeading.py +33 -0
  113. LOGS/Entities/LabNotebookEntryContent/EntryContentHorizontalRule.py +12 -0
  114. LOGS/Entities/LabNotebookEntryContent/EntryContentItem.py +37 -0
  115. LOGS/Entities/LabNotebookEntryContent/EntryContentListItem.py +49 -0
  116. LOGS/Entities/LabNotebookEntryContent/EntryContentOrderedList.py +31 -0
  117. LOGS/Entities/LabNotebookEntryContent/EntryContentParagraph.py +13 -0
  118. LOGS/Entities/LabNotebookEntryContent/EntryContentTable.py +17 -0
  119. LOGS/Entities/LabNotebookEntryContent/EntryContentTableCell.py +40 -0
  120. LOGS/Entities/LabNotebookEntryContent/EntryContentTableRow.py +8 -0
  121. LOGS/Entities/LabNotebookEntryContent/EntryContentTaskList.py +17 -0
  122. LOGS/Entities/LabNotebookEntryContent/EntryContentTaskListItem.py +31 -0
  123. LOGS/Entities/LabNotebookEntryContent/EntryContentText.py +33 -0
  124. LOGS/Entities/LabNotebookEntryContent/IEntryContentWithAttribute.py +23 -0
  125. LOGS/Entities/LabNotebookEntryContent/IEntryContentWithContent.py +38 -0
  126. LOGS/Entities/LabNotebookEntryContent/IEntryContentWithTextAttribute.py +16 -0
  127. LOGS/Entities/LabNotebookEntryContent/TextAttribute.py +46 -0
  128. LOGS/Entities/LabNotebookEntryContent/TextMarkAtributes.py +64 -0
  129. LOGS/Entities/LabNotebookEntryContent/TextMarkConverter.py +45 -0
  130. LOGS/Entities/LabNotebookEntryContent/TextMarks.py +71 -0
  131. LOGS/Entities/LabNotebookEntryContent/__init__.py +34 -0
  132. LOGS/Entities/LabNotebookEntryMinimal.py +8 -0
  133. LOGS/Entities/LabNotebookEntryRequestParameter.py +59 -0
  134. LOGS/Entities/LabNotebookExperiment.py +58 -0
  135. LOGS/Entities/LabNotebookExperimentMinimal.py +8 -0
  136. LOGS/Entities/LabNotebookExperimentRequestParameter.py +52 -0
  137. LOGS/Entities/LabNotebookExperiments.py +16 -0
  138. LOGS/Entities/LabNotebookMinimal.py +8 -0
  139. LOGS/Entities/LabNotebookModels.py +14 -0
  140. LOGS/Entities/LabNotebookRequestParameter.py +42 -0
  141. LOGS/Entities/LabNotebookTemplate.py +42 -0
  142. LOGS/Entities/LabNotebookTemplateMinimal.py +8 -0
  143. LOGS/Entities/LabNotebookTemplateRequestParameter.py +38 -0
  144. LOGS/Entities/LabNotebookTemplates.py +16 -0
  145. LOGS/Entities/LabNotebooks.py +12 -0
  146. LOGS/Entities/Method.py +66 -0
  147. LOGS/Entities/MethodMinimal.py +8 -0
  148. LOGS/Entities/MethodRequestParameter.py +16 -0
  149. LOGS/Entities/Methods.py +12 -0
  150. LOGS/Entities/Origin.py +53 -0
  151. LOGS/Entities/OriginMinimal.py +8 -0
  152. LOGS/Entities/OriginRequestParameter.py +28 -0
  153. LOGS/Entities/Origins.py +12 -0
  154. LOGS/Entities/ParserLog.py +49 -0
  155. LOGS/Entities/Permission.py +9 -0
  156. LOGS/Entities/Person.py +145 -0
  157. LOGS/Entities/PersonCategory.py +12 -0
  158. LOGS/Entities/PersonMinimal.py +8 -0
  159. LOGS/Entities/PersonRequestParameter.py +58 -0
  160. LOGS/Entities/Persons.py +12 -0
  161. LOGS/Entities/Project.py +52 -0
  162. LOGS/Entities/ProjectMinimal.py +8 -0
  163. LOGS/Entities/ProjectPersonPermission.py +102 -0
  164. LOGS/Entities/ProjectRequestParameter.py +58 -0
  165. LOGS/Entities/Projects.py +12 -0
  166. LOGS/Entities/Role.py +94 -0
  167. LOGS/Entities/RoleMinimal.py +8 -0
  168. LOGS/Entities/RoleRequestParameter.py +40 -0
  169. LOGS/Entities/Roles.py +12 -0
  170. LOGS/Entities/RunState.py +9 -0
  171. LOGS/Entities/Sample.py +53 -0
  172. LOGS/Entities/SampleMinimal.py +8 -0
  173. LOGS/Entities/SampleRequestParameter.py +54 -0
  174. LOGS/Entities/Samples.py +12 -0
  175. LOGS/Entities/SharedContent.py +87 -0
  176. LOGS/Entities/SharedContentMinimal.py +8 -0
  177. LOGS/Entities/SharedContentRequestParameter.py +38 -0
  178. LOGS/Entities/SharedContents.py +12 -0
  179. LOGS/Entities/Signature.py +60 -0
  180. LOGS/Entities/Track.py +93 -0
  181. LOGS/Entities/TrackData.py +20 -0
  182. LOGS/Entities/TrackImage.py +21 -0
  183. LOGS/Entities/TrackImageData.py +20 -0
  184. LOGS/Entities/TrackMatrix.py +28 -0
  185. LOGS/Entities/TrackMatrixData.py +22 -0
  186. LOGS/Entities/TrackSettings.py +55 -0
  187. LOGS/Entities/TrackTable.py +21 -0
  188. LOGS/Entities/TrackTableData.py +22 -0
  189. LOGS/Entities/TrackXY.py +40 -0
  190. LOGS/Entities/TrackXYComplex.py +51 -0
  191. LOGS/Entities/TrackXYComplexData.py +50 -0
  192. LOGS/Entities/TrackXYData.py +31 -0
  193. LOGS/Entities/Vendor.py +40 -0
  194. LOGS/Entities/VendorMinimal.py +8 -0
  195. LOGS/Entities/VendorRequestParameter.py +17 -0
  196. LOGS/Entities/Vendors.py +12 -0
  197. LOGS/Entities/__init__.py +118 -0
  198. LOGS/Entity/ConnectedEntity.py +170 -0
  199. LOGS/Entity/Entity.py +203 -0
  200. LOGS/Entity/EntityConnector.py +70 -0
  201. LOGS/Entity/EntityIterator.py +263 -0
  202. LOGS/Entity/EntityMinimal.py +141 -0
  203. LOGS/Entity/EntityMinimalWithIntId.py +36 -0
  204. LOGS/Entity/EntityMinimalWithStrId.py +36 -0
  205. LOGS/Entity/EntityMinimalWithType.py +47 -0
  206. LOGS/Entity/EntityRequestParameter.py +104 -0
  207. LOGS/Entity/EntitySortBy.py +69 -0
  208. LOGS/Entity/EntityWithIntId.py +26 -0
  209. LOGS/Entity/EntityWithStrId.py +26 -0
  210. LOGS/Entity/IGenericEntityOrderBy.py +55 -0
  211. LOGS/Entity/IdIterator.py +207 -0
  212. LOGS/Entity/SerializableContent.py +834 -0
  213. LOGS/Entity/__init__.py +23 -0
  214. LOGS/Interfaces/ICustomFieldValue.py +92 -0
  215. LOGS/Interfaces/ICustomSectionValue.py +161 -0
  216. LOGS/Interfaces/ICustomTypeValue.py +152 -0
  217. LOGS/Interfaces/ICustomValue.py +28 -0
  218. LOGS/Interfaces/IEntityInterface.py +7 -0
  219. LOGS/Interfaces/IEntryRecord.py +57 -0
  220. LOGS/Interfaces/IHierarchicalEntity.py +41 -0
  221. LOGS/Interfaces/IHierarchyType.py +63 -0
  222. LOGS/Interfaces/ILockableEntity.py +52 -0
  223. LOGS/Interfaces/IModificationRecord.py +56 -0
  224. LOGS/Interfaces/INamedEntity.py +25 -0
  225. LOGS/Interfaces/IOwnedEntity.py +27 -0
  226. LOGS/Interfaces/IPaginationRequest.py +11 -0
  227. LOGS/Interfaces/IPermissionedEntity.py +72 -0
  228. LOGS/Interfaces/IProjectBased.py +27 -0
  229. LOGS/Interfaces/ISessionedEntity.py +59 -0
  230. LOGS/Interfaces/ISignableEntity.py +49 -0
  231. LOGS/Interfaces/ISoftDeletable.py +28 -0
  232. LOGS/Interfaces/ITypedEntity.py +129 -0
  233. LOGS/Interfaces/IUniqueEntity.py +61 -0
  234. LOGS/Interfaces/IVersionedEntity.py +39 -0
  235. LOGS/Interfaces/__init__.py +7 -0
  236. LOGS/LOGS.py +1436 -0
  237. LOGS/LOGSConnection.py +647 -0
  238. LOGS/LOGSOptions.py +11 -0
  239. LOGS/Parameters/Color.py +92 -0
  240. LOGS/Parameters/ParameterBase.py +55 -0
  241. LOGS/Parameters/ParameterConverter.py +24 -0
  242. LOGS/Parameters/ParameterElement.py +99 -0
  243. LOGS/Parameters/ParameterList.py +52 -0
  244. LOGS/Parameters/ParameterTable.py +64 -0
  245. LOGS/Parameters/__init__.py +13 -0
  246. LOGS/ServerMetaData.py +120 -0
  247. LOGS/__init__.py +12 -0
  248. logs_py-4.0.7.dist-info/METADATA +51 -0
  249. logs_py-4.0.7.dist-info/RECORD +251 -0
  250. logs_py-4.0.7.dist-info/WHEEL +5 -0
  251. logs_py-4.0.7.dist-info/top_level.txt +1 -0
@@ -0,0 +1,23 @@
1
+ """
2
+ This package is written for the LOGS Repository.
3
+
4
+ It's objects can be used to write your own dataset parser.
5
+
6
+ License:
7
+ Permission to use this libraray and all of its contents is
8
+ strictly permitted to the Signals Company.
9
+ """
10
+
11
+ from ..Auxiliary.Exceptions import *
12
+ from .ConnectedEntity import *
13
+ from .Entity import *
14
+ from .EntityConnector import *
15
+ from .EntityIterator import *
16
+ from .EntityMinimal import *
17
+ from .EntityMinimalWithIntId import *
18
+ from .EntityMinimalWithStrId import *
19
+ from .EntityMinimalWithType import *
20
+ from .EntityRequestParameter import *
21
+ from .EntityWithIntId import *
22
+ from .EntityWithStrId import *
23
+ from .SerializableContent import *
@@ -0,0 +1,92 @@
1
+ import re
2
+ from typing import TYPE_CHECKING, Any, Optional, cast
3
+
4
+ from LOGS.Auxiliary.CustomFieldValueTypeChecker import CustomFieldValueTypeChecker
5
+ from LOGS.Auxiliary.Exceptions import EntityNotConnectedException
6
+ from LOGS.Auxiliary.Tools import Tools
7
+ from LOGS.Entities.CustomFieldModels import CustomFieldDataType, CustomFieldValueType
8
+ from LOGS.Interfaces.ICustomValue import ITypedCustomValue
9
+ from LOGS.LOGSConnection import LOGSConnection
10
+
11
+ if TYPE_CHECKING:
12
+ from LOGS.Entity.ConnectedEntity import ConnectedEntity
13
+
14
+
15
+ class ICustomFieldValue(ITypedCustomValue):
16
+ _type: CustomFieldValueType = CustomFieldValueType.CustomField
17
+ _valueTypeChecker: CustomFieldValueTypeChecker = cast(
18
+ CustomFieldValueTypeChecker, None
19
+ )
20
+ _newLineRe = re.compile(r"[\n\r\t\b\f]+")
21
+ _connection: Optional[LOGSConnection] = None
22
+
23
+ _id: Optional[int] = None
24
+ _dataType: CustomFieldDataType
25
+ _value: Optional[Any] = None
26
+ _name: Optional[str] = None
27
+
28
+ def __init__(self, ref=None, dataType: Optional[CustomFieldDataType] = None):
29
+ if not dataType:
30
+ raise Exception("Data type is not set")
31
+ self._dataType = dataType
32
+ self._setTypeChecker()
33
+ super().__init__(ref)
34
+
35
+ def _getConnection(self):
36
+ if not self._connection:
37
+ raise EntityNotConnectedException(cast("ConnectedEntity", self))
38
+ return self._connection
39
+
40
+ def _setTypeChecker(self):
41
+ self._valueTypeChecker = CustomFieldValueTypeChecker(
42
+ self._dataType, self._getConnection()
43
+ )
44
+
45
+ def _contentToString(self) -> str:
46
+ if self._valueTypeChecker._isArrayType:
47
+ v = [str(f) for f in self.value] if self.value is not None else []
48
+ t = ", ".join(v)
49
+ else:
50
+ t = str(self.value) if self.value is not None else ""
51
+ t = self._newLineRe.sub(" ", t)
52
+ return Tools.truncString(t, 100)
53
+
54
+ def __str__(self):
55
+ id = f" [{'' + self._dataType.name + ']' if self._dataType else ''}{' ID:' + str(self.id) if self.id else ''}"
56
+ return f"<{type(self).__name__}{id}>"
57
+
58
+ @property
59
+ def identifier(self):
60
+ name = (
61
+ f" '{getattr(self, 'name')}'"
62
+ if hasattr(self, "name") and getattr(self, "name")
63
+ else ""
64
+ )
65
+ return "%s(id:%s)%s" % (
66
+ type(self).__name__,
67
+ str(self.id),
68
+ name,
69
+ )
70
+
71
+ @property
72
+ def id(self) -> Optional[int]:
73
+ return self._id
74
+
75
+ @property
76
+ def dataType(self) -> Optional[CustomFieldDataType]:
77
+ return self._dataType
78
+
79
+ @property
80
+ def value(self) -> Optional[Any]:
81
+ return self._value
82
+
83
+ @value.setter
84
+ def value(self, value):
85
+ if not self._dataType:
86
+ raise Exception("Data type is not set")
87
+
88
+ self._value = self._valueTypeChecker.checkAndConvert(value, type(self).__name__)
89
+
90
+ @property
91
+ def name(self) -> Optional[str]:
92
+ return self._name
@@ -0,0 +1,161 @@
1
+ from typing import TYPE_CHECKING, Any, Dict, List, Optional, Type, Union, cast
2
+
3
+ from LOGS.Auxiliary.Tools import Tools
4
+ from LOGS.Entities.CustomFieldModels import CustomFieldValueType
5
+ from LOGS.Interfaces.ICustomFieldValue import ICustomFieldValue
6
+ from LOGS.Interfaces.ICustomValue import ITypedCustomValue
7
+
8
+ if TYPE_CHECKING:
9
+ pass
10
+
11
+
12
+ class ICustomSectionValue(ITypedCustomValue):
13
+ _noSerialize: List[str] = ["fieldNames"]
14
+
15
+ _type: CustomFieldValueType = CustomFieldValueType.CustomTypeSection
16
+ _customTypeId: int = cast(int, None)
17
+ _sectionIndex: int = cast(int, None)
18
+
19
+ _fieldNames: List[str] = []
20
+ _fieldTypes: Dict[str, Type[ICustomFieldValue]] = {}
21
+ _fieldIds: Dict[int, str] = {}
22
+ _name: Optional[str] = None
23
+
24
+ def __init__(self, ref=None):
25
+ for fieldName in self._fieldNames:
26
+ setattr(self, "_" + fieldName, self._fieldTypes[fieldName]())
27
+ super().__init__(ref)
28
+
29
+ def fromDict(self, ref) -> None:
30
+ if isinstance(ref, dict) and "content" in ref:
31
+ content = ref["content"]
32
+ del ref["content"]
33
+
34
+ super().fromDict(ref)
35
+
36
+ if content is not None:
37
+ if not isinstance(content, list):
38
+ raise ValueError(
39
+ f"Invalid content format. (Expected a 'list' got '{type(content).__name__}')"
40
+ )
41
+ for i, c in enumerate(content):
42
+ if not isinstance(c, dict):
43
+ raise ValueError(
44
+ f"Invalid content item {i} format. (Expected a 'dict' got '{type(c).__name__}')"
45
+ )
46
+ if "value" not in c:
47
+ continue
48
+ if "id" not in c:
49
+ raise ValueError(f"Content item {i} is missing the 'id' field.")
50
+ fieldId = Tools.checkAndConvert(
51
+ c["id"], int, f"content[{i}].id", allowNone=False
52
+ )
53
+ self.setField(fieldId, c["value"])
54
+
55
+ def toDict(self) -> Dict[str, Any]:
56
+ result = super().toDict()
57
+ content = []
58
+ for name in self._fieldNames:
59
+ field = self.getCustomField(name)
60
+ if field is not None:
61
+ content.append(field.toDict() if hasattr(field, "toDict") else field)
62
+ result["content"] = content
63
+ return result
64
+
65
+ @classmethod
66
+ def _generateId(cls, customTypeId: int, sectionIndex: int):
67
+ return f"{customTypeId}.{sectionIndex}"
68
+
69
+ def _getFieldNameFromId(self, fieldId: int) -> str:
70
+ if fieldId not in self._fieldIds:
71
+ raise AttributeError(f"Unknown field ID '{type(self).__name__}.{fieldId}'.")
72
+ return self._fieldIds[fieldId]
73
+
74
+ def setField(self, fieldNameOrId: Union[str, int], value):
75
+ fieldName = (
76
+ self._getFieldNameFromId(fieldNameOrId)
77
+ if isinstance(fieldNameOrId, int)
78
+ else fieldNameOrId
79
+ )
80
+
81
+ if fieldName not in self._fieldNames:
82
+ raise AttributeError(f"Unknown field '{type(self).__name__}.{fieldName}'.")
83
+ f = self.getCustomField(fieldName)
84
+ if f is not None:
85
+ f.value = value
86
+
87
+ def getField(self, fieldNameOrId: Union[str, int]):
88
+ fieldName = (
89
+ self._getFieldNameFromId(fieldNameOrId)
90
+ if isinstance(fieldNameOrId, int)
91
+ else fieldNameOrId
92
+ )
93
+
94
+ if fieldName not in self._fieldNames:
95
+ raise AttributeError(f"Unknown field '{type(self).__name__}.{fieldName}'.")
96
+ f = self.getCustomField(fieldName)
97
+ return f.value if f is not None else None
98
+
99
+ def _getCustomFieldByName(self, fieldName: str) -> Optional[ICustomFieldValue]:
100
+ return getattr(self, "_" + fieldName)
101
+
102
+ def getCustomField(self, fieldName: str) -> Optional[ICustomFieldValue]:
103
+ if fieldName not in self._fieldNames:
104
+ raise AttributeError(
105
+ f"Unknown custom field '{type(self).__name__}.{fieldName}'."
106
+ )
107
+ return self._getCustomFieldByName(fieldName)
108
+
109
+ def _contentToString(self, indentation: int = 0, hideNone: bool = False) -> str:
110
+ s = ""
111
+ for name in self._fieldNames:
112
+ field = self.getCustomField(name)
113
+ if field is not None:
114
+ content = field._contentToString()
115
+ if not content and hideNone:
116
+ continue
117
+ s += f"{self._indentationString * indentation}{name} = {content}\n"
118
+ return s
119
+
120
+ def __str__(self):
121
+ id1 = f"typeID:{self._customTypeId}" if self._customTypeId is not None else ""
122
+ id2 = f"index:{self._sectionIndex}" if self._sectionIndex is not None else ""
123
+ id = f"{id1}{' ' if id2 else ''}{id2}; " if id1 or id2 else ""
124
+ return f"<{type(self).__name__} [{id}{Tools.numberPlural('field' , len(self._fieldNames))}]>"
125
+
126
+ def customField(self, nameOrId) -> Optional[ICustomFieldValue]:
127
+ for name in self._fieldNames:
128
+ value = self._getCustomFieldByName(name)
129
+ if isinstance(nameOrId, int):
130
+ if value is not None and value.id == nameOrId:
131
+ return value
132
+ else:
133
+ if value is not None and value.name == str(nameOrId):
134
+ return value
135
+
136
+ return None
137
+
138
+ @classmethod
139
+ def getId(cls) -> str:
140
+ return cls._generateId(cls._customTypeId, cls._sectionIndex)
141
+
142
+ @property
143
+ def customFields(self) -> List[ICustomFieldValue]:
144
+ result = []
145
+ for name in self._fieldNames:
146
+ value = self._getCustomFieldByName(name)
147
+ if value is not None:
148
+ result.append(value)
149
+ return result
150
+
151
+ @property
152
+ def fieldNames(self) -> List[str]:
153
+ return self._fieldNames
154
+
155
+ @property
156
+ def name(self) -> Optional[str]:
157
+ return self._name
158
+
159
+ @name.setter
160
+ def name(self, value):
161
+ self._name = self.checkAndConvertNullable(value, str, "name")
@@ -0,0 +1,152 @@
1
+ from typing import TYPE_CHECKING, Any, Dict, List, Optional, Type, Union, cast
2
+
3
+ from LOGS.Interfaces.ICustomFieldValue import ICustomFieldValue
4
+ from LOGS.Interfaces.ICustomSectionValue import ICustomSectionValue
5
+ from LOGS.Interfaces.ICustomValue import ICustomValue
6
+
7
+ if TYPE_CHECKING:
8
+ pass
9
+
10
+
11
+ class ICustomTypeValue(ICustomValue):
12
+ _id: Optional[int] = None
13
+ _name: Optional[str] = None
14
+
15
+ _fieldNames: List[str] = []
16
+ _fieldTypes: Dict[str, Type[ICustomFieldValue]] = {}
17
+ _fieldIds: Dict[int, str] = {}
18
+
19
+ def __init__(
20
+ self,
21
+ ref=None,
22
+ ):
23
+ for fieldName in self._fieldNames:
24
+ setattr(self, "_" + fieldName, self._fieldTypes[fieldName]())
25
+ if not isinstance(ref, dict):
26
+ ref = {"content": ref}
27
+ super().__init__(ref)
28
+
29
+ def fromDict(self, ref) -> None:
30
+ if isinstance(ref, dict) and "content" in ref:
31
+ content = ref["content"]
32
+ del ref["content"]
33
+
34
+ super().fromDict(ref)
35
+
36
+ if content is not None:
37
+ if not isinstance(content, list):
38
+ raise ValueError(
39
+ f"Invalid content format. (Expected a 'list' got '{type(content).__name__}')"
40
+ )
41
+ for i, c in enumerate(content):
42
+ if not isinstance(c, dict):
43
+ raise ValueError(
44
+ f"Invalid content item {i} format. (Expected a 'dict' got '{type(c).__name__}')"
45
+ )
46
+ if "type" not in c:
47
+ raise ValueError(f"Content item {i} is missing the 'type' field.")
48
+ if c["type"] != "CustomTypeSection" or "content" not in c:
49
+ continue
50
+
51
+ s = self.getSection(i)
52
+ if s is not None:
53
+ s.override(c)
54
+
55
+ def toDict(self) -> Dict[str, Any]:
56
+ result = super().toDict()
57
+ content = []
58
+ for name in self._fieldNames:
59
+ field = self.getSection(name)
60
+ if field is not None:
61
+ content.append(field.toDict() if hasattr(field, "toDict") else field)
62
+ # print("content:", content)
63
+ return cast(Any, content)
64
+
65
+ def __str__(self):
66
+ id = f" [ID: {self.id}]" if self.id else ""
67
+ return f"<{type(self).__name__}{id}>"
68
+
69
+ def _contentToString(self, indentation: int = 0, hideNone: bool = False) -> str:
70
+ tab = self._indentationString * indentation
71
+ s = ""
72
+ for name in self._fieldNames:
73
+ section = self.getSection(name)
74
+ if not section and hideNone:
75
+ continue
76
+ content = ""
77
+ if section is not None:
78
+ content = section._contentToString(indentation + 1, hideNone=hideNone)
79
+ if not content and hideNone:
80
+ continue
81
+ s += f"{tab}{name}:\n{content}"
82
+ return s
83
+
84
+ def _getFieldNameFromId(self, fieldId: str) -> str:
85
+ if fieldId in self._fieldIds:
86
+ return self._fieldIds[fieldId]
87
+ return fieldId
88
+
89
+ def getField(self, fieldNameOrId: str):
90
+ fieldName = self._getFieldNameFromId(fieldNameOrId)
91
+
92
+ if fieldName not in self._fieldNames:
93
+ raise AttributeError(f"Unknown field '{type(self).__name__}.{fieldName}'.")
94
+ return self.getSection(fieldName)
95
+
96
+ def _getSectionByName(self, sectionName: str) -> Optional[ICustomSectionValue]:
97
+ return getattr(self, "_" + sectionName)
98
+
99
+ def getSection(
100
+ self, sectionIndexOrFieldId: Union[str, int]
101
+ ) -> Optional[ICustomSectionValue]:
102
+
103
+ if isinstance(sectionIndexOrFieldId, int):
104
+ if self.id is None:
105
+ raise ValueError(f"Section with index {sectionIndexOrFieldId} unknown")
106
+ fieldId = ICustomSectionValue._generateId(self.id, sectionIndexOrFieldId)
107
+ else:
108
+ fieldId = sectionIndexOrFieldId
109
+
110
+ fieldName = self._getFieldNameFromId(fieldId)
111
+ if fieldName not in self._fieldNames:
112
+ raise AttributeError(
113
+ f"Section with index or name '{sectionIndexOrFieldId}' unknown."
114
+ )
115
+ return self._getSectionByName(fieldName)
116
+
117
+ def printFieldValues(self, hideNone: bool = False):
118
+
119
+ s = f"{type(self).__name__}"
120
+
121
+ customFields = self.customFields
122
+ for field in customFields:
123
+ if hideNone and (field.value is None or field.value == ""):
124
+ continue
125
+ s += f"\n{self._indentationString}{field.name} [{field.id}] = {field.value}"
126
+ print(s)
127
+
128
+ def customField(self, nameOrId) -> Optional[ICustomFieldValue]:
129
+ for name in self._fieldNames:
130
+ section = self._getSectionByName(name)
131
+ if section is not None:
132
+ field = section.customField(nameOrId)
133
+ if field is not None:
134
+ return field
135
+ return None
136
+
137
+ @property
138
+ def customFields(self) -> List[ICustomFieldValue]:
139
+ result = []
140
+ for name in self._fieldNames:
141
+ section = self._getSectionByName(name)
142
+ if section is not None:
143
+ result.extend(section.customFields)
144
+ return result
145
+
146
+ @property
147
+ def id(self) -> Optional[int]:
148
+ return self._id
149
+
150
+ @property
151
+ def name(self) -> Optional[str]:
152
+ return self._name
@@ -0,0 +1,28 @@
1
+ from typing import TYPE_CHECKING, cast
2
+
3
+ from LOGS.Auxiliary.Exceptions import IllegalFieldValueException
4
+ from LOGS.Entities.CustomFieldModels import CustomFieldValueType
5
+ from LOGS.Entity.SerializableContent import SerializableContent
6
+
7
+ if TYPE_CHECKING:
8
+ pass
9
+
10
+
11
+ class ICustomValue(SerializableContent):
12
+ _indentationString: str = " "
13
+
14
+
15
+ class ITypedCustomValue(ICustomValue):
16
+ _type: CustomFieldValueType = cast(CustomFieldValueType, None)
17
+
18
+ @property
19
+ def type(self) -> CustomFieldValueType:
20
+ return self._type
21
+
22
+ @type.setter
23
+ def type(self, value):
24
+ value = self.checkAndConvert(value, CustomFieldValueType, "type")
25
+ if value != self._type:
26
+ raise IllegalFieldValueException(
27
+ self, "type", value, f"Only value '{self._type}' allowed."
28
+ )
@@ -0,0 +1,7 @@
1
+ class IEntityInterface:
2
+ def _getEntityConnection(self):
3
+ from LOGS.Entity.ConnectedEntity import ConnectedEntity
4
+
5
+ if isinstance(self, ConnectedEntity):
6
+ return self._getConnection()
7
+ return None
@@ -0,0 +1,57 @@
1
+ from dataclasses import dataclass
2
+ from datetime import datetime
3
+ from typing import TYPE_CHECKING, List, Optional
4
+
5
+ from LOGS.Auxiliary import Tools
6
+ from LOGS.Auxiliary.MinimalModelGenerator import MinimalModelGenerator
7
+ from LOGS.Interfaces.IEntityInterface import IEntityInterface
8
+
9
+ if TYPE_CHECKING:
10
+ from LOGS.Entities.PersonMinimal import PersonMinimal
11
+
12
+
13
+ @dataclass
14
+ class IEnteredOnRequest:
15
+ enteredFrom: Optional[datetime] = None
16
+ enteredTo: Optional[datetime] = None
17
+
18
+
19
+ class IEnteredByRequest:
20
+ createdByIds: Optional[List[int]]
21
+
22
+
23
+ @dataclass
24
+ class IEntryRecordRequest(IEnteredOnRequest, IEnteredByRequest):
25
+ pass
26
+
27
+
28
+ class IEnteredOn(IEntityInterface):
29
+ _enteredOn: Optional[datetime] = None
30
+
31
+ @property
32
+ def enteredOn(self) -> Optional[datetime]:
33
+ return self._enteredOn
34
+
35
+ @enteredOn.setter
36
+ def enteredOn(self, value):
37
+ self._enteredOn = Tools.checkAndConvert(
38
+ value, datetime, "enteredOn", allowNone=True
39
+ )
40
+
41
+
42
+ class IEnteredBy(IEntityInterface):
43
+ _enteredBy: Optional["PersonMinimal"] = None
44
+
45
+ @property
46
+ def enteredBy(self) -> Optional["PersonMinimal"]:
47
+ return self._enteredBy
48
+
49
+ @enteredBy.setter
50
+ def enteredBy(self, value):
51
+ self._enteredBy = MinimalModelGenerator.MinimalFromSingle(
52
+ value, "PersonMinimal", "enteredBy", connection=self._getEntityConnection()
53
+ )
54
+
55
+
56
+ class IEntryRecord(IEnteredOn, IEnteredBy):
57
+ pass
@@ -0,0 +1,41 @@
1
+ from dataclasses import dataclass
2
+ from typing import TYPE_CHECKING, List, Optional
3
+
4
+ from LOGS.Auxiliary.MinimalModelGenerator import MinimalModelGenerator
5
+ from LOGS.Interfaces.IEntityInterface import IEntityInterface
6
+
7
+ if TYPE_CHECKING:
8
+ from LOGS.Entities.InventoryItemMinimal import InventoryItemMinimal
9
+
10
+
11
+ @dataclass
12
+ class IHierarchicalEntityRequest:
13
+ childrenOfParentIds: Optional[List[int]] = None
14
+ descendantsOfIds: Optional[List[int]] = None
15
+ excludeHierarchyChildren: Optional[bool] = None
16
+ isHierarchyRoot: Optional[bool] = None
17
+
18
+
19
+ class IHierarchicalEntity(IEntityInterface):
20
+ _ancestors: Optional[List["InventoryItemMinimal"]] = None
21
+ _parent: Optional["InventoryItemMinimal"] = None
22
+
23
+ @property
24
+ def ancestors(self) -> Optional[List["InventoryItemMinimal"]]:
25
+ return self._ancestors
26
+
27
+ @ancestors.setter
28
+ def ancestors(self, value):
29
+ self._ancestors = MinimalModelGenerator.MinimalFromList(
30
+ value, "InventoryItemMinimal", "ancestors", self._getEntityConnection()
31
+ )
32
+
33
+ @property
34
+ def parent(self) -> Optional["InventoryItemMinimal"]:
35
+ return self._parent
36
+
37
+ @parent.setter
38
+ def parent(self, value):
39
+ self._parent = MinimalModelGenerator.MinimalFromSingle(
40
+ value, "InventoryItemMinimal", "parent", self._getEntityConnection()
41
+ )
@@ -0,0 +1,63 @@
1
+ from dataclasses import dataclass
2
+ from typing import TYPE_CHECKING, List, Optional
3
+
4
+ from LOGS.Auxiliary import Tools
5
+ from LOGS.Entity.EntityMinimalWithIntId import EntityMinimalWithIntId
6
+ from LOGS.Interfaces.IEntityInterface import IEntityInterface
7
+
8
+ if TYPE_CHECKING:
9
+ pass
10
+
11
+
12
+ @dataclass
13
+ class IHierarchyTypeRequest:
14
+ childrenOfParentIds: Optional[List[int]] = None
15
+ descendantsOfIds: Optional[List[int]] = None
16
+ isRoot: Optional[List[bool]] = None
17
+
18
+
19
+ class IHierarchyType(IEntityInterface):
20
+ _inventoryName: Optional[str]
21
+ _isHierarchyRoot: Optional[bool]
22
+ _rootHierarchy: Optional[EntityMinimalWithIntId]
23
+ _parentTypes: Optional[List[EntityMinimalWithIntId]]
24
+
25
+ @property
26
+ def inventoryName(self) -> Optional[str]:
27
+ return self._inventoryName
28
+
29
+ @inventoryName.setter
30
+ def inventoryName(self, value):
31
+ self._inventoryName = Tools.checkAndConvert(
32
+ value, str, "inventoryName", allowNone=True
33
+ )
34
+
35
+ @property
36
+ def isHierarchyRoot(self) -> Optional[bool]:
37
+ return self._isHierarchyRoot
38
+
39
+ @isHierarchyRoot.setter
40
+ def isHierarchyRoot(self, value):
41
+ self._isHierarchyRoot = Tools.checkAndConvert(
42
+ value, bool, "isHierarchyRoot", allowNone=True
43
+ )
44
+
45
+ @property
46
+ def rootHierarchy(self) -> Optional[EntityMinimalWithIntId]:
47
+ return self._rootHierarchy
48
+
49
+ @rootHierarchy.setter
50
+ def rootHierarchy(self, value):
51
+ self._rootHierarchy = Tools.checkAndConvert(
52
+ value, EntityMinimalWithIntId, "rootHierarchy", allowNone=True
53
+ )
54
+
55
+ @property
56
+ def parentTypes(self) -> Optional[List[EntityMinimalWithIntId]]:
57
+ return self._parentTypes
58
+
59
+ @parentTypes.setter
60
+ def parentTypes(self, value):
61
+ self._parentTypes = Tools.checkListAndConvert(
62
+ value, EntityMinimalWithIntId, "parentTypes", allowNone=True
63
+ )
@@ -0,0 +1,52 @@
1
+ from dataclasses import dataclass
2
+ from datetime import datetime
3
+ from typing import TYPE_CHECKING, List, Optional, Union
4
+
5
+ from LOGS.Auxiliary.MinimalModelGenerator import MinimalModelGenerator
6
+ from LOGS.Auxiliary.Tools import Tools
7
+ from LOGS.Interfaces.IEntityInterface import IEntityInterface
8
+
9
+ if TYPE_CHECKING:
10
+ from LOGS.Entities.PersonMinimal import PersonMinimal
11
+
12
+
13
+ @dataclass
14
+ class ILockableEntityRequest:
15
+ lockedByIds: Optional[List[int]] = None
16
+ lockedFrom: Optional[datetime] = None
17
+ lockedTo: Optional[datetime] = None
18
+ isLocked: Optional[bool] = None
19
+
20
+
21
+ class ILockableEntity(IEntityInterface):
22
+ _lockedBy: Optional["PersonMinimal"] = None
23
+ _lockedOn: Optional[datetime] = None
24
+ _isLocked: Optional[bool] = None
25
+
26
+ @property
27
+ def lockedBy(self) -> Optional["PersonMinimal"]:
28
+ return self._lockedBy
29
+
30
+ @lockedBy.setter
31
+ def lockedBy(self, value):
32
+ self._lockedBy = MinimalModelGenerator.MinimalFromSingle(
33
+ value, "PersonMinimal", "lockedBy", self._getEntityConnection()
34
+ )
35
+
36
+ @property
37
+ def lockedOn(self) -> Optional[datetime]:
38
+ return self._lockedOn
39
+
40
+ @lockedOn.setter
41
+ def lockedOn(self, value: Optional[Union[datetime, dict]]):
42
+ self._lockedOn = Tools.checkAndConvert(
43
+ value, datetime, "lockedOn", allowNone=True
44
+ )
45
+
46
+ @property
47
+ def isLocked(self) -> Optional[bool]:
48
+ return self._isLocked
49
+
50
+ @isLocked.setter
51
+ def isLocked(self, value: Optional[bool]):
52
+ self._isLocked = Tools.checkAndConvert(value, bool, "isLocked", allowNone=True)