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
@@ -2,38 +2,37 @@ import logging
2
2
 
3
3
  import click
4
4
 
5
- from udata.commands import cli, exit_with_error, echo, white
6
- from udata.tasks import schedulables, celery
5
+ from udata.commands import cli, echo, exit_with_error, white
6
+ from udata.tasks import celery, schedulables
7
7
 
8
8
  from .models import PeriodicTask
9
9
 
10
10
  log = logging.getLogger(__name__)
11
11
 
12
- SCHEDULE_LINE = '{name}: {label} ↦ {schedule}'
12
+ SCHEDULE_LINE = "{name}: {label} ↦ {schedule}"
13
13
 
14
14
 
15
15
  def job_label(name, args, kwargs):
16
16
  label = name
17
17
  params = args[:]
18
- params += ['='.join((k, v)) for k, v in sorted(kwargs.items())]
18
+ params += ["=".join((k, v)) for k, v in sorted(kwargs.items())]
19
19
  if params:
20
- label += '(' + ', '.join(params) + ')'
20
+ label += "(" + ", ".join(params) + ")"
21
21
  return label
22
22
 
23
23
 
24
- @cli.group('job')
24
+ @cli.group("job")
25
25
  def grp():
26
- '''Jobs related operations'''
26
+ """Jobs related operations"""
27
27
  pass
28
28
 
29
29
 
30
30
  @grp.command()
31
- @click.argument('name', metavar='<name>')
32
- @click.argument('params', nargs=-1, metavar='<arg key=value ...>')
33
- @click.option('-d', '--delay', is_flag=True,
34
- help='Run the job asynchronously on a worker')
31
+ @click.argument("name", metavar="<name>")
32
+ @click.argument("params", nargs=-1, metavar="<arg key=value ...>")
33
+ @click.option("-d", "--delay", is_flag=True, help="Run the job asynchronously on a worker")
35
34
  def run(name, params, delay):
36
- '''
35
+ """
37
36
  Run the job <name>
38
37
 
39
38
  Jobs args and kwargs are given as parameters without dashes.
@@ -41,50 +40,50 @@ def run(name, params, delay):
41
40
  Ex:
42
41
  udata job run my-job arg1 arg2 key1=value key2=value
43
42
  udata job run my-job -- arg1 arg2 key1=value key2=value
44
- '''
45
- args = [p for p in params if '=' not in p]
46
- kwargs = dict(p.split('=') for p in params if '=' in p)
43
+ """
44
+ args = [p for p in params if "=" not in p]
45
+ kwargs = dict(p.split("=") for p in params if "=" in p)
47
46
 
48
47
  if name not in celery.tasks:
49
- exit_with_error('Job %s not found', name)
48
+ exit_with_error("Job %s not found", name)
50
49
  job = celery.tasks[name]
51
50
  label = job_label(name, args, kwargs)
52
51
  if delay:
53
- log.info('Sending job %s', label)
52
+ log.info("Sending job %s", label)
54
53
  job.delay(*args, **kwargs)
55
- log.info('Job sended to workers')
54
+ log.info("Job sended to workers")
56
55
  else:
57
- log.info('Running job %s', label)
56
+ log.info("Running job %s", label)
58
57
  job.run(*args, **kwargs)
59
- log.info('Job %s done', name)
58
+ log.info("Job %s done", name)
60
59
 
61
60
 
62
61
  @grp.command()
63
62
  def list():
64
- '''List all availables jobs'''
63
+ """List all availables jobs"""
65
64
  for job in sorted([s.name for s in schedulables()]):
66
65
  echo(job)
67
66
 
68
67
 
69
68
  @grp.command()
70
- @click.argument('cron', metavar='<cron>')
71
- @click.argument('name', metavar='<name>')
72
- @click.argument('params', nargs=-1, metavar='<arg key=value ...>')
69
+ @click.argument("cron", metavar="<cron>")
70
+ @click.argument("name", metavar="<name>")
71
+ @click.argument("params", nargs=-1, metavar="<arg key=value ...>")
73
72
  def schedule(cron, name, params):
74
- '''
73
+ """
75
74
  Schedule the job <name> to run periodically given the <cron> expression.
76
75
 
77
76
  Jobs args and kwargs are given as parameters without dashes.
78
77
 
79
78
  Ex:
80
79
  udata job schedule "* * 0 * *" my-job arg1 arg2 key1=value key2=value
