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,103 +1,138 @@
1
- from udata.api import api, fields, base_reference
2
-
1
+ from udata.api import api, base_reference, fields
3
2
  from udata.core.badges.fields import badge_fields
4
3
  from udata.core.dataset.api_fields import dataset_fields
5
4
  from udata.core.organization.api_fields import org_ref_fields
6
5
  from udata.core.user.api_fields import user_ref_fields
7
6
 
8
- from .constants import REUSE_TOPICS, REUSE_TYPES, IMAGE_SIZES
7
+ from .constants import IMAGE_SIZES, REUSE_TOPICS, REUSE_TYPES
9
8
 
10
9
  BIGGEST_IMAGE_SIZE = IMAGE_SIZES[0]
11
10
 
12
11
 
13
- reuse_fields = api.model('Reuse', {
14
- 'id': fields.String(description='The reuse identifier', readonly=True),
15
- 'title': fields.String(description='The reuse title', required=True),
16
- 'slug': fields.String(
17
- description='The reuse permalink string', readonly=True),
18
- 'type': fields.String(
19
- description='The reuse type', required=True, enum=list(REUSE_TYPES)),
20
- 'url': fields.String(
21
- description='The reuse remote URL (website)', required=True),
22
- 'description': fields.Markdown(
23
- description='The reuse description in Markdown', required=True),
24
- 'tags': fields.List(
25
- fields.String, description='Some keywords to help in search'),
26
- 'badges': fields.List(fields.Nested(badge_fields),
27
- description='The reuse badges',
28
- readonly=True),
29
- 'topic': fields.String(
30
- description='The reuse topic', required=True, enum=list(REUSE_TOPICS)),
31
- 'featured': fields.Boolean(
32
- description='Is the reuse featured', readonly=True),
33
- 'private': fields.Boolean(
34
- description='Is the reuse private to the owner or the organization'),
35
- 'image': fields.ImageField(description='The reuse thumbnail thumbnail (cropped) URL'),
36
- 'image_thumbnail': fields.ImageField(attribute='image', size=BIGGEST_IMAGE_SIZE,
37
- description='The reuse thumbnail thumbnail URL. This is the square '
38
- '({0}x{0}) and cropped version.'.format(BIGGEST_IMAGE_SIZE)),
39
- 'created_at': fields.ISODateTime(
40
- description='The reuse creation date', readonly=True),
41
- 'last_modified': fields.ISODateTime(
42
- description='The reuse last modification date', readonly=True),
43
- 'deleted': fields.ISODateTime(
44
- description='The deletion date if deleted', readonly=True),
45
- 'datasets': fields.List(
46
- fields.Nested(dataset_fields), description='The reused datasets'),
47
- 'organization': fields.Nested(
48
- org_ref_fields, allow_null=True,
49
- description='The publishing organization', readonly=True),
50
- 'owner': fields.Nested(
51
- user_ref_fields, description='The owner user', readonly=True,
52
- allow_null=True),
53
- 'metrics': fields.Raw(attribute=lambda o: o.get_metrics(),
54
- description='The reuse metrics', readonly=True),
55
- 'uri': fields.UrlFor(
56
- 'api.reuse', lambda o: {'reuse': o},
57
- description='The reuse API URI', readonly=True),
58
- 'page': fields.UrlFor(
59
- 'reuses.show', lambda o: {'reuse': o},
60
- description='The reuse page URL', readonly=True, fallback_endpoint='api.reuse'),
61
- 'extras': fields.Raw(description='Extras attributes as key-value pairs'),
62
- }, mask='*,datasets{title,uri,page}')
12
+ reuse_fields = api.model(
13
+ "Reuse",
14
+ {
15
+ "id": fields.String(description="The reuse identifier", readonly=True),
16
+ "title": fields.String(description="The reuse title", required=True),
17
+ "slug": fields.String(description="The reuse permalink string", readonly=True),
18
+ "type": fields.String(description="The reuse type", required=True, enum=list(REUSE_TYPES)),
19
+ "url": fields.String(description="The reuse remote URL (website)", required=True),
20
+ "description": fields.Markdown(
21
+ description="The reuse description in Markdown", required=True
22
+ ),
23
+ "tags": fields.List(fields.String, description="Some keywords to help in search"),
24
+ "badges": fields.List(
25
+ fields.Nested(badge_fields), description="The reuse badges", readonly=True
26
+ ),
27
+ "topic": fields.String(
28
+ description="The reuse topic", required=True, enum=list(REUSE_TOPICS)
29
+ ),
30
+ "featured": fields.Boolean(description="Is the reuse featured", readonly=True),
31
+ "private": fields.Boolean(
32
+ description="Is the reuse private to the owner or the organization"
33
+ ),
34
+ "image": fields.ImageField(description="The reuse thumbnail thumbnail (cropped) URL"),
35
+ "image_thumbnail": fields.ImageField(
36
+ attribute="image",
37
+ size=BIGGEST_IMAGE_SIZE,
38
+ description="The reuse thumbnail thumbnail URL. This is the square "
39
+ "({0}x{0}) and cropped version.".format(BIGGEST_IMAGE_SIZE),
40
+ ),
41
+ "created_at": fields.ISODateTime(description="The reuse creation date", readonly=True),
42
+ "last_modified": fields.ISODateTime(
43
+ description="The reuse last modification date", readonly=True
44
+ ),
45
+ "deleted": fields.ISODateTime(description="The deletion date if deleted", readonly=True),
46
+ "datasets": fields.List(fields.Nested(dataset_fields), description="The reused datasets"),
47
+ "organization": fields.Nested(
48
+ org_ref_fields,
49
+ allow_null=True,
50
+ description="The publishing organization",
51
+ readonly=True,
52
+ ),
53
+ "owner": fields.Nested(
54
+ user_ref_fields, description="The owner user", readonly=True, allow_null=True
55
+ ),
56
+ "metrics": fields.Raw(
57
+ attribute=lambda o: o.get_metrics(), description="The reuse metrics", readonly=True
58
+ ),
59
+ "uri": fields.UrlFor(
60
+ "api.reuse", lambda o: {"reuse": o}, description="The reuse API URI", readonly=True
61
+ ),
62
+ "page": fields.UrlFor(
63
+ "reuses.show",
64
+ lambda o: {"reuse": o},
65
+ description="The reuse page URL",
66
+ readonly=True,
67
+ fallback_endpoint="api.reuse",
68
+ ),
69
+ "extras": fields.Raw(description="Extras attributes as key-value pairs"),
70
+ },
71
+ mask="*,datasets{title,uri,page}",
72
+ )
63
73
 
