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
udata/sitemap.py CHANGED
@@ -1,13 +1,13 @@
1
1
  from functools import wraps
2
+
2
3
  from flask import current_app, request
3
4
  from flask_sitemap import Sitemap, sitemap_page_needed
4
5
 
5
6
  from udata.app import cache
6
7
 
7
-
8
8
  sitemap = Sitemap()
9
9
 
10
- CACHE_KEY = 'sitemap-page-{0}'
10
+ CACHE_KEY = "sitemap-page-{0}"
11
11
 
12
12
 
13
13
  @sitemap_page_needed.connect
@@ -19,22 +19,24 @@ def create_page(app, page, urlset):
19
19
  def load_page(fn):
20
20
  @wraps(fn)
21
21
  def loader(*args, **kwargs):
22
- page = kwargs.get('page')
22
+ page = kwargs.get("page")
23
23
  key = CACHE_KEY.format(page)
24
24
  return cache.get(key) or fn(*args, **kwargs)
25
+
25
26
  return loader
26
27
 
27
28
 
28
29
  def set_scheme(fn):
29
30
  @wraps(fn)
30
31
  def set_scheme_on_call(*args, **kwargs):
31
- scheme = 'https' if request.is_secure else 'http'
32
- current_app.config['SITEMAP_URL_SCHEME'] = scheme
32
+ scheme = "https" if request.is_secure else "http"
33
+ current_app.config["SITEMAP_URL_SCHEME"] = scheme
33
34
  return fn(*args, **kwargs)
35
+
34
36
  return set_scheme_on_call
35
37
 
36
38
 
37
39
  def init_app(app):
38
40
  sitemap.decorators = []
39
- app.config['SITEMAP_VIEW_DECORATORS'] = [load_page, set_scheme]
41
+ app.config["SITEMAP_VIEW_DECORATORS"] = [load_page, set_scheme]
40
42
  sitemap.init_app(app)
udata/storage/s3.py CHANGED
@@ -1,20 +1,22 @@
1
+ import json
1
2
  from typing import Any
3
+
2
4
  import boto3
3
5
  from flask import current_app
4
- import json
6
+
5
7
 
6
8
  def get_client():
7
- url = current_app.config.get('S3_URL')
9
+ url = current_app.config.get("S3_URL")
8
10
  if url is None:
9
- raise ValueError('No S3_URL provided')
10
-
11
- access_key_id = current_app.config.get('S3_ACCESS_KEY_ID')
11
+ raise ValueError("No S3_URL provided")
12
+
13
+ access_key_id = current_app.config.get("S3_ACCESS_KEY_ID")
12
14
  if access_key_id is None:
13
- raise ValueError('No S3_ACCESS_KEY_ID provided')
14
-
15
- secret_access_key = current_app.config.get('S3_SECRET_ACCESS_KEY')
15
+ raise ValueError("No S3_ACCESS_KEY_ID provided")
16
+
17
+ secret_access_key = current_app.config.get("S3_SECRET_ACCESS_KEY")
16
18
  if secret_access_key is None:
17
- raise ValueError('No S3_SECRET_ACCESS_KEY provided')
19
+ raise ValueError("No S3_SECRET_ACCESS_KEY provided")
18
20
 
19
21
  return boto3.client(
20
22
  "s3",
@@ -23,6 +25,7 @@ def get_client():
23
25
  aws_secret_access_key=secret_access_key,
24
26
  )
25
27
 
28
+
26
29
  def store_bytes(bucket: str, filename: str, bytes: bytes):
27
30
  return get_client().put_object(
28
31
  Bucket=bucket,
@@ -30,25 +33,29 @@ def store_bytes(bucket: str, filename: str, bytes: bytes):
30
33
  Body=bytes,
31
34
  )
32
35
 
36
+
33
37
  def store_as_json(bucket: str, filename: str, value):
34
- return store_bytes(bucket, filename, bytes(json.dumps(value).encode('UTF-8')))
38
+ return store_bytes(bucket, filename, bytes(json.dumps(value).encode("UTF-8")))
39
+
35
40
 
36
41
  def get_bytes(bucket: str, filename: str) -> bytes | None:
37
42
  client = get_client()
38
43
  try:
39
- return client.get_object(Bucket=bucket, Key=filename)['Body'].read()
44
+ return client.get_object(Bucket=bucket, Key=filename)["Body"].read()
40
45
  except client.exceptions.NoSuchKey:
41
46
  return None
42
47
 
48
+
43
49
  def get_from_json(bucket: str, filename: str) -> Any | None:
44
50
  bytes = get_bytes(bucket, filename)
45
51
  if bytes is None:
46
52
  return None
47
53
 
48
- return json.loads(bytes.decode('utf-8'))
54
+ return json.loads(bytes.decode("utf-8"))
55
+
49
56
 
50
57
  def delete_file(bucket: str, filename: str):
51
58
  return get_client().delete_object(
52
59
  Bucket=bucket,
53
60
  Key=filename,
54
- )
61
+ )
udata/tags.py CHANGED
@@ -2,9 +2,8 @@ from flask import current_app
2
2
  from slugify import slugify
3
3
  from werkzeug.local import LocalProxy
4
4
 
5
-
6
- MIN_TAG_LENGTH = LocalProxy(lambda: current_app.config['TAG_MIN_LENGTH'])
7
- MAX_TAG_LENGTH = LocalProxy(lambda: current_app.config['TAG_MAX_LENGTH'])
5
+ MIN_TAG_LENGTH = LocalProxy(lambda: current_app.config["TAG_MIN_LENGTH"])
6
+ MAX_TAG_LENGTH = LocalProxy(lambda: current_app.config["TAG_MAX_LENGTH"])
8
7
 
9
8
 
10
9
  def slug(value):
@@ -14,11 +13,11 @@ def slug(value):
14
13
  def normalize(value):
15
14
  value = slug(value)
16
15
  if len(value) < MIN_TAG_LENGTH:
17
- value = ''
16
+ value = ""
18
17
  elif len(value) > MAX_TAG_LENGTH:
19
18
  value = value[:MAX_TAG_LENGTH]
20
19
  return value
21
20
 
22
21
 
23
22
  def tags_list(value):
24
- return list(set(slug(tag) for tag in value.split(',') if tag.strip()))
23
+ return list(set(slug(tag) for tag in value.split(",") if tag.strip()))
udata/tasks.py CHANGED
@@ -1,5 +1,4 @@
1
1
  import logging
2
-
3
2
  from urllib.parse import urlparse
4
3
 
5
4
  from celery import Celery, Task
@@ -26,7 +25,7 @@ class ContextTask(Task):
26
25
 
27
26
  class JobTask(ContextTask):
28
27
  abstract = True
29
- default_queue = 'low'
28
+ default_queue = "low"
30
29
 
31
30
  @property
32
31
  def log(self):
@@ -35,7 +34,7 @@ class JobTask(ContextTask):
35
34
 
36
35
  class Scheduler(MongoScheduler):
37
36
  def apply_async(self, entry, **kwargs):
38
- '''A MongoScheduler storing the last task_id'''
37
+ """A MongoScheduler storing the last task_id"""
39
38
  result = super(Scheduler, self).apply_async(entry, **kwargs)
40
39
  entry._task.last_run_id = result.id
41
40
  return result
@@ -45,43 +44,42 @@ celery = Celery(task_cls=ContextTask)
45
44
 
46
45
 
47
46
  def router(name, args, kwargs, options, task=None, **kw):