81
- '''
80
+ """
82
81
  if name not in celery.tasks:
83
- exit_with_error('Job %s not found', name)
82
+ exit_with_error("Job %s not found", name)
84
83
 
85
- args = [p for p in params if '=' not in p]
86
- kwargs = dict(p.split('=') for p in params if '=' in p)
87
- label = 'Job {0}'.format(job_label(name, args, kwargs))
84
+ args = [p for p in params if "=" not in p]
85
+ kwargs = dict(p.split("=") for p in params if "=" in p)
86
+ label = "Job {0}".format(job_label(name, args, kwargs))
88
87
 
89
88
  try:
90
89
  task = PeriodicTask.objects.get(task=name, args=args, kwargs=kwargs)
@@ -93,56 +92,56 @@ def schedule(cron, name, params):
93
92
  task = PeriodicTask.objects.create(
94
93
  task=name,
95
94
  name=label,
96
- description='Periodic {0} job'.format(name),
95
+ description="Periodic {0} job".format(name),
97
96
  enabled=True,
98
97
  args=args,
99
98
  kwargs=kwargs,
100
99
  crontab=PeriodicTask.Crontab.parse(cron),
101
100
  )
102
101
 
103
- msg = 'Scheduled {label} with the following crontab: {cron}'
102
+ msg = "Scheduled {label} with the following crontab: {cron}"
104
103
  log.info(msg.format(label=label, cron=task.schedule_display))
105
104
 
106
105
 
107
106
  @grp.command()
108
- @click.argument('name', metavar='<name>')
109
- @click.argument('params', nargs=-1, metavar='<arg key=value ...>')
107
+ @click.argument("name", metavar="<name>")
108
+ @click.argument("params", nargs=-1, metavar="<arg key=value ...>")
110
109
  def unschedule(name, params):
111
- '''
110
+ """
112
111
  Unschedule the job <name> with the given parameters.
113
112
 
114
113
  Jobs args and kwargs are given as parameters without dashes.
115
114
 
116
115
  Ex:
117
116
  udata job unschedule my-job arg1 arg2 key1=value key2=value
118
- '''
117
+ """
119
118
  if name not in celery.tasks:
120
- exit_with_error('Job %s not found', name)
119
+ exit_with_error("Job %s not found", name)
121
120
 
122
- args = [p for p in params if '=' not in p]
123
- kwargs = dict(p.split('=') for p in params if '=' in p)
124
- label = 'Job {0}'.format(job_label(name, args, kwargs))
121
+ args = [p for p in params if "=" not in p]
122
+ kwargs = dict(p.split("=") for p in params if "=" in p)
123
+ label = "Job {0}".format(job_label(name, args, kwargs))
125
124
 
126
125
  try:
127
126
  task = PeriodicTask.objects.get(task=name, args=args, kwargs=kwargs)
128
127
  except PeriodicTask.DoesNotExist:
129
- exit_with_error('No scheduled job match {0}'.format(label))
128
+ exit_with_error("No scheduled job match {0}".format(label))
130
129
 
131
130
  task.delete()
132
- msg = 'Unscheduled {label} with the following crontab: {cron}'
131
+ msg = "Unscheduled {label} with the following crontab: {cron}"
133
132
  log.info(msg.format(label=label, cron=task.schedule_display))
134
133
 
135
134
 
136
135
  @grp.command()
137
136
  def scheduled():
138
- '''
137
+ """
139
138
  List scheduled jobs.
140
- '''
139
+ """
141
140
  for job in sorted(schedulables(), key=lambda s: s.name):
142
141
  for task in PeriodicTask.objects(task=job.name):
143
142
  label = job_label(task.task, task.args, task.kwargs)
144
- echo(SCHEDULE_LINE.format(
145
- name=white(task.name),
146
- label=label,
147
- schedule=task.schedule_display
148
- ))
143
+ echo(
144
+ SCHEDULE_LINE.format(
145
+ name=white(task.name), label=label, schedule=task.schedule_display
146
+ )
147
+ )
udata/core/jobs/forms.py CHANGED
@@ -7,11 +7,11 @@ from .models import PeriodicTask
7
7
  class CrontabForm(ModelForm):
8
8
  model_class = PeriodicTask.Crontab
9
9
 
10
- minute = fields.StringField(default='*')
11
- hour = fields.StringField(default='*')
12
- day_of_week = fields.StringField(default='*')
13
- day_of_month = fields.StringField(default='*')
14
- month_of_year = fields.StringField(default='*')
10
+ minute = fields.StringField(default="*")
11
+ hour = fields.StringField(default="*")
12
+ day_of_week = fields.StringField(default="*")
13
+ day_of_month = fields.StringField(default="*")
14
+ month_of_year = fields.StringField(default="*")
15
15
 
16
16
 
17
17
  class IntervalForm(ModelForm):
@@ -24,16 +24,16 @@ class IntervalForm(ModelForm):
24
24
  class PeriodicTaskForm(ModelForm):
25
25
  model_class = PeriodicTask
26
26
 
27
- name = fields.StringField(_('Name'), [validators.DataRequired()])
28
- description = fields.StringField(_('Description'))
29
- task = fields.StringField(_('Tasks'))
30
- enabled = fields.BooleanField(_('Enabled'))
27
+ name = fields.StringField(_("Name"), [validators.DataRequired()])
28
+ description = fields.StringField(_("Description"))
29
+ task = fields.StringField(_("Tasks"))
30
+ enabled = fields.BooleanField(_("Enabled"))
31
31
 
32
32
  def save(self, commit=True, **kwargs):
33
- '''
33
+ """
34
34
  PeriodicTask is dynamic and save behavior changed
