udata 9.1.2.dev30355__py2.py3-none-any.whl → 9.1.2.dev30382__py2.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 udata might be problematic. Click here for more details.

Files changed (425) hide show
  1. tasks/__init__.py +109 -107
  2. tasks/helpers.py +18 -18
  3. udata/__init__.py +4 -4
  4. udata/admin/views.py +5 -5
  5. udata/api/__init__.py +135 -124
  6. udata/api/commands.py +45 -37
  7. udata/api/errors.py +5 -4
  8. udata/api/fields.py +23 -21
  9. udata/api/oauth2.py +55 -74
  10. udata/api/parsers.py +15 -15
  11. udata/api/signals.py +1 -1
  12. udata/api_fields.py +137 -89
  13. udata/app.py +56 -54
  14. udata/assets.py +5 -5
  15. udata/auth/__init__.py +37 -26
  16. udata/auth/forms.py +23 -15
  17. udata/auth/helpers.py +1 -1
  18. udata/auth/mails.py +3 -3
  19. udata/auth/password_validation.py +19 -15
  20. udata/auth/views.py +94 -68
  21. udata/commands/__init__.py +71 -69
  22. udata/commands/cache.py +7 -7
  23. udata/commands/db.py +201 -140
  24. udata/commands/dcat.py +36 -30
  25. udata/commands/fixtures.py +100 -84
  26. udata/commands/images.py +21 -20
  27. udata/commands/info.py +17 -20
  28. udata/commands/init.py +10 -10
  29. udata/commands/purge.py +12 -13
  30. udata/commands/serve.py +41 -29
  31. udata/commands/static.py +16 -18
  32. udata/commands/test.py +20 -20
  33. udata/commands/tests/fixtures.py +26 -24
  34. udata/commands/worker.py +31 -33
  35. udata/core/__init__.py +12 -12
  36. udata/core/activity/__init__.py +0 -1
  37. udata/core/activity/api.py +59 -49
  38. udata/core/activity/models.py +28 -26
  39. udata/core/activity/signals.py +1 -1
  40. udata/core/activity/tasks.py +16 -10
  41. udata/core/badges/api.py +6 -6
  42. udata/core/badges/commands.py +14 -13
  43. udata/core/badges/fields.py +8 -5
  44. udata/core/badges/forms.py +7 -4
  45. udata/core/badges/models.py +16 -31
  46. udata/core/badges/permissions.py +1 -3
  47. udata/core/badges/signals.py +2 -2
  48. udata/core/badges/tasks.py +3 -2
  49. udata/core/badges/tests/test_commands.py +10 -10
  50. udata/core/badges/tests/test_model.py +24 -31
  51. udata/core/contact_point/api.py +19 -18
  52. udata/core/contact_point/api_fields.py +21 -14
  53. udata/core/contact_point/factories.py +2 -2
  54. udata/core/contact_point/forms.py +7 -6
  55. udata/core/contact_point/models.py +3 -5
  56. udata/core/dataservices/api.py +26 -21
  57. udata/core/dataservices/factories.py +13 -11
  58. udata/core/dataservices/models.py +35 -40
  59. udata/core/dataservices/permissions.py +4 -4
  60. udata/core/dataservices/rdf.py +40 -17
  61. udata/core/dataservices/tasks.py +4 -3
  62. udata/core/dataset/actions.py +10 -10
  63. udata/core/dataset/activities.py +21 -23
  64. udata/core/dataset/api.py +321 -298
  65. udata/core/dataset/api_fields.py +443 -271
  66. udata/core/dataset/apiv2.py +305 -229
  67. udata/core/dataset/commands.py +38 -36
  68. udata/core/dataset/constants.py +61 -54
  69. udata/core/dataset/csv.py +70 -74
  70. udata/core/dataset/events.py +39 -32
  71. udata/core/dataset/exceptions.py +8 -4
  72. udata/core/dataset/factories.py +57 -65
  73. udata/core/dataset/forms.py +87 -63
  74. udata/core/dataset/models.py +336 -280
  75. udata/core/dataset/permissions.py +9 -6
  76. udata/core/dataset/preview.py +15 -17
  77. udata/core/dataset/rdf.py +156 -122
  78. udata/core/dataset/search.py +92 -77
  79. udata/core/dataset/signals.py +1 -1
  80. udata/core/dataset/tasks.py +63 -54
  81. udata/core/discussions/actions.py +5 -5
  82. udata/core/discussions/api.py +124 -120
  83. udata/core/discussions/factories.py +2 -2
  84. udata/core/discussions/forms.py +9 -7
  85. udata/core/discussions/metrics.py +1 -3
  86. udata/core/discussions/models.py +25 -24
  87. udata/core/discussions/notifications.py +18 -14
  88. udata/core/discussions/permissions.py +3 -3
  89. udata/core/discussions/signals.py +4 -4
  90. udata/core/discussions/tasks.py +24 -28
  91. udata/core/followers/api.py +32 -33
  92. udata/core/followers/models.py +9 -9
  93. udata/core/followers/signals.py +3 -3
  94. udata/core/jobs/actions.py +7 -7
  95. udata/core/jobs/api.py +99 -92
  96. udata/core/jobs/commands.py +48 -49
  97. udata/core/jobs/forms.py +11 -11
  98. udata/core/jobs/models.py +6 -6
  99. udata/core/metrics/__init__.py +2 -2
  100. udata/core/metrics/commands.py +34 -30
  101. udata/core/metrics/models.py +2 -4
  102. udata/core/metrics/signals.py +1 -1
  103. udata/core/metrics/tasks.py +3 -3
  104. udata/core/organization/activities.py +12 -15
  105. udata/core/organization/api.py +167 -174
  106. udata/core/organization/api_fields.py +183 -124
  107. udata/core/organization/apiv2.py +32 -32
  108. udata/core/organization/commands.py +20 -22
  109. udata/core/organization/constants.py +11 -11
  110. udata/core/organization/csv.py +17 -15
  111. udata/core/organization/factories.py +8 -11
  112. udata/core/organization/forms.py +32 -26
  113. udata/core/organization/metrics.py +2 -1
  114. udata/core/organization/models.py +87 -67
  115. udata/core/organization/notifications.py +18 -14
  116. udata/core/organization/permissions.py +10 -11
  117. udata/core/organization/rdf.py +14 -14
  118. udata/core/organization/search.py +30 -28
  119. udata/core/organization/signals.py +7 -7
  120. udata/core/organization/tasks.py +42 -61
  121. udata/core/owned.py +38 -27
  122. udata/core/post/api.py +82 -81
  123. udata/core/post/constants.py +8 -5
  124. udata/core/post/factories.py +4 -4
  125. udata/core/post/forms.py +13 -14
  126. udata/core/post/models.py +20 -22
  127. udata/core/post/tests/test_api.py +30 -32
  128. udata/core/reports/api.py +8 -7
  129. udata/core/reports/constants.py +1 -3
  130. udata/core/reports/models.py +10 -10
  131. udata/core/reuse/activities.py +15 -19
  132. udata/core/reuse/api.py +123 -126
  133. udata/core/reuse/api_fields.py +120 -85
  134. udata/core/reuse/apiv2.py +11 -10
  135. udata/core/reuse/constants.py +23 -23
  136. udata/core/reuse/csv.py +18 -18
  137. udata/core/reuse/factories.py +5 -9
  138. udata/core/reuse/forms.py +24 -21
  139. udata/core/reuse/models.py +55 -51
  140. udata/core/reuse/permissions.py +2 -2
  141. udata/core/reuse/search.py +49 -46
  142. udata/core/reuse/signals.py +1 -1
  143. udata/core/reuse/tasks.py +4 -5
  144. udata/core/site/api.py +47 -50
  145. udata/core/site/factories.py +2 -2
  146. udata/core/site/forms.py +4 -5
  147. udata/core/site/models.py +94 -63
  148. udata/core/site/rdf.py +14 -14
  149. udata/core/spam/api.py +16 -9
  150. udata/core/spam/constants.py +4 -4
  151. udata/core/spam/fields.py +13 -7
  152. udata/core/spam/models.py +27 -20
  153. udata/core/spam/signals.py +1 -1
  154. udata/core/spam/tests/test_spam.py +6 -5
  155. udata/core/spatial/api.py +72 -80
  156. udata/core/spatial/api_fields.py +73 -58
  157. udata/core/spatial/commands.py +67 -64
  158. udata/core/spatial/constants.py +3 -3
  159. udata/core/spatial/factories.py +37 -54
  160. udata/core/spatial/forms.py +27 -26
  161. udata/core/spatial/geoids.py +17 -17
  162. udata/core/spatial/models.py +43 -47
  163. udata/core/spatial/tasks.py +2 -1
  164. udata/core/spatial/tests/test_api.py +115 -130
  165. udata/core/spatial/tests/test_fields.py +74 -77
  166. udata/core/spatial/tests/test_geoid.py +22 -22
  167. udata/core/spatial/tests/test_models.py +5 -7
  168. udata/core/spatial/translations.py +16 -16
  169. udata/core/storages/__init__.py +16 -18
  170. udata/core/storages/api.py +66 -64
  171. udata/core/storages/tasks.py +7 -7
  172. udata/core/storages/utils.py +15 -15
  173. udata/core/storages/views.py +5 -6
  174. udata/core/tags/api.py +17 -14
  175. udata/core/tags/csv.py +4 -4
  176. udata/core/tags/models.py +8 -5
  177. udata/core/tags/tasks.py +11 -13
  178. udata/core/tags/views.py +4 -4
  179. udata/core/topic/api.py +84 -73
  180. udata/core/topic/apiv2.py +157 -127
  181. udata/core/topic/factories.py +3 -4
  182. udata/core/topic/forms.py +12 -14
  183. udata/core/topic/models.py +14 -19
  184. udata/core/topic/parsers.py +26 -26
  185. udata/core/user/activities.py +30 -29
  186. udata/core/user/api.py +151 -152
  187. udata/core/user/api_fields.py +132 -100
  188. udata/core/user/apiv2.py +7 -7
  189. udata/core/user/commands.py +38 -38
  190. udata/core/user/factories.py +8 -9
  191. udata/core/user/forms.py +14 -11
  192. udata/core/user/metrics.py +2 -2
  193. udata/core/user/models.py +68 -69
  194. udata/core/user/permissions.py +4 -5
  195. udata/core/user/rdf.py +7 -8
  196. udata/core/user/tasks.py +2 -2
  197. udata/core/user/tests/test_user_model.py +24 -16
  198. udata/db/tasks.py +2 -1
  199. udata/entrypoints.py +35 -31
  200. udata/errors.py +2 -1
  201. udata/event/values.py +6 -6
  202. udata/factories.py +2 -2
  203. udata/features/identicon/api.py +5 -6
  204. udata/features/identicon/backends.py +48 -55
  205. udata/features/identicon/tests/test_backends.py +4 -5
  206. udata/features/notifications/__init__.py +0 -1
  207. udata/features/notifications/actions.py +9 -9
  208. udata/features/notifications/api.py +17 -13
  209. udata/features/territories/__init__.py +12 -10
  210. udata/features/territories/api.py +14 -15
  211. udata/features/territories/models.py +23 -28
  212. udata/features/transfer/actions.py +8 -11
  213. udata/features/transfer/api.py +84 -77
  214. udata/features/transfer/factories.py +2 -1
  215. udata/features/transfer/models.py +11 -12
  216. udata/features/transfer/notifications.py +19 -15
  217. udata/features/transfer/permissions.py +5 -5
  218. udata/forms/__init__.py +5 -2
  219. udata/forms/fields.py +164 -172
  220. udata/forms/validators.py +19 -22
  221. udata/forms/widgets.py +9 -13
  222. udata/frontend/__init__.py +31 -26
  223. udata/frontend/csv.py +68 -58
  224. udata/frontend/markdown.py +40 -44
  225. udata/harvest/actions.py +89 -77
  226. udata/harvest/api.py +294 -238
  227. udata/harvest/backends/__init__.py +4 -4
  228. udata/harvest/backends/base.py +128 -111
  229. udata/harvest/backends/dcat.py +80 -66
  230. udata/harvest/commands.py +56 -60
  231. udata/harvest/csv.py +8 -8
  232. udata/harvest/exceptions.py +6 -3
  233. udata/harvest/filters.py +24 -23
  234. udata/harvest/forms.py +27 -28
  235. udata/harvest/models.py +88 -80
  236. udata/harvest/notifications.py +15 -10
  237. udata/harvest/signals.py +13 -13
  238. udata/harvest/tasks.py +11 -10
  239. udata/harvest/tests/factories.py +23 -24
  240. udata/harvest/tests/test_actions.py +136 -166
  241. udata/harvest/tests/test_api.py +220 -214
  242. udata/harvest/tests/test_base_backend.py +117 -112
  243. udata/harvest/tests/test_dcat_backend.py +380 -308
  244. udata/harvest/tests/test_filters.py +33 -22
  245. udata/harvest/tests/test_models.py +11 -14
  246. udata/harvest/tests/test_notifications.py +6 -7
  247. udata/harvest/tests/test_tasks.py +7 -6
  248. udata/i18n.py +237 -78
  249. udata/linkchecker/backends.py +5 -11
  250. udata/linkchecker/checker.py +23 -22
  251. udata/linkchecker/commands.py +4 -6
  252. udata/linkchecker/models.py +6 -6
  253. udata/linkchecker/tasks.py +18 -20
  254. udata/mail.py +21 -21
  255. udata/migrations/2020-07-24-remove-s-from-scope-oauth.py +9 -8
  256. udata/migrations/2020-08-24-add-fs-filename.py +9 -8
  257. udata/migrations/2020-09-28-update-reuses-datasets-metrics.py +5 -4
  258. udata/migrations/2020-10-16-migrate-ods-resources.py +9 -10
  259. udata/migrations/2021-04-08-update-schema-with-new-structure.py +8 -7
  260. udata/migrations/2021-05-27-fix-default-schema-name.py +7 -6
  261. udata/migrations/2021-07-05-remove-unused-badges.py +17 -15
  262. udata/migrations/2021-07-07-update-schema-for-community-resources.py +7 -6
  263. udata/migrations/2021-08-17-follow-integrity.py +5 -4
  264. udata/migrations/2021-08-17-harvest-integrity.py +13 -12
  265. udata/migrations/2021-08-17-oauth2client-integrity.py +5 -4
  266. udata/migrations/2021-08-17-transfer-integrity.py +5 -4
  267. udata/migrations/2021-08-17-users-integrity.py +9 -8
  268. udata/migrations/2021-12-14-reuse-topics.py +7 -6
  269. udata/migrations/2022-04-21-improve-extension-detection.py +8 -7
  270. udata/migrations/2022-09-22-clean-inactive-harvest-datasets.py +16 -14
  271. udata/migrations/2022-10-10-add-fs_uniquifier-to-user-model.py +6 -6
  272. udata/migrations/2022-10-10-migrate-harvest-extras.py +36 -26
  273. udata/migrations/2023-02-08-rename-internal-dates.py +46 -28
  274. udata/migrations/2024-01-29-fix-reuse-and-dataset-with-private-None.py +10 -8
  275. udata/migrations/2024-03-22-migrate-activity-kwargs-to-extras.py +6 -4
  276. udata/migrations/2024-06-11-fix-reuse-datasets-references.py +7 -6
  277. udata/migrations/__init__.py +123 -105
  278. udata/models/__init__.py +4 -4
  279. udata/mongo/__init__.py +13 -11
  280. udata/mongo/badges_field.py +3 -2
  281. udata/mongo/datetime_fields.py +13 -12
  282. udata/mongo/document.py +17 -16
  283. udata/mongo/engine.py +15 -16
  284. udata/mongo/errors.py +2 -1
  285. udata/mongo/extras_fields.py +30 -20
  286. udata/mongo/queryset.py +12 -12
  287. udata/mongo/slug_fields.py +38 -28
  288. udata/mongo/taglist_field.py +1 -2
  289. udata/mongo/url_field.py +5 -5
  290. udata/mongo/uuid_fields.py +4 -3
  291. udata/notifications/__init__.py +1 -1
  292. udata/notifications/mattermost.py +10 -9
  293. udata/rdf.py +167 -188
  294. udata/routing.py +40 -45
  295. udata/search/__init__.py +18 -19
  296. udata/search/adapter.py +17 -16
  297. udata/search/commands.py +44 -51
  298. udata/search/fields.py +13 -20
  299. udata/search/query.py +23 -18
  300. udata/search/result.py +9 -10
  301. udata/sentry.py +21 -19
  302. udata/settings.py +262 -198
  303. udata/sitemap.py +8 -6
  304. udata/static/chunks/{11.e9b9ca1f3e03d4020377.js → 11.52e531c19f8de80c00cf.js} +3 -3
  305. udata/static/chunks/{11.e9b9ca1f3e03d4020377.js.map → 11.52e531c19f8de80c00cf.js.map} +1 -1
  306. udata/static/chunks/{13.038c0d9aa0dfa0181c4b.js → 13.c3343a7f1070061c0e10.js} +2 -2
  307. udata/static/chunks/{13.038c0d9aa0dfa0181c4b.js.map → 13.c3343a7f1070061c0e10.js.map} +1 -1
  308. udata/static/chunks/{16.0baa2b64a74a2dcde25c.js → 16.8fa42440ad75ca172e6d.js} +2 -2
  309. udata/static/chunks/{16.0baa2b64a74a2dcde25c.js.map → 16.8fa42440ad75ca172e6d.js.map} +1 -1
  310. udata/static/chunks/{19.350a9f150b074b4ecefa.js → 19.9c6c8412729cd6d59cfa.js} +3 -3
  311. udata/static/chunks/{19.350a9f150b074b4ecefa.js.map → 19.9c6c8412729cd6d59cfa.js.map} +1 -1
  312. udata/static/chunks/{5.6ebbce2b9b3e696d3da5.js → 5.71d15c2e4f21feee2a9a.js} +3 -3
  313. udata/static/chunks/{5.6ebbce2b9b3e696d3da5.js.map → 5.71d15c2e4f21feee2a9a.js.map} +1 -1
  314. udata/static/chunks/{6.d8a5f7b017bcbd083641.js → 6.9139dc098b8ea640b890.js} +3 -3
  315. udata/static/chunks/{6.d8a5f7b017bcbd083641.js.map → 6.9139dc098b8ea640b890.js.map} +1 -1
  316. udata/static/common.js +1 -1
  317. udata/static/common.js.map +1 -1
  318. udata/storage/s3.py +20 -13
  319. udata/tags.py +4 -5
  320. udata/tasks.py +43 -42
  321. udata/tests/__init__.py +9 -6
  322. udata/tests/api/__init__.py +5 -6
  323. udata/tests/api/test_auth_api.py +395 -321
  324. udata/tests/api/test_base_api.py +31 -33
  325. udata/tests/api/test_contact_points.py +7 -9
  326. udata/tests/api/test_dataservices_api.py +211 -158
  327. udata/tests/api/test_datasets_api.py +823 -812
  328. udata/tests/api/test_follow_api.py +13 -15
  329. udata/tests/api/test_me_api.py +95 -112
  330. udata/tests/api/test_organizations_api.py +301 -339
  331. udata/tests/api/test_reports_api.py +35 -25
  332. udata/tests/api/test_reuses_api.py +134 -139
  333. udata/tests/api/test_swagger.py +5 -5
  334. udata/tests/api/test_tags_api.py +18 -25
  335. udata/tests/api/test_topics_api.py +94 -94
  336. udata/tests/api/test_transfer_api.py +53 -48
  337. udata/tests/api/test_user_api.py +128 -141
  338. udata/tests/apiv2/test_datasets.py +290 -198
  339. udata/tests/apiv2/test_me_api.py +10 -11
  340. udata/tests/apiv2/test_organizations.py +56 -74
  341. udata/tests/apiv2/test_swagger.py +5 -5
  342. udata/tests/apiv2/test_topics.py +69 -87
  343. udata/tests/cli/test_cli_base.py +8 -8
  344. udata/tests/cli/test_db_cli.py +21 -19
  345. udata/tests/dataservice/test_dataservice_tasks.py +8 -12
  346. udata/tests/dataset/test_csv_adapter.py +44 -35
  347. udata/tests/dataset/test_dataset_actions.py +2 -3
  348. udata/tests/dataset/test_dataset_commands.py +7 -8
  349. udata/tests/dataset/test_dataset_events.py +36 -29
  350. udata/tests/dataset/test_dataset_model.py +224 -217
  351. udata/tests/dataset/test_dataset_rdf.py +142 -131
  352. udata/tests/dataset/test_dataset_tasks.py +15 -15
  353. udata/tests/dataset/test_resource_preview.py +10 -13
  354. udata/tests/features/territories/__init__.py +9 -13
  355. udata/tests/features/territories/test_territories_api.py +71 -91
  356. udata/tests/forms/test_basic_fields.py +7 -7
  357. udata/tests/forms/test_current_user_field.py +39 -66
  358. udata/tests/forms/test_daterange_field.py +31 -39
  359. udata/tests/forms/test_dict_field.py +28 -26
  360. udata/tests/forms/test_extras_fields.py +102 -76
  361. udata/tests/forms/test_form_field.py +8 -8
  362. udata/tests/forms/test_image_field.py +33 -26
  363. udata/tests/forms/test_model_field.py +134 -123
  364. udata/tests/forms/test_model_list_field.py +7 -7
  365. udata/tests/forms/test_nested_model_list_field.py +117 -79
  366. udata/tests/forms/test_publish_as_field.py +36 -65
  367. udata/tests/forms/test_reference_field.py +34 -53
  368. udata/tests/forms/test_user_forms.py +23 -21
  369. udata/tests/forms/test_uuid_field.py +6 -10
  370. udata/tests/frontend/__init__.py +9 -6
  371. udata/tests/frontend/test_auth.py +7 -6
  372. udata/tests/frontend/test_csv.py +81 -96
  373. udata/tests/frontend/test_hooks.py +43 -43
  374. udata/tests/frontend/test_markdown.py +211 -191
  375. udata/tests/helpers.py +32 -37
  376. udata/tests/models.py +2 -2
  377. udata/tests/organization/test_csv_adapter.py +21 -16
  378. udata/tests/organization/test_notifications.py +11 -18
  379. udata/tests/organization/test_organization_model.py +13 -13
  380. udata/tests/organization/test_organization_rdf.py +29 -22
  381. udata/tests/organization/test_organization_tasks.py +16 -17
  382. udata/tests/plugin.py +76 -73
  383. udata/tests/reuse/test_reuse_model.py +21 -21
  384. udata/tests/reuse/test_reuse_task.py +11 -13
  385. udata/tests/search/__init__.py +11 -12
  386. udata/tests/search/test_adapter.py +60 -70
  387. udata/tests/search/test_query.py +16 -16
  388. udata/tests/search/test_results.py +10 -7
  389. udata/tests/site/test_site_api.py +11 -16
  390. udata/tests/site/test_site_metrics.py +20 -30
  391. udata/tests/site/test_site_model.py +4 -5
  392. udata/tests/site/test_site_rdf.py +94 -78
  393. udata/tests/test_activity.py +17 -17
  394. udata/tests/test_discussions.py +292 -299
  395. udata/tests/test_i18n.py +37 -40
  396. udata/tests/test_linkchecker.py +91 -85
  397. udata/tests/test_mail.py +13 -17
  398. udata/tests/test_migrations.py +219 -180
  399. udata/tests/test_model.py +164 -157
  400. udata/tests/test_notifications.py +17 -17
  401. udata/tests/test_owned.py +14 -14
  402. udata/tests/test_rdf.py +25 -23
  403. udata/tests/test_routing.py +89 -93
  404. udata/tests/test_storages.py +137 -128
  405. udata/tests/test_tags.py +44 -46
  406. udata/tests/test_topics.py +7 -7
  407. udata/tests/test_transfer.py +42 -49
  408. udata/tests/test_uris.py +160 -161
  409. udata/tests/test_utils.py +79 -71
  410. udata/tests/user/test_user_rdf.py +5 -9
  411. udata/tests/workers/test_jobs_commands.py +57 -58
  412. udata/tests/workers/test_tasks_routing.py +23 -29
  413. udata/tests/workers/test_workers_api.py +125 -131
  414. udata/tests/workers/test_workers_helpers.py +6 -6
  415. udata/tracking.py +4 -6
  416. udata/uris.py +45 -46
  417. udata/utils.py +68 -66
  418. udata/wsgi.py +1 -1
  419. {udata-9.1.2.dev30355.dist-info → udata-9.1.2.dev30382.dist-info}/METADATA +3 -2
  420. udata-9.1.2.dev30382.dist-info/RECORD +704 -0
  421. udata-9.1.2.dev30355.dist-info/RECORD +0 -704
  422. {udata-9.1.2.dev30355.dist-info → udata-9.1.2.dev30382.dist-info}/LICENSE +0 -0
  423. {udata-9.1.2.dev30355.dist-info → udata-9.1.2.dev30382.dist-info}/WHEEL +0 -0
  424. {udata-9.1.2.dev30355.dist-info → udata-9.1.2.dev30382.dist-info}/entry_points.txt +0 -0
  425. {udata-9.1.2.dev30355.dist-info → udata-9.1.2.dev30382.dist-info}/top_level.txt +0 -0
