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
@@ -1,6 +1,6 @@
1
1
  import logging
2
- import pytest
3
2
 
3
+ import pytest
4
4
  from voluptuous import Invalid
5
5
 
6
6
  from udata.harvest import filters
@@ -10,11 +10,23 @@ log = logging.getLogger(__name__)
10
10
 
11
11
  class FiltersTest:
12
12
  def test_boolean(self):
13
- true_values = ('1', 'on', 't', 'TRUE', 'true', 'y', 'yes', ' 1 ',
14
- ' tRuE ', True, 1, 2, -1)
15
- false_values = ('0', 'f', 'FALSE', 'false', 'n', 'no', 'off', ' 0 ',
16
- ' f ', False, 0)
17
- none_values = ('', ' ', None)
13
+ true_values = (
14
+ "1",
15
+ "on",
16
+ "t",
17
+ "TRUE",
18
+ "true",
19
+ "y",
20
+ "yes",
21
+ " 1 ",
22
+ " tRuE ",
23
+ True,
24
+ 1,
25
+ 2,
26
+ -1,
27
+ )
28
+ false_values = ("0", "f", "FALSE", "false", "n", "no", "off", " 0 ", " f ", False, 0)
29
+ none_values = ("", " ", None)
18
30
 
19
31
  for value in true_values:
20
32
  assert filters.boolean(value)
@@ -26,11 +38,11 @@ class FiltersTest:
26
38
  assert filters.boolean(value) is None
27
39
 
28
40
  with pytest.raises(Invalid):
29
- filters.boolean('vrai')
41
+ filters.boolean("vrai")
30
42
 
31
43
  def test_empty_none(self):
32
- empty_values = 0, '', [], {}
33
- non_empty_values = 'hello', ' hello '
44
+ empty_values = 0, "", [], {}
45
+ non_empty_values = "hello", " hello "
34
46
 
35
47
  for value in empty_values:
36
48
  assert filters.empty_none(value) is None
@@ -39,39 +51,38 @@ class FiltersTest:
39
51
  assert filters.empty_none(value) == value
40
52
 
41
53
  def test_strip(self):
42
- assert filters.strip(' hello ') == 'hello'
43
- assert filters.strip(' ') is None
54
+ assert filters.strip(" hello ") == "hello"
55
+ assert filters.strip(" ") is None
44
56
 
45
57
  def test_line_endings(self):
46
- result = filters.line_endings('hello\r\nworld!\r ')
47
- assert result == 'hello\nworld!\n '
58
+ result = filters.line_endings("hello\r\nworld!\r ")
59
+ assert result == "hello\nworld!\n "
48
60
 
49
61
  def test_hash(self):
50
62
  hashes = {
51
- 'md5': 'bd8668597bfba2d1843441d7199bea65',
52
- 'sha1': 'f2f0249827f501286b4713683e526d541d2cc7e2',
53
- 'sha256': ('c4373e1d81eb44882bf9ff539d0e5f'
54
- 'faf03a114abf9306591117d781966268f9')
63
+ "md5": "bd8668597bfba2d1843441d7199bea65",
64
+ "sha1": "f2f0249827f501286b4713683e526d541d2cc7e2",
65
+ "sha256": ("c4373e1d81eb44882bf9ff539d0e5f" "faf03a114abf9306591117d781966268f9"),
55
66
  }
56
67
 
57
68
  for type, value in hashes.items():
58
- assert filters.hash(value) == {'type': type, 'value': value}
69
+ assert filters.hash(value) == {"type": type, "value": value}
59
70
 
60
71
  def test_unknown_hash(self):
61
- assert filters.hash('xxxx') is None
72
+ assert filters.hash("xxxx") is None
62
73
  assert filters.hash(None) is None
63
74
 
64
75
 
65
76
  class IsUrlFilterTest:
66
77
  def test_valid_url_with_defaults(self):
67
78
  f = filters.is_url()
