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
@@ -4,27 +4,27 @@ from udata.auth import current_user
4
4
  from udata.forms import Form, ModelForm, fields, validators
5
5
  from udata.i18n import lazy_gettext as _
6
6
 
7
- from .models import Organization, MembershipRequest, Member
8
7
  from .constants import DESCRIPTION_SIZE_LIMIT, LOGO_SIZES, ORG_ROLES, TITLE_SIZE_LIMIT
8
+ from .models import Member, MembershipRequest, Organization
9
9
 
10
10
  __all__ = (
11
- 'OrganizationForm',
12
- 'MemberForm',
13
- 'MembershipRequestForm',
14
- 'MembershipRefuseForm',
11
+ "OrganizationForm",
12
+ "MemberForm",
13
+ "MembershipRequestForm",
14
+ "MembershipRefuseForm",
15
15
  )
16
16
 
17
17
 
18
18
  def org_bid_check(form, field):
19
19
  if field.data:
20
20
  # EID checks are country dependant. Following one is suitable for France.
21
- if current_app.config.get('ORG_BID_FORMAT') == 'siret':
21
+ if current_app.config.get("ORG_BID_FORMAT") == "siret":
22
22
  siret_number = str(field.data)
23
23
  # Length control done here instead of using WTForm validator because field must remain optional.
24
24
  if len(siret_number) != 14:
25
- raise validators.ValidationError(_('A siret number is made of 14 digits'))
25
+ raise validators.ValidationError(_("A siret number is made of 14 digits"))
26
26
  # Siret exception for the french postal service which business number id does not match the algorithm.
27
- if siret_number == '35600000000048':
27
+ if siret_number == "35600000000048":
28
28
  return
29
29
  # Checksum verification on only the SIREN part, the 9 first digits.
30
30
  try:
@@ -33,37 +33,40 @@ def org_bid_check(form, field):
33
33
  chiffres = [chiffre - 9 if chiffre > 9 else chiffre for chiffre in chiffres]
34
34
  total = sum(chiffres)
35
35
  except ValueError:
36
- raise validators.ValidationError(_('A siret number is only made of digits'))
36
+ raise validators.ValidationError(_("A siret number is only made of digits"))
37
37
 
38
38
  if not total % 10 == 0:
39
- raise validators.ValidationError(_('Invalid Siret number'))
39
+ raise validators.ValidationError(_("Invalid Siret number"))
40
40
 
41
41
 
42
42
  class OrganizationForm(ModelForm):
43
43
  model_class = Organization
44
44
 
45
- name = fields.StringField(_('Name'), [validators.DataRequired(), validators.Length(max=TITLE_SIZE_LIMIT)])
46
- acronym = fields.StringField(
47
- _('Acronym'), description=_('Shorter organization name'))
45
+ name = fields.StringField(
46
+ _("Name"), [validators.DataRequired(), validators.Length(max=TITLE_SIZE_LIMIT)]
47
+ )
48
+ acronym = fields.StringField(_("Acronym"), description=_("Shorter organization name"))
48
49
  description = fields.MarkdownField(
49
- _('Description'), [validators.DataRequired(), validators.Length(max=DESCRIPTION_SIZE_LIMIT)],
50
- description=_('The details about your organization'))
51
- url = fields.URLField(
52
- _('Website'), description=_('The organization website URL'))
53
- logo = fields.ImageField(_('Logo'), sizes=LOGO_SIZES)
54
- business_number_id = fields.StringField(_('Business id'), [org_bid_check],
55
- description=_('Business identification number'))
50
+ _("Description"),
51
+ [validators.DataRequired(), validators.Length(max=DESCRIPTION_SIZE_LIMIT)],
52
+ description=_("The details about your organization"),
53
+ )
54
+ url = fields.URLField(_("Website"), description=_("The organization website URL"))
55
+ logo = fields.ImageField(_("Logo"), sizes=LOGO_SIZES)
56
+ business_number_id = fields.StringField(
57
+ _("Business id"), [org_bid_check], description=_("Business identification number")
58
+ )
56
59
 
57
60
  deleted = fields.DateTimeField()
58
61
  extras = fields.ExtrasField()
