udata 12.0.2.dev15__py3-none-any.whl → 13.0.1.dev21__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 (258) hide show
  1. udata/api/__init__.py +1 -0
  2. udata/api_fields.py +10 -4
  3. udata/app.py +11 -10
  4. udata/auth/__init__.py +9 -10
  5. udata/auth/mails.py +137 -45
  6. udata/auth/views.py +5 -12
  7. udata/commands/__init__.py +2 -3
  8. udata/commands/info.py +1 -3
  9. udata/commands/tests/test_fixtures.py +6 -3
  10. udata/core/access_type/api.py +18 -0
  11. udata/core/access_type/constants.py +98 -0
  12. udata/core/access_type/models.py +44 -0
  13. udata/core/activity/models.py +1 -1
  14. udata/core/badges/models.py +1 -1
  15. udata/core/badges/tasks.py +35 -1
  16. udata/core/badges/tests/test_commands.py +2 -4
  17. udata/core/badges/tests/test_model.py +2 -2
  18. udata/core/badges/tests/test_tasks.py +55 -0
  19. udata/core/constants.py +1 -0
  20. udata/core/contact_point/models.py +8 -0
  21. udata/core/dataservices/api.py +3 -3
  22. udata/core/dataservices/apiv2.py +3 -1
  23. udata/core/dataservices/constants.py +0 -29
  24. udata/core/dataservices/models.py +44 -44
  25. udata/core/dataservices/rdf.py +2 -1
  26. udata/core/dataservices/search.py +5 -9
  27. udata/core/dataservices/tasks.py +33 -0
  28. udata/core/dataset/api_fields.py +11 -0
  29. udata/core/dataset/apiv2.py +11 -0
  30. udata/core/dataset/constants.py +0 -1
  31. udata/core/dataset/forms.py +29 -0
  32. udata/core/dataset/models.py +16 -4
  33. udata/core/dataset/rdf.py +2 -1
  34. udata/core/dataset/search.py +2 -2
  35. udata/core/dataset/tasks.py +86 -8
  36. udata/core/discussions/mails.py +63 -0
  37. udata/core/discussions/tasks.py +4 -18
  38. udata/core/metrics/__init__.py +0 -6
  39. udata/core/organization/api.py +3 -1
  40. udata/core/organization/mails.py +144 -0
  41. udata/core/organization/models.py +2 -1
  42. udata/core/organization/search.py +1 -1
  43. udata/core/organization/tasks.py +21 -49
  44. udata/core/pages/tests/test_api.py +0 -2
  45. udata/core/reuse/api.py +27 -1
  46. udata/core/reuse/mails.py +21 -0
  47. udata/core/reuse/models.py +10 -1
  48. udata/core/reuse/search.py +1 -1
  49. udata/core/reuse/tasks.py +2 -3
  50. udata/core/site/models.py +2 -6
  51. udata/core/spatial/tests/test_api.py +17 -20
  52. udata/core/spatial/tests/test_models.py +3 -3
  53. udata/core/user/mails.py +54 -0
  54. udata/core/user/models.py +2 -3
  55. udata/core/user/tasks.py +8 -23
  56. udata/core/user/tests/test_user_model.py +2 -6
  57. udata/entrypoints.py +0 -5
  58. udata/features/identicon/tests/test_backends.py +3 -13
  59. udata/forms/fields.py +3 -3
  60. udata/forms/widgets.py +2 -2
  61. udata/frontend/__init__.py +3 -32
  62. udata/harvest/actions.py +4 -9
  63. udata/harvest/api.py +5 -14
  64. udata/harvest/backends/__init__.py +20 -11
  65. udata/harvest/backends/base.py +2 -2
  66. udata/harvest/backends/ckan/harvesters.py +2 -1
  67. udata/harvest/backends/dcat.py +3 -0
  68. udata/harvest/backends/maaf.py +1 -0
  69. udata/harvest/commands.py +6 -4
  70. udata/harvest/forms.py +9 -6
  71. udata/harvest/tasks.py +3 -5
  72. udata/harvest/tests/ckan/test_ckan_backend.py +300 -337
  73. udata/harvest/tests/ckan/test_ckan_backend_errors.py +94 -99
  74. udata/harvest/tests/ckan/test_ckan_backend_filters.py +128 -122
  75. udata/harvest/tests/ckan/test_dkan_backend.py +39 -51
  76. udata/harvest/tests/dcat/datara--5a26b0f6-0ccf-46ad-ac58-734054b91977.rdf.xml +255 -0
  77. udata/harvest/tests/dcat/datara--f40c3860-7236-4b30-a141-23b8ae33f7b2.rdf.xml +289 -0
  78. udata/harvest/tests/factories.py +1 -1
  79. udata/harvest/tests/test_actions.py +11 -9
  80. udata/harvest/tests/test_api.py +4 -5
  81. udata/harvest/tests/test_base_backend.py +5 -4
  82. udata/harvest/tests/test_dcat_backend.py +50 -19
  83. udata/harvest/tests/test_models.py +2 -4
  84. udata/harvest/tests/test_notifications.py +2 -4
  85. udata/harvest/tests/test_tasks.py +2 -3
  86. udata/mail.py +90 -53
  87. udata/migrations/2025-01-05-dataservices-fields-changes.py +8 -14
  88. udata/migrations/2025-10-21-remove-ckan-harvest-modified-at.py +28 -0
  89. udata/migrations/2025-10-29-harvesters-sources-integrity.py +27 -0
  90. udata/mongo/taglist_field.py +3 -3
  91. udata/rdf.py +32 -15
  92. udata/sentry.py +3 -4
  93. udata/settings.py +7 -2
  94. udata/tags.py +5 -5
  95. udata/tasks.py +3 -3
  96. udata/templates/mail/message.html +65 -0
  97. udata/templates/mail/message.txt +16 -0
  98. udata/tests/__init__.py +40 -58
  99. udata/tests/api/__init__.py +87 -2
  100. udata/tests/api/test_activities_api.py +17 -23
  101. udata/tests/api/test_auth_api.py +2 -4
  102. udata/tests/api/test_contact_points.py +48 -54
  103. udata/tests/api/test_dataservices_api.py +57 -37
  104. udata/tests/api/test_datasets_api.py +146 -49
  105. udata/tests/api/test_me_api.py +4 -6
  106. udata/tests/api/test_organizations_api.py +19 -38
  107. udata/tests/api/test_reports_api.py +0 -4
  108. udata/tests/api/test_reuses_api.py +92 -19
  109. udata/tests/api/test_security_api.py +124 -0
  110. udata/tests/api/test_swagger.py +2 -3
  111. udata/tests/api/test_tags_api.py +6 -7
  112. udata/tests/api/test_transfer_api.py +0 -2
  113. udata/tests/api/test_user_api.py +8 -10
  114. udata/tests/apiv2/test_datasets.py +0 -4
  115. udata/tests/apiv2/test_me_api.py +0 -2
  116. udata/tests/apiv2/test_organizations.py +0 -2
  117. udata/tests/apiv2/test_swagger.py +2 -3
  118. udata/tests/apiv2/test_topics.py +0 -2
  119. udata/tests/cli/test_cli_base.py +14 -12
  120. udata/tests/cli/test_db_cli.py +51 -54
  121. udata/tests/contact_point/test_contact_point_models.py +2 -2
  122. udata/tests/dataservice/test_csv_adapter.py +2 -5
  123. udata/tests/dataservice/test_dataservice_rdf.py +8 -6
  124. udata/tests/dataservice/test_dataservice_tasks.py +36 -38
  125. udata/tests/dataset/test_csv_adapter.py +2 -5
  126. udata/tests/dataset/test_dataset_actions.py +2 -4
  127. udata/tests/dataset/test_dataset_commands.py +2 -4
  128. udata/tests/dataset/test_dataset_events.py +3 -3
  129. udata/tests/dataset/test_dataset_model.py +6 -7
  130. udata/tests/dataset/test_dataset_rdf.py +201 -12
  131. udata/tests/dataset/test_dataset_recommendations.py +2 -2
  132. udata/tests/dataset/test_dataset_tasks.py +66 -68
  133. udata/tests/dataset/test_resource_preview.py +39 -48
  134. udata/tests/dataset/test_transport_tasks.py +2 -2
  135. udata/tests/features/territories/__init__.py +0 -6
  136. udata/tests/features/territories/test_territories_api.py +25 -24
  137. udata/tests/forms/test_current_user_field.py +2 -2
  138. udata/tests/forms/test_dict_field.py +2 -4
  139. udata/tests/forms/test_extras_fields.py +2 -3
  140. udata/tests/forms/test_image_field.py +2 -2
  141. udata/tests/forms/test_model_field.py +2 -4
  142. udata/tests/forms/test_publish_as_field.py +2 -4
  143. udata/tests/forms/test_user_forms.py +26 -29
  144. udata/tests/frontend/test_auth.py +2 -3
  145. udata/tests/frontend/test_csv.py +5 -6
  146. udata/tests/frontend/test_error_handlers.py +2 -3
  147. udata/tests/frontend/test_hooks.py +5 -7
  148. udata/tests/frontend/test_markdown.py +3 -4
  149. udata/tests/helpers.py +2 -7
  150. udata/tests/metrics/test_metrics.py +52 -48
  151. udata/tests/metrics/test_tasks.py +154 -150
  152. udata/tests/organization/test_csv_adapter.py +2 -5
  153. udata/tests/organization/test_notifications.py +2 -4
  154. udata/tests/organization/test_organization_model.py +3 -4
  155. udata/tests/organization/test_organization_rdf.py +2 -8
  156. udata/tests/plugin.py +6 -110
  157. udata/tests/reuse/test_reuse_model.py +3 -4
  158. udata/tests/site/test_site_api.py +0 -2
  159. udata/tests/site/test_site_csv_exports.py +0 -2
  160. udata/tests/site/test_site_metrics.py +2 -4
  161. udata/tests/site/test_site_model.py +2 -2
  162. udata/tests/site/test_site_rdf.py +4 -7
  163. udata/tests/test_activity.py +3 -3
  164. udata/tests/test_api_fields.py +6 -9
  165. udata/tests/test_cors.py +0 -2
  166. udata/tests/test_dcat_commands.py +2 -3
  167. udata/tests/test_discussions.py +2 -7
  168. udata/tests/test_mail.py +150 -114
  169. udata/tests/test_migrations.py +413 -419
  170. udata/tests/test_model.py +10 -11
  171. udata/tests/test_notifications.py +2 -3
  172. udata/tests/test_owned.py +3 -3
  173. udata/tests/test_rdf.py +19 -15
  174. udata/tests/test_routing.py +5 -5
  175. udata/tests/test_storages.py +6 -5
  176. udata/tests/test_tags.py +2 -4
  177. udata/tests/test_topics.py +2 -4
  178. udata/tests/test_transfer.py +4 -5
  179. udata/tests/topic/test_topic_tasks.py +25 -27
  180. udata/tests/user/test_user_rdf.py +2 -8
  181. udata/tests/user/test_user_tasks.py +3 -5
  182. udata/tests/workers/test_jobs_commands.py +2 -2
  183. udata/tests/workers/test_tasks_routing.py +27 -27
  184. udata/translations/ar/LC_MESSAGES/udata.mo +0 -0
  185. udata/translations/ar/LC_MESSAGES/udata.po +369 -435
  186. udata/translations/de/LC_MESSAGES/udata.mo +0 -0
  187. udata/translations/de/LC_MESSAGES/udata.po +371 -437
  188. udata/translations/es/LC_MESSAGES/udata.mo +0 -0
  189. udata/translations/es/LC_MESSAGES/udata.po +369 -435
  190. udata/translations/fr/LC_MESSAGES/udata.mo +0 -0
  191. udata/translations/fr/LC_MESSAGES/udata.po +381 -447
  192. udata/translations/it/LC_MESSAGES/udata.mo +0 -0
  193. udata/translations/it/LC_MESSAGES/udata.po +371 -437
  194. udata/translations/pt/LC_MESSAGES/udata.mo +0 -0
  195. udata/translations/pt/LC_MESSAGES/udata.po +371 -437
  196. udata/translations/sr/LC_MESSAGES/udata.mo +0 -0
  197. udata/translations/sr/LC_MESSAGES/udata.po +372 -438
  198. udata/translations/udata.pot +379 -440
  199. udata/utils.py +14 -2
  200. {udata-12.0.2.dev15.dist-info → udata-13.0.1.dev21.dist-info}/METADATA +1 -2
  201. {udata-12.0.2.dev15.dist-info → udata-13.0.1.dev21.dist-info}/RECORD +205 -242
  202. udata/templates/mail/account_deleted.html +0 -5
  203. udata/templates/mail/account_deleted.txt +0 -6
  204. udata/templates/mail/account_inactivity.html +0 -40
  205. udata/templates/mail/account_inactivity.txt +0 -31
  206. udata/templates/mail/badge_added_association.html +0 -33
  207. udata/templates/mail/badge_added_association.txt +0 -11
  208. udata/templates/mail/badge_added_certified.html +0 -33
  209. udata/templates/mail/badge_added_certified.txt +0 -11
  210. udata/templates/mail/badge_added_company.html +0 -33
  211. udata/templates/mail/badge_added_company.txt +0 -11
  212. udata/templates/mail/badge_added_local_authority.html +0 -33
  213. udata/templates/mail/badge_added_local_authority.txt +0 -11
  214. udata/templates/mail/badge_added_public_service.html +0 -33
  215. udata/templates/mail/badge_added_public_service.txt +0 -11
  216. udata/templates/mail/discussion_closed.html +0 -47
  217. udata/templates/mail/discussion_closed.txt +0 -16
  218. udata/templates/mail/inactive_account_deleted.html +0 -5
  219. udata/templates/mail/inactive_account_deleted.txt +0 -6
  220. udata/templates/mail/membership_refused.html +0 -20
  221. udata/templates/mail/membership_refused.txt +0 -11
  222. udata/templates/mail/membership_request.html +0 -46
  223. udata/templates/mail/membership_request.txt +0 -12
  224. udata/templates/mail/new_discussion.html +0 -44
  225. udata/templates/mail/new_discussion.txt +0 -15
  226. udata/templates/mail/new_discussion_comment.html +0 -45
  227. udata/templates/mail/new_discussion_comment.txt +0 -16
  228. udata/templates/mail/new_member.html +0 -27
  229. udata/templates/mail/new_member.txt +0 -11
  230. udata/templates/mail/new_reuse.html +0 -37
  231. udata/templates/mail/new_reuse.txt +0 -9
  232. udata/templates/mail/test.html +0 -6
  233. udata/templates/mail/test.txt +0 -6
  234. udata/templates/mail/user_mail_card.html +0 -26
  235. udata/templates/security/email/base.html +0 -105
  236. udata/templates/security/email/base.txt +0 -6
  237. udata/templates/security/email/button.html +0 -3
  238. udata/templates/security/email/change_notice.html +0 -22
  239. udata/templates/security/email/change_notice.txt +0 -8
  240. udata/templates/security/email/confirmation_instructions.html +0 -20
  241. udata/templates/security/email/confirmation_instructions.txt +0 -7
  242. udata/templates/security/email/login_instructions.html +0 -19
  243. udata/templates/security/email/login_instructions.txt +0 -7
  244. udata/templates/security/email/reset_instructions.html +0 -24
  245. udata/templates/security/email/reset_instructions.txt +0 -9
  246. udata/templates/security/email/reset_notice.html +0 -11
  247. udata/templates/security/email/reset_notice.txt +0 -4
  248. udata/templates/security/email/welcome.html +0 -24
  249. udata/templates/security/email/welcome.txt +0 -9
  250. udata/templates/security/email/welcome_existing.html +0 -32
  251. udata/templates/security/email/welcome_existing.txt +0 -14
  252. udata/terms.md +0 -6
  253. udata/tests/frontend/__init__.py +0 -23
  254. udata/tests/metrics/conftest.py +0 -15
  255. {udata-12.0.2.dev15.dist-info → udata-13.0.1.dev21.dist-info}/WHEEL +0 -0
  256. {udata-12.0.2.dev15.dist-info → udata-13.0.1.dev21.dist-info}/entry_points.txt +0 -0
  257. {udata-12.0.2.dev15.dist-info → udata-13.0.1.dev21.dist-info}/licenses/LICENSE +0 -0
  258. {udata-12.0.2.dev15.dist-info → udata-13.0.1.dev21.dist-info}/top_level.txt +0 -0