68
- assert f('https://somewhere.com/path') == 'https://somewhere.com/path'
79
+ assert f("https://somewhere.com/path") == "https://somewhere.com/path"
69
80
 
70
81
  def test_allowed_scheme_not_allowed(self):
71
82
  f = filters.is_url()
72
83
  with pytest.raises(Invalid):
73
- f('not-allowed://somewhere.com')
84
+ f("not-allowed://somewhere.com")
74
85
 
75
86
  def test_valid_url_with_default_scheme(self):
76
87
  f = filters.is_url()
77
- assert f('somewhere.com/path') == 'http://somewhere.com/path'
88
+ assert f("somewhere.com/path") == "http://somewhere.com/path"
@@ -1,30 +1,27 @@
1
1
  import logging
2
+
2
3
  import pytest
3
4
 
4
5
  from udata.utils import faker
5
6
 
6
7
  from ..models import HarvestSource
7
8
 
8
-
9
9
  log = logging.getLogger(__name__)
10
10
 
11
11
 
12
- @pytest.mark.usefixtures('clean_db')
12
+ @pytest.mark.usefixtures("clean_db")
13
13
  class HarvestSourceTest:
14
14
  def test_defaults(self):
15
- source = HarvestSource.objects.create(name='Test', url=faker.url(), backend='factory')
16
- assert source.name == 'Test'
17
- assert source.slug == 'test'
15
+ source = HarvestSource.objects.create(name="Test", url=faker.url(), backend="factory")
16
+ assert source.name == "Test"
17
+ assert source.slug == "test"
18
18
 
19
19
  def test_domain(self):
20
- source = HarvestSource(name='Test',
21
- url='http://www.somewhere.com/path/')
22
- assert source.domain == 'www.somewhere.com'
20
+ source = HarvestSource(name="Test", url="http://www.somewhere.com/path/")
21
+ assert source.domain == "www.somewhere.com"
23
22
 
24
- source = HarvestSource(name='Test',
25
- url='https://www.somewhere.com/path/')
26
- assert source.domain == 'www.somewhere.com'
23
+ source = HarvestSource(name="Test", url="https://www.somewhere.com/path/")
24
+ assert source.domain == "www.somewhere.com"
27
25
 
28
- source = HarvestSource(name='Test',
29
- url='http://www.somewhere.com:666/path/')
30
- assert source.domain == 'www.somewhere.com'
26
+ source = HarvestSource(name="Test", url="http://www.somewhere.com:666/path/")
27
+ assert source.domain == "www.somewhere.com"
@@ -1,14 +1,13 @@
1
1
  import pytest
2
2
 
3
- from udata.core.user.factories import UserFactory, AdminFactory
4
-
5
- from .factories import HarvestSourceFactory
6
-
3
+ from udata.core.user.factories import AdminFactory, UserFactory
7
4
  from udata.harvest.notifications import validate_harvester_notifications
8
5
  from udata.tests.helpers import assert_equal_dates
9
6
 
7
+ from .factories import HarvestSourceFactory
8
+
10
9
 
11
- @pytest.mark.usefixtures('clean_db')
10
+ @pytest.mark.usefixtures("clean_db")
12
11
  class HarvestNotificationsTest:
13
12
  def test_pending_harvester_validations(self):
14
13
  source = HarvestSourceFactory()
@@ -22,5 +21,5 @@ class HarvestNotificationsTest:
22
21
  assert len(notifications) == 1
23
22
  dt, details = notifications[0]
24
23
  assert_equal_dates(dt, source.created_at)
25
- assert details['id'] == source.id
26
- assert details['name'] == source.name
24
+ assert details["id"] == source.id
25
+ assert details["name"] == source.name
@@ -1,21 +1,22 @@
1
1
  import logging
2
+
2
3
  import pytest
3
4
 
4
- from ..tasks import purge_harvest_sources, purge_harvest_jobs
5
+ from ..tasks import purge_harvest_jobs, purge_harvest_sources
5
6
 
6
7
  log = logging.getLogger(__name__)
