udata 9.1.2.dev30355__py2.py3-none-any.whl → 9.1.2.dev30454__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 (413) 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 +111 -134
  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 +58 -55
  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/cors.py +99 -0
  199. udata/db/tasks.py +2 -1
  200. udata/entrypoints.py +35 -31
  201. udata/errors.py +2 -1
  202. udata/event/values.py +6 -6
  203. udata/factories.py +2 -2
  204. udata/features/identicon/api.py +5 -6
  205. udata/features/identicon/backends.py +48 -55
  206. udata/features/identicon/tests/test_backends.py +4 -5
  207. udata/features/notifications/__init__.py +0 -1
  208. udata/features/notifications/actions.py +9 -9
  209. udata/features/notifications/api.py +17 -13
  210. udata/features/territories/__init__.py +12 -10
  211. udata/features/territories/api.py +14 -15
  212. udata/features/territories/models.py +23 -28
  213. udata/features/transfer/actions.py +8 -11
  214. udata/features/transfer/api.py +84 -77
  215. udata/features/transfer/factories.py +2 -1
  216. udata/features/transfer/models.py +11 -12
  217. udata/features/transfer/notifications.py +19 -15
  218. udata/features/transfer/permissions.py +5 -5
  219. udata/forms/__init__.py +5 -2
  220. udata/forms/fields.py +164 -172
  221. udata/forms/validators.py +19 -22
  222. udata/forms/widgets.py +9 -13
  223. udata/frontend/__init__.py +31 -26
  224. udata/frontend/csv.py +68 -58
  225. udata/frontend/markdown.py +40 -44
  226. udata/harvest/actions.py +89 -77
  227. udata/harvest/api.py +294 -238
  228. udata/harvest/backends/__init__.py +4 -4
  229. udata/harvest/backends/base.py +128 -111
  230. udata/harvest/backends/dcat.py +80 -66
  231. udata/harvest/commands.py +56 -60
  232. udata/harvest/csv.py +8 -8
  233. udata/harvest/exceptions.py +6 -3
  234. udata/harvest/filters.py +24 -23
  235. udata/harvest/forms.py +27 -28
  236. udata/harvest/models.py +88 -80
  237. udata/harvest/notifications.py +15 -10
  238. udata/harvest/signals.py +13 -13
  239. udata/harvest/tasks.py +11 -10
  240. udata/harvest/tests/factories.py +23 -24
  241. udata/harvest/tests/test_actions.py +136 -166
  242. udata/harvest/tests/test_api.py +220 -214
  243. udata/harvest/tests/test_base_backend.py +117 -112
  244. udata/harvest/tests/test_dcat_backend.py +380 -308
  245. udata/harvest/tests/test_filters.py +33 -22
  246. udata/harvest/tests/test_models.py +11 -14
  247. udata/harvest/tests/test_notifications.py +6 -7
  248. udata/harvest/tests/test_tasks.py +7 -6
  249. udata/i18n.py +237 -78
  250. udata/linkchecker/backends.py +5 -11
  251. udata/linkchecker/checker.py +23 -22
  252. udata/linkchecker/commands.py +4 -6
  253. udata/linkchecker/models.py +6 -6
  254. udata/linkchecker/tasks.py +18 -20
  255. udata/mail.py +21 -21
  256. udata/migrations/2020-07-24-remove-s-from-scope-oauth.py +9 -8
  257. udata/migrations/2020-08-24-add-fs-filename.py +9 -8
  258. udata/migrations/2020-09-28-update-reuses-datasets-metrics.py +5 -4
  259. udata/migrations/2020-10-16-migrate-ods-resources.py +9 -10
  260. udata/migrations/2021-04-08-update-schema-with-new-structure.py +8 -7
  261. udata/migrations/2021-05-27-fix-default-schema-name.py +7 -6
  262. udata/migrations/2021-07-05-remove-unused-badges.py +17 -15
  263. udata/migrations/2021-07-07-update-schema-for-community-resources.py +7 -6
  264. udata/migrations/2021-08-17-follow-integrity.py +5 -4
  265. udata/migrations/2021-08-17-harvest-integrity.py +13 -12
  266. udata/migrations/2021-08-17-oauth2client-integrity.py +5 -4
  267. udata/migrations/2021-08-17-transfer-integrity.py +5 -4
  268. udata/migrations/2021-08-17-users-integrity.py +9 -8
  269. udata/migrations/2021-12-14-reuse-topics.py +7 -6
  270. udata/migrations/2022-04-21-improve-extension-detection.py +8 -7
  271. udata/migrations/2022-09-22-clean-inactive-harvest-datasets.py +16 -14
  272. udata/migrations/2022-10-10-add-fs_uniquifier-to-user-model.py +6 -6
  273. udata/migrations/2022-10-10-migrate-harvest-extras.py +36 -26
  274. udata/migrations/2023-02-08-rename-internal-dates.py +46 -28
  275. udata/migrations/2024-01-29-fix-reuse-and-dataset-with-private-None.py +10 -8
  276. udata/migrations/2024-03-22-migrate-activity-kwargs-to-extras.py +6 -4
  277. udata/migrations/2024-06-11-fix-reuse-datasets-references.py +7 -6
  278. udata/migrations/__init__.py +123 -105
  279. udata/models/__init__.py +4 -4
  280. udata/mongo/__init__.py +13 -11
  281. udata/mongo/badges_field.py +3 -2
  282. udata/mongo/datetime_fields.py +13 -12
  283. udata/mongo/document.py +17 -16
  284. udata/mongo/engine.py +15 -16
  285. udata/mongo/errors.py +2 -1
  286. udata/mongo/extras_fields.py +30 -20
  287. udata/mongo/queryset.py +12 -12
  288. udata/mongo/slug_fields.py +38 -28
  289. udata/mongo/taglist_field.py +1 -2
  290. udata/mongo/url_field.py +5 -5
  291. udata/mongo/uuid_fields.py +4 -3
  292. udata/notifications/__init__.py +1 -1
  293. udata/notifications/mattermost.py +10 -9
  294. udata/rdf.py +167 -188
  295. udata/routing.py +40 -45
  296. udata/search/__init__.py +18 -19
  297. udata/search/adapter.py +17 -16
  298. udata/search/commands.py +44 -51
  299. udata/search/fields.py +13 -20
  300. udata/search/query.py +23 -18
  301. udata/search/result.py +9 -10
  302. udata/sentry.py +21 -19
  303. udata/settings.py +262 -198
  304. udata/sitemap.py +8 -6
  305. udata/storage/s3.py +20 -13
  306. udata/tags.py +4 -5
  307. udata/tasks.py +43 -42
  308. udata/tests/__init__.py +9 -6
  309. udata/tests/api/__init__.py +8 -6
  310. udata/tests/api/test_auth_api.py +395 -321
  311. udata/tests/api/test_base_api.py +33 -35
  312. udata/tests/api/test_contact_points.py +7 -9
  313. udata/tests/api/test_dataservices_api.py +211 -158
  314. udata/tests/api/test_datasets_api.py +823 -812
  315. udata/tests/api/test_follow_api.py +13 -15
  316. udata/tests/api/test_me_api.py +95 -112
  317. udata/tests/api/test_organizations_api.py +301 -339
  318. udata/tests/api/test_reports_api.py +35 -25
  319. udata/tests/api/test_reuses_api.py +134 -139
  320. udata/tests/api/test_swagger.py +5 -5
  321. udata/tests/api/test_tags_api.py +18 -25
  322. udata/tests/api/test_topics_api.py +94 -94
  323. udata/tests/api/test_transfer_api.py +53 -48
  324. udata/tests/api/test_user_api.py +128 -141
  325. udata/tests/apiv2/test_datasets.py +290 -198
  326. udata/tests/apiv2/test_me_api.py +10 -11
  327. udata/tests/apiv2/test_organizations.py +56 -74
  328. udata/tests/apiv2/test_swagger.py +5 -5
  329. udata/tests/apiv2/test_topics.py +69 -87
  330. udata/tests/cli/test_cli_base.py +8 -8
  331. udata/tests/cli/test_db_cli.py +21 -19
  332. udata/tests/dataservice/test_dataservice_tasks.py +8 -12
  333. udata/tests/dataset/test_csv_adapter.py +44 -35
  334. udata/tests/dataset/test_dataset_actions.py +2 -3
  335. udata/tests/dataset/test_dataset_commands.py +7 -8
  336. udata/tests/dataset/test_dataset_events.py +36 -29
  337. udata/tests/dataset/test_dataset_model.py +224 -217
  338. udata/tests/dataset/test_dataset_rdf.py +142 -131
  339. udata/tests/dataset/test_dataset_tasks.py +15 -15
  340. udata/tests/dataset/test_resource_preview.py +10 -13
  341. udata/tests/features/territories/__init__.py +9 -13
  342. udata/tests/features/territories/test_territories_api.py +71 -91
  343. udata/tests/forms/test_basic_fields.py +7 -7
  344. udata/tests/forms/test_current_user_field.py +39 -66
  345. udata/tests/forms/test_daterange_field.py +31 -39
  346. udata/tests/forms/test_dict_field.py +28 -26
  347. udata/tests/forms/test_extras_fields.py +102 -76
  348. udata/tests/forms/test_form_field.py +8 -8
  349. udata/tests/forms/test_image_field.py +33 -26
  350. udata/tests/forms/test_model_field.py +134 -123
  351. udata/tests/forms/test_model_list_field.py +7 -7
  352. udata/tests/forms/test_nested_model_list_field.py +117 -79
  353. udata/tests/forms/test_publish_as_field.py +36 -65
  354. udata/tests/forms/test_reference_field.py +34 -53
  355. udata/tests/forms/test_user_forms.py +23 -21
  356. udata/tests/forms/test_uuid_field.py +6 -10
  357. udata/tests/frontend/__init__.py +9 -6
  358. udata/tests/frontend/test_auth.py +7 -6
  359. udata/tests/frontend/test_csv.py +81 -96
  360. udata/tests/frontend/test_hooks.py +43 -43
  361. udata/tests/frontend/test_markdown.py +211 -191
  362. udata/tests/helpers.py +32 -37
  363. udata/tests/models.py +2 -2
  364. udata/tests/organization/test_csv_adapter.py +21 -16
  365. udata/tests/organization/test_notifications.py +11 -18
  366. udata/tests/organization/test_organization_model.py +13 -13
  367. udata/tests/organization/test_organization_rdf.py +29 -22
  368. udata/tests/organization/test_organization_tasks.py +16 -17
  369. udata/tests/plugin.py +79 -73
  370. udata/tests/reuse/test_reuse_model.py +21 -21
  371. udata/tests/reuse/test_reuse_task.py +11 -13
  372. udata/tests/search/__init__.py +11 -12
  373. udata/tests/search/test_adapter.py +60 -70
  374. udata/tests/search/test_query.py +16 -16
  375. udata/tests/search/test_results.py +10 -7
  376. udata/tests/site/test_site_api.py +11 -16
  377. udata/tests/site/test_site_metrics.py +20 -30
  378. udata/tests/site/test_site_model.py +4 -5
  379. udata/tests/site/test_site_rdf.py +94 -78
  380. udata/tests/test_activity.py +17 -17
  381. udata/tests/test_cors.py +62 -0
  382. udata/tests/test_discussions.py +292 -299
  383. udata/tests/test_i18n.py +37 -40
  384. udata/tests/test_linkchecker.py +91 -85
  385. udata/tests/test_mail.py +13 -17
  386. udata/tests/test_migrations.py +219 -180
  387. udata/tests/test_model.py +164 -157
  388. udata/tests/test_notifications.py +17 -17
  389. udata/tests/test_owned.py +14 -14
  390. udata/tests/test_rdf.py +25 -23
  391. udata/tests/test_routing.py +89 -93
  392. udata/tests/test_storages.py +137 -128
  393. udata/tests/test_tags.py +44 -46
  394. udata/tests/test_topics.py +7 -7
  395. udata/tests/test_transfer.py +42 -49
  396. udata/tests/test_uris.py +160 -161
  397. udata/tests/test_utils.py +79 -71
  398. udata/tests/user/test_user_rdf.py +5 -9
  399. udata/tests/workers/test_jobs_commands.py +57 -58
  400. udata/tests/workers/test_tasks_routing.py +23 -29
  401. udata/tests/workers/test_workers_api.py +125 -131
  402. udata/tests/workers/test_workers_helpers.py +6 -6
  403. udata/tracking.py +4 -6
  404. udata/uris.py +45 -46
  405. udata/utils.py +68 -66
  406. udata/wsgi.py +1 -1
  407. {udata-9.1.2.dev30355.dist-info → udata-9.1.2.dev30454.dist-info}/METADATA +7 -3
  408. udata-9.1.2.dev30454.dist-info/RECORD +706 -0
  409. udata-9.1.2.dev30355.dist-info/RECORD +0 -704
  410. {udata-9.1.2.dev30355.dist-info → udata-9.1.2.dev30454.dist-info}/LICENSE +0 -0
  411. {udata-9.1.2.dev30355.dist-info → udata-9.1.2.dev30454.dist-info}/WHEEL +0 -0
  412. {udata-9.1.2.dev30355.dist-info → udata-9.1.2.dev30454.dist-info}/entry_points.txt +0 -0
  413. {udata-9.1.2.dev30355.dist-info → udata-9.1.2.dev30454.dist-info}/top_level.txt +0 -0