59
62
 
60
63
  def save(self, commit=True, **kwargs):
61
- '''Register the current user as admin on creation'''
64
+ """Register the current user as admin on creation"""
62
65
  org = super(OrganizationForm, self).save(commit=False, **kwargs)
63
66
 
64
67
  if not org.id:
65
68
  user = current_user._get_current_object()
66
- member = Member(user=user, role='admin')
69
+ member = Member(user=user, role="admin")
67
70
  org.members.append(member)
68
71
  org.count_members()
69
72
 
@@ -77,16 +80,19 @@ class MembershipRequestForm(ModelForm):
77
80
  model_class = MembershipRequest
78
81
 
79
82
  user = fields.CurrentUserField()
80
- comment = fields.StringField(_('Comment'), [validators.DataRequired()])
83
+ comment = fields.StringField(_("Comment"), [validators.DataRequired()])
81
84
 
82
85
 
83
86
  class MembershipRefuseForm(Form):
84
- comment = fields.StringField(_('Comment'), [validators.DataRequired()])
87
+ comment = fields.StringField(_("Comment"), [validators.DataRequired()])
85
88
 
86
89
 
87
90
  class MemberForm(ModelForm):
88
91
  model_class = Member
89
92
 
90
93
  role = fields.SelectField(
91
- _('Role'), default='editor', choices=list(ORG_ROLES.items()),
92
- validators=[validators.DataRequired()])
94
+ _("Role"),
95
+ default="editor",
96
+ choices=list(ORG_ROLES.items()),
97
+ validators=[validators.DataRequired()],
98
+ )
@@ -1,5 +1,6 @@
1
- from udata.models import Dataset, Reuse, Organization
2
1
  from udata.core.owned import Owned
2
+ from udata.models import Dataset, Organization, Reuse
3
+
3
4
 
4
5
  @Dataset.on_create.connect
5
6
  @Dataset.on_update.connect
@@ -2,33 +2,46 @@ from datetime import datetime
2
2
  from itertools import chain
3
3
 
4
4
  from blinker import Signal
5
- from mongoengine.signals import pre_save, post_save
5
+ from mongoengine.signals import post_save, pre_save
6
6
  from werkzeug.utils import cached_property
7
7
 
8
8
  from udata.core.badges.models import BadgeMixin
9
9
  from udata.core.metrics.models import WithMetrics
10
10
  from udata.core.storages import avatars, default_image_basename
11
11
  from udata.frontend.markdown import mdstrip
12
- from udata.mongo import db
13
12
  from udata.i18n import lazy_gettext as _
13
+ from udata.mongo import db
14
14
  from udata.uris import endpoint_for
15
- from .constants import ASSOCIATION, CERTIFIED, COMPANY, LOCAL_AUTHORITY, LOGO_SIZES, ORG_BID_SIZE_LIMIT, ORG_ROLES, DEFAULT_ROLE, MEMBERSHIP_STATUS, LOGO_MAX_SIZE, PUBLIC_SERVICE
16
15
 
16
+ from .constants import (
17
+ ASSOCIATION,
18
+ CERTIFIED,
19
+ COMPANY,
20
+ DEFAULT_ROLE,
21
+ LOCAL_AUTHORITY,
22
+ LOGO_MAX_SIZE,
23
+ LOGO_SIZES,
24
+ MEMBERSHIP_STATUS,
25
+ ORG_BID_SIZE_LIMIT,
26
+ ORG_ROLES,
27
+ PUBLIC_SERVICE,
28
+ )
29
+
30
+ __all__ = ("Organization", "Team", "Member", "MembershipRequest")
17
31
 
18
- __all__ = ('Organization', 'Team', 'Member', 'MembershipRequest')
19
32
 
20
33
  class Team(db.EmbeddedDocument):
21
34
  name = db.StringField(required=True)
22
35
  slug = db.SlugField(
23
- max_length=255, required=True, populate_from='name', update=True,
24
- unique=False)
36
+ max_length=255, required=True, populate_from="name", update=True, unique=False
37
+ )
25
38
  description = db.StringField()
26
39
 