7
8
 
8
9
 
9
- @pytest.mark.usefixtures('clean_db')
10
+ @pytest.mark.usefixtures("clean_db")
10
11
  class HarvestActionsTest:
11
12
  def test_purge_sources(self, mocker):
12
- '''It should purge from DB sources flagged as deleted'''
13
- mock = mocker.patch('udata.harvest.actions.purge_sources')
13
+ """It should purge from DB sources flagged as deleted"""
14
+ mock = mocker.patch("udata.harvest.actions.purge_sources")
14
15
  purge_harvest_sources()
15
16
  mock.assert_called_once_with()
16
17
 
17
18
  def test_purge_jobs(self, mocker):
18
- '''It should purge from DB jobs older than retention policy'''
19
- mock = mocker.patch('udata.harvest.actions.purge_jobs')
19
+ """It should purge from DB jobs older than retention policy"""
20
+ mock = mocker.patch("udata.harvest.actions.purge_jobs")
20
21
  purge_harvest_jobs()
21
22
  mock.assert_called_once_with()
udata/i18n.py CHANGED
@@ -1,23 +1,23 @@
1
1
  import importlib.util
2
-
3
2
  from contextlib import contextmanager
4
- from os.path import join, dirname, basename
3
+ from datetime import datetime
5
4
  from glob import iglob
5
+ from os.path import basename, dirname, join
6
6
 
7
+ import flask_babel
8
+ from babel.dates import format_timedelta as babel_format_timedelta
7
9
  from flask import ( # noqa
8
- g, request, current_app, abort, redirect, url_for, has_request_context
10
+ abort,
11
+ current_app,
12
+ g,
13
+ has_request_context,
14
+ redirect,
15
+ request,
16
+ url_for,
9
17
  )
10
18
  from flask.blueprints import BlueprintSetupState, _endpoint_from_view_func
11
-
12
- from babel.dates import format_timedelta as babel_format_timedelta
13
-
14
- from datetime import datetime
15
-
16
- import flask_babel
17
- from flask_babel import Babel, refresh
18
- from flask_babel import format_date, format_datetime # noqa
19
+ from flask_babel import Babel, format_date, format_datetime, refresh # noqa
19
20
  from flask_babel import get_locale as get_current_locale # noqa
20
-
21
21
  from werkzeug.local import LocalProxy
22
22
 
23
23
  from udata import entrypoints
@@ -36,8 +36,9 @@ def get_translation_directories_and_domains():
36
36
  spec = importlib.util.find_spec(pkg)
37
37
  path = dirname(spec.origin)
38
38
  plugin_domains = [
39
- f.replace(path, '').replace('.pot', '')[1:]
40
- for f in iglob(join(path, '**/translations/*.pot'), recursive=True)]
39
+ f.replace(path, "").replace(".pot", "")[1:]
40
+ for f in iglob(join(path, "**/translations/*.pot"), recursive=True)
41
+ ]
41
42
  for domain in plugin_domains:
42
43
  translations_dir.append(join(path, dirname(domain)))
43
44
  domains.append(basename(domain))
@@ -46,7 +47,7 @@ def get_translation_directories_and_domains():
46
47
 
47
48
 
48
49
  def get_locale():
49
- if getattr(g, 'lang_code', None):
50
+ if getattr(g, "lang_code", None):
50
51
  return g.lang_code
51
52
  return str(default_lang)
52
53
 
@@ -88,22 +89,25 @@ def lazy_pgettext(*args, **kwargs):
88
89
  return flask_babel.lazy_pgettext(*args, **kwargs)
89
90
 
90
91
 
91
- def format_timedelta(datetime_or_timedelta, granularity='second',
92
- add_direction=False, threshold=0.85):
93
- '''This is format_timedelta from Flask-Babel'''
94
- '''Flask-BabelEx missed the add_direction parameter'''
92
+ def format_timedelta(
93
+ datetime_or_timedelta, granularity="second", add_direction=False, threshold=0.85
94
+ ):
95
+ """This is format_timedelta from Flask-Babel"""
96
+ """Flask-BabelEx missed the add_direction parameter"""
95
97
  if isinstance(datetime_or_timedelta, datetime):