@@ -1,5 +1,5 @@
1
- import logging
2
1
  import json
2
+ import logging
3
3
 
4
4
  import click
5
5
  import requests
@@ -7,112 +7,120 @@ from flask import current_app
7
7
 
8
8
  from udata.commands import cli
9
9
  from udata.core.dataset.factories import (
10
- DatasetFactory, ResourceFactory, CommunityResourceFactory
10
+ CommunityResourceFactory,
11
+ DatasetFactory,
12
+ ResourceFactory,
11
13
  )
14
+ from udata.core.discussions.factories import DiscussionFactory, MessageDiscussionFactory
12
15
  from udata.core.organization.factories import OrganizationFactory
13
16
  from udata.core.organization.models import Member, Organization
14
17
  from udata.core.reuse.factories import ReuseFactory
15
18
  from udata.core.user.factories import UserFactory
16
- from udata.core.discussions.factories import (
17
- MessageDiscussionFactory, DiscussionFactory
18
- )
19
19
 
20
20
  log = logging.getLogger(__name__)
21
21
 
22
22
 
23
- DATASET_URL = '/api/1/datasets'
24
- ORG_URL = '/api/1/organizations'
25
- REUSE_URL = '/api/1/reuses'
26
- COMMUNITY_RES_URL = '/api/1/datasets/community_resources'
27
- DISCUSSION_URL = '/api/1/discussions'
23
+ DATASET_URL = "/api/1/datasets"
24
+ ORG_URL = "/api/1/organizations"
25
+ REUSE_URL = "/api/1/reuses"
26
+ COMMUNITY_RES_URL = "/api/1/datasets/community_resources"
27
+ DISCUSSION_URL = "/api/1/discussions"
28
28
 