@@ -1,17 +1,26 @@
1
- from udata.entrypoints import EntrypointError, get_enabled
1
+ from fnmatch import fnmatch
2
+ from importlib.metadata import entry_points
2
3
 
4
+ from flask import current_app
3
5
 
4
- def get(app, name):
5
- """Get a backend given its name"""
6
- backend = get_all(app).get(name)
7
- if not backend:
8
- msg = 'Harvest backend "{0}" is not registered'.format(name)
9
- raise EntrypointError(msg)
10
- return backend
6
+ from .base import BaseBackend, HarvestExtraConfig, HarvestFeature, HarvestFilter # noqa
11
7
 
12
8
 
13
- def get_all(app):
14
- return get_enabled("udata.harvesters", app)
9
+ def get_backend(name: str) -> type[BaseBackend] | None:
10
+ return get_enabled_backends().get(name)
15
11
 
16
12
 
17
- from .base import BaseBackend, HarvestFeature, HarvestFilter, HarvestExtraConfig # noqa
13
+ def get_all_backends() -> dict[str, type[BaseBackend]]:
14
+ # Note that we use the `BaseBackend.name` and not `ep.name`. The entrypoint name
15
+ # is not used anymore.
16
+ return {ep.load().name: ep.load() for ep in entry_points(group="udata.harvesters")}
17
+
18
+
19
+ def is_backend_enabled(backend: type[BaseBackend]) -> bool:
20
+ return any(fnmatch(backend.name, g) for g in current_app.config["HARVESTER_BACKENDS"])
21
+
22
+
23
+ def get_enabled_backends() -> dict[str, type[BaseBackend]]:
24
+ return {
25
+ name: backend for name, backend in get_all_backends().items() if is_backend_enabled(backend)
26
+ }
@@ -85,8 +85,8 @@ class BaseBackend(object):
85
85
  Also provides a few helpers needed on all or some backends.
