followthemoney 1.3.7__py3-none-any.whl → 3.8.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.
Files changed (186) hide show
  1. followthemoney/__init__.py +5 -3
  2. followthemoney/cli/__init__.py +17 -0
  3. followthemoney/cli/aggregate.py +56 -0
  4. followthemoney/cli/cli.py +88 -0
  5. followthemoney/cli/exports.py +121 -0
  6. followthemoney/cli/mapping.py +85 -0
  7. followthemoney/cli/sieve.py +67 -0
  8. followthemoney/cli/util.py +142 -0
  9. followthemoney/compare.py +130 -60
  10. followthemoney/exc.py +19 -6
  11. followthemoney/export/common.py +29 -0
  12. followthemoney/export/csv.py +82 -0
  13. followthemoney/export/excel.py +75 -0
  14. followthemoney/export/graph.py +79 -0
  15. followthemoney/export/neo4j.py +182 -0
  16. followthemoney/export/rdf.py +26 -0
  17. followthemoney/graph.py +308 -0
  18. followthemoney/helpers.py +212 -0
  19. followthemoney/mapping/__init__.py +1 -1
  20. followthemoney/mapping/csv.py +67 -35
  21. followthemoney/mapping/entity.py +116 -44
  22. followthemoney/mapping/property.py +90 -44
  23. followthemoney/mapping/query.py +27 -19
  24. followthemoney/mapping/source.py +15 -5
  25. followthemoney/mapping/sql.py +75 -61
  26. followthemoney/messages.py +13 -7
  27. followthemoney/model.py +108 -56
  28. followthemoney/namespace.py +119 -0
  29. followthemoney/offshore.py +48 -0
  30. followthemoney/ontology.py +77 -0
  31. followthemoney/property.py +204 -71
  32. followthemoney/proxy.py +455 -118
  33. followthemoney/rdf.py +9 -0
  34. followthemoney/schema/Address.yaml +78 -0
  35. followthemoney/schema/Airplane.yaml +17 -10
  36. followthemoney/schema/Analyzable.yaml +54 -0
  37. followthemoney/schema/Article.yaml +16 -0
  38. followthemoney/schema/Assessment.yaml +32 -0
  39. followthemoney/schema/Asset.yaml +10 -4
  40. followthemoney/schema/Associate.yaml +41 -0
  41. followthemoney/schema/Audio.yaml +24 -0
  42. followthemoney/schema/BankAccount.yaml +53 -9
  43. followthemoney/schema/Call.yaml +48 -0
  44. followthemoney/schema/CallForTenders.yaml +117 -0
  45. followthemoney/schema/Company.yaml +37 -12
  46. followthemoney/schema/Contract.yaml +41 -7
  47. followthemoney/schema/ContractAward.yaml +30 -11
  48. followthemoney/schema/CourtCase.yaml +16 -10
  49. followthemoney/schema/CourtCaseParty.yaml +17 -6
  50. followthemoney/schema/CryptoWallet.yaml +48 -0
  51. followthemoney/schema/Debt.yaml +37 -0
  52. followthemoney/schema/Directorship.yaml +17 -4
  53. followthemoney/schema/Document.yaml +72 -139
  54. followthemoney/schema/Documentation.yml +38 -0
  55. followthemoney/schema/EconomicActivity.yaml +32 -17
  56. followthemoney/schema/Email.yaml +76 -0
  57. followthemoney/schema/Employment.yaml +39 -0
  58. followthemoney/schema/Event.yaml +35 -3
  59. followthemoney/schema/Family.yaml +41 -0
  60. followthemoney/schema/Folder.yaml +13 -0
  61. followthemoney/schema/HyperText.yaml +21 -0
  62. followthemoney/schema/Identification.yaml +40 -0
  63. followthemoney/schema/Image.yaml +25 -0
  64. followthemoney/schema/Interest.yaml +3 -6
  65. followthemoney/schema/Interval.yaml +56 -5
  66. followthemoney/schema/LegalEntity.yaml +81 -20
  67. followthemoney/schema/License.yaml +7 -3
  68. followthemoney/schema/Membership.yaml +19 -4
  69. followthemoney/schema/Mention.yaml +54 -0
  70. followthemoney/schema/Message.yaml +73 -0
  71. followthemoney/schema/Note.yaml +23 -0
  72. followthemoney/schema/Occupancy.yaml +40 -0
  73. followthemoney/schema/Organization.yaml +38 -3
  74. followthemoney/schema/Ownership.yaml +16 -4
  75. followthemoney/schema/Package.yaml +17 -0
  76. followthemoney/schema/Page.yaml +43 -0
  77. followthemoney/schema/Pages.yaml +23 -0
  78. followthemoney/schema/Passport.yaml +15 -17
  79. followthemoney/schema/Payment.yaml +38 -7
  80. followthemoney/schema/Person.yaml +61 -5
  81. followthemoney/schema/PlainText.yaml +17 -0
  82. followthemoney/schema/Position.yaml +50 -0
  83. followthemoney/schema/Post.yaml +42 -0
  84. followthemoney/schema/Project.yaml +27 -0
  85. followthemoney/schema/ProjectParticipant.yaml +36 -0
  86. followthemoney/schema/PublicBody.yaml +14 -3
  87. followthemoney/schema/RealEstate.yaml +19 -3
  88. followthemoney/schema/Representation.yaml +17 -6
  89. followthemoney/schema/Sanction.yaml +44 -20
  90. followthemoney/schema/Security.yaml +59 -0
  91. followthemoney/schema/Similar.yaml +37 -0
  92. followthemoney/schema/Succession.yaml +36 -0
  93. followthemoney/schema/Table.yaml +32 -0
  94. followthemoney/schema/TaxRoll.yaml +27 -9
  95. followthemoney/schema/Thing.yaml +69 -13
  96. followthemoney/schema/Trip.yaml +42 -0
  97. followthemoney/schema/UnknownLink.yaml +17 -6
  98. followthemoney/schema/UserAccount.yaml +44 -0
  99. followthemoney/schema/Value.yaml +5 -1
  100. followthemoney/schema/Vehicle.yaml +25 -8
  101. followthemoney/schema/Vessel.yaml +18 -10
  102. followthemoney/schema/Video.yaml +20 -0
  103. followthemoney/schema/Workbook.yaml +18 -0
  104. followthemoney/schema.py +406 -135
  105. followthemoney/translations/ar/LC_MESSAGES/followthemoney.mo +0 -0
  106. followthemoney/translations/ar/LC_MESSAGES/followthemoney.po +2900 -787
  107. followthemoney/translations/bs/LC_MESSAGES/followthemoney.mo +0 -0
  108. followthemoney/translations/bs/LC_MESSAGES/followthemoney.po +2108 -520
  109. followthemoney/translations/de/LC_MESSAGES/followthemoney.mo +0 -0
  110. followthemoney/translations/de/LC_MESSAGES/followthemoney.po +2902 -782
  111. followthemoney/translations/es/LC_MESSAGES/followthemoney.mo +0 -0
  112. followthemoney/translations/es/LC_MESSAGES/followthemoney.po +2893 -779
  113. followthemoney/translations/fr/LC_MESSAGES/followthemoney.mo +0 -0
  114. followthemoney/translations/fr/LC_MESSAGES/followthemoney.po +4362 -0
  115. followthemoney/translations/fr/followthemoney.po +3861 -0
  116. followthemoney/translations/messages.pot +3021 -725
  117. followthemoney/translations/nb/LC_MESSAGES/followthemoney.mo +0 -0
  118. followthemoney/translations/nb/LC_MESSAGES/followthemoney.po +3778 -0
  119. followthemoney/translations/nl/LC_MESSAGES/followthemoney.mo +0 -0
  120. followthemoney/translations/nl/LC_MESSAGES/followthemoney.po +3837 -0
  121. followthemoney/translations/pt_BR/LC_MESSAGES/followthemoney.mo +0 -0
  122. followthemoney/translations/pt_BR/LC_MESSAGES/followthemoney.po +3784 -0
  123. followthemoney/translations/ru/LC_MESSAGES/followthemoney.mo +0 -0
  124. followthemoney/translations/ru/LC_MESSAGES/followthemoney.po +2837 -539
  125. followthemoney/translations/ru/followthemoney.po +4221 -0
  126. followthemoney/translations/tr/LC_MESSAGES/followthemoney.mo +0 -0
  127. followthemoney/translations/tr/LC_MESSAGES/followthemoney.po +2073 -491
  128. followthemoney/types/__init__.py +35 -17
  129. followthemoney/types/address.py +41 -21
  130. followthemoney/types/checksum.py +25 -0
  131. followthemoney/types/common.py +233 -88
  132. followthemoney/types/country.py +89 -56
  133. followthemoney/types/date.py +59 -76
  134. followthemoney/types/email.py +66 -35
  135. followthemoney/types/entity.py +66 -13
  136. followthemoney/types/gender.py +66 -0
  137. followthemoney/types/iban.py +47 -28
  138. followthemoney/types/identifier.py +49 -22
  139. followthemoney/types/ip.py +35 -21
  140. followthemoney/types/json.py +58 -0
  141. followthemoney/types/language.py +124 -37
  142. followthemoney/types/mimetype.py +44 -0
  143. followthemoney/types/name.py +56 -12
  144. followthemoney/types/number.py +30 -0
  145. followthemoney/types/phone.py +92 -34
  146. followthemoney/types/registry.py +52 -0
  147. followthemoney/types/string.py +43 -0
  148. followthemoney/types/topic.py +94 -0
  149. followthemoney/types/url.py +39 -17
  150. followthemoney/util.py +139 -45
  151. followthemoney-3.8.0.dist-info/METADATA +153 -0
  152. followthemoney-3.8.0.dist-info/RECORD +157 -0
  153. {followthemoney-1.3.7.dist-info → followthemoney-3.8.0.dist-info}/WHEEL +1 -2
  154. followthemoney-3.8.0.dist-info/entry_points.txt +17 -0
  155. followthemoney-1.3.7.dist-info/LICENSE.txt → followthemoney-3.8.0.dist-info/licenses/LICENSE +1 -1
  156. followthemoney/link.py +0 -75
  157. followthemoney/schema/Associate.yml +0 -19
  158. followthemoney/schema/Family.yml +0 -19
  159. followthemoney/schema/Land.yml +0 -9
  160. followthemoney/schema/Relationship.yaml +0 -26
  161. followthemoney/types/domain.py +0 -50
  162. followthemoney-1.3.7.dist-info/DESCRIPTION.rst +0 -3
  163. followthemoney-1.3.7.dist-info/METADATA +0 -39
  164. followthemoney-1.3.7.dist-info/RECORD +0 -108
  165. followthemoney-1.3.7.dist-info/entry_points.txt +0 -3
  166. followthemoney-1.3.7.dist-info/metadata.json +0 -1
  167. followthemoney-1.3.7.dist-info/namespace_packages.txt +0 -1
  168. followthemoney-1.3.7.dist-info/top_level.txt +0 -3
  169. ns/ontology.py +0 -128
  170. tests/types/test_addresses.py +0 -24
  171. tests/types/test_common.py +0 -32
  172. tests/types/test_countries.py +0 -27
  173. tests/types/test_dates.py +0 -73
  174. tests/types/test_domains.py +0 -23
  175. tests/types/test_emails.py +0 -32
  176. tests/types/test_entity.py +0 -19
  177. tests/types/test_iban.py +0 -109
  178. tests/types/test_identifiers.py +0 -27
  179. tests/types/test_ip.py +0 -29
  180. tests/types/test_languages.py +0 -23
  181. tests/types/test_names.py +0 -33
  182. tests/types/test_phones.py +0 -24
  183. tests/types/test_registry.py +0 -14
  184. tests/types/test_urls.py +0 -23
  185. {ns → followthemoney/export}/__init__.py +0 -0
  186. /tests/types/__init__.py → /followthemoney/py.typed +0 -0