@@ -1,21 +1,20 @@
1
- import pytest
2
-
3
1
  from datetime import datetime, timedelta
4
2
  from urllib.parse import urlparse
3
+
4
+ import pytest
5
5
  from dateutil.parser import parse
6
6
  from voluptuous import Schema
7
7
 
8
- from udata.harvest.models import HarvestItem
9
- from udata.utils import faker
10
8
  from udata.core.dataset import tasks
11
9
  from udata.core.dataset.factories import DatasetFactory
10
+ from udata.harvest.models import HarvestItem
12
11
  from udata.models import Dataset
13
12
  from udata.tests.helpers import assert_equal_dates
13
+ from udata.utils import faker
14
14
 
15
- from .factories import HarvestSourceFactory
16
-
17
- from ..backends import BaseBackend, HarvestFilter, HarvestFeature
15
+ from ..backends import BaseBackend, HarvestFeature, HarvestFilter
18
16
  from ..exceptions import HarvestException
17
+ from .factories import HarvestSourceFactory
19
18
 
20
19
 
21
20
  class Unknown:
@@ -24,17 +23,17 @@ class Unknown:
24
23
 
25
24
  class FakeBackend(BaseBackend):
26
25
  filters = (
27
- HarvestFilter('First filter', 'first', str),
28
- HarvestFilter('Second filter', 'second', str),
26
+ HarvestFilter("First filter", "first", str),
27
+ HarvestFilter("Second filter", "second", str),
29
28
  )