86
86
  """
87
87
 
88
- name = None
89
- display_name = None
88
+ name: str
89
+ display_name: str | None = None
90
90
  verify_ssl = True
91
91
 
92
92
  # Define some allowed filters on the backend
@@ -25,6 +25,7 @@ ALLOWED_RESOURCE_TYPES = ("dkan", "file", "file.upload", "api", "metadata")
25
25
 
26
26
 
27
27
  class CkanBackend(BaseBackend):
28
+ name = "ckan"
28
29
  display_name = "CKAN"
29
30
  filters = (
30
31
  HarvestFilter(_("Organization"), "organization", str, _("A CKAN Organization name")),
@@ -158,7 +159,6 @@ class CkanBackend(BaseBackend):
158
159
  dataset.tags = [t["name"] for t in data["tags"] if t["name"]]
159
160
 
160
161
  dataset.harvest.created_at = data["metadata_created"]
161
- dataset.harvest.modified_at = data["metadata_modified"]
162
162
 
163
163
  dataset.harvest.ckan_name = data["name"]
164
164
 
@@ -266,5 +266,6 @@ class CkanBackend(BaseBackend):
266
266
 
267
267
 
268
268
  class DkanBackend(CkanBackend):
269
+ name = "dkan"
269
270
  schema = dkan_schema
270
271
  filters = []
@@ -63,6 +63,7 @@ def extract_graph(source, target, node, specs):
63
63
 
64
64
 
65
65
  class DcatBackend(BaseBackend):
66
+ name = "dcat"
66
67
  display_name = "DCAT"
67
68
 
68
69
  def __init__(self, *args, **kwargs):
@@ -256,6 +257,7 @@ class CswDcatBackend(DcatBackend):
256
257
  The parsing of items is then the same as for the DcatBackend.
257
258
  """