64
- reuse_page_fields = api.model('ReusePage', fields.pager(reuse_fields))
74
+ reuse_page_fields = api.model("ReusePage", fields.pager(reuse_fields))
65
75
 
66
76
 
67
- reuse_ref_fields = api.inherit('ReuseReference', base_reference, {
68
- 'title': fields.String(description='The reuse title', readonly=True),
69
- 'image': fields.ImageField(description='The reuse thumbnail thumbnail (cropped) URL'),
70
- 'image_thumbnail': fields.ImageField(attribute='image', size=BIGGEST_IMAGE_SIZE,
71
- description='The reuse thumbnail thumbnail URL. This is the square '
72
- '({0}x{0}) and cropped version.'.format(BIGGEST_IMAGE_SIZE)),
73
- 'uri': fields.UrlFor(
74
- 'api.reuse', lambda o: {'reuse': o},
75
- description='The reuse API URI', readonly=True),
76
- 'page': fields.UrlFor(
77
- 'reuses.show', lambda o: {'reuse': o},
78
- description='The reuse page URL', readonly=True, fallback_endpoint='api.reuse'),
79
- })
77
+ reuse_ref_fields = api.inherit(
78
+ "ReuseReference",
79
+ base_reference,
80
+ {
81
+ "title": fields.String(description="The reuse title", readonly=True),
82
+ "image": fields.ImageField(description="The reuse thumbnail thumbnail (cropped) URL"),
83
+ "image_thumbnail": fields.ImageField(
84
+ attribute="image",
85
+ size=BIGGEST_IMAGE_SIZE,
86
+ description="The reuse thumbnail thumbnail URL. This is the square "
87
+ "({0}x{0}) and cropped version.".format(BIGGEST_IMAGE_SIZE),
88
+ ),
89
+ "uri": fields.UrlFor(
90
+ "api.reuse", lambda o: {"reuse": o}, description="The reuse API URI", readonly=True
91
+ ),
92
+ "page": fields.UrlFor(
93
+ "reuses.show",
94
+ lambda o: {"reuse": o},
95
+ description="The reuse page URL",
96
+ readonly=True,
97
+ fallback_endpoint="api.reuse",
98
+ ),
99
+ },
100
+ )
80
101
 
81
102
 
82
- reuse_type_fields = api.model('ReuseType', {
83
- 'id': fields.String(description='The reuse type identifier'),
84
- 'label': fields.String(description='The reuse type display name')
85
- })
103
+ reuse_type_fields = api.model(
104
+ "ReuseType",
105
+ {
106
+ "id": fields.String(description="The reuse type identifier"),
107
+ "label": fields.String(description="The reuse type display name"),
108
+ },
109
+ )
86
110
 