30
29
  features = (
31
- HarvestFeature('feature', 'A test feature'),
32
- HarvestFeature('enabled', 'A test feature enabled by default', default=True),
30
+ HarvestFeature("feature", "A test feature"),
31
+ HarvestFeature("enabled", "A test feature enabled by default", default=True),
33
32
  )
34
33
 
35
34
  def inner_harvest(self):
36
- for i in range(self.source.config.get('nb_datasets', 3)):
37
- remote_id = f'fake-{i}'
35
+ for i in range(self.source.config.get("nb_datasets", 3)):
36
+ remote_id = f"fake-{i}"
38
37
  self.process_dataset(remote_id)
39
38
  if self.is_done():
40
39
  return
@@ -44,37 +43,37 @@ class FakeBackend(BaseBackend):
44
43
 
45
44
  for key, value in DatasetFactory.as_dict(visible=True).items():
46
45
  setattr(dataset, key, value)
47
- if self.source.config.get('last_modified'):
48
- dataset.last_modified_internal = self.source.config['last_modified']
46
+ if self.source.config.get("last_modified"):
47
+ dataset.last_modified_internal = self.source.config["last_modified"]
49
48
  return dataset
50
49
 
51
50
 
52
51
  class HarvestFilterTest:
53
- @pytest.mark.parametrize('type,expected', HarvestFilter.TYPES.items())
52
+ @pytest.mark.parametrize("type,expected", HarvestFilter.TYPES.items())
54
53
  def test_type_ok(self, type, expected):
