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
@@ -1,17 +1,18 @@
1
1
  from blinker import Signal
2
- from mongoengine.signals import pre_save, post_save
2
+ from mongoengine.signals import post_save, pre_save
3
3
  from werkzeug.utils import cached_property
4
4
 
5
- from udata.core.storages import images, default_image_basename
5
+ from udata.core.owned import Owned, OwnedQuerySet
6
+ from udata.core.storages import default_image_basename, images
6
7
  from udata.frontend.markdown import mdstrip
7
8
  from udata.i18n import lazy_gettext as _
8
- from udata.models import db, BadgeMixin, WithMetrics
9
- from udata.utils import hash_url
9
+ from udata.models import BadgeMixin, WithMetrics, db
10
10
  from udata.uris import endpoint_for
11
- from udata.core.owned import Owned, OwnedQuerySet
11
+ from udata.utils import hash_url
12
+
12
13
  from .constants import IMAGE_MAX_SIZE, IMAGE_SIZES, REUSE_TOPICS, REUSE_TYPES
13
14
 
14
- __all__ = ('Reuse',)
15
+ __all__ = ("Reuse",)
15
16
 
16
17
 
17
18
  class ReuseQuerySet(OwnedQuerySet):
@@ -19,25 +20,23 @@ class ReuseQuerySet(OwnedQuerySet):
19
20
  return self(private__ne=True, datasets__0__exists=True, deleted=None)
20
21
 
21
22
  def hidden(self):
22
- return self(db.Q(private=True) |
23
- db.Q(datasets__0__exists=False) |
24
- db.Q(deleted__ne=None))
23
+ return self(db.Q(private=True) | db.Q(datasets__0__exists=False) | db.Q(deleted__ne=None))
25
24
 
26
25
 
27
26
  class Reuse(db.Datetimed, WithMetrics, BadgeMixin, Owned, db.Document):
28
27
  title = db.StringField(required=True)
29
- slug = db.SlugField(max_length=255, required=True, populate_from='title',
30
- update=True, follow=True)
28
+ slug = db.SlugField(
29
+ max_length=255, required=True, populate_from="title", update=True, follow=True
30
+ )
31
31
  description = db.StringField(required=True)
32
32
  type = db.StringField(required=True, choices=list(REUSE_TYPES))
33
33
  url = db.StringField(required=True)
34
34
  urlhash = db.StringField(required=True, unique=True)
35
35
  image_url = db.StringField()
36
36
  image = db.ImageField(
37
- fs=images, basename=default_image_basename, max_size=IMAGE_MAX_SIZE,
38
- thumbnails=IMAGE_SIZES)
39
- datasets = db.ListField(
40
- db.ReferenceField('Dataset', reverse_delete_rule=db.PULL))
37
+ fs=images, basename=default_image_basename, max_size=IMAGE_MAX_SIZE, thumbnails=IMAGE_SIZES
38
+ )
39
+ datasets = db.ListField(db.ReferenceField("Dataset", reverse_delete_rule=db.PULL))
41
40
  tags = db.TagListField()
42
41
  topic = db.StringField(required=True, choices=list(REUSE_TOPICS))
43
42
  # badges = db.ListField(db.EmbeddedDocumentField(ReuseBadge))
@@ -51,28 +50,31 @@ class Reuse(db.Datetimed, WithMetrics, BadgeMixin, Owned, db.Document):
51
50
  deleted = db.DateTimeField()
52
51
 
53
52
  def __str__(self):
54
- return self.title or ''
53
+ return self.title or ""
55
54
 
56
55
  __badges__ = {}
57
56
 
58
57
  __metrics_keys__ = [
59
- 'discussions',
60
- 'datasets',
61
- 'followers',
62
- 'views',
58
+ "discussions",
59
+ "datasets",
60
+ "followers",
61
+ "views",
63
62
  ]
64
63
 