258
259
 
260
+ name = "csw-dcat"
259
261
  display_name = "CSW-DCAT"
260
262
 
261
263
  # CSW_REQUEST is based on:
@@ -424,6 +426,7 @@ class CswIso19139DcatBackend(CswDcatBackend):
424
426
  The parsing of items is then the same as for the DcatBackend.
425
427
  """
426
428
 
429
+ name = "csw-iso-19139"
427
430
  display_name = "CSW-ISO-19139"
428
431
 
429
432
  extra_configs = (
@@ -129,6 +129,7 @@ def dictize(element):
129
129
 
130
130
 
131
131
  class MaafBackend(BaseBackend):
132
+ name = "maaf"
132
133
  display_name = "MAAF"
133
134
  verify_ssl = False
134
135
 
udata/harvest/commands.py CHANGED
@@ -2,7 +2,8 @@ import logging
2
2
 
3
3
  import click
4
4
 
5
- from udata.commands import cli
5
+ from udata.commands import KO, OK, cli, green, red
6
+ from udata.harvest.backends import get_all_backends, is_backend_enabled
6
7
 
7
8
  from . import actions
8
9
 
@@ -89,9 +90,10 @@ def sources(scheduled=False):
89
90
  @grp.command()
90
91
  def backends():
91
92
  """List available backends"""
92
- log.info("Available backends:")
93
- for backend in actions.list_backends():
94
- log.info("%s (%s)", backend.name, backend.display_name or backend.name)
93
+ print("Available backends:")
94
+ for backend in get_all_backends().values():
95
+ status = green(OK) if is_backend_enabled(backend) else red(KO)
96
+ click.echo("{0} {1} ({2})".format(status, backend.display_name, backend.name))
95
97
 
96
98
 
97
99
  @grp.command()
udata/harvest/forms.py CHANGED
@@ -1,8 +1,8 @@
1
1
  from udata.forms import Form, fields, validators
2
+ from udata.harvest.backends import get_backend, get_enabled_backends
2
3
  from udata.i18n import lazy_gettext as _
3
4
  from udata.utils import safe_unicode
4
5
 
5
- from .actions import list_backends
6
6
  from .models import VALIDATION_REFUSED, VALIDATION_STATES
7
7
 
8
8
  __all__ = "HarvestSourceForm", "HarvestSourceValidationForm"
@@ -13,9 +13,6 @@ class HarvestConfigField(fields.DictField):
13
13
  A DictField with extras validations on known configurations
14
14
  """