27
- members = db.ListField(db.ReferenceField('User'))
40
+ members = db.ListField(db.ReferenceField("User"))
28
41
 
29
42
 
30
43
  class Member(db.EmbeddedDocument):
31
- user = db.ReferenceField('User')
44
+ user = db.ReferenceField("User")
32
45
  role = db.StringField(choices=list(ORG_ROLES), default=DEFAULT_ROLE)
33
46
  since = db.DateTimeField(default=datetime.utcnow, required=True)
34
47
 
@@ -38,18 +51,18 @@ class Member(db.EmbeddedDocument):
38
51
 
39
52
 
40
53
  class MembershipRequest(db.EmbeddedDocument):
41
- '''
54
+ """
42
55
  Pending organization membership requests
43
- '''
56
+ """
57
+
44
58
  id = db.AutoUUIDField()
45
- user = db.ReferenceField('User')
46
- status = db.StringField(
47
- choices=list(MEMBERSHIP_STATUS), default='pending')
59
+ user = db.ReferenceField("User")
60
+ status = db.StringField(choices=list(MEMBERSHIP_STATUS), default="pending")
48
61
 
49
62
  created = db.DateTimeField(default=datetime.utcnow, required=True)
50
63
 
51
64
  handled_on = db.DateTimeField()
52
- handled_by = db.ReferenceField('User')
65
+ handled_by = db.ReferenceField("User")
53
66
 
54
67
  comment = db.StringField()
55
68
  refusal_comment = db.StringField()
@@ -73,13 +86,15 @@ class OrganizationQuerySet(db.BaseQuerySet):
73
86
  class Organization(WithMetrics, BadgeMixin, db.Datetimed, db.Document):
74
87
  name = db.StringField(required=True)
75
88
  acronym = db.StringField(max_length=128)
76
- slug = db.SlugField(max_length=255, required=True, populate_from='name',
77
- update=True, follow=True)
89
+ slug = db.SlugField(
90
+ max_length=255, required=True, populate_from="name", update=True, follow=True
91
+ )
78
92
  description = db.StringField(required=True)
79
93
  url = db.StringField()
80
94
  image_url = db.StringField()
81
- logo = db.ImageField(fs=avatars, basename=default_image_basename,
82
- max_size=LOGO_MAX_SIZE, thumbnails=LOGO_SIZES)
95
+ logo = db.ImageField(
96
+ fs=avatars, basename=default_image_basename, max_size=LOGO_MAX_SIZE, thumbnails=LOGO_SIZES
97
+ )
83
98
  business_number_id = db.StringField(max_length=ORG_BID_SIZE_LIMIT)
84
99
 
85
100
  members = db.ListField(db.EmbeddedDocumentField(Member))
@@ -93,38 +108,38 @@ class Organization(WithMetrics, BadgeMixin, db.Datetimed, db.Document):
93
108
  deleted = db.DateTimeField()
94
109
 
95
110
  meta = {
96
- 'indexes': [
97
- '$name',
98
- 'created_at',
99
- 'slug',
100
- 'metrics.reuses',
101
- 'metrics.datasets',
102
- 'metrics.followers',
103
- 'metrics.views',
104
- 'last_modified'
111
+ "indexes": [
112
+ "$name",
113
+ "created_at",
114
+ "slug",
115
+ "metrics.reuses",
116
+ "metrics.datasets",
117
+ "metrics.followers",
118
+ "metrics.views",
119
+ "last_modified",
105
120
  ],
106
- 'ordering': ['-created_at'],
107
- 'queryset_class': OrganizationQuerySet,
108
- 'auto_create_index_on_save': True
121
+ "ordering": ["-created_at"],
122
+ "queryset_class": OrganizationQuerySet,
123
+ "auto_create_index_on_save": True,
109
124
  }
110
125
 
111
126
  def __str__(self):
112
- return self.name or ''
127
+ return self.name or ""
113
128
 
114
129
  __badges__ = {
115
- PUBLIC_SERVICE: _('Public Service'),
116
- CERTIFIED: _('Certified'),
117
- ASSOCIATION: _('Association'),
118
- COMPANY: _('Company'),
119
- LOCAL_AUTHORITY: _('Local authority'),
130
+ PUBLIC_SERVICE: _("Public Service"),
131
+ CERTIFIED: _("Certified"),
132
+ ASSOCIATION: _("Association"),
133
+ COMPANY: _("Company"),
134
+ LOCAL_AUTHORITY: _("Local authority"),
120
135
  }
121
136
 
122
137
  __metrics_keys__ = [
123
- 'datasets',
124
- 'members',
125
- 'reuses',
126
- 'followers',
127
- 'views',
138
+ "datasets",
139
+ "members",
140
+ "reuses",
141
+ "followers",
142
+ "views",
128
143
  ]
129
144
 
130
145
  before_save = Signal()
@@ -141,13 +156,13 @@ class Organization(WithMetrics, BadgeMixin, db.Datetimed, db.Document):
141
156
  @classmethod
142
157
  def post_save(cls, sender, document, **kwargs):
143
158
  cls.after_save.send(document)
144
- if kwargs.get('created'):
159
+ if kwargs.get("created"):
145
160
  cls.on_create.send(document)
146
161
  else:
147
162
  cls.on_update.send(document)
148
163
 
149
164
  def url_for(self, *args, **kwargs):
150
- return endpoint_for('organizations.show', 'api.organization', org=self, *args, **kwargs)
165
+ return endpoint_for("organizations.show", "api.organization", org=self, *args, **kwargs)
151
166
 
152
167
  display_url = property(url_for)
153
168
 
@@ -157,15 +172,15 @@ class Organization(WithMetrics, BadgeMixin, db.Datetimed, db.Document):
157
172
 
158
173
  @property
159
174
  def pending_requests(self):
160
- return [r for r in self.requests if r.status == 'pending']
175
+ return [r for r in self.requests if r.status == "pending"]
161
176
 
162
177
  @property
163
178
  def refused_requests(self):
164
- return [r for r in self.requests if r.status == 'refused']
179
+ return [r for r in self.requests if r.status == "refused"]
165
180
 
166
181
  @property
167
182
  def accepted_requests(self):
168
- return [r for r in self.requests if r.status == 'accepted']
183
+ return [r for r in self.requests if r.status == "accepted"]
169
184
 
170
185
  @property
171
186
  def certified(self):
@@ -199,11 +214,11 @@ class Organization(WithMetrics, BadgeMixin, db.Datetimed, db.Document):
199
214
 
200
215
  def is_admin(self, user):
201
216
  member = self.member(user)
202
- return member is not None and member.role == 'admin'
217
+ return member is not None and member.role == "admin"
203
218
 
204
219
  def pending_request(self, user):
205
220
  for request in self.requests:
206
- if request.user == user and request.status == 'pending':
221
+ if request.user == user and request.status == "pending":
207
222
  return request
208
223
  return None
209
224
 
@@ -217,58 +232,63 @@ class Organization(WithMetrics, BadgeMixin, db.Datetimed, db.Document):
217
232
 
218
233
  def check_availability(self):
219
234
  from udata.models import Dataset # Circular imports.
235
+
220
236
  # Performances: only check the first 20 datasets for now.
221
237
  return chain(
222
- *[dataset.check_availability()
223
- for dataset in Dataset.objects(organization=self).visible()[:20]]
238
+ *[
239
+ dataset.check_availability()
240
+ for dataset in Dataset.objects(organization=self).visible()[:20]
241
+ ]
224
242
  )
225
243
 
226
244
  @cached_property
227
245
  def json_ld(self):
228
- type_ = 'GovernmentOrganization' if self.public_service \
229
- else 'Organization'
246
+ type_ = "GovernmentOrganization" if self.public_service else "Organization"
230
247
 
231
248
  result = {
232
- '@context': 'http://schema.org',
233
- '@type': type_,
234
- '@id': str(self.id),
235
- 'alternateName': self.slug,
236
- 'url': endpoint_for('organizations.show', 'api.organization', org=self, _external=True),
237
- 'name': self.name,
238
- 'dateCreated': self.created_at.isoformat(),
239
- 'dateModified': self.last_modified.isoformat()
249
+ "@context": "http://schema.org",
250
+ "@type": type_,
251
+ "@id": str(self.id),
252
+ "alternateName": self.slug,
253
+ "url": endpoint_for("organizations.show", "api.organization", org=self, _external=True),
254
+ "name": self.name,
255
+ "dateCreated": self.created_at.isoformat(),
256
+ "dateModified": self.last_modified.isoformat(),
240
257
  }
241
258
 
242
259
  if self.description:
243
- result['description'] = mdstrip(self.description)
260
+ result["description"] = mdstrip(self.description)
244
261
 
245
262
  logo = self.logo(external=True)
246
263
  if logo:
247
- result['logo'] = logo
264
+ result["logo"] = logo
248
265
 
249
266
  return result
250
267
 
251
268
  @property
252
269
  def views_count(self):
253
- return self.metrics.get('views', 0)
270
+ return self.metrics.get("views", 0)
254
271
 
255
272
  def count_members(self):
256
- self.metrics['members'] = len(self.members)
273
+ self.metrics["members"] = len(self.members)
257
274
  self.save()
258
275
 
259
276
  def count_datasets(self):
260
277
  from udata.models import Dataset
261
- self.metrics['datasets'] = Dataset.objects(organization=self).visible().count()
278
+
279
+ self.metrics["datasets"] = Dataset.objects(organization=self).visible().count()
262
280
  self.save()
263
281
 
264
282
  def count_reuses(self):
265
283
  from udata.models import Reuse
266
- self.metrics['reuses'] = Reuse.objects(organization=self).visible().count()
284
+
285
+ self.metrics["reuses"] = Reuse.objects(organization=self).visible().count()
267
286
  self.save()
268
287
 
269
288
  def count_followers(self):
270
289
  from udata.models import Follow
271
- self.metrics['followers'] = Follow.objects(until=None).followers(self).count()
290
+
291
+ self.metrics["followers"] = Follow.objects(until=None).followers(self).count()
272
292
  self.save()
273
293
 
274
294
 
@@ -1,27 +1,31 @@
1
- from udata.features.notifications.actions import notifier
2
-
3
-
4
1
  import logging
5
2
 
3
+ from udata.features.notifications.actions import notifier
4
+
6
5
  log = logging.getLogger(__name__)
7
6
 
8
7
 
9
- @notifier('membership_request')
8
+ @notifier("membership_request")
10
9
  def membership_request_notifications(user):
11
- '''Notify user about pending membership requests'''
10
+ """Notify user about pending membership requests"""
12
11
  orgs = [o for o in user.organizations if o.is_admin(user)]
13
12
  notifications = []
14
13
 
15
14
  for org in orgs:
16
15
  for request in org.pending_requests:
17
- notifications.append((request.created, {
18
- 'id': request.id,
19
- 'organization': org.id,
20
- 'user': {
21
- 'id': request.user.id,
22
- 'fullname': request.user.fullname,
23
- 'avatar': str(request.user.avatar)
24
- }
25
- }))
16
+ notifications.append(
17
+ (
18
+ request.created,
19
+ {
20
+ "id": request.id,
21
+ "organization": org.id,
22
+ "user": {
23
+ "id": request.user.id,
24
+ "fullname": request.user.fullname,
25
+ "avatar": str(request.user.avatar),
26
+ },
27
+ },
28
+ )
29
+ )
26
30
 
27
31
  return notifications
@@ -1,29 +1,29 @@
1
1
  from collections import namedtuple
2
2
  from functools import partial
3
3
 
4
- from udata.auth import current_user, identity_loaded, Permission
4
+ from udata.auth import Permission, current_user, identity_loaded
5
5
  from udata.models import Organization
6
6
  from udata.utils import get_by
7
7
 
8
-
9
- OrganizationNeed = namedtuple('organization', ('role', 'value'))
10
- OrganizationAdminNeed = partial(OrganizationNeed, 'admin')
11
- OrganizationEditorNeed = partial(OrganizationNeed, 'editor')
8
+ OrganizationNeed = namedtuple("organization", ("role", "value"))
9
+ OrganizationAdminNeed = partial(OrganizationNeed, "admin")
10
+ OrganizationEditorNeed = partial(OrganizationNeed, "editor")
12
11
 
13
12
 
14
13
  class EditOrganizationPermission(Permission):
15
- '''Permissions to edit organization assets'''
14
+ """Permissions to edit organization assets"""
15
+
16
16
  def __init__(self, org):
17
17
  need = OrganizationAdminNeed(org.id)
18
18
  super(EditOrganizationPermission, self).__init__(need)
19
19
 
20
20
 
21
21
  class OrganizationPrivatePermission(Permission):
22
- '''Permission to see organization private assets'''
22
+ """Permission to see organization private assets"""
23
+
23
24
  def __init__(self, org):
24
25
  super(OrganizationPrivatePermission, self).__init__(
25
- OrganizationAdminNeed(org.id),
26
- OrganizationEditorNeed(org.id)
26
+ OrganizationAdminNeed(org.id), OrganizationEditorNeed(org.id)
27
27
  )
28
28
 
29
29
 
@@ -31,6 +31,5 @@ class OrganizationPrivatePermission(Permission):
31
31
  def inject_organization_needs(sender, identity):
32
32
  if current_user.is_authenticated:
33
33
  for org in Organization.objects(members__user=current_user.id):
34
- membership = get_by(org.members, 'user',
35
- current_user._get_current_object())
34
+ membership = get_by(org.members, "user", current_user._get_current_object())
36
35
  identity.provides.add(OrganizationNeed(membership.role, org.id))
@@ -1,27 +1,27 @@
1
- '''
1
+ """
2
2
  This module centralize organization helpers