35
35
  See: https://github.com/zakird/celerybeat-mongo/commit/dfbbd20edde91134b57f5406d0ce4eac59d6899b
36
- '''
36
+ """
37
37
  if not self.instance:
38
38
  self.instance = self.model_class() # Force populate_obj in super()
39
39
  return super(PeriodicTaskForm, self).save(commit, **kwargs)
udata/core/jobs/models.py CHANGED
@@ -1,12 +1,12 @@
1
- from celerybeatmongo.models import PeriodicTask as BasePeriodicTask, PERIODS
1
+ from celerybeatmongo.models import PERIODS
2
+ from celerybeatmongo.models import PeriodicTask as BasePeriodicTask
2
3
 
3
4
  from udata.i18n import lazy_gettext as _
4
5
  from udata.mongo import db
5
6
 
7
+ __all__ = ("PeriodicTask", "PERIODS")
6
8
 
7
- __all__ = ('PeriodicTask', 'PERIODS')
8
-
9
- CRON = '{minute} {hour} {day_of_month} {month_of_year} {day_of_week}'
9
+ CRON = "{minute} {hour} {day_of_month} {month_of_year} {day_of_week}"
10
10
 
11
11
 
12
12
  class PeriodicTask(BasePeriodicTask):
@@ -15,8 +15,8 @@ class PeriodicTask(BasePeriodicTask):
15
15
  class Interval(BasePeriodicTask.Interval):
16
16
  def __str__(self):
17
17
  if self.every == 1:
18
- return _('every {0.period_singular}').format(self)
19
- return _('every {0.every} {0.period}').format(self)
18
+ return _("every {0.period_singular}").format(self)
19
+ return _("every {0.every} {0.period}").format(self)
20
20
 
21
21
  class Crontab(BasePeriodicTask.Crontab):
22
22
  def __str__(self):
@@ -6,8 +6,8 @@ def init_app(app):
6
6
  import udata.core.user.metrics # noqa
7
7
  import udata.core.organization.metrics # noqa
8
8
  import udata.core.discussions.metrics # noqa
9
- import udata.core.reuse.metrics # noqa
9
+ import udata.core.reuse.metrics # noqa
10
10
  import udata.core.followers.metrics # noqa
11
11
 
12
12
  # Load metrics from plugins
13
- entrypoints.get_enabled('udata.metrics', app)
13
+ entrypoints.get_enabled("udata.metrics", app)
@@ -1,40 +1,44 @@
1
1
  import logging
2
2
 
3
3
  import click
4
-
5
4
  from flask import current_app
6
5
 
7
6
  from udata.commands import cli, success
8
- from udata.models import User, Dataset, Reuse, Organization, Site, GeoZone
7
+ from udata.models import Dataset, GeoZone, Organization, Reuse, Site, User
9
8
 
10
9
  log = logging.getLogger(__name__)
11
10
 
12
11
 
13
- @cli.group('metrics')
12
+ @cli.group("metrics")
14
13
  def grp():
15
- '''Metrics related operations'''
14
+ """Metrics related operations"""
16
15
  pass
17
16
 
18
17
 
19
18
  @grp.command()
20
- @click.option('-s', '--site', is_flag=True, help='Update site metrics')
21
- @click.option('-o', '--organizations', is_flag=True,
22
- help='Compute organizations metrics')
23
- @click.option('-d', '--datasets', is_flag=True,
24
- help='Compute datasets metrics')
25
- @click.option('-r', '--reuses', is_flag=True, help='Compute reuses metrics')
26
- @click.option('-u', '--users', is_flag=True, help='Compute users metrics')
27
- @click.option('-g', '--geozones', is_flag=True, help='Compute geo levels metrics')
28
- @click.option('--drop', is_flag=True, help='Clear old metrics before computing new ones')
29
- def update(site=False, organizations=False, users=False, datasets=False,
30
- reuses=False, geozones = False, drop=False):
31
- '''Update all metrics for the current date'''
19
+ @click.option("-s", "--site", is_flag=True, help="Update site metrics")
20
+ @click.option("-o", "--organizations", is_flag=True, help="Compute organizations metrics")
21
+ @click.option("-d", "--datasets", is_flag=True, help="Compute datasets metrics")
22
+ @click.option("-r", "--reuses", is_flag=True, help="Compute reuses metrics")
23
+ @click.option("-u", "--users", is_flag=True, help="Compute users metrics")
24
+ @click.option("-g", "--geozones", is_flag=True, help="Compute geo levels metrics")
25
+ @click.option("--drop", is_flag=True, help="Clear old metrics before computing new ones")
26
+ def update(
27
+ site=False,
28
+ organizations=False,
29
+ users=False,
30
+ datasets=False,
31
+ reuses=False,
32
+ geozones=False,
33
+ drop=False,
34
+ ):
35
+ """Update all metrics for the current date"""
32
36
  do_all = not any((site, organizations, users, datasets, reuses, geozones))
33
37
 
34
38
  if do_all or site:
35
- log.info('Update site metrics')
39
+ log.info("Update site metrics")
36
40
  try:
37
- site = Site.objects(id=current_app.config['SITE_ID']).first()
41
+ site = Site.objects(id=current_app.config["SITE_ID"]).first()
38
42
  if drop:
39
43
  site.metrics.clear()
40
44
  site.count_users()
@@ -53,10 +57,10 @@ def update(site=False, organizations=False, users=False, datasets=False,
53
57
  site.count_max_org_reuses()
54
58
  site.count_max_org_datasets()
55
59
  except Exception as e:
56
- log.info(f'Error during update: {e}')
60
+ log.info(f"Error during update: {e}")
57
61
 
58
62
  if do_all or datasets:
59
- log.info('Update datasets metrics')
63
+ log.info("Update datasets metrics")
60
64
  all_datasets = Dataset.objects.visible().timeout(False)
61
65
  with click.progressbar(all_datasets, length=Dataset.objects.count()) as dataset_bar:
62
66
  for dataset in dataset_bar:
@@ -67,11 +71,11 @@ def update(site=False, organizations=False, users=False, datasets=False,
67
71
  dataset.count_reuses()
68
72
  dataset.count_followers()
69
73
  except Exception as e:
70
- log.info(f'Error during update: {e}')
74
+ log.info(f"Error during update: {e}")
71
75
  continue
72
76
 
73
77
  if do_all or reuses:
74
- log.info('Update reuses metrics')
78
+ log.info("Update reuses metrics")
75
79
  all_reuses = Reuse.objects.visible().timeout(False)
76
80
  with click.progressbar(all_reuses, length=Reuse.objects.visible().count()) as reuses_bar:
77
81
  for reuse in reuses_bar:
@@ -81,11 +85,11 @@ def update(site=False, organizations=False, users=False, datasets=False,
81
85
  reuse.count_discussions()
82
86
  reuse.count_followers()
83
87
  except Exception as e:
84
- log.info(f'Error during update: {e}')
88
+ log.info(f"Error during update: {e}")
85
89
  continue
86
90
 
87
91
  if do_all or organizations:
88
- log.info('Update organizations metrics')
92
+ log.info("Update organizations metrics")
89
93
  all_org = Organization.objects.visible().timeout(False)
90
94
  with click.progressbar(all_org, length=Organization.objects.visible().count()) as org_bar:
91
95
  for organization in org_bar:
@@ -97,11 +101,11 @@ def update(site=False, organizations=False, users=False, datasets=False,
97
101
  organization.count_followers()
98
102
  organization.count_members()
99
103
  except Exception as e:
100
- log.info(f'Error during update: {e}')
104
+ log.info(f"Error during update: {e}")
101
105
  continue
102
106
 
103
107
  if do_all or users:
104
- log.info('Update user metrics')
108
+ log.info("Update user metrics")
105
109
  all_users = User.objects.timeout(False)
106
110
  with click.progressbar(all_users, length=User.objects.count()) as users_bar:
107
111
  for user in users_bar:
@@ -113,11 +117,11 @@ def update(site=False, organizations=False, users=False, datasets=False,
113
117
  user.count_followers()
114
118
  user.count_following()
115
119
  except Exception as e:
116
- log.info(f'Error during update: {e}')
120
+ log.info(f"Error during update: {e}")
117
121
  continue
118
122
 
119
123
  if do_all or geozones:
120
- log.info('Update GeoZone metrics')
124
+ log.info("Update GeoZone metrics")
121
125
  all_geozones = GeoZone.objects.timeout(False)
122
126
  with click.progressbar(all_geozones, length=GeoZone.objects.count()) as geozones_bar:
123
127
  for geozone in geozones_bar:
@@ -126,7 +130,7 @@ def update(site=False, organizations=False, users=False, datasets=False,
126
130
  geozone.metrics.clear()
127
131
  geozone.count_datasets()
128
132
  except Exception as e:
129
- log.info(f'Error during update: {e}')
133
+ log.info(f"Error during update: {e}")
130
134
  continue
131
135
 
132
- success('All metrics have been updated')
136
+ success("All metrics have been updated")
@@ -1,8 +1,7 @@
1
1
  from udata.api_fields import field
2
2
  from udata.mongo import db
3
3
 
4
-
5
- __all__ = ('WithMetrics',)
4
+ __all__ = ("WithMetrics",)
6
5
 
7
6
 
8
7
  class WithMetrics(object):
@@ -11,5 +10,4 @@ class WithMetrics(object):
11
10
  __metrics_keys__ = []
12
11
 
13
12
  def get_metrics(self):
14
- return {key:self.metrics.get(key, 0) for key in self.__metrics_keys__}
15
-
13
+ return {key: self.metrics.get(key, 0) for key in self.__metrics_keys__}
@@ -3,4 +3,4 @@ from blinker import Namespace
3
3
  namespace = Namespace()
4
4
 
5
5
  #: Trigerred when a site's metrics job is done.
6
- on_site_metrics_computed = namespace.signal('on-site-metrics-computed')
6
+ on_site_metrics_computed = namespace.signal("on-site-metrics-computed")
@@ -1,13 +1,13 @@
1
1
  from flask import current_app
2
2
 
3
+ from udata.core.metrics.signals import on_site_metrics_computed
3
4
  from udata.models import Site
4
5
  from udata.tasks import job
5
- from udata.core.metrics.signals import on_site_metrics_computed
6
6
 
7
7
 
8
- @job('compute-site-metrics')
8
+ @job("compute-site-metrics")
9
9
  def compute_site_metrics(self):
10
- site = Site.objects(id=current_app.config['SITE_ID']).first()
10
+ site = Site.objects(id=current_app.config["SITE_ID"]).first()
11
11
  site.count_users()
12
12
  site.count_org()
13
13
  site.count_datasets()
@@ -1,31 +1,28 @@
1
1
  from flask_security import current_user
2
2
 
3
3
  from udata.i18n import lazy_gettext as _
4
- from udata.models import db, Organization, Activity
4
+ from udata.models import Activity, Organization, db
5
5
 
6
-
7
- __all__ = (
8
- 'UserCreatedOrganization', 'UserUpdatedOrganization', 'OrgRelatedActivity'
9
- )
6
+ __all__ = ("UserCreatedOrganization", "UserUpdatedOrganization", "OrgRelatedActivity")
10
7
 
11
8
 
12
9
  class OrgRelatedActivity(object):
13
- related_to = db.ReferenceField('Organization')
14
- template = 'activity/organization.html'
10
+ related_to = db.ReferenceField("Organization")
11
+ template = "activity/organization.html"
15
12
 
16
13
 
17
14
  class UserCreatedOrganization(OrgRelatedActivity, Activity):
18
- key = 'organization:created'
19
- icon = 'fa fa-plus'
20
- badge_type = 'success'
21
- label = _('created an organization')
15
+ key = "organization:created"
16
+ icon = "fa fa-plus"
17
+ badge_type = "success"
18
+ label = _("created an organization")
22
19
 
23
20
 
24
21
  class UserUpdatedOrganization(OrgRelatedActivity, Activity):
25
- key = 'organization:updated'
26
- icon = 'fa fa-pencil'
27
- badge_type = 'error'
28
- label = _('updated an organization')
22
+ key = "organization:updated"
23
+ icon = "fa fa-pencil"
24
+ badge_type = "error"
25
+ label = _("updated an organization")
29
26
 
30
27
 
31
28
  @Organization.on_create.connect