29
29
 
30
- DEFAULT_FIXTURE_FILE = 'https://raw.githubusercontent.com/opendatateam/udata-fixtures/main/results.json' # noqa
30
+ DEFAULT_FIXTURE_FILE = (
31
+ "https://raw.githubusercontent.com/opendatateam/udata-fixtures/main/results.json" # noqa
32
+ )
31
33
 
32
34
 
33
35
  @cli.command()
34
- @click.argument('data-source')
36
+ @click.argument("data-source")
35
37
  def generate_fixtures_file(data_source):
36
- '''Build sample fixture file based on datasets slugs list (users, datasets, reuses).'''
37
- datasets_slugs = current_app.config['FIXTURE_DATASET_SLUGS']
38
+ """Build sample fixture file based on datasets slugs list (users, datasets, reuses)."""
39
+ datasets_slugs = current_app.config["FIXTURE_DATASET_SLUGS"]
38
40
  json_result = []
39
41
 
40
42
  with click.progressbar(datasets_slugs) as bar:
41
43
  for slug in bar:
42
44
  json_fixture = {}
43
45
 
44
- json_dataset = requests.get(f'{data_source}{DATASET_URL}/{slug}/').json()
45
- del json_dataset['uri']
46
- del json_dataset['page']
47
- del json_dataset['last_update']
48
- del json_dataset['last_modified']
49
- del json_dataset['license']
50
- del json_dataset['badges']
51
- del json_dataset['spatial']
52
- del json_dataset['quality']
53
- json_dataset['created_at_internal'] = json_dataset.pop('created_at')
54
- json_resources = json_dataset.pop('resources')
46
+ json_dataset = requests.get(f"{data_source}{DATASET_URL}/{slug}/").json()
47
+ del json_dataset["uri"]
48
+ del json_dataset["page"]
49
+ del json_dataset["last_update"]
50
+ del json_dataset["last_modified"]
51
+ del json_dataset["license"]
52
+ del json_dataset["badges"]
53
+ del json_dataset["spatial"]
54
+ del json_dataset["quality"]
55
+ json_dataset["created_at_internal"] = json_dataset.pop("created_at")
56
+ json_resources = json_dataset.pop("resources")
55
57
  for res in json_resources:
56
- del res['latest']
57
- del res['preview_url']
58
- del res['last_modified']
59
- res['created_at_internal'] = res.pop('created_at')
60
- if json_dataset['organization'] is None:
61
- json_owner = json_dataset.pop('owner')
62
- json_dataset['owner'] = json_owner['id']
58
+ del res["latest"]
59
+ del res["preview_url"]
60
+ del res["last_modified"]
61
+ res["created_at_internal"] = res.pop("created_at")
62
+ if json_dataset["organization"] is None:
63
+ json_owner = json_dataset.pop("owner")
64
+ json_dataset["owner"] = json_owner["id"]
63
65
  else:
64
- json_org = json_dataset.pop('organization')
66
+ json_org = json_dataset.pop("organization")
65
67
  json_org = requests.get(f"{data_source}{ORG_URL}/{json_org['id']}/").json()
66
- del json_org['members']
67
- del json_org['page']
68
- del json_org['uri']
69
- del json_org['logo_thumbnail']
70
- json_fixture['organization'] = json_org
71
- json_fixture['resources'] = json_resources
72
- json_fixture['dataset'] = json_dataset
73
-
74
- json_reuses = requests.get(f"{data_source}{REUSE_URL}/?dataset={json_dataset['id']}").json()['data']
68
+ del json_org["members"]
69
+ del json_org["page"]
70
+ del json_org["uri"]
71
+ del json_org["logo_thumbnail"]
72
+ json_fixture["organization"] = json_org
73
+ json_fixture["resources"] = json_resources
74
+ json_fixture["dataset"] = json_dataset
75
+
76
+ json_reuses = requests.get(
77
+ f"{data_source}{REUSE_URL}/?dataset={json_dataset['id']}"
78
+ ).json()["data"]
75
79
  for reuse in json_reuses:
76
- del reuse['datasets']
77
- del reuse['image_thumbnail']
78
- del reuse['page']
79
- del reuse['uri']
80
- del reuse['organization']
81
- del reuse['owner']
82
- json_fixture['reuses'] = json_reuses
83
-
84
- json_community = requests.get(f"{data_source}{COMMUNITY_RES_URL}/?dataset={json_dataset['id']}").json()['data']
80
+ del reuse["datasets"]
81
+ del reuse["image_thumbnail"]
82
+ del reuse["page"]
83
+ del reuse["uri"]
84
+ del reuse["organization"]
85
+ del reuse["owner"]
86
+ json_fixture["reuses"] = json_reuses
87
+
88
+ json_community = requests.get(
89
+ f"{data_source}{COMMUNITY_RES_URL}/?dataset={json_dataset['id']}"
90
+ ).json()["data"]
85
91
  for com in json_community:
86
- del com['dataset']
87
- del com['organization']
88
- del com['owner']
89
- del com['latest']
90
- del com['last_modified']
91
- del com['preview_url']
92
- com['created_at_internal'] = com.pop('created_at')
93
- json_fixture['community_resources'] = json_community
94
-
95
- json_discussion = requests.get(f"{data_source}{DISCUSSION_URL}/?for={json_dataset['id']}").json()['data']
92
+ del com["dataset"]
93
+ del com["organization"]
94
+ del com["owner"]
95
+ del com["latest"]
96
+ del com["last_modified"]
97
+ del com["preview_url"]
98
+ com["created_at_internal"] = com.pop("created_at")
99
+ json_fixture["community_resources"] = json_community
100
+
101
+ json_discussion = requests.get(
102
+ f"{data_source}{DISCUSSION_URL}/?for={json_dataset['id']}"
103
+ ).json()["data"]
96
104
  for discussion in json_discussion:
97
- del discussion['subject']
98
- del discussion['user']
99
- del discussion['url']
100
- del discussion['class']
101
- for message in discussion['discussion']:
102
- del message['posted_by']
103
- json_fixture['discussions'] = json_discussion
105
+ del discussion["subject"]
106
+ del discussion["user"]
107
+ del discussion["url"]
108
+ del discussion["class"]
109
+ for message in discussion["discussion"]:
110
+ del message["posted_by"]
111
+ json_fixture["discussions"] = json_discussion
104
112
 
105
113
  json_result.append(json_fixture)
106
114
 
107
- with open('results.json', 'w') as f:
115
+ with open("results.json", "w") as f:
108
116
  json.dump(json_result, f)
109
117
 
110
118
 
111
119
  @cli.command()
112
- @click.argument('source', default=DEFAULT_FIXTURE_FILE)
120
+ @click.argument("source", default=DEFAULT_FIXTURE_FILE)
113
121
  def generate_fixtures(source):
114
- '''Build sample fixture data (users, datasets, reuses) from local or remote file.'''
115
- if source.startswith('http'):
122
+ """Build sample fixture data (users, datasets, reuses) from local or remote file."""
123
+ if source.startswith("http"):
116
124
  json_fixtures = requests.get(source).json()
117
125
  else:
118
126
  with open(source) as f:
@@ -121,21 +129,29 @@ def generate_fixtures(source):
121
129
  with click.progressbar(json_fixtures) as bar:
122
130
  for fixture in bar:
123
131
  user = UserFactory()
124
- if not fixture['organization']:
125
- dataset = DatasetFactory(**fixture['dataset'], owner=user)
132
+ if not fixture["organization"]:
133
+ dataset = DatasetFactory(**fixture["dataset"], owner=user)
126
134
  else:
127
- org = Organization.objects(id=fixture['organization']['id']).first()
135
+ org = Organization.objects(id=fixture["organization"]["id"]).first()
128
136
  if not org:
129
- org = OrganizationFactory(**fixture['organization'], members=[Member(user=user)])
130
- dataset = DatasetFactory(**fixture['dataset'], organization=org)
131
- for resource in fixture['resources']:
137
+ org = OrganizationFactory(
138
+ **fixture["organization"], members=[Member(user=user)]
139
+ )
140
+ dataset = DatasetFactory(**fixture["dataset"], organization=org)
141
+ for resource in fixture["resources"]:
132
142
  res = ResourceFactory(**resource)
133
143
  dataset.add_resource(res)
134
- for reuse in fixture['reuses']:
144
+ for reuse in fixture["reuses"]:
135
145
  ReuseFactory(**reuse, datasets=[dataset], owner=user)
136
- for community in fixture['community_resources']:
146
+ for community in fixture["community_resources"]:
137
147
  CommunityResourceFactory(**community, dataset=dataset, owner=user)
138
- for discussion in fixture['discussions']:
139
- messages = discussion.pop('discussion')
140
- DiscussionFactory(**discussion, subject=dataset, user=user,
141
- discussion=[MessageDiscussionFactory(**message, posted_by=user) for message in messages])
148
+ for discussion in fixture["discussions"]:
149
+ messages = discussion.pop("discussion")
150
+ DiscussionFactory(
151
+ **discussion,
152
+ subject=dataset,
153
+ user=user,
154
+ discussion=[
155
+ MessageDiscussionFactory(**message, posted_by=user) for message in messages
156
+ ],
157
+ )
udata/commands/images.py CHANGED
@@ -1,5 +1,4 @@
1
1
  import logging
2
-
3
2
  from collections import Counter
4
3
 
5
4
  from udata.commands import cli, header, success
@@ -7,9 +6,9 @@ from udata.commands import cli, header, success
7
6
  log = logging.getLogger(__name__)
8
7
 
9
8
 