3
3
  for RDF/DCAT serialization and parsing
4
- '''
4
+ """
5
5
 
6
6
  from flask import url_for
7
- from rdflib import Graph, URIRef, Literal, BNode
8
- from rdflib.namespace import RDF, RDFS, FOAF
9
-
10
- from udata.rdf import DCAT, DCT, namespace_manager, paginate_catalog
7
+ from rdflib import BNode, Graph, Literal, URIRef
8
+ from rdflib.namespace import FOAF, RDF, RDFS
11
9
 
12
10
  from udata.core.dataset.rdf import dataset_to_rdf
13
- from udata.utils import Paginable
11
+ from udata.rdf import DCAT, DCT, namespace_manager, paginate_catalog
14
12
  from udata.uris import endpoint_for
13
+ from udata.utils import Paginable
15
14
 
16
15
 
17
16
  def organization_to_rdf(org, graph=None):
18
- '''
17
+ """
19
18
  Map a Resource domain model to a DCAT/RDF graph
20
- '''
19
+ """
21
20
  graph = graph or Graph(namespace_manager=namespace_manager)
22
21
  if org.id:
23
- org_url = endpoint_for('organizations.show_redirect', 'api.organization',
24
- org=org.id, _external=True)
22
+ org_url = endpoint_for(
23
+ "organizations.show_redirect", "api.organization", org=org.id, _external=True
24
+ )
25
25
  id = URIRef(org_url)
