followthemoney 4.3.1__py3-none-any.whl → 4.3.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.
Potentially problematic release.
This version of followthemoney might be problematic. Click here for more details.
- followthemoney/__init__.py +1 -1
- followthemoney/model.py +2 -0
- followthemoney/property.py +4 -3
- followthemoney/schema.py +4 -2
- followthemoney/statement/util.py +2 -2
- followthemoney/types/address.py +3 -3
- followthemoney/types/checksum.py +3 -3
- followthemoney/types/country.py +3 -3
- followthemoney/types/date.py +3 -3
- followthemoney/types/entity.py +3 -3
- followthemoney/types/gender.py +6 -6
- followthemoney/types/identifier.py +3 -3
- followthemoney/types/ip.py +3 -3
- followthemoney/types/json.py +2 -2
- followthemoney/types/language.py +3 -3
- followthemoney/types/mimetype.py +3 -3
- followthemoney/types/name.py +3 -3
- followthemoney/types/number.py +2 -2
- followthemoney/types/phone.py +3 -3
- followthemoney/types/string.py +2 -2
- followthemoney/types/topic.py +6 -3
- followthemoney/types/url.py +3 -3
- {followthemoney-4.3.1.dist-info → followthemoney-4.3.2.dist-info}/METADATA +1 -1
- {followthemoney-4.3.1.dist-info → followthemoney-4.3.2.dist-info}/RECORD +27 -27
- {followthemoney-4.3.1.dist-info → followthemoney-4.3.2.dist-info}/WHEEL +0 -0
- {followthemoney-4.3.1.dist-info → followthemoney-4.3.2.dist-info}/entry_points.txt +0 -0
- {followthemoney-4.3.1.dist-info → followthemoney-4.3.2.dist-info}/licenses/LICENSE +0 -0
followthemoney/__init__.py
CHANGED
|
@@ -9,7 +9,7 @@ from followthemoney.statement import Statement, StatementEntity, SE
|
|
|
9
9
|
from followthemoney.dataset import Dataset, DefaultDataset, DS
|
|
10
10
|
from followthemoney.util import set_model_locale
|
|
11
11
|
|
|
12
|
-
__version__ = "4.3.
|
|
12
|
+
__version__ = "4.3.2"
|
|
13
13
|
|
|
14
14
|
# Data model singleton
|
|
15
15
|
model = Model.instance()
|
followthemoney/model.py
CHANGED
|
@@ -9,6 +9,7 @@ from followthemoney.types.common import PropertyType, PropertyTypeToDict
|
|
|
9
9
|
from followthemoney.schema import Schema, SchemaToDict
|
|
10
10
|
from followthemoney.property import Property
|
|
11
11
|
from followthemoney.exc import InvalidModel, InvalidData
|
|
12
|
+
from followthemoney.util import const
|
|
12
13
|
|
|
13
14
|
if TYPE_CHECKING:
|
|
14
15
|
from followthemoney.proxy import EntityProxy
|
|
@@ -72,6 +73,7 @@ class Model(object):
|
|
|
72
73
|
if not isinstance(data, dict):
|
|
73
74
|
raise InvalidModel("Model file is not a mapping: %s" % filepath)
|
|
74
75
|
for name, config in data.items():
|
|
76
|
+
name = const(name)
|
|
75
77
|
self.schemata[name] = Schema(self, name, config)
|
|
76
78
|
|
|
77
79
|
def get(self, name: Union[str, Schema]) -> Optional[Schema]:
|
followthemoney/property.py
CHANGED
|
@@ -87,17 +87,16 @@ class Property:
|
|
|
87
87
|
self.schema = schema
|
|
88
88
|
|
|
89
89
|
#: Machine-readable name for this property.
|
|
90
|
-
self.name =
|
|
90
|
+
self.name = name
|
|
91
91
|
if not check_property_name(self.name):
|
|
92
92
|
raise InvalidModel("Invalid name: %s" % self.name)
|
|
93
93
|
|
|
94
94
|
#: Qualified property name, which also includes the schema name.
|
|
95
95
|
self.qname = const("%s:%s" % (schema.name, self.name))
|
|
96
96
|
|
|
97
|
-
self._hash = hash("<Property(%r)>" % self.qname)
|
|
98
|
-
|
|
99
97
|
self._label = data.get("label", name)
|
|
100
98
|
self._description = data.get("description")
|
|
99
|
+
self._hash = hash("<Property(%r)>" % self.qname)
|
|
101
100
|
|
|
102
101
|
#: This property is deprecated and should not be used.
|
|
103
102
|
self.deprecated = as_bool(data.get("deprecated", False))
|
|
@@ -162,6 +161,8 @@ class Property:
|
|
|
162
161
|
format_ = get_identifier_format(self.format)
|
|
163
162
|
if format_ is None or format_.NAME != self.format:
|
|
164
163
|
raise InvalidModel("Invalid identifier format: %s" % self.format)
|
|
164
|
+
# Internalize the string:
|
|
165
|
+
self.format = format_.NAME
|
|
165
166
|
|
|
166
167
|
@property
|
|
167
168
|
def label(self) -> str:
|
followthemoney/schema.py
CHANGED
|
@@ -106,7 +106,7 @@ class Schema:
|
|
|
106
106
|
|
|
107
107
|
def __init__(self, model: "Model", name: str, data: SchemaSpec) -> None:
|
|
108
108
|
#: Machine-readable name of the schema, used for identification.
|
|
109
|
-
self.name =
|
|
109
|
+
self.name = name
|
|
110
110
|
self.model = model
|
|
111
111
|
self._label = data.get("label", name)
|
|
112
112
|
self._plural = data.get("plural", self.label)
|
|
@@ -191,6 +191,7 @@ class Schema:
|
|
|
191
191
|
#: inherited from parent schemata.
|
|
192
192
|
self.properties: Dict[str, Property] = {}
|
|
193
193
|
for pname, prop in data.get("properties", {}).items():
|
|
194
|
+
pname = const(pname)
|
|
194
195
|
self.properties[pname] = Property(self, pname, prop)
|
|
195
196
|
|
|
196
197
|
def generate(self, model: "Model") -> None:
|
|
@@ -264,6 +265,7 @@ class Schema:
|
|
|
264
265
|
name = data.get("name")
|
|
265
266
|
if name is None:
|
|
266
267
|
raise InvalidModel("Unnamed reverse: %s" % other)
|
|
268
|
+
name = const(name)
|
|
267
269
|
|
|
268
270
|
prop = self.get(name)
|
|
269
271
|
if prop is None:
|
|
@@ -272,7 +274,7 @@ class Schema:
|
|
|
272
274
|
"type": registry.entity.name,
|
|
273
275
|
"reverse": {"name": other.name},
|
|
274
276
|
"range": other.schema.name,
|
|
275
|
-
"hidden": data.get("hidden", other.hidden),
|
|
277
|
+
"hidden": as_bool(data.get("hidden", other.hidden)),
|
|
276
278
|
}
|
|
277
279
|
prop = Property(self, name, spec)
|
|
278
280
|
prop.stub = True
|
followthemoney/statement/util.py
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import sys
|
|
2
1
|
from functools import cache
|
|
3
2
|
from typing import Tuple
|
|
4
3
|
|
|
5
4
|
from followthemoney.model import Model
|
|
5
|
+
from followthemoney.util import const
|
|
6
6
|
|
|
7
7
|
BASE_ID = "id"
|
|
8
8
|
|
|
@@ -28,4 +28,4 @@ def get_prop_type(schema: str, prop: str) -> str:
|
|
|
28
28
|
def unpack_prop(id: str) -> Tuple[str, str, str]:
|
|
29
29
|
schema, prop = id.split(":", 1)
|
|
30
30
|
prop_type = get_prop_type(schema, prop)
|
|
31
|
-
return
|
|
31
|
+
return const(schema), prop_type, const(prop)
|
followthemoney/types/address.py
CHANGED
|
@@ -6,7 +6,7 @@ from rigour.text.distance import levenshtein_similarity
|
|
|
6
6
|
|
|
7
7
|
from followthemoney.types.common import PropertyType
|
|
8
8
|
from followthemoney.util import defer as _
|
|
9
|
-
from followthemoney.util import dampen
|
|
9
|
+
from followthemoney.util import dampen
|
|
10
10
|
|
|
11
11
|
if TYPE_CHECKING:
|
|
12
12
|
from followthemoney.proxy import EntityProxy
|
|
@@ -20,8 +20,8 @@ class AddressType(PropertyType):
|
|
|
20
20
|
|
|
21
21
|
LINE_BREAKS = re.compile(r"(\r\n|\n|<BR/>|<BR>|\t|ESQ\.,|ESQ,|;)")
|
|
22
22
|
COMMATA = re.compile(r"(,\s?[,\.])")
|
|
23
|
-
name =
|
|
24
|
-
group =
|
|
23
|
+
name = "address"
|
|
24
|
+
group = "addresses"
|
|
25
25
|
label = _("Address")
|
|
26
26
|
plural = _("Addresses")
|
|
27
27
|
matchable = True
|
followthemoney/types/checksum.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from followthemoney.types.common import PropertyType
|
|
2
|
-
from followthemoney.util import
|
|
2
|
+
from followthemoney.util import defer as _
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
class ChecksumType(PropertyType):
|
|
@@ -12,8 +12,8 @@ class ChecksumType(PropertyType):
|
|
|
12
12
|
of this type are scrubbed when submitted via the normal API. Checksums can only
|
|
13
13
|
be defined by uploading a document to be ingested."""
|
|
14
14
|
|
|
15
|
-
name =
|
|
16
|
-
group =
|
|
15
|
+
name = "checksum"
|
|
16
|
+
group = "checksums"
|
|
17
17
|
label = _("Checksum")
|
|
18
18
|
plural = _("Checksums")
|
|
19
19
|
matchable = True
|
followthemoney/types/country.py
CHANGED
|
@@ -3,7 +3,7 @@ from babel.core import Locale
|
|
|
3
3
|
from rigour.territories import get_ftm_countries, lookup_territory
|
|
4
4
|
|
|
5
5
|
from followthemoney.types.common import EnumType, EnumValues
|
|
6
|
-
from followthemoney.util import
|
|
6
|
+
from followthemoney.util import defer as _
|
|
7
7
|
|
|
8
8
|
if TYPE_CHECKING:
|
|
9
9
|
from followthemoney.proxy import EntityProxy
|
|
@@ -15,8 +15,8 @@ class CountryType(EnumType):
|
|
|
15
15
|
a number of unusual and controversial designations (e.g. the Soviet Union,
|
|
16
16
|
Transnistria, Somaliland, Kosovo)."""
|
|
17
17
|
|
|
18
|
-
name =
|
|
19
|
-
group =
|
|
18
|
+
name = "country"
|
|
19
|
+
group = "countries"
|
|
20
20
|
label = _("Country")
|
|
21
21
|
plural = _("Countries")
|
|
22
22
|
matchable = True
|
followthemoney/types/date.py
CHANGED
|
@@ -5,7 +5,7 @@ from prefixdate import parse, parse_format, Precision
|
|
|
5
5
|
|
|
6
6
|
from followthemoney.types.common import PropertyType
|
|
7
7
|
from followthemoney.util import defer as _
|
|
8
|
-
from followthemoney.util import dampen
|
|
8
|
+
from followthemoney.util import dampen
|
|
9
9
|
|
|
10
10
|
if TYPE_CHECKING:
|
|
11
11
|
from followthemoney.proxy import EntityProxy
|
|
@@ -20,8 +20,8 @@ class DateType(PropertyType):
|
|
|
20
20
|
The timezone is always expected to be UTC and cannot be specified otherwise. There is
|
|
21
21
|
no support for calendar weeks (`2021-W7`) and date ranges (`2021-2024`)."""
|
|
22
22
|
|
|
23
|
-
name =
|
|
24
|
-
group =
|
|
23
|
+
name = "date"
|
|
24
|
+
group = "dates"
|
|
25
25
|
label = _("Date")
|
|
26
26
|
plural = _("Dates")
|
|
27
27
|
matchable = True
|
followthemoney/types/entity.py
CHANGED
|
@@ -4,7 +4,7 @@ from typing import Any, Optional, TYPE_CHECKING
|
|
|
4
4
|
from followthemoney.types.common import PropertyType
|
|
5
5
|
from followthemoney.value import Value
|
|
6
6
|
from followthemoney.util import ENTITY_ID_LEN, get_entity_id, sanitize_text
|
|
7
|
-
from followthemoney.util import
|
|
7
|
+
from followthemoney.util import gettext, defer as _
|
|
8
8
|
from followthemoney.exc import InvalidData
|
|
9
9
|
|
|
10
10
|
if TYPE_CHECKING:
|
|
@@ -22,8 +22,8 @@ class EntityType(PropertyType):
|
|
|
22
22
|
|
|
23
23
|
REGEX_RAW = r"^[0-9a-zA-Z]([0-9a-zA-Z\.\-]*[0-9a-zA-Z])?$"
|
|
24
24
|
REGEX = re.compile(REGEX_RAW)
|
|
25
|
-
name =
|
|
26
|
-
group =
|
|
25
|
+
name = "entity"
|
|
26
|
+
group = "entities"
|
|
27
27
|
label = _("Entity")
|
|
28
28
|
plural = _("Entities")
|
|
29
29
|
matchable = True
|
followthemoney/types/gender.py
CHANGED
|
@@ -2,7 +2,7 @@ from typing import Optional, TYPE_CHECKING
|
|
|
2
2
|
from babel.core import Locale
|
|
3
3
|
|
|
4
4
|
from followthemoney.types.common import EnumType, EnumValues
|
|
5
|
-
from followthemoney.util import
|
|
5
|
+
from followthemoney.util import gettext, defer as _
|
|
6
6
|
|
|
7
7
|
if TYPE_CHECKING:
|
|
8
8
|
from followthemoney.proxy import EntityProxy
|
|
@@ -14,9 +14,9 @@ class GenderType(EnumType):
|
|
|
14
14
|
government databases and represent it in a way that can be used by
|
|
15
15
|
structured tools. I'm not sure this justifies the simplification."""
|
|
16
16
|
|
|
17
|
-
MALE =
|
|
18
|
-
FEMALE =
|
|
19
|
-
OTHER =
|
|
17
|
+
MALE = "male"
|
|
18
|
+
FEMALE = "female"
|
|
19
|
+
OTHER = "other"
|
|
20
20
|
|
|
21
21
|
LOOKUP = {
|
|
22
22
|
"m": MALE,
|
|
@@ -34,8 +34,8 @@ class GenderType(EnumType):
|
|
|
34
34
|
"divers": OTHER,
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
name =
|
|
38
|
-
group =
|
|
37
|
+
name = "gender"
|
|
38
|
+
group = "genders"
|
|
39
39
|
label = _("Gender")
|
|
40
40
|
plural = _("Genders")
|
|
41
41
|
matchable = False
|
|
@@ -4,7 +4,7 @@ from rigour.ids import get_identifier_format
|
|
|
4
4
|
|
|
5
5
|
from followthemoney.types.common import PropertyType
|
|
6
6
|
from followthemoney.util import dampen, shortest, longest
|
|
7
|
-
from followthemoney.util import
|
|
7
|
+
from followthemoney.util import defer as _
|
|
8
8
|
|
|
9
9
|
if TYPE_CHECKING:
|
|
10
10
|
from followthemoney.proxy import EntityProxy
|
|
@@ -20,8 +20,8 @@ class IdentifierType(PropertyType):
|
|
|
20
20
|
Four- or five-digit industry classifiers create more noise than value."""
|
|
21
21
|
|
|
22
22
|
COMPARE_CLEAN = re.compile(r"[\W_]+")
|
|
23
|
-
name =
|
|
24
|
-
group =
|
|
23
|
+
name = "identifier"
|
|
24
|
+
group = "identifiers"
|
|
25
25
|
label = _("Identifier")
|
|
26
26
|
plural = _("Identifiers")
|
|
27
27
|
matchable = True
|
followthemoney/types/ip.py
CHANGED
|
@@ -2,7 +2,7 @@ from typing import Optional, TYPE_CHECKING
|
|
|
2
2
|
from ipaddress import ip_address
|
|
3
3
|
|
|
4
4
|
from followthemoney.types.common import PropertyType
|
|
5
|
-
from followthemoney.util import
|
|
5
|
+
from followthemoney.util import defer as _
|
|
6
6
|
|
|
7
7
|
if TYPE_CHECKING:
|
|
8
8
|
from followthemoney.proxy import EntityProxy
|
|
@@ -13,8 +13,8 @@ class IpType(PropertyType):
|
|
|
13
13
|
by the protocol versions 4 (e.g. `192.168.1.143`) and 6
|
|
14
14
|
(e.g. `0:0:0:0:0:ffff:c0a8:18f`)."""
|
|
15
15
|
|
|
16
|
-
name =
|
|
17
|
-
group =
|
|
16
|
+
name = "ip"
|
|
17
|
+
group = "ips"
|
|
18
18
|
label = _("IP Address")
|
|
19
19
|
plural = _("IP Addresses")
|
|
20
20
|
matchable = True
|
followthemoney/types/json.py
CHANGED
|
@@ -3,7 +3,7 @@ from typing import Any, Optional, Sequence, TYPE_CHECKING
|
|
|
3
3
|
from banal import ensure_list
|
|
4
4
|
|
|
5
5
|
from followthemoney.types.common import PropertyType
|
|
6
|
-
from followthemoney.util import
|
|
6
|
+
from followthemoney.util import sanitize_text, defer as _
|
|
7
7
|
|
|
8
8
|
if TYPE_CHECKING:
|
|
9
9
|
from followthemoney.proxy import EntityProxy
|
|
@@ -14,7 +14,7 @@ class JsonType(PropertyType):
|
|
|
14
14
|
and some other edge cases. It's a really bad idea and we should try to get rid
|
|
15
15
|
of JSON properties."""
|
|
16
16
|
|
|
17
|
-
name =
|
|
17
|
+
name = "json"
|
|
18
18
|
group = None
|
|
19
19
|
label = _("Nested data")
|
|
20
20
|
plural = _("Nested data")
|
followthemoney/types/language.py
CHANGED
|
@@ -4,7 +4,7 @@ from rigour.langs import iso_639_alpha3
|
|
|
4
4
|
|
|
5
5
|
from followthemoney.types.common import EnumType, EnumValues
|
|
6
6
|
from followthemoney.util import defer as _, gettext
|
|
7
|
-
from followthemoney.util import
|
|
7
|
+
from followthemoney.util import get_env_list
|
|
8
8
|
|
|
9
9
|
if TYPE_CHECKING:
|
|
10
10
|
from followthemoney.proxy import EntityProxy
|
|
@@ -16,8 +16,8 @@ class LanguageType(EnumType):
|
|
|
16
16
|
for additional languages once there is a specific need for them to be
|
|
17
17
|
supported."""
|
|
18
18
|
|
|
19
|
-
name =
|
|
20
|
-
group =
|
|
19
|
+
name = "language"
|
|
20
|
+
group = "languages"
|
|
21
21
|
label = _("Language")
|
|
22
22
|
plural = _("Languages")
|
|
23
23
|
matchable = False
|
followthemoney/types/mimetype.py
CHANGED
|
@@ -3,7 +3,7 @@ from rigour.mime import normalize_mimetype, parse_mimetype
|
|
|
3
3
|
from rigour.mime import DEFAULT
|
|
4
4
|
|
|
5
5
|
from followthemoney.types.common import PropertyType
|
|
6
|
-
from followthemoney.util import
|
|
6
|
+
from followthemoney.util import defer as _
|
|
7
7
|
|
|
8
8
|
if TYPE_CHECKING:
|
|
9
9
|
from followthemoney.proxy import EntityProxy
|
|
@@ -18,8 +18,8 @@ class MimeType(PropertyType):
|
|
|
18
18
|
MIME type properties do not contain parameters as used in HTTP headers,
|
|
19
19
|
like `charset=UTF-8`."""
|
|
20
20
|
|
|
21
|
-
name =
|
|
22
|
-
group =
|
|
21
|
+
name = "mimetype"
|
|
22
|
+
group = "mimetypes"
|
|
23
23
|
label = _("MIME-Type")
|
|
24
24
|
plural = _("MIME-Types")
|
|
25
25
|
matchable = False
|
followthemoney/types/name.py
CHANGED
|
@@ -7,7 +7,7 @@ from rigour.text.distance import levenshtein_similarity
|
|
|
7
7
|
|
|
8
8
|
from followthemoney.types.common import PropertyType
|
|
9
9
|
from followthemoney.util import dampen
|
|
10
|
-
from followthemoney.util import
|
|
10
|
+
from followthemoney.util import defer as _
|
|
11
11
|
|
|
12
12
|
if TYPE_CHECKING:
|
|
13
13
|
from followthemoney.proxy import EntityProxy
|
|
@@ -21,8 +21,8 @@ class NameType(PropertyType):
|
|
|
21
21
|
No validation rules apply, and things having multiple names must be considered
|
|
22
22
|
a perfectly ordinary case."""
|
|
23
23
|
|
|
24
|
-
name =
|
|
25
|
-
group =
|
|
24
|
+
name = "name"
|
|
25
|
+
group = "names"
|
|
26
26
|
label = _("Name")
|
|
27
27
|
plural = _("Names")
|
|
28
28
|
matchable = True
|
followthemoney/types/number.py
CHANGED
|
@@ -2,7 +2,7 @@ import re
|
|
|
2
2
|
from typing import Optional, Tuple
|
|
3
3
|
|
|
4
4
|
from followthemoney.types.common import PropertyType
|
|
5
|
-
from followthemoney.util import
|
|
5
|
+
from followthemoney.util import defer as _
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
class NumberType(PropertyType):
|
|
@@ -24,7 +24,7 @@ class NumberType(PropertyType):
|
|
|
24
24
|
_FLOAT_FMT = "{:" + SEPARATOR + "." + str(PRECISION) + "f}"
|
|
25
25
|
_INT_FMT = "{:" + SEPARATOR + "d}"
|
|
26
26
|
|
|
27
|
-
name =
|
|
27
|
+
name = "number"
|
|
28
28
|
label = _("Number")
|
|
29
29
|
plural = _("Numbers")
|
|
30
30
|
matchable = False
|
followthemoney/types/phone.py
CHANGED
|
@@ -6,7 +6,7 @@ from phonenumbers.phonenumberutil import region_code_for_number, NumberParseExce
|
|
|
6
6
|
|
|
7
7
|
from followthemoney.types.common import PropertyType
|
|
8
8
|
from followthemoney.util import defer as _
|
|
9
|
-
from followthemoney.util import
|
|
9
|
+
from followthemoney.util import dampen
|
|
10
10
|
|
|
11
11
|
if TYPE_CHECKING:
|
|
12
12
|
from followthemoney.proxy import EntityProxy
|
|
@@ -29,8 +29,8 @@ class PhoneType(PropertyType):
|
|
|
29
29
|
validation outcome from doing the two operations the other way around. Always
|
|
30
30
|
define the country first."""
|
|
31
31
|
|
|
32
|
-
name =
|
|
33
|
-
group =
|
|
32
|
+
name = "phone"
|
|
33
|
+
group = "phones"
|
|
34
34
|
label = _("Phone number")
|
|
35
35
|
plural = _("Phone numbers")
|
|
36
36
|
matchable = True
|
followthemoney/types/string.py
CHANGED
|
@@ -6,7 +6,7 @@ from followthemoney.util import MEGABYTE
|
|
|
6
6
|
class StringType(PropertyType):
|
|
7
7
|
"""A simple string property with no additional semantics."""
|
|
8
8
|
|
|
9
|
-
name =
|
|
9
|
+
name = "string"
|
|
10
10
|
label = _("Label")
|
|
11
11
|
plural = _("Labels")
|
|
12
12
|
matchable = False
|
|
@@ -21,7 +21,7 @@ class TextType(StringType):
|
|
|
21
21
|
string properties, it might make sense to treat properties of this type as
|
|
22
22
|
full-text search material."""
|
|
23
23
|
|
|
24
|
-
name =
|
|
24
|
+
name = "text"
|
|
25
25
|
label = _("Text")
|
|
26
26
|
plural = _("Texts")
|
|
27
27
|
total_size = 30 * MEGABYTE
|
followthemoney/types/topic.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from babel.core import Locale
|
|
2
2
|
|
|
3
3
|
from followthemoney.types.common import EnumType, EnumValues
|
|
4
|
-
from followthemoney.util import
|
|
4
|
+
from followthemoney.util import gettext, defer as _
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
class TopicType(EnumType):
|
|
@@ -15,8 +15,8 @@ class TopicType(EnumType):
|
|
|
15
15
|
enable queries such as _find all paths between a government procurement
|
|
16
16
|
award and a politician_."""
|
|
17
17
|
|
|
18
|
-
name =
|
|
19
|
-
group =
|
|
18
|
+
name = "topic"
|
|
19
|
+
group = "topics"
|
|
20
20
|
label = _("Topic")
|
|
21
21
|
plural = _("Topics")
|
|
22
22
|
matchable = False
|
|
@@ -86,6 +86,8 @@ class TopicType(EnumType):
|
|
|
86
86
|
"sanction.linked": _("Sanction-linked entity"),
|
|
87
87
|
"sanction.counter": _("Counter-sanctioned entity"),
|
|
88
88
|
"export.control": _("Export controlled"),
|
|
89
|
+
# For BIS 50% rule:
|
|
90
|
+
"export.control.linked": _("Export control-linked"),
|
|
89
91
|
"export.risk": _("Trade risk"),
|
|
90
92
|
"debarment": _("Debarred entity"),
|
|
91
93
|
"poi": _("Person of interest"),
|
|
@@ -103,6 +105,7 @@ class TopicType(EnumType):
|
|
|
103
105
|
"crime",
|
|
104
106
|
"debarment",
|
|
105
107
|
"export.control",
|
|
108
|
+
"export.control.linked",
|
|
106
109
|
"export.risk",
|
|
107
110
|
"poi",
|
|
108
111
|
"mare.detained",
|
followthemoney/types/url.py
CHANGED
|
@@ -2,7 +2,7 @@ from typing import Optional, TYPE_CHECKING
|
|
|
2
2
|
from rigour.urls import clean_url, compare_urls
|
|
3
3
|
|
|
4
4
|
from followthemoney.types.common import PropertyType
|
|
5
|
-
from followthemoney.util import
|
|
5
|
+
from followthemoney.util import dampen, defer as _
|
|
6
6
|
|
|
7
7
|
if TYPE_CHECKING:
|
|
8
8
|
from followthemoney.proxy import EntityProxy
|
|
@@ -16,8 +16,8 @@ class UrlType(PropertyType):
|
|
|
16
16
|
SCHEMES = ("http", "https", "ftp", "mailto")
|
|
17
17
|
DEFAULT_SCHEME = "http"
|
|
18
18
|
|
|
19
|
-
name =
|
|
20
|
-
group =
|
|
19
|
+
name = "url"
|
|
20
|
+
group = "urls"
|
|
21
21
|
label = _("URL")
|
|
22
22
|
plural = _("URLs")
|
|
23
23
|
matchable = True
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: followthemoney
|
|
3
|
-
Version: 4.3.
|
|
3
|
+
Version: 4.3.2
|
|
4
4
|
Summary: A data model for anti corruption data modeling and analysis.
|
|
5
5
|
Project-URL: Documentation, https://followthemoney.tech/
|
|
6
6
|
Project-URL: Repository, https://github.com/opensanctions/followthemoney.git
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
followthemoney/__init__.py,sha256=
|
|
1
|
+
followthemoney/__init__.py,sha256=kG5Rw6bsNjeqFk_uLfIEX5RmB6YTLuc5iQJG_ZnqUII,856
|
|
2
2
|
followthemoney/compare.py,sha256=frgumsDv4Ru9UkNof62jDjKCxxpCgV1Rusfu8s20uGA,6327
|
|
3
3
|
followthemoney/entity.py,sha256=bBiX7hNquXemS3vYCUHKtWI_IqX43Z6i8RQDbZ7gXsg,3449
|
|
4
4
|
followthemoney/exc.py,sha256=GyMgwY4QVm87hLevDfV7gM1MJsDqfNCi_UQw7F_A8X8,858
|
|
5
5
|
followthemoney/graph.py,sha256=7X1CGHGvmktS2LSZqld2iXWzG7B831eCNYyBqamqEJ8,10921
|
|
6
6
|
followthemoney/helpers.py,sha256=KCdv1XAE7KQEXBiXp52Kvuck7wMaeNVBM3uaFemcvb4,7873
|
|
7
7
|
followthemoney/messages.py,sha256=zUEa9CFecU8nRafIzhN6TKCh1kEihiIyIS1qr8PxY4g,806
|
|
8
|
-
followthemoney/model.py,sha256=
|
|
8
|
+
followthemoney/model.py,sha256=chAUGob5tXWS0o8f0X6mSFCCnI2HoHE5pXU9O5ukrpc,7447
|
|
9
9
|
followthemoney/names.py,sha256=LODQqExKEHdH4z6Mmbhlm0KeKRzGcptaSWzYXZ7lONI,1120
|
|
10
10
|
followthemoney/namespace.py,sha256=utggu9IGA8bhgEYom3OUB1KxkAJR_TrMNbY5MUF_db8,4536
|
|
11
11
|
followthemoney/ontology.py,sha256=WWY_PYQGl5Ket4zZBuZglzQxD2Bh9UqHok6GJNNX7GA,3001
|
|
12
|
-
followthemoney/property.py,sha256=
|
|
12
|
+
followthemoney/property.py,sha256=bIkSEAMbxCxZUV4ze_65edZjR9CI7WWvy-7CS32hgSk,8303
|
|
13
13
|
followthemoney/proxy.py,sha256=nahd9lLZzum_-QEchqydinDa1Zg5_Ffl0fyo35BNncQ,19707
|
|
14
14
|
followthemoney/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
15
|
-
followthemoney/schema.py,sha256=
|
|
15
|
+
followthemoney/schema.py,sha256=ylyL7mBx7TG86OlZmXg6y4sgpEiIUBZUPy9q83hMHrc,18149
|
|
16
16
|
followthemoney/util.py,sha256=LoCSp1iE6VwXjotCkBXFRppeQs55726GzOuNIu3CvRE,4409
|
|
17
17
|
followthemoney/value.py,sha256=BJ4Sj5Tg2kMrslR6FjQUr96d8Kt75U7ny9NgzVGT0ZE,2335
|
|
18
18
|
followthemoney/cli/__init__.py,sha256=0mmz84uhXRp2qUn3syKnDXofU3MMAAe291s7htqX0Bg,187
|
|
@@ -117,7 +117,7 @@ followthemoney/statement/__init__.py,sha256=7m2VUCAuqNZXIY0WFJRFkw5UG14QuxATL4f_
|
|
|
117
117
|
followthemoney/statement/entity.py,sha256=oeudwhqfYLJKqbzxEydasMHqevkDASNyYN6s0yddW6I,18755
|
|
118
118
|
followthemoney/statement/serialize.py,sha256=9eXzQ1biR2mSxWRID5C7xDdku4b4ZImHeRJ53yLZ0yo,7225
|
|
119
119
|
followthemoney/statement/statement.py,sha256=Ae-EYuzS8S12BkaRqrvMuI1C7YwlRKa5C_pTBELyNMM,8029
|
|
120
|
-
followthemoney/statement/util.py,sha256=
|
|
120
|
+
followthemoney/statement/util.py,sha256=QMYSwAcnh2fCM1LtH_-v8Z5GdwOZfUTT1UkQ_ZMQ470,797
|
|
121
121
|
followthemoney/translations/messages.pot,sha256=JhtY9NJ9wP_EAX4APxOqMyvKcX53oIC9kAxBsliJkf4,107703
|
|
122
122
|
followthemoney/translations/ar/LC_MESSAGES/followthemoney.mo,sha256=uhb2crSNh8K2ts_QUeD2wvgWgzzpLJWRzXok-Uyx3Zk,38795
|
|
123
123
|
followthemoney/translations/ar/LC_MESSAGES/followthemoney.po,sha256=DuIfvR5v0sPGwFbeg3y6_jCbeglvHWXQ2LDH6prfwLc,121326
|
|
@@ -142,27 +142,27 @@ followthemoney/translations/ru/LC_MESSAGES/followthemoney.po,sha256=7SQWytOTvoAQ
|
|
|
142
142
|
followthemoney/translations/tr/LC_MESSAGES/followthemoney.mo,sha256=SC84e_ZF_oFJG1NKdyZY_W6Kb6POORZB6wdeAcEWmnE,487
|
|
143
143
|
followthemoney/translations/tr/LC_MESSAGES/followthemoney.po,sha256=AZC3marhtVVq8Ck1FOgnt4sbDMz548nX48O9GDwImbQ,89826
|
|
144
144
|
followthemoney/types/__init__.py,sha256=rWwQeiuMh2BNIuvhpMfJ4bPADDvt9Axu1eedvNFi0qY,3350
|
|
145
|
-
followthemoney/types/address.py,sha256=
|
|
146
|
-
followthemoney/types/checksum.py,sha256=
|
|
145
|
+
followthemoney/types/address.py,sha256=Gc-hqz00dRRkeANqkyPD2wtt7ksR9wMf4CX-U-5XvMo,2214
|
|
146
|
+
followthemoney/types/checksum.py,sha256=_0ev2Wwtd4iX_bLz0Lu-xcJIxNfH_V9kBKKtuZhoAwg,802
|
|
147
147
|
followthemoney/types/common.py,sha256=4ks7zPT8rknrGSd4JFc1zRkS-TL4SX-25_ZbjcVDos0,10081
|
|
148
|
-
followthemoney/types/country.py,sha256=
|
|
149
|
-
followthemoney/types/date.py,sha256=
|
|
148
|
+
followthemoney/types/country.py,sha256=X3Z1j6rIiCITpLtpFXwjTIh9uJwI99_gmPMJx8Jsq2w,1512
|
|
149
|
+
followthemoney/types/date.py,sha256=O3Xav9QNBqjy7LuUWiZrUdGrOvwwOdk6ea5qQEStIwQ,3084
|
|
150
150
|
followthemoney/types/email.py,sha256=L3RTYrMABlNQF7hCynXGfzoj6YNEHW5JAY_BwuhoZdA,3375
|
|
151
|
-
followthemoney/types/entity.py,sha256=
|
|
152
|
-
followthemoney/types/gender.py,sha256=
|
|
153
|
-
followthemoney/types/identifier.py,sha256=
|
|
154
|
-
followthemoney/types/ip.py,sha256=
|
|
155
|
-
followthemoney/types/json.py,sha256=
|
|
156
|
-
followthemoney/types/language.py,sha256=
|
|
157
|
-
followthemoney/types/mimetype.py,sha256=
|
|
158
|
-
followthemoney/types/name.py,sha256=
|
|
159
|
-
followthemoney/types/number.py,sha256=
|
|
160
|
-
followthemoney/types/phone.py,sha256=
|
|
161
|
-
followthemoney/types/string.py,sha256=
|
|
162
|
-
followthemoney/types/topic.py,sha256=
|
|
163
|
-
followthemoney/types/url.py,sha256=
|
|
164
|
-
followthemoney-4.3.
|
|
165
|
-
followthemoney-4.3.
|
|
166
|
-
followthemoney-4.3.
|
|
167
|
-
followthemoney-4.3.
|
|
168
|
-
followthemoney-4.3.
|
|
151
|
+
followthemoney/types/entity.py,sha256=56h6x8Ct7hWZIC3BjZHmRKGy9Ff2vuULNWH3xDRsKiU,2317
|
|
152
|
+
followthemoney/types/gender.py,sha256=XY9us98Sk25O1xnHN-88tbv9pHy6Mn7SR8GRYi6v5gI,1683
|
|
153
|
+
followthemoney/types/identifier.py,sha256=TYJwE7urjHFxEcDuiZMxGoCN6n34rAIdCt5_96Y7vI0,2198
|
|
154
|
+
followthemoney/types/ip.py,sha256=rCXkRrh_jDeWAhswCgSe6Z4uhIW7yvLAxIEw4x1SM3A,1279
|
|
155
|
+
followthemoney/types/json.py,sha256=Hefwns1-ziJf310MWvdfX5ICkOgj9cnnMJuqq1e6qKY,1676
|
|
156
|
+
followthemoney/types/language.py,sha256=JDFCO9g9lvgKihhYTz6e7TbJd3V9RTGJlS8kDn6aSCY,2726
|
|
157
|
+
followthemoney/types/mimetype.py,sha256=oqVP8EfGckPAI3WAziHomp6oUN7KXdIPWzGZPsRtIA8,1242
|
|
158
|
+
followthemoney/types/name.py,sha256=zd0aC4VGp1SYUI8Rj0-ZXlrpUI7ZcnJIljZqsEsV-CY,2363
|
|
159
|
+
followthemoney/types/number.py,sha256=vpAyhmc7UQlIm8h7Z5k8k4cTk37ykRF-AgYA1r_g1QQ,3934
|
|
160
|
+
followthemoney/types/phone.py,sha256=_HanfxxTV7jp75gZO2evBc9HWwQTxEMQRaoVDcoXDIQ,3790
|
|
161
|
+
followthemoney/types/string.py,sha256=SEh3xqQCnm377PGvwfR6ao85pHJCNeCUWBKnvccrJ7I,1216
|
|
162
|
+
followthemoney/types/topic.py,sha256=9FIH_WmwVOFg1CJRBF4KeE6vNTn-QQkzsKU5XaMqNJ0,4604
|
|
163
|
+
followthemoney/types/url.py,sha256=sSHKtzvm4kc-VTvNCPIDykOG1hUoawhORj6Bklo0a2A,1434
|
|
164
|
+
followthemoney-4.3.2.dist-info/METADATA,sha256=mbUEVQBE2Sx9c9SjZjHWnRreRI0HPuDZ5k-KnNhF8uo,6747
|
|
165
|
+
followthemoney-4.3.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
166
|
+
followthemoney-4.3.2.dist-info/entry_points.txt,sha256=caoFTlf213jhg5sz3TNSofutjUTzaKtWATuSIdd9Cps,653
|
|
167
|
+
followthemoney-4.3.2.dist-info/licenses/LICENSE,sha256=H6_EVXisnJC0-18CjXIaqrBSFq_VH3OnS7u3dccOv6g,1148
|
|
168
|
+
followthemoney-4.3.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|