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
@@ -2,137 +2,130 @@ import hashlib
2
2
  import io
3
3
 
4
4
  import pydenticon
5
-
6
- from flask import redirect, send_file, current_app
5
+ from flask import current_app, redirect, send_file
7
6
 
8
7
  from udata import entrypoints
9
8
  from udata.app import cache
10
9
 
11
- ADORABLE_AVATARS_URL = 'https://api.adorable.io/avatars/{size}/{identifier}.png' # noqa
12
- ROBOHASH_URL = 'https://robohash.org/{identifier}.png?size={size}x{size}&set={skin}&bgset={bg}' # noqa
10
+ ADORABLE_AVATARS_URL = "https://api.adorable.io/avatars/{size}/{identifier}.png" # noqa
11
+ ROBOHASH_URL = "https://robohash.org/{identifier}.png?size={size}x{size}&set={skin}&bgset={bg}" # noqa
13
12
 
14
13
 
15
14
  # Default values overriden by theme default and local config
16
15
  DEFAULTS = {
17
- 'AVATAR_PROVIDER': 'internal',
16
+ "AVATAR_PROVIDER": "internal",
18
17
  # Internal provider
19
- 'AVATAR_INTERNAL_SIZE': 7,
20
- 'AVATAR_INTERNAL_FOREGROUND': [
21
- 'rgb(45,79,255)',
22
- 'rgb(254,180,44)',
23
- 'rgb(226,121,234)',
24
- 'rgb(30,179,253)',
25
- 'rgb(232,77,65)',
26
- 'rgb(49,203,115)',
27
- 'rgb(141,69,170)'
18
+ "AVATAR_INTERNAL_SIZE": 7,
19
+ "AVATAR_INTERNAL_FOREGROUND": [
20
+ "rgb(45,79,255)",
21
+ "rgb(254,180,44)",
22
+ "rgb(226,121,234)",
23
+ "rgb(30,179,253)",
24
+ "rgb(232,77,65)",
25
+ "rgb(49,203,115)",
26
+ "rgb(141,69,170)",
28
27
  ],
29
- 'AVATAR_INTERNAL_BACKGROUND': 'rgb(224,224,224)',
30
- 'AVATAR_INTERNAL_PADDING': 10,
31
-
28
+ "AVATAR_INTERNAL_BACKGROUND": "rgb(224,224,224)",
29
+ "AVATAR_INTERNAL_PADDING": 10,
32
30
  # robohash prodiver
33
- 'AVATAR_ROBOHASH_SKIN': 'set1',
34
- 'AVATAR_ROBOHASH_BACKGROUND': 'bg1',
31
+ "AVATAR_ROBOHASH_SKIN": "set1",
32
+ "AVATAR_ROBOHASH_BACKGROUND": "bg1",
35
33
  }
36
34
 
37
35
 
38
36
  def get_config(key):
39
- '''
37
+ """
40
38
  Get an identicon configuration parameter.
41
39
 
42
40
  Precedance order is:
43
41
  - application config (`udata.cfg`)
44
42
  - default
45
- '''
46
- key = 'AVATAR_{0}'.format(key.upper())
43
+ """
44
+ key = "AVATAR_{0}".format(key.upper())
47
45
  local_config = current_app.config.get(key)
48
46
  return local_config or DEFAULTS[key]
49
47
 
50
48
 
51
49
  def get_internal_config(key):
52
- return get_config('internal_{0}'.format(key))
50
+ return get_config("internal_{0}".format(key))
53
51
 
54
52
 
55
53
  def get_provider():
56
- '''Get the current provider from config'''
57
- name = get_config('provider')
58
- available = entrypoints.get_all('udata.avatars')
54
+ """Get the current provider from config"""
55
+ name = get_config("provider")
56
+ available = entrypoints.get_all("udata.avatars")
59
57
  if name not in available:
60
- raise ValueError('Unknown avatar provider: {0}'.format(name))
58
+ raise ValueError("Unknown avatar provider: {0}".format(name))
61
59
  return available[name]
62
60
 
63
61
 
64
62
  def get_identicon(identifier, size):
65
- '''
63
+ """
66
64
  Get an identicon for a given identifier at a given size.
67
65
 
68
66
  Automatically select the provider from `AVATAR_PROVIDER`
69
67
 
70
68
  :returns: a HTTP response, either an image or a redirect
71
- '''
69
+ """
72
70
  return get_provider()(identifier, size)
73
71
 
74
72
 
75
73
  @cache.memoize()
76
74
  def generate_pydenticon(identifier, size):
77
- '''
75
+ """
78
76
  Use pydenticon to generate an identicon image.
79
77
  All parameters are extracted from configuration.
80
- '''
81
- blocks_size = get_internal_config('size')
82
- foreground = get_internal_config('foreground')
83
- background = get_internal_config('background')
84
- generator = pydenticon.Generator(blocks_size, blocks_size,
85
- digest=hashlib.sha1,
86
- foreground=foreground,
87
- background=background)
78
+ """
79
+ blocks_size = get_internal_config("size")
80
+ foreground = get_internal_config("foreground")
81
+ background = get_internal_config("background")
82
+ generator = pydenticon.Generator(
83
+ blocks_size, blocks_size, digest=hashlib.sha1, foreground=foreground, background=background
84
+ )
88
85
 
89
86
  # Pydenticon adds padding to the size and as a consequence
90
87
  # we need to compute the size without the padding
91
- padding = int(round(get_internal_config('padding') * size / 100.))
88
+ padding = int(round(get_internal_config("padding") * size / 100.0))
92
89
  size = size - 2 * padding
93
- padding = (padding, ) * 4
94
- return generator.generate(identifier, size, size,
95
- padding=padding,
96
- output_format='png')
90
+ padding = (padding,) * 4
91
+ return generator.generate(identifier, size, size, padding=padding, output_format="png")
97
92
 
98
93
 
99
94
  def internal(identifier, size):
100
- '''
95
+ """
101
96
  Internal provider
102
97
 
103
98
  Use pydenticon to generate an identicon.
104
- '''
99
+ """
105
100
  identicon = generate_pydenticon(identifier, size)
106
- response = send_file(io.BytesIO(identicon), mimetype='image/png')
101
+ response = send_file(io.BytesIO(identicon), mimetype="image/png")
107
102
  etag = hashlib.sha1(identicon).hexdigest()
108
103
  response.set_etag(etag)
109
104
  return response
110
105
 
111
106
 
112
107
  def adorable(identifier, size):
113
- '''
108
+ """
114
109
  Adorable Avatars provider
115
110
 
116
111
  Simply redirect to the external API.
117
112
 
118
113
  See: http://avatars.adorable.io/
119
- '''
114
+ """
120
115
  url = ADORABLE_AVATARS_URL.format(identifier=identifier, size=size)
121
116
  return redirect(url)
122
117
 
123
118
 
124
119
  def robohash(identifier, size):
125
- '''
120
+ """
126
121
  Robohash provider
127
122
 
128
123
  Redirect to the Robohash API
129
124
  with parameters extracted from configuration.
130
125
 
131
126
  See: https://robohash.org/
132
- '''
133
- skin = get_config('robohash_skin')
134
- background = get_config('robohash_background')
135
- url = ROBOHASH_URL.format(
136
- identifier=identifier, size=size, skin=skin, bg=background
137
- )
127
+ """
128
+ skin = get_config("robohash_skin")
129
+ background = get_config("robohash_background")
130
+ url = ROBOHASH_URL.format(identifier=identifier, size=size, skin=skin, bg=background)
138
131
  return redirect(url)
@@ -1,10 +1,10 @@
1
1
  import pytest
2
2
 
3
3
  from udata.features.identicon.backends import internal
4
- from udata.utils import faker
5
4
  from udata.tests.helpers import assert200
5
+ from udata.utils import faker
6
6
 
7
- pytestmark = pytest.mark.usefixtures('app')
7
+ pytestmark = pytest.mark.usefixtures("app")
8
8
 
9
9
 
10
10
  def assert_stream_equal(response1, response2):
@@ -18,12 +18,11 @@ class InternalBackendTest:
18
18
  def test_base_rendering(self):
19
19
  response = internal(faker.word(), 32)
20
20
  assert200(response)
21
- assert response.mimetype == 'image/png'
21
+ assert response.mimetype == "image/png"
22
22
  assert response.is_streamed
23
23
  etag, weak = response.get_etag()
24
24
  assert etag is not None
25
25
 
26
26
  def test_render_twice_the_same(self):
27
27
  identifier = faker.word()
28
- assert_stream_equal(internal(identifier, 32),
29
- internal(identifier, 32))
28
+ assert_stream_equal(internal(identifier, 32), internal(identifier, 32))
@@ -1,4 +1,3 @@
1
-
2
1
  import logging
3
2
 
4
3
  log = logging.getLogger(__name__)
@@ -6,32 +6,32 @@ _providers = {}
6
6
 
7
7
 
8
8
  def register_provider(name, func):
9
- '''Register a notification provder'''
9
+ """Register a notification provder"""
10
10
  _providers[name] = func
11
11
 
12
12
 
13
13
  def list_providers():
14
- '''List registere notifcation provider'''
14
+ """List registere notifcation provider"""
15
15
  return _providers.keys()
16
16
 
17
17
 
18
18
  def notifier(name):
19
- '''A decorator registering a function as provider'''
19
+ """A decorator registering a function as provider"""
20
+
20
21
  def wrapper(func):
21
22
  register_provider(name, func)
22
23
  return func
24
+
23
25
  return wrapper
24
26
 
25
27
 
26
28
  def get_notifications(user):
27
- '''List notification for a given user'''
29
+ """List notification for a given user"""
28
30
  notifications = []
29
31
 
30
32
  for name, func in _providers.items():
31
- notifications.extend([{
32
- 'type': name,
33
- 'created_on': dt,
34
- 'details': details
35
- } for dt, details in func(user)])
33
+ notifications.extend(
34
+ [{"type": name, "created_on": dt, "details": details} for dt, details in func(user)]
35
+ )
36
36
 
37
37
  return notifications
@@ -1,26 +1,30 @@
1
- from udata.api import api, fields, API
1
+ from udata.api import API, api, fields
2
2
  from udata.auth import current_user
3
3
 
4
4
  from .actions import get_notifications
5
5
 
6
- notifs = api.namespace('notifications', 'Notifications API')
6
+ notifs = api.namespace("notifications", "Notifications API")
7
7
 
8
- notifications_fields = api.model('Notification', {
9
- 'type': fields.String(description='The notification type', readonly=True),
10
- 'created_on': fields.ISODateTime(
11
- description='The notification creation datetime', readonly=True),
12
- 'details': fields.Raw(
13
- description='Key-Value details depending on notification type',
14
- readonly=True)
15
- })
8
+ notifications_fields = api.model(
9
+ "Notification",
10
+ {
11
+ "type": fields.String(description="The notification type", readonly=True),
12
+ "created_on": fields.ISODateTime(
13
+ description="The notification creation datetime", readonly=True
14
+ ),
15
+ "details": fields.Raw(
16
+ description="Key-Value details depending on notification type", readonly=True
17
+ ),
18
+ },
19
+ )
16
20
 
17
21
 
18
- @notifs.route('/', endpoint='notifications')
22
+ @notifs.route("/", endpoint="notifications")
19
23
  class NotificationsAPI(API):
20
24
  @api.secure
21
- @api.doc('get_notifications')
25
+ @api.doc("get_notifications")
22
26
  @api.marshal_list_with(notifications_fields)
23
27
  def get(self):
24
- '''List all current user pending notifications'''
28
+ """List all current user pending notifications"""
25
29
  user = current_user._get_current_object()
26
30
  return get_notifications(user)
@@ -1,6 +1,6 @@
1
1
  from flask import current_app
2
2
 
3
- from udata.models import db, GeoZone
3
+ from udata.models import GeoZone, db
4
4
 
5
5
 
6
6
  def check_for_territories(query):
@@ -9,26 +9,28 @@ def check_for_territories(query):
9
9
 
10
10
  Results are sorted by population and area (biggest first).
11
11
  """
12
- if not query or not current_app.config.get('ACTIVATE_TERRITORIES'):
12
+ if not query or not current_app.config.get("ACTIVATE_TERRITORIES"):
13
13
  return []
14
14
 
15
15
  dbqs = db.Q()
16
16
  query = query.lower()
17
17
  is_digit = query.isdigit()
18
18
  query_length = len(query)
19
- for level in current_app.config.get('HANDLED_LEVELS'):
20
- if level == 'country':
19
+ for level in current_app.config.get("HANDLED_LEVELS"):
20
+ if level == "country":
21
21
  continue # Level not fully handled yet.
22
22
  q = db.Q(level=level)
23
- if (query_length == 2 and level == 'fr:departement' and
24
- (is_digit or query in ('2a', '2b'))):
23
+ if query_length == 2 and level == "fr:departement" and (is_digit or query in ("2a", "2b")):
25
24
  # Counties + Corsica.
26
25
  q &= db.Q(code=query)
27
- elif query_length == 3 and level == 'fr:departement' and is_digit:
26
+ elif query_length == 3 and level == "fr:departement" and is_digit:
28
27
  # French DROM-COM.
29
28
  q &= db.Q(code=query)
30
- elif query_length == 5 and level == 'fr:commune' and (
31
- is_digit or query.startswith('2a') or query.startswith('2b')):
29
+ elif (
30
+ query_length == 5
31
+ and level == "fr:commune"
32
+ and (is_digit or query.startswith("2a") or query.startswith("2b"))
33
+ ):
32
34
  # INSEE code then postal codes with Corsica exceptions.
33
35
  q &= db.Q(code=query)
34
36
  elif query_length >= 4:
@@ -44,4 +46,4 @@ def check_for_territories(query):
44
46
  return []
45
47
 
46
48
  # Sort matching results by population and area.
47
- return GeoZone.objects(dbqs).order_by('-population', '-area')
49
+ return GeoZone.objects(dbqs).order_by("-population", "-area")
@@ -1,26 +1,25 @@
1
- from udata.api import api, API
1
+ from udata.api import API, api
2
2
  from udata.features.territories import check_for_territories
3
3
 
4
4
  suggest_parser = api.parser()
5
5
  suggest_parser.add_argument(
6
- 'q', type=str, help='The string to autocomplete/suggest',
7
- location='args', required=True)
6
+ "q", type=str, help="The string to autocomplete/suggest", location="args", required=True
7
+ )
8
8
  suggest_parser.add_argument(
9
- 'size', type=int, help='The maximum result size',
10
- location='args', required=False)
9
+ "size", type=int, help="The maximum result size", location="args", required=False
10
+ )
11
11
 
12
12
 
13
- @api.route('/territory/suggest/', endpoint='suggest_territory')
13
+ @api.route("/territory/suggest/", endpoint="suggest_territory")
14
14
  class SuggestTerritoriesAPI(API):
15
- @api.doc('suggest_territory')
15
+ @api.doc("suggest_territory")
16
16
  @api.expect(suggest_parser)
17
17
  def get(self):
18
18
  args = suggest_parser.parse_args()
19
- territories = check_for_territories(args['q'])
20
- if args['size']:
21
- territories = territories[:args['size']]
22
- return [{
23
- 'id': territory.id,
24
- 'title': territory.name,
25
- 'page': territory.external_url
26
- } for territory in territories]
19
+ territories = check_for_territories(args["q"])
20
+ if args["size"]:
21
+ territories = territories[: args["size"]]
22
+ return [
23
+ {"id": territory.id, "title": territory.name, "page": territory.external_url}
24
+ for territory in territories
25
+ ]
@@ -2,27 +2,20 @@ from flask import url_for
2
2
 
3
3
  from udata.models import License, Organization
4
4
 
5
- __all__ = (
6
- 'TerritoryDataset', 'ResourceBasedTerritoryDataset', 'TERRITORY_DATASETS'
7
- )
5
+ __all__ = ("TerritoryDataset", "ResourceBasedTerritoryDataset", "TERRITORY_DATASETS")
8
6
 
9
7
 
10
- TERRITORY_DATASETS = {
11
- 'commune': {},
12
- 'departement': {},
13
- 'region': {},
14
- 'country': {}
15
- }
8
+ TERRITORY_DATASETS = {"commune": {}, "departement": {}, "region": {}, "country": {}}
16
9
 
17
10
 
18
11
  class TerritoryDataset(object):
19
12
  order = 0
20
- id = ''
21
- title = ''
22
- organization_id = ''
23
- url_template = ''
24
- description = ''
25
- license_id = 'fr-lo'
13
+ id = ""
14
+ title = ""
15
+ organization_id = ""
16
+ url_template = ""
17
+ description = ""
18
+ license_id = "fr-lo"
26
19
 
27
20
  def __init__(self, territory):
28
21
  self.territory = territory
@@ -33,8 +26,7 @@ class TerritoryDataset(object):
33
26
 
34
27
  @property
35
28
  def slug(self):
36
- return '{territory_id}:{id}'.format(
37
- territory_id=self.territory.id, id=self.id)
29
+ return "{territory_id}:{id}".format(territory_id=self.territory.id, id=self.id)
38
30
 
39
31
  @property
40
32
  def organization(self):
@@ -46,19 +38,22 @@ class TerritoryDataset(object):
46
38
 
47
39
 
48
40
  class ResourceBasedTerritoryDataset(TerritoryDataset):
49
- dataset_id = ''
50
- resource_id = ''
51
- territory_attr = ''
52
- csv_column = ''
41
+ dataset_id = ""
42
+ resource_id = ""
43
+ territory_attr = ""
44
+ csv_column = ""
53
45
 
54
46
  def url_for(self, external=False):
55
- return url_for('territories.territory_dataset_resource',
56
- territory=self.territory,
57
- dataset=self.dataset_id,
58
- resource_id=self.resource_id,
59
- territory_attr=self.territory_attr,
60
- csv_column=self.csv_column,
61
- _external=external)
47
+ return url_for(
48
+ "territories.territory_dataset_resource",
49
+ territory=self.territory,
50
+ dataset=self.dataset_id,
51
+ resource_id=self.resource_id,
52
+ territory_attr=self.territory_attr,
53
+ csv_column=self.csv_column,
54
+ _external=external,
55
+ )
56
+
62
57
  url = property(url_for)
63
58
 
64
59
  @property
@@ -1,9 +1,7 @@
1
1
  import logging
2
-
3
2
  from datetime import datetime
4
3
 
5
-
6
- from udata.auth import login_required, current_user
4
+ from udata.auth import current_user, login_required
7
5
  from udata.models import Organization, User
8
6
 
9
7
  from .models import Transfer
@@ -14,28 +12,27 @@ log = logging.getLogger(__name__)
14
12
 
15
13
  @login_required
16
14
  def request_transfer(subject, recipient, comment):
17
- '''Initiate a transfer request'''
15
+ """Initiate a transfer request"""
18
16
  TransferPermission(subject).test()
19
17
  if recipient == (subject.organization or subject.owner):
20
- raise ValueError(
21
- 'Recipient should be different than the current owner')
18
+ raise ValueError("Recipient should be different than the current owner")
22
19
  transfer = Transfer.objects.create(
23
20
  owner=subject.organization or subject.owner,
24
21
  recipient=recipient,
25
22
  subject=subject,
26
- comment=comment
23
+ comment=comment,
27
24
  )
28
25
  return transfer
29
26
 
30
27
 
31
28
  @login_required
32
29
  def accept_transfer(transfer, comment=None):
33
- '''Accept an incoming a transfer request'''
30
+ """Accept an incoming a transfer request"""
34
31
  TransferResponsePermission(transfer).test()
35
32
 
36
33
  transfer.responded = datetime.utcnow()
37
34
  transfer.responder = current_user._get_current_object()
38
- transfer.status = 'accepted'
35
+ transfer.status = "accepted"
39
36
  transfer.response_comment = comment
40
37
  transfer.save()
41
38
 
@@ -53,12 +50,12 @@ def accept_transfer(transfer, comment=None):
53
50
 
54
51
  @login_required
55
52
  def refuse_transfer(transfer, comment=None):
56
- '''Refuse an incoming a transfer request'''
53
+ """Refuse an incoming a transfer request"""
57
54
  TransferResponsePermission(transfer).test()
58
55
 
59
56
  transfer.responded = datetime.utcnow()
60
57
  transfer.responder = current_user._get_current_object()
61
- transfer.status = 'refused'
58
+ transfer.status = "refused"
62
59
  transfer.response_comment = comment
63
60
  transfer.save()
64
61