gedcom-x 0.5.7__py3-none-any.whl → 0.5.9__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.7.dist-info → gedcom_x-0.5.9.dist-info}/METADATA +1 -1
- gedcom_x-0.5.9.dist-info/RECORD +56 -0
- gedcomx/Extensions/rs10/rsLink.py +110 -60
- gedcomx/TopLevelTypeCollection.py +1 -1
- gedcomx/__init__.py +43 -42
- gedcomx/address.py +217 -0
- gedcomx/{Agent.py → agent.py} +107 -34
- gedcomx/attribution.py +115 -0
- gedcomx/{Conclusion.py → conclusion.py} +120 -51
- gedcomx/{Converter.py → converter.py} +261 -116
- gedcomx/coverage.py +64 -0
- gedcomx/{Date.py → date.py} +43 -9
- gedcomx/{Document.py → document.py} +60 -12
- gedcomx/{Event.py → event.py} +88 -31
- gedcomx/evidence_reference.py +20 -0
- gedcomx/{Fact.py → fact.py} +81 -74
- gedcomx/{Gedcom.py → gedcom.py} +10 -0
- gedcomx/{Gedcom5x.py → gedcom5x.py} +31 -21
- gedcomx/gedcom7/Exceptions.py +9 -0
- gedcomx/gedcom7/GedcomStructure.py +94 -0
- gedcomx/gedcom7/Specification.py +347 -0
- gedcomx/gedcom7/__init__.py +26 -0
- gedcomx/gedcom7/g7interop.py +205 -0
- gedcomx/gedcom7/gedcom7.py +160 -0
- gedcomx/gedcom7/logger.py +19 -0
- gedcomx/{GedcomX.py → gedcomx.py} +109 -106
- gedcomx/gender.py +91 -0
- gedcomx/group.py +72 -0
- gedcomx/{Identifier.py → identifier.py} +48 -21
- gedcomx/{LoggingHub.py → logging_hub.py} +19 -0
- gedcomx/{Mutations.py → mutations.py} +59 -30
- gedcomx/{Name.py → name.py} +88 -47
- gedcomx/note.py +105 -0
- gedcomx/online_account.py +19 -0
- gedcomx/{Person.py → person.py} +61 -41
- gedcomx/{PlaceDescription.py → place_description.py} +71 -23
- gedcomx/{PlaceReference.py → place_reference.py} +32 -10
- gedcomx/{Qualifier.py → qualifier.py} +20 -4
- gedcomx/relationship.py +156 -0
- gedcomx/resource.py +112 -0
- gedcomx/serialization.py +794 -0
- gedcomx/source_citation.py +37 -0
- gedcomx/source_description.py +401 -0
- gedcomx/{SourceReference.py → source_reference.py} +56 -21
- gedcomx/subject.py +122 -0
- gedcomx/textvalue.py +89 -0
- gedcomx/{Translation.py → translation.py} +4 -4
- gedcomx/uri.py +273 -0
- gedcom_x-0.5.7.dist-info/RECORD +0 -49
- gedcomx/Address.py +0 -131
- gedcomx/Attribution.py +0 -91
- gedcomx/Coverage.py +0 -37
- gedcomx/EvidenceReference.py +0 -11
- gedcomx/Gender.py +0 -65
- gedcomx/Group.py +0 -37
- gedcomx/Note.py +0 -73
- gedcomx/OnlineAccount.py +0 -10
- gedcomx/Relationship.py +0 -97
- gedcomx/Resource.py +0 -85
- gedcomx/Serialization.py +0 -816
- gedcomx/SourceCitation.py +0 -25
- gedcomx/SourceDescription.py +0 -314
- gedcomx/Subject.py +0 -59
- gedcomx/TextValue.py +0 -35
- gedcomx/URI.py +0 -105
- {gedcom_x-0.5.7.dist-info → gedcom_x-0.5.9.dist-info}/WHEEL +0 -0
- {gedcom_x-0.5.7.dist-info → gedcom_x-0.5.9.dist-info}/top_level.txt +0 -0
- /gedcomx/{Exceptions.py → exceptions.py} +0 -0
- /gedcomx/{ExtensibleEnum.py → extensible_enum.py} +0 -0
@@ -0,0 +1,205 @@
|
|
1
|
+
from .. import *
|
2
|
+
|
3
|
+
g7toX = {
|
4
|
+
"ABBR": "https://gedcom.io/terms/v7/ABBR",
|
5
|
+
"ADDR": "https://gedcom.io/terms/v7/ADDR",
|
6
|
+
"ADOP": "https://gedcom.io/terms/v7/ADOP",
|
7
|
+
"ADOP-FAMC": "https://gedcom.io/terms/v7/ADOP-FAMC",
|
8
|
+
"ADR1": "https://gedcom.io/terms/v7/ADR1",
|
9
|
+
"ADR2": "https://gedcom.io/terms/v7/ADR2",
|
10
|
+
"ADR3": "https://gedcom.io/terms/v7/ADR3",
|
11
|
+
"AGE": "https://gedcom.io/terms/v7/AGE",
|
12
|
+
"AGNC": "https://gedcom.io/terms/v7/AGNC",
|
13
|
+
"ALIA": "https://gedcom.io/terms/v7/ALIA",
|
14
|
+
"ANCI": "https://gedcom.io/terms/v7/ANCI",
|
15
|
+
"ANUL": "https://gedcom.io/terms/v7/ANUL",
|
16
|
+
"ASSO": "https://gedcom.io/terms/v7/ASSO",
|
17
|
+
"AUTH": "https://gedcom.io/terms/v7/AUTH",
|
18
|
+
"BAPL": "https://gedcom.io/terms/v7/BAPL",
|
19
|
+
"BAPM": "https://gedcom.io/terms/v7/BAPM",
|
20
|
+
"BARM": "https://gedcom.io/terms/v7/BARM",
|
21
|
+
"BASM": "https://gedcom.io/terms/v7/BASM",
|
22
|
+
"BIRT": "https://gedcom.io/terms/v7/BIRT",
|
23
|
+
"BLES": "https://gedcom.io/terms/v7/BLES",
|
24
|
+
"BURI": "https://gedcom.io/terms/v7/BURI",
|
25
|
+
"CALN": "https://gedcom.io/terms/v7/CALN",
|
26
|
+
"CAST": "https://gedcom.io/terms/v7/CAST",
|
27
|
+
"CAUS": "https://gedcom.io/terms/v7/CAUS",
|
28
|
+
"CENS": "https://gedcom.io/terms/v7/CENS",
|
29
|
+
"CHAN": "https://gedcom.io/terms/v7/CHAN",
|
30
|
+
"CHIL": "https://gedcom.io/terms/v7/CHIL",
|
31
|
+
"CHR": "https://gedcom.io/terms/v7/CHR",
|
32
|
+
"CHRA": "https://gedcom.io/terms/v7/CHRA",
|
33
|
+
"CITY": "https://gedcom.io/terms/v7/CITY",
|
34
|
+
"CONF": "https://gedcom.io/terms/v7/CONF",
|
35
|
+
"CONL": "https://gedcom.io/terms/v7/CONL",
|
36
|
+
"CONT": "https://gedcom.io/terms/v7/CONT",
|
37
|
+
"COPR": "https://gedcom.io/terms/v7/COPR",
|
38
|
+
"CORP": "https://gedcom.io/terms/v7/CORP",
|
39
|
+
"CREA": "https://gedcom.io/terms/v7/CREA",
|
40
|
+
"CREM": "https://gedcom.io/terms/v7/CREM",
|
41
|
+
"CROP": "https://gedcom.io/terms/v7/CROP",
|
42
|
+
"CTRY": "https://gedcom.io/terms/v7/CTRY",
|
43
|
+
"DATA": "https://gedcom.io/terms/v7/DATA",
|
44
|
+
"DATA-EVEN": "https://gedcom.io/terms/v7/DATA-EVEN",
|
45
|
+
"DATA-EVEN-DATE": "https://gedcom.io/terms/v7/DATA-EVEN-DATE",
|
46
|
+
"DATE": "https://gedcom.io/terms/v7/DATE",
|
47
|
+
"DATE-exact": "https://gedcom.io/terms/v7/DATE-exact",
|
48
|
+
"DEAT": "https://gedcom.io/terms/v7/DEAT",
|
49
|
+
"DESI": "https://gedcom.io/terms/v7/DESI",
|
50
|
+
"DEST": "https://gedcom.io/terms/v7/DEST",
|
51
|
+
"DIV": "https://gedcom.io/terms/v7/DIV",
|
52
|
+
"DIVF": "https://gedcom.io/terms/v7/DIVF",
|
53
|
+
"DSCR": "https://gedcom.io/terms/v7/DSCR",
|
54
|
+
"EDUC": "https://gedcom.io/terms/v7/EDUC",
|
55
|
+
"EMAIL": "https://gedcom.io/terms/v7/EMAIL",
|
56
|
+
"EMIG": "https://gedcom.io/terms/v7/EMIG",
|
57
|
+
"ENDL": "https://gedcom.io/terms/v7/ENDL",
|
58
|
+
"ENGA": "https://gedcom.io/terms/v7/ENGA",
|
59
|
+
"EVEN": "https://gedcom.io/terms/v7/EVEN",
|
60
|
+
"EXID": "https://gedcom.io/terms/v7/EXID",
|
61
|
+
"EXID-TYPE": "https://gedcom.io/terms/v7/EXID-TYPE",
|
62
|
+
"FACT": "https://gedcom.io/terms/v7/FACT",
|
63
|
+
"FAM": "https://gedcom.io/terms/v7/FAM",
|
64
|
+
"FAM-CENS": "https://gedcom.io/terms/v7/FAM-CENS",
|
65
|
+
"FAM-EVEN": "https://gedcom.io/terms/v7/FAM-EVEN",
|
66
|
+
"FAM-FACT": "https://gedcom.io/terms/v7/FAM-FACT",
|
67
|
+
"FAM-HUSB": "https://gedcom.io/terms/v7/FAM-HUSB",
|
68
|
+
"FAM-NCHI": "https://gedcom.io/terms/v7/FAM-NCHI",
|
69
|
+
"FAM-RESI": "https://gedcom.io/terms/v7/FAM-RESI",
|
70
|
+
"FAM-WIFE": "https://gedcom.io/terms/v7/FAM-WIFE",
|
71
|
+
"FAMC": "https://gedcom.io/terms/v7/FAMC",
|
72
|
+
"FAMC-ADOP": "https://gedcom.io/terms/v7/FAMC-ADOP",
|
73
|
+
"FAMC-STAT": "https://gedcom.io/terms/v7/FAMC-STAT",
|
74
|
+
"FAMS": "https://gedcom.io/terms/v7/FAMS",
|
75
|
+
"FAX": "https://gedcom.io/terms/v7/FAX",
|
76
|
+
"FCOM": "https://gedcom.io/terms/v7/FCOM",
|
77
|
+
"FILE": "https://gedcom.io/terms/v7/FILE",
|
78
|
+
"FILE-TRAN": "https://gedcom.io/terms/v7/FILE-TRAN",
|
79
|
+
"FORM": "https://gedcom.io/terms/v7/FORM",
|
80
|
+
"GEDC": "https://gedcom.io/terms/v7/GEDC",
|
81
|
+
"GEDC-VERS": "https://gedcom.io/terms/v7/GEDC-VERS",
|
82
|
+
"GIVN": "https://gedcom.io/terms/v7/GIVN",
|
83
|
+
"GRAD": "https://gedcom.io/terms/v7/GRAD",
|
84
|
+
"HEAD": "https://gedcom.io/terms/v7/HEAD",
|
85
|
+
"HEAD-DATE": "https://gedcom.io/terms/v7/HEAD-DATE",
|
86
|
+
"HEAD-LANG": "https://gedcom.io/terms/v7/HEAD-LANG",
|
87
|
+
"HEAD-PLAC": "https://gedcom.io/terms/v7/HEAD-PLAC",
|
88
|
+
"HEAD-PLAC-FORM": "https://gedcom.io/terms/v7/HEAD-PLAC-FORM",
|
89
|
+
"HEAD-SOUR": "https://gedcom.io/terms/v7/HEAD-SOUR",
|
90
|
+
"HEAD-SOUR-DATA": "https://gedcom.io/terms/v7/HEAD-SOUR-DATA",
|
91
|
+
"HEIGHT": "https://gedcom.io/terms/v7/HEIGHT",
|
92
|
+
"HUSB": "https://gedcom.io/terms/v7/HUSB",
|
93
|
+
"IDNO": "https://gedcom.io/terms/v7/IDNO",
|
94
|
+
"IMMI": "https://gedcom.io/terms/v7/IMMI",
|
95
|
+
"INDI": "https://gedcom.io/terms/v7/INDI",
|
96
|
+
"INDI-CENS": "https://gedcom.io/terms/v7/INDI-CENS",
|
97
|
+
"INDI-EVEN": "https://gedcom.io/terms/v7/INDI-EVEN",
|
98
|
+
"INDI-FACT": "https://gedcom.io/terms/v7/INDI-FACT",
|
99
|
+
"INDI-FAMC": "https://gedcom.io/terms/v7/INDI-FAMC",
|
100
|
+
"INDI-NAME": "https://gedcom.io/terms/v7/INDI-NAME",
|
101
|
+
"INDI-NCHI": "https://gedcom.io/terms/v7/INDI-NCHI",
|
102
|
+
"INDI-RELI": "https://gedcom.io/terms/v7/INDI-RELI",
|
103
|
+
"INDI-RESI": "https://gedcom.io/terms/v7/INDI-RESI",
|
104
|
+
"INDI-TITL": "https://gedcom.io/terms/v7/INDI-TITL",
|
105
|
+
"INIL": "https://gedcom.io/terms/v7/INIL",
|
106
|
+
"LANG": "https://gedcom.io/terms/v7/LANG",
|
107
|
+
"LATI": "https://gedcom.io/terms/v7/LATI",
|
108
|
+
"LEFT": "https://gedcom.io/terms/v7/LEFT",
|
109
|
+
"LONG": "https://gedcom.io/terms/v7/LONG",
|
110
|
+
"MAP": "https://gedcom.io/terms/v7/MAP",
|
111
|
+
"MARB": "https://gedcom.io/terms/v7/MARB",
|
112
|
+
"MARC": "https://gedcom.io/terms/v7/MARC",
|
113
|
+
"MARL": "https://gedcom.io/terms/v7/MARL",
|
114
|
+
"MARR": "https://gedcom.io/terms/v7/MARR",
|
115
|
+
"MARS": "https://gedcom.io/terms/v7/MARS",
|
116
|
+
"MEDI": "https://gedcom.io/terms/v7/MEDI",
|
117
|
+
"MIME": "https://gedcom.io/terms/v7/MIME",
|
118
|
+
"NAME": "https://gedcom.io/terms/v7/NAME",
|
119
|
+
"NAME-TRAN": "https://gedcom.io/terms/v7/NAME-TRAN",
|
120
|
+
"NAME-TYPE": "https://gedcom.io/terms/v7/NAME-TYPE",
|
121
|
+
"NATI": "https://gedcom.io/terms/v7/NATI",
|
122
|
+
"NATU": "https://gedcom.io/terms/v7/NATU",
|
123
|
+
"NCHI": "https://gedcom.io/terms/v7/NCHI",
|
124
|
+
"NICK": "https://gedcom.io/terms/v7/NICK",
|
125
|
+
"NMR": "https://gedcom.io/terms/v7/NMR",
|
126
|
+
"NO": "https://gedcom.io/terms/v7/NO",
|
127
|
+
"NO-DATE": "https://gedcom.io/terms/v7/NO-DATE",
|
128
|
+
"NOTE": "https://gedcom.io/terms/v7/NOTE",
|
129
|
+
"NOTE-TRAN": "https://gedcom.io/terms/v7/NOTE-TRAN",
|
130
|
+
"NPFX": "https://gedcom.io/terms/v7/NPFX",
|
131
|
+
"NSFX": "https://gedcom.io/terms/v7/NSFX",
|
132
|
+
"OBJE": "https://gedcom.io/terms/v7/OBJE",
|
133
|
+
"OCCU": "https://gedcom.io/terms/v7/OCCU",
|
134
|
+
"ORDN": "https://gedcom.io/terms/v7/ORDN",
|
135
|
+
"PAGE": "https://gedcom.io/terms/v7/PAGE",
|
136
|
+
"PEDI": "https://gedcom.io/terms/v7/PEDI",
|
137
|
+
"PHON": "https://gedcom.io/terms/v7/PHON",
|
138
|
+
"PHRASE": "https://gedcom.io/terms/v7/PHRASE",
|
139
|
+
"PLAC": "https://gedcom.io/terms/v7/PLAC",
|
140
|
+
"PLAC-FORM": "https://gedcom.io/terms/v7/PLAC-FORM",
|
141
|
+
"PLAC-TRAN": "https://gedcom.io/terms/v7/PLAC-TRAN",
|
142
|
+
"POST": "https://gedcom.io/terms/v7/POST",
|
143
|
+
"PROB": "https://gedcom.io/terms/v7/PROB",
|
144
|
+
"PROP": "https://gedcom.io/terms/v7/PROP",
|
145
|
+
"PUBL": "https://gedcom.io/terms/v7/PUBL",
|
146
|
+
"QUAY": "https://gedcom.io/terms/v7/QUAY",
|
147
|
+
"REFN": "https://gedcom.io/terms/v7/REFN",
|
148
|
+
"RELI": "https://gedcom.io/terms/v7/RELI",
|
149
|
+
"REPO": "https://gedcom.io/terms/v7/REPO",
|
150
|
+
"RESI": "https://gedcom.io/terms/v7/RESI",
|
151
|
+
"RESN": "https://gedcom.io/terms/v7/RESN",
|
152
|
+
"RETI": "https://gedcom.io/terms/v7/RETI",
|
153
|
+
"ROLE": "https://gedcom.io/terms/v7/ROLE",
|
154
|
+
"SCHMA": "https://gedcom.io/terms/v7/SCHMA",
|
155
|
+
"SDATE": "https://gedcom.io/terms/v7/SDATE",
|
156
|
+
"SEX": "https://gedcom.io/terms/v7/SEX",
|
157
|
+
"SLGC": "https://gedcom.io/terms/v7/SLGC",
|
158
|
+
"SLGS": "https://gedcom.io/terms/v7/SLGS",
|
159
|
+
"SNOTE": "https://gedcom.io/terms/v7/SNOTE",
|
160
|
+
"SOUR": "https://gedcom.io/terms/v7/SOUR",
|
161
|
+
"SOUR-DATA": "https://gedcom.io/terms/v7/SOUR-DATA",
|
162
|
+
"SOUR-EVEN": "https://gedcom.io/terms/v7/SOUR-EVEN",
|
163
|
+
"SPFX": "https://gedcom.io/terms/v7/SPFX",
|
164
|
+
"SSN": "https://gedcom.io/terms/v7/SSN",
|
165
|
+
"STAE": "https://gedcom.io/terms/v7/STAE",
|
166
|
+
"STAT": "https://gedcom.io/terms/v7/STAT",
|
167
|
+
"SUBM": "https://gedcom.io/terms/v7/SUBM",
|
168
|
+
"SUBM-LANG": "https://gedcom.io/terms/v7/SUBM-LANG",
|
169
|
+
"SURN": "https://gedcom.io/terms/v7/SURN",
|
170
|
+
"TAG": "https://gedcom.io/terms/v7/TAG",
|
171
|
+
"TEMP": "https://gedcom.io/terms/v7/TEMP",
|
172
|
+
"TEXT": "https://gedcom.io/terms/v7/TEXT",
|
173
|
+
"TIME": "https://gedcom.io/terms/v7/TIME",
|
174
|
+
"TITL": "https://gedcom.io/terms/v7/TITL",
|
175
|
+
"TOP": "https://gedcom.io/terms/v7/TOP",
|
176
|
+
"TRAN": "https://gedcom.io/terms/v7/TRAN",
|
177
|
+
"TRLR": "https://gedcom.io/terms/v7/TRLR",
|
178
|
+
"TYPE": "https://gedcom.io/terms/v7/TYPE",
|
179
|
+
"UID": "https://gedcom.io/terms/v7/UID",
|
180
|
+
"VERS": "https://gedcom.io/terms/v7/VERS",
|
181
|
+
"WIDTH": "https://gedcom.io/terms/v7/WIDTH",
|
182
|
+
"WIFE": "https://gedcom.io/terms/v7/WIFE",
|
183
|
+
"WILL": "https://gedcom.io/terms/v7/WILL",
|
184
|
+
"WWW": "https://gedcom.io/terms/v7/WWW",
|
185
|
+
"enumset-ADOP": "https://gedcom.io/terms/v7/enumset-ADOP",
|
186
|
+
"enumset-EVEN": "https://gedcom.io/terms/v7/enumset-EVEN",
|
187
|
+
"enumset-EVENATTR": "https://gedcom.io/terms/v7/enumset-EVENATTR",
|
188
|
+
"enumset-FAMC-STAT": "https://gedcom.io/terms/v7/enumset-FAMC-STAT",
|
189
|
+
"enumset-MEDI": "https://gedcom.io/terms/v7/enumset-MEDI",
|
190
|
+
"enumset-NAME-TYPE": "https://gedcom.io/terms/v7/enumset-NAME-TYPE",
|
191
|
+
"enumset-PEDI": "https://gedcom.io/terms/v7/enumset-PEDI",
|
192
|
+
"enumset-QUAY": "https://gedcom.io/terms/v7/enumset-QUAY",
|
193
|
+
"enumset-RESN": "https://gedcom.io/terms/v7/enumset-RESN",
|
194
|
+
"enumset-ROLE": "https://gedcom.io/terms/v7/enumset-ROLE",
|
195
|
+
"enumset-SEX": "https://gedcom.io/terms/v7/enumset-SEX",
|
196
|
+
"ord-STAT": "https://gedcom.io/terms/v7/ord-STAT",
|
197
|
+
"record-FAM": "https://gedcom.io/terms/v7/record-FAM",
|
198
|
+
"record-INDI": "https://gedcom.io/terms/v7/record-INDI",
|
199
|
+
"record-OBJE": "https://gedcom.io/terms/v7/record-OBJE",
|
200
|
+
"record-REPO": "https://gedcom.io/terms/v7/record-REPO",
|
201
|
+
"record-SNOTE": "https://gedcom.io/terms/v7/record-SNOTE",
|
202
|
+
"record-SOUR": "https://gedcom.io/terms/v7/record-SOUR",
|
203
|
+
"record-SUBM": "https://gedcom.io/terms/v7/record-SUBM"
|
204
|
+
}
|
205
|
+
|
@@ -0,0 +1,160 @@
|
|
1
|
+
|
2
|
+
from __future__ import annotations
|
3
|
+
from typing import Any, Dict, List, Optional, Union, Iterable
|
4
|
+
from collections import defaultdict
|
5
|
+
|
6
|
+
|
7
|
+
from .GedcomStructure import GedcomStructure
|
8
|
+
from . import Specification as g7specs
|
9
|
+
from .logger import get_logger
|
10
|
+
|
11
|
+
|
12
|
+
from typing import Dict, List, Optional
|
13
|
+
|
14
|
+
|
15
|
+
|
16
|
+
class Gedcom7:
|
17
|
+
def __init__(self, filepath: Optional[str] = None):
|
18
|
+
self.persons: List[Any] = []
|
19
|
+
self.families: List[Any] = []
|
20
|
+
self.sources: List[Any] = []
|
21
|
+
self.records: List['GedcomStructure'] = []
|
22
|
+
self._tag_index: Dict[str, List[int]] = defaultdict(list) # tag -> list of record indices
|
23
|
+
|
24
|
+
# ---- indexing helpers -------------------------------------------------
|
25
|
+
@staticmethod
|
26
|
+
def _norm_tag(tag: str) -> str:
|
27
|
+
return tag.upper()
|
28
|
+
|
29
|
+
def _rebuild_index(self) -> None:
|
30
|
+
self._tag_index.clear()
|
31
|
+
for i, rec in enumerate(self.records):
|
32
|
+
if getattr(rec, "tag", None):
|
33
|
+
self._tag_index[self._norm_tag(rec.tag)].append(i)
|
34
|
+
|
35
|
+
# Optional: keep index in sync if you append records elsewhere
|
36
|
+
def _append_record(self, rec: 'GedcomStructure') -> None:
|
37
|
+
self.records.append(rec)
|
38
|
+
if getattr(rec, "tag", None):
|
39
|
+
self._tag_index[self._norm_tag(rec.tag)].append(len(self.records) - 1)
|
40
|
+
|
41
|
+
# ---- Python container protocol ----------------------------------------
|
42
|
+
def __len__(self) -> int:
|
43
|
+
return len(self.records)
|
44
|
+
|
45
|
+
def __iter__(self) -> Iterable['GedcomStructure']:
|
46
|
+
return iter(self.records)
|
47
|
+
|
48
|
+
def __contains__(self, key: Union[str, 'GedcomStructure']) -> bool:
|
49
|
+
if isinstance(key, str):
|
50
|
+
return self._norm_tag(key) in self._tag_index
|
51
|
+
return key in self.records
|
52
|
+
|
53
|
+
def __getitem__(self, key: Union[int, slice, str, tuple]) -> Union['GedcomStructure', List['GedcomStructure']]:
|
54
|
+
# by position
|
55
|
+
if isinstance(key, (int, slice)):
|
56
|
+
return self.records[key]
|
57
|
+
|
58
|
+
# by tag
|
59
|
+
if isinstance(key, str):
|
60
|
+
idxs = self._tag_index.get(self._norm_tag(key), [])
|
61
|
+
return [self.records[i] for i in idxs]
|
62
|
+
|
63
|
+
# combo: ('INDI', 0) or ('INDI', 0:5)
|
64
|
+
if isinstance(key, tuple) and len(key) == 2 and isinstance(key[0], str):
|
65
|
+
tag, sub = key
|
66
|
+
items = self[tag] # list for that tag
|
67
|
+
if isinstance(sub, int) or isinstance(sub, slice):
|
68
|
+
return items[sub]
|
69
|
+
raise TypeError(f"Unsupported sub-key type: {type(sub)!r}")
|
70
|
+
|
71
|
+
raise TypeError(f"Unsupported key type: {type(key)!r}")
|
72
|
+
|
73
|
+
# ---- your existing methods (trimmed) ----------------------------------
|
74
|
+
@staticmethod
|
75
|
+
def parse_gedcom_line(line: str) -> Optional[Dict[str, Any]]:
|
76
|
+
|
77
|
+
line = line.lstrip('\ufeff').rstrip('\r\n')
|
78
|
+
if not line:
|
79
|
+
return None
|
80
|
+
|
81
|
+
parts = line.split(maxsplit=3)
|
82
|
+
if len(parts) < 2:
|
83
|
+
return None # not even "0 HEAD"
|
84
|
+
|
85
|
+
# 1) Level
|
86
|
+
try:
|
87
|
+
level = int(parts[0])
|
88
|
+
except ValueError:
|
89
|
+
return None
|
90
|
+
|
91
|
+
# 2) Is parts[1] an XREF?
|
92
|
+
xref = None
|
93
|
+
if parts[1].startswith('@') and parts[1].endswith('@'):
|
94
|
+
xref = parts[1]
|
95
|
+
|
96
|
+
# 3) Where is the tag?
|
97
|
+
if xref:
|
98
|
+
# must have at least ["0", "@X@", "TAG"]
|
99
|
+
if len(parts) < 3:
|
100
|
+
return None
|
101
|
+
tag = parts[2]
|
102
|
+
# everything after index 2 is the value
|
103
|
+
value_parts = parts[3:] # could be empty or one-element
|
104
|
+
else:
|
105
|
+
tag = parts[1]
|
106
|
+
# everything after index 1 is the value
|
107
|
+
value_parts = parts[2:] # could be empty, one- or two-element
|
108
|
+
|
109
|
+
|
110
|
+
# 4) re-assemble the full value
|
111
|
+
value = " ".join(value_parts) # empty string if value_parts == []
|
112
|
+
if value.startswith('@') and value.endswith('@'):
|
113
|
+
xref = parts[1]
|
114
|
+
|
115
|
+
if tag == 'TAG':
|
116
|
+
xtag, uri = value.split()
|
117
|
+
g7specs.structure_specs[xtag] = uri
|
118
|
+
g7specs.structure_specs[uri] = {'label': 'Extension_' + xtag}
|
119
|
+
|
120
|
+
return {
|
121
|
+
"level": level,
|
122
|
+
"xref": xref,
|
123
|
+
"tag": tag,
|
124
|
+
"value": value
|
125
|
+
}
|
126
|
+
|
127
|
+
|
128
|
+
def loadfile(self, filepath: str) -> None:
|
129
|
+
log = get_logger('importlog')
|
130
|
+
context: Dict[int, GedcomStructure] = {}
|
131
|
+
records: List[GedcomStructure] = []
|
132
|
+
|
133
|
+
with open(filepath, 'r', encoding='utf8') as file:
|
134
|
+
for lineno, raw in enumerate(file, start=1):
|
135
|
+
record = Gedcom7.parse_gedcom_line(raw)
|
136
|
+
if record is None:
|
137
|
+
log.error(f'empty line at {lineno}: {raw}')
|
138
|
+
continue
|
139
|
+
|
140
|
+
level = int(record["level"])
|
141
|
+
if record["tag"] == g7specs.CONT:
|
142
|
+
context[level - 1].value += "\n" + record["value"]
|
143
|
+
continue
|
144
|
+
|
145
|
+
structure = GedcomStructure(
|
146
|
+
level=level,
|
147
|
+
tag=record["tag"],
|
148
|
+
xref=record["xref"],
|
149
|
+
text=record["value"],
|
150
|
+
parent=context[level - 1] if level > 0 else None,
|
151
|
+
line_num=lineno
|
152
|
+
)
|
153
|
+
|
154
|
+
if level == 0:
|
155
|
+
records.append(structure)
|
156
|
+
|
157
|
+
context[level] = structure
|
158
|
+
|
159
|
+
self.records = records
|
160
|
+
self._rebuild_index() # <-- build fast tag index once
|
@@ -0,0 +1,19 @@
|
|
1
|
+
import logging
|
2
|
+
|
3
|
+
def get_logger(name=None):
|
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
|