65
64
  meta = {
66
- 'indexes': ['$title',
67
- 'created_at',
68
- 'last_modified',
69
- 'metrics.datasets',
70
- 'metrics.followers',
71
- 'metrics.views',
72
- 'urlhash'] + Owned.meta['indexes'],
73
- 'ordering': ['-created_at'],
74
- 'queryset_class': ReuseQuerySet,
75
- 'auto_create_index_on_save': True
65
+ "indexes": [
66
+ "$title",
67
+ "created_at",
68
+ "last_modified",
69
+ "metrics.datasets",
70
+ "metrics.followers",
71
+ "metrics.views",
72
+ "urlhash",
73
+ ]
74
+ + Owned.meta["indexes"],
75
+ "ordering": ["-created_at"],
76
+ "queryset_class": ReuseQuerySet,
77
+ "auto_create_index_on_save": True,
76
78
  }
77
79
 
78
80
  before_save = Signal()
@@ -83,7 +85,7 @@ class Reuse(db.Datetimed, WithMetrics, BadgeMixin, Owned, db.Document):
83
85
  after_delete = Signal()
84
86
  on_delete = Signal()
85
87
 
86
- verbose_name = _('reuse')
88
+ verbose_name = _("reuse")
87
89
 
88
90
  @classmethod
89
91
  def pre_save(cls, sender, document, **kwargs):
@@ -92,10 +94,10 @@ class Reuse(db.Datetimed, WithMetrics, BadgeMixin, Owned, db.Document):
92
94
 
93
95
  @classmethod
94
96
  def post_save(cls, sender, document, **kwargs):
95
- if 'post_save' in kwargs.get('ignores', []):
97
+ if "post_save" in kwargs.get("ignores", []):
96
98
  return
97
99
  cls.after_save.send(document)
98
- if kwargs.get('created'):
100
+ if kwargs.get("created"):
99
101
  cls.on_create.send(document)
100
102
  else:
101
103
  cls.on_update.send(document)
@@ -103,7 +105,7 @@ class Reuse(db.Datetimed, WithMetrics, BadgeMixin, Owned, db.Document):
103
105
  cls.on_delete.send(document)
104
106
 
105
107
  def url_for(self, *args, **kwargs):
106
- return endpoint_for('reuses.show', 'api.reuse', reuse=self, *args, **kwargs)
108
+ return endpoint_for("reuses.show", "api.reuse", reuse=self, *args, **kwargs)
107
109
 
108
110
  display_url = property(url_for)
109
111
 
@@ -129,8 +131,8 @@ class Reuse(db.Datetimed, WithMetrics, BadgeMixin, Owned, db.Document):
129
131
 
130
132
  def clean(self):
131
133
  super(Reuse, self).clean()
132
- '''Auto populate urlhash from url'''
133
- if not self.urlhash or 'url' in self._get_changed_fields():
134
+ """Auto populate urlhash from url"""
135
+ if not self.urlhash or "url" in self._get_changed_fields():
134
136
  self.urlhash = hash_url(self.url)
135
137
 
136
138
  @classmethod
@@ -146,18 +148,18 @@ class Reuse(db.Datetimed, WithMetrics, BadgeMixin, Owned, db.Document):
146
148
  @cached_property
147
149
  def json_ld(self):
148
150
  result = {
149
- '@context': 'http://schema.org',
150
- '@type': 'CreativeWork',
151
- 'alternateName': self.slug,
152
- 'dateCreated': self.created_at.isoformat(),
153
- 'dateModified': self.last_modified.isoformat(),
154
- 'url': endpoint_for('reuses.show', 'api.reuse', reuse=self, _external=True),
155
- 'name': self.title,
156
- 'isBasedOnUrl': self.url,
151
+ "@context": "http://schema.org",
152
+ "@type": "CreativeWork",
153
+ "alternateName": self.slug,
154
+ "dateCreated": self.created_at.isoformat(),
155
+ "dateModified": self.last_modified.isoformat(),
156
+ "url": endpoint_for("reuses.show", "api.reuse", reuse=self, _external=True),
157
+ "name": self.title,
158
+ "isBasedOnUrl": self.url,
157
159
  }
158
160
 
159
161
  if self.description:
160
- result['description'] = mdstrip(self.description)
162
+ result["description"] = mdstrip(self.description)
161
163
 
162
164
  if self.organization:
163
165
  author = self.organization.json_ld
@@ -167,26 +169,28 @@ class Reuse(db.Datetimed, WithMetrics, BadgeMixin, Owned, db.Document):
167
169
  author = None
168
170
 
169
171
  if author:
170
- result['author'] = author
172
+ result["author"] = author
171
173
 
172
174
  return result
173
175
 
174
176
  @property
175
177
  def views_count(self):
176
- return self.metrics.get('views', 0)
178
+ return self.metrics.get("views", 0)
177
179
 
178
180
  def count_datasets(self):
179
- self.metrics['datasets'] = len(self.datasets)
180
- self.save(signal_kwargs={'ignores': ['post_save']})
181
+ self.metrics["datasets"] = len(self.datasets)
182
+ self.save(signal_kwargs={"ignores": ["post_save"]})
181
183
 
182
184
  def count_discussions(self):
183
185
  from udata.models import Discussion
184
- self.metrics['discussions'] = Discussion.objects(subject=self, closed=None).count()
186
+
187
+ self.metrics["discussions"] = Discussion.objects(subject=self, closed=None).count()
185
188
  self.save()
186
189
 
187
190
  def count_followers(self):
188
191
  from udata.models import Follow
189
- self.metrics['followers'] = Follow.objects(until=None).followers(self).count()
192
+
193
+ self.metrics["followers"] = Follow.objects(until=None).followers(self).count()
190
194
  self.save()
191
195
 
192
196
 
@@ -1,7 +1,7 @@
1
1
  from udata.auth import Permission, UserNeed
2
-
3
2
  from udata.core.organization.permissions import (
4
- OrganizationAdminNeed, OrganizationEditorNeed
3
+ OrganizationAdminNeed,
4
+ OrganizationEditorNeed,
5
5
  )
6
6
 
7
7
 
@@ -1,54 +1,57 @@
1
1
  import datetime
2
- from udata.models import (
3
- Reuse, Organization, User
4
- )
2
+
3
+ from udata.core.reuse.api import DEFAULT_SORTING, ReuseApiParser
4
+ from udata.models import Organization, Reuse, User
5
5
  from udata.search import (
6
- ModelSearchAdapter, register,
7
- ModelTermsFilter, BoolFilter, Filter
6
+ BoolFilter,
7
+ Filter,
8
+ ModelSearchAdapter,
9
+ ModelTermsFilter,
10
+ register,
8
11
  )
9
- from udata.core.reuse.api import ReuseApiParser, DEFAULT_SORTING
10
12
  from udata.utils import to_iso_datetime
11
13
 
12
-
13
- __all__ = ('ReuseSearch', )
14
+ __all__ = ("ReuseSearch",)
14
15
 
15
16
 
16
17
  @register
17
18
  class ReuseSearch(ModelSearchAdapter):
18
19
  model = Reuse
19
- search_url = 'reuses/'
20
+ search_url = "reuses/"
20
21
 
21
22
  sorts = {
22
- 'created': 'created_at',
23
- 'datasets': 'metrics.datasets',
24
- 'followers': 'metrics.followers',
25
- 'views': 'metrics.views'
23
+ "created": "created_at",
24
+ "datasets": "metrics.datasets",
25
+ "followers": "metrics.followers",
26
+ "views": "metrics.views",
26
27
  }
27
28
 
28
29
  filters = {
29
- 'tag': Filter(),
30
- 'organization': ModelTermsFilter(model=Organization),
31
- 'owner': ModelTermsFilter(model=User),
32
- 'type': Filter(),
33
- 'badge': Filter(),
34
- 'featured': BoolFilter(),
35
- 'topic': Filter(),
30
+ "tag": Filter(),
31
+ "organization": ModelTermsFilter(model=Organization),
32
+ "owner": ModelTermsFilter(model=User),
33
+ "type": Filter(),
34
+ "badge": Filter(),
35
+ "featured": BoolFilter(),
36
+ "topic": Filter(),
36
37
  }