10
- @cli.group('images')
9
+ @cli.group("images")
11
10
  def grp():
12
- '''Images related operations'''
11
+ """Images related operations"""
13
12
  pass
14
13
 
15
14
 
@@ -25,45 +24,47 @@ def render_or_skip(obj, attr):
25
24
 
26
25
  @grp.command()
27
26
  def render():
28
- '''Force (re)rendering stored images'''
27
+ """Force (re)rendering stored images"""
29
28
  from udata.core.organization.models import Organization
30
29
  from udata.core.post.models import Post
31
30
  from udata.core.reuse.models import Reuse
32
31
  from udata.core.user.models import User
33
32
 
34
- header('Rendering images')
33
+ header("Rendering images")
35
34
 
36
35
  count = Counter()
37
36
  total = Counter()
38
37
 
39
38
  organizations = Organization.objects(logo__exists=True)
40
- total['orgs'] = organizations.count()
41
- log.info('Processing {0} organizations logos'.format(total['orgs']))
39
+ total["orgs"] = organizations.count()
40
+ log.info("Processing {0} organizations logos".format(total["orgs"]))
42
41
  for org in organizations:
43
- count['orgs'] += render_or_skip(org, 'logo')
42
+ count["orgs"] += render_or_skip(org, "logo")
44
43
 
45
44
  users = User.objects(avatar__exists=True)
46
- total['users'] = users.count()
47
- log.info('Processing {0} user avatars'.format(total['users']))
45
+ total["users"] = users.count()
46
+ log.info("Processing {0} user avatars".format(total["users"]))
48
47
  for user in users:
49
- count['users'] += render_or_skip(user, 'avatar')
48
+ count["users"] += render_or_skip(user, "avatar")
50
49
 
51
50
  posts = Post.objects(image__exists=True)
52
- total['posts'] = posts.count()
53
- log.info('Processing {0} post images'.format(total['posts']))
51
+ total["posts"] = posts.count()
52
+ log.info("Processing {0} post images".format(total["posts"]))
54
53
  for post in posts:
55
- count['posts'] += render_or_skip(post, 'image')
54
+ count["posts"] += render_or_skip(post, "image")
56
55
 
57
56
  reuses = Reuse.objects(image__exists=True)
58
- total['reuses'] = reuses.count()
59
- log.info('Processing {0} reuse images'.format(total['reuses']))
57
+ total["reuses"] = reuses.count()
58
+ log.info("Processing {0} reuse images".format(total["reuses"]))
60
59
  for reuse in reuses:
61
- count['reuses'] += render_or_skip(reuse, 'image')
60
+ count["reuses"] += render_or_skip(reuse, "image")
62
61
 