@@ -1,108 +0,0 @@
1
- followthemoney/__init__.py,sha256=sADtT61dmZQulxvCMeOf0L5x5jLcCPQTnhSO8ecwJd4,297
2
- followthemoney/compare.py,sha256=WIrQsGK1R0qBlpwwj_SsyLWCnd1pGxE24IqvhLDDFgQ,2394
3
- followthemoney/exc.py,sha256=QVCtjW12TA-O6fqn4r6WAp_94vWgUigZ-rRTknRDwOs,389
4
- followthemoney/link.py,sha256=-qKb7o_1zFT7qB7xwkSw2ZtLM9TNFp7MuEuVDdRwBp4,2485
5
- followthemoney/messages.py,sha256=bZ40lXmBDl6cKBsmqdSF6uQJ28BYHpE9kwpVxVuBjKs,585
6
- followthemoney/model.py,sha256=DwyOjueXbJZFyquUxqE5LGzcq6g5YZThUpVIUTxwvHo,3420
7
- followthemoney/property.py,sha256=TtPFpXYCRi2AWUZWMfaZMlUWwSPHfqXxQoQxvLl8NoY,3047
8
- followthemoney/proxy.py,sha256=t-4v_3n2ZhZ9TxmOphPesVkpE6Mcvi8eL8Br1SV-U0k,5665
9
- followthemoney/schema.py,sha256=O_nhb-8--IHbV_Qz9f0Yd1UtAft2CWz_J7F273JifxY,6159
10
- followthemoney/util.py,sha256=xV9LiTQVlv7p2yYsZn-JTWYrpsgj-hM6J1vcERLC-mA,1849
11
- followthemoney/mapping/__init__.py,sha256=j5xXyrabtgBVPyBao_W37a2cebJaDD8yhkdHmgLEajk,80
12
- followthemoney/mapping/csv.py,sha256=t5r3laRJfA--IwhaxXcqnwbtD2hJAn_Zt60wkzPPl1c,2152
13
- followthemoney/mapping/entity.py,sha256=W98bUmLlTL3nQnTs3yM7KbtcqrMayQ77HQb-iQgUI5k,3269
14
- followthemoney/mapping/property.py,sha256=pir_U9RJzbAvj9j7cAq_T3t-Uizyhv7MgHLd8e7vNQI,3632
15
- followthemoney/mapping/query.py,sha256=jAX0pgEZnCCc1SgIaFLDj5QLAgAIsD1EC5ITKvIOYcU,2179
16
- followthemoney/mapping/source.py,sha256=wesjkTXSGdASi74d_8QIxqWjBBSl7rbpixyCcbQEEMw,260
17
- followthemoney/mapping/sql.py,sha256=JRqTvl4qN0ROeOVVuYoA5s5bET4MZs-D6sxzyN4gdzM,3929
18
- followthemoney/schema/Airplane.yaml,sha256=-l9tQrY-8U_j_3pqzo8M07xmJysN_-R8gn7kFt2RIFQ,556
19
- followthemoney/schema/Asset.yaml,sha256=iKZDR9_r6CwYZL0rr91i6wovxtviH1f-hPs1cXjNgn0,134
20
- followthemoney/schema/Associate.yml,sha256=5zlIzSseo6jXvy1T8_kVS5U6a8BKcd-x8c2CF8ckzts,440
21
- followthemoney/schema/BankAccount.yaml,sha256=0-CKrwUwmECWlhacqRq0-JMc7Ne68rXjQEJH2Ksk58I,486
22
- followthemoney/schema/Company.yaml,sha256=4Hk2xOGVrNtB7V8W6ldati-N2V8-IM3lOBqX2J5DuJs,2465
23
- followthemoney/schema/Contract.yaml,sha256=geYyK068GW60qiB8DSbRYGvUGa02e2gAE1hy9yHa7wQ,952
24
- followthemoney/schema/ContractAward.yaml,sha256=npN-AQKK384-qqdAs6Fh6NRmQp5jkQos6IeOQtwbkWQ,1313
25
- followthemoney/schema/CourtCase.yaml,sha256=uYVbK2HQSZKxvoIGkcR8FApKUaP_xjWUibuFWBGmkFw,542
26
- followthemoney/schema/CourtCaseParty.yaml,sha256=NHIV7ogEDuWP--elF4BbQ1UZv56nxBxt8GU2jbMHuhM,431
27
- followthemoney/schema/Directorship.yaml,sha256=D4Dwn-PCAyd-nyt4EYtvjH5Ut55nii_nQNErEDbp7b8,578
28
- followthemoney/schema/Document.yaml,sha256=dNbKTSxBmGlhA95FQV1IPDufi2xUtR5hqkzmfZWRnLM,3776
29
- followthemoney/schema/EconomicActivity.yaml,sha256=z31dYAeTcCO3fA1AJbTeykuqPD0THMSJCB6ytlcb08E,3632
30
- followthemoney/schema/Event.yaml,sha256=E5g0T-lw5OeD6c26H4uCK6V0KmwFcsOnBQZYSrEkCWo,190
31
- followthemoney/schema/Family.yml,sha256=DqCvwLAdVDuhnFn_PYlCXDAnyKN6PGsk4a7bjheEzlw,426
32
- followthemoney/schema/Interest.yaml,sha256=V2YKMKMJ8vsCF0NbcNgqalVzfZQKIAGVw0MRrfMzLn0,335
33
- followthemoney/schema/Interval.yaml,sha256=IWCpj99wqpgPV0Hexr1s_YEUiX_zWTlziDtnOWIJHUw,398
34
- followthemoney/schema/Land.yml,sha256=49x9k8u8NSChjiql981ivG0vtu8DITyc6IgxCibX-y8,145
35
- followthemoney/schema/LegalEntity.yaml,sha256=A8tvAgKG8oDNPx8wvZHnNPTWX_7_QZL1KdHnDRCk-ds,2695
36
- followthemoney/schema/License.yaml,sha256=tf8EZkDqsNL5Kxj8X6J8CnZBnDfPYqqqXo3Q7TQuOt8,413
37
- followthemoney/schema/Membership.yaml,sha256=CxwBuzDQwSEeVV4_D7iDcohtF9RepAD34FsGWNldFns,485
38
- followthemoney/schema/Organization.yaml,sha256=fKg__araMoDk0YbSfqIN3rYTzSeVJKSFiqrtgtuIvt4,122
39
- followthemoney/schema/Ownership.yaml,sha256=ya1p7Paqq2mL4sVQdo6-lXVS5aOikQ9go9nrj-VX1CA,826
40
- followthemoney/schema/Passport.yaml,sha256=gKseZtdL1v7mFfpFhVjNtKe1RoZ9x_RYlmoh0qF5hsY,843
41
- followthemoney/schema/Payment.yaml,sha256=8DlWvaznzTVeTk84I-YkZQJklI8rd7kIbkQvmnoD7XY,1159
42
- followthemoney/schema/Person.yaml,sha256=AB0YK_E1m9sZk1e37RMAz0cnTOhMO_uzzQ9rjRxDFXI,1010
43
- followthemoney/schema/PublicBody.yaml,sha256=rKIlrGccItQev2w8mW7ZMMKwXdEFwDlLH-fJExoWxbU,118
44
- followthemoney/schema/RealEstate.yaml,sha256=3p8uNOkDLAbrztlKKxvb2qlN2mTLI3hxhq6fB-US5qw,968
45
- followthemoney/schema/Relationship.yaml,sha256=ERZNb8qr_MX_Wpp7fJPpIN_OkFGK2pAXSOSVWVQNI_Y,876
46
- followthemoney/schema/Representation.yaml,sha256=3FY-4m-XzyPmEYQIPnuGcjINnwkoZyRh0gm0mTvJsVo,607
47
- followthemoney/schema/Sanction.yaml,sha256=rB3sFqU4CGPW90vo0y5iVgtu5RCm-O_EVTTqQK1WBwU,778
48
- followthemoney/schema/TaxRoll.yaml,sha256=vzhX3_jguH3pdqM_jcJTVfXBMADyriyaRogZQDFtb5w,382
49
- followthemoney/schema/Thing.yaml,sha256=40QFFnuJrdBKoBkEE_K8cWRVsGB4cdd8zhvaiMd57Mg,1108
50
- followthemoney/schema/UnknownLink.yaml,sha256=b4RtZ17NCcZMfNa2V32x5wV2tr6wgUR8D0m399sxl2Y,516
51
- followthemoney/schema/Value.yaml,sha256=YuNrMqs6Ano7UZ6e8n19BC0_z5lw2zmOK-qA-7vjC94,233
52
- followthemoney/schema/Vehicle.yaml,sha256=YFbk1MFcgGcTCjWmT-REq2KiG5BHSxfaIccVZcmfoYA,674
53
- followthemoney/schema/Vessel.yaml,sha256=OTumM933Q1gMUwsf40WmPko0C1us0jrkPnjZrBZQlkI,940
54
- followthemoney/translations/messages.pot,sha256=wkhN0tyKWJIzZ7DgnFSZs07SNomhZbJFdt7la9ppowo,52102
55
- followthemoney/translations/ar/LC_MESSAGES/followthemoney.mo,sha256=zSycbQcxS6s9El3O5B82F-uzPEr6eNDUHVSnbVwiFC4,23023
56
- followthemoney/translations/ar/LC_MESSAGES/followthemoney.po,sha256=HnaFBYHE7YIVri3kPk_EOMz9CiwGf7uePl1FOgj4Io4,52697
57
- followthemoney/translations/bs/LC_MESSAGES/followthemoney.mo,sha256=dOsUqsUojlhHyHlhVeJ756fRAmsQo4AK2t77eAOhTJU,22946
58
- followthemoney/translations/bs/LC_MESSAGES/followthemoney.po,sha256=d6hbqeIJ9prrF3a0smu9XlvqbzRpgC94nAhBsCwjiEc,54818
59
- followthemoney/translations/de/LC_MESSAGES/followthemoney.mo,sha256=7WvA_T-loQyLDv7lLi61AM6T3W4MdJ-CgvIA8AFfOD8,22778
60
- followthemoney/translations/de/LC_MESSAGES/followthemoney.po,sha256=hR4VXvTcedFmvb4ZqIhmE4jInBhYHSDD1HrdFbS1xxk,52795
61
- followthemoney/translations/es/LC_MESSAGES/followthemoney.mo,sha256=tg4bKZ5WN8SfBkIB6D_Wi5_iZZcdxlvkEYkON-Sg5MY,23159
62
- followthemoney/translations/es/LC_MESSAGES/followthemoney.po,sha256=B8-d1qmQQXuxmqsVsN1aYUn6GuT3iXwbkA4Sx2UAD4I,53932
63
- followthemoney/translations/ru/LC_MESSAGES/followthemoney.mo,sha256=Oj-emYrJtA1qgrlCBlNH2Syl2_Yx_G7VLO1MrQ4p8WM,30688
64
- followthemoney/translations/ru/LC_MESSAGES/followthemoney.po,sha256=ZN0zjS-0Klqo0V4R2m8UI0xTbRm3TaO5Y5icyIY_y7I,67531
65
- followthemoney/translations/tr/LC_MESSAGES/followthemoney.mo,sha256=XuQiiJ2bkvbZX-wKZpPVXbR_FJZj9hB0G8dpK61ylQA,22723
66
- followthemoney/translations/tr/LC_MESSAGES/followthemoney.po,sha256=DETPMV21aIwnAKlqsm5nnU5pMWntCByg1uiuisq9K2A,52161
67
- followthemoney/types/__init__.py,sha256=Ise3QV1LUUjQwueS7GV7cz5S9km4Av8DlImbkigHPOs,1234
68
- followthemoney/types/address.py,sha256=OGsBuA-bU_4g4sJQ-ywWkKUJZKnMz8bK70OB5545ZrM,1048
69
- followthemoney/types/common.py,sha256=4Ao-ic7NPU4Jgb4hj2wWS2kz2wsiwzm_LLJ0w_efPlA,3772
70
- followthemoney/types/country.py,sha256=FpvdeGJj94DPk3Bj-zGgxC1r_k4vQG_uawmKQBJUPug,2053
71
- followthemoney/types/date.py,sha256=i50KcrCmo9S-BxoeNfecGMXA5YV86nsy-QPtbWptdpc,3250
72
- followthemoney/types/domain.py,sha256=a4L7X8cx_Vf_Ubh41cDuv3jOlR_XZ-wfwmyo2oUfrZU,1513
73
- followthemoney/types/email.py,sha256=RPSy_W3xH7fHXPmdypvWYlaj62xH578XCZJEQUSmA0E,1668
74
- followthemoney/types/entity.py,sha256=0qpnzmroWl-rLf-Fa-ThtgpcwXfcKNd2iJ8uyUJJPJM,491
75
- followthemoney/types/iban.py,sha256=wj9HEsNbyg-7eExZ3vchNSOchIwabjvo7lCTDm5WciU,954
76
- followthemoney/types/identifier.py,sha256=n9U8pfgM2-WAJGt05ffvGoOM9ERwHLmfH2Us2sMRKWQ,961
77
- followthemoney/types/ip.py,sha256=dBIq-OdYwyagGY-PRv-ll7Y1PRQtfMd-unaHI5IkHrM,897
78
- followthemoney/types/language.py,sha256=z6Jry00mRbpQrWgA9V1GVpX6v8fSAzIKDIfBw6CgxbE,974
79
- followthemoney/types/name.py,sha256=35wZFCLNDKBZcIoq_BBOvJM8EffDla0tN5Ou9Qo8iYM,649
80
- followthemoney/types/phone.py,sha256=kKqyABvImI8oOO-RR6Vi4_2XO0hbGrv3ooM1W5GnTIw,1898
81
- followthemoney/types/url.py,sha256=nS3wVJPKUEW_vXPJeZFS-PhmrpnZFpBS30dQ-9aNfmc,665
82
- followthemoney-1.3.7.dist-info/DESCRIPTION.rst,sha256=hh8qzEHyicPoOxY54ypPcyrKxKdHvblURpPENJzuhMY,57
83
- followthemoney-1.3.7.dist-info/LICENSE.txt,sha256=FKdfpdlHid0qSctUFUOfdL-DQTdbVcaOasZaq2eoFz8,1098
84
- followthemoney-1.3.7.dist-info/METADATA,sha256=o8Cx6e_svt3zBpx_f1CWKGPYDxtGT-EM2kQKJmGUFFE,1290
85
- followthemoney-1.3.7.dist-info/RECORD,,
86
- followthemoney-1.3.7.dist-info/WHEEL,sha256=8Lm45v9gcYRm70DrgFGVe4WsUtUMi1_0Tso1hqPGMjA,92
87
- followthemoney-1.3.7.dist-info/entry_points.txt,sha256=cVTk_xRDcaCzmhpRoIFzBtqad35hNuYEpkQrOtBa6cs,68
88
- followthemoney-1.3.7.dist-info/metadata.json,sha256=f_yRsvL-UQYzhaQHJwygUxCtcfhGe4nqacd9Jfp3nfg,1216
89
- followthemoney-1.3.7.dist-info/namespace_packages.txt,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
90
- followthemoney-1.3.7.dist-info/top_level.txt,sha256=-Pvehz2KyTTC0636TWtRHb4RT1_32DivEdqEGtUYOLA,24
91
- ns/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
92
- ns/ontology.py,sha256=3nVeQAS6lLtU3ZaFJ-CtpBfKBXcDlJQLhg2rOQlMLIo,4592
93
- tests/types/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
94
- tests/types/test_addresses.py,sha256=EveB50p3FTpBMoSLl8a_H2EigxPnlo8UqzHpEzoz1jc,769
95
- tests/types/test_common.py,sha256=k8uFcCKk4gef7TnfSPsniIEG6o2Aw3qyW2L0vQ9xecI,1090
96
- tests/types/test_countries.py,sha256=GUKMHBW9LBdMEOMXA7UMT1xJKoV5HKqsiRlGnFYlVvI,1060
97
- tests/types/test_dates.py,sha256=xR-vLX_1xvlDQ0pg78vX5Ho-HY6FrV13AwKPbjRLVzg,3197
98
- tests/types/test_domains.py,sha256=Wl44ipvuBqpny_TgTNkIJMUJwcnnPz5dDD6iIwYsUAc,803
99
- tests/types/test_emails.py,sha256=Hd0eaqDtfLDoIIe67dGMsTGG2SikkBOktDIJxzXfOzM,1282
100
- tests/types/test_entity.py,sha256=TG36OK2S45pMv1s5d9nzTjPiXi-hR2-W81nXmEOKgeU,572
101
- tests/types/test_iban.py,sha256=tODG9YDurVSm-AMytxalBUQJkfj-V-3t_OMk1t8XUGA,6292
102
- tests/types/test_identifiers.py,sha256=CMv0oALK3jvWmb6Vi_7Db86uQEqY7cVeR7fBdJ2PP9I,904
103
- tests/types/test_ip.py,sha256=mop6WP6r0nz-WWVA2XRGZGeP7gsuu6L7mJy6QloVxe8,1020
104
- tests/types/test_languages.py,sha256=g-F-3CGDexZ7OC3F3ox3NgwK2eeobXwkd8N9_GRaRE0,708
105
- tests/types/test_names.py,sha256=eGxNYDymUN3efbAKxwf1lsoB-k6krbLJXXHty_RLm5E,1175
106
- tests/types/test_phones.py,sha256=05LDu6iRNW9sSlws1OIzIYtwNuPu1_w_TemqmJtcb4I,873
107
- tests/types/test_registry.py,sha256=jhQ-Br9BZqDAwFplWdbMqTwovhfbGeHOmZljEH1zaow,394
108
- tests/types/test_urls.py,sha256=g6hPxau0FOwVq53PvoQbzUJat0Gjy7VMIdPk1iCPPic,822
@@ -1,3 +0,0 @@
1
- [babel.extractors]
2
- ftmmodel = followthemoney.messages:extract_yaml
3
-
@@ -1 +0,0 @@
1
- {"description_content_type": "UNKNOWN", "extensions": {"python.details": {"contacts": [{"email": "pudo@occrp.org", "name": "Organized Crime and Corruption Reporting Project", "role": "author"}], "document_names": {"description": "DESCRIPTION.rst", "license": "LICENSE.txt"}, "project_urls": {"Home": "https://occrp.org"}}, "python.exports": {"babel.extractors": {"ftmmodel": "followthemoney.messages:extract_yaml"}}}, "extras": ["dev"], "generator": "bdist_wheel (0.30.0)", "license": "MIT", "metadata_version": "2.0", "name": "followthemoney", "run_requires": [{"requires": ["babel", "banal (>=0.3.8)", "countrynames (>=1.6.0)", "languagecodes (>=1.0.4)", "normality (>=0.6.1)", "phonenumbers (>=8.9.11)", "python-levenshtein (>=0.12.0)", "pytz (>=2018.5)", "pyyaml", "rdflib (>=4.1)", "requests[security] (>=2.18.4)", "schwifty (>=2018.4.1)", "sqlalchemy (>=1.2.0)", "urlnormalizer (>=1.2.0)"]}, {"extra": "dev", "requires": ["bumpversion (>=0.5.3)", "coverage (>=4.1)", "flake8 (>=2.6.0)", "nose", "pip (>=10.0.0)", "recommonmark (>=0.4.0)", "responses (>=0.9.0)", "transifex-client", "twine", "wheel (>=0.29.0)"]}], "summary": "UNKNOWN", "test_requires": [{"requires": ["coverage", "nose"]}], "version": "1.3.7"}
@@ -1,3 +0,0 @@
1
- followthemoney
2
- ns
3
- tests
ns/ontology.py DELETED
@@ -1,128 +0,0 @@
1
- import sys
2
- import json
3
- from datetime import datetime
4
- from rdflib import Graph, Namespace, URIRef, Literal
5
- from rdflib.namespace import OWL, DCTERMS, RDF, RDFS, XSD
6
-
7
- from followthemoney import model, types
8
-
9
-
10
- class Ontology(object):
11
-
12
- def __init__(self, ns_uri):
13
-
14
- self.ns_uri = ns_uri
15
- self.uri = URIRef(ns_uri)
16
- self.ns = Namespace(ns_uri)
17
-
18
- self.graph = Graph(identifier=ns_uri)
19
- self.graph.namespace_manager.bind('ftm', self.ns)
20
- self.graph.namespace_manager.bind('owl', OWL)
21
- self.graph.namespace_manager.bind('dct', DCTERMS)
22
-
23
- self.graph.add((self.uri, RDF.type, OWL.Ontology))
24
- self.graph.add((self.uri, RDFS.label, Literal("Follow The Money")))
25
- self.graph.add((self.uri, RDFS.comment, Literal(
26
- "A vocabulary for investigative reporting, based on real life.")))
27
- self.graph.add((self.uri, DCTERMS.modified,
28
- Literal(datetime.now().strftime('%Y-%m-%dT%H:%I:%M'), datatype=XSD.dateTime)))
29
-
30
- self.add_schemata()
31
-
32
- def uri_for(self, thing):
33
- url = self.uri + thing.name # Not using urljoin for this because it loses fragments
34
- return URIRef(url)
35
-
36
- def property_range(self, prop):
37
- if prop.type == types.entities:
38
- return self.uri_for(model[prop.range])
39
- elif prop.type == types.dates:
40
- return XSD.dateTime
41
- return None
42
-
43
- def add_class(self, entity):
44
- entity_uri = self.uri_for(entity)
45
- self.graph.add((entity_uri, RDF.type, RDFS.Class))
46
- self.graph.add((entity_uri, RDFS.isDefinedBy, self.uri))
47
- for extends in entity.extends:
48
- self.graph.add((entity_uri, RDFS.subClassOf,
49
- self.uri_for(model[extends])))
50
-
51
- self.graph.add((entity_uri, RDFS.label, Literal(entity.label)))
52
- if entity.description is not None:
53
- self.graph.add((entity_uri, RDFS.comment,
54
- Literal(entity.description)))
55
-
56
- def add_property(self, entity, prop):
57
- prop_uri = self.uri_for(prop)
58
- self.graph.add((prop_uri, RDF.type, RDF.Property))
59
- self.graph.add((prop_uri, RDFS.isDefinedBy, self.uri))
60
-
61
- self.graph.add((prop_uri, RDFS.label, Literal(prop.label)))
62
- if prop.description is not None:
63
- self.graph.add((prop_uri, RDFS.comment, Literal(prop.description)))
64
-
65
- self.graph.add((prop_uri, RDFS.domain, self.uri_for(entity)))
66
- prop_range = self.property_range(prop)
67
- if prop_range is not None:
68
- self.graph.add((prop_uri, RDFS.range, prop_range))
69
-
70
- def add_schemata(self):
71
- for schema in model:
72
- self.add_class(schema)
73
- for prop in schema._own_properties:
74
- self.add_property(schema, prop)
75
-
76
- def serialize(self, format='n3'):
77
- return self.graph.serialize(format=format)
78
-
79
- def jsonld_context(self):
80
- context = {
81
- '@context': {
82
- 'xsd': 'http://www.w3.org/2001/XMLSchema#',
83
- 'ftm': self.ns_uri
84
- }
85
- }
86
-
87
- for s, p, o in self.graph.triples((None, None, None)):
88
- name = s.split(self.ns_uri)[1]
89
- if name != "":
90
- # id_types = ['entity', 'url', 'uri']
91
- # if model.property_types.get(name) in id_types:
92
- # context['@context'][name] = {
93
- # '@id': 'ftm:%s' % name,
94
- # '@type': '@id'
95
- # }
96
- # elif model.property_types.get(name) == 'date':
97
- # context['@context'][name] = {
98
- # '@id': 'ftm:%s' % name,
99
- # '@type': 'xsd:dateTime'
100
- # }
101
- # else:
102
- context['@context'][name] = 'ftm:%s' % name
103
-
104
- return context
105
-
106
- def write_namespace_docs(self, path):
107
- ttl_fn = '%s/ftm.ttl' % path
108
- with open(ttl_fn, 'w') as ttl_file:
109
- ttl = self.serialize()
110
- ttl_file.write(ttl.decode('utf-8'))
111
-
112
- xml_fn = '%s/ftm.xml' % path
113
- with open(xml_fn, 'w') as xml_file:
114
- xml = self.serialize('xml')
115
- xml_file.write(xml.decode('utf-8'))
116
-
117
- json_fn = '%s/ftm.jsonld' % path
118
- with open(json_fn, 'w') as json_file:
119
- json_file.write(json.dumps(
120
- self.jsonld_context(), indent=4, sort_keys=True))
121
-
122
-
123
- if __name__ == '__main__':
124
- uri = sys.argv[1]
125
- path = sys.argv[2]
126
- o = Ontology(uri)
127
- o.write_namespace_docs(path)
128
- print("Namespace docs written to %s" % path)
@@ -1,24 +0,0 @@
1
- import unittest
2
-
3
- from followthemoney.types import addresses
4
-
5
- UK = """43 Duke Street
6
- Edinburgh
7
- EH6 8HH"""
8
-
9
-
10
- class AddressesTest(unittest.TestCase):
11
-
12
- def test_clean(self):
13
- self.assertEqual(addresses.clean(UK),
14
- '43 Duke Street, Edinburgh, EH6 8HH')
15
- self.assertEqual(addresses.clean('huhu\n haha'), 'huhu, haha')
16
- self.assertEqual(addresses.clean('huhu,\n haha'), 'huhu, haha')
17
-
18
- def test_normalize(self):
19
- self.assertEqual(addresses.normalize(UK), ['43 Duke Street, Edinburgh, EH6 8HH']) # noqa
20
- self.assertEqual(addresses.normalize('\n '), [])
21
-
22
- def test_specificity(self):
23
- self.assertGreater(addresses.specificity(UK), 0.2)
24
- self.assertLess(addresses.specificity('London'), 0.2)
@@ -1,32 +0,0 @@
1
- import unittest
2
-
3
- from followthemoney.types import registry
4
-
5
-
6
- class CommonTest(unittest.TestCase):
7
-
8
- def test_normalise_set(self):
9
- t = registry.name
10
- self.assertEqual(t.normalize_set(None), [])
11
- self.assertEqual(t.normalize_set('boban'), ['boban'])
12
- self.assertEqual(t.normalize_set(['boban']), ['boban'])
13
-
14
- def test_ref(self):
15
- t = registry.name
16
- self.assertEqual(t.ref(''), None)
17
- self.assertEqual(t.ref({'id': 'banana'}), 'n:banana')
18
- self.assertEqual(t.ref('banana'), 'n:banana')
19
- nt, v = registry.deref('n:banana')
20
- self.assertEqual(v, 'banana')
21
- self.assertEqual(t, nt)
22
-
23
- def test_funcs(self):
24
- t = registry.name
25
- self.assertEqual(t.country_hint('banana'), None)
26
- self.assertEqual(str(t), 'name')
27
- self.assertEqual(hash(t), hash('name'))
28
-
29
- self.assertGreater(t.compare_sets(['banana'], ['banana']), 0)
30
- self.assertEqual(t.compare_sets(['banana'], []), 0)
31
- self.assertIsNotNone(t.ref('banana'))
32
- self.assertIsNone(registry.text.ref('banana'))
@@ -1,27 +0,0 @@
1
- import unittest
2
-
3
- from followthemoney.types import countries
4
-
5
-
6
- class CountriesTest(unittest.TestCase):
7
-
8
- def test_country_codes(self):
9
- self.assertEqual(countries.clean('DE'), 'de')
10
- self.assertTrue(countries.validate('DE'))
11
- self.assertFalse(countries.validate('DEU'))
12
- self.assertFalse(countries.validate(''))
13
- self.assertFalse(countries.validate(None))
14
- self.assertFalse(countries.validate(4))
15
- self.assertFalse(countries.validate('SU'))
16
- self.assertTrue(countries.validate('XK'))
17
- self.assertTrue(countries.validate('EU'))
18
-
19
- self.assertEqual(countries.country_hint('eu'), 'eu')
20
- assert 'iso-3166-1:eu' in countries.rdf('eu')
21
-
22
- def test_country_names(self):
23
- self.assertEqual(countries.clean(None), None)
24
- self.assertEqual(countries.clean('Takatukaland', guess=False), None)
25
- self.assertEqual(countries.clean('Germany'), 'de')
26
- # self.assertEqual(countries.clean('Germani'), 'de')
27
- self.assertEqual(countries.clean('Soviet Union'), 'suhh')
tests/types/test_dates.py DELETED
@@ -1,73 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- import unittest
3
- from datetime import datetime
4
-
5
- from followthemoney.types import dates
6
-
7
-
8
- class DatesTest(unittest.TestCase):
9
-
10
- def test_validate(self):
11
- self.assertTrue(dates.validate('2017-04-04T10:30:29'))
12
- self.assertTrue(dates.validate('2017-04-04T10:30:29Z'))
13
- self.assertTrue(dates.validate('2017-04-04T10:30:29+01'))
14
- self.assertTrue(dates.validate('2017-04-04T10:30:29+0200'))
15
- self.assertTrue(dates.validate('2017-04-04T10:30:29+03:00'))
16
- self.assertTrue(dates.validate('2017-04-04T10:30:29-04:00'))
17
- self.assertTrue(dates.validate(datetime.utcnow().isoformat()))
18
- self.assertFalse(dates.validate('01-02-2003'))
19
- self.assertFalse(dates.validate('Thursday 21 March 2017'))
20
-
21
- def test_is_partial_date(self):
22
- self.assertTrue(dates.validate('2017-04-04 10:30:29'))
23
- self.assertTrue(dates.validate('2017-04-04 10:30'))
24
- self.assertTrue(dates.validate('2017-04-04 10'))
25
- self.assertTrue(dates.validate('2017-04-04'))
26
- self.assertTrue(dates.validate('2017-4-4'))
27
- self.assertTrue(dates.validate('2017-4'))
28
- self.assertTrue(dates.validate('2017'))
29
- self.assertFalse(dates.validate('0017'))
30
- self.assertFalse(dates.validate(None))
31
- self.assertFalse(dates.validate(5))
32
- self.assertFalse(dates.validate('2017-20-01'))
33
-
34
- def test_chop_dates(self):
35
- self.assertEquals(dates.clean('2017-00-00'), '2017')
36
- self.assertEquals(dates.clean('2017-00-00T00:00:00'), '2017')
37
- self.assertEquals(dates.clean('2017-00-00T12:03:49'), '2017')
38
- self.assertEquals(dates.clean('2017-01-01T00:00:00'), '2017-01-01')
39
-
40
- def test_patch_dates(self):
41
- self.assertEquals(dates.clean('2017-1-3'), '2017-01-03')
42
- self.assertEquals(dates.clean('2017-3'), '2017-03')
43
- self.assertEquals(dates.clean('2017-0'), '2017')
44
- self.assertEquals(dates.clean('2017-5-2T00:00:00'), '2017-05-02')
45
- self.assertEquals(dates.clean('2017-5-2T10:00:00'), '2017-05-02T10:00:00') # noqa
46
-
47
- def test_convert_datetime(self):
48
- dt = datetime.utcnow()
49
- iso, _ = dt.isoformat().split('.', 1)
50
- self.assertEquals(dates.clean(dt), iso)
51
- self.assertTrue(dates.validate(iso))
52
-
53
- dt = datetime.utcnow().date()
54
- iso = dt.isoformat()
55
- self.assertEquals(dates.clean(dt), iso)
56
-
57
- def test_parse_date(self):
58
- self.assertEquals(dates.clean(None), None)
59
- self.assertEquals(dates.clean(''), None)
60
- self.assertEquals(dates.clean('banana'), None)
61
- self.assertEquals(dates.clean('2017-04-04'), '2017-04-04')
62
- self.assertEquals(dates.clean('2017-4-4'), '2017-04-04')
63
-
64
- self.assertEquals(dates.clean('4/2017', format="%m/%Y"), '2017-04')
65
- self.assertEquals(dates.clean('4/2017', format="4/%Y"), '2017')
66
- self.assertEquals(dates.clean('4/2xx017', format="%m/%Y"), None)
67
-
68
- def test_specificity(self):
69
- self.assertEqual(dates.specificity('2011'), 0)
70
- self.assertGreater(dates.specificity('2011-01-01'), 0.1)
71
-
72
- def test_compare(self):
73
- self.assertGreater(dates.compare('2011-01-01', '2011-01-01'), 0.9)
@@ -1,23 +0,0 @@
1
- import unittest
2
-
3
- from followthemoney.types import domains
4
-
5
-
6
- class DomainsTest(unittest.TestCase):
7
-
8
- def test_parse(self):
9
- self.assertEqual(domains.clean('pudo.org'), 'pudo.org')
10
- self.assertEqual(domains.clean('pudoorg'), None)
11
- self.assertEqual(domains.clean(None), None)
12
- self.assertEqual(domains.clean('x.a'), None)
13
-
14
- def test_normalize(self):
15
- self.assertEqual(domains.normalize('PUDO'), [])
16
- self.assertEqual(domains.normalize('PUDO.org'), ['pudo.org'])
17
-
18
- def test_domain_validity(self):
19
- self.assertTrue(domains.validate('pudo.org'))
20
- self.assertFalse(domains.validate('pudo'))
21
- self.assertFalse(domains.validate('x.a'))
22
- self.assertFalse(domains.validate(''))
23
- self.assertFalse(domains.validate('@pudo.org'))
@@ -1,32 +0,0 @@
1
- import unittest
2
-
3
- from followthemoney.types import emails
4
-
5
-
6
- class EmailsTest(unittest.TestCase):
7
-
8
- def test_parse(self):
9
- self.assertEqual(emails.clean('foo@pudo.org'), 'foo@pudo.org')
10
- self.assertEqual(emails.clean('"foo@pudo.org"'), 'foo@pudo.org')
11
- self.assertEqual(emails.clean('pudo.org'), None)
12
- self.assertEqual(emails.clean('foo@'), None)
13
- self.assertEqual(emails.clean(None), None)
14
- self.assertEqual(emails.clean(5), None)
15
- self.assertEqual(emails.clean('foo@PUDO.org'), 'foo@pudo.org')
16
- self.assertEqual(emails.clean('FOO@PUDO.org'), 'FOO@pudo.org')
17
-
18
- def test_normalize(self):
19
- self.assertEqual(emails.normalize(None), [])
20
- self.assertEqual(emails.normalize('FOO@PUDO'), [])
21
- self.assertEqual(emails.normalize('FOO@PUDO.org'), ['foo@pudo.org'])
22
-
23
- def test_domain_validity(self):
24
- self.assertTrue(emails.validate('foo@pudo.org'))
25
- self.assertFalse(emails.validate('foo@pudo'))
26
- self.assertFalse(emails.validate(None))
27
- self.assertFalse(emails.validate(''))
28
- self.assertFalse(emails.validate('@pudo.org'))
29
- self.assertFalse(emails.validate('foo@'))
30
-
31
- def test_specificity(self):
32
- self.assertEqual(emails.specificity('foo@pudo.org'), 1)
@@ -1,19 +0,0 @@
1
- import unittest
2
-
3
- from followthemoney.types import entities
4
-
5
-
6
- class EntityTest(unittest.TestCase):
7
-
8
- def test_parse(self):
9
- self.assertEqual(entities.clean('88'), '88')
10
- self.assertEqual(entities.clean(88), '88')
11
- self.assertEqual(entities.clean({'id': 88}), '88')
12
- self.assertEqual(entities.clean(None), None)
13
-
14
- def test_normalize(self):
15
- self.assertEqual(entities.normalize('FOO'), ['FOO'])
16
- self.assertEqual(entities.normalize(None), [])
17
-
18
- def test_funcs(self):
19
- self.assertEqual(entities.specificity('bla'), 1)
tests/types/test_iban.py DELETED
@@ -1,109 +0,0 @@
1
- import unittest
2
-
3
- from followthemoney.types import ibans
4
-
5
-
6
- class IbansTest(unittest.TestCase):
7
-
8
- def test_parse(self):
9
- self.assertEqual(ibans.clean('GB29 NWBK 6016 1331 9268 19'),
10
- 'GB29NWBK60161331926819')
11
-
12
- def test_domain_validity(self):
13
- self.assertTrue(ibans.validate('GB29 NWBK 6016 1331 9268 19'))
14
- self.assertTrue(ibans.validate('GB29NWBK60161331926819'))
15
- self.assertFalse(ibans.validate('GB28 NWBK 6016 1331 9268 19'))
16
- self.assertFalse(ibans.validate('GB29NWBKN0161331926819'))
17
- self.assertFalse(ibans.validate(None))
18
- self.assertTrue(ibans.validate('AL35202111090000000001234567'))
19
- self.assertTrue(ibans.validate('AD1400080001001234567890'))
20
- self.assertTrue(ibans.validate('AT483200000012345864'))
21
- self.assertTrue(ibans.validate('AZ96AZEJ00000000001234567890'))
22
- self.assertTrue(ibans.validate('BH02CITI00001077181611'))
23
- # self.assertTrue(ibans.validate('BY86AKBB10100000002966000000'))
24
- self.assertTrue(ibans.validate('BE71096123456769'))
25
- self.assertTrue(ibans.validate('BA275680000123456789'))
26
- self.assertTrue(ibans.validate('BR1500000000000010932840814P2'))
27
- self.assertTrue(ibans.validate('BG18RZBB91550123456789'))
28
- # self.assertTrue(ibans.validate('CR37012600000123456789'))
29
- self.assertTrue(ibans.validate('HR1723600001101234565'))
30
- self.assertTrue(ibans.validate('CY21002001950000357001234567'))
31
- self.assertTrue(ibans.validate('CZ5508000000001234567899'))
32
- self.assertTrue(ibans.validate('DK9520000123456789'))
33
- self.assertTrue(ibans.validate('DO22ACAU00000000000123456789'))
34
- # self.assertTrue(ibans.validate('SV43ACAT00000000000000123123'))
35
- self.assertTrue(ibans.validate('EE471000001020145685'))
36
- self.assertTrue(ibans.validate('FO9264600123456789'))
37
- self.assertTrue(ibans.validate('FI1410093000123458'))
38
- self.assertTrue(ibans.validate('FR7630006000011234567890189'))
39
- self.assertTrue(ibans.validate('GE60NB0000000123456789'))
40
- self.assertTrue(ibans.validate('DE91100000000123456789'))
41
- self.assertTrue(ibans.validate('GI04BARC000001234567890'))
42
- self.assertTrue(ibans.validate('GR9608100010000001234567890'))
43
- self.assertTrue(ibans.validate('GL8964710123456789'))
44
- self.assertTrue(ibans.validate('GT20AGRO00000000001234567890'))
45
- self.assertTrue(ibans.validate('HU93116000060000000012345676'))
46
- self.assertTrue(ibans.validate('IS030001121234561234567890'))
47
- # self.assertTrue(ibans.validate('IQ20CBIQ861800101010500'))
48
- self.assertTrue(ibans.validate('IE64IRCE92050112345678'))
49
- self.assertTrue(ibans.validate('IL170108000000012612345'))
50
- self.assertTrue(ibans.validate('IT60X0542811101000000123456'))
51
- self.assertTrue(ibans.validate('JO71CBJO0000000000001234567890'))
52
- self.assertTrue(ibans.validate('KZ563190000012344567'))
53
- self.assertTrue(ibans.validate('XK051212012345678906'))
54
- self.assertTrue(ibans.validate('KW81CBKU0000000000001234560101'))
55
- self.assertTrue(ibans.validate('LV97HABA0012345678910'))
56
- self.assertTrue(ibans.validate('LB92000700000000123123456123'))
57
- self.assertTrue(ibans.validate('LI7408806123456789012'))
58
- self.assertTrue(ibans.validate('LT601010012345678901'))
59
- self.assertTrue(ibans.validate('LU120010001234567891'))
60
- self.assertTrue(ibans.validate('MK07200002785123453'))
61
- self.assertTrue(ibans.validate('MT31MALT01100000000000000000123'))
62
- self.assertTrue(ibans.validate('MR1300020001010000123456753'))
63
- self.assertTrue(ibans.validate('MU43BOMM0101123456789101000MUR'))
64
- self.assertTrue(ibans.validate('MD21EX000000000001234567'))
65
- self.assertTrue(ibans.validate('MC5810096180790123456789085'))
66
- self.assertTrue(ibans.validate('ME25505000012345678951'))
67
- self.assertTrue(ibans.validate('NL02ABNA0123456789'))
68
- self.assertTrue(ibans.validate('NO8330001234567'))
69
- self.assertTrue(ibans.validate('PK36SCBL0000001123456702'))
70
- self.assertTrue(ibans.validate('PS92PALS000000000400123456702'))
71
- self.assertTrue(ibans.validate('PL10105000997603123456789123'))
72
- self.assertTrue(ibans.validate('PT50002700000001234567833'))
73
- self.assertTrue(ibans.validate('QA54QNBA000000000000693123456'))
74
- self.assertTrue(ibans.validate('RO09BCYP0000001234567890'))
75
- self.assertTrue(ibans.validate('LC14BOSL123456789012345678901234'))
76
- self.assertTrue(ibans.validate('SM76P0854009812123456789123'))
77
- self.assertTrue(ibans.validate('ST23000200000289355710148'))
78
- self.assertTrue(ibans.validate('SA4420000001234567891234'))
79
- self.assertTrue(ibans.validate('RS35105008123123123173'))
80
- self.assertTrue(ibans.validate('SC52BAHL01031234567890123456USD'))
81
- self.assertTrue(ibans.validate('SK8975000000000012345671'))
82
- self.assertTrue(ibans.validate('SI56192001234567892'))
83
- self.assertTrue(ibans.validate('ES7921000813610123456789'))
84
- self.assertTrue(ibans.validate('SE1412345678901234567890'))
85
- self.assertTrue(ibans.validate('CH5604835012345678009'))
86
- self.assertTrue(ibans.validate('TL380080012345678910157'))
87
- self.assertTrue(ibans.validate('TN4401000067123456789123'))
88
- self.assertTrue(ibans.validate('TR320010009999901234567890'))
89
- self.assertTrue(ibans.validate('UA903052992990004149123456789'))
90
- self.assertTrue(ibans.validate('AE460090000000123456789'))
91
- self.assertTrue(ibans.validate('GB98MIDL07009312345678'))
92
- self.assertTrue(ibans.validate('VG21PACG0000000123456789'))
93
-
94
- def test_specificity(self):
95
- self.assertEqual(ibans.specificity('VG21PACG0000000123456789'), 1)
96
-
97
- def test_country(self):
98
- iban = 'AE460090000000123456789'
99
- assert 'ae' == ibans.country_hint(iban)
100
- assert ibans.country_hint('') is None
101
-
102
- def test_compare(self):
103
- iban = 'AE460090000000123456789'
104
- comp = ibans.compare_safe(iban, iban)
105
- assert comp == 1, comp
106
- comp = ibans.compare_safe(iban, iban + 'X')
107
- assert comp == 0, comp
108
- comp = ibans.compare_safe(iban, None)
109
- assert comp == 0, comp
@@ -1,27 +0,0 @@
1
- import unittest
2
-
3
- from followthemoney.types import identifiers
4
-
5
-
6
- class IdentifiersTest(unittest.TestCase):
7
-
8
- def test_parse(self):
9
- self.assertEqual(identifiers.clean('88/9'), '88/9')
10
-
11
- def test_normalize(self):
12
- self.assertEqual(identifiers.normalize('FOO'), ['foo'])
13
- self.assertEqual(identifiers.normalize('xx '), ['xx'])
14
- self.assertEqual(identifiers.normalize(' '), [])
15
-
16
- def test_domain_validity(self):
17
- self.assertTrue(identifiers.validate('foo@pudo.org'))
18
-
19
- def test_compare(self):
20
- comp = identifiers.compare('AS98187', '98187')
21
- assert comp == 0.7, comp
22
- comp = identifiers.compare_safe(None, '98187')
23
- assert comp == 0, comp
24
- comp = identifiers.compare_sets(['AS98187'], ['98187'])
25
- assert comp == 0.7, comp
26
- comp = identifiers.compare_sets(['98187'], ['AS98187'])
27
- assert comp == 0.7, comp