37
38
 
38
39
  @classmethod
39
40
  def is_indexable(cls, reuse):
40
- return (reuse.deleted is None and
41
- len(reuse.datasets) > 0 and
42
- not reuse.private)
41
+ return reuse.deleted is None and len(reuse.datasets) > 0 and not reuse.private
43
42
 
44
43
  @classmethod
45
44
  def mongo_search(cls, args):
46
45
  reuses = Reuse.objects(deleted=None, private__ne=True)
47
46
  reuses = ReuseApiParser.parse_filters(reuses, args)
48
47
 
49
- sort = cls.parse_sort(args['sort']) or ('$text_score' if args['q'] else None) or DEFAULT_SORTING
50
- offset = (args['page'] - 1) * args['page_size']
51
- return reuses.order_by(sort).skip(offset).limit(args['page_size']), reuses.count()
48
+ sort = (
49
+ cls.parse_sort(args["sort"])
50
+ or ("$text_score" if args["q"] else None)
51
+ or DEFAULT_SORTING
52
+ )
53
+ offset = (args["page"] - 1) * args["page_size"]
54
+ return reuses.order_by(sort).skip(offset).limit(args["page_size"]), reuses.count()
52
55
 
53
56
  @classmethod
54
57
  def serialize(cls, reuse):
@@ -57,10 +60,10 @@ class ReuseSearch(ModelSearchAdapter):
57
60
  if reuse.organization:
58
61
  org = Organization.objects(id=reuse.organization.id).first()
59
62
  organization = {
60
- 'id': str(org.id),
61
- 'name': org.name,
62
- 'public_service': 1 if org.public_service else 0,
63
- 'followers': org.metrics.get('followers', 0)
63
+ "id": str(org.id),
64
+ "name": org.name,
65
+ "public_service": 1 if org.public_service else 0,
66
+ "followers": org.metrics.get("followers", 0),
64
67
  }
65
68
  elif reuse.owner:
66
69
  owner = User.objects(id=reuse.owner.id).first()
@@ -70,20 +73,20 @@ class ReuseSearch(ModelSearchAdapter):
70
73
  extras[key] = to_iso_datetime(value) if isinstance(value, datetime.datetime) else value
71
74
 
72
75
  return {
73
- 'id': str(reuse.id),
74
- 'title': reuse.title,
75
- 'description': reuse.description,
76
- 'url': reuse.url,
77
- 'created_at': to_iso_datetime(reuse.created_at),
78
- 'views': reuse.metrics.get('views', 0),
79
- 'followers': reuse.metrics.get('followers', 0),
80
- 'datasets': reuse.metrics.get('datasets', 0),
81
- 'featured': 1 if reuse.featured else 0,
82
- 'organization': organization,
83
- 'owner': str(owner.id) if owner else None,
84
- 'type': reuse.type,
85
- 'topic': reuse.topic,
86
- 'tags': reuse.tags,
87
- 'badges': [badge.kind for badge in reuse.badges],
88
- 'extras': extras
76
+ "id": str(reuse.id),
77
+ "title": reuse.title,
78
+ "description": reuse.description,
79
+ "url": reuse.url,
80
+ "created_at": to_iso_datetime(reuse.created_at),
81
+ "views": reuse.metrics.get("views", 0),
82
+ "followers": reuse.metrics.get("followers", 0),
83
+ "datasets": reuse.metrics.get("datasets", 0),
84
+ "featured": 1 if reuse.featured else 0,
85
+ "organization": organization,
86
+ "owner": str(owner.id) if owner else None,
87
+ "type": reuse.type,
88
+ "topic": reuse.topic,
89
+ "tags": reuse.tags,
90
+ "badges": [badge.kind for badge in reuse.badges],
91
+ "extras": extras,
89
92
  }
@@ -3,4 +3,4 @@ from blinker import Namespace
3
3
  namespace = Namespace()
4
4
 
5
5
  #: Trigerred when a reuse is published