63
- log.info('''Summary:
62
+ log.info(
63
+ """Summary:
64
64
  Organization logos: {count[orgs]}/{total[orgs]}
65
65
  User avatars: {count[users]}/{total[users]}
66
66
  Post images: {count[posts]}/{total[posts]}
67
67
  Reuse images: {count[reuses]}/{total[reuses]}
68
- '''.format(count=count, total=total))
69
- success('Images rendered')
68
+ """.format(count=count, total=total)
69
+ )
70
+ success("Images rendered")
udata/commands/info.py CHANGED
@@ -1,21 +1,18 @@
1
1
  import logging
2
2
 
3
3
  from click import echo
4
-
5
4
  from flask import current_app
6
5
 
7
6
  from udata import entrypoints
8
- from udata.commands import cli, white, OK, KO, green, red
9
-
7
+ from udata.commands import KO, OK, cli, green, red, white
10
8
  from udata.features.identicon.backends import get_config as avatar_config
11
9
 
12
-
13
10
  log = logging.getLogger(__name__)
14
11
 
15
12
 
16
- @cli.group('info')
13
+ @cli.group("info")
17
14
  def grp():
18
- '''Display some details about the local environment'''
15
+ """Display some details about the local environment"""
19
16
  pass
20
17
 
21
18
 
@@ -29,28 +26,28 @@ def is_active(ep, actives):
29
26
 
30
27
  @grp.command()
31
28
  def config():
32
- '''Display some details about the local configuration'''
33
- if hasattr(current_app, 'settings_file'):
34
- log.info('Loaded configuration from %s', current_app.settings_file)
29
+ """Display some details about the local configuration"""
30
+ if hasattr(current_app, "settings_file"):
31
+ log.info("Loaded configuration from %s", current_app.settings_file)
35
32
 
36
- log.info(white('Current configuration'))
33
+ log.info(white("Current configuration"))
37
34
  for key in sorted(current_app.config):
38
- if key.startswith('__') or not key.isupper():
35
+ if key.startswith("__") or not key.isupper():
39
36
  continue
40
- echo('{0}: {1}'.format(white(key), current_app.config[key]))
37
+ echo("{0}: {1}".format(white(key), current_app.config[key]))
41
38
 
42
39
 
43
40
  @grp.command()
44
41
  def plugins():
45
- '''Display some details about the local plugins'''
46
- plugins = current_app.config['PLUGINS']
42
+ """Display some details about the local plugins"""
43
+ plugins = current_app.config["PLUGINS"]
47
44
  for name, description in entrypoints.ENTRYPOINTS.items():
48
- echo('{0} ({1})'.format(white(description), name))
49
- if name == 'udata.themes':
50
- actives = [current_app.config['THEME']]
51
- elif name == 'udata.avatars':
52
- actives = [avatar_config('provider')]
45
+ echo("{0} ({1})".format(white(description), name))
46
+ if name == "udata.themes":
47
+ actives = [current_app.config["THEME"]]
48
+ elif name == "udata.avatars":
49
+ actives = [avatar_config("provider")]
53
50
  else:
54
51
  actives = plugins
55
52
  for ep in sorted(entrypoints.iter_all(name), key=by_name):
56
- echo('> {0}: {1}'.format(ep.name, is_active(ep, actives)))
53
+ echo("> {0}: {1}".format(ep.name, is_active(ep, actives)))
udata/commands/init.py CHANGED
@@ -3,7 +3,7 @@ import logging
3
3
  import click
4
4
  from flask import current_app
5
5
 
6
- from udata.commands import cli, success, IS_TTY
6
+ from udata.commands import IS_TTY, cli, success
7
7
  from udata.core.dataset.commands import licenses
8
8
  from udata.core.spatial.commands import load as spatial_load
9
9
  from udata.core.user import commands as user_commands
@@ -19,31 +19,31 @@ log = logging.getLogger(__name__)
19
19
  @cli.command()
20
20
  @click.pass_context
21
21
  def init(ctx):
22
- '''Initialize your udata instance (search index, user, sample data...)'''
22
+ """Initialize your udata instance (search index, user, sample data...)"""
23
23
 
24
- log.info('Apply DB migrations if needed')
24
+ log.info("Apply DB migrations if needed")
25
25
  ctx.invoke(migrate, record=True)
26
26
 
27
- if current_app.config['SEARCH_SERVICE_API_URL']:
28
- log.info('Preparing index')
27
+ if current_app.config["SEARCH_SERVICE_API_URL"]:
28
+ log.info("Preparing index")
29
29
  ctx.invoke(index)
30
30
 
31
31
  if IS_TTY:
32
- text = _('Do you want to create a superadmin user?')
32
+ text = _("Do you want to create a superadmin user?")
33
33
  if click.confirm(text, default=True):
34
34
  user = ctx.invoke(user_commands.create)
35
35
  ctx.invoke(user_commands.set_admin, email=user.email)
36
36
 
37
- text = _('Do you want to import some data-related license?')
37
+ text = _("Do you want to import some data-related license?")
38
38
  if click.confirm(text, default=True):
39
39
  ctx.invoke(licenses)
40
40
 
41
- text = _('Do you want to import some spatial zones (countries)?')
41
+ text = _("Do you want to import some spatial zones (countries)?")
42
42
  if click.confirm(text, default=True):
43
43
  ctx.invoke(spatial_load)
44
44
 
45
- text = _('Do you want to create some sample data?')
45
+ text = _("Do you want to create some sample data?")
46
46
  if click.confirm(text, default=True):
47
47
  ctx.invoke(generate_fixtures)
48
48
 
49
- success(_('Your udata instance is ready!'))
49
+ success(_("Your udata instance is ready!"))
udata/commands/purge.py CHANGED
@@ -3,9 +3,8 @@ import logging
3
3
  import click
4
4
 
5
5
  from udata.commands import cli, success
6
-
7
- from udata.core.dataset.tasks import purge_datasets
8
6
  from udata.core.dataservices.tasks import purge_dataservices
7
+ from udata.core.dataset.tasks import purge_datasets
9
8
  from udata.core.organization.tasks import purge_organizations
10
9
  from udata.core.reuse.tasks import purge_reuses
11
10
 
@@ -13,32 +12,32 @@ log = logging.getLogger(__name__)
13
12
 
14
13
 
15
14
  @cli.command()
16
- @click.option('-d', '--datasets', is_flag=True)
17
- @click.option('-r', '--reuses', is_flag=True)
18
- @click.option('-o', '--organizations', is_flag=True)
19
- @click.option('--dataservices', is_flag=True)
15
+ @click.option("-d", "--datasets", is_flag=True)
16
+ @click.option("-r", "--reuses", is_flag=True)
17
+ @click.option("-o", "--organizations", is_flag=True)
18
+ @click.option("--dataservices", is_flag=True)
20
19
  def purge(datasets, reuses, organizations, dataservices):
21
- '''
20
+ """
22
21
  Permanently remove data flagged as deleted.
23
22
 
24
23
  If no model flag is given, all models are purged.