55
54
  label = faker.word()
56
55
  key = faker.word()
57
56
  description = faker.sentence()
58
57
  hf = HarvestFilter(label, key, type, description)
59
58
  assert hf.as_dict() == {
60
- 'label': label,
61
- 'key': key,
62
- 'type': expected,
63
- 'description': description,
59
+ "label": label,
60
+ "key": key,
61
+ "type": expected,
62
+ "description": description,
64
63
  }
65
64
 
66
- @pytest.mark.parametrize('type', [dict, list, tuple, Unknown])
65
+ @pytest.mark.parametrize("type", [dict, list, tuple, Unknown])
67
66
  def test_type_ko(self, type):
68
67
  with pytest.raises(TypeError):
69
68
  HarvestFilter(faker.word(), faker.word(), type, faker.sentence())
70
69
 
71
70
 
72
- @pytest.mark.usefixtures('clean_db')
71
+ @pytest.mark.usefixtures("clean_db")
73
72
  class BaseBackendTest:
74
73
  def test_simple_harvest(self):
75
74
  now = datetime.utcnow()
76
75
  nb_datasets = 3
77
- source = HarvestSourceFactory(config={'nb_datasets': nb_datasets})
76
+ source = HarvestSourceFactory(config={"nb_datasets": nb_datasets})
78
77
  backend = FakeBackend(source)