6
- on_reuse_published = namespace.signal('on-reuse-published')
6
+ on_reuse_published = namespace.signal("on-reuse-published")
udata/core/reuse/tasks.py CHANGED
@@ -1,6 +1,6 @@
1
1
  from udata import mail
2
- from udata.i18n import lazy_gettext as _
3
2
  from udata.core import storages
3
+ from udata.i18n import lazy_gettext as _
4
4
  from udata.models import Activity, Discussion, Follow, Transfer
5
5
  from udata.tasks import get_logger, job, task
6
6
 
@@ -9,10 +9,10 @@ from .models import Reuse
9
9
  log = get_logger(__name__)
10
10
 
11
11
 
12
- @job('purge-reuses')
12
+ @job("purge-reuses")
13
13
  def purge_reuses(self):
14
14
  for reuse in Reuse.objects(deleted__ne=None):
15
- log.info(f'Purging reuse {reuse}')
15
+ log.info(f"Purging reuse {reuse}")
16
16
  # Remove followers
17
17
  Follow.objects(following=reuse).delete()
18
18
  # Remove discussions
@@ -42,5 +42,4 @@ def notify_new_reuse(reuse_id):
42
42
  else:
43
43
  recipients = None
44
44
  if recipients:
45
- mail.send(_('New reuse'), recipients, 'new_reuse', reuse=reuse,
46
- dataset=dataset)
45
+ mail.send(_("New reuse"), recipients, "new_reuse", reuse=reuse, dataset=dataset)
udata/core/site/api.py CHANGED
@@ -1,115 +1,112 @@
1
1
  from bson import ObjectId
2
-
3
- from flask import request, redirect, url_for, json, make_response
2
+ from flask import json, make_response, redirect, request, url_for
4
3
  from mongoengine import Q
5
4
 
6
- from udata.api import api, API, fields
5
+ from udata.api import API, api, fields
7
6
  from udata.auth import admin_permission
8
7
  from udata.core.dataservices.models import Dataservice
9
- from udata.models import Dataset, Reuse
10
- from udata.utils import multi_to_dict
11
- from udata.rdf import (
12
- CONTEXT, RDF_EXTENSIONS,
13
- negociate_content, graph_response
14
- )
15
-
16
8
  from udata.core.dataset.api_fields import dataset_fields
17
9
  from udata.core.reuse.api_fields import reuse_fields
10
+ from udata.models import Dataset, Reuse
11
+ from udata.rdf import CONTEXT, RDF_EXTENSIONS, graph_response, negociate_content
12
+ from udata.utils import multi_to_dict
18
13
 
19
14
  from .models import current_site
20
15
  from .rdf import build_catalog
21
16
 
22
- site_fields = api.model('Site', {
23
- 'id': fields.String(
24
- description='The Site unique identifier', required=True),
25
- 'title': fields.String(
26
- description='The site display title', required=True),
27
- 'metrics': fields.Raw(attribute=lambda o: o.get_metrics(), description='The associated metrics', default={}),
28
- })
17
+ site_fields = api.model(
18
+ "Site",
19
+ {
20
+ "id": fields.String(description="The Site unique identifier", required=True),
21
+ "title": fields.String(description="The site display title", required=True),
22
+ "metrics": fields.Raw(
23
+ attribute=lambda o: o.get_metrics(), description="The associated metrics", default={}
24
+ ),
25
+ },
26
+ )
29
27
 
30
28
 
31
- @api.route('/site/', endpoint='site')
29
+ @api.route("/site/", endpoint="site")
32
30
  class SiteAPI(API):
33
-
34
- @api.doc(id='get_site')
31
+ @api.doc(id="get_site")
35
32
  @api.marshal_with(site_fields)
36
33
  def get(self):
37
- '''Site-wide variables'''
34
+ """Site-wide variables"""
38
35
  return current_site
39
36
 
40
37
 
41
- @api.route('/site/home/datasets/', endpoint='home_datasets')
38
+ @api.route("/site/home/datasets/", endpoint="home_datasets")
42
39
  class SiteHomeDatasetsAPI(API):
43
- @api.doc('get_home_datasets')
40
+ @api.doc("get_home_datasets")
44
41
  # @api.secure(admin_permission)