26
26
  else:
27
27
  id = BNode()
@@ -37,7 +37,7 @@ def organization_to_rdf(org, graph=None):
37
37
 
38
38
  def build_org_catalog(org, datasets, format=None):
39
39
  graph = Graph(namespace_manager=namespace_manager)
40
- org_catalog_url = url_for('api.organization_rdf', org=org.id, _external=True)
40
+ org_catalog_url = url_for("api.organization_rdf", org=org.id, _external=True)
41
41
 
42
42
  catalog = graph.resource(URIRef(org_catalog_url))
43
43
  catalog.set(RDF.type, DCAT.Catalog)
@@ -48,9 +48,9 @@ def build_org_catalog(org, datasets, format=None):
48
48
  for dataset in datasets:
49
49
  catalog.add(DCAT.dataset, dataset_to_rdf(dataset, graph))
50
50
 
51
- values = {'org': org.id}
51
+ values = {"org": org.id}
52
52
 
53
53
  if isinstance(datasets, Paginable):
54
- paginate_catalog(catalog, graph, datasets, format, 'api.organization_rdf_format', **values)
54
+ paginate_catalog(catalog, graph, datasets, format, "api.organization_rdf_format", **values)
55
55
 
56
56
  return catalog
@@ -1,30 +1,28 @@
1
1
  import datetime