96
98
  datetime_or_timedelta = datetime.utcnow() - datetime_or_timedelta
97
- return babel_format_timedelta(datetime_or_timedelta,
98
- granularity,
99
- threshold=threshold,
100
- add_direction=add_direction,
101
- locale=get_current_locale())
99
+ return babel_format_timedelta(
100
+ datetime_or_timedelta,
101
+ granularity,
102
+ threshold=threshold,
103
+ add_direction=add_direction,
104
+ locale=get_current_locale(),
105
+ )
102
106
 
103
107
 
104
108
  def _default_lang(user=None):
105
- lang = getattr(user or current_user, 'prefered_language', None)
106
- return lang or current_app.config['DEFAULT_LANGUAGE']
109
+ lang = getattr(user or current_user, "prefered_language", None)
110
+ return lang or current_app.config["DEFAULT_LANGUAGE"]
107
111
 
108
112
 
109
113
  default_lang = LocalProxy(lambda: _default_lang())
@@ -111,12 +115,12 @@ default_lang = LocalProxy(lambda: _default_lang())
111
115
 
112
116
  @contextmanager
113
117
  def language(lang_code):
114
- '''Force a given language'''
118
+ """Force a given language"""
115
119
  ctx = None
116
120
  if not request:
117
121
  ctx = current_app.test_request_context()
118
122
  ctx.push()
119
- backup = g.get('lang_code')
123
+ backup = g.get("lang_code")
120
124
  g.lang_code = lang_code
121
125
  refresh()
122
126
  yield
@@ -127,10 +131,13 @@ def language(lang_code):
127
131
 
128
132
 
129
133
  def check_config(cfg):
130
- default_language = cfg['DEFAULT_LANGUAGE']
131
- if default_language not in cfg.get('LANGUAGES', []):
132
- raise ConfigError('You are using a DEFAULT_LANGUAGE {0} not defined '
133
- 'into LANGUAGES'.format(default_language))
134
+ default_language = cfg["DEFAULT_LANGUAGE"]
135
+ if default_language not in cfg.get("LANGUAGES", []):
136
+ raise ConfigError(
137
+ "You are using a DEFAULT_LANGUAGE {0} not defined " "into LANGUAGES".format(
138
+ default_language
139
+ )
140
+ )
134
141
 
135
142
 
136
143
  def init_app(app):
@@ -138,44 +145,43 @@ def init_app(app):
138
145
  translations_dir, domains = get_translation_directories_and_domains()
139
146
  Babel(
140
147
  app,
141
- default_locale=app.config['DEFAULT_LANGUAGE'],
142
- default_translation_directories=';'.join(translations_dir),
143
- default_domain=';'.join(domains),
144
- locale_selector=get_locale
148
+ default_locale=app.config["DEFAULT_LANGUAGE"],
149
+ default_translation_directories=";".join(translations_dir),
150
+ default_domain=";".join(domains),
151
+ locale_selector=get_locale,
145
152
  )
146
153
 
147
154
 
148
155
  def _add_language_code(endpoint, values):
149
156
  try:
150
- if current_app.url_map.is_endpoint_expecting(endpoint, 'lang_code'):
151
- values.setdefault('lang_code', g.get('lang_code') or get_locale())
157
+ if current_app.url_map.is_endpoint_expecting(endpoint, "lang_code"):
158
+ values.setdefault("lang_code", g.get("lang_code") or get_locale())
152
159
  except KeyError: # Endpoint does not exist
153
160
  pass
154
161
 
155
162
 
156
163
  def _pull_lang_code(endpoint, values):