15
15
 
16
- def get_backend(self, form):
17
- return next(b for b in list_backends() if b.name == form.backend.data)
18
-
19
16
  def get_filter_specs(self, backend, key):
20
17
  candidates = (f for f in backend.filters if f.key == key)
21
18
  return next(candidates, None)
@@ -30,7 +27,10 @@ class HarvestConfigField(fields.DictField):
30
27
 
31
28
  def pre_validate(self, form):
32
29
  if self.data:
33
- backend = self.get_backend(form)
30
+ backend = get_backend(form.backend.data)
31
+ if backend is None:
32
+ return # Should have been catch by the enum check for `form.backend`
33
+
34
34
  # Validate filters
35
35
  for f in self.data.get("filters") or []:
36
36
  if not ("key" in f and "value" in f):
@@ -49,6 +49,7 @@ class HarvestConfigField(fields.DictField):
49
49
  msg = '"{0}" filter should of type "{1}"'
50
50
  msg = msg.format(specs.key, specs.type.__name__)
51
51
  raise validators.ValidationError(msg)
52
+
52
53
  # Validate extras configs
53
54
  for f in self.data.get("extra_configs") or []:
54
55
  if not ("key" in f and "value" in f):
@@ -63,6 +64,7 @@ class HarvestConfigField(fields.DictField):
63
64
  msg = '"{0}" extra config should be of type "{1}"'