87
111
 
88
- reuse_suggestion_fields = api.model('ReuseSuggestion', {
89
- 'id': fields.String(description='The reuse identifier', readonly=True),
90
- 'title': fields.String(description='The reuse title', readonly=True),
91
- 'slug': fields.String(
92
- description='The reuse permalink string', readonly=True),
93
- 'image_url': fields.ImageField(size=BIGGEST_IMAGE_SIZE, description='The reuse thumbnail URL', readonly=True),
94
- 'page': fields.UrlFor(
95
- 'reuses.show_redirect', lambda o: {'reuse': o['slug']},
96
- description='The reuse page URL', readonly=True, fallback_endpoint='api.reuse')
97
- })
112
+ reuse_suggestion_fields = api.model(
113
+ "ReuseSuggestion",
114
+ {
115
+ "id": fields.String(description="The reuse identifier", readonly=True),
116
+ "title": fields.String(description="The reuse title", readonly=True),
117
+ "slug": fields.String(description="The reuse permalink string", readonly=True),
118
+ "image_url": fields.ImageField(
119
+ size=BIGGEST_IMAGE_SIZE, description="The reuse thumbnail URL", readonly=True
120
+ ),
121
+ "page": fields.UrlFor(
122
+ "reuses.show_redirect",
123
+ lambda o: {"reuse": o["slug"]},
124
+ description="The reuse page URL",
125
+ readonly=True,
126
+ fallback_endpoint="api.reuse",
127
+ ),
128
+ },
129
+ )
98
130
 
99
131
 
100
- reuse_topic_fields = api.model('ReuseTopic', {
101
- 'id': fields.String(description='The reuse topic identifier'),
102
- 'label': fields.String(description='The reuse topic display name')
103
- })
132
+ reuse_topic_fields = api.model(
133
+ "ReuseTopic",
134
+ {
135
+ "id": fields.String(description="The reuse topic identifier"),
136
+ "label": fields.String(description="The reuse topic display name"),
137
+ },
138
+ )
udata/core/reuse/apiv2.py CHANGED
@@ -1,29 +1,30 @@
1
1
  from flask import request
2
2
 
3
3
  from udata import search
4
- from udata.api import apiv2, API
4
+ from udata.api import API, apiv2
5
5
  from udata.utils import multi_to_dict
6
6
 
7
- from .api_fields import reuse_page_fields, reuse_fields
7
+ from .api_fields import reuse_fields, reuse_page_fields
8
8
  from .search import ReuseSearch
9
9
 
10
- apiv2.inherit('ReusePage', reuse_page_fields)
11
- apiv2.inherit('Reuse', reuse_fields)
10
+ apiv2.inherit("ReusePage", reuse_page_fields)
11
+ apiv2.inherit("Reuse", reuse_fields)
12
12
 
13
- ns = apiv2.namespace('reuses', 'Reuse related operations')
13
+ ns = apiv2.namespace("reuses", "Reuse related operations")
14
14
 
15
15
  search_parser = ReuseSearch.as_request_parser()
16
16
 
17
- DEFAULT_SORTING = '-created_at'
17
+ DEFAULT_SORTING = "-created_at"
18
18
 
19
19
 
20
- @ns.route('/search/', endpoint='reuse_search')
20
+ @ns.route("/search/", endpoint="reuse_search")
21
21
  class ReuseSearchAPI(API):
22
- '''Reuses collection search endpoint'''
23
- @apiv2.doc('search_reuses')
22
+ """Reuses collection search endpoint"""
23
+
24
+ @apiv2.doc("search_reuses")
24
25
  @apiv2.expect(search_parser)
25
26
  @apiv2.marshal_with(reuse_page_fields)
26
27
  def get(self):
27
- '''Search all reuses'''
28
+ """Search all reuses"""
28
29
  search_parser.parse_args()
29
30
  return search.query(ReuseSearch, **multi_to_dict(request.args))
@@ -1,32 +1,32 @@
1
1
  from udata.i18n import lazy_gettext as _
2
2
 
3
3
  REUSE_TYPES = {
4
- 'api': _('API'),
5
- 'application': _('Application'),
6
- 'idea': _('Idea'),
7
- 'news_article': _('News Article'),
8
- 'paper': _('Paper'),
9
- 'post': _('Post'),
10
- 'visualization': _('Visualization'),
11
- 'hardware': _('Connected device'),
4
+ "api": _("API"),
5
+ "application": _("Application"),
6
+ "idea": _("Idea"),
7
+ "news_article": _("News Article"),
8
+ "paper": _("Paper"),
9
+ "post": _("Post"),
10
+ "visualization": _("Visualization"),
11
+ "hardware": _("Connected device"),
12
12
  }