45
42
  @api.marshal_list_with(dataset_fields)
46
43
  def get(self):
47
- '''List homepage datasets'''
44
+ """List homepage datasets"""
48
45
  return current_site.settings.home_datasets
49
46
 
50
47
  @api.secure(admin_permission)
51
- @api.doc('set_home_datasets')
52
- @api.expect(([str], 'Dataset IDs to put in homepage'))
48
+ @api.doc("set_home_datasets")
49
+ @api.expect(([str], "Dataset IDs to put in homepage"))
53
50
  @api.marshal_list_with(dataset_fields)
54
51
  def put(self):
55
- '''Set the homepage datasets editorial selection'''
52
+ """Set the homepage datasets editorial selection"""
56
53
  if not isinstance(request.json, list):
57
- api.abort(400, 'Expect a list of dataset IDs')
54
+ api.abort(400, "Expect a list of dataset IDs")
58
55
  ids = [ObjectId(id) for id in request.json]
59
56
  current_site.settings.home_datasets = Dataset.objects.bulk_list(ids)
60
57
  current_site.save()
61
58
  return current_site.settings.home_datasets
62
59
 
63
60
 
64
- @api.route('/site/home/reuses/', endpoint='home_reuses')
61
+ @api.route("/site/home/reuses/", endpoint="home_reuses")
65
62
  class SiteHomeReusesAPI(API):
66
- @api.doc('get_home_reuses')
63
+ @api.doc("get_home_reuses")
67
64
  @api.secure(admin_permission)
68
65
  @api.marshal_list_with(reuse_fields)
69
66
  def get(self):
70
- '''List homepage featured reuses'''
67
+ """List homepage featured reuses"""
71
68
  return current_site.settings.home_reuses
72
69
 
73
70
  @api.secure(admin_permission)
74
- @api.doc('set_home_reuses')
75
- @api.expect(([str], 'Reuse IDs to put in homepage'))
71
+ @api.doc("set_home_reuses")
72
+ @api.expect(([str], "Reuse IDs to put in homepage"))
76
73
  @api.marshal_list_with(reuse_fields)
77
74
  def put(self):
78
- '''Set the homepage reuses editorial selection'''
75
+ """Set the homepage reuses editorial selection"""
79
76
  if not isinstance(request.json, list):
80
- api.abort(400, 'Expect a list of reuse IDs')
77
+ api.abort(400, "Expect a list of reuse IDs")
81
78
  ids = [ObjectId(id) for id in request.json]
82
79
  current_site.settings.home_reuses = Reuse.objects.bulk_list(ids)
83
80
  current_site.save()
84
81
  return current_site.settings.home_reuses
85
82
 
86
83
 
87
- @api.route('/site/data.<format>', endpoint='site_dataportal')
84
+ @api.route("/site/data.<format>", endpoint="site_dataportal")
88
85
  class SiteDataPortal(API):
89
86
  def get(self, format):
90
- '''Root RDF endpoint with content negociation handling'''
91
- url = url_for('api.site_rdf_catalog_format', format=format)
87
+ """Root RDF endpoint with content negociation handling"""
88
+ url = url_for("api.site_rdf_catalog_format", format=format)
92
89
  return redirect(url)
93
90
 
94
91
 
95
- @api.route('/site/catalog', endpoint='site_rdf_catalog')
92
+ @api.route("/site/catalog", endpoint="site_rdf_catalog")
96
93
  class SiteRdfCatalog(API):
97
94
  def get(self):
98
- '''Root RDF endpoint with content negociation handling'''
95
+ """Root RDF endpoint with content negociation handling"""
99
96
  format = RDF_EXTENSIONS[negociate_content()]
100
- url = url_for('api.site_rdf_catalog_format', format=format)
97
+ url = url_for("api.site_rdf_catalog_format", format=format)
101
98
  return redirect(url)
102
99
 
103
100
 