2
+
2
3
  from udata import search
4
+ from udata.core.organization.api import DEFAULT_SORTING, OrgApiParser
3
5
  from udata.models import Organization
4
6
  from udata.search.fields import Filter
5
- from udata.core.organization.api import OrgApiParser, DEFAULT_SORTING
6
7
  from udata.utils import to_iso_datetime
7
8
 
8
-
9
- __all__ = ('OrganizationSearch', )
9
+ __all__ = ("OrganizationSearch",)
10
10
 
11
11
 
12
12
  @search.register
13
13
  class OrganizationSearch(search.ModelSearchAdapter):
14
14
  model = Organization
15
- search_url = 'organizations/'
15
+ search_url = "organizations/"
16
16
 
17
17
  sorts = {
18
- 'reuses': 'metrics.reuses',
19
- 'datasets': 'metrics.datasets',
20
- 'followers': 'metrics.followers',
21
- 'views': 'metrics.views',
22
- 'created': 'created_at'
18
+ "reuses": "metrics.reuses",
19
+ "datasets": "metrics.datasets",
20
+ "followers": "metrics.followers",
21
+ "views": "metrics.views",
22
+ "created": "created_at",
23
23
  }
24
24
 
25
- filters = {
26
- 'badge': Filter()
27
- }
25
+ filters = {"badge": Filter()}
28
26
 