48
- '''
47
+ """
49
48
  A celery router using the predeclared :class:`ContextTask`
50
49
  attributes (`router` or `default_queue` and/or `default routing_key`).
51
- '''
50
+ """
52
51
  # Fetch task by name if necessary
53
52
  task = task or celery.tasks.get(name)
54
53
  if not task:
55
54
  return
56
55
  # Single route param override everything
57
56
  if task.route:
58
- queue = task.route.split('.', 1)[0]
59
- return {'queue': queue, 'routing_key': task.route}
57
+ queue = task.route.split(".", 1)[0]
58
+ return {"queue": queue, "routing_key": task.route}
60
59
  # queue parameter, routing_key computed if not present
61
60
  if task.default_queue:
62
61
  key = task.default_routing_key
63
- key = key or '{0.default_queue}.{0.name}'.format(task)
64
- return {'queue': task.default_queue, 'routing_key': key}
62
+ key = key or "{0.default_queue}.{0.name}".format(task)
63
+ return {"queue": task.default_queue, "routing_key": key}
65
64
  # only routing_key, queue should not be returned to fallback on default
66
65
  elif task.default_routing_key:
67
- return {'routing_key': task.default_routing_key}
66
+ return {"routing_key": task.default_routing_key}
68
67
 
69
68
 
70
69
  def task(*args, **kwargs):
71
- for arg in 'queue', 'routing_key':
70
+ for arg in "queue", "routing_key":
72
71
  if arg in kwargs:
73
- kwargs['default_{0}'.format(arg)] = kwargs.pop(arg)
72
+ kwargs["default_{0}".format(arg)] = kwargs.pop(arg)
74
73
  return celery.task(*args, **kwargs)
75
74
 
76
75
 
77
76
  def job(name, **kwargs):
78
- '''A shortcut decorator for declaring jobs'''
79
- return task(name=name, schedulable=True, base=JobTask,
80
- bind=True, **kwargs)
77
+ """A shortcut decorator for declaring jobs"""
78
+ return task(name=name, schedulable=True, base=JobTask, bind=True, **kwargs)
81
79
 
82
80
 
83
81
  def as_task_param(obj):
84
- '''Pass a document as task parameter'''
82
+ """Pass a document as task parameter"""
85
83
  return obj.__class__.__name__, (obj.pk if isinstance(obj.pk, str) else str(obj.pk))
86
84
 
87
85
 
@@ -91,7 +89,7 @@ def get_logger(name):
91
89
 
92
90
 
93
91
  def connect(signal, *args, **kwargs):
94
- by_id = kwargs.pop('by_id', False)
92
+ by_id = kwargs.pop("by_id", False)
95
93
 
96
94
  def wrapper(func):
97
95
  t = task(func, *args, **kwargs)
@@ -101,34 +99,35 @@ def connect(signal, *args, **kwargs):
101
99
 
102
100
  signal.connect(call_task, weak=False)
103
101
  return t
102
+
104
103
  return wrapper
105
104
 
106
105
 
107
- @job('test-log')
106
+ @job("test-log")
108
107
  def log_test(self):
109
- self.log.debug('This is a DEBUG message')
110
- self.log.info('This is an INFO message')
111
- self.log.warning('This is a WARNING message')
112
- self.log.error('This is a ERROR message')
108
+ self.log.debug("This is a DEBUG message")
109
+ self.log.info("This is an INFO message")
110
+ self.log.warning("This is a WARNING message")
111
+ self.log.error("This is a ERROR message")
113
112
 
114
113
 
115
- @job('test-low-queue', queue='low')
116
- @job('test-default-queue', queue='default')
117
- @job('test-high-queue', queue='high')
114
+ @job("test-low-queue", queue="low")
115
+ @job("test-default-queue", queue="default")
116
+ @job("test-high-queue", queue="high")
118
117
  def queue_test(self, raises=False):
119
- '''
118
+ """
120
119
  An empty task to test the queues.
121
120
  Set raise to True if you want a notification (ie. Sentry)