79
78
 
80
79
  job = backend.harvest()
@@ -85,34 +84,36 @@ class BaseBackendTest:
85
84
  assert_equal_dates(dataset.last_modified, now)
86
85
  assert dataset.harvest.source_id == str(source.id)
87
86
  assert dataset.harvest.domain == source.domain
88
- assert dataset.harvest.remote_id.startswith('fake-')
87
+ assert dataset.harvest.remote_id.startswith("fake-")
89
88
  assert_equal_dates(dataset.harvest.last_update, now)
90
89
 
91
90
  def test_has_feature_defaults(self):
92
91
  source = HarvestSourceFactory()
93
92
  backend = FakeBackend(source)
94
93
 
95
- assert not backend.has_feature('feature')
96
- assert backend.has_feature('enabled')
94
+ assert not backend.has_feature("feature")
95
+ assert backend.has_feature("enabled")
97
96
 
98
97
  def test_has_feature_defined(self):
99
- source = HarvestSourceFactory(config={
100
- 'features': {
101
- 'feature': True,
102
- 'enabled': False,
98
+ source = HarvestSourceFactory(
99
+ config={
100
+ "features": {
101
+ "feature": True,
102
+ "enabled": False,
103
+ }
103
104
  }
104
- })
105
+ )
105
106
  backend = FakeBackend(source)
106
107
 
107
- assert backend.has_feature('feature')
108
- assert not backend.has_feature('enabled')
108
+ assert backend.has_feature("feature")
109
+ assert not backend.has_feature("enabled")
109
110
 
110
111
  def test_has_feature_unkown(self):
111
112
  source = HarvestSourceFactory()
112
113
  backend = FakeBackend(source)
113
114
 
114
115
  with pytest.raises(HarvestException):
115
- backend.has_feature('unknown')
116
+ backend.has_feature("unknown")
116
117
 
117
118
  def test_get_filters_empty(self):
118
119
  source = HarvestSourceFactory()
@@ -121,19 +122,21 @@ class BaseBackendTest:
121
122
  assert backend.get_filters() == []
122
123
 
123
124
  def test_get_filters(self):
124
- source = HarvestSourceFactory(config={
125
- 'filters': [
126
- {'key': 'second', 'value': ''},
127
- {'key': 'first', 'value': ''},
128
- ]
129
- })
125
+ source = HarvestSourceFactory(
126
+ config={
127
+ "filters": [
128
+ {"key": "second", "value": ""},
129
+ {"key": "first", "value": ""},
130
+ ]
131
+ }
132
+ )
130
133
  backend = FakeBackend(source)
131
134
 
132
- assert [f['key'] for f in backend.get_filters()] == ['second', 'first']
135
+ assert [f["key"] for f in backend.get_filters()] == ["second", "first"]
133
136
 
134
137
  def test_harvest_source_id(self):
135
138
  nb_datasets = 3
136
- source = HarvestSourceFactory(config={'nb_datasets': nb_datasets})
139
+ source = HarvestSourceFactory(config={"nb_datasets": nb_datasets})
137
140
  backend = FakeBackend(source)
138
141
 
139
142
  job = backend.harvest()
@@ -149,12 +152,12 @@ class BaseBackendTest:
149
152
  assert len(datasets) == nb_datasets
150
153
  for dataset in datasets:
151
154
  assert dataset.harvest.source_id == str(source.id)
152
- parsed = urlparse(source_url).netloc.split(':')[0]
155
+ parsed = urlparse(source_url).netloc.split(":")[0]
153
156
  assert parsed == dataset.harvest.domain
154
157
 
155
158
  def test_dont_overwrite_last_modified(self, mocker):
156
- last_modified = faker.date_time_between(start_date='-30y', end_date='-1y')
157
- source = HarvestSourceFactory(config={'nb_datasets': 1, 'last_modified': last_modified})
159
+ last_modified = faker.date_time_between(start_date="-30y", end_date="-1y")
160
+ source = HarvestSourceFactory(config={"nb_datasets": 1, "last_modified": last_modified})
158
161
  backend = FakeBackend(source)
159
162
 
160
163
  backend.harvest()
@@ -165,8 +168,8 @@ class BaseBackendTest:
165
168
  assert_equal_dates(dataset.harvest.last_update, datetime.utcnow())
166
169
 
167
170
  def test_dont_overwrite_last_modified_even_if_set_to_same(self, mocker):
168
- last_modified = faker.date_time_between(start_date='-30y', end_date='-1y')
169
- source = HarvestSourceFactory(config={'nb_datasets': 1, 'last_modified': last_modified})
171
+ last_modified = faker.date_time_between(start_date="-30y", end_date="-1y")
172
+ source = HarvestSourceFactory(config={"nb_datasets": 1, "last_modified": last_modified})
170
173
  backend = FakeBackend(source)
171
174
 
172
175
  backend.harvest()
@@ -179,28 +182,32 @@ class BaseBackendTest:
179
182
 
180
183
  def test_autoarchive(self, app):
181
184
  nb_datasets = 3
182
- source = HarvestSourceFactory(config={'nb_datasets': nb_datasets})
185
+ source = HarvestSourceFactory(config={"nb_datasets": nb_datasets})
183
186
  backend = FakeBackend(source)
184
187
 
185
188
  # create a dangling dataset to be archived
186
- limit = app.config['HARVEST_AUTOARCHIVE_GRACE_DAYS']
189
+ limit = app.config["HARVEST_AUTOARCHIVE_GRACE_DAYS"]
187
190
  last_update = datetime.utcnow() - timedelta(days=limit + 1)
188
- dataset_arch = DatasetFactory(harvest={
189
- 'domain': source.domain,
190
- 'source_id': str(source.id),
191
- 'remote_id': 'not-on-remote',
192
- 'last_update': last_update,
193
- })
191
+ dataset_arch = DatasetFactory(
192
+ harvest={
193
+ "domain": source.domain,
194
+ "source_id": str(source.id),
195
+ "remote_id": "not-on-remote",
196
+ "last_update": last_update,
197
+ }
198
+ )
194
199
 
195
200
  # create a dangling dataset that _won't_ be archived because of grace period
196
- limit = app.config['HARVEST_AUTOARCHIVE_GRACE_DAYS']
201
+ limit = app.config["HARVEST_AUTOARCHIVE_GRACE_DAYS"]
197
202
  last_update = datetime.utcnow() - timedelta(days=limit - 1)
198
- dataset_no_arch = DatasetFactory(harvest={
199
- 'domain': source.domain,
200
- 'source_id': str(source.id),
201
- 'remote_id': 'not-on-remote-two',
202
- 'last_update': last_update,
203
- })
203
+ dataset_no_arch = DatasetFactory(
204
+ harvest={
205
+ "domain": source.domain,
206
+ "source_id": str(source.id),
207
+ "remote_id": "not-on-remote-two",
208
+ "last_update": last_update,
209
+ }
210
+ )
204
211
 
205
212
  job = backend.harvest()
206
213
 
@@ -209,35 +216,35 @@ class BaseBackendTest:
209
216
  # all datasets : 3 mocks + 2 manuals (arch and no_arch)
210
217
  assert Dataset.objects.count() == nb_datasets + 2
211
218
 
212
- archived_items = [i for i in job.items if i.status == 'archived']
219
+ archived_items = [i for i in job.items if i.status == "archived"]
213
220
  assert len(archived_items) == 1
214
221
  assert archived_items[0].dataset == dataset_arch
215
222
 
216
223
  dataset_arch.reload()
217
224
  assert dataset_arch.archived is not None
218
- assert 'archived' in dataset_arch.harvest
219
- assert 'archived_at' in dataset_arch.harvest
225
+ assert "archived" in dataset_arch.harvest
226
+ assert "archived_at" in dataset_arch.harvest
220
227
 
221
228
  dataset_no_arch.reload()
222
229
  assert dataset_no_arch.archived is None
223
- assert 'archived' not in dataset_no_arch.harvest
224
- assert 'archived_at' not in dataset_no_arch.harvest
230
+ assert "archived" not in dataset_no_arch.harvest
231
+ assert "archived_at" not in dataset_no_arch.harvest
225
232
 
226
233
  # test unarchive: archive manually then relaunch harvest
227
- dataset = Dataset.objects.get(**{'harvest__remote_id': 'fake-1'})
234
+ dataset = Dataset.objects.get(**{"harvest__remote_id": "fake-1"})
228
235
  dataset.archived = datetime.utcnow()
229
- dataset.harvest.archived = 'not-on-remote'
236
+ dataset.harvest.archived = "not-on-remote"
230
237
  dataset.harvest.archived_at = datetime.utcnow()
231
238
  dataset.save()
232
239
  backend.harvest()
233
240
  dataset.reload()
234
241
  assert dataset.archived is None
235
- assert 'archived' not in dataset.harvest
236
- assert 'archived_at' not in dataset.harvest
242
+ assert "archived" not in dataset.harvest
243
+ assert "archived_at" not in dataset.harvest
237
244
 
238
245
  def test_harvest_datasets_get_deleted(self):
239
246
  nb_datasets = 3
240
- source = HarvestSourceFactory(config={'nb_datasets': nb_datasets})
247
+ source = HarvestSourceFactory(config={"nb_datasets": nb_datasets})
241
248
  backend = FakeBackend(source)
242
249
 
243
250
  job = backend.harvest()
@@ -246,7 +253,7 @@ class BaseBackendTest:
246
253
  assert item.dataset is not None
247
254
 
248
255
  for dataset in Dataset.objects():
249
- dataset.deleted = '2016-01-01'
256
+ dataset.deleted = "2016-01-01"
250
257
  dataset.save()
251
258
 
252
259
  tasks.purge_datasets()
@@ -256,81 +263,79 @@ class BaseBackendTest:
256
263
  assert item.dataset is None
257
264
 
258
265
 
259
- @pytest.mark.usefixtures('clean_db')
266
+ @pytest.mark.usefixtures("clean_db")
260
267
  class BaseBackendValidateTest:
261
268
  @pytest.fixture
262
269
  def validate(self):
263
270
  return FakeBackend(HarvestSourceFactory()).validate
264
271
 
265
272
  def test_valid_data(self, validate):
266
- schema = Schema({'key': str})
267
- data = {'key': 'value'}
273
+ schema = Schema({"key": str})
274
+ data = {"key": "value"}
268
275
  assert validate(data, schema) == data
269
276
 
270
277
  def test_handle_basic_error(self, validate):
271
- schema = Schema({'bad-value': str})
272
- data = {'bad-value': 42}
278
+ schema = Schema({"bad-value": str})
279
+ data = {"bad-value": 42}
273
280
  with pytest.raises(HarvestException) as excinfo:
274
281
  validate(data, schema)
275
282
  msg = str(excinfo.value)
276
- assert '[bad-value] expected str: 42' in msg
283
+ assert "[bad-value] expected str: 42" in msg
277
284
 
278
285
  def test_handle_required_values(self, validate):
279
- schema = Schema({'missing': str}, required=True)
286
+ schema = Schema({"missing": str}, required=True)
280
287
  data = {}
281
288
  with pytest.raises(HarvestException) as excinfo:
282
289
  validate(data, schema)
283
290
  msg = str(excinfo.value)
284
- assert '[missing] required key not provided' in msg
285
- assert '[missing] required key not provided: None' not in msg
291
+ assert "[missing] required key not provided" in msg
292
+ assert "[missing] required key not provided: None" not in msg
286
293
 
287
294
  def test_handle_multiple_errors_on_object(self, validate):
288
- schema = Schema({'bad-value': str, 'other-bad-value': int})
289
- data = {'bad-value': 42, 'other-bad-value': 'wrong'}
295
+ schema = Schema({"bad-value": str, "other-bad-value": int})
296
+ data = {"bad-value": 42, "other-bad-value": "wrong"}
290
297
  with pytest.raises(HarvestException) as excinfo:
291
298
  validate(data, schema)
292
299
  msg = str(excinfo.value)
293
- assert '[bad-value] expected str: 42' in msg
294
- assert '[other-bad-value] expected int: wrong' in msg
300
+ assert "[bad-value] expected str: 42" in msg
301
+ assert "[other-bad-value] expected int: wrong" in msg
295
302
 
296
303
  def test_handle_multiple_error_on_nested_object(self, validate):
297
- schema = Schema({'nested': {
298
- 'bad-value': str, 'other-bad-value': int
299
- }})
300
- data = {'nested': {'bad-value': 42, 'other-bad-value': 'wrong'}}
304
+ schema = Schema({"nested": {"bad-value": str, "other-bad-value": int}})
305
+ data = {"nested": {"bad-value": 42, "other-bad-value": "wrong"}}
301
306
  with pytest.raises(HarvestException) as excinfo:
302
307
  validate(data, schema)
303
308
  msg = str(excinfo.value)
304
- assert '[nested.bad-value] expected str: 42' in msg
305
- assert '[nested.other-bad-value] expected int: wrong' in msg
309
+ assert "[nested.bad-value] expected str: 42" in msg
310
+ assert "[nested.other-bad-value] expected int: wrong" in msg
306
311
 
307
312
  def test_handle_multiple_error_on_nested_list(self, validate):
308
- schema = Schema({'nested': [
309
- {'bad-value': str, 'other-bad-value': int}
310
- ]})
311
- data = {'nested': [
312
- {'bad-value': 42, 'other-bad-value': 'wrong'},
313
- ]}
313
+ schema = Schema({"nested": [{"bad-value": str, "other-bad-value": int}]})
314
+ data = {
315
+ "nested": [
316
+ {"bad-value": 42, "other-bad-value": "wrong"},
317
+ ]
318
+ }
314
319
  with pytest.raises(HarvestException) as excinfo:
315
320
  validate(data, schema)
316
321
  msg = str(excinfo.value)
317
- assert '[nested.0.bad-value] expected str: 42' in msg
318
- assert '[nested.0.other-bad-value] expected int: wrong' in msg
322
+ assert "[nested.0.bad-value] expected str: 42" in msg
323
+ assert "[nested.0.other-bad-value] expected int: wrong" in msg
319
324
 
320
325
  # See: https://github.com/alecthomas/voluptuous/pull/330
321
- @pytest.mark.skip(reason='Not yet supported by Voluptuous')
326
+ @pytest.mark.skip(reason="Not yet supported by Voluptuous")
322
327
  def test_handle_multiple_error_on_nested_list_items(self, validate):
323
- schema = Schema({'nested': [
324
- {'bad-value': str, 'other-bad-value': int}
325
- ]})
326
- data = {'nested': [
327
- {'bad-value': 42, 'other-bad-value': 'wrong'},
328
- {'bad-value': 43, 'other-bad-value': 'bad'},
329
- ]}
328
+ schema = Schema({"nested": [{"bad-value": str, "other-bad-value": int}]})
329
+ data = {
330
+ "nested": [
331
+ {"bad-value": 42, "other-bad-value": "wrong"},
332
+ {"bad-value": 43, "other-bad-value": "bad"},
333
+ ]
334
+ }
330
335
  with pytest.raises(HarvestException) as excinfo:
331
336
  validate(data, schema)
332
337
  msg = str(excinfo.value)
333
- assert '[nested.0.bad-value] expected str: 42' in msg
334
- assert '[nested.0.other-bad-value] expected int: wrong' in msg
335
- assert '[nested.1.bad-value] expected str: 43' in msg
336
- assert '[nested.1.other-bad-value] expected int: bad' in msg
338
+ assert "[nested.0.bad-value] expected str: 42" in msg
339
+ assert "[nested.0.other-bad-value] expected int: wrong" in msg
340
+ assert "[nested.1.bad-value] expected str: 43" in msg
341
+ assert "[nested.1.other-bad-value] expected int: bad" in msg