13
13
 
14
14
  REUSE_TOPICS = {
15
- 'health': _('Health'),
16
- 'transport_and_mobility': _('Transport and mobility'),
17
- 'housing_and_development': _('Housing and development'),
18
- 'food_and_agriculture': _('Food and agriculture'),
19
- 'culture_and_recreation': _('Culture and recreation'),
20
- 'economy_and_business': _('Economy and business'),
21
- 'environment_and_energy': _('Environment and energy'),
22
- 'work_and_training': _('Work and training'),
23
- 'politics_and_public_life': _('Politics and public life'),
24
- 'safety_and_security': _('Safety and security'),
25
- 'education_and_research': _('Education and research'),
26
- 'society_and_demography': _('Society and demography'),
27
- 'law_and_justice': _('Law and justice'),
28
- 'open_data_tools': _('Open data tools'),
29
- 'others': _('Others'),
15
+ "health": _("Health"),
16
+ "transport_and_mobility": _("Transport and mobility"),
17
+ "housing_and_development": _("Housing and development"),
18
+ "food_and_agriculture": _("Food and agriculture"),
19
+ "culture_and_recreation": _("Culture and recreation"),
20
+ "economy_and_business": _("Economy and business"),
21
+ "environment_and_energy": _("Environment and energy"),
22
+ "work_and_training": _("Work and training"),
23
+ "politics_and_public_life": _("Politics and public life"),
24
+ "safety_and_security": _("Safety and security"),
25
+ "education_and_research": _("Education and research"),
26
+ "society_and_demography": _("Society and demography"),
27
+ "law_and_justice": _("Law and justice"),
28
+ "open_data_tools": _("Open data tools"),
29
+ "others": _("Others"),
30
30
  }
31
31
 
32
32
 
udata/core/reuse/csv.py CHANGED
@@ -6,24 +6,24 @@ from .models import Reuse
6
6
  @csv.adapter(Reuse)
7
7
  class ReuseCsvAdapter(csv.Adapter):
8
8
  fields = (
9
- 'id',
10
- 'title',
11
- 'slug',
12
- ('url', 'external_url'),
13
- 'type',
14
- 'description',
15
- ('remote_url', 'url'),
16
- ('organization', 'organization.name'),
17
- ('organization_id', 'organization.id'),
18
- ('owner', 'owner.slug'), # in case it's owned by a user
19
- ('owner_id', 'owner.id'),
20
- ('image', lambda r: r.image(external=True)),
21
- ('featured', lambda r: r.featured or False),
22
- 'created_at',
23
- 'last_modified',
24
- 'topic',
25
- ('tags', lambda r: ','.join(r.tags)),
26
- ('datasets', lambda r: ','.join([str(d.id) for d in r.datasets])),
9
+ "id",
10
+ "title",
11
+ "slug",
12
+ ("url", "external_url"),
13
+ "type",
14
+ "description",
15
+ ("remote_url", "url"),
16
+ ("organization", "organization.name"),
17
+ ("organization_id", "organization.id"),
18
+ ("owner", "owner.slug"), # in case it's owned by a user
19
+ ("owner_id", "owner.id"),
20
+ ("image", lambda r: r.image(external=True)),
21
+ ("featured", lambda r: r.featured or False),
22
+ "created_at",
23
+ "last_modified",
24
+ "topic",
25
+ ("tags", lambda r: ",".join(r.tags)),
26
+ ("datasets", lambda r: ",".join([str(d.id) for d in r.datasets])),
27
27
  )
28
28
 
29
29
  def dynamic_fields(self):
@@ -1,30 +1,26 @@
1
1
  import factory
2
-
3
2
  from factory.fuzzy import FuzzyChoice
4
3
 
5
4
  from udata.core.dataset.factories import DatasetFactory
6
5
  from udata.factories import ModelFactory
7
6
  from udata.utils import faker
8
7
 
8
+ from .constants import REUSE_TOPICS, REUSE_TYPES
9
9
  from .models import Reuse
10
- from .constants import REUSE_TYPES, REUSE_TOPICS
11
10
 
12
11
 
13
12
  class ReuseFactory(ModelFactory):
14
13
  class Meta:
15
14
  model = Reuse
16
15
 
17
- title = factory.Faker('sentence')
18
- description = factory.Faker('text')
19
- url = factory.LazyAttribute(
20
- lambda o: '/'.join([faker.url(), faker.unique_string()]))
16
+ title = factory.Faker("sentence")
17
+ description = factory.Faker("text")
18
+ url = factory.LazyAttribute(lambda o: "/".join([faker.url(), faker.unique_string()]))
21
19
  type = FuzzyChoice(REUSE_TYPES.keys())