122
- '''
123
- self.log.info('Just a test task')
121
+ """
122
+ self.log.info("Just a test task")
124
123
  if raises:
125
- raise Exception('Test task processing')
124
+ raise Exception("Test task processing")
126
125
 
127
126
 
128
- @job('test-error')
127
+ @job("test-error")
129
128
  def error_test(self):
130
- self.log.info('There should be an error soon')
131
- raise Exception('There is an error')
129
+ self.log.info("There should be an error soon")
130
+ raise Exception("There is an error")
132
131
 
133
132
 
134
133
  def schedulables():
@@ -137,23 +136,25 @@ def schedulables():
137
136
 
138
137
  def default_scheduler_config(url):
139
138
  parsed_url = urlparse(url)
140
- default_url = '{0}://{1}'.format(*parsed_url)
139
+ default_url = "{0}://{1}".format(*parsed_url)
141
140
  return parsed_url.path[1:], default_url
142
141
 
143
142
 
144
143
  def init_app(app):
145
144
  celery.main = app.import_name
146
145
 
147
- db, url = default_scheduler_config(app.config['MONGODB_HOST'])
146
+ db, url = default_scheduler_config(app.config["MONGODB_HOST"])
148
147
 
149
- app.config.setdefault('CELERY_MONGODB_SCHEDULER_DB', db)
150
- app.config.setdefault('CELERY_MONGODB_SCHEDULER_URL', url)
148
+ app.config.setdefault("CELERY_MONGODB_SCHEDULER_DB", db)
149
+ app.config.setdefault("CELERY_MONGODB_SCHEDULER_URL", url)
151
150
 
152
- celery.conf.update(**dict(
153
- (k.replace('CELERY_', '').lower(), v)
154
- for k, v in app.config.items()
155
- if k.startswith('CELERY_')
156
- ))
151
+ celery.conf.update(
152
+ **dict(
153
+ (k.replace("CELERY_", "").lower(), v)
154
+ for k, v in app.config.items()
155
+ if k.startswith("CELERY_")
156
+ )
157
+ )
157
158
 
158
159
  ContextTask.current_app = app
159
160
 
@@ -172,6 +173,6 @@ def init_app(app):
172
173
  import udata.harvest.tasks # noqa
173
174
  import udata.db.tasks # noqa
174
175
 
175
- entrypoints.get_enabled('udata.tasks', app)
176
+ entrypoints.get_enabled("udata.tasks", app)
176
177
 
177
178
  return celery
udata/tests/__init__.py CHANGED
@@ -1,6 +1,9 @@
1
1
  import unittest
2
+
2
3
  import pytest
4
+
3
5
  from udata import settings
6
+
4
7
  from . import helpers
5
8
 
6
9
 
@@ -13,9 +16,9 @@ class TestCase(unittest.TestCase):
13
16
  return self.create_app()
14
17
 
15
18
  def create_app(self):
16
- '''
19
+ """
17
20
  Here for compatibility legacy test classes
18
- '''
21
+ """
19
22
  return self.app
20
23
 
21
24
  def assertEqualDates(self, datetime1, datetime2, limit=1): # Seconds.
@@ -29,9 +32,9 @@ class WebTestMixin(object):
29
32
 
30
33
  @pytest.fixture(autouse=True)
31
34
  def inject_client(self, client):
32
- '''
35
+ """
33
36
  Inject test client for compatibility with Flask-Testing.
34
- '''
37
+ """
35
38
  self.client = client
36
39
 
37
40
  def get(self, url, **kwargs):
@@ -70,11 +73,11 @@ class WebTestMixin(object):
70
73
 
71
74
 
72
75
  for code in 200, 201, 204, 400, 401, 403, 404, 410, 500:
73
- name = 'assert{0}'.format(code)
76
+ name = "assert{0}".format(code)
74
77
  helper = getattr(helpers, name)
75
78
  setattr(WebTestMixin, name, lambda s, r, h=helper: h(r))
76
79
 
77
80
 
78
- @pytest.mark.usefixtures('clean_db')
81
+ @pytest.mark.usefixtures("clean_db")
79
82
  class DBTestMixin(object):
80
83
  pass
@@ -1,18 +1,17 @@
1
- import pytest
2
-
3
1
  from contextlib import contextmanager
4
2
 
3
+ import pytest
4
+
5
5
  from ..frontend import FrontTestCase
6
6
 
7
7
 
8
- @pytest.mark.usefixtures('instance_path')
8
+ @pytest.mark.usefixtures("instance_path")
9
9
  class APITestCase(FrontTestCase):
10
-
11
10
  @pytest.fixture(autouse=True)
12
11
  def inject_api(self, api):
13
- '''
12
+ """
14
13
  Inject API test client for compatibility with legacy tests.
15
- '''
14
+ """
16
15
  self.api = api
17
16
 
18
17
  @contextmanager
@@ -34,3 +33,6 @@ class APITestCase(FrontTestCase):
34
33
 
35
34
  def delete(self, url, data=None, *args, **kwargs):
36
35
  return self.api.delete(url, data=data, *args, **kwargs)
36
+
37
+ def options(self, url, data=None, *args, **kwargs):
38
+ return self.api.options(url, data=data, *args, **kwargs)