gedcom-x 0.5.7__tar.gz → 0.5.9__tar.gz
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 → gedcom_x-0.5.9}/PKG-INFO +1 -1
- {gedcom_x-0.5.7 → gedcom_x-0.5.9}/gedcom_x.egg-info/PKG-INFO +1 -1
- gedcom_x-0.5.9/gedcom_x.egg-info/SOURCES.txt +89 -0
- gedcom_x-0.5.9/gedcomx/Extensions/rs10/rsLink.py +166 -0
- {gedcom_x-0.5.7 → gedcom_x-0.5.9}/gedcomx/TopLevelTypeCollection.py +1 -1
- gedcom_x-0.5.9/gedcomx/__init__.py +50 -0
- gedcom_x-0.5.9/gedcomx/address.py +217 -0
- gedcom_x-0.5.7/gedcomx/Agent.py → gedcom_x-0.5.9/gedcomx/agent.py +107 -34
- gedcom_x-0.5.9/gedcomx/attribution.py +115 -0
- gedcom_x-0.5.7/gedcomx/Conclusion.py → gedcom_x-0.5.9/gedcomx/conclusion.py +120 -51
- gedcom_x-0.5.7/gedcomx/Converter.py → gedcom_x-0.5.9/gedcomx/converter.py +261 -116
- gedcom_x-0.5.9/gedcomx/coverage.py +64 -0
- gedcom_x-0.5.7/gedcomx/Date.py → gedcom_x-0.5.9/gedcomx/date.py +43 -9
- gedcom_x-0.5.7/gedcomx/Document.py → gedcom_x-0.5.9/gedcomx/document.py +60 -12
- gedcom_x-0.5.7/gedcomx/Event.py → gedcom_x-0.5.9/gedcomx/event.py +88 -31
- gedcom_x-0.5.9/gedcomx/evidence_reference.py +20 -0
- gedcom_x-0.5.7/gedcomx/Fact.py → gedcom_x-0.5.9/gedcomx/fact.py +81 -74
- gedcom_x-0.5.7/gedcomx/Gedcom.py → gedcom_x-0.5.9/gedcomx/gedcom.py +10 -0
- gedcom_x-0.5.7/gedcomx/Gedcom5x.py → gedcom_x-0.5.9/gedcomx/gedcom5x.py +31 -21
- gedcom_x-0.5.9/gedcomx/gedcom7/Exceptions.py +9 -0
- gedcom_x-0.5.9/gedcomx/gedcom7/GedcomStructure.py +94 -0
- gedcom_x-0.5.9/gedcomx/gedcom7/Specification.py +347 -0
- gedcom_x-0.5.9/gedcomx/gedcom7/__init__.py +26 -0
- gedcom_x-0.5.9/gedcomx/gedcom7/g7interop.py +205 -0
- gedcom_x-0.5.9/gedcomx/gedcom7/gedcom7.py +160 -0
- gedcom_x-0.5.9/gedcomx/gedcom7/logger.py +19 -0
- gedcom_x-0.5.7/gedcomx/GedcomX.py → gedcom_x-0.5.9/gedcomx/gedcomx.py +109 -106
- gedcom_x-0.5.9/gedcomx/gender.py +91 -0
- gedcom_x-0.5.9/gedcomx/group.py +72 -0
- gedcom_x-0.5.7/gedcomx/Identifier.py → gedcom_x-0.5.9/gedcomx/identifier.py +48 -21
- gedcom_x-0.5.7/gedcomx/LoggingHub.py → gedcom_x-0.5.9/gedcomx/logging_hub.py +19 -0
- gedcom_x-0.5.7/gedcomx/Mutations.py → gedcom_x-0.5.9/gedcomx/mutations.py +59 -30
- gedcom_x-0.5.7/gedcomx/Name.py → gedcom_x-0.5.9/gedcomx/name.py +88 -47
- gedcom_x-0.5.9/gedcomx/note.py +105 -0
- gedcom_x-0.5.9/gedcomx/online_account.py +19 -0
- gedcom_x-0.5.7/gedcomx/Person.py → gedcom_x-0.5.9/gedcomx/person.py +61 -41
- gedcom_x-0.5.7/gedcomx/PlaceDescription.py → gedcom_x-0.5.9/gedcomx/place_description.py +71 -23
- gedcom_x-0.5.7/gedcomx/PlaceReference.py → gedcom_x-0.5.9/gedcomx/place_reference.py +32 -10
- gedcom_x-0.5.7/gedcomx/Qualifier.py → gedcom_x-0.5.9/gedcomx/qualifier.py +20 -4
- gedcom_x-0.5.9/gedcomx/relationship.py +156 -0
- gedcom_x-0.5.9/gedcomx/resource.py +112 -0
- gedcom_x-0.5.9/gedcomx/serialization.py +794 -0
- gedcom_x-0.5.9/gedcomx/source_citation.py +37 -0
- gedcom_x-0.5.9/gedcomx/source_description.py +401 -0
- gedcom_x-0.5.7/gedcomx/SourceReference.py → gedcom_x-0.5.9/gedcomx/source_reference.py +56 -21
- gedcom_x-0.5.9/gedcomx/subject.py +122 -0
- gedcom_x-0.5.9/gedcomx/textvalue.py +89 -0
- gedcom_x-0.5.7/gedcomx/Translation.py → gedcom_x-0.5.9/gedcomx/translation.py +4 -4
- gedcom_x-0.5.9/gedcomx/uri.py +273 -0
- {gedcom_x-0.5.7 → gedcom_x-0.5.9}/pyproject.toml +2 -2
- {gedcom_x-0.5.7 → gedcom_x-0.5.9}/setup.py +1 -1
- gedcom_x-0.5.7/gedcom_x.egg-info/SOURCES.txt +0 -52
- gedcom_x-0.5.7/gedcomx/Address.py +0 -131
- gedcom_x-0.5.7/gedcomx/Attribution.py +0 -91
- gedcom_x-0.5.7/gedcomx/Coverage.py +0 -37
- gedcom_x-0.5.7/gedcomx/EvidenceReference.py +0 -11
- gedcom_x-0.5.7/gedcomx/Extensions/rs10/rsLink.py +0 -116
- gedcom_x-0.5.7/gedcomx/Gender.py +0 -65
- gedcom_x-0.5.7/gedcomx/Group.py +0 -37
- gedcom_x-0.5.7/gedcomx/Note.py +0 -73
- gedcom_x-0.5.7/gedcomx/OnlineAccount.py +0 -10
- gedcom_x-0.5.7/gedcomx/Relationship.py +0 -97
- gedcom_x-0.5.7/gedcomx/Resource.py +0 -85
- gedcom_x-0.5.7/gedcomx/Serialization.py +0 -816
- gedcom_x-0.5.7/gedcomx/SourceCitation.py +0 -25
- gedcom_x-0.5.7/gedcomx/SourceDescription.py +0 -314
- gedcom_x-0.5.7/gedcomx/Subject.py +0 -59
- gedcom_x-0.5.7/gedcomx/TextValue.py +0 -35
- gedcom_x-0.5.7/gedcomx/URI.py +0 -105
- gedcom_x-0.5.7/gedcomx/__init__.py +0 -49
- {gedcom_x-0.5.7 → gedcom_x-0.5.9}/README.md +0 -0
- {gedcom_x-0.5.7 → gedcom_x-0.5.9}/gedcom_x.egg-info/dependency_links.txt +0 -0
- {gedcom_x-0.5.7 → gedcom_x-0.5.9}/gedcom_x.egg-info/top_level.txt +0 -0
- {gedcom_x-0.5.7 → gedcom_x-0.5.9}/gedcomx/Extensions/__init__.py +0 -0
- {gedcom_x-0.5.7 → gedcom_x-0.5.9}/gedcomx/Extensions/rs10/__init__.py +0 -0
- {gedcom_x-0.5.7 → gedcom_x-0.5.9}/gedcomx/Logging.py +0 -0
- {gedcom_x-0.5.7 → gedcom_x-0.5.9}/gedcomx/Zip.py +0 -0
- /gedcom_x-0.5.7/gedcomx/Exceptions.py → /gedcom_x-0.5.9/gedcomx/exceptions.py +0 -0
- /gedcom_x-0.5.7/gedcomx/ExtensibleEnum.py → /gedcom_x-0.5.9/gedcomx/extensible_enum.py +0 -0
- {gedcom_x-0.5.7 → gedcom_x-0.5.9}/setup.cfg +0 -0
@@ -0,0 +1,89 @@
|
|
1
|
+
README.md
|
2
|
+
pyproject.toml
|
3
|
+
setup.py
|
4
|
+
gedcom_x.egg-info/PKG-INFO
|
5
|
+
gedcom_x.egg-info/SOURCES.txt
|
6
|
+
gedcom_x.egg-info/dependency_links.txt
|
7
|
+
gedcom_x.egg-info/top_level.txt
|
8
|
+
gedcomx/Address.py
|
9
|
+
gedcomx/Agent.py
|
10
|
+
gedcomx/Attribution.py
|
11
|
+
gedcomx/Conclusion.py
|
12
|
+
gedcomx/Converter.py
|
13
|
+
gedcomx/Coverage.py
|
14
|
+
gedcomx/Date.py
|
15
|
+
gedcomx/Document.py
|
16
|
+
gedcomx/Event.py
|
17
|
+
gedcomx/Exceptions.py
|
18
|
+
gedcomx/Fact.py
|
19
|
+
gedcomx/Gedcom.py
|
20
|
+
gedcomx/Gedcom5x.py
|
21
|
+
gedcomx/GedcomX.py
|
22
|
+
gedcomx/Gender.py
|
23
|
+
gedcomx/Group.py
|
24
|
+
gedcomx/Identifier.py
|
25
|
+
gedcomx/Logging.py
|
26
|
+
gedcomx/Mutations.py
|
27
|
+
gedcomx/Name.py
|
28
|
+
gedcomx/Note.py
|
29
|
+
gedcomx/Person.py
|
30
|
+
gedcomx/Qualifier.py
|
31
|
+
gedcomx/Relationship.py
|
32
|
+
gedcomx/Resource.py
|
33
|
+
gedcomx/Serialization.py
|
34
|
+
gedcomx/Subject.py
|
35
|
+
gedcomx/TextValue.py
|
36
|
+
gedcomx/TopLevelTypeCollection.py
|
37
|
+
gedcomx/Translation.py
|
38
|
+
gedcomx/URI.py
|
39
|
+
gedcomx/Zip.py
|
40
|
+
gedcomx/__init__.py
|
41
|
+
gedcomx/address.py
|
42
|
+
gedcomx/agent.py
|
43
|
+
gedcomx/attribution.py
|
44
|
+
gedcomx/conclusion.py
|
45
|
+
gedcomx/converter.py
|
46
|
+
gedcomx/coverage.py
|
47
|
+
gedcomx/date.py
|
48
|
+
gedcomx/document.py
|
49
|
+
gedcomx/event.py
|
50
|
+
gedcomx/evidence_reference.py
|
51
|
+
gedcomx/exceptions.py
|
52
|
+
gedcomx/extensible_enum.py
|
53
|
+
gedcomx/fact.py
|
54
|
+
gedcomx/gedcom.py
|
55
|
+
gedcomx/gedcom5x.py
|
56
|
+
gedcomx/gedcomx.py
|
57
|
+
gedcomx/gender.py
|
58
|
+
gedcomx/group.py
|
59
|
+
gedcomx/identifier.py
|
60
|
+
gedcomx/logging_hub.py
|
61
|
+
gedcomx/mutations.py
|
62
|
+
gedcomx/name.py
|
63
|
+
gedcomx/note.py
|
64
|
+
gedcomx/online_account.py
|
65
|
+
gedcomx/person.py
|
66
|
+
gedcomx/place_description.py
|
67
|
+
gedcomx/place_reference.py
|
68
|
+
gedcomx/qualifier.py
|
69
|
+
gedcomx/relationship.py
|
70
|
+
gedcomx/resource.py
|
71
|
+
gedcomx/serialization.py
|
72
|
+
gedcomx/source_citation.py
|
73
|
+
gedcomx/source_description.py
|
74
|
+
gedcomx/source_reference.py
|
75
|
+
gedcomx/subject.py
|
76
|
+
gedcomx/textvalue.py
|
77
|
+
gedcomx/translation.py
|
78
|
+
gedcomx/uri.py
|
79
|
+
gedcomx/Extensions/__init__.py
|
80
|
+
gedcomx/Extensions/rs10/__init__.py
|
81
|
+
gedcomx/Extensions/rs10/rsLink.py
|
82
|
+
gedcomx/gedcom7/Exceptions.py
|
83
|
+
gedcomx/gedcom7/Gedcom7.py
|
84
|
+
gedcomx/gedcom7/GedcomStructure.py
|
85
|
+
gedcomx/gedcom7/Specification.py
|
86
|
+
gedcomx/gedcom7/__init__.py
|
87
|
+
gedcomx/gedcom7/g7interop.py
|
88
|
+
gedcomx/gedcom7/gedcom7.py
|
89
|
+
gedcomx/gedcom7/logger.py
|
@@ -0,0 +1,166 @@
|
|
1
|
+
from typing import Any, Dict, Iterable, Iterator, List, Optional, Tuple, Union
|
2
|
+
"""
|
3
|
+
======================================================================
|
4
|
+
Project: Gedcom-X
|
5
|
+
File: rsLink.py
|
6
|
+
Author: David J. Cartwright
|
7
|
+
Purpose: Link type of GedcomX RS (Extension)
|
8
|
+
|
9
|
+
Created: 2025-08-25
|
10
|
+
Updated:
|
11
|
+
-
|
12
|
+
|
13
|
+
======================================================================
|
14
|
+
"""
|
15
|
+
|
16
|
+
"""
|
17
|
+
======================================================================
|
18
|
+
GEDCOM Module Types
|
19
|
+
======================================================================
|
20
|
+
"""
|
21
|
+
from ...exceptions import GedcomClassAttributeError
|
22
|
+
from ...logging_hub import hub, logging
|
23
|
+
from ...uri import URI
|
24
|
+
"""
|
25
|
+
======================================================================
|
26
|
+
Logging
|
27
|
+
======================================================================
|
28
|
+
"""
|
29
|
+
log = logging.getLogger("gedcomx")
|
30
|
+
serial_log = "gedcomx.serialization"
|
31
|
+
deserial_log = "gedcomx.deserialization"
|
32
|
+
#=====================================================================
|
33
|
+
|
34
|
+
|
35
|
+
class rsLink():
|
36
|
+
"""A link description object. RS Extension to GedcomX by FamilySearch.
|
37
|
+
|
38
|
+
Args:
|
39
|
+
rel (str): Link relation identifier. Required.
|
40
|
+
href (str, optional): Link target URI. If omitted, provide `template`.
|
41
|
+
template (str, optional): URI Template (see RFC 6570). If omitted, provide `href`.
|
42
|
+
type (str, optional): Media type(s) of the linked resource (RFC 2616 §3.7).
|
43
|
+
accept (str, optional): Acceptable media type(s) for updating the linked resource (RFC 2616 §3.7).
|
44
|
+
allow (str, optional): Allowable HTTP methods to transition to the linked resource (RFC 2616 §14.7).
|
45
|
+
hreflang (str, optional): Language of the linked resource (e.g., BCP-47 tag).
|
46
|
+
title (str, optional): Human-readable label for the link.
|
47
|
+
|
48
|
+
Raises:
|
49
|
+
ValueError: If neither `href` nor `template` is provided.
|
50
|
+
"""
|
51
|
+
|
52
|
+
"""Attribution Information for a Genealogy, Conclusion, Subject and child classes
|
53
|
+
|
54
|
+
Args:
|
55
|
+
contributor (Agent, optional): Contributor to object being attributed.
|
56
|
+
modified (timestamp, optional): timestamp for when this record was modified.
|
57
|
+
changeMessage (str, optional): Birth date (YYYY-MM-DD).
|
58
|
+
creator (Agent, optional): Creator of object being attributed.
|
59
|
+
created (timestamp, optional): timestamp for when this record was created
|
60
|
+
|
61
|
+
Raises:
|
62
|
+
|
63
|
+
"""
|
64
|
+
identifier = "http://gedcomx.org/v1/Link"
|
65
|
+
|
66
|
+
def __init__(self,
|
67
|
+
href: Optional[URI] = None,
|
68
|
+
template: Optional[str] = None,
|
69
|
+
type: Optional[str] = None,
|
70
|
+
accept: Optional[str] = None,
|
71
|
+
allow: Optional[str] = None,
|
72
|
+
hreflang: Optional[str] = None,
|
73
|
+
title: Optional[str] = None) -> None:
|
74
|
+
|
75
|
+
|
76
|
+
self.href = href if isinstance(href,URI) else URI.from_url(href) if isinstance(href,str) else None
|
77
|
+
self.template = template
|
78
|
+
self.type = type
|
79
|
+
self.accept = accept
|
80
|
+
self.allow = allow
|
81
|
+
self.hreflang = hreflang
|
82
|
+
self.title = title
|
83
|
+
|
84
|
+
if self.href is None: # and self.template is None:
|
85
|
+
raise GedcomClassAttributeError("href or template are required")
|
86
|
+
|
87
|
+
def __str__(self) -> str:
|
88
|
+
def to_text(v):
|
89
|
+
if v is None:
|
90
|
+
return None
|
91
|
+
# unwrap URI-like objects
|
92
|
+
if isinstance(v, URI):
|
93
|
+
return getattr(v, "value", None) or str(v)
|
94
|
+
# normalize strings (skip empty/whitespace-only)
|
95
|
+
if isinstance(v, str):
|
96
|
+
s = v.strip()
|
97
|
+
return s or None
|
98
|
+
return str(v)
|
99
|
+
|
100
|
+
parts = []
|
101
|
+
|
102
|
+
# show href as the primary bit if present
|
103
|
+
href_s = to_text(self.href)
|
104
|
+
if href_s:
|
105
|
+
parts.append(href_s)
|
106
|
+
|
107
|
+
# show other fields as key=value
|
108
|
+
for name in ("template", "type", "accept", "allow", "hreflang", "title"):
|
109
|
+
val = to_text(getattr(self, name, None))
|
110
|
+
if val:
|
111
|
+
parts.append(f"{name}={val}")
|
112
|
+
|
113
|
+
return " | ".join(parts) if parts else self.__class__.__name__
|
114
|
+
|
115
|
+
|
116
|
+
|
117
|
+
@classmethod
|
118
|
+
def _from_json_(cls, data: Any, context: Any = None) -> "rsLink":
|
119
|
+
"""
|
120
|
+
Build an rsLink from JSON.
|
121
|
+
|
122
|
+
Accepted shapes:
|
123
|
+
- {"rel": "self", "href": "https://..."}
|
124
|
+
- {"rel": {...}, "href": {...}} # URI objects as dicts
|
125
|
+
- {"href": "https://...", "type": "...", ...} # rel optional
|
126
|
+
- {"uri": "https://..."} or {"url": "..."} # href aliases
|
127
|
+
- "https://example.com" # shorthand -> href only
|
128
|
+
|
129
|
+
Note:
|
130
|
+
- `rel` is coerced to a URI if possible.
|
131
|
+
- `href` is coerced to a URI (string/dict supported).
|
132
|
+
- If both `href` and `template` are missing, __init__ will raise.
|
133
|
+
"""
|
134
|
+
# Shorthand: bare string is an href
|
135
|
+
|
136
|
+
if not isinstance(data, dict):
|
137
|
+
raise TypeError(f"{cls.__name__}._from_json_ expected dict or str, got {type(data)}")
|
138
|
+
|
139
|
+
print("LINK DATA:",data)
|
140
|
+
# Extract with common aliases
|
141
|
+
rel = data.get("rel")
|
142
|
+
href = data.get("href")
|
143
|
+
|
144
|
+
|
145
|
+
|
146
|
+
return cls(
|
147
|
+
rel=rel,
|
148
|
+
href=href,
|
149
|
+
template=data.get("template"),
|
150
|
+
type=data.get("type"),
|
151
|
+
accept=data.get("accept"),
|
152
|
+
allow=data.get("allow"),
|
153
|
+
hreflang=data.get("hreflang"),
|
154
|
+
title=data.get("title"),
|
155
|
+
)
|
156
|
+
|
157
|
+
|
158
|
+
class _rsLinks():
|
159
|
+
|
160
|
+
def __init__(self,
|
161
|
+
person: rsLink | None = None,
|
162
|
+
portrait: rsLink | None= None
|
163
|
+
) -> None:
|
164
|
+
|
165
|
+
self.person = person
|
166
|
+
self.portrait = portrait
|
@@ -0,0 +1,50 @@
|
|
1
|
+
from .agent import Agent
|
2
|
+
from .address import Address
|
3
|
+
from .attribution import Attribution
|
4
|
+
from .conclusion import Conclusion
|
5
|
+
from .converter import GedcomConverter
|
6
|
+
from .coverage import Coverage
|
7
|
+
from .date import Date
|
8
|
+
from .document import Document
|
9
|
+
from .document import DocumentType
|
10
|
+
from .evidence_reference import EvidenceReference
|
11
|
+
from .extensible_enum import ExtensibleEnum
|
12
|
+
from .event import Event
|
13
|
+
from .event import EventType
|
14
|
+
from .event import EventRole
|
15
|
+
from .fact import Fact
|
16
|
+
from .fact import FactQualifier
|
17
|
+
from .fact import FactType
|
18
|
+
from .gedcom import Gedcom
|
19
|
+
from .gedcom5x import Gedcom5x, Gedcom5xRecord
|
20
|
+
from .gedcomx import GedcomX
|
21
|
+
from .gender import Gender, GenderType
|
22
|
+
from .group import Group, GroupRole
|
23
|
+
from .identifier import Identifier, IdentifierType, IdentifierList
|
24
|
+
from .Logging import get_logger
|
25
|
+
from .name import Name, NameForm, NamePart, NamePartType, NameType, NamePartQualifier
|
26
|
+
from .note import Note
|
27
|
+
from .online_account import OnlineAccount
|
28
|
+
from .person import Person, QuickPerson
|
29
|
+
from .place_description import PlaceDescription
|
30
|
+
from .place_reference import PlaceReference
|
31
|
+
from .qualifier import Qualifier
|
32
|
+
from .relationship import Relationship, RelationshipType
|
33
|
+
from .serialization import Serialization
|
34
|
+
from .source_citation import SourceCitation
|
35
|
+
from .source_description import SourceDescription
|
36
|
+
from .source_description import ResourceType
|
37
|
+
from .source_reference import SourceReference
|
38
|
+
from .subject import Subject
|
39
|
+
from .textvalue import TextValue
|
40
|
+
from .resource import Resource
|
41
|
+
from .uri import URI
|
42
|
+
|
43
|
+
|
44
|
+
from .Extensions.rs10.rsLink import rsLink
|
45
|
+
|
46
|
+
from .gedcom7.gedcom7 import Gedcom7, GedcomStructure
|
47
|
+
from .translation import g7toXtable
|
48
|
+
|
49
|
+
|
50
|
+
|
@@ -0,0 +1,217 @@
|
|
1
|
+
from typing import Any, Dict, Optional, List
|
2
|
+
|
3
|
+
"""
|
4
|
+
======================================================================
|
5
|
+
Project: Gedcom-X
|
6
|
+
File: address.py
|
7
|
+
Author: David J. Cartwright
|
8
|
+
Purpose:
|
9
|
+
|
10
|
+
Created: 2025-08-25
|
11
|
+
Updated:
|
12
|
+
- 2025-09-03: _from_json_ refactoring
|
13
|
+
|
14
|
+
======================================================================
|
15
|
+
"""
|
16
|
+
|
17
|
+
"""
|
18
|
+
======================================================================
|
19
|
+
GEDCOM Module Types
|
20
|
+
======================================================================
|
21
|
+
"""
|
22
|
+
from .logging_hub import hub, logging
|
23
|
+
"""
|
24
|
+
======================================================================
|
25
|
+
Logging
|
26
|
+
======================================================================
|
27
|
+
"""
|
28
|
+
log = logging.getLogger("gedcomx")
|
29
|
+
serial_log = "gedcomx.serialization"
|
30
|
+
#=====================================================================
|
31
|
+
|
32
|
+
class Address:
|
33
|
+
"""A GedcomX Address Data Type
|
34
|
+
A GedcomX Address Data Type.
|
35
|
+
|
36
|
+
Represents a postal address according to the GedcomX conceptual model.
|
37
|
+
|
38
|
+
Args:
|
39
|
+
value (str, optional): A complete address as a single string.
|
40
|
+
city (str, optional): Name of the city or town.
|
41
|
+
country (str, optional): Name of the country.
|
42
|
+
postalCode (str, optional): Postal or ZIP code.
|
43
|
+
stateOrProvince (str, optional): Name of the state, province, or region.
|
44
|
+
street (str, optional): First street address line.
|
45
|
+
street2 (str, optional): Second street address line.
|
46
|
+
street3 (str, optional): Third street address line.
|
47
|
+
street4 (str, optional): Fourth street address line.
|
48
|
+
street5 (str, optional): Fifth street address line.
|
49
|
+
street6 (str, optional): Sixth street address line.
|
50
|
+
"""
|
51
|
+
|
52
|
+
identifier = "http://gedcomx.org/v1/Address"
|
53
|
+
version = 'http://gedcomx.org/conceptual-model/v1'
|
54
|
+
|
55
|
+
def __init__(self, value: Optional[str] = None,
|
56
|
+
city: Optional[str] = None,
|
57
|
+
country: Optional[str] = None,
|
58
|
+
postalCode: Optional[str] = None,
|
59
|
+
stateOrProvince: Optional[str] = None,
|
60
|
+
street: Optional[str] = None,
|
61
|
+
street2: Optional[str] = None,
|
62
|
+
street3: Optional[str] = None,
|
63
|
+
street4: Optional[str] = None,
|
64
|
+
street5: Optional[str] = None,
|
65
|
+
street6: Optional[str] = None):
|
66
|
+
|
67
|
+
self._value = value #TODO impliment a parser for date strings.
|
68
|
+
self.city = city
|
69
|
+
self.country = country
|
70
|
+
self.postalCode = postalCode
|
71
|
+
self.stateOrProvince = stateOrProvince
|
72
|
+
self.street = street
|
73
|
+
self.street2 = street2
|
74
|
+
self.street3 = street3
|
75
|
+
self.street4 = street4
|
76
|
+
self.street5 = street5
|
77
|
+
self.street6 = street6
|
78
|
+
|
79
|
+
@property
|
80
|
+
def value(self) -> str:
|
81
|
+
return ', '.join(filter(None, [
|
82
|
+
self.street, self.street2, self.street3,
|
83
|
+
self.street4, self.street5, self.street6,
|
84
|
+
self.city, self.stateOrProvince,
|
85
|
+
self.postalCode, self.country
|
86
|
+
]))
|
87
|
+
|
88
|
+
@value.setter
|
89
|
+
def value(self,value: str):
|
90
|
+
self._value = value
|
91
|
+
return
|
92
|
+
raise NotImplementedError("Parsing of a full address is not implimented.")
|
93
|
+
|
94
|
+
def _append(self,value):
|
95
|
+
if self._value:
|
96
|
+
self._value = self._value + ' ' + value
|
97
|
+
else:
|
98
|
+
self._value = value
|
99
|
+
|
100
|
+
def __eq__(self, other):
|
101
|
+
if not isinstance(other, self.__class__):
|
102
|
+
return False
|
103
|
+
|
104
|
+
return (
|
105
|
+
self.value == other.value and
|
106
|
+
self.city == other.city and
|
107
|
+
self.country == other.country and
|
108
|
+
self.postalCode == other.postalCode and
|
109
|
+
self.stateOrProvince == other.stateOrProvince and
|
110
|
+
self.street == other.street and
|
111
|
+
self.street2 == other.street2 and
|
112
|
+
self.street3 == other.street3 and
|
113
|
+
self.street4 == other.street4 and
|
114
|
+
self.street5 == other.street5 and
|
115
|
+
self.street6 == other.street6
|
116
|
+
)
|
117
|
+
|
118
|
+
def __str__(self) -> str:
|
119
|
+
# Combine non-empty address components into a formatted string
|
120
|
+
parts = [
|
121
|
+
self._value,
|
122
|
+
self.street,
|
123
|
+
self.street2,
|
124
|
+
self.street3,
|
125
|
+
self.street4,
|
126
|
+
self.street5,
|
127
|
+
self.street6,
|
128
|
+
self.city,
|
129
|
+
self.stateOrProvince,
|
130
|
+
self.postalCode,
|
131
|
+
self.country
|
132
|
+
]
|
133
|
+
|
134
|
+
# Filter out any parts that are None or empty strings
|
135
|
+
filtered_parts = [str(part) for part in parts if part]
|
136
|
+
|
137
|
+
# Join the remaining parts with a comma and space
|
138
|
+
return ', '.join(filtered_parts)
|
139
|
+
|
140
|
+
@property
|
141
|
+
def _as_dict_(self):
|
142
|
+
with hub.use(serial_log):
|
143
|
+
log.debug(f"Serializing 'Address' with value: '{self.value}'")
|
144
|
+
type_as_dict = {}
|
145
|
+
if self.city: type_as_dict["city"] = self.city
|
146
|
+
if self.country: type_as_dict["country"] = self.country
|
147
|
+
if self.postalCode: type_as_dict["postalCode"] = self.postalCode
|
148
|
+
if self.stateOrProvince: type_as_dict["stateOrProvince"] = self.stateOrProvince
|
149
|
+
if self.street: type_as_dict["street"] = self.street
|
150
|
+
if self.street2: type_as_dict["street2"] = self.street2
|
151
|
+
if self.street3: type_as_dict["street3"] = self.street3
|
152
|
+
if self.street4: type_as_dict["street4"] = self.street4
|
153
|
+
if self.street5: type_as_dict["street5"] = self.street5
|
154
|
+
if self.street6: type_as_dict["street6"] = self.street6
|
155
|
+
log.debug(f"'Address' serialized with fields: '{type_as_dict.keys()}'")
|
156
|
+
if type_as_dict == {} or len(type_as_dict.keys()) == 0: log.warning("serializing and empty 'Address' Object")
|
157
|
+
|
158
|
+
return type_as_dict if type_as_dict != {} else None
|
159
|
+
|
160
|
+
|
161
|
+
@classmethod
|
162
|
+
def _from_json_(cls, data: Any, context: Any = None) -> "Address":
|
163
|
+
"""
|
164
|
+
Build an Address from JSON.
|
165
|
+
Supports:
|
166
|
+
- Shorthand string -> value
|
167
|
+
- Aliases: postal_code/postal -> postalCode; state/province -> stateOrProvince
|
168
|
+
- Line aliases: line1..line6 / address1..address6 / addr1..addr6 -> street..street6
|
169
|
+
- 'lines': [..] list -> street..street6
|
170
|
+
"""
|
171
|
+
if data is None: return None
|
172
|
+
|
173
|
+
if not isinstance(data, dict):
|
174
|
+
raise TypeError(f"{cls.__name__}._from_json_ expected dict or str, got {type(data)}")
|
175
|
+
|
176
|
+
address_data: Dict[str, Any] = {}
|
177
|
+
|
178
|
+
# Freeform value (accept a few aliases)
|
179
|
+
if (v := data.get("value")) is None:
|
180
|
+
address_data["value"] = str(v)
|
181
|
+
|
182
|
+
# Simple scalars
|
183
|
+
if (city := data.get("city")) is not None:
|
184
|
+
address_data["city"] = city
|
185
|
+
if (country := data.get("country")) is not None:
|
186
|
+
address_data["country"] = country
|
187
|
+
|
188
|
+
# Postal code (aliases)
|
189
|
+
if (postal := data.get("postalCode")) is not None:
|
190
|
+
address_data["postalCode"] = postal
|
191
|
+
|
192
|
+
# State / Province (aliases)
|
193
|
+
if (stateprov := data.get("stateOrProvince")) is not None:
|
194
|
+
address_data["stateOrProvince"] = stateprov
|
195
|
+
|
196
|
+
if data.get("street") is not None:
|
197
|
+
address_data["street"] = data["street"]
|
198
|
+
|
199
|
+
if data.get("street2") is not None:
|
200
|
+
address_data["street2"] = data["street2"]
|
201
|
+
|
202
|
+
if data.get("street3") is not None:
|
203
|
+
address_data["street3"] = data["street3"]
|
204
|
+
|
205
|
+
if data.get("street4") is not None:
|
206
|
+
address_data["street4"] = data["street4"]
|
207
|
+
|
208
|
+
if data.get("street5") is not None:
|
209
|
+
address_data["street5"] = data["street5"]
|
210
|
+
|
211
|
+
if data.get("street6") is not None:
|
212
|
+
address_data["street6"] = data["street6"]
|
213
|
+
|
214
|
+
|
215
|
+
return cls(**address_data)
|
216
|
+
|
217
|
+
|