22
20
  topic = FuzzyChoice(REUSE_TOPICS.keys())
23
21
 
24
22
  class Params:
25
- visible = factory.Trait(
26
- datasets=factory.LazyAttribute(lambda o: [DatasetFactory()])
27
- )
23
+ visible = factory.Trait(datasets=factory.LazyAttribute(lambda o: [DatasetFactory()]))
28
24
 
29
25
 
30
26
  class VisibleReuseFactory(ReuseFactory):
udata/core/reuse/forms.py CHANGED
@@ -1,41 +1,44 @@
1
+ from udata.core.reuse.constants import REUSE_TOPICS, REUSE_TYPES
1
2
  from udata.forms import ModelForm, fields, validators
2
3
  from udata.i18n import lazy_gettext as _
3
4
  from udata.models import Reuse
4
- from udata.core.reuse.constants import REUSE_TYPES, REUSE_TOPICS
5
5
 
6
- from .constants import IMAGE_SIZES, TITLE_SIZE_LIMIT, DESCRIPTION_SIZE_LIMIT
6
+ from .constants import DESCRIPTION_SIZE_LIMIT, IMAGE_SIZES, TITLE_SIZE_LIMIT
7
7
 
8
- __all__ = ('ReuseForm', )
8
+ __all__ = ("ReuseForm",)
9
9
 
10
10
 
11
11
  def check_url_does_not_exists(form, field):
12
- '''Ensure a reuse URL is not yet registered'''
12
+ """Ensure a reuse URL is not yet registered"""
13
13
  if field.data != field.object_data and Reuse.url_exists(field.data):
14
- raise validators.ValidationError(_('This URL is already registered'))
14
+ raise validators.ValidationError(_("This URL is already registered"))
15
15
 
16
16
 
17
17
  class ReuseForm(ModelForm):
18
18
  model_class = Reuse
19
19
 
20
- title = fields.StringField(_('Title'), [validators.DataRequired(), validators.Length(max=TITLE_SIZE_LIMIT)])
20
+ title = fields.StringField(
21
+ _("Title"), [validators.DataRequired(), validators.Length(max=TITLE_SIZE_LIMIT)]
22
+ )
21
23
  description = fields.MarkdownField(
22
- _('Description'), [validators.DataRequired(), validators.Length(max=DESCRIPTION_SIZE_LIMIT)],
23
- description=_('The details about the reuse (build process, specifics, '
24
- 'self-critics...).'))
25
- type = fields.SelectField(_('Type'), choices=list(REUSE_TYPES.items()))
26
- url = fields.URLField(
27
- _('URL'), [validators.DataRequired(), check_url_does_not_exists])
28
- image = fields.ImageField(
29
- _('Image'), sizes=IMAGE_SIZES, placeholder='reuse')
30
- tags = fields.TagField(_('Tags'), description=_('Some taxonomy keywords'))
31
- datasets = fields.DatasetListField(_('Used datasets'))
24
+ _("Description"),
25
+ [validators.DataRequired(), validators.Length(max=DESCRIPTION_SIZE_LIMIT)],
26
+ description=_(
27
+ "The details about the reuse (build process, specifics, " "self-critics...)."
28
+ ),
29
+ )
30
+ type = fields.SelectField(_("Type"), choices=list(REUSE_TYPES.items()))
31
+ url = fields.URLField(_("URL"), [validators.DataRequired(), check_url_does_not_exists])
32
+ image = fields.ImageField(_("Image"), sizes=IMAGE_SIZES, placeholder="reuse")
33
+ tags = fields.TagField(_("Tags"), description=_("Some taxonomy keywords"))
34
+ datasets = fields.DatasetListField(_("Used datasets"))
32
35
  private = fields.BooleanField(
33
- _('Private'),
34
- description=_('Restrict the dataset visibility to you or '
35
- 'your organization only.'))
36
- topic = fields.SelectField(_('Topic'), choices=list(REUSE_TOPICS.items()))
36
+ _("Private"),
37
+ description=_("Restrict the dataset visibility to you or " "your organization only."),
38
+ )
39
+ topic = fields.SelectField(_("Topic"), choices=list(REUSE_TOPICS.items()))
37
40
 
38
41
  owner = fields.CurrentUserField()
39
- organization = fields.PublishAsField(_('Publish as'))
42
+ organization = fields.PublishAsField(_("Publish as"))
40
43
  deleted = fields.DateTimeField()
41
44
  extras = fields.ExtrasField()