gedcom-x 0.5.1__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.1.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 +110 -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.1.dist-info/RECORD +0 -37
- gedcomx/_Resource.py +0 -11
- {gedcom_x-0.5.1.dist-info → gedcom_x-0.5.2.dist-info}/WHEEL +0 -0
- {gedcom_x-0.5.1.dist-info → gedcom_x-0.5.2.dist-info}/top_level.txt +0 -0
gedcomx/GedcomX.py
CHANGED
@@ -13,9 +13,10 @@ from .Agent import Agent
|
|
13
13
|
from .Attribution import Attribution
|
14
14
|
from .Conclusion import Conclusion
|
15
15
|
from .Coverage import Coverage
|
16
|
-
from .Date import Date
|
16
|
+
from .Date import Date, date_to_timestamp
|
17
17
|
from .Document import Document
|
18
18
|
from .EvidenceReference import EvidenceReference
|
19
|
+
from .Exceptions import TagConversionError
|
19
20
|
from .Event import Event,EventType,EventRole,EventRoleType
|
20
21
|
from .Fact import Fact, FactType, FactQualifier
|
21
22
|
from .Gedcom import Gedcom
|
@@ -23,6 +24,7 @@ from .Gedcom import GedcomRecord
|
|
23
24
|
from .Gender import Gender, GenderType
|
24
25
|
from .Group import Group
|
25
26
|
from .Identifier import Identifier, IdentifierType
|
27
|
+
from .Logging import get_logger
|
26
28
|
from .Name import Name, NameType, NameForm, NamePart, NamePartType, NamePartQualifier
|
27
29
|
from .Note import Note
|
28
30
|
from .OnlineAccount import OnlineAccount
|
@@ -37,7 +39,10 @@ from .SourceReference import SourceReference, KnownSourceReference
|
|
37
39
|
from .Subject import Subject
|
38
40
|
from .TextValue import TextValue
|
39
41
|
from .TopLevelTypeCollection import TopLevelTypeCollection
|
40
|
-
from .
|
42
|
+
from .Resource import Resource, URI
|
43
|
+
|
44
|
+
import_log = get_logger('import')
|
45
|
+
convert_log = get_logger('conversion')
|
41
46
|
|
42
47
|
def TypeCollection(item_type):
|
43
48
|
class Collection:
|
@@ -108,8 +113,10 @@ def TypeCollection(item_type):
|
|
108
113
|
|
109
114
|
def byName(self, sname: str):
|
110
115
|
# Use the name index for fast lookup
|
111
|
-
|
112
|
-
|
116
|
+
if sname:
|
117
|
+
sname = sname.strip()
|
118
|
+
return self._name_index.get(sname, [])
|
119
|
+
return None
|
113
120
|
|
114
121
|
def byId(self, id):
|
115
122
|
# Use the id index for fast lookup
|
@@ -122,7 +129,9 @@ def TypeCollection(item_type):
|
|
122
129
|
def append(self, item):
|
123
130
|
if not isinstance(item, item_type):
|
124
131
|
raise TypeError(f"Expected item of type {item_type.__name__}, got {type(item).__name__}")
|
125
|
-
item.
|
132
|
+
item.uri.path = f'{str(item_type.__name__)}s' if (item.uri.path is None or item.uri.path == "") else item.uri.path
|
133
|
+
|
134
|
+
|
126
135
|
#if isinstance(item,Agent):
|
127
136
|
# item._uri._path = 'Agents'
|
128
137
|
# print(item._uri._as_dict_)
|
@@ -163,30 +172,49 @@ def TypeCollection(item_type):
|
|
163
172
|
|
164
173
|
@property
|
165
174
|
def _items_as_dict(self) -> dict:
|
166
|
-
|
167
|
-
|
168
|
-
#return {f'{str(item_type.__name__)}s': [item._as_dict_ for item in self._items]}
|
169
|
-
return {f'{str(item_type.__name__)}s': [item._as_dict_ for item in self._items]}
|
170
|
-
|
171
|
-
@property
|
172
|
-
def json(self):
|
173
|
-
return json.dumps(self._as_dict, indent=4)
|
175
|
+
return {f'{str(item_type.__name__)}s': [item._as_dict_ for item in self._items]}
|
174
176
|
|
175
177
|
@property
|
176
178
|
def _as_dict_(self):
|
177
|
-
return {
|
179
|
+
return {f'{str(item_type.__name__).lower()}s': [item._as_dict_ for item in self._items]}
|
180
|
+
|
181
|
+
@property
|
182
|
+
def json(self) -> str:
|
183
|
+
|
184
|
+
return json.dumps(self._as_dict_, indent=4)
|
178
185
|
|
179
186
|
return Collection()
|
180
187
|
|
181
188
|
class GedcomX:
|
189
|
+
"""
|
190
|
+
Main GedcomX Object representing a Genealogy. Stores collections of Top Level Gedcom-X Types.
|
191
|
+
complies with GEDCOM X Conceptual Model V1 (http://gedcomx.org/conceptual-model/v1)
|
192
|
+
|
193
|
+
Parameters
|
194
|
+
----------
|
195
|
+
id : str
|
196
|
+
Unique identifier for this Genealogy.
|
197
|
+
attribution : Attribution Object
|
198
|
+
Attribution information for the Genealogy
|
199
|
+
filepath : str
|
200
|
+
Not Implimented.
|
201
|
+
description : str
|
202
|
+
Description of the Genealogy: ex. 'My Family Tree'
|
203
|
+
|
204
|
+
Raises
|
205
|
+
------
|
206
|
+
ValueError
|
207
|
+
If `id` is not a valid UUID.
|
208
|
+
"""
|
182
209
|
version = 'http://gedcomx.org/conceptual-model/v1'
|
183
210
|
|
184
|
-
def __init__(self, id: str = None, attribution: Attribution = None, filepath: str = None) -> None:
|
211
|
+
def __init__(self, id: str = None, attribution: Attribution = None, filepath: str = None, description: str = None) -> None:
|
185
212
|
self.id = id
|
186
213
|
self.attribution = attribution
|
187
214
|
|
188
215
|
self._filepath = None
|
189
216
|
|
217
|
+
self.description = description
|
190
218
|
self.source_descriptions = TypeCollection(SourceDescription)
|
191
219
|
self.persons = TypeCollection(Person)
|
192
220
|
self.relationships = TypeCollection(Relationship)
|
@@ -199,7 +227,6 @@ class GedcomX:
|
|
199
227
|
self.person_relationships_lookup = {}
|
200
228
|
|
201
229
|
def _add(self,gedcomx_type_object):
|
202
|
-
#print(type(gedcomx_type_object))
|
203
230
|
if gedcomx_type_object:
|
204
231
|
if isinstance(gedcomx_type_object,Person):
|
205
232
|
self.add_person(gedcomx_type_object)
|
@@ -228,16 +255,27 @@ class GedcomX:
|
|
228
255
|
raise ValueError(f"When adding a SourceDescription, value must be of type SourceDescription, type {type(sourceDescription)} was provided")
|
229
256
|
|
230
257
|
def add_person(self,person: Person):
|
258
|
+
"""Add a Person object to the Genealogy
|
259
|
+
|
260
|
+
Args:
|
261
|
+
person: Person Object
|
262
|
+
|
263
|
+
Returns:
|
264
|
+
None
|
265
|
+
|
266
|
+
Raises:
|
267
|
+
ValueError: If `person` is not of type Person.
|
268
|
+
"""
|
231
269
|
if person and isinstance(person,Person):
|
232
270
|
if person.id is None:
|
233
271
|
person.id =self.personURIgenerator()
|
234
272
|
self.persons.append(item=person)
|
235
273
|
else:
|
236
|
-
raise ValueError()
|
274
|
+
raise ValueError(f'person must be a Person Object not type: {type(person)}')
|
237
275
|
|
238
276
|
def add_relationship(self,relationship: Relationship):
|
239
277
|
if relationship and isinstance(relationship,Relationship):
|
240
|
-
if isinstance(relationship.person1,
|
278
|
+
if isinstance(relationship.person1,Resource) and isinstance(relationship.person2,Resource):
|
241
279
|
print("Adding unresolved Relationship")
|
242
280
|
self.relationships.append(relationship)
|
243
281
|
return
|
@@ -277,9 +315,21 @@ class GedcomX:
|
|
277
315
|
self.places.append(placeDescription)
|
278
316
|
|
279
317
|
def add_agent(self,agent: Agent):
|
318
|
+
"""Add a Agent object to the Genealogy
|
319
|
+
|
320
|
+
Args:
|
321
|
+
agent: Agent Object
|
322
|
+
|
323
|
+
Returns:
|
324
|
+
None
|
325
|
+
|
326
|
+
Raises:
|
327
|
+
ValueError: If `agent` is not of type Agent.
|
328
|
+
"""
|
280
329
|
if agent and isinstance(agent,Agent):
|
330
|
+
if agent in self.agents:
|
331
|
+
return
|
281
332
|
if agent.id is None:
|
282
|
-
raise("Empty ID")
|
283
333
|
agent.id = Agent.default_id_generator()
|
284
334
|
if self.agents.byId(agent.id):
|
285
335
|
raise ValueError
|
@@ -293,7 +343,7 @@ class GedcomX:
|
|
293
343
|
return
|
294
344
|
self.events.append(event_to_add)
|
295
345
|
|
296
|
-
def
|
346
|
+
def get_person_by_id(self,id: str):
|
297
347
|
filtered = [person for person in self.persons if getattr(person, 'id') == id]
|
298
348
|
if filtered: return filtered[0]
|
299
349
|
return None
|
@@ -303,11 +353,23 @@ class GedcomX:
|
|
303
353
|
if filtered: return filtered[0]
|
304
354
|
return None
|
305
355
|
|
356
|
+
def json(self):
|
357
|
+
"""
|
358
|
+
JSON Representation of the GedcomX Genealogy.
|
359
|
+
|
360
|
+
Returns:
|
361
|
+
str: JSON Representation of the GedcomX Genealogy in the GEDCOM X JSON Serialization Format
|
362
|
+
"""
|
363
|
+
gedcomx_json = {
|
364
|
+
'persons': [person._as_dict_ for person in self.persons],
|
365
|
+
'sourceDescriptions' : [sourceDescription._as_dict_ for sourceDescription in self.source_descriptions]
|
366
|
+
}
|
367
|
+
return json.dumps(gedcomx_json, indent=4)
|
306
368
|
|
307
369
|
class Translater():
|
308
|
-
def __init__(self,gedcom) -> None:
|
370
|
+
def __init__(self,gedcom: Gedcom) -> None:
|
309
371
|
self.handlers = {}
|
310
|
-
self.gedcom: Gedcom = gedcom
|
372
|
+
self.gedcom: Gedcom = gedcom
|
311
373
|
self.gedcomx = GedcomX()
|
312
374
|
|
313
375
|
self.object_stack = []
|
@@ -316,6 +378,7 @@ class Translater():
|
|
316
378
|
|
317
379
|
self.translate()
|
318
380
|
|
381
|
+
|
319
382
|
gedcom_even_to_fact = {
|
320
383
|
# Person Fact Types
|
321
384
|
"ADOP": FactType.Adoption,
|
@@ -367,15 +430,55 @@ class Translater():
|
|
367
430
|
"ADOP": FactType.AdoptiveParent
|
368
431
|
}
|
369
432
|
|
433
|
+
gedcom_even_to_evnt = {
|
434
|
+
# Person Fact Types
|
435
|
+
"ADOP": EventType.Adoption,
|
436
|
+
"CHR": EventType.AdultChristening,
|
437
|
+
"BAPM": EventType.Baptism,
|
438
|
+
"BARM": EventType.BarMitzvah,
|
439
|
+
"BASM": EventType.BatMitzvah,
|
440
|
+
"BIRT": EventType.Birth,
|
441
|
+
"BIRT, CHR": EventType.Birth,
|
442
|
+
"BLES": EventType.Blessing,
|
443
|
+
"BURI": EventType.Burial,
|
444
|
+
|
445
|
+
"CENS": EventType.Census,
|
446
|
+
"CIRC": EventType.Circumcision,
|
447
|
+
"CONF": EventType.Confirmation,
|
448
|
+
"CREM": EventType.Cremation,
|
449
|
+
"DEAT": EventType.Death,
|
450
|
+
"EDUC": EventType.Education,
|
451
|
+
"EMIG": EventType.Emigration,
|
452
|
+
"FCOM": EventType.FirstCommunion,
|
370
453
|
|
454
|
+
"IMMI": EventType.Immigration,
|
455
|
+
|
456
|
+
"NATU": EventType.Naturalization,
|
457
|
+
|
458
|
+
"ORDN": EventType.Ordination,
|
459
|
+
|
460
|
+
|
461
|
+
# Couple Relationship Fact Types
|
462
|
+
"ANUL": EventType.Annulment,
|
463
|
+
"DIV": EventType.Divorce,
|
464
|
+
"DIVF": EventType.DivorceFiling,
|
465
|
+
"ENGA": EventType.Engagement,
|
466
|
+
"MARR": EventType.Marriage
|
467
|
+
|
468
|
+
}
|
469
|
+
|
470
|
+
@staticmethod
|
371
471
|
def clean_str(text: str) -> str:
|
372
472
|
# Regular expression to match HTML/XML tags
|
473
|
+
if text is None or text.strip() == '':
|
474
|
+
return None
|
373
475
|
clean_text = re.sub(r'<[^>]+>', '', text)
|
374
476
|
|
375
477
|
return clean_text
|
376
478
|
|
377
479
|
def translate(self):
|
378
|
-
for repository in self.gedcom.repositories:
|
480
|
+
for n, repository in enumerate(self.gedcom.repositories):
|
481
|
+
print(f"Parsing Repository {n}")
|
379
482
|
self.parse_record(repository)
|
380
483
|
print(f"Translated {len(self.gedcomx.agents)} 'REPO' records to Agents")
|
381
484
|
for source in self.gedcom.sources:
|
@@ -402,7 +505,7 @@ class Translater():
|
|
402
505
|
|
403
506
|
print(f"Translated {len(self.gedcomx.events)} 'EVEN' records to Events")
|
404
507
|
|
405
|
-
def find_urls(
|
508
|
+
def find_urls(self,text: str):
|
406
509
|
# Regular expression pattern to match URLs
|
407
510
|
url_pattern = re.compile(r'https?://[^\s]+')
|
408
511
|
# Find all URLs using the pattern
|
@@ -411,37 +514,36 @@ class Translater():
|
|
411
514
|
|
412
515
|
@property
|
413
516
|
def event_type_conversion_table(self):
|
414
|
-
return {'BIRT':EventType.
|
415
|
-
'OBIT':FactType.
|
517
|
+
return {'BIRT':EventType.Birth,
|
518
|
+
'OBIT':FactType.Obituary}
|
416
519
|
|
417
520
|
def parse_record(self,record: GedcomRecord):
|
418
|
-
|
419
|
-
if DEBUG: print(record.describe())
|
521
|
+
|
420
522
|
handler_name = 'handle_' + record.tag.lower()
|
421
523
|
|
422
|
-
if hasattr(self,handler_name):
|
423
|
-
|
424
|
-
handler = getattr(self,handler_name)
|
524
|
+
if hasattr(self,handler_name):
|
525
|
+
convert_log.info(f'Parsing Record: {record.describe()}')
|
526
|
+
handler = getattr(self,handler_name)
|
425
527
|
handler(record)
|
426
528
|
else:
|
427
529
|
if record.tag in self.missing_handler_count:
|
428
530
|
self.missing_handler_count[record.tag] += 1
|
429
531
|
else:
|
430
532
|
self.missing_handler_count[record.tag] = 1
|
431
|
-
|
432
|
-
|
533
|
+
|
534
|
+
convert_log.error(f'Failed Parsing Record: {record.describe()}')
|
433
535
|
for sub_record in record.subRecords():
|
434
536
|
self.parse_record(sub_record)
|
435
|
-
|
436
|
-
def handle__apid(self, record):
|
537
|
+
|
538
|
+
def handle__apid(self, record: GedcomRecord):
|
437
539
|
if isinstance(self.object_map[record.level-1], SourceReference):
|
438
|
-
self.object_map[record.level-1].
|
540
|
+
self.object_map[record.level-1].description.add_identifier(Identifier(value=URI.from_url('APID://' + record.value)))
|
439
541
|
elif isinstance(self.object_map[record.level-1], SourceDescription):
|
440
542
|
self.object_map[record.level-1].add_identifier(Identifier(value=URI.from_url('APID://' + record.value)))
|
441
543
|
else:
|
442
544
|
raise ValueError(f"Could not handle '_APID' tag in record {record.describe()}, last stack object {type(self.object_map[record.level-1])}")
|
443
545
|
|
444
|
-
def handle__meta(self, record):
|
546
|
+
def handle__meta(self, record: GedcomRecord):
|
445
547
|
if isinstance(self.object_map[record.level-1], SourceDescription):
|
446
548
|
gxobject = Note(text=Translater.clean_str(record.value))
|
447
549
|
self.object_map[record.level-1].add_note(gxobject)
|
@@ -450,14 +552,14 @@ class Translater():
|
|
450
552
|
else:
|
451
553
|
raise ValueError(f"Could not handle 'WWW' tag in record {record.describe()}, last stack object {self.object_map[record.level-1]}")
|
452
554
|
|
453
|
-
def handle__wlnk(self, record):
|
555
|
+
def handle__wlnk(self, record: GedcomRecord):
|
454
556
|
return self.handle_sour(record)
|
455
557
|
|
456
|
-
def handle_addr(self, record):
|
558
|
+
def handle_addr(self, record: GedcomRecord):
|
457
559
|
if isinstance(self.object_map[record.level-1], Agent):
|
458
560
|
# TODO CHeck if URL?
|
459
561
|
if Translater.clean_str(record.value):
|
460
|
-
gxobject =
|
562
|
+
gxobject = Address(value=Translater.clean_str(record.value))
|
461
563
|
else:
|
462
564
|
gxobject = Address()
|
463
565
|
self.object_map[record.level-1].address = gxobject
|
@@ -466,26 +568,80 @@ class Translater():
|
|
466
568
|
else:
|
467
569
|
raise ValueError(f"I do not know how to handle an 'ADDR' tag for a {type(self.object_map[record.level-1])}")
|
468
570
|
|
469
|
-
def handle_adr1(self, record):
|
571
|
+
def handle_adr1(self, record: GedcomRecord):
|
470
572
|
if isinstance(self.object_map[record.level-1], Address):
|
471
573
|
if Translater.clean_str(record.value):
|
472
|
-
self.object_map[record.level-1].street = Translater.clean_str(record.value)
|
473
|
-
|
574
|
+
self.object_map[record.level-1].street = Translater.clean_str(record.value)
|
474
575
|
else:
|
475
|
-
raise ValueError(f"I do not know how to handle an '
|
576
|
+
raise ValueError(f"I do not know how to handle an 'ADR1' tag for a {type(self.object_map[record.level-1])}")
|
577
|
+
|
578
|
+
def handle_adr2(self, record: GedcomRecord):
|
579
|
+
if isinstance(self.object_map[record.level-1], Address):
|
580
|
+
if Translater.clean_str(record.value):
|
581
|
+
self.object_map[record.level-1].street2 = Translater.clean_str(record.value)
|
582
|
+
else:
|
583
|
+
raise ValueError(f"I do not know how to handle an 'ADR2' tag for a {type(self.object_map[record.level-1])}")
|
584
|
+
|
585
|
+
def handle_adr3(self, record: GedcomRecord):
|
586
|
+
if isinstance(self.object_map[record.level-1], Address):
|
587
|
+
if Translater.clean_str(record.value):
|
588
|
+
self.object_map[record.level-1].street3 = Translater.clean_str(record.value)
|
589
|
+
else:
|
590
|
+
raise ValueError(f"I do not know how to handle an 'ADR3' tag for a {type(self.object_map[record.level-1])}")
|
591
|
+
|
592
|
+
def handle_adr4(self, record: GedcomRecord):
|
593
|
+
if isinstance(self.object_map[record.level-1], Address):
|
594
|
+
if Translater.clean_str(record.value):
|
595
|
+
self.object_map[record.level-1].street4 = Translater.clean_str(record.value)
|
596
|
+
else:
|
597
|
+
raise ValueError(f"I do not know how to handle an 'ADR4' tag for a {type(self.object_map[record.level-1])}")
|
598
|
+
|
599
|
+
def handle_adr5(self, record: GedcomRecord):
|
600
|
+
if isinstance(self.object_map[record.level-1], Address):
|
601
|
+
if Translater.clean_str(record.value):
|
602
|
+
self.object_map[record.level-1].street5 = Translater.clean_str(record.value)
|
603
|
+
else:
|
604
|
+
raise ValueError(f"I do not know how to handle an 'ADR5' tag for a {type(self.object_map[record.level-1])}")
|
605
|
+
|
606
|
+
def handle_adr6(self, record: GedcomRecord):
|
607
|
+
if isinstance(self.object_map[record.level-1], Address):
|
608
|
+
if Translater.clean_str(record.value):
|
609
|
+
self.object_map[record.level-1].street5 = Translater.clean_str(record.value)
|
610
|
+
else:
|
611
|
+
raise ValueError(f"I do not know how to handle an 'ADR6' tag for a {type(self.object_map[record.level-1])}")
|
612
|
+
|
613
|
+
def handle_phon(self, record: GedcomRecord):
|
614
|
+
if isinstance(self.object_map[record.level-1], Agent):
|
615
|
+
if Translater.clean_str(record.value):
|
616
|
+
self.object_map[record.level-1].phones.append(Translater.clean_str(record.value))
|
617
|
+
else:
|
618
|
+
raise ValueError(f"I do not know how to handle an '{record.tag}' tag for a {type(self.object_map[record.level-1])}")
|
619
|
+
|
620
|
+
def handle_email(self, record: GedcomRecord):
|
621
|
+
if isinstance(self.object_map[record.level-1], Agent):
|
622
|
+
if Translater.clean_str(record.value):
|
623
|
+
self.object_map[record.level-1].emails.append(Translater.clean_str(record.value))
|
624
|
+
else:
|
625
|
+
raise ValueError(f"I do not know how to handle an '{record.tag}' tag for a {type(self.object_map[record.level-1])}")
|
626
|
+
|
627
|
+
def handle_fax(self, record: GedcomRecord):
|
628
|
+
if isinstance(self.object_map[record.level-1], Agent):
|
629
|
+
if Translater.clean_str(record.value):
|
630
|
+
self.object_map[record.level-1].emails.append('FAX:' + Translater.clean_str(record.value))
|
631
|
+
else:
|
632
|
+
raise ValueError(f"I do not know how to handle an '{record.tag}' tag for a {type(self.object_map[record.level-1])}")
|
476
633
|
|
477
|
-
def handle_adop(self, record):
|
634
|
+
def handle_adop(self, record: GedcomRecord):
|
478
635
|
if isinstance(self.object_map[record.level-1], Person):
|
479
|
-
gxobject = Fact(type=FactType.
|
636
|
+
gxobject = Fact(type=FactType.Adoption)
|
480
637
|
self.object_map[record.level-1].add_fact(gxobject)
|
481
638
|
|
482
639
|
self.object_stack.append(gxobject)
|
483
640
|
self.object_map[record.level] = gxobject
|
484
641
|
else:
|
485
|
-
|
486
|
-
assert False
|
642
|
+
raise TagConversionError(record=record,levelstack=self.object_map)
|
487
643
|
|
488
|
-
def handle_auth(self, record):
|
644
|
+
def handle_auth(self, record: GedcomRecord):
|
489
645
|
if isinstance(self.object_map[record.level-1], SourceDescription):
|
490
646
|
if self.gedcomx.agents.byName(record.value):
|
491
647
|
gxobject = self.gedcomx.agents.byName(record.value)[0]
|
@@ -497,10 +653,9 @@ class Translater():
|
|
497
653
|
self.object_stack.append(gxobject)
|
498
654
|
self.object_map[record.level] = gxobject
|
499
655
|
else:
|
500
|
-
|
501
|
-
assert False
|
656
|
+
raise TagConversionError(record=record,levelstack=self.object_map)
|
502
657
|
|
503
|
-
def handle_bapm(self, record):
|
658
|
+
def handle_bapm(self, record: GedcomRecord):
|
504
659
|
if isinstance(self.object_map[record.level-1], Person):
|
505
660
|
gxobject = Fact(type=FactType.Baptism)
|
506
661
|
self.object_map[record.level-1].add_fact(gxobject)
|
@@ -508,10 +663,9 @@ class Translater():
|
|
508
663
|
self.object_stack.append(gxobject)
|
509
664
|
self.object_map[record.level] = gxobject
|
510
665
|
else:
|
511
|
-
|
512
|
-
assert False
|
666
|
+
raise TagConversionError(record=record,levelstack=self.object_map)
|
513
667
|
|
514
|
-
def handle_birt(self, record):
|
668
|
+
def handle_birt(self, record: GedcomRecord):
|
515
669
|
if isinstance(self.object_map[record.level-1], Person):
|
516
670
|
#gxobject = Event(type=EventType.BIRTH, roles=[EventRole(person=self.object_map[record.level-1], type=EventRoleType.Principal)])
|
517
671
|
gxobject = Fact(type=FactType.Birth)
|
@@ -521,10 +675,9 @@ class Translater():
|
|
521
675
|
self.object_stack.append(gxobject)
|
522
676
|
self.object_map[record.level] = gxobject
|
523
677
|
else:
|
524
|
-
|
525
|
-
assert False
|
678
|
+
raise TagConversionError(record=record,levelstack=self.object_map)
|
526
679
|
|
527
|
-
def handle_buri(self, record):
|
680
|
+
def handle_buri(self, record: GedcomRecord):
|
528
681
|
if isinstance(self.object_map[record.level-1], Person):
|
529
682
|
gxobject = Fact(type=FactType.Burial)
|
530
683
|
self.object_map[record.level-1].add_fact(gxobject)
|
@@ -532,10 +685,9 @@ class Translater():
|
|
532
685
|
self.object_stack.append(gxobject)
|
533
686
|
self.object_map[record.level] = gxobject
|
534
687
|
else:
|
535
|
-
|
536
|
-
assert False
|
688
|
+
raise TagConversionError(record=record,levelstack=self.object_map)
|
537
689
|
|
538
|
-
def handle_caln(self, record):
|
690
|
+
def handle_caln(self, record: GedcomRecord):
|
539
691
|
if isinstance(self.object_map[record.level-1], SourceReference):
|
540
692
|
self.object_map[record.level-1].description.add_identifier(Identifier(value=URI.from_url('Call Number:' + record.value)))
|
541
693
|
elif isinstance(self.object_map[record.level-1], SourceDescription):
|
@@ -546,7 +698,19 @@ class Translater():
|
|
546
698
|
else:
|
547
699
|
raise ValueError(f"Could not handle 'CALN' tag in record {record.describe()}, last stack object {type(self.object_map[record.level-1])}")
|
548
700
|
|
549
|
-
def
|
701
|
+
def handle_chan(self, record: GedcomRecord):
|
702
|
+
if isinstance(self.object_map[record.level-1], SourceDescription):
|
703
|
+
self.object_map[record.level-1].created = Date(record.subRecord('DATE'))
|
704
|
+
elif isinstance(self.object_map[record.level-1], Agent):
|
705
|
+
if self.object_map[record.level-1].attribution is None:
|
706
|
+
gxobject = Attribution()
|
707
|
+
self.object_map[record.level-1].attribution = gxobject
|
708
|
+
self.object_stack.append(gxobject)
|
709
|
+
self.object_map[record.level] = gxobject
|
710
|
+
else:
|
711
|
+
raise ValueError()
|
712
|
+
|
713
|
+
def handle_chr(self, record: GedcomRecord):
|
550
714
|
if isinstance(self.object_map[record.level-1], Person):
|
551
715
|
gxobject = Fact(type=FactType.Christening)
|
552
716
|
self.object_map[record.level-1].add_fact(gxobject)
|
@@ -554,16 +718,15 @@ class Translater():
|
|
554
718
|
self.object_stack.append(gxobject)
|
555
719
|
self.object_map[record.level] = gxobject
|
556
720
|
else:
|
557
|
-
|
558
|
-
assert False
|
721
|
+
raise TagConversionError(record=record,levelstack=self.object_map)
|
559
722
|
|
560
|
-
def handle_city(self, record):
|
723
|
+
def handle_city(self, record: GedcomRecord):
|
561
724
|
if isinstance(self.object_map[record.level-1], Address):
|
562
725
|
self.object_map[record.level-1].city = Translater.clean_str(record.value)
|
563
726
|
else:
|
564
727
|
raise ValueError(f"I do not know how to handle an 'CITY' tag for a {type(self.object_map[record.level-1])}")
|
565
728
|
|
566
|
-
def handle_conc(self, record):
|
729
|
+
def handle_conc(self, record: GedcomRecord):
|
567
730
|
if isinstance(self.object_map[record.level-1], Note):
|
568
731
|
gxobject = Translater.clean_str(str(record.value))
|
569
732
|
self.object_map[record.level-1].append(gxobject)
|
@@ -582,69 +745,85 @@ class Translater():
|
|
582
745
|
self.object_map[record.level-1].notes[0].text += record.value
|
583
746
|
|
584
747
|
else:
|
585
|
-
|
586
|
-
assert False
|
748
|
+
raise TagConversionError(record=record,levelstack=self.object_map)
|
587
749
|
|
588
|
-
def handle_cont(self, record):
|
750
|
+
def handle_cont(self, record: GedcomRecord):
|
589
751
|
if isinstance(self.object_map[record.level-1], Note):
|
590
|
-
gxobject = str("\n" + record.value)
|
752
|
+
gxobject = str("\n" + record.value if record.value else '')
|
591
753
|
self.object_map[record.level-1].append(gxobject)
|
592
754
|
elif isinstance(self.object_map[record.level-1], Agent):
|
593
|
-
gxobject = str("\n" + record.value)
|
755
|
+
gxobject = str("\n" + record.value if record.value else '')
|
594
756
|
elif isinstance(self.object_map[record.level-1], Qualifier):
|
595
|
-
gxobject = str("\n" + record.value)
|
757
|
+
gxobject = str("\n" + record.value if record.value else '')
|
596
758
|
self.object_map[record.level-1].append(gxobject)
|
597
759
|
elif isinstance(self.object_map[record.level-1], TextValue):
|
598
760
|
#gxobject = TextValue(value="\n" + record.value)
|
599
|
-
self.object_map[record.level-1]._append_to_value(record.value)
|
761
|
+
self.object_map[record.level-1]._append_to_value(record.value if record.value else '\n')
|
600
762
|
elif isinstance(self.object_map[record.level-1], SourceReference):
|
601
763
|
self.object_map[record.level-1].append(record.value)
|
764
|
+
elif isinstance(self.object_map[record.level-1], Address):
|
765
|
+
self.object_map[record.level-1]._append(record.value)
|
602
766
|
else:
|
603
|
-
|
604
|
-
assert False
|
767
|
+
raise TagConversionError(record=record,levelstack=self.object_map)
|
605
768
|
|
606
|
-
def
|
769
|
+
def handle_crea(self, record: GedcomRecord):
|
607
770
|
if isinstance(self.object_map[record.level-1], SourceDescription):
|
608
|
-
self.object_map[record.level-1].created = Date(original=record.
|
771
|
+
self.object_map[record.level-1].created = Date(original=record.subRecord('DATE'))
|
772
|
+
|
773
|
+
elif isinstance(self.object_map[record.level-1], Agent):
|
774
|
+
if self.object_map[record.level-1].attribution is None:
|
775
|
+
gxobject = Attribution()
|
776
|
+
self.object_map[record.level-1].attribution = gxobject
|
777
|
+
self.object_stack.append(gxobject)
|
778
|
+
self.object_map[record.level] = gxobject
|
779
|
+
else:
|
780
|
+
convert_log.info(f"[{record.tag}] Attribution already exists for SourceDescription with id: {self.object_map[record.level-1].id}")
|
609
781
|
else:
|
610
|
-
raise ValueError(f"Could not handle '
|
782
|
+
raise ValueError(f"Could not handle '{record.tag}' tag in record {record.describe()}, last stack object {self.object_map[record.level-1]}")
|
611
783
|
|
612
|
-
def handle_ctry(self, record):
|
784
|
+
def handle_ctry(self, record: GedcomRecord):
|
613
785
|
if isinstance(self.object_map[record.level-1], Address):
|
614
786
|
self.object_map[record.level-1].country = Translater.clean_str(record.value)
|
615
787
|
else:
|
616
|
-
raise ValueError(f"I do not know how to handle an '
|
788
|
+
raise ValueError(f"I do not know how to handle an '{record.tag}' tag for a {type(self.object_map[record.level-1])}")
|
617
789
|
|
618
790
|
def handle_data(self, record: GedcomRecord) -> None:
|
619
|
-
if record.value != '':
|
791
|
+
if record.value != '' and record.value == 'None':
|
620
792
|
assert False
|
621
|
-
self.object_map[record.level] =
|
793
|
+
self.object_map[record.level] = self.object_map[record.level-1]
|
622
794
|
|
623
795
|
def handle_date(self, record: GedcomRecord):
|
624
796
|
if record.parent.tag == 'PUBL':
|
625
|
-
gxobject = Date(original=record.value)
|
626
|
-
self.object_map[0].published = gxobject
|
627
|
-
|
628
|
-
self.
|
629
|
-
self.
|
797
|
+
#gxobject = Date(original=record.value) #TODO Make a parser for solid timestamps
|
798
|
+
#self.object_map[0].published = gxobject
|
799
|
+
#self.object_map[0].published = date_to_timestamp(record.value) if record.value else None
|
800
|
+
self.object_map[0].published = record.value
|
801
|
+
#self.object_stack.append(gxobject)
|
802
|
+
#self.object_map[record.level] = gxobject
|
630
803
|
elif isinstance(self.object_map[record.level-1], Event):
|
631
804
|
self.object_map[record.level-1].date = Date(original=record.value)
|
632
805
|
elif isinstance(self.object_map[record.level-1], Fact):
|
633
806
|
self.object_map[record.level-1].date = Date(original=record.value)
|
634
807
|
elif record.parent.tag == 'DATA' and isinstance(self.object_map[record.level-2], SourceReference):
|
635
808
|
gxobject = Note(text='Date: ' + record.value)
|
636
|
-
self.object_map[record.level-2].
|
809
|
+
self.object_map[record.level-2].description.add_note(gxobject)
|
637
810
|
self.object_stack.append(gxobject)
|
638
811
|
self.object_map[record.level] = gxobject
|
639
812
|
elif isinstance(self.object_map[record.level-1], SourceDescription):
|
640
813
|
|
641
814
|
self.object_map[record.level-1].ctreated = record.value #TODO String to timestamp
|
642
|
-
|
815
|
+
elif isinstance(self.object_map[record.level-1], Attribution):
|
816
|
+
if record.parent.tag == 'CREA':
|
817
|
+
self.object_map[record.level-1].created = record.value #TODO G7
|
818
|
+
elif record.parent.tag == "CHAN":
|
819
|
+
self.object_map[record.level-1].modified = record.value #TODO G7
|
820
|
+
elif record.parent.tag in ['CREA','CHAN']:
|
821
|
+
pass
|
822
|
+
|
643
823
|
else:
|
644
|
-
|
645
|
-
assert False
|
824
|
+
raise TagConversionError(record=record,levelstack=self.object_map)
|
646
825
|
|
647
|
-
def handle_deat(self, record):
|
826
|
+
def handle_deat(self, record: GedcomRecord):
|
648
827
|
if isinstance(self.object_map[record.level-1], Person):
|
649
828
|
gxobject = Fact(type=FactType.Death)
|
650
829
|
self.object_map[record.level-1].add_fact(gxobject)
|
@@ -652,12 +831,11 @@ class Translater():
|
|
652
831
|
self.object_stack.append(gxobject)
|
653
832
|
self.object_map[record.level] = gxobject
|
654
833
|
else:
|
655
|
-
|
656
|
-
assert False
|
834
|
+
raise TagConversionError(record=record,levelstack=self.object_map)
|
657
835
|
|
658
836
|
def handle_even(self, record: GedcomRecord):
|
659
837
|
# TODO If events in a @S, check if only 1 person matches?
|
660
|
-
if not record.value.strip() == '':
|
838
|
+
if record.value and (not record.value.strip() == ''):
|
661
839
|
values = [value.strip() for value in record.value.split(",")]
|
662
840
|
for value in values:
|
663
841
|
if value in Translater.gedcom_even_to_fact.keys():
|
@@ -667,18 +845,21 @@ class Translater():
|
|
667
845
|
|
668
846
|
self.object_stack.append(gxobject)
|
669
847
|
self.object_map[record.level] = gxobject
|
670
|
-
|
848
|
+
|
849
|
+
elif isinstance(self.object_map[record.level-1], SourceDescription):
|
850
|
+
gxobject = Event(type=Translater.gedcom_even_to_evnt[value],sources=[self.object_map[record.level-1]])
|
851
|
+
self.gedcomx.add_event(gxobject)
|
852
|
+
self.object_stack.append(gxobject)
|
853
|
+
self.object_map[record.level] = gxobject
|
671
854
|
else:
|
672
|
-
|
855
|
+
raise TagConversionError(record=record,levelstack=self.object_map)
|
673
856
|
assert False
|
674
857
|
# TODO: Fix, this. making an event to cacth subtags, why are these fact tied to a source? GEDCOM is horrible
|
675
858
|
gxobject = Event(type=EventType.UNKNOWN)
|
676
859
|
self.object_stack.append(gxobject)
|
677
860
|
self.object_map[record.level] = gxobject
|
678
861
|
else:
|
679
|
-
|
680
|
-
|
681
|
-
print("This event does not look like a Fact")
|
862
|
+
raise TagConversionError(record=record,levelstack=self.object_map)
|
682
863
|
|
683
864
|
else:
|
684
865
|
possible_fact = FactType.guess(record.subRecord('TYPE')[0].value)
|
@@ -708,6 +889,13 @@ class Translater():
|
|
708
889
|
else:
|
709
890
|
assert False
|
710
891
|
|
892
|
+
def handle_exid(self,record: GedcomRecord):
|
893
|
+
gxobject = Identifier(type=IdentifierType.External,value=[record.value])
|
894
|
+
self.object_map[record.level-1].add_identifier(gxobject)
|
895
|
+
|
896
|
+
self.object_stack.append(gxobject)
|
897
|
+
self.object_map[record.level] = gxobject
|
898
|
+
|
711
899
|
def handle_fam(self, record: GedcomRecord) -> None:
|
712
900
|
if record.tag != 'FAM' or record.level != 0:
|
713
901
|
raise ValueError("Invalid record: Must be a level 0 FAM record")
|
@@ -716,16 +904,16 @@ class Translater():
|
|
716
904
|
|
717
905
|
husband_record = record.subRecords('HUSB')
|
718
906
|
if husband_record:
|
719
|
-
husband = self.gedcomx.
|
907
|
+
husband = self.gedcomx.get_person_by_id(husband_record[0].xref)
|
720
908
|
|
721
909
|
wife_record = record.subRecords('WIFE')
|
722
910
|
if wife_record:
|
723
|
-
wife = self.gedcomx.
|
911
|
+
wife = self.gedcomx.get_person_by_id(wife_record[0].xref)
|
724
912
|
|
725
913
|
children_records = record.subRecords('CHIL')
|
726
914
|
if children_records:
|
727
915
|
for child_record in children_records:
|
728
|
-
child = self.gedcomx.
|
916
|
+
child = self.gedcomx.get_person_by_id(child_record.xref)
|
729
917
|
if child:
|
730
918
|
children.append(child)
|
731
919
|
|
@@ -748,41 +936,43 @@ class Translater():
|
|
748
936
|
return
|
749
937
|
|
750
938
|
def handle_file(self, record: GedcomRecord):
|
751
|
-
if record.value.strip() != '':
|
939
|
+
if record.value and record.value.strip() != '':
|
752
940
|
#raise ValueError(f"I did not expect the 'FILE' tag to have a value: {record.value}")
|
753
941
|
#TODO Handle files referenced here
|
754
942
|
...
|
755
943
|
elif isinstance(self.object_map[record.level-1], SourceDescription):
|
756
944
|
...
|
757
945
|
self.object_map[record.level-1].resourceType = ResourceType.DigitalArtifact
|
758
|
-
|
759
|
-
|
946
|
+
|
760
947
|
def handle_form(self, record: GedcomRecord):
|
761
948
|
if record.parent.tag == 'FILE' and isinstance(self.object_map[record.level-2], SourceDescription):
|
762
|
-
if record.value.strip() != '':
|
949
|
+
if record.value and record.value.strip() != '':
|
763
950
|
mime_type, _ = mimetypes.guess_type('placehold.' + record.value)
|
764
951
|
if mime_type:
|
765
952
|
self.object_map[record.level-2].mediaType = mime_type
|
766
953
|
else:
|
767
954
|
print(f"Could not determing mime type from {record.value}")
|
955
|
+
elif isinstance(self.object_map[record.level-1], PlaceDescription):
|
956
|
+
self.object_map[record.level-1].names.append(TextValue(value=record.value))
|
957
|
+
elif record.parent.tag == 'TRAN':
|
958
|
+
pass #TODO
|
768
959
|
else:
|
769
|
-
raise
|
960
|
+
raise TagConversionError(record=record,levelstack=self.object_map)
|
770
961
|
|
771
|
-
def handle_givn(self, record):
|
962
|
+
def handle_givn(self, record: GedcomRecord):
|
772
963
|
if isinstance(self.object_map[record.level-1], Name):
|
773
964
|
given_name = NamePart(value=record.value, type=NamePartType.Given)
|
774
965
|
self.object_map[record.level-1]._add_name_part(given_name)
|
775
966
|
else:
|
776
|
-
|
777
|
-
assert False
|
967
|
+
raise TagConversionError(record=record,levelstack=self.object_map)
|
778
968
|
|
779
|
-
def handle_indi(self, record):
|
969
|
+
def handle_indi(self, record: GedcomRecord):
|
780
970
|
person = Person(id=record.xref.replace('@',''))
|
781
971
|
self.gedcomx.add_person(person)
|
782
972
|
self.object_stack.append(person)
|
783
973
|
self.object_map[record.level] = person
|
784
974
|
|
785
|
-
def handle_immi(self, record):
|
975
|
+
def handle_immi(self, record: GedcomRecord):
|
786
976
|
if isinstance(self.object_map[record.level-1], Person):
|
787
977
|
gxobject = Fact(type=FactType.Immigration)
|
788
978
|
self.object_map[record.level-1].add_fact(gxobject)
|
@@ -790,10 +980,9 @@ class Translater():
|
|
790
980
|
self.object_stack.append(gxobject)
|
791
981
|
self.object_map[record.level] = gxobject
|
792
982
|
else:
|
793
|
-
|
794
|
-
assert False
|
983
|
+
raise TagConversionError(record=record,levelstack=self.object_map)
|
795
984
|
|
796
|
-
def handle_marr(self, record):
|
985
|
+
def handle_marr(self, record: GedcomRecord):
|
797
986
|
if isinstance(self.object_map[record.level-1], Person):
|
798
987
|
gxobject = Fact(type=FactType.Marriage)
|
799
988
|
self.object_map[record.level-1].add_fact(gxobject)
|
@@ -801,10 +990,9 @@ class Translater():
|
|
801
990
|
self.object_stack.append(gxobject)
|
802
991
|
self.object_map[record.level] = gxobject
|
803
992
|
else:
|
804
|
-
|
805
|
-
assert False
|
993
|
+
raise TagConversionError(record=record,levelstack=self.object_map)
|
806
994
|
|
807
|
-
def handle_name(self, record):
|
995
|
+
def handle_name(self, record: GedcomRecord):
|
808
996
|
if isinstance(self.object_map[record.level-1], Person):
|
809
997
|
gxobject = Name.simple(record.value)
|
810
998
|
#gxobject = Name(nameForms=[NameForm(fullText=record.value)], type=NameType.BirthName)
|
@@ -816,10 +1004,9 @@ class Translater():
|
|
816
1004
|
gxobject = TextValue(value=record.value)
|
817
1005
|
self.object_map[record.level-1].add_name(gxobject)
|
818
1006
|
else:
|
819
|
-
|
820
|
-
assert False
|
1007
|
+
raise TagConversionError(record=record,levelstack=self.object_map)
|
821
1008
|
|
822
|
-
def handle_note(self, record):
|
1009
|
+
def handle_note(self, record: GedcomRecord):
|
823
1010
|
if isinstance(self.object_map[record.level-1], SourceDescription):
|
824
1011
|
gxobject = Note(text=Translater.clean_str(record.value))
|
825
1012
|
self.object_map[record.level-1].add_note(gxobject)
|
@@ -828,7 +1015,7 @@ class Translater():
|
|
828
1015
|
self.object_map[record.level] = gxobject
|
829
1016
|
elif isinstance(self.object_map[record.level-1], SourceReference):
|
830
1017
|
gxobject = Note(text=Translater.clean_str(record.value))
|
831
|
-
self.object_map[record.level-1].
|
1018
|
+
self.object_map[record.level-1].description.add_note(gxobject)
|
832
1019
|
|
833
1020
|
self.object_stack.append(gxobject)
|
834
1021
|
self.object_map[record.level] = gxobject
|
@@ -838,19 +1025,30 @@ class Translater():
|
|
838
1025
|
|
839
1026
|
self.object_stack.append(gxobject)
|
840
1027
|
self.object_map[record.level] = gxobject
|
1028
|
+
elif isinstance(self.object_map[record.level-1], Agent):
|
1029
|
+
gxobject = Note(text=record.value)
|
1030
|
+
self.object_map[record.level-1].add_note(gxobject)
|
1031
|
+
|
1032
|
+
self.object_stack.append(gxobject)
|
1033
|
+
self.object_map[record.level] = gxobject
|
1034
|
+
elif isinstance(self.object_map[record.level-1], Attribution):
|
1035
|
+
if self.object_map[record.level-1].changeMessage is None:
|
1036
|
+
self.object_map[record.level-1].changeMessage = record.value
|
1037
|
+
else:
|
1038
|
+
self.object_map[record.level-1].changeMessage = self.object_map[record.level-1].changeMessage + '' + record.value
|
1039
|
+
|
841
1040
|
else:
|
842
1041
|
raise ValueError(f"Could not handle 'NOTE' tag in record {record.describe()}, last stack object {type(self.object_map[record.level-1])}")
|
843
1042
|
assert False
|
844
1043
|
|
845
|
-
def handle_nsfx(self, record):
|
1044
|
+
def handle_nsfx(self, record: GedcomRecord):
|
846
1045
|
if isinstance(self.object_map[record.level-1], Name):
|
847
1046
|
surname = NamePart(value=record.value, type=NamePartType.Suffix)
|
848
1047
|
self.object_map[record.level-1]._add_name_part(surname)
|
849
1048
|
else:
|
850
|
-
|
851
|
-
assert False
|
1049
|
+
raise TagConversionError(record=record,levelstack=self.object_map)
|
852
1050
|
|
853
|
-
def handle_occu(self, record):
|
1051
|
+
def handle_occu(self, record: GedcomRecord):
|
854
1052
|
if isinstance(self.object_map[record.level-1], Person):
|
855
1053
|
gxobject = Fact(type=FactType.Occupation)
|
856
1054
|
self.object_map[record.level-1].add_fact(gxobject)
|
@@ -858,13 +1056,12 @@ class Translater():
|
|
858
1056
|
self.object_stack.append(gxobject)
|
859
1057
|
self.object_map[record.level] = gxobject
|
860
1058
|
else:
|
861
|
-
|
862
|
-
assert False
|
1059
|
+
raise TagConversionError(record=record,levelstack=self.object_map)
|
863
1060
|
|
864
1061
|
def handle_obje(self, record: GedcomRecord):
|
865
1062
|
self.handle_sour(record)
|
866
1063
|
|
867
|
-
def handle_page(self, record):
|
1064
|
+
def handle_page(self, record: GedcomRecord):
|
868
1065
|
if isinstance(self.object_map[record.level-1], SourceReference):
|
869
1066
|
self.object_map[record.level-1].descriptionId = record.value
|
870
1067
|
self.object_map[record.level-1].add_qualifier(KnownSourceReference.Page)
|
@@ -875,7 +1072,7 @@ class Translater():
|
|
875
1072
|
else:
|
876
1073
|
raise ValueError(f"Could not handle 'PAGE' tag in record {record.describe()}, last stack object {self.object_map[record.level-1]}")
|
877
1074
|
|
878
|
-
def handle_plac(self, record):
|
1075
|
+
def handle_plac(self, record: GedcomRecord):
|
879
1076
|
if isinstance(self.object_map[record.level-1], Agent):
|
880
1077
|
gxobject = Address(value=record.value)
|
881
1078
|
self.object_map[record.level-1].add_address(gxobject)
|
@@ -889,6 +1086,9 @@ class Translater():
|
|
889
1086
|
place_des = PlaceDescription(names=[TextValue(value=record.value)])
|
890
1087
|
self.gedcomx.add_place_description(place_des)
|
891
1088
|
self.object_map[record.level-1].place = PlaceReference(original=record.value, descriptionRef=place_des)
|
1089
|
+
if len(record.subRecords()) > 0:
|
1090
|
+
self.object_map[record.level]= place_des
|
1091
|
+
|
892
1092
|
elif isinstance(self.object_map[record.level-1], Fact):
|
893
1093
|
if self.gedcomx.places.byName(record.value):
|
894
1094
|
self.object_map[record.level-1].place = PlaceReference(original=record.value, descriptionRef=self.gedcomx.places.byName(record.value)[0])
|
@@ -902,18 +1102,17 @@ class Translater():
|
|
902
1102
|
self.object_stack.append(gxobject)
|
903
1103
|
self.object_map[record.level] = gxobject
|
904
1104
|
else:
|
905
|
-
|
906
|
-
assert False
|
1105
|
+
raise TagConversionError(record=record,levelstack=self.object_map)
|
907
1106
|
|
908
|
-
def handle_post(self, record):
|
1107
|
+
def handle_post(self, record: GedcomRecord):
|
909
1108
|
if isinstance(self.object_map[record.level-1], Address):
|
910
1109
|
self.object_map[record.level-1].postalCode = Translater.clean_str(record.value)
|
911
1110
|
else:
|
912
1111
|
raise ValueError(f"I do not know how to handle an 'POST' tag for a {type(self.object_map[record.level-1])}")
|
913
1112
|
|
914
|
-
def handle_publ(self, record):
|
1113
|
+
def handle_publ(self, record: GedcomRecord):
|
915
1114
|
if isinstance(self.object_map[record.level-1], SourceDescription):
|
916
|
-
if self.gedcomx.agents.byName(record.value):
|
1115
|
+
if record.value and self.gedcomx.agents.byName(record.value):
|
917
1116
|
gxobject = self.gedcomx.agents.byName(record.value)[0]
|
918
1117
|
else:
|
919
1118
|
gxobject = Agent(names=[TextValue(record.value)])
|
@@ -923,10 +1122,9 @@ class Translater():
|
|
923
1122
|
self.object_stack.append(gxobject)
|
924
1123
|
self.object_map[record.level] = gxobject
|
925
1124
|
else:
|
926
|
-
|
927
|
-
assert False
|
1125
|
+
raise TagConversionError(record=record,levelstack=self.object_map)
|
928
1126
|
|
929
|
-
def handle_prob(self, record):
|
1127
|
+
def handle_prob(self, record: GedcomRecord):
|
930
1128
|
if isinstance(self.object_map[record.level-1], Person):
|
931
1129
|
gxobject = Fact(type=FactType.Probate)
|
932
1130
|
self.object_map[record.level-1].add_fact(gxobject)
|
@@ -934,28 +1132,46 @@ class Translater():
|
|
934
1132
|
self.object_stack.append(gxobject)
|
935
1133
|
self.object_map[record.level] = gxobject
|
936
1134
|
else:
|
937
|
-
|
938
|
-
assert False
|
1135
|
+
raise TagConversionError(record=record,levelstack=self.object_map)
|
939
1136
|
|
940
|
-
def
|
1137
|
+
def handle_uid(self, record: GedcomRecord):
|
1138
|
+
if isinstance(self.object_map[record.level-1], Agent):
|
1139
|
+
gxobject = Identifier(value=['UID:' + record.value],type=IdentifierType.Primary)
|
1140
|
+
self.object_map[record.level-1].add_identifier(gxobject) #NOTE GC7
|
1141
|
+
self.object_stack.append(gxobject)
|
1142
|
+
self.object_map[record.level] = gxobject
|
1143
|
+
|
1144
|
+
def handle_refn(self, record: GedcomRecord):
|
941
1145
|
if isinstance(self.object_map[record.level-1], Person) or isinstance(self.object_map[record.level-1], SourceDescription):
|
942
|
-
|
1146
|
+
gxobject = Identifier(value=[URI.from_url('Reference Number:' + record.value)])
|
1147
|
+
self.object_map[record.level-1].add_identifier(gxobject)
|
1148
|
+
self.object_stack.append(gxobject)
|
1149
|
+
self.object_map[record.level] = gxobject
|
1150
|
+
elif isinstance(self.object_map[record.level-1], Agent):
|
1151
|
+
gxobject = Identifier(value=['Reference Number:' + record.value])
|
1152
|
+
self.object_map[record.level-1].add_identifier(gxobject) #NOTE GC7
|
1153
|
+
self.object_stack.append(gxobject)
|
1154
|
+
self.object_map[record.level] = gxobject
|
943
1155
|
else:
|
944
1156
|
raise ValueError(f"Could not handle 'REFN' tag in record {record.describe()}, last stack object {type(self.object_map[record.level-1])}")
|
945
1157
|
|
946
|
-
def handle_repo(self, record):
|
1158
|
+
def handle_repo(self, record: GedcomRecord):
|
1159
|
+
|
947
1160
|
if record.level == 0:
|
948
1161
|
|
949
|
-
gxobject = Agent(id=record.
|
1162
|
+
gxobject = Agent(id=record.xref)
|
950
1163
|
self.gedcomx.add_agent(gxobject)
|
951
1164
|
self.object_stack.append(gxobject)
|
952
1165
|
self.object_map[record.level] = gxobject
|
953
1166
|
|
954
1167
|
elif isinstance(self.object_map[record.level-1], SourceDescription):
|
955
|
-
if self.gedcomx.agents.byId(record.
|
1168
|
+
if self.gedcomx.agents.byId(record.xref) is not None:
|
1169
|
+
|
956
1170
|
# TODO WHere and what to add this to?
|
957
|
-
gxobject = self.gedcomx.agents.byId(record.
|
1171
|
+
gxobject = self.gedcomx.agents.byId(record.xref)
|
958
1172
|
self.object_map[record.level-1].repository = gxobject
|
1173
|
+
self.object_map[record.level] = gxobject
|
1174
|
+
|
959
1175
|
else:
|
960
1176
|
print(record.describe())
|
961
1177
|
raise ValueError()
|
@@ -967,20 +1183,19 @@ class Translater():
|
|
967
1183
|
self.object_stack.append(gxobject)
|
968
1184
|
self.object_map[record.level] = gxobject
|
969
1185
|
|
970
|
-
def handle_resi(self, record):
|
1186
|
+
def handle_resi(self, record: GedcomRecord):
|
971
1187
|
if isinstance(self.object_map[record.level-1], Person):
|
972
1188
|
gxobject = Fact(type=FactType.Residence)
|
973
|
-
if record.value.strip() != '':
|
1189
|
+
if record.value and record.value.strip() != '':
|
974
1190
|
gxobject.add_note(Note(text=record.value))
|
975
1191
|
self.object_map[record.level-1].add_fact(gxobject)
|
976
1192
|
|
977
1193
|
self.object_stack.append(gxobject)
|
978
1194
|
self.object_map[record.level] = gxobject
|
979
1195
|
else:
|
980
|
-
|
981
|
-
assert False
|
1196
|
+
raise TagConversionError(record=record,levelstack=self.object_map)
|
982
1197
|
|
983
|
-
def handle_rin(self, record):
|
1198
|
+
def handle_rin(self, record: GedcomRecord):
|
984
1199
|
if isinstance(self.object_map[record.level-1], SourceDescription):
|
985
1200
|
self.object_map[record.level-1].id = record.value
|
986
1201
|
self.object_map[record.level-1].add_note(Note(text=f"Source had RIN: of {record.value}"))
|
@@ -1004,51 +1219,59 @@ class Translater():
|
|
1004
1219
|
else:
|
1005
1220
|
assert False
|
1006
1221
|
|
1007
|
-
def handle_sour(self, record):
|
1222
|
+
def handle_sour(self, record: GedcomRecord):
|
1008
1223
|
if record.level == 0 or record.tag == '_WLNK' or (record.level == 0 and record.tag == 'OBJE'):
|
1009
|
-
source_description = SourceDescription(id=record.xref)
|
1224
|
+
source_description = SourceDescription(id=record.xref.replace('@','') if record.xref else None)
|
1010
1225
|
self.gedcomx.add_source_description(source_description)
|
1011
1226
|
self.object_stack.append(source_description)
|
1012
1227
|
self.object_map[record.level] = source_description
|
1013
1228
|
else:
|
1229
|
+
# This 'SOUR' is a SourceReference
|
1230
|
+
if record.xref and record.xref.strip() == '':
|
1231
|
+
import_log.warning(f"SOUR points to nothing: {record.describe()}")
|
1232
|
+
return False
|
1014
1233
|
if self.gedcomx.source_descriptions.byId(record.xref):
|
1015
1234
|
gxobject = SourceReference(descriptionId=record.xref, description=self.gedcomx.source_descriptions.byId(record.xref))
|
1016
1235
|
else:
|
1236
|
+
import_log.warning(f'Could not find source with id: {record.xref}')
|
1017
1237
|
source_description = SourceDescription(id=record.xref)
|
1018
1238
|
gxobject = SourceReference(descriptionId=record.value, description=source_description)
|
1019
|
-
|
1020
|
-
|
1021
|
-
|
1022
|
-
|
1239
|
+
if isinstance(self.object_map[record.level-1],SourceReference):
|
1240
|
+
self.object_map[record.level-1].description.add_source(gxobject)
|
1241
|
+
elif record.parent.tag in ['NOTE']:
|
1242
|
+
pass
|
1243
|
+
else:
|
1244
|
+
self.object_map[record.level-1].add_source(gxobject)
|
1023
1245
|
self.object_stack.append(gxobject)
|
1024
1246
|
self.object_map[record.level] = gxobject
|
1025
|
-
|
1026
|
-
|
1027
|
-
def handle_stae(self, record):
|
1247
|
+
|
1248
|
+
def handle_stae(self, record: GedcomRecord):
|
1028
1249
|
if isinstance(self.object_map[record.level-1], Address):
|
1029
1250
|
self.object_map[record.level-1].stateOrProvince = Translater.clean_str(record.value)
|
1030
1251
|
else:
|
1031
1252
|
raise ValueError(f"I do not know how to handle an 'STAE' tag for a {type(self.object_map[record.level-1])}")
|
1032
1253
|
|
1033
|
-
def handle_surn(self, record):
|
1254
|
+
def handle_surn(self, record: GedcomRecord):
|
1034
1255
|
if isinstance(self.object_map[record.level-1], Name):
|
1035
1256
|
surname = NamePart(value=record.value, type=NamePartType.Surname)
|
1036
1257
|
self.object_map[record.level-1]._add_name_part(surname)
|
1037
1258
|
else:
|
1038
|
-
|
1039
|
-
assert False
|
1259
|
+
raise TagConversionError(record=record,levelstack=self.object_map)
|
1040
1260
|
|
1041
1261
|
def handle_text(self, record: GedcomRecord):
|
1042
1262
|
if record.parent.tag == 'DATA':
|
1043
1263
|
if isinstance(self.object_map[record.level-2], SourceReference):
|
1044
1264
|
gxobject = TextValue(value=record.value)
|
1045
|
-
self.object_map[record.level-2].
|
1265
|
+
self.object_map[record.level-2].description.add_description(gxobject)
|
1046
1266
|
self.object_stack.append(gxobject)
|
1047
1267
|
self.object_map[record.level] = gxobject
|
1268
|
+
elif isinstance(self.object_map[record.level-1], SourceDescription):
|
1269
|
+
gxobject = Document(text=record.value)
|
1270
|
+
self.object_map[record.level-1].analysis = gxobject
|
1048
1271
|
else:
|
1049
1272
|
assert False
|
1050
1273
|
|
1051
|
-
def handle_titl(self, record):
|
1274
|
+
def handle_titl(self, record: GedcomRecord):
|
1052
1275
|
if isinstance(self.object_map[record.level-1], SourceDescription):
|
1053
1276
|
|
1054
1277
|
gxobject = TextValue(value=Translater.clean_str(record.value))
|
@@ -1068,12 +1291,12 @@ class Translater():
|
|
1068
1291
|
|
1069
1292
|
self.object_map[record.level]._add_name_part(gxobject)
|
1070
1293
|
else:
|
1071
|
-
|
1072
|
-
print(self.object_map[record.level])
|
1073
|
-
raise ValueError(f"Could not handle 'TITL' tag in record {record.describe()}, last stack object {type(self.object_map[record.level-1])}")
|
1074
|
-
assert False
|
1294
|
+
raise TagConversionError(record=record,levelstack=self.object_map)
|
1075
1295
|
|
1076
|
-
def
|
1296
|
+
def handle_tran(self, record: GedcomRecord):
|
1297
|
+
pass
|
1298
|
+
|
1299
|
+
def handle_type(self, record: GedcomRecord):
|
1077
1300
|
# peek to see if event or fact
|
1078
1301
|
if isinstance(self.object_map[record.level-1], Event):
|
1079
1302
|
if EventType.guess(record.value):
|
@@ -1084,6 +1307,11 @@ class Translater():
|
|
1084
1307
|
elif isinstance(self.object_map[record.level-1], Fact):
|
1085
1308
|
if not self.object_map[record.level-1].type:
|
1086
1309
|
self.object_map[0].type = FactType.guess(record.value)
|
1310
|
+
elif isinstance(self.object_map[record.level-1], Identifier):
|
1311
|
+
|
1312
|
+
self.object_map[record.level-1].values.append(Translater.clean_str(record.value))
|
1313
|
+
self.object_map[record.level-1].type = IdentifierType.Other
|
1314
|
+
|
1087
1315
|
elif record.parent.tag == 'FORM':
|
1088
1316
|
if not self.object_map[0].mediaType:
|
1089
1317
|
self.object_map[0].mediaType = record.value
|
@@ -1091,15 +1319,17 @@ class Translater():
|
|
1091
1319
|
else:
|
1092
1320
|
raise ValueError(f"I do not know how to handle 'TYPE' tag for {type(self.object_map[record.level-1])}")
|
1093
1321
|
|
1094
|
-
def handle__url(self, record):
|
1322
|
+
def handle__url(self, record: GedcomRecord):
|
1095
1323
|
if isinstance(self.object_map[record.level-2], SourceDescription):
|
1096
1324
|
self.object_map[record.level-2].about = URI.from_url(record.value)
|
1097
1325
|
else:
|
1098
1326
|
raise ValueError(f"Could not handle '_URL' tag in record {record.describe()}, last stack object {self.object_map[record.level-1]}")
|
1099
1327
|
|
1100
|
-
def handle_www(self, record):
|
1101
|
-
if isinstance(self.object_map[record.level-
|
1102
|
-
self.object_map[record.level-
|
1328
|
+
def handle_www(self, record: GedcomRecord):
|
1329
|
+
if isinstance(self.object_map[record.level-1], Agent):
|
1330
|
+
self.object_map[record.level-1].homepage = Translater.clean_str(record.value)
|
1331
|
+
elif isinstance(self.object_map[record.level-2], SourceReference):
|
1332
|
+
self.object_map[record.level-2].description.add_identifier(Identifier(value=URI.from_url(record.value)))
|
1103
1333
|
else:
|
1104
1334
|
raise ValueError(f"Could not handle 'WWW' tag in record {record.describe()}, last stack object {self.object_map[record.level-1]}")
|
1105
1335
|
|