157
- lang_code = values.pop('lang_code', g.get('lang_code') or get_locale())
158
- if lang_code not in current_app.config['LANGUAGES']:
159
- abort(redirect(
160
- url_for(endpoint, lang_code=default_lang, **values)))
164
+ lang_code = values.pop("lang_code", g.get("lang_code") or get_locale())
165
+ if lang_code not in current_app.config["LANGUAGES"]:
166
+ abort(redirect(url_for(endpoint, lang_code=default_lang, **values)))
161
167
  g.lang_code = lang_code
162
168
 
163
169
 
164
170
  def redirect_to_lang(*args, **kwargs):
165
- '''Redirect non lang-prefixed urls to default language.'''
166
- endpoint = request.endpoint.replace('_redirect', '')
171
+ """Redirect non lang-prefixed urls to default language."""
172
+ endpoint = request.endpoint.replace("_redirect", "")
167
173
  kwargs = multi_to_dict(request.args)
168
174
  kwargs.update(request.view_args)
169
- kwargs['lang_code'] = default_lang
175
+ kwargs["lang_code"] = default_lang
170
176
  return redirect(url_for(endpoint, **kwargs))
171
177
 
172
178
 
173
179
  def redirect_to_unlocalized(*args, **kwargs):
174
- '''Redirect lang-prefixed urls to no prefixed URL.'''
175
- endpoint = request.endpoint.replace('_redirect', '')
180
+ """Redirect lang-prefixed urls to no prefixed URL."""
181
+ endpoint = request.endpoint.replace("_redirect", "")
176
182
  kwargs = multi_to_dict(request.args)
177
183
  kwargs.update(request.view_args)
178
- kwargs.pop('lang_code', None)
184
+ kwargs.pop("lang_code", None)
179
185
  return redirect(url_for(endpoint, **kwargs))
180
186
 
181
187
 
@@ -187,35 +193,51 @@ class I18nBlueprintSetupState(BlueprintSetupState):
187
193
  The URL rule is registered twice.