29
27
  @classmethod
30
28
  def is_indexable(cls, org):
@@ -35,9 +33,13 @@ class OrganizationSearch(search.ModelSearchAdapter):
35
33
  orgs = Organization.objects(deleted=None)
36
34
  orgs = OrgApiParser.parse_filters(orgs, args)
37
35
 
38
- sort = cls.parse_sort(args['sort']) or ('$text_score' if args['q'] else None) or DEFAULT_SORTING
39
- offset = (args['page'] - 1) * args['page_size']
40
- return orgs.order_by(sort).skip(offset).limit(args['page_size']), orgs.count()
36
+ sort = (
37
+ cls.parse_sort(args["sort"])
38
+ or ("$text_score" if args["q"] else None)
39
+ or DEFAULT_SORTING
40
+ )
41
+ offset = (args["page"] - 1) * args["page_size"]
42
+ return orgs.order_by(sort).skip(offset).limit(args["page_size"]), orgs.count()
41
43
 
42
44
  @classmethod
43
45
  def serialize(cls, organization):
@@ -45,17 +47,17 @@ class OrganizationSearch(search.ModelSearchAdapter):
45
47
  for key, value in organization.extras.items():
46
48
  extras[key] = to_iso_datetime(value) if isinstance(value, datetime.datetime) else value
47
49
  return {
48
- 'id': str(organization.id),
49
- 'name': organization.name,
50
- 'acronym': organization.acronym if organization.acronym else None,
51
- 'description': organization.description,
52
- 'url': organization.url,
53
- 'badges': [badge.kind for badge in organization.badges],
54
- 'created_at': to_iso_datetime(organization.created_at),
55
- 'orga_sp': 1 if organization.public_service else 0,
56
- 'followers': organization.metrics.get('followers', 0),
57
- 'datasets': organization.metrics.get('datasets', 0),
58
- 'reuses': organization.metrics.get('reuses', 0),
59
- 'views': organization.metrics.get('views', 0),
60
- 'extras': extras
50
+ "id": str(organization.id),
51
+ "name": organization.name,
52
+ "acronym": organization.acronym if organization.acronym else None,
53
+ "description": organization.description,
54
+ "url": organization.url,
55
+ "badges": [badge.kind for badge in organization.badges],
56
+ "created_at": to_iso_datetime(organization.created_at),
57
+ "orga_sp": 1 if organization.public_service else 0,
58
+ "followers": organization.metrics.get("followers", 0),
59
+ "datasets": organization.metrics.get("datasets", 0),
60
+ "reuses": organization.metrics.get("reuses", 0),
61
+ "views": organization.metrics.get("views", 0),
62
+ "extras": extras,
61
63
  }