gedcom-x 0.5__py3-none-any.whl → 0.5.2__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.dist-info → gedcom_x-0.5.2.dist-info}/METADATA +1 -1
- gedcom_x-0.5.2.dist-info/RECORD +42 -0
- gedcomx/Address.py +40 -11
- gedcomx/Agent.py +129 -23
- gedcomx/Attribution.py +38 -54
- gedcomx/Conclusion.py +60 -45
- gedcomx/Date.py +49 -8
- gedcomx/Document.py +19 -9
- gedcomx/Event.py +4 -4
- gedcomx/EvidenceReference.py +2 -2
- gedcomx/Exceptions.py +10 -0
- gedcomx/Fact.py +70 -46
- gedcomx/Gedcom.py +111 -37
- gedcomx/GedcomX.py +405 -175
- gedcomx/Gender.py +61 -8
- gedcomx/Group.py +3 -3
- gedcomx/Identifier.py +93 -10
- gedcomx/Logging.py +19 -0
- gedcomx/Name.py +67 -38
- gedcomx/Note.py +5 -4
- gedcomx/OnlineAccount.py +2 -2
- gedcomx/Person.py +88 -33
- gedcomx/PlaceDescription.py +22 -8
- gedcomx/PlaceReference.py +7 -5
- gedcomx/Relationship.py +19 -9
- gedcomx/Resource.py +61 -0
- gedcomx/Serialization.py +44 -1
- gedcomx/SourceCitation.py +6 -1
- gedcomx/SourceDescription.py +89 -72
- gedcomx/SourceReference.py +25 -14
- gedcomx/Subject.py +10 -8
- gedcomx/TextValue.py +2 -1
- gedcomx/URI.py +95 -61
- gedcomx/Zip.py +1 -0
- gedcomx/_Links.py +37 -0
- gedcomx/__init__.py +4 -2
- gedcomx/g7interop.py +205 -0
- gedcom_x-0.5.dist-info/RECORD +0 -37
- gedcomx/_Resource.py +0 -11
- {gedcom_x-0.5.dist-info → gedcom_x-0.5.2.dist-info}/WHEEL +0 -0
- {gedcom_x-0.5.dist-info → gedcom_x-0.5.2.dist-info}/top_level.txt +0 -0
gedcomx/Gender.py
CHANGED
@@ -5,11 +5,13 @@ from gedcomx.Attribution import Attribution
|
|
5
5
|
from gedcomx.Conclusion import ConfidenceLevel
|
6
6
|
from gedcomx.Note import Note
|
7
7
|
from gedcomx.SourceReference import SourceReference
|
8
|
-
from gedcomx.
|
8
|
+
from gedcomx.Resource import Resource
|
9
9
|
|
10
10
|
from .Conclusion import Conclusion
|
11
11
|
from .Qualifier import Qualifier
|
12
12
|
|
13
|
+
from collections.abc import Sized
|
14
|
+
|
13
15
|
class GenderType(Enum):
|
14
16
|
Male = "http://gedcomx.org/Male"
|
15
17
|
Female = "http://gedcomx.org/Female"
|
@@ -33,16 +35,67 @@ class Gender(Conclusion):
|
|
33
35
|
def __init__(self,
|
34
36
|
id: Optional[str] = None,
|
35
37
|
lang: Optional[str] = 'en',
|
36
|
-
sources: Optional[List[SourceReference]] =
|
37
|
-
analysis: Optional[
|
38
|
-
notes: Optional[List[Note]] =
|
38
|
+
sources: Optional[List[SourceReference]] = None,
|
39
|
+
analysis: Optional[Resource] = None,
|
40
|
+
notes: Optional[List[Note]] = None,
|
39
41
|
confidence: Optional[ConfidenceLevel] = None,
|
40
42
|
attribution: Optional[Attribution] = None,
|
41
|
-
type: GenderType = None
|
43
|
+
type: Optional[GenderType] = None
|
42
44
|
) -> None:
|
43
|
-
super().__init__(id, lang, sources, analysis, notes, confidence, attribution)
|
45
|
+
super().__init__(id=id, lang=lang, sources=sources, analysis=analysis, notes=notes, confidence=confidence, attribution=attribution)
|
44
46
|
self.type = type
|
45
47
|
|
48
|
+
@property
|
49
|
+
def _as_dict_(self):
|
50
|
+
def _serialize(value):
|
51
|
+
if isinstance(value, (str, int, float, bool, type(None))):
|
52
|
+
return value
|
53
|
+
elif isinstance(value, dict):
|
54
|
+
return {k: _serialize(v) for k, v in value.items()}
|
55
|
+
elif isinstance(value, (list, tuple, set)):
|
56
|
+
return [_serialize(v) for v in value]
|
57
|
+
elif hasattr(value, "_as_dict_"):
|
58
|
+
return value._as_dict_
|
59
|
+
else:
|
60
|
+
return str(value) # fallback for unknown objects
|
61
|
+
|
62
|
+
gender_fields = super()._as_dict_ # Start with base class fields
|
63
|
+
# Only add Relationship-specific fields
|
64
|
+
gender_fields.update({
|
65
|
+
'type':self.type.value if self.type else None
|
66
|
+
|
67
|
+
})
|
68
|
+
|
69
|
+
# Serialize and exclude None values
|
70
|
+
for key, value in gender_fields.items():
|
71
|
+
if value is not None:
|
72
|
+
gender_fields[key] = _serialize(value)
|
73
|
+
|
74
|
+
return {
|
75
|
+
k: v
|
76
|
+
for k, v in gender_fields.items()
|
77
|
+
if v is not None and not (isinstance(v, Sized) and len(v) == 0)
|
78
|
+
}
|
79
|
+
|
80
|
+
return gender_fields
|
81
|
+
|
46
82
|
@classmethod
|
47
|
-
def _from_json_(cls,
|
48
|
-
|
83
|
+
def _from_json_(cls,data):
|
84
|
+
id = data.get('id') if data.get('id') else None
|
85
|
+
lang = data.get('lang',None)
|
86
|
+
sources = [SourceReference._from_json_(o) for o in data.get('sources')] if data.get('sources') else None
|
87
|
+
analysis = None #URI.from_url(data.get('analysis')) if data.get('analysis',None) else None,
|
88
|
+
notes = [Note._from_json_(o) for o in data.get('notes',[])]
|
89
|
+
#TODO confidence = ConfidenceLevel(data.get('confidence')),
|
90
|
+
attribution = Attribution._from_json_(data.get('attribution'))
|
91
|
+
type = GenderType(data.get('type'))
|
92
|
+
|
93
|
+
|
94
|
+
return Gender(id=id,
|
95
|
+
lang=lang,
|
96
|
+
sources=sources,
|
97
|
+
analysis=analysis,
|
98
|
+
notes=notes,
|
99
|
+
attribution=attribution,
|
100
|
+
type=type)
|
101
|
+
|
gedcomx/Group.py
CHANGED
@@ -9,7 +9,7 @@ from .Identifier import Identifier
|
|
9
9
|
from .Note import Note
|
10
10
|
from .PlaceReference import PlaceReference
|
11
11
|
from .SourceReference import SourceReference
|
12
|
-
from .
|
12
|
+
from .Resource import Resource
|
13
13
|
|
14
14
|
from .TextValue import TextValue
|
15
15
|
from .Subject import Subject
|
@@ -22,14 +22,14 @@ class GroupRole:
|
|
22
22
|
identifier = 'http://gedcomx.org/v1/GroupRole'
|
23
23
|
version = 'http://gedcomx.org/conceptual-model/v1'
|
24
24
|
|
25
|
-
def __init__(self, person:
|
25
|
+
def __init__(self, person: Resource,type: Optional[Enum], date: Optional[Date],details: Optional[str]) -> None:
|
26
26
|
pass
|
27
27
|
|
28
28
|
class Group(Subject):
|
29
29
|
identifier = 'http://gedcomx.org/v1/Group'
|
30
30
|
version = 'http://gedcomx.org/conceptual-model/v1'
|
31
31
|
|
32
|
-
def __init__(self, id: str | None, lang: str | None, sources: SourceReference | None, analysis:
|
32
|
+
def __init__(self, id: str | None, lang: str | None, sources: SourceReference | None, analysis: Resource | None, notes: Note | None, confidence: ConfidenceLevel | None, attribution: Attribution | None, extracted: bool | None, evidence: List[EvidenceReference] | None, media: List[SourceReference] | None, identifiers: List[Identifier] | None,
|
33
33
|
names: TextValue,
|
34
34
|
date: Optional[Date],
|
35
35
|
place: Optional[PlaceReference],
|
gedcomx/Identifier.py
CHANGED
@@ -4,6 +4,7 @@ from enum import Enum
|
|
4
4
|
from typing import List, Optional, Dict, Any
|
5
5
|
|
6
6
|
from .Qualifier import Qualifier
|
7
|
+
from .Resource import Resource
|
7
8
|
from .URI import URI
|
8
9
|
|
9
10
|
class IdentifierType(Enum):
|
@@ -11,6 +12,8 @@ class IdentifierType(Enum):
|
|
11
12
|
Authority = "http://gedcomx.org/Authority"
|
12
13
|
Deprecated = "http://gedcomx.org/Deprecated"
|
13
14
|
Persistant = "http://gedcomx.org/Persistent"
|
15
|
+
External = "https://gedcom.io/terms/v7/EXID"
|
16
|
+
Other = "user provided"
|
14
17
|
|
15
18
|
@property
|
16
19
|
def description(self):
|
@@ -35,10 +38,11 @@ class Identifier:
|
|
35
38
|
identifier = 'http://gedcomx.org/v1/Identifier'
|
36
39
|
version = 'http://gedcomx.org/conceptual-model/v1'
|
37
40
|
|
38
|
-
def __init__(self, value: Optional[URI], type: Optional[IdentifierType] = IdentifierType.Primary) -> None:
|
39
|
-
|
41
|
+
def __init__(self, value: Optional[List[URI]], type: Optional[IdentifierType] = IdentifierType.Primary) -> None:
|
42
|
+
if not isinstance(value,list):
|
43
|
+
value = [value]
|
40
44
|
self.type = type
|
41
|
-
|
45
|
+
self.values = value if value else []
|
42
46
|
|
43
47
|
@property
|
44
48
|
def _as_dict_(self):
|
@@ -54,9 +58,8 @@ class Identifier:
|
|
54
58
|
else:
|
55
59
|
return str(value) # fallback for unknown objects
|
56
60
|
|
57
|
-
|
58
61
|
identifier_fields = {
|
59
|
-
'value': self.
|
62
|
+
'value': self.values if self.values else None,
|
60
63
|
'type': self.type.value if self.type else None
|
61
64
|
|
62
65
|
}
|
@@ -69,21 +72,101 @@ class Identifier:
|
|
69
72
|
return identifier_fields
|
70
73
|
|
71
74
|
@classmethod
|
72
|
-
def _from_json_(cls, data: Dict[str, Any]) -> 'Identifier':
|
75
|
+
def _from_json_(cls, data: Dict[str, Any]) -> 'Identifier | None':
|
73
76
|
"""
|
74
77
|
Construct an Identifier from a dict parsed from JSON.
|
75
78
|
"""
|
79
|
+
#for name, member in IdentifierType.__members__.items():
|
80
|
+
# print(name)
|
81
|
+
|
76
82
|
# Parse value (URI dict or string)
|
77
|
-
|
83
|
+
print('--------------',data)
|
78
84
|
for key in data.keys():
|
79
85
|
type = key
|
80
86
|
value = data[key]
|
81
|
-
uri_obj: Optional[
|
87
|
+
uri_obj: Optional[Resource] = None
|
82
88
|
# TODO DO THIS BETTER
|
83
89
|
|
84
90
|
# Parse type
|
85
91
|
raw_type = data.get('type')
|
86
|
-
|
92
|
+
if raw_type is None:
|
93
|
+
return None
|
94
|
+
id_type: Optional[IdentifierType] = IdentifierType(raw_type) if raw_type else None
|
95
|
+
return cls(value=value, type=id_type)
|
96
|
+
|
97
|
+
class IdentifierList():
|
98
|
+
def __init__(self) -> None:
|
99
|
+
self.identifiers = {}
|
100
|
+
|
101
|
+
def make_hashable(self, obj):
|
102
|
+
"""Convert any object into a hashable representation."""
|
103
|
+
if isinstance(obj, dict):
|
104
|
+
# Convert dict to sorted tuple of key/value pairs
|
105
|
+
return tuple(sorted((k, self.make_hashable(v)) for k, v in obj.items()))
|
106
|
+
elif isinstance(obj, (list, set, tuple)):
|
107
|
+
# Convert sequences/sets into tuples
|
108
|
+
return tuple(self.make_hashable(i) for i in obj)
|
109
|
+
elif hasattr(obj,'_as_dict_'):
|
110
|
+
as_dict = obj._as_dict_
|
111
|
+
t = tuple(sorted((k, self.make_hashable(v)) for k, v in as_dict.items()))
|
112
|
+
return t
|
113
|
+
else:
|
114
|
+
return obj # Immutable stays as is
|
115
|
+
|
116
|
+
def unique_list(self, items):
|
117
|
+
"""Return a list without duplicates, preserving order."""
|
118
|
+
seen = set()
|
119
|
+
result = []
|
120
|
+
for item in items:
|
121
|
+
h = self.make_hashable(item)
|
122
|
+
if h not in seen:
|
123
|
+
seen.add(h)
|
124
|
+
result.append(item)
|
125
|
+
return result
|
126
|
+
|
127
|
+
def append(self, identifier: Identifier):
|
128
|
+
if isinstance(identifier, Identifier):
|
129
|
+
self.add_identifer(identifier)
|
130
|
+
else:
|
131
|
+
raise ValueError()
|
132
|
+
|
133
|
+
def add_identifer(self, identifier: Identifier):
|
134
|
+
if identifier and isinstance(identifier,Identifier):
|
135
|
+
if identifier.type.value in self.identifiers.keys():
|
136
|
+
self.identifiers[identifier.type.value].extend(identifier.values)
|
137
|
+
else:
|
138
|
+
self.identifiers[identifier.type.value] = identifier.values
|
139
|
+
print(self.identifiers[identifier.type.value])
|
140
|
+
self.identifiers[identifier.type.value] = self.unique_list(self.identifiers[identifier.type.value])
|
87
141
|
|
142
|
+
# TODO Merge Identifiers
|
143
|
+
def contains(self,identifier: Identifier):
|
144
|
+
if identifier and isinstance(identifier,Identifier):
|
145
|
+
if identifier.type.value in self.identifiers.keys():
|
146
|
+
pass
|
147
|
+
|
148
|
+
def __get_item__(self):
|
149
|
+
pass
|
150
|
+
|
151
|
+
@classmethod
|
152
|
+
def _from_json_(cls,data):
|
153
|
+
identifier_list = IdentifierList()
|
154
|
+
for name, member in IdentifierType.__members__.items():
|
155
|
+
values = data.get(member.value,None)
|
156
|
+
if values:
|
157
|
+
identifier_list.add_identifer(Identifier(values,IdentifierType(member.value)))
|
158
|
+
return identifier_list
|
159
|
+
|
160
|
+
@property
|
161
|
+
def _as_dict_(self):
|
162
|
+
identifiers_dict = {}
|
163
|
+
for key in self.identifiers.keys():
|
164
|
+
# Should always be flat due to unique_list in add method.
|
165
|
+
identifiers_dict[key] = [u.value for u in self.identifiers[key]]
|
166
|
+
|
167
|
+
return identifiers_dict
|
168
|
+
|
169
|
+
|
170
|
+
|
171
|
+
|
88
172
|
|
89
|
-
return cls(value=value, type=id_type)
|
gedcomx/Logging.py
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
import logging
|
2
|
+
|
3
|
+
def get_logger(name='gedcomx.log'):
|
4
|
+
logger = logging.getLogger(name)
|
5
|
+
if not logger.handlers:
|
6
|
+
logger.setLevel(logging.DEBUG)
|
7
|
+
|
8
|
+
formatter = logging.Formatter('[%(asctime)s] %(levelname)s - %(name)s - %(message)s')
|
9
|
+
|
10
|
+
console_handler = logging.StreamHandler()
|
11
|
+
console_handler.setFormatter(formatter)
|
12
|
+
logger.addHandler(console_handler)
|
13
|
+
|
14
|
+
# Optional: file logging
|
15
|
+
file_handler = logging.FileHandler(f"{name}.log", encoding="utf-8")
|
16
|
+
file_handler.setFormatter(formatter)
|
17
|
+
logger.addHandler(file_handler)
|
18
|
+
|
19
|
+
return logger
|
gedcomx/Name.py
CHANGED
@@ -5,8 +5,9 @@ from .Attribution import Attribution
|
|
5
5
|
from .Conclusion import Conclusion, ConfidenceLevel
|
6
6
|
from .Date import Date
|
7
7
|
from .Note import Note
|
8
|
+
from .Serialization import Serialization
|
8
9
|
from .SourceReference import SourceReference
|
9
|
-
from .
|
10
|
+
from .Resource import Resource
|
10
11
|
|
11
12
|
|
12
13
|
class NameType(Enum):
|
@@ -99,10 +100,11 @@ class NamePart:
|
|
99
100
|
self.value = value
|
100
101
|
self.qualifiers = qualifiers
|
101
102
|
|
102
|
-
def
|
103
|
-
return
|
104
|
-
|
105
|
-
|
103
|
+
def _as_dict_(self):
|
104
|
+
return Serialization.serialize_dict(
|
105
|
+
{'type': self.type.value if self.type else None,
|
106
|
+
'value': self.value if self.value else None,
|
107
|
+
'qualifiers': [qualifier.value for qualifier in self.qualifiers] if self.qualifiers else None})
|
106
108
|
|
107
109
|
def __eq__(self, other):
|
108
110
|
if not isinstance(other, NamePart):
|
@@ -120,10 +122,12 @@ class NameForm:
|
|
120
122
|
self.fullText = fullText
|
121
123
|
self.parts = parts
|
122
124
|
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
125
|
+
@property
|
126
|
+
def _as_dict_(self):
|
127
|
+
return Serialization.serialize_dict(
|
128
|
+
{'lang': self.lang,
|
129
|
+
'fullText': self.fullText,
|
130
|
+
'parts': [part._as_dict_() for part in self.parts] if self.parts else None})
|
127
131
|
|
128
132
|
def _fulltext_parts(self):
|
129
133
|
pass
|
@@ -137,37 +141,40 @@ class Name(Conclusion):
|
|
137
141
|
"""
|
138
142
|
Takes a string and returns a GedcomX Name Object
|
139
143
|
"""
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
# Assign val1 and val2 based on the split
|
144
|
-
given = parts[0] if len(parts) > 1 else ""
|
145
|
-
surname = parts[1] if len(parts) > 1 else parts[0]
|
144
|
+
if text:
|
145
|
+
text = text.replace("/","")
|
146
|
+
parts = text.rsplit(' ', 1)
|
146
147
|
|
147
|
-
|
148
|
-
|
149
|
-
|
148
|
+
# Assign val1 and val2 based on the split
|
149
|
+
given = parts[0] if len(parts) > 1 else ""
|
150
|
+
surname = parts[1] if len(parts) > 1 else parts[0]
|
151
|
+
|
152
|
+
# Remove any '/' characters from both val1 and val2
|
153
|
+
#given = given.replace('/', '')
|
154
|
+
#surname = surname.replace('/', '')
|
150
155
|
|
151
|
-
|
152
|
-
|
156
|
+
given_name_part = NamePart(type = NamePartType.Given, value=given)
|
157
|
+
surname_part = NamePart(type = NamePartType.Surname, value=surname)
|
153
158
|
|
154
|
-
|
155
|
-
|
159
|
+
name_form = NameForm(fullText=text,parts=[given_name_part,surname_part])
|
160
|
+
name = Name(type=NameType.BirthName,nameForms=[name_form])
|
161
|
+
else:
|
162
|
+
name = Name()
|
156
163
|
return name
|
157
164
|
|
158
165
|
def __init__(self, id: str = None,
|
159
166
|
lang: str = 'en',
|
160
|
-
sources: Optional[List[SourceReference]] =
|
161
|
-
analysis:
|
162
|
-
notes: Optional[List[Note]] =
|
163
|
-
confidence: ConfidenceLevel = None,
|
164
|
-
attribution: Attribution = None,
|
167
|
+
sources: Optional[List[SourceReference]] = None,
|
168
|
+
analysis: Resource = None,
|
169
|
+
notes: Optional[List[Note]] = None,
|
170
|
+
confidence: Optional[ConfidenceLevel] = None,
|
171
|
+
attribution: Optional[Attribution] = None,
|
165
172
|
type: Optional[NameType] = None,
|
166
|
-
nameForms: NameForm
|
173
|
+
nameForms: Optional[List[NameForm]]= None,
|
167
174
|
date: Optional[Date] = None) -> None:
|
168
175
|
super().__init__(id, lang, sources, analysis, notes, confidence, attribution)
|
169
176
|
self.type = type
|
170
|
-
self.nameForms = nameForms
|
177
|
+
self.nameForms = nameForms if nameForms else []
|
171
178
|
self.date = date
|
172
179
|
|
173
180
|
def _add_name_part(self, namepart_to_add: NamePart):
|
@@ -179,11 +186,38 @@ class Name(Conclusion):
|
|
179
186
|
|
180
187
|
@property
|
181
188
|
def _as_dict_(self):
|
189
|
+
def _serialize(value):
|
190
|
+
if isinstance(value, (str, int, float, bool, type(None))):
|
191
|
+
return value
|
192
|
+
elif isinstance(value, dict):
|
193
|
+
return {k: _serialize(v) for k, v in value.items()}
|
194
|
+
elif isinstance(value, (list, tuple, set)):
|
195
|
+
return [_serialize(v) for v in value]
|
196
|
+
elif hasattr(value, "_as_dict_"):
|
197
|
+
return value._as_dict_
|
198
|
+
else:
|
199
|
+
return str(value) # fallback for unknown objects
|
200
|
+
|
182
201
|
name_as_dict = super()._as_dict_
|
202
|
+
|
183
203
|
name_as_dict.update( {
|
184
204
|
'type':self.type.value if self.type else None,
|
185
|
-
'nameForms': [nameForm.
|
186
|
-
'date': self.date.
|
205
|
+
'nameForms': [nameForm._as_dict_ for nameForm in self.nameForms],
|
206
|
+
'date': self.date._as_dict_ if self.date else None})
|
207
|
+
|
208
|
+
#del name_as_dict['id']
|
209
|
+
# Serialize and exclude None values
|
210
|
+
for key, value in name_as_dict.items():
|
211
|
+
if value is not None:
|
212
|
+
name_as_dict[key] = _serialize(value)
|
213
|
+
|
214
|
+
# 3) merge and filter out None *at the top level*
|
215
|
+
return {
|
216
|
+
k: v
|
217
|
+
for k, v in name_as_dict.items()
|
218
|
+
if v is not None
|
219
|
+
}
|
220
|
+
|
187
221
|
return name_as_dict
|
188
222
|
|
189
223
|
def ensure_list(val):
|
@@ -223,7 +257,7 @@ Name._from_json_ = classmethod(lambda cls, data: cls(
|
|
223
257
|
id=data.get('id'),
|
224
258
|
lang=data.get('lang', 'en'),
|
225
259
|
sources=[SourceReference._from_json_(s) for s in ensure_list(data.get('sources'))],
|
226
|
-
analysis=
|
260
|
+
analysis=Resource._from_json_(data['analysis']) if data.get('analysis') else None,
|
227
261
|
notes=[Note._from_json_(n) for n in ensure_list(data.get('notes'))],
|
228
262
|
confidence=ConfidenceLevel._from_json_(data['confidence']) if data.get('confidence') else None,
|
229
263
|
attribution=Attribution._from_json_(data['attribution']) if data.get('attribution') else None,
|
@@ -232,10 +266,5 @@ Name._from_json_ = classmethod(lambda cls, data: cls(
|
|
232
266
|
date=Date._from_json_(data['date']) if data.get('date') else None
|
233
267
|
))
|
234
268
|
|
235
|
-
|
236
|
-
**self._as_dict_,
|
237
|
-
'type': self.type.value if self.type else None,
|
238
|
-
'nameForms': [nf._to_dict_() for nf in self.nameForms] if self.nameForms else [],
|
239
|
-
'date': self.date._prop_date() if self.date else None
|
240
|
-
}
|
269
|
+
|
241
270
|
|
gedcomx/Note.py
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
from typing import Optional
|
2
2
|
|
3
3
|
from .Attribution import Attribution
|
4
|
+
from .Serialization import Serialization
|
4
5
|
|
5
6
|
class Note:
|
6
7
|
identifier = 'http://gedcomx.org/v1/Note'
|
@@ -10,24 +11,24 @@ class Note:
|
|
10
11
|
self.lang = lang
|
11
12
|
self.subject = subject
|
12
13
|
self.text = text
|
13
|
-
self.attribution = attribution
|
14
|
-
|
15
|
-
|
14
|
+
self.attribution = attribution
|
16
15
|
|
17
16
|
def append(self, text_to_add: str):
|
18
17
|
if text_to_add and isinstance(text_to_add, str):
|
19
18
|
self.text = self.text + text_to_add
|
20
19
|
else:
|
20
|
+
return #TODO
|
21
21
|
raise ValueError("The text to add must be a non-empty string.")
|
22
22
|
|
23
23
|
@property
|
24
24
|
def _as_dict_(self):
|
25
|
-
|
25
|
+
note_dict = {
|
26
26
|
"lang":self.lang if self.lang else None,
|
27
27
|
"subject":self.subject if self.subject else None,
|
28
28
|
"text":self.text if self.text else None,
|
29
29
|
"attribution": self.attribution if self.attribution else None
|
30
30
|
}
|
31
|
+
return Serialization.serialize_dict(note_dict)
|
31
32
|
|
32
33
|
def __eq__(self, other):
|
33
34
|
if not isinstance(other, Note):
|
gedcomx/OnlineAccount.py
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
from typing import Optional
|
2
2
|
|
3
|
-
from .
|
3
|
+
from .Resource import Resource
|
4
4
|
|
5
5
|
class OnlineAccount:
|
6
6
|
identifier = 'http://gedcomx.org/v1/OnlineAccount'
|
7
7
|
version = 'http://gedcomx.org/conceptual-model/v1'
|
8
8
|
|
9
|
-
def __init__(self, serviceHomepage:
|
9
|
+
def __init__(self, serviceHomepage: Resource, accountName: str) -> None:
|
10
10
|
pass
|