104
- @api.route('/site/catalog.<format>', endpoint='site_rdf_catalog_format')
101
+ @api.route("/site/catalog.<format>", endpoint="site_rdf_catalog_format")
105
102
  class SiteRdfCatalogFormat(API):
106
103
  def get(self, format):
107
104
  params = multi_to_dict(request.args)
108
- page = int(params.get('page', 1))
109
- page_size = int(params.get('page_size', 100))
105
+ page = int(params.get("page", 1))
106
+ page_size = int(params.get("page_size", 100))
110
107
  datasets = Dataset.objects.visible()
111
- if 'tag' in params:
112
- datasets = datasets.filter(tags=params.get('tag', ''))
108
+ if "tag" in params:
109
+ datasets = datasets.filter(tags=params.get("tag", ""))
113
110
  datasets = datasets.paginate(page, page_size)
114
111
 
115
112
  # We need to add Dataservice to the catalog.
@@ -119,14 +116,14 @@ class SiteRdfCatalogFormat(API):
119
116
  # - Do not duplicate the datasets (each dataset is present once in the catalog)
120
117
  # - Do not duplicate the dataservices (each dataservice is present once in the catalog)
121
118
  # - Every referenced dataset for one dataservices present on the page (hard to do)
122
- #
119
+ #
123
120
  # Multiple solutions are possible but none check all the constraints.
124
121
  # The selected one is to put all the dataservices referencing at least one of the dataset on
125
122
  # the page at the end of it. It means dataservices could be duplicated (present on multiple pages)
126
123
  # and these dataservices may referenced some datasets not present in the current page. It's working
127
124
  # if somebody is doing the same thing as us (keeping the list of all the datasets IDs for the entire catalog then
128
125
  # listing all dataservices in a second pass)
129
- # Another option is to do some tricky Mongo requests to order/group datasets by their presence in some dataservices but
126
+ # Another option is to do some tricky Mongo requests to order/group datasets by their presence in some dataservices but
130
127
  # it could be really hard to do with a n..n relation.
131
128
  # Let's keep this solution simple right now and iterate on it in the future.
132
129
  dataservices_filter = Q(datasets__in=[d.id for d in datasets])
@@ -143,9 +140,9 @@ class SiteRdfCatalogFormat(API):
143
140
  return make_response(*graph_response(catalog, format))
144
141
 
145
142
 
146
- @api.route('/site/context.jsonld', endpoint='site_jsonld_context')
143
+ @api.route("/site/context.jsonld", endpoint="site_jsonld_context")
147
144
  class SiteJsonLdContext(API):
148
145
  def get(self):
149
146
  response = make_response(json.dumps(CONTEXT))
150
- response.headers['Content-Type'] = 'application/ld+json'
147
+ response.headers["Content-Type"] = "application/ld+json"
151
148
  return response
@@ -14,6 +14,6 @@ class SiteFactory(ModelFactory):
14
14
  class Meta:
15
15
  model = Site
16
16
 
17
- id = factory.Faker('word')
18
- title = factory.Faker('name')
17
+ id = factory.Faker("word")
18
+ title = factory.Faker("name")
19
19
  settings = factory.SubFactory(SiteSettingsFactory)
udata/core/site/forms.py CHANGED
@@ -3,13 +3,12 @@ from udata.i18n import lazy_gettext as _
3
3
 
4
4
  from .models import Site
5
5
 
6
- __all__ = ('SiteConfigForm', )
6
+ __all__ = ("SiteConfigForm",)
7
7
 
8
8
 
9
9
  class SiteConfigForm(ModelForm):
10
10
  model_class = Site
11
11
 
12
- title = fields.StringField(_('Title'), [validators.DataRequired()])
13
- keywords = fields.TagField(_('Tags'), description=_('Some SEO keywords'))
14
- feed_size = fields.IntegerField(
15
- _('Feed size'), description=_('Number of elements in feeds'))
12
+ title = fields.StringField(_("Title"), [validators.DataRequired()])
13
+ keywords = fields.TagField(_("Tags"), description=_("Some SEO keywords"))
14
+ feed_size = fields.IntegerField(_("Feed size"), description=_("Number of elements in feeds"))