followthemoney 3.8.4__py3-none-any.whl → 4.0.0__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.
- followthemoney/__init__.py +30 -10
- followthemoney/cli/__init__.py +3 -12
- followthemoney/cli/aggregate.py +1 -1
- followthemoney/cli/cli.py +1 -1
- followthemoney/cli/exports.py +6 -2
- followthemoney/cli/mapping.py +6 -4
- followthemoney/cli/sieve.py +1 -1
- followthemoney/cli/statement.py +62 -0
- followthemoney/cli/util.py +2 -3
- followthemoney/compare.py +26 -16
- followthemoney/dataset/__init__.py +17 -0
- followthemoney/dataset/catalog.py +77 -0
- followthemoney/dataset/coverage.py +29 -0
- followthemoney/dataset/dataset.py +137 -0
- followthemoney/dataset/publisher.py +25 -0
- followthemoney/dataset/resource.py +30 -0
- followthemoney/dataset/util.py +58 -0
- followthemoney/entity.py +73 -0
- followthemoney/exc.py +6 -0
- followthemoney/export/common.py +3 -3
- followthemoney/export/csv.py +10 -12
- followthemoney/export/neo4j.py +1 -1
- followthemoney/export/rdf.py +57 -5
- followthemoney/graph.py +6 -4
- followthemoney/mapping/csv.py +6 -18
- followthemoney/mapping/sql.py +3 -4
- followthemoney/model.py +36 -9
- followthemoney/namespace.py +3 -1
- followthemoney/ontology.py +18 -16
- followthemoney/property.py +12 -15
- followthemoney/proxy.py +44 -65
- followthemoney/schema/Analyzable.yaml +2 -3
- followthemoney/schema/BankAccount.yaml +2 -3
- followthemoney/schema/Company.yaml +0 -6
- followthemoney/schema/Contract.yaml +0 -1
- followthemoney/schema/CryptoWallet.yaml +1 -1
- followthemoney/schema/Document.yaml +0 -6
- followthemoney/schema/Interval.yaml +7 -0
- followthemoney/schema/LegalEntity.yaml +6 -0
- followthemoney/schema/License.yaml +2 -0
- followthemoney/schema/Page.yaml +0 -1
- followthemoney/schema/Person.yaml +0 -5
- followthemoney/schema/Sanction.yaml +1 -0
- followthemoney/schema/Thing.yaml +0 -2
- followthemoney/schema/UserAccount.yaml +6 -3
- followthemoney/schema.py +27 -39
- followthemoney/statement/__init__.py +19 -0
- followthemoney/statement/entity.py +437 -0
- followthemoney/statement/serialize.py +245 -0
- followthemoney/statement/statement.py +256 -0
- followthemoney/statement/util.py +31 -0
- followthemoney/types/__init__.py +66 -23
- followthemoney/types/address.py +3 -3
- followthemoney/types/checksum.py +3 -7
- followthemoney/types/common.py +9 -14
- followthemoney/types/country.py +3 -7
- followthemoney/types/date.py +21 -11
- followthemoney/types/email.py +0 -4
- followthemoney/types/entity.py +5 -11
- followthemoney/types/gender.py +6 -10
- followthemoney/types/identifier.py +9 -3
- followthemoney/types/ip.py +5 -9
- followthemoney/types/json.py +2 -2
- followthemoney/types/language.py +3 -7
- followthemoney/types/mimetype.py +4 -8
- followthemoney/types/name.py +7 -8
- followthemoney/types/number.py +88 -6
- followthemoney/types/phone.py +4 -11
- followthemoney/types/string.py +4 -4
- followthemoney/types/topic.py +3 -7
- followthemoney/types/url.py +5 -10
- followthemoney/util.py +12 -13
- followthemoney/value.py +67 -0
- {followthemoney-3.8.4.dist-info → followthemoney-4.0.0.dist-info}/METADATA +38 -34
- {followthemoney-3.8.4.dist-info → followthemoney-4.0.0.dist-info}/RECORD +78 -69
- {followthemoney-3.8.4.dist-info → followthemoney-4.0.0.dist-info}/entry_points.txt +1 -0
- {followthemoney-3.8.4.dist-info → followthemoney-4.0.0.dist-info}/licenses/LICENSE +1 -0
- followthemoney/offshore.py +0 -48
- followthemoney/rdf.py +0 -9
- followthemoney/schema/Assessment.yaml +0 -32
- followthemoney/schema/Post.yaml +0 -42
- followthemoney/types/iban.py +0 -58
- followthemoney/types/registry.py +0 -52
- {followthemoney-3.8.4.dist-info → followthemoney-4.0.0.dist-info}/WHEEL +0 -0
followthemoney/property.py
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
from banal import is_mapping, as_bool
|
|
2
|
-
from typing import TYPE_CHECKING,
|
|
2
|
+
from typing import TYPE_CHECKING, Any, List, Optional, TypedDict
|
|
3
3
|
|
|
4
4
|
from followthemoney.exc import InvalidModel
|
|
5
5
|
from followthemoney.types import registry
|
|
6
|
-
from followthemoney.
|
|
7
|
-
from followthemoney.util import gettext, get_entity_id
|
|
6
|
+
from followthemoney.util import gettext, get_entity_id, const
|
|
8
7
|
|
|
9
8
|
if TYPE_CHECKING:
|
|
10
9
|
from followthemoney.schema import Schema
|
|
@@ -26,7 +25,6 @@ class PropertyDict(TypedDict, total=False):
|
|
|
26
25
|
deprecated: Optional[bool]
|
|
27
26
|
maxLength: Optional[int]
|
|
28
27
|
# stub: Optional[bool]
|
|
29
|
-
rdf: Optional[str]
|
|
30
28
|
range: Optional[str]
|
|
31
29
|
format: Optional[str]
|
|
32
30
|
|
|
@@ -66,7 +64,6 @@ class Property:
|
|
|
66
64
|
"stub",
|
|
67
65
|
"_reverse",
|
|
68
66
|
"reverse",
|
|
69
|
-
"uri",
|
|
70
67
|
)
|
|
71
68
|
|
|
72
69
|
#: Invalid property names.
|
|
@@ -79,10 +76,10 @@ class Property:
|
|
|
79
76
|
self.schema = schema
|
|
80
77
|
|
|
81
78
|
#: Machine-readable name for this property.
|
|
82
|
-
self.name = name
|
|
79
|
+
self.name = const(name)
|
|
83
80
|
|
|
84
81
|
#: Qualified property name, which also includes the schema name.
|
|
85
|
-
self.qname = "%s:%s" % (schema.name, self.name)
|
|
82
|
+
self.qname = const("%s:%s" % (schema.name, self.name))
|
|
86
83
|
if self.name in self.RESERVED:
|
|
87
84
|
raise InvalidModel("Reserved name: %s" % self.name)
|
|
88
85
|
|
|
@@ -97,12 +94,11 @@ class Property:
|
|
|
97
94
|
#: This property should not be shown or mentioned in the user interface.
|
|
98
95
|
self.hidden = as_bool(data.get("hidden"))
|
|
99
96
|
|
|
100
|
-
type_ = data.get("type"
|
|
101
|
-
if type_ is None or type_ not in registry.named:
|
|
102
|
-
raise InvalidModel("Invalid type: %s" % type_)
|
|
103
|
-
|
|
97
|
+
type_ = data.get("type") or "string"
|
|
104
98
|
#: The data type for this property.
|
|
105
|
-
self.type = registry
|
|
99
|
+
self.type = registry.get(type_)
|
|
100
|
+
if self.type is None:
|
|
101
|
+
raise InvalidModel("Invalid type: %s" % type_)
|
|
106
102
|
|
|
107
103
|
#: Whether this property should be used for matching and cross-referencing.
|
|
108
104
|
_matchable = data.get("matchable")
|
|
@@ -137,9 +133,6 @@ class Property:
|
|
|
137
133
|
self._reverse = data.get("reverse")
|
|
138
134
|
self.reverse: Optional["Property"] = None
|
|
139
135
|
|
|
140
|
-
#: RDF term for this property (i.e. the predicate URI).
|
|
141
|
-
self.uri = URIRef(cast(str, data.get("rdf", NS[self.qname])))
|
|
142
|
-
|
|
143
136
|
def generate(self, model: "Model") -> None:
|
|
144
137
|
"""Setup method used when loading the model in order to build out the reverse
|
|
145
138
|
links of the property."""
|
|
@@ -170,6 +163,10 @@ class Property:
|
|
|
170
163
|
return 0.0
|
|
171
164
|
return self.type.specificity(value)
|
|
172
165
|
|
|
166
|
+
def caption(self, value: str) -> str:
|
|
167
|
+
"""Return a user-friendly caption for the given value."""
|
|
168
|
+
return self.type.caption(value, format=self.format)
|
|
169
|
+
|
|
173
170
|
def validate(self, data: List[Any]) -> Optional[str]:
|
|
174
171
|
"""Validate that the data should be stored.
|
|
175
172
|
|
followthemoney/proxy.py
CHANGED
|
@@ -1,36 +1,25 @@
|
|
|
1
1
|
import logging
|
|
2
|
-
from typing import
|
|
3
|
-
|
|
4
|
-
Any,
|
|
5
|
-
Dict,
|
|
6
|
-
Generator,
|
|
7
|
-
List,
|
|
8
|
-
Optional,
|
|
9
|
-
Set,
|
|
10
|
-
Tuple,
|
|
11
|
-
Union,
|
|
12
|
-
Type,
|
|
13
|
-
TypeVar,
|
|
14
|
-
cast,
|
|
15
|
-
)
|
|
16
|
-
import warnings
|
|
2
|
+
from typing import TYPE_CHECKING, cast, Any
|
|
3
|
+
from typing import Dict, Generator, List, Optional, Set, Tuple, Union, Type, TypeVar
|
|
17
4
|
from itertools import product
|
|
18
5
|
from banal import ensure_dict
|
|
6
|
+
from rigour.names import pick_name
|
|
19
7
|
|
|
20
8
|
from followthemoney.exc import InvalidData
|
|
21
9
|
from followthemoney.types import registry
|
|
22
10
|
from followthemoney.types.common import PropertyType
|
|
23
11
|
from followthemoney.property import Property
|
|
24
|
-
from followthemoney.
|
|
12
|
+
from followthemoney.value import string_list, Values
|
|
25
13
|
from followthemoney.util import sanitize_text, gettext
|
|
26
|
-
from followthemoney.util import merge_context,
|
|
14
|
+
from followthemoney.util import merge_context, make_entity_id
|
|
15
|
+
from followthemoney.model import Model
|
|
16
|
+
from followthemoney.schema import Schema
|
|
27
17
|
|
|
28
18
|
if TYPE_CHECKING:
|
|
29
19
|
from followthemoney.model import Model
|
|
30
20
|
|
|
31
21
|
log = logging.getLogger(__name__)
|
|
32
22
|
P = Union[Property, str]
|
|
33
|
-
Triple = Tuple[Identifier, Identifier, Identifier]
|
|
34
23
|
E = TypeVar("E", bound="EntityProxy")
|
|
35
24
|
|
|
36
25
|
|
|
@@ -45,7 +34,7 @@ class EntityProxy(object):
|
|
|
45
34
|
|
|
46
35
|
def __init__(
|
|
47
36
|
self,
|
|
48
|
-
|
|
37
|
+
schema: Schema,
|
|
49
38
|
data: Dict[str, Any],
|
|
50
39
|
key_prefix: Optional[str] = None,
|
|
51
40
|
cleaned: bool = True,
|
|
@@ -57,9 +46,6 @@ class EntityProxy(object):
|
|
|
57
46
|
|
|
58
47
|
#: The schema definition for this entity, which implies the properties
|
|
59
48
|
#: That can be set on it.
|
|
60
|
-
schema = model.get(data.pop("schema", None))
|
|
61
|
-
if schema is None:
|
|
62
|
-
raise InvalidData(gettext("No schema for entity."))
|
|
63
49
|
self.schema = schema
|
|
64
50
|
|
|
65
51
|
#: When using :meth:`~make_id` to generate a natural key for this entity,
|
|
@@ -71,7 +57,7 @@ class EntityProxy(object):
|
|
|
71
57
|
#: A unique identifier for this entity, usually a hashed natural key,
|
|
72
58
|
#: a UUID, or a very simple slug. Can be signed using a
|
|
73
59
|
#: :class:`~followthemoney.namespace.Namespace`.
|
|
74
|
-
self.id = data
|
|
60
|
+
self.id = str(data["id"]) if "id" in data else None
|
|
75
61
|
if not cleaned:
|
|
76
62
|
self.id = sanitize_text(self.id)
|
|
77
63
|
|
|
@@ -162,7 +148,7 @@ class EntityProxy(object):
|
|
|
162
148
|
def add(
|
|
163
149
|
self,
|
|
164
150
|
prop: P,
|
|
165
|
-
values:
|
|
151
|
+
values: Values,
|
|
166
152
|
cleaned: bool = False,
|
|
167
153
|
quiet: bool = False,
|
|
168
154
|
fuzzy: bool = False,
|
|
@@ -192,11 +178,9 @@ class EntityProxy(object):
|
|
|
192
178
|
msg = gettext("Stub property (%s): %s")
|
|
193
179
|
raise InvalidData(msg % (self.schema, prop))
|
|
194
180
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
value = prop.type.clean(value, proxy=self, fuzzy=fuzzy, format=format)
|
|
199
|
-
self.unsafe_add(prop, value, cleaned=True)
|
|
181
|
+
value: Optional[str] = None
|
|
182
|
+
for value in string_list(values, sanitize=not cleaned):
|
|
183
|
+
self.unsafe_add(prop, value, cleaned=cleaned, fuzzy=fuzzy, format=format)
|
|
200
184
|
return None
|
|
201
185
|
|
|
202
186
|
def unsafe_add(
|
|
@@ -236,7 +220,7 @@ class EntityProxy(object):
|
|
|
236
220
|
def set(
|
|
237
221
|
self,
|
|
238
222
|
prop: P,
|
|
239
|
-
values:
|
|
223
|
+
values: Values,
|
|
240
224
|
cleaned: bool = False,
|
|
241
225
|
quiet: bool = False,
|
|
242
226
|
fuzzy: bool = False,
|
|
@@ -377,34 +361,21 @@ class EntityProxy(object):
|
|
|
377
361
|
data[group] = values
|
|
378
362
|
return data
|
|
379
363
|
|
|
380
|
-
def triples(self, qualified: bool = True) -> Generator[Triple, None, None]:
|
|
381
|
-
"""Serialise the entity into a set of RDF triple statements. The
|
|
382
|
-
statements include the property values, an ``RDF#type`` definition
|
|
383
|
-
that refers to the entity schema, and a ``SKOS#prefLabel`` with the
|
|
384
|
-
entity caption."""
|
|
385
|
-
if self.id is None or self.schema is None:
|
|
386
|
-
return
|
|
387
|
-
uri = registry.entity.rdf(self.id)
|
|
388
|
-
yield (uri, RDF.type, self.schema.uri)
|
|
389
|
-
if qualified:
|
|
390
|
-
caption = self.caption
|
|
391
|
-
if caption != self.schema.label:
|
|
392
|
-
yield (uri, SKOS.prefLabel, Literal(caption))
|
|
393
|
-
for prop, value in self.itervalues():
|
|
394
|
-
value = prop.type.rdf(value)
|
|
395
|
-
if qualified:
|
|
396
|
-
yield (uri, prop.uri, value)
|
|
397
|
-
else:
|
|
398
|
-
yield (uri, URIRef(prop.name), value)
|
|
399
|
-
|
|
400
364
|
@property
|
|
401
365
|
def caption(self) -> str:
|
|
402
366
|
"""The user-facing label to be used for this entity. This checks a list
|
|
403
367
|
of properties defined by the schema (caption) and returns the first
|
|
404
368
|
available value. If no caption is available, return the schema label."""
|
|
405
|
-
for
|
|
406
|
-
|
|
407
|
-
|
|
369
|
+
for prop_ in self.schema.caption:
|
|
370
|
+
prop = self.schema.properties[prop_]
|
|
371
|
+
values = self.get(prop)
|
|
372
|
+
if prop.type == registry.name and len(values) > 1:
|
|
373
|
+
name = pick_name(sorted(values))
|
|
374
|
+
if name is not None:
|
|
375
|
+
return name
|
|
376
|
+
else:
|
|
377
|
+
for value in values:
|
|
378
|
+
return value
|
|
408
379
|
return self.schema.label
|
|
409
380
|
|
|
410
381
|
@property
|
|
@@ -448,7 +419,7 @@ class EntityProxy(object):
|
|
|
448
419
|
|
|
449
420
|
def clone(self: E) -> E:
|
|
450
421
|
"""Make a deep copy of the current entity proxy."""
|
|
451
|
-
return self.__class__.from_dict(self.
|
|
422
|
+
return self.__class__.from_dict(self.to_dict())
|
|
452
423
|
|
|
453
424
|
def merge(self: E, other: E) -> E:
|
|
454
425
|
"""Merge another entity proxy into this one. This will try and find
|
|
@@ -467,30 +438,36 @@ class EntityProxy(object):
|
|
|
467
438
|
self.add(prop, values, cleaned=True, quiet=True)
|
|
468
439
|
return self
|
|
469
440
|
|
|
441
|
+
def __getstate__(self) -> Dict[str, Any]:
|
|
442
|
+
data = {slot: getattr(self, slot) for slot in self.__slots__}
|
|
443
|
+
data["schema"] = self.schema.name
|
|
444
|
+
return data
|
|
445
|
+
|
|
446
|
+
def __setstate__(self, data: Dict[str, Any]) -> None:
|
|
447
|
+
for slot in self.__slots__:
|
|
448
|
+
value = data.get(slot)
|
|
449
|
+
if slot == "schema":
|
|
450
|
+
value = Model.instance()[data["schema"]]
|
|
451
|
+
setattr(self, slot, value)
|
|
452
|
+
|
|
470
453
|
def __str__(self) -> str:
|
|
471
454
|
return self.caption
|
|
472
455
|
|
|
473
456
|
def __repr__(self) -> str:
|
|
474
|
-
return "<E(%r,%r)>" % (self.id, str(self))
|
|
457
|
+
return "<E(%r,%s,%r)>" % (self.id, self.schema.name, str(self))
|
|
475
458
|
|
|
476
459
|
def __len__(self) -> int:
|
|
477
460
|
return self._size
|
|
478
461
|
|
|
479
462
|
def __hash__(self) -> int:
|
|
480
463
|
if not self.id:
|
|
481
|
-
|
|
482
|
-
"Hashing an EntityProxy without an ID results in undefined behaviour",
|
|
483
|
-
RuntimeWarning,
|
|
484
|
-
)
|
|
464
|
+
raise RuntimeError("Cannot hash entity without an ID")
|
|
485
465
|
return hash(self.id)
|
|
486
466
|
|
|
487
467
|
def __eq__(self, other: Any) -> bool:
|
|
488
468
|
try:
|
|
489
469
|
if self.id is None or other.id is None:
|
|
490
|
-
|
|
491
|
-
"Comparing EntityProxys without IDs results in undefined behaviour",
|
|
492
|
-
RuntimeWarning,
|
|
493
|
-
)
|
|
470
|
+
raise RuntimeError("Cannot compare entities without IDs.")
|
|
494
471
|
return bool(self.id == other.id)
|
|
495
472
|
except AttributeError:
|
|
496
473
|
return False
|
|
@@ -498,11 +475,13 @@ class EntityProxy(object):
|
|
|
498
475
|
@classmethod
|
|
499
476
|
def from_dict(
|
|
500
477
|
cls: Type[E],
|
|
501
|
-
model: "Model",
|
|
502
478
|
data: Dict[str, Any],
|
|
503
479
|
cleaned: bool = True,
|
|
504
480
|
) -> E:
|
|
505
481
|
"""Instantiate a proxy based on the given model and serialised dictionary.
|
|
506
482
|
|
|
507
483
|
Use :meth:`followthemoney.model.Model.get_proxy` instead."""
|
|
508
|
-
|
|
484
|
+
schema = Model.instance().get(data.get("schema", ""))
|
|
485
|
+
if schema is None:
|
|
486
|
+
raise InvalidData(gettext("No schema for entity."))
|
|
487
|
+
return cls(schema, data, cleaned=cleaned)
|
|
@@ -56,12 +56,6 @@ Company:
|
|
|
56
56
|
mbsCode:
|
|
57
57
|
label: "MBS"
|
|
58
58
|
type: identifier
|
|
59
|
-
ibcRuc:
|
|
60
|
-
# TODO: Remove this. It's a column name in the ICIJ-released OffshoreLeaks datasets
|
|
61
|
-
# but seems to just mean "company number".
|
|
62
|
-
deprecated: true
|
|
63
|
-
label: "ibcRUC"
|
|
64
|
-
type: identifier
|
|
65
59
|
caemCode:
|
|
66
60
|
label: "COD CAEM"
|
|
67
61
|
description: "(RO) What kind of activity a legal entity is allowed to develop"
|
|
@@ -30,12 +30,10 @@ Document:
|
|
|
30
30
|
title:
|
|
31
31
|
label: "Title"
|
|
32
32
|
type: string
|
|
33
|
-
rdf: http://purl.org/dc/elements/1.1/title
|
|
34
33
|
caption: true
|
|
35
34
|
author:
|
|
36
35
|
label: "Author"
|
|
37
36
|
description: "The original author, not the uploader"
|
|
38
|
-
rdf: http://purl.org/dc/elements/1.1/creator
|
|
39
37
|
generator:
|
|
40
38
|
label: "Generator"
|
|
41
39
|
description: "The program used to generate this file"
|
|
@@ -61,11 +59,9 @@ Document:
|
|
|
61
59
|
mimeType:
|
|
62
60
|
label: "MIME type"
|
|
63
61
|
type: mimetype
|
|
64
|
-
rdf: http://purl.org/dc/terms/format
|
|
65
62
|
language:
|
|
66
63
|
label: "Language"
|
|
67
64
|
type: language
|
|
68
|
-
rdf: http://purl.org/dc/terms/language
|
|
69
65
|
translatedLanguage:
|
|
70
66
|
label: "The language of the translated text"
|
|
71
67
|
hidden: true
|
|
@@ -78,7 +74,6 @@ Document:
|
|
|
78
74
|
label: "Date"
|
|
79
75
|
description: "If not otherwise specified"
|
|
80
76
|
type: date
|
|
81
|
-
rdf: http://purl.org/dc/elements/1.1/date
|
|
82
77
|
authoredAt:
|
|
83
78
|
label: "Authored on"
|
|
84
79
|
type: date
|
|
@@ -95,7 +90,6 @@ Document:
|
|
|
95
90
|
name: children
|
|
96
91
|
label: "Child documents"
|
|
97
92
|
hidden: true
|
|
98
|
-
rdf: http://purl.org/dc/terms/isPartOf
|
|
99
93
|
ancestors:
|
|
100
94
|
label: "Ancestors"
|
|
101
95
|
type: entity
|
|
@@ -42,6 +42,13 @@ Interval:
|
|
|
42
42
|
label: "Source link"
|
|
43
43
|
type: url
|
|
44
44
|
matchable: false
|
|
45
|
+
proof:
|
|
46
|
+
label: Source document
|
|
47
|
+
reverse:
|
|
48
|
+
name: provenIntervals
|
|
49
|
+
label: "Derived relationships"
|
|
50
|
+
type: entity
|
|
51
|
+
range: Document
|
|
45
52
|
publisher:
|
|
46
53
|
label: "Publishing source"
|
|
47
54
|
publisherUrl:
|
|
@@ -102,6 +102,12 @@ LegalEntity:
|
|
|
102
102
|
bvdId:
|
|
103
103
|
label: Bureau van Dijk ID
|
|
104
104
|
type: identifier
|
|
105
|
+
uscCode:
|
|
106
|
+
# cf. https://en.wikipedia.org/wiki/Unified_Social_Credit_Identifier
|
|
107
|
+
label: "USCC"
|
|
108
|
+
description: "Unified Social Credit Identifier"
|
|
109
|
+
type: identifier
|
|
110
|
+
format: uscc
|
|
105
111
|
icijId:
|
|
106
112
|
label: ICIJ ID
|
|
107
113
|
description: "ID according to International Consortium for Investigative Journalists"
|
followthemoney/schema/Page.yaml
CHANGED
|
@@ -6,7 +6,6 @@ Person:
|
|
|
6
6
|
description: >
|
|
7
7
|
A natural person, as opposed to a corporation of some type.
|
|
8
8
|
matchable: true
|
|
9
|
-
rdf: http://xmlns.com/foaf/0.1/Person
|
|
10
9
|
featured:
|
|
11
10
|
- name
|
|
12
11
|
- nationality
|
|
@@ -26,14 +25,12 @@ Person:
|
|
|
26
25
|
properties:
|
|
27
26
|
title:
|
|
28
27
|
label: Title
|
|
29
|
-
rdf: http://xmlns.com/foaf/0.1/title
|
|
30
28
|
# The `firstName`, `lastName`, `secondName` etc. properties intentionally do not use
|
|
31
29
|
# the `name` property type. Many FtM tools (including Aleph) use name properties to
|
|
32
30
|
# compare/match entities, but matching entites just on e.g. a first name would lead to
|
|
33
31
|
# too many false positives.
|
|
34
32
|
firstName:
|
|
35
33
|
label: First name
|
|
36
|
-
rdf: http://xmlns.com/foaf/0.1/givenName
|
|
37
34
|
secondName:
|
|
38
35
|
label: Second name
|
|
39
36
|
middleName:
|
|
@@ -44,13 +41,11 @@ Person:
|
|
|
44
41
|
label: Matronymic
|
|
45
42
|
lastName:
|
|
46
43
|
label: Last name
|
|
47
|
-
rdf: http://xmlns.com/foaf/0.1/lastName
|
|
48
44
|
nameSuffix:
|
|
49
45
|
label: Name suffix
|
|
50
46
|
birthDate:
|
|
51
47
|
label: Birth date
|
|
52
48
|
type: date
|
|
53
|
-
rdf: http://xmlns.com/foaf/0.1/birthday
|
|
54
49
|
birthPlace:
|
|
55
50
|
label: Place of birth
|
|
56
51
|
birthCountry:
|
followthemoney/schema/Thing.yaml
CHANGED
|
@@ -14,7 +14,6 @@ Thing:
|
|
|
14
14
|
name:
|
|
15
15
|
label: Name
|
|
16
16
|
type: name
|
|
17
|
-
rdf: http://www.w3.org/2004/02/skos/core#prefLabel
|
|
18
17
|
summary: # a short one-liner kind of description
|
|
19
18
|
label: Summary
|
|
20
19
|
type: text
|
|
@@ -27,7 +26,6 @@ Thing:
|
|
|
27
26
|
alias:
|
|
28
27
|
label: Other name
|
|
29
28
|
type: name
|
|
30
|
-
rdf: http://www.w3.org/2004/02/skos/core#altLabel
|
|
31
29
|
previousName:
|
|
32
30
|
label: Previous name
|
|
33
31
|
type: name
|
|
@@ -28,11 +28,14 @@ UserAccount:
|
|
|
28
28
|
label: "Service"
|
|
29
29
|
type: string
|
|
30
30
|
email:
|
|
31
|
-
label:
|
|
31
|
+
label: E-Mail
|
|
32
32
|
type: email
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
description: "Email address"
|
|
34
|
+
phone:
|
|
35
|
+
label: Phone
|
|
35
36
|
type: phone
|
|
37
|
+
description: "Phone number"
|
|
38
|
+
maxLength: 32
|
|
36
39
|
username:
|
|
37
40
|
label: "Username"
|
|
38
41
|
type: string
|