gedcom-x 0.5.1__py3-none-any.whl → 0.5.5__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.
- {gedcom_x-0.5.1.dist-info → gedcom_x-0.5.5.dist-info}/METADATA +1 -1
- gedcom_x-0.5.5.dist-info/RECORD +43 -0
- gedcomx/Address.py +42 -11
- gedcomx/Agent.py +136 -23
- gedcomx/Attribution.py +39 -91
- gedcomx/Conclusion.py +132 -53
- gedcomx/Coverage.py +10 -0
- gedcomx/Date.py +47 -11
- gedcomx/Document.py +43 -12
- gedcomx/Event.py +24 -5
- gedcomx/EvidenceReference.py +2 -2
- gedcomx/Exceptions.py +16 -0
- gedcomx/Fact.py +73 -50
- gedcomx/Gedcom.py +40 -333
- gedcomx/Gedcom5x.py +558 -0
- gedcomx/GedcomX.py +439 -194
- gedcomx/Gender.py +27 -8
- gedcomx/Group.py +3 -3
- gedcomx/Identifier.py +192 -55
- gedcomx/Logging.py +19 -0
- gedcomx/Mutations.py +228 -0
- gedcomx/Name.py +73 -38
- gedcomx/Note.py +5 -4
- gedcomx/OnlineAccount.py +2 -2
- gedcomx/Person.py +106 -92
- gedcomx/PlaceDescription.py +39 -16
- gedcomx/PlaceReference.py +14 -15
- gedcomx/Relationship.py +35 -56
- gedcomx/Resource.py +75 -0
- gedcomx/Serialization.py +394 -30
- gedcomx/SourceCitation.py +6 -1
- gedcomx/SourceDescription.py +89 -75
- gedcomx/SourceReference.py +33 -88
- gedcomx/Subject.py +12 -10
- gedcomx/TextValue.py +2 -1
- gedcomx/Translation.py +219 -0
- gedcomx/URI.py +96 -61
- gedcomx/Zip.py +1 -0
- gedcomx/__init__.py +11 -3
- gedcom_x-0.5.1.dist-info/RECORD +0 -37
- gedcomx/_Resource.py +0 -11
- {gedcom_x-0.5.1.dist-info → gedcom_x-0.5.5.dist-info}/WHEEL +0 -0
- {gedcom_x-0.5.1.dist-info → gedcom_x-0.5.5.dist-info}/top_level.txt +0 -0
gedcomx/SourceDescription.py
CHANGED
@@ -9,18 +9,23 @@ from .Agent import Agent
|
|
9
9
|
from .Attribution import Attribution
|
10
10
|
from .Coverage import Coverage
|
11
11
|
from .Date import Date
|
12
|
-
from .Identifier import Identifier
|
12
|
+
from .Identifier import Identifier, IdentifierList
|
13
13
|
from .Note import Note
|
14
14
|
from .SourceCitation import SourceCitation
|
15
15
|
from .SourceReference import SourceReference
|
16
16
|
from .TextValue import TextValue
|
17
|
+
from .Resource import Resource, get_resource_as_dict
|
18
|
+
from .Serialization import Serialization
|
17
19
|
from .URI import URI
|
18
20
|
|
21
|
+
from collections.abc import Sized
|
22
|
+
|
19
23
|
class ResourceType(Enum):
|
20
24
|
Collection = "http://gedcomx.org/Collection"
|
21
25
|
PhysicalArtifact = "http://gedcomx.org/PhysicalArtifact"
|
22
26
|
DigitalArtifact = "http://gedcomx.org/DigitalArtifact"
|
23
27
|
Record = "http://gedcomx.org/Record"
|
28
|
+
Person = "http://gedcomx.org/Person"
|
24
29
|
|
25
30
|
@property
|
26
31
|
def description(self):
|
@@ -33,26 +38,49 @@ class ResourceType(Enum):
|
|
33
38
|
return descriptions.get(self, "No description available.")
|
34
39
|
|
35
40
|
class SourceDescription:
|
41
|
+
"""
|
42
|
+
The SourceDescription data type defines a description of a source of genealogical information.
|
43
|
+
http://gedcomx.org/v1/SourceDescription
|
44
|
+
|
45
|
+
Parameters
|
46
|
+
----------
|
47
|
+
id : str
|
48
|
+
Unique identifier for this SourceDescription.
|
49
|
+
attribution : Attribution Object
|
50
|
+
Attribution information for the Genealogy
|
51
|
+
filepath : str
|
52
|
+
Not Implimented.
|
53
|
+
description : str
|
54
|
+
Description of the Genealogy: ex. 'My Family Tree'
|
55
|
+
|
56
|
+
Raises
|
57
|
+
------
|
58
|
+
ValueError
|
59
|
+
If `id` is not a valid UUID.
|
60
|
+
"""
|
36
61
|
identifier = "http://gedcomx.org/v1/SourceDescription"
|
62
|
+
"""
|
63
|
+
Gedcom-X Specification Identifier
|
64
|
+
"""
|
37
65
|
|
38
66
|
def __init__(self, id: Optional[str] = None,
|
39
67
|
resourceType: Optional[ResourceType] = None,
|
40
68
|
citations: Optional[List[SourceCitation]] = [],
|
41
69
|
mediaType: Optional[str] = None,
|
42
70
|
about: Optional[URI] = None,
|
43
|
-
mediator: Optional[
|
44
|
-
publisher: Optional[
|
45
|
-
authors: Optional[List[
|
46
|
-
sources: List[SourceReference] =
|
47
|
-
analysis: Optional[
|
71
|
+
mediator: Optional[Resource] = None,
|
72
|
+
publisher: Optional[Resource|Agent] = None,
|
73
|
+
authors: Optional[List[Resource]] = None,
|
74
|
+
sources: Optional[List[SourceReference]] = None, # SourceReference
|
75
|
+
analysis: Optional[Resource] = None, # analysis should be of type 'Document', not specified to avoid circular import
|
48
76
|
componentOf: Optional[SourceReference] = None, # SourceReference
|
49
|
-
titles: Optional[List[TextValue]] =
|
50
|
-
notes: Optional[List[Note]] =
|
77
|
+
titles: Optional[List[TextValue]] = None,
|
78
|
+
notes: Optional[List[Note]] = None,
|
51
79
|
attribution: Optional[Attribution] = None,
|
52
|
-
rights: Optional[List[
|
53
|
-
coverage: Optional[Coverage] = None, # Coverage
|
54
|
-
descriptions: Optional[List[TextValue]] =
|
55
|
-
identifiers: Optional[
|
80
|
+
rights: Optional[List[Resource]] = [],
|
81
|
+
coverage: Optional[List[Coverage]] = None, # Coverage
|
82
|
+
descriptions: Optional[List[TextValue]] = None,
|
83
|
+
identifiers: Optional[IdentifierList] = None,
|
56
84
|
created: Optional[Date] = None,
|
57
85
|
modified: Optional[Date] = None,
|
58
86
|
published: Optional[Date] = None,
|
@@ -65,9 +93,9 @@ class SourceDescription:
|
|
65
93
|
self.mediaType = mediaType
|
66
94
|
self.about = about
|
67
95
|
self.mediator = mediator
|
68
|
-
self.
|
96
|
+
self._publisher = publisher
|
69
97
|
self.authors = authors or []
|
70
|
-
self.
|
98
|
+
self.sources = sources or []
|
71
99
|
self.analysis = analysis
|
72
100
|
self.componentOf = componentOf
|
73
101
|
self.titles = titles or []
|
@@ -76,14 +104,30 @@ class SourceDescription:
|
|
76
104
|
self.rights = rights or []
|
77
105
|
self.coverage = coverage or []
|
78
106
|
self.descriptions = descriptions or []
|
79
|
-
self.identifiers = identifiers or
|
107
|
+
self.identifiers = identifiers or IdentifierList()
|
80
108
|
self.created = created
|
81
109
|
self.modified = modified
|
82
110
|
self.published = published
|
83
111
|
self.repository = repository
|
84
112
|
self.max_note_count = max_note_count
|
85
113
|
|
86
|
-
self.
|
114
|
+
self.uri = URI(fragment=id)
|
115
|
+
|
116
|
+
@property
|
117
|
+
def publisher(self) -> Resource | Agent | None:
|
118
|
+
return self._publisher
|
119
|
+
|
120
|
+
|
121
|
+
@publisher.setter
|
122
|
+
def publisher(self, value: Resource | Agent):
|
123
|
+
if value is None:
|
124
|
+
self._publisher = None
|
125
|
+
elif isinstance(value,Resource):
|
126
|
+
self._publisher = value
|
127
|
+
elif isinstance(value,Agent):
|
128
|
+
self._publisher = value
|
129
|
+
else:
|
130
|
+
raise ValueError(f"'publisher' must be of type 'URI' or 'Agent', type: {type(value)} was provided")
|
87
131
|
|
88
132
|
def add_description(self, desccription_to_add: TextValue):
|
89
133
|
if desccription_to_add and isinstance(desccription_to_add,TextValue):
|
@@ -94,9 +138,6 @@ class SourceDescription:
|
|
94
138
|
|
95
139
|
def add_identifier(self, identifier_to_add: Identifier):
|
96
140
|
if identifier_to_add and isinstance(identifier_to_add,Identifier):
|
97
|
-
for current_identifier in self.identifiers:
|
98
|
-
if identifier_to_add == current_identifier:
|
99
|
-
return
|
100
141
|
self.identifiers.append(identifier_to_add)
|
101
142
|
|
102
143
|
def add_note(self,note_to_add: Note):
|
@@ -139,51 +180,37 @@ class SourceDescription:
|
|
139
180
|
|
140
181
|
@property
|
141
182
|
def _as_dict_(self) -> Dict[str, Any]:
|
142
|
-
|
143
|
-
if hasattr(val, '_as_dict_'):
|
144
|
-
return val._as_dict_
|
145
|
-
if isinstance(val, URI):
|
146
|
-
return val._prop_dict()
|
147
|
-
if isinstance(val, Enum):
|
148
|
-
return val.value
|
149
|
-
if isinstance(val, (str, int, float, bool)) or val is None:
|
150
|
-
return val
|
151
|
-
if isinstance(val, list):
|
152
|
-
return [_serialize(v) for v in val]
|
153
|
-
if isinstance(val, dict):
|
154
|
-
return {k: _serialize(v) for k, v in val.items()}
|
155
|
-
return str(val)
|
156
|
-
|
157
|
-
data = {
|
183
|
+
type_as_dict = {
|
158
184
|
'id': self.id,
|
185
|
+
'about': self.about._as_dict_ if self.about else None,
|
159
186
|
'resourceType': self.resourceType.value if self.resourceType else None,
|
160
187
|
'citations': [c._as_dict_ for c in self.citations] or None,
|
161
188
|
'mediaType': self.mediaType,
|
162
|
-
'
|
163
|
-
'
|
164
|
-
'
|
165
|
-
'authors': [a._prop_dict() for a in self.authors] or None,
|
189
|
+
'mediator': self.mediator._as_dict_ if self.mediator else None,
|
190
|
+
'publisher': self.publisher._as_dict_ if self.publisher else None,
|
191
|
+
'authors': self.authors and [a._as_dict_ for a in self.authors] or None,
|
166
192
|
'sources': [s._as_dict_ for s in self.sources] or None,
|
167
|
-
'analysis': self.analysis.
|
193
|
+
'analysis': self.analysis._as_dict_ if self.analysis else None,
|
168
194
|
'componentOf': self.componentOf._as_dict_ if self.componentOf else None,
|
169
|
-
'titles': [t.
|
170
|
-
'notes': [n.
|
195
|
+
'titles': [t._as_dict_ for t in self.titles] or None,
|
196
|
+
'notes': [n._as_dict_ for n in self.notes] or None,
|
171
197
|
'attribution': self.attribution._as_dict_ if self.attribution else None,
|
172
|
-
'rights': [r.
|
173
|
-
'coverage':
|
174
|
-
'descriptions': [d.
|
175
|
-
'identifiers':
|
176
|
-
'created': self.created
|
177
|
-
'modified': self.modified
|
178
|
-
'published': self.published
|
179
|
-
'repository': self.repository.
|
198
|
+
'rights': [r._as_dict_ for r in self.rights] or None,
|
199
|
+
'coverage': [c._as_dict_ for c in self.coverage] or None,
|
200
|
+
'descriptions': [d._as_dict_ for d in self.descriptions] or None,
|
201
|
+
'identifiers': self.identifiers._as_dict_ if self.identifiers else None,
|
202
|
+
'created': self.created if self.created else None,
|
203
|
+
'modified': self.modified if self.modified else None,
|
204
|
+
'published': self.published if self.published else None,
|
205
|
+
'repository': self.repository._as_dict_ if self.repository else None,
|
206
|
+
'uri': self.uri.value
|
180
207
|
}
|
181
|
-
|
182
|
-
return
|
183
|
-
|
208
|
+
|
209
|
+
return Serialization.serialize_dict(type_as_dict)
|
210
|
+
|
211
|
+
|
184
212
|
@classmethod
|
185
213
|
def _from_json_(cls, data: Dict[str, Any]) -> 'SourceDescription':
|
186
|
-
print(data,type(data))
|
187
214
|
# TODO Hande Resource/URI
|
188
215
|
|
189
216
|
# Basic fields
|
@@ -193,11 +220,11 @@ class SourceDescription:
|
|
193
220
|
# Sub-objects
|
194
221
|
citations = [SourceCitation._from_json_(c) for c in data.get('citations', [])]
|
195
222
|
about = URI._from_json_(data['about']) if data.get('about') else None
|
196
|
-
mediator =
|
197
|
-
publisher =
|
198
|
-
authors = [
|
223
|
+
mediator = Resource._from_json_(data['mediator']) if data.get('mediator') else None
|
224
|
+
publisher = Resource._from_json_(data['publisher']) if data.get('publisher') else None
|
225
|
+
authors = [Resource._from_json_(a) for a in data.get('authors', [])]
|
199
226
|
sources = [SourceReference._from_json_(s) for s in data.get('sources', [])]
|
200
|
-
analysis =
|
227
|
+
analysis = Resource._from_json_(data['analysis']) if data.get('analysis') else None
|
201
228
|
component_of = SourceReference._from_json_(data['componentOf']) if data.get('componentOf') else None
|
202
229
|
titles = [TextValue._from_json_(t) for t in data.get('titles', [])]
|
203
230
|
notes = [Note._from_json_(n) for n in data.get('notes', [])]
|
@@ -205,9 +232,10 @@ class SourceDescription:
|
|
205
232
|
rights = [URI._from_json_(r) for r in data.get('rights', [])]
|
206
233
|
coverage = [Coverage._from_json_(cvg) for cvg in data.get('coverage',[])]
|
207
234
|
descriptions = [TextValue._from_json_(d) for d in data.get('descriptions', [])]
|
208
|
-
identifiers =
|
235
|
+
identifiers = IdentifierList._from_json_(data.get('identifiers', []))
|
236
|
+
|
209
237
|
created = Date._from_json_(data['created']) if data.get('created') else None
|
210
|
-
modified =
|
238
|
+
modified = data.get('modified',None)
|
211
239
|
published = Date._from_json_(data['published']) if data.get('published') else None
|
212
240
|
repository = Agent._from_json_(data['repository']) if data.get('repository') else None
|
213
241
|
|
@@ -224,18 +252,4 @@ class SourceDescription:
|
|
224
252
|
published=published, repository=repository
|
225
253
|
)
|
226
254
|
|
227
|
-
|
228
|
-
def publisher(self) -> URI:
|
229
|
-
if not self._publisher is None or isinstance(self._publisher,URI): assert False
|
230
|
-
return self._publisher
|
231
|
-
|
232
|
-
@publisher.setter
|
233
|
-
def publisher(self, value: URI | Agent):
|
234
|
-
if value is None:
|
235
|
-
self._publisher = None
|
236
|
-
elif isinstance(value,URI):
|
237
|
-
assert False
|
238
|
-
elif isinstance(value,Agent):
|
239
|
-
self._publisher = value._uri
|
240
|
-
else:
|
241
|
-
raise ValueError(f"'publisher' must be of type 'URI' or 'Agent', type: {type(value)} was provided")
|
255
|
+
|
gedcomx/SourceReference.py
CHANGED
@@ -3,8 +3,12 @@ from typing import List, Optional
|
|
3
3
|
from .Attribution import Attribution
|
4
4
|
from .Qualifier import Qualifier
|
5
5
|
|
6
|
+
from .Resource import Resource
|
7
|
+
from .Serialization import Serialization
|
6
8
|
from .URI import URI
|
7
9
|
|
10
|
+
from collections.abc import Sized
|
11
|
+
|
8
12
|
class KnownSourceReference(Qualifier):
|
9
13
|
CharacterRegion = "http://gedcomx.org/CharacterRegion"
|
10
14
|
RectangleRegion = "http://gedcomx.org/RectangleRegion"
|
@@ -42,38 +46,29 @@ class KnownSourceReference(Qualifier):
|
|
42
46
|
class SourceReference:
|
43
47
|
identifier = 'http://gedcomx.org/v1/SourceReference'
|
44
48
|
version = 'http://gedcomx.org/conceptual-model/v1'
|
45
|
-
|
49
|
+
|
46
50
|
def __init__(self,
|
47
|
-
description: URI
|
51
|
+
description: URI | object | None = None,
|
52
|
+
descriptionId: Optional[str] = None,
|
53
|
+
attribution: Optional[Attribution] = None,
|
54
|
+
qualifiers: Optional[List[Qualifier]] = None
|
55
|
+
) -> None:
|
48
56
|
|
49
|
-
|
50
|
-
|
51
|
-
from .SourceDescription import SourceDescription
|
52
|
-
self._description_object = None
|
53
|
-
if isinstance(description,URI):
|
54
|
-
#TODO See if Local, If not try to resolve,
|
55
|
-
self._description_object = description
|
56
|
-
|
57
|
-
elif isinstance(description,SourceDescription):
|
58
|
-
self._description_object = description
|
59
|
-
if hasattr(description,'_uri'):
|
60
|
-
self.description = description._uri
|
61
|
-
else:
|
62
|
-
assert False
|
63
|
-
self.description = URI(object=description)
|
64
|
-
description._uri = self.description
|
65
|
-
description._object = description
|
66
|
-
else:
|
67
|
-
raise ValueError(f"'description' must be of type 'SourceDescription' or 'URI', type: {type(description)} was provided")
|
68
|
-
|
69
|
-
#self.description = description
|
57
|
+
self.description = description
|
70
58
|
self.descriptionId = descriptionId
|
71
59
|
self.attribution = attribution
|
72
|
-
self.qualifiers = qualifiers
|
60
|
+
self.qualifiers = qualifiers if qualifiers and isinstance(qualifiers, list) else []
|
73
61
|
|
74
62
|
def add_qualifier(self, qualifier: Qualifier):
|
75
|
-
if isinstance(qualifier, Qualifier):
|
63
|
+
if isinstance(qualifier, (Qualifier,KnownSourceReference)):
|
64
|
+
if self.qualifiers:
|
65
|
+
#TODO Prevent Duplicates
|
66
|
+
for current_qualifier in self.qualifiers:
|
67
|
+
if qualifier == current_qualifier:
|
68
|
+
return
|
76
69
|
self.qualifiers.append(qualifier)
|
70
|
+
return
|
71
|
+
raise ValueError("The 'qualifier' must be type 'Qualifier' or 'KnownSourceReference', not " + str(type(qualifier)))
|
77
72
|
|
78
73
|
def append(self, text_to_add: str):
|
79
74
|
if text_to_add and isinstance(text_to_add, str):
|
@@ -86,83 +81,33 @@ class SourceReference:
|
|
86
81
|
|
87
82
|
@property
|
88
83
|
def _as_dict_(self):
|
89
|
-
|
90
|
-
def _serialize(value):
|
91
|
-
if isinstance(value, (str, int, float, bool, type(None))):
|
92
|
-
return value
|
93
|
-
elif isinstance(value, dict):
|
94
|
-
return {k: _serialize(v) for k, v in value.items()}
|
95
|
-
elif isinstance(value, (list, tuple, set)):
|
96
|
-
return [_serialize(v) for v in value]
|
97
|
-
elif hasattr(value, "_as_dict_"):
|
98
|
-
return value._as_dict_
|
99
|
-
else:
|
100
|
-
return str(value) # fallback for unknown objects
|
101
|
-
|
102
84
|
# Only add Relationship-specific fields
|
103
|
-
|
104
|
-
'description':self.
|
85
|
+
type_as_dict = {
|
86
|
+
'description':self.description._as_dict_ if self.description else None,
|
105
87
|
'descriptionId': self.descriptionId.replace("\n"," ").replace("\r"," ") if self.descriptionId else None,
|
106
|
-
'attribution': self.attribution if self.attribution else None,
|
88
|
+
'attribution': self.attribution._as_dict_ if self.attribution else None,
|
107
89
|
'qualifiers':[qualifier.value for qualifier in self.qualifiers ] if self.qualifiers else None
|
108
90
|
}
|
91
|
+
return Serialization.serialize_dict(type_as_dict)
|
109
92
|
|
110
|
-
|
111
|
-
|
112
|
-
if value is not None:
|
113
|
-
sourcereference_fields[key] = _serialize(value)
|
114
|
-
|
115
|
-
return sourcereference_fields
|
93
|
+
|
94
|
+
|
116
95
|
|
117
96
|
@classmethod
|
118
|
-
def _from_json_(cls, data: dict):
|
119
|
-
print(data)
|
120
|
-
|
97
|
+
def _from_json_(cls, data: dict):
|
121
98
|
"""
|
122
|
-
Rehydrate a SourceReference from the dict
|
99
|
+
Rehydrate a SourceReference from the dict passed down from JSON deserialization.
|
100
|
+
NOTE: This does not resolve references to SourceDescription objects.
|
123
101
|
"""
|
124
|
-
from .
|
125
|
-
|
126
|
-
|
127
|
-
desc_json = data.get('description')
|
128
|
-
#if not desc_json:
|
129
|
-
# raise ValueError("SourceReference JSON missing 'description'")
|
130
|
-
#desc_obj = SourceDescription._from_json_(desc_json)
|
131
|
-
desc_obj = URI.from_url(data.get('description')) #TODO <--- URI Reference
|
132
|
-
|
133
|
-
|
134
|
-
# 2) Simple fields
|
135
|
-
description_id = data.get('descriptionId')
|
136
|
-
|
137
|
-
# 3) Attribution (if present)
|
138
|
-
attrib = None
|
139
|
-
if data.get('attribution') is not None:
|
140
|
-
attrib = Attribution._from_json_(data['attribution'])
|
102
|
+
from .Serialization import Serialization
|
103
|
+
return Serialization.deserialize(data, SourceReference)
|
104
|
+
|
141
105
|
|
142
|
-
# 4) Qualifiers list
|
143
|
-
raw_quals = data.get('qualifiers', [])
|
144
|
-
qualifiers: List[Qualifier] = []
|
145
|
-
for q in raw_quals:
|
146
|
-
try:
|
147
|
-
# Try the known‐source enum first
|
148
|
-
qualifiers.append(KnownSourceReference(q))
|
149
|
-
except ValueError:
|
150
|
-
# Fallback to generic Qualifier
|
151
|
-
qualifiers.append(Qualifier(q))
|
152
|
-
|
153
|
-
# 5) Instantiate via your existing __init__
|
154
|
-
inst = cls(
|
155
|
-
description=desc_obj,
|
156
|
-
descriptionId=description_id,
|
157
|
-
attribution=attrib,
|
158
|
-
qualifiers=qualifiers
|
159
|
-
)
|
160
|
-
return inst
|
161
106
|
|
162
107
|
def __eq__(self, other):
|
163
108
|
if not isinstance(other, self.__class__):
|
164
109
|
return False
|
165
110
|
|
166
111
|
return (
|
167
|
-
self.description.
|
112
|
+
self.description.uri == other.description.uri
|
168
113
|
)
|
gedcomx/Subject.py
CHANGED
@@ -4,11 +4,12 @@ from typing import List, Optional
|
|
4
4
|
from .Attribution import Attribution
|
5
5
|
from .Conclusion import Conclusion, ConfidenceLevel
|
6
6
|
from .EvidenceReference import EvidenceReference
|
7
|
-
from .Identifier import Identifier
|
7
|
+
from .Identifier import Identifier, IdentifierList
|
8
8
|
from .Note import Note
|
9
|
-
from .Serialization import
|
9
|
+
from .Serialization import Serialization
|
10
10
|
from .SourceReference import SourceReference
|
11
|
-
from .
|
11
|
+
from .Resource import Resource
|
12
|
+
from .Extensions.rs10.rsLink import _rsLinkList
|
12
13
|
|
13
14
|
class Subject(Conclusion):
|
14
15
|
identifier = 'http://gedcomx.org/v1/Subject'
|
@@ -18,22 +19,23 @@ class Subject(Conclusion):
|
|
18
19
|
id: Optional[str],
|
19
20
|
lang: Optional[str] = 'en',
|
20
21
|
sources: Optional[List[SourceReference]] = [],
|
21
|
-
analysis: Optional[
|
22
|
+
analysis: Optional[Resource] = None,
|
22
23
|
notes: Optional[List[Note]] = [],
|
23
24
|
confidence: Optional[ConfidenceLevel] = None,
|
24
25
|
attribution: Optional[Attribution] = None,
|
25
26
|
extracted: Optional[bool] = None,
|
26
27
|
evidence: Optional[List[EvidenceReference]] = [],
|
27
28
|
media: Optional[List[SourceReference]] = [],
|
28
|
-
identifiers: Optional[
|
29
|
-
uri: Optional[
|
30
|
-
|
29
|
+
identifiers: Optional[IdentifierList] = None,
|
30
|
+
uri: Optional[Resource] = None,
|
31
|
+
links: Optional[_rsLinkList] = None) -> None:
|
32
|
+
super().__init__(id, lang, sources, analysis, notes, confidence, attribution,links=links)
|
31
33
|
self.extracted = extracted
|
32
34
|
self.evidence = evidence
|
33
35
|
self.media = media
|
34
|
-
self.identifiers = identifiers
|
36
|
+
self.identifiers = identifiers if identifiers else IdentifierList()
|
37
|
+
self.uri = uri
|
35
38
|
|
36
|
-
|
37
39
|
def add_identifier(self, identifier_to_add: Identifier):
|
38
40
|
if identifier_to_add and isinstance(identifier_to_add,Identifier):
|
39
41
|
for current_identifier in self.identifiers:
|
@@ -61,7 +63,7 @@ class Subject(Conclusion):
|
|
61
63
|
"extracted": self.extracted,
|
62
64
|
"evidence": [evidence_ref for evidence_ref in self.evidence] if self.evidence else None,
|
63
65
|
"media": [media for media in self.media] if self.media else None,
|
64
|
-
"identifiers":
|
66
|
+
"identifiers": self.identifiers._as_dict_ if self.identifiers else None
|
65
67
|
|
66
68
|
})
|
67
69
|
|
gedcomx/TextValue.py
CHANGED
@@ -13,7 +13,8 @@ class TextValue:
|
|
13
13
|
raise ValueError(f"Cannot append object of type {type(value_to_append)}.")
|
14
14
|
self.value += ' ' + value_to_append
|
15
15
|
|
16
|
-
|
16
|
+
@property
|
17
|
+
def _as_dict_(self):
|
17
18
|
return {
|
18
19
|
"lang":self.lang if self.lang else None,
|
19
20
|
"value":self.value if self.value else None
|