25
- '''
24
+ """
26
25
  purge_all = not any((datasets, reuses, organizations, dataservices))
27
26
 
28
27
  if purge_all or datasets:
29
- log.info('Purging datasets')
28
+ log.info("Purging datasets")
30
29
  purge_datasets()
31
30
 
32
31
  if purge_all or reuses:
33
- log.info('Purging reuses')
32
+ log.info("Purging reuses")
34
33
  purge_reuses()
35
34
 
36
35
  if purge_all or organizations:
37
- log.info('Purging organizations')
36
+ log.info("Purging organizations")
38
37
  purge_organizations()
39
38
 
40
39
  if purge_all or dataservices:
41
- log.info('Purging dataservices')
40
+ log.info("Purging dataservices")
42
41
  purge_dataservices()
43
42
 
44
- success('Done')
43
+ success("Done")
udata/commands/serve.py CHANGED
@@ -2,37 +2,44 @@ import logging
2
2
  import os
3
3
 
4
4
  import click
5
-
6
5
  from flask import current_app
7
- from flask.cli import pass_script_info, DispatchingApp
8
-
6
+ from flask.cli import DispatchingApp, pass_script_info
9
7
  from werkzeug.serving import run_simple
10
8
 
11
9
  from udata.commands import cli
12
10
 
13
-
14
11
  log = logging.getLogger(__name__)
15
12
 
16
13
 
17
- @cli.command(short_help='Runs a development server.')
18
- @click.option('--host', '-h', default='127.0.0.1',
19
- help='The interface to bind to.')
20
- @click.option('--port', '-p', default=7000,
21
- help='The port to bind to.')
22
- @click.option('-r/-nr', '--reload/--no-reload', default=None,
23
- help='Enable or disable the reloader. By default the reloader '
24
- 'is active if debug is enabled.')
25
- @click.option('-d/-nd', '--debugger/--no-debugger', default=None,
26
- help='Enable or disable the debugger. By default the debugger '
27
- 'is active if debug is enabled.')
28
- @click.option('--eager-loading/--lazy-loader', default=None,
29
- help='Enable or disable eager loading. By default eager '
30
- 'loading is enabled if the reloader is disabled.')
31
- @click.option('--with-threads/--without-threads', default=True,
32
- help='Enable or disable multithreading.')
14
+ @cli.command(short_help="Runs a development server.")
15
+ @click.option("--host", "-h", default="127.0.0.1", help="The interface to bind to.")
16
+ @click.option("--port", "-p", default=7000, help="The port to bind to.")
17
+ @click.option(
18
+ "-r/-nr",
19
+ "--reload/--no-reload",
20
+ default=None,
21
+ help="Enable or disable the reloader. By default the reloader "
22
+ "is active if debug is enabled.",
23
+ )
24
+ @click.option(
25
+ "-d/-nd",
26
+ "--debugger/--no-debugger",
27
+ default=None,
28
+ help="Enable or disable the debugger. By default the debugger "
29
+ "is active if debug is enabled.",
30
+ )
31
+ @click.option(
32
+ "--eager-loading/--lazy-loader",
33
+ default=None,
34
+ help="Enable or disable eager loading. By default eager "
35
+ "loading is enabled if the reloader is disabled.",
36
+ )
37
+ @click.option(
38
+ "--with-threads/--without-threads", default=True, help="Enable or disable multithreading."
39
+ )
33
40
  @pass_script_info
34
41
  def serve(info, host, port, reload, debugger, eager_loading, with_threads):
35
- '''
42
+ """
36
43
  Runs a local udata development server.
37
44
 
38
45
  This local server is recommended for development purposes only but it
@@ -45,14 +52,14 @@ def serve(info, host, port, reload, debugger, eager_loading, with_threads):
45
52
 
46
53
  The reloader and debugger are by default enabled if the debug flag of
47
54
  Flask is enabled and disabled otherwise.
48
- '''
55
+ """
49
56
  # Werkzeug logger is special and is required
50
57
  # with this configuration for development server
51
- logger = logging.getLogger('werkzeug')
58
+ logger = logging.getLogger("werkzeug")
52
59
  logger.setLevel(logging.INFO)
53
60
  logger.handlers = []
54
61
 
55
- debug = current_app.config['DEBUG']
62
+ debug = current_app.config["DEBUG"]
56
63
  if reload is None:
57
64
  reload = bool(debug)
58
65
  if debugger is None:
@@ -62,10 +69,15 @@ def serve(info, host, port, reload, debugger, eager_loading, with_threads):
62
69
 
63
70
  app = DispatchingApp(info.load_app, use_eager_loading=eager_loading)
64
71
 
65
- settings = os.environ.get('UDATA_SETTINGS',
66
- os.path.join(os.getcwd(), 'udata.cfg'))
72
+ settings = os.environ.get("UDATA_SETTINGS", os.path.join(os.getcwd(), "udata.cfg"))
67
73
  extra_files = [settings]
68
74
 
69
- run_simple(host, port, app, use_reloader=reload,
70
- use_debugger=debugger, threaded=with_threads,
71
- extra_files=extra_files)
75
+ run_simple(
76
+ host,
77
+ port,
78
+ app,
79
+ use_reloader=reload,
80
+ use_debugger=debugger,
81
+ threaded=with_threads,
82
+ extra_files=extra_files,
83
+ )