188
194
  """
189
195
  # Static assets are not localized
190
- if endpoint == 'static':
196
+ if endpoint == "static":
191
197
  return super(I18nBlueprintSetupState, self).add_url_rule(
192
- rule, endpoint=endpoint, view_func=view_func, **options)
198
+ rule, endpoint=endpoint, view_func=view_func, **options
199
+ )
193
200
  if self.url_prefix:
194
201
  rule = self.url_prefix + rule
195
- options.setdefault('subdomain', self.subdomain)
202
+ options.setdefault("subdomain", self.subdomain)
196
203
  if endpoint is None:
197
204
  endpoint = _endpoint_from_view_func(view_func)
198
205
  defaults = self.url_defaults
199
- if 'defaults' in options:
200
- defaults = dict(defaults, **options.pop('defaults'))
206
+ if "defaults" in options:
207
+ defaults = dict(defaults, **options.pop("defaults"))
201
208
 
202
- if options.pop('localize', True):
203
- self.app.add_url_rule('/<lang:lang_code>' + rule,
204
- '%s.%s' % (self.blueprint.name, endpoint),
205
- view_func, defaults=defaults, **options)
209
+ if options.pop("localize", True):
210
+ self.app.add_url_rule(
211
+ "/<lang:lang_code>" + rule,
212
+ "%s.%s" % (self.blueprint.name, endpoint),
213
+ view_func,
214
+ defaults=defaults,
215
+ **options,
216
+ )
206
217
 
207
218
  self.app.add_url_rule(
208
- rule, '%s.%s_redirect' % (self.blueprint.name, endpoint),
209
- redirect_to_lang, defaults=defaults, **options)
219
+ rule,
220
+ "%s.%s_redirect" % (self.blueprint.name, endpoint),
221
+ redirect_to_lang,
222
+ defaults=defaults,
223
+ **options,
224
+ )
210
225
  else:
211
- self.app.add_url_rule(rule,
212
- '%s.%s' % (self.blueprint.name, endpoint),
213
- view_func, defaults=defaults, **options)
226
+ self.app.add_url_rule(
227
+ rule,
228
+ "%s.%s" % (self.blueprint.name, endpoint),
229
+ view_func,
230
+ defaults=defaults,
231
+ **options,
232
+ )
214
233
 
215
234
  self.app.add_url_rule(
216
- '/<lang:lang_code>' + rule,
217
- '%s.%s_redirect' % (self.blueprint.name, endpoint),
218
- redirect_to_unlocalized, defaults=defaults, **options)
235
+ "/<lang:lang_code>" + rule,
236
+ "%s.%s_redirect" % (self.blueprint.name, endpoint),
237
+ redirect_to_unlocalized,
238
+ defaults=defaults,
239
+ **options,
240
+ )
219
241
 
220
242
 
221
243
  class I18nBlueprint(Blueprint):
@@ -229,17 +251,154 @@ class I18nBlueprint(Blueprint):
229
251
 
230
252
 
231
253
  ISO_639_1_CODES = (
232
- 'aa', 'ab', 'af', 'am', 'an', 'ar', 'as', 'ay', 'az', 'ba', 'be', 'bg',
233
- 'bh', 'bi', 'bn', 'bo', 'br', 'ca', 'co', 'cs', 'cy', 'da', 'de', 'dz',
234
- 'el', 'en', 'eo', 'es', 'et', 'eu', 'fa', 'fi', 'fj', 'fo', 'fr', 'fy',
235
- 'ga', 'gd', 'gl', 'gn', 'gu', 'gv', 'ha', 'he', 'hi', 'hr', 'ht', 'hu',
236
- 'hy', 'ia', 'id', 'ie', 'ii', 'ik', 'in', 'io', 'is', 'it', 'iu', 'iw',
237
- 'ja', 'ji', 'jv', 'ka', 'kk', 'kl', 'km', 'kn', 'ko', 'ks', 'ku', 'ky',
238
- 'la', 'li', 'ln', 'lo', 'lt', 'lv', 'mg', 'mi', 'mk', 'ml', 'mn', 'mo',
239
- 'mr', 'ms', 'mt', 'my', 'na', 'ne', 'nl', 'no', 'oc', 'om', 'or', 'pa',
240
- 'pl', 'ps', 'pt', 'qu', 'rm', 'rn', 'ro', 'ru', 'rw', 'sa', 'sd', 'sg',
241
- 'sh', 'si', 'sk', 'sl', 'sm', 'sn', 'so', 'sq', 'sr', 'ss', 'st', 'su',
242
- 'sv', 'sw', 'ta', 'te', 'tg', 'th', 'ti', 'tk', 'tl', 'tn', 'to', 'tr',
243
- 'ts', 'tt', 'tw', 'ug', 'uk', 'ur', 'uz', 'vi', 'vo', 'wa', 'wo', 'xh',
244
- 'yi', 'yo', 'zh', 'zh-Hans', 'zh-Hant', 'zu'
254
+ "aa",
255
+ "ab",
256
+ "af",
257
+ "am",
258
+ "an",
259
+ "ar",
260
+ "as",
261
+ "ay",
262
+ "az",
263
+ "ba",
264
+ "be",
265
+ "bg",
266
+ "bh",
267
+ "bi",
268
+ "bn",
269
+ "bo",
270
+ "br",
271
+ "ca",
272
+ "co",
273
+ "cs",
274
+ "cy",
275
+ "da",
276
+ "de",
277
+ "dz",
278
+ "el",
279
+ "en",
280
+ "eo",
281
+ "es",
282
+ "et",
283
+ "eu",
284
+ "fa",
285
+ "fi",
286
+ "fj",
287
+ "fo",
288
+ "fr",
289
+ "fy",
290
+ "ga",
291
+ "gd",
292
+ "gl",
293
+ "gn",
294
+ "gu",
295
+ "gv",
296
+ "ha",
297
+ "he",
298
+ "hi",
299
+ "hr",
300
+ "ht",
301
+ "hu",
302
+ "hy",
303
+ "ia",
304
+ "id",
305
+ "ie",
306
+ "ii",
307
+ "ik",
308
+ "in",
309
+ "io",
310
+ "is",
311
+ "it",
312
+ "iu",
313
+ "iw",
314
+ "ja",
315
+ "ji",
316
+ "jv",
317
+ "ka",
318
+ "kk",
319
+ "kl",
320
+ "km",
321
+ "kn",
322
+ "ko",
323
+ "ks",
324
+ "ku",
325
+ "ky",
326
+ "la",
327
+ "li",
328
+ "ln",
329
+ "lo",
330
+ "lt",
331
+ "lv",
332
+ "mg",
333
+ "mi",
334
+ "mk",
335
+ "ml",
336
+ "mn",
337
+ "mo",
338
+ "mr",
339
+ "ms",
340
+ "mt",
341
+ "my",
342
+ "na",
343
+ "ne",
344
+ "nl",
345
+ "no",
346
+ "oc",
347
+ "om",
348
+ "or",
349
+ "pa",
350
+ "pl",
351
+ "ps",
352
+ "pt",
353
+ "qu",
354
+ "rm",
355
+ "rn",
356
+ "ro",
357
+ "ru",
358
+ "rw",
359
+ "sa",
360
+ "sd",
361
+ "sg",
362
+ "sh",
363
+ "si",
364
+ "sk",
365
+ "sl",
366
+ "sm",
367
+ "sn",
368
+ "so",
369
+ "sq",
370
+ "sr",
371
+ "ss",
372
+ "st",
373
+ "su",
374
+ "sv",
375
+ "sw",
376
+ "ta",
377
+ "te",
378
+ "tg",
379
+ "th",
380
+ "ti",
381
+ "tk",
382
+ "tl",
383
+ "tn",
384
+ "to",
385
+ "tr",
386
+ "ts",
387
+ "tt",
388
+ "tw",
389
+ "ug",
390
+ "uk",
391
+ "ur",
392
+ "uz",
393
+ "vi",
394
+ "vo",
395
+ "wa",
396
+ "wo",
397
+ "xh",
398
+ "yi",
399
+ "yo",
400
+ "zh",
401
+ "zh-Hans",
402
+ "zh-Hant",
403
+ "zu",
245
404
  )
@@ -8,30 +8,24 @@ from udata.entrypoints import get_enabled
8
8
  log = logging.getLogger(__name__)
9
9
 
10
10
 
11
- ENTRYPOINT = 'udata.linkcheckers'
11
+ ENTRYPOINT = "udata.linkcheckers"
12
12
 
13
13
 
14
14
  class NoCheckLinkchecker(object):
15
15
  """Dummy linkchecker for resources that need no check"""
16
16
 
17
17
  def check(self, _):
18
- return {
19
- 'check:status': 204,
20
- 'check:available': True,
21
- 'check:date': datetime.utcnow()
22
- }
18
+ return {"check:status": 204, "check:available": True, "check:date": datetime.utcnow()}
23
19
 
24
20
 
25
21
  def get(name):
26
- '''Get a linkchecker given its name or fallback on default'''
22
+ """Get a linkchecker given its name or fallback on default"""
27
23
  linkcheckers = get_enabled(ENTRYPOINT, current_app)
28
24
  linkcheckers.update(no_check=NoCheckLinkchecker) # no_check always enabled
29
25
  selected_linkchecker = linkcheckers.get(name)
30
26
  if not selected_linkchecker:
31
- default_linkchecker = current_app.config.get(
32
- 'LINKCHECKING_DEFAULT_LINKCHECKER')
27
+ default_linkchecker = current_app.config.get("LINKCHECKING_DEFAULT_LINKCHECKER")
33
28
  selected_linkchecker = linkcheckers.get(default_linkchecker)
34
29
  if not selected_linkchecker:
35
- log.error('No linkchecker found ({} requested and no fallback)'.format(
36
- name))
30
+ log.error("No linkchecker found ({} requested and no fallback)".format(name))
37
31
  return selected_linkchecker