64
65
  msg = msg.format(specs.key, specs.type.__name__)
65
66
  raise validators.ValidationError(msg)
67
+
66
68
  # Validate features
67
69
  for key, value in (self.data.get("features") or {}).items():
68
70
  if not isinstance(value, bool):
@@ -81,7 +83,8 @@ class HarvestSourceForm(Form):
81
83
  )
82
84
  url = fields.URLField(_("URL"), [validators.DataRequired()])
83
85
  backend = fields.SelectField(
84
- _("Backend"), choices=lambda: [(b.name, b.display_name) for b in list_backends()]
86
+ _("Backend"),
87
+ choices=lambda: [(b.name, b.display_name) for b in get_enabled_backends().values()],
85
88
  )
86
89
  owner = fields.CurrentUserField()
87
90
  organization = fields.PublishAsField(_("Publish as"))
udata/harvest/tasks.py CHANGED
@@ -1,5 +1,3 @@
1
- from flask import current_app
2
-
3
1
  from udata.tasks import get_logger, job, task
4
2
 
5
3
  from . import backends
@@ -16,7 +14,7 @@ def harvest(self, ident):
16
14
  if source.deleted or not source.active:
17
15
  log.info('Ignoring inactive or deleted source "%s"', source.id)
18
16
  return # Ignore deleted and inactive sources
19
- Backend = backends.get(current_app, source.backend)
17
+ Backend = backends.get_backend(source.backend)
20
18
  backend = Backend(source)
21
19
 
22
20
  backend.harvest()
@@ -27,7 +25,7 @@ def harvest_job_item(job_id, item_id):
27
25
  log.info('Harvesting item %s for job "%s"', item_id, job_id)
28
26
 
29
27
  job = HarvestJob.objects.get(pk=job_id)
30
- Backend = backends.get(current_app, job.source.backend)
28
+ Backend = backends.get_backend(job.source.backend)
31
29
  backend = Backend(job)
32
30
 
33
31
  item = next(i for i in job.items if i.remote_id == item_id)
@@ -40,7 +38,7 @@ def harvest_job_item(job_id, item_id):
40
38
  def harvest_job_finalize(results, job_id):
41
39
  log.info('Finalize harvesting for job "%s"', job_id)
42
40
  job = HarvestJob.objects.get(pk=job_id)
43
- Backend = backends.get(current_app, job.source.backend)
41
+ Backend = backends.get_backend(job.source.backend)
44
42
  backend = Backend(job)
45
43
  backend.finalize()
46
44