udata 12.0.2.dev10__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.
- udata/api/__init__.py +1 -0
- udata/api_fields.py +10 -4
- udata/app.py +11 -10
- udata/auth/__init__.py +9 -10
- udata/auth/mails.py +137 -45
- udata/auth/views.py +5 -12
- udata/commands/__init__.py +2 -4
- udata/commands/info.py +1 -3
- udata/commands/tests/test_fixtures.py +6 -3
- udata/core/access_type/api.py +18 -0
- udata/core/access_type/constants.py +98 -0
- udata/core/access_type/models.py +44 -0
- udata/core/activity/models.py +1 -1
- udata/core/badges/models.py +1 -1
- udata/core/badges/tasks.py +35 -1
- udata/core/badges/tests/test_commands.py +2 -4
- udata/core/badges/tests/test_model.py +2 -2
- udata/core/badges/tests/test_tasks.py +55 -0
- udata/core/constants.py +1 -0
- udata/core/contact_point/models.py +8 -0
- udata/core/dataservices/api.py +10 -12
- udata/core/dataservices/apiv2.py +3 -1
- udata/core/dataservices/constants.py +0 -29
- udata/core/dataservices/models.py +44 -44
- udata/core/dataservices/rdf.py +2 -1
- udata/core/dataservices/search.py +5 -9
- udata/core/dataservices/tasks.py +33 -0
- udata/core/dataset/api.py +15 -24
- udata/core/dataset/api_fields.py +11 -0
- udata/core/dataset/apiv2.py +11 -0
- udata/core/dataset/constants.py +0 -1
- udata/core/dataset/forms.py +29 -0
- udata/core/dataset/models.py +24 -42
- udata/core/dataset/rdf.py +2 -1
- udata/core/dataset/search.py +2 -2
- udata/core/dataset/tasks.py +86 -8
- udata/core/discussions/mails.py +63 -0
- udata/core/discussions/tasks.py +4 -18
- udata/core/metrics/__init__.py +0 -6
- udata/core/organization/api.py +20 -14
- udata/core/organization/mails.py +144 -0
- udata/core/organization/models.py +2 -1
- udata/core/organization/rdf.py +3 -3
- udata/core/organization/search.py +1 -1
- udata/core/organization/tasks.py +21 -49
- udata/core/pages/tests/test_api.py +0 -2
- udata/core/reuse/api.py +29 -3
- udata/core/reuse/mails.py +21 -0
- udata/core/reuse/models.py +10 -1
- udata/core/reuse/search.py +1 -1
- udata/core/reuse/tasks.py +2 -3
- udata/core/site/api.py +27 -19
- udata/core/site/models.py +2 -6
- udata/core/site/rdf.py +2 -2
- udata/core/spatial/tests/test_api.py +17 -20
- udata/core/spatial/tests/test_models.py +3 -3
- udata/core/user/mails.py +54 -0
- udata/core/user/models.py +2 -3
- udata/core/user/tasks.py +8 -23
- udata/core/user/tests/test_user_model.py +2 -6
- udata/entrypoints.py +0 -6
- udata/features/identicon/tests/test_backends.py +3 -13
- udata/forms/fields.py +3 -3
- udata/forms/widgets.py +2 -2
- udata/frontend/__init__.py +3 -32
- udata/harvest/actions.py +4 -9
- udata/harvest/api.py +5 -14
- udata/harvest/backends/__init__.py +20 -11
- udata/harvest/backends/base.py +2 -2
- udata/harvest/backends/ckan/harvesters.py +2 -1
- udata/harvest/backends/dcat.py +3 -0
- udata/harvest/backends/maaf.py +1 -0
- udata/harvest/commands.py +6 -4
- udata/harvest/forms.py +9 -6
- udata/harvest/tasks.py +3 -5
- udata/harvest/tests/ckan/test_ckan_backend.py +300 -337
- udata/harvest/tests/ckan/test_ckan_backend_errors.py +94 -99
- udata/harvest/tests/ckan/test_ckan_backend_filters.py +128 -122
- udata/harvest/tests/ckan/test_dkan_backend.py +39 -51
- udata/harvest/tests/dcat/bnodes.xml +17 -1
- udata/harvest/tests/dcat/datara--5a26b0f6-0ccf-46ad-ac58-734054b91977.rdf.xml +255 -0
- udata/harvest/tests/dcat/datara--f40c3860-7236-4b30-a141-23b8ae33f7b2.rdf.xml +289 -0
- udata/harvest/tests/factories.py +1 -1
- udata/harvest/tests/test_actions.py +11 -9
- udata/harvest/tests/test_api.py +4 -5
- udata/harvest/tests/test_base_backend.py +5 -4
- udata/harvest/tests/test_dcat_backend.py +72 -16
- udata/harvest/tests/test_models.py +2 -4
- udata/harvest/tests/test_notifications.py +2 -4
- udata/harvest/tests/test_tasks.py +2 -3
- udata/mail.py +90 -53
- udata/migrations/2025-01-05-dataservices-fields-changes.py +8 -14
- udata/migrations/2025-10-21-remove-ckan-harvest-modified-at.py +28 -0
- udata/migrations/2025-10-29-harvesters-sources-integrity.py +27 -0
- udata/models/__init__.py +0 -2
- udata/mongo/extras_fields.py +4 -3
- udata/mongo/taglist_field.py +3 -3
- udata/rdf.py +65 -20
- udata/sentry.py +3 -4
- udata/settings.py +15 -13
- udata/tags.py +5 -5
- udata/tasks.py +3 -3
- udata/templates/mail/message.html +65 -0
- udata/templates/mail/message.txt +16 -0
- udata/tests/__init__.py +40 -58
- udata/tests/api/__init__.py +87 -2
- udata/tests/api/test_activities_api.py +17 -23
- udata/tests/api/test_auth_api.py +2 -4
- udata/tests/api/test_contact_points.py +48 -54
- udata/tests/api/test_dataservices_api.py +65 -97
- udata/tests/api/test_datasets_api.py +171 -56
- udata/tests/api/test_me_api.py +4 -6
- udata/tests/api/test_organizations_api.py +19 -38
- udata/tests/api/test_reports_api.py +0 -4
- udata/tests/api/test_reuses_api.py +99 -23
- udata/tests/api/test_security_api.py +124 -0
- udata/tests/api/test_swagger.py +2 -3
- udata/tests/api/test_tags_api.py +6 -7
- udata/tests/api/test_transfer_api.py +0 -2
- udata/tests/api/test_user_api.py +8 -10
- udata/tests/apiv2/test_datasets.py +0 -4
- udata/tests/apiv2/test_me_api.py +0 -2
- udata/tests/apiv2/test_organizations.py +0 -2
- udata/tests/apiv2/test_swagger.py +2 -3
- udata/tests/apiv2/test_topics.py +0 -2
- udata/tests/cli/test_cli_base.py +14 -12
- udata/tests/cli/test_db_cli.py +51 -54
- udata/tests/contact_point/test_contact_point_models.py +2 -2
- udata/tests/dataservice/test_csv_adapter.py +2 -5
- udata/tests/dataservice/test_dataservice_rdf.py +64 -4
- udata/tests/dataservice/test_dataservice_tasks.py +36 -38
- udata/tests/dataset/test_csv_adapter.py +2 -5
- udata/tests/dataset/test_dataset_actions.py +2 -4
- udata/tests/dataset/test_dataset_commands.py +2 -4
- udata/tests/dataset/test_dataset_events.py +3 -3
- udata/tests/dataset/test_dataset_model.py +6 -7
- udata/tests/dataset/test_dataset_rdf.py +205 -16
- udata/tests/dataset/test_dataset_recommendations.py +2 -2
- udata/tests/dataset/test_dataset_tasks.py +66 -68
- udata/tests/dataset/test_resource_preview.py +39 -48
- udata/tests/dataset/test_transport_tasks.py +2 -2
- udata/tests/features/territories/__init__.py +0 -6
- udata/tests/features/territories/test_territories_api.py +25 -24
- udata/tests/forms/test_current_user_field.py +2 -2
- udata/tests/forms/test_dict_field.py +2 -4
- udata/tests/forms/test_extras_fields.py +2 -3
- udata/tests/forms/test_image_field.py +2 -2
- udata/tests/forms/test_model_field.py +2 -4
- udata/tests/forms/test_publish_as_field.py +2 -4
- udata/tests/forms/test_user_forms.py +26 -29
- udata/tests/frontend/test_auth.py +2 -3
- udata/tests/frontend/test_csv.py +5 -6
- udata/tests/frontend/test_error_handlers.py +2 -3
- udata/tests/frontend/test_hooks.py +5 -7
- udata/tests/frontend/test_markdown.py +3 -4
- udata/tests/helpers.py +2 -7
- udata/tests/metrics/test_metrics.py +52 -48
- udata/tests/metrics/test_tasks.py +154 -150
- udata/tests/organization/test_csv_adapter.py +2 -5
- udata/tests/organization/test_notifications.py +2 -4
- udata/tests/organization/test_organization_model.py +3 -4
- udata/tests/organization/test_organization_rdf.py +6 -12
- udata/tests/plugin.py +6 -110
- udata/tests/reuse/test_reuse_model.py +3 -4
- udata/tests/site/test_site_api.py +0 -2
- udata/tests/site/test_site_csv_exports.py +0 -2
- udata/tests/site/test_site_metrics.py +2 -4
- udata/tests/site/test_site_model.py +2 -2
- udata/tests/site/test_site_rdf.py +85 -29
- udata/tests/test_activity.py +3 -3
- udata/tests/test_api_fields.py +6 -9
- udata/tests/test_cors.py +0 -2
- udata/tests/test_dcat_commands.py +2 -3
- udata/tests/test_discussions.py +2 -7
- udata/tests/test_mail.py +150 -114
- udata/tests/test_migrations.py +413 -419
- udata/tests/test_model.py +10 -11
- udata/tests/test_notifications.py +2 -3
- udata/tests/test_owned.py +3 -3
- udata/tests/test_rdf.py +19 -15
- udata/tests/test_routing.py +5 -5
- udata/tests/test_storages.py +6 -5
- udata/tests/test_tags.py +2 -4
- udata/tests/test_topics.py +2 -4
- udata/tests/test_transfer.py +4 -5
- udata/tests/topic/test_topic_tasks.py +25 -27
- udata/tests/user/test_user_rdf.py +2 -8
- udata/tests/user/test_user_tasks.py +3 -5
- udata/tests/workers/test_jobs_commands.py +2 -2
- udata/tests/workers/test_tasks_routing.py +27 -27
- udata/translations/ar/LC_MESSAGES/udata.mo +0 -0
- udata/translations/ar/LC_MESSAGES/udata.po +369 -435
- udata/translations/de/LC_MESSAGES/udata.mo +0 -0
- udata/translations/de/LC_MESSAGES/udata.po +371 -437
- udata/translations/es/LC_MESSAGES/udata.mo +0 -0
- udata/translations/es/LC_MESSAGES/udata.po +369 -435
- udata/translations/fr/LC_MESSAGES/udata.mo +0 -0
- udata/translations/fr/LC_MESSAGES/udata.po +381 -447
- udata/translations/it/LC_MESSAGES/udata.mo +0 -0
- udata/translations/it/LC_MESSAGES/udata.po +371 -437
- udata/translations/pt/LC_MESSAGES/udata.mo +0 -0
- udata/translations/pt/LC_MESSAGES/udata.po +371 -437
- udata/translations/sr/LC_MESSAGES/udata.mo +0 -0
- udata/translations/sr/LC_MESSAGES/udata.po +372 -438
- udata/translations/udata.pot +379 -440
- udata/utils.py +66 -4
- {udata-12.0.2.dev10.dist-info → udata-13.0.1.dev21.dist-info}/METADATA +1 -4
- {udata-12.0.2.dev10.dist-info → udata-13.0.1.dev21.dist-info}/RECORD +212 -256
- udata/linkchecker/__init__.py +0 -0
- udata/linkchecker/backends.py +0 -31
- udata/linkchecker/checker.py +0 -75
- udata/linkchecker/commands.py +0 -21
- udata/linkchecker/models.py +0 -9
- udata/linkchecker/tasks.py +0 -55
- udata/templates/mail/account_deleted.html +0 -5
- udata/templates/mail/account_deleted.txt +0 -6
- udata/templates/mail/account_inactivity.html +0 -40
- udata/templates/mail/account_inactivity.txt +0 -31
- udata/templates/mail/badge_added_association.html +0 -33
- udata/templates/mail/badge_added_association.txt +0 -11
- udata/templates/mail/badge_added_certified.html +0 -33
- udata/templates/mail/badge_added_certified.txt +0 -11
- udata/templates/mail/badge_added_company.html +0 -33
- udata/templates/mail/badge_added_company.txt +0 -11
- udata/templates/mail/badge_added_local_authority.html +0 -33
- udata/templates/mail/badge_added_local_authority.txt +0 -11
- udata/templates/mail/badge_added_public_service.html +0 -33
- udata/templates/mail/badge_added_public_service.txt +0 -11
- udata/templates/mail/discussion_closed.html +0 -47
- udata/templates/mail/discussion_closed.txt +0 -16
- udata/templates/mail/inactive_account_deleted.html +0 -5
- udata/templates/mail/inactive_account_deleted.txt +0 -6
- udata/templates/mail/membership_refused.html +0 -20
- udata/templates/mail/membership_refused.txt +0 -11
- udata/templates/mail/membership_request.html +0 -46
- udata/templates/mail/membership_request.txt +0 -12
- udata/templates/mail/new_discussion.html +0 -44
- udata/templates/mail/new_discussion.txt +0 -15
- udata/templates/mail/new_discussion_comment.html +0 -45
- udata/templates/mail/new_discussion_comment.txt +0 -16
- udata/templates/mail/new_member.html +0 -27
- udata/templates/mail/new_member.txt +0 -11
- udata/templates/mail/new_reuse.html +0 -37
- udata/templates/mail/new_reuse.txt +0 -9
- udata/templates/mail/test.html +0 -6
- udata/templates/mail/test.txt +0 -6
- udata/templates/mail/user_mail_card.html +0 -26
- udata/templates/security/email/base.html +0 -105
- udata/templates/security/email/base.txt +0 -6
- udata/templates/security/email/button.html +0 -3
- udata/templates/security/email/change_notice.html +0 -22
- udata/templates/security/email/change_notice.txt +0 -8
- udata/templates/security/email/confirmation_instructions.html +0 -20
- udata/templates/security/email/confirmation_instructions.txt +0 -7
- udata/templates/security/email/login_instructions.html +0 -19
- udata/templates/security/email/login_instructions.txt +0 -7
- udata/templates/security/email/reset_instructions.html +0 -24
- udata/templates/security/email/reset_instructions.txt +0 -9
- udata/templates/security/email/reset_notice.html +0 -11
- udata/templates/security/email/reset_notice.txt +0 -4
- udata/templates/security/email/welcome.html +0 -24
- udata/templates/security/email/welcome.txt +0 -9
- udata/templates/security/email/welcome_existing.html +0 -32
- udata/templates/security/email/welcome_existing.txt +0 -14
- udata/terms.md +0 -6
- udata/tests/frontend/__init__.py +0 -23
- udata/tests/metrics/conftest.py +0 -15
- udata/tests/test_linkchecker.py +0 -277
- {udata-12.0.2.dev10.dist-info → udata-13.0.1.dev21.dist-info}/WHEEL +0 -0
- {udata-12.0.2.dev10.dist-info → udata-13.0.1.dev21.dist-info}/entry_points.txt +0 -0
- {udata-12.0.2.dev10.dist-info → udata-13.0.1.dev21.dist-info}/licenses/LICENSE +0 -0
- {udata-12.0.2.dev10.dist-info → udata-13.0.1.dev21.dist-info}/top_level.txt +0 -0
udata/linkchecker/__init__.py
DELETED
|
File without changes
|
udata/linkchecker/backends.py
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import logging
|
|
2
|
-
from datetime import datetime
|
|
3
|
-
|
|
4
|
-
from flask import current_app
|
|
5
|
-
|
|
6
|
-
from udata.entrypoints import get_enabled
|
|
7
|
-
|
|
8
|
-
log = logging.getLogger(__name__)
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
ENTRYPOINT = "udata.linkcheckers"
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
class NoCheckLinkchecker(object):
|
|
15
|
-
"""Dummy linkchecker for resources that need no check"""
|
|
16
|
-
|
|
17
|
-
def check(self, _):
|
|
18
|
-
return {"check:status": 204, "check:available": True, "check:date": datetime.utcnow()}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
def get(name):
|
|
22
|
-
"""Get a linkchecker given its name or fallback on default"""
|
|
23
|
-
linkcheckers = get_enabled(ENTRYPOINT, current_app)
|
|
24
|
-
linkcheckers.update(no_check=NoCheckLinkchecker) # no_check always enabled
|
|
25
|
-
selected_linkchecker = linkcheckers.get(name)
|
|
26
|
-
if not selected_linkchecker:
|
|
27
|
-
default_linkchecker = current_app.config.get("LINKCHECKING_DEFAULT_LINKCHECKER")
|
|
28
|
-
selected_linkchecker = linkcheckers.get(default_linkchecker)
|
|
29
|
-
if not selected_linkchecker:
|
|
30
|
-
log.error("No linkchecker found ({} requested and no fallback)".format(name))
|
|
31
|
-
return selected_linkchecker
|
udata/linkchecker/checker.py
DELETED
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
from urllib.parse import urlparse
|
|
2
|
-
|
|
3
|
-
from flask import current_app
|
|
4
|
-
|
|
5
|
-
from .backends import NoCheckLinkchecker
|
|
6
|
-
from .backends import get as get_linkchecker
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
def _get_check_keys(the_dict, resource, previous_status):
|
|
10
|
-
check_keys = {k: v for k, v in the_dict.items() if k.startswith("check:")}
|
|
11
|
-
check_keys["check:count-availability"] = _compute_count_availability(
|
|
12
|
-
resource, check_keys.get("check:available"), previous_status
|
|
13
|
-
)
|
|
14
|
-
return check_keys
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
def _compute_count_availability(resource, status, previous_status):
|
|
18
|
-
"""Compute the `check:count-availability` extra value"""
|
|
19
|
-
count_availability = resource.extras.get("check:count-availability", 1)
|
|
20
|
-
return count_availability + 1 if status == previous_status else 1
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
def is_ignored(resource):
|
|
24
|
-
"""Check if the resource's URL is to be ignored"""
|
|
25
|
-
ignored_domains = current_app.config["LINKCHECKING_IGNORE_DOMAINS"]
|
|
26
|
-
ignored_patterns = current_app.config["LINKCHECKING_IGNORE_PATTERNS"]
|
|
27
|
-
url = resource.url
|
|
28
|
-
if not url:
|
|
29
|
-
return True
|
|
30
|
-
parsed_url = urlparse(url)
|
|
31
|
-
ignored_domains_match = parsed_url.netloc in ignored_domains
|
|
32
|
-
ignored_patterns_match = any([p in url for p in ignored_patterns])
|
|
33
|
-
return ignored_domains_match or ignored_patterns_match
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
def dummy_check_response():
|
|
37
|
-
"""Trigger a dummy check"""
|
|
38
|
-
return NoCheckLinkchecker().check(None)
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
def check_resource(resource):
|
|
42
|
-
"""
|
|
43
|
-
Check a resource availability against a linkchecker backend
|
|
44
|
-
|
|
45
|
-
The linkchecker used can be configured on a resource basis by setting
|
|
46
|
-
the `resource.extras['check:checker']` attribute with a key that points
|
|
47
|
-
to a valid `udata.linkcheckers` entrypoint. If not set, it will
|
|
48
|
-
fallback on the default linkchecker defined by the configuration variable
|
|
49
|
-
`LINKCHECKING_DEFAULT_LINKCHECKER`.
|
|
50
|
-
|
|
51
|
-
Returns
|
|
52
|
-
-------
|
|
53
|
-
dict or (dict, int)
|
|
54
|
-
Check results dict and status code (if error).
|
|
55
|
-
"""
|
|
56
|
-
linkchecker_type = resource.extras.get("check:checker")
|
|
57
|
-
LinkChecker = get_linkchecker(linkchecker_type)
|
|
58
|
-
if not LinkChecker:
|
|
59
|
-
return {"error": "No linkchecker configured."}, 503
|
|
60
|
-
if is_ignored(resource):
|
|
61
|
-
return dummy_check_response()
|
|
62
|
-
result = LinkChecker().check(resource)
|
|
63
|
-
if not result:
|
|
64
|
-
return {"error": "No response from linkchecker"}, 503
|
|
65
|
-
elif result.get("check:error"):
|
|
66
|
-
return {"error": result["check:error"]}, 500
|
|
67
|
-
elif not result.get("check:status"):
|
|
68
|
-
return {"error": "No status in response from linkchecker"}, 503
|
|
69
|
-
# store the check result in the resource's extras
|
|
70
|
-
# XXX maybe this logic should be in the `Resource` model?
|
|
71
|
-
previous_status = resource.extras.get("check:available")
|
|
72
|
-
check_keys = _get_check_keys(result, resource, previous_status)
|
|
73
|
-
resource.extras.update(check_keys)
|
|
74
|
-
resource.save(signal_kwargs={"ignores": ["post_save"]}) # Prevent signal triggering on dataset
|
|
75
|
-
return result
|
udata/linkchecker/commands.py
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import logging
|
|
2
|
-
|
|
3
|
-
import click
|
|
4
|
-
|
|
5
|
-
from udata.commands import cli
|
|
6
|
-
from udata.linkchecker.tasks import check_resources
|
|
7
|
-
|
|
8
|
-
log = logging.getLogger(__name__)
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
@cli.group("linkchecker")
|
|
12
|
-
def grp():
|
|
13
|
-
"""Link checking operations"""
|
|
14
|
-
pass
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
@grp.command()
|
|
18
|
-
@click.option("-n", "--number", type=int, default=5000, help="Number of URLs to check")
|
|
19
|
-
def check(number):
|
|
20
|
-
"""Check <number> of URLs that have not been (recently) checked"""
|
|
21
|
-
check_resources(number)
|
udata/linkchecker/models.py
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
from udata.core.dataset.models import ResourceMixin
|
|
2
|
-
from udata.mongo import db
|
|
3
|
-
|
|
4
|
-
# Register harvest extras
|
|
5
|
-
ResourceMixin.extras.register("check:available", db.BooleanField)
|
|
6
|
-
ResourceMixin.extras.register("check:count-availability", db.IntField)
|
|
7
|
-
ResourceMixin.extras.register("check:status", db.IntField)
|
|
8
|
-
ResourceMixin.extras.register("check:url", db.StringField)
|
|
9
|
-
ResourceMixin.extras.register("check:date", db.DateTimeField)
|
udata/linkchecker/tasks.py
DELETED
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import logging
|
|
2
|
-
import uuid
|
|
3
|
-
|
|
4
|
-
from flask import current_app
|
|
5
|
-
|
|
6
|
-
from udata.models import Dataset
|
|
7
|
-
from udata.tasks import job
|
|
8
|
-
from udata.utils import get_by
|
|
9
|
-
|
|
10
|
-
from .checker import check_resource
|
|
11
|
-
|
|
12
|
-
log = logging.getLogger(__name__)
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
@job("check_resources")
|
|
16
|
-
def check_resources(self, number):
|
|
17
|
-
"""Check <number> of URLs that have not been (recently) checked"""
|
|
18
|
-
if not current_app.config.get("LINKCHECKING_ENABLED"):
|
|
19
|
-
log.error("Link checking is disabled.")
|
|
20
|
-
return
|
|
21
|
-
|
|
22
|
-
base_pipeline = [
|
|
23
|
-
{"$match": {"resources": {"$gt": []}}},
|
|
24
|
-
{"$project": {"resources._id": True, "resources.extras.check:date": True}},
|
|
25
|
-
{"$unwind": "$resources"},
|
|
26
|
-
]
|
|
27
|
-
# unchecked resources
|
|
28
|
-
pipeline = base_pipeline + [
|
|
29
|
-
{"$match": {"resources.extras.check:date": {"$eq": None}}},
|
|
30
|
-
{"$limit": number},
|
|
31
|
-
]
|
|
32
|
-
resources = list(Dataset.objects.aggregate(*pipeline))
|
|
33
|
-
# not recently checked resources
|
|
34
|
-
slots_left = number - len(resources)
|
|
35
|
-
if slots_left:
|
|
36
|
-
pipeline = base_pipeline + [
|
|
37
|
-
{"$match": {"resources.extras.check:date": {"$ne": None}}},
|
|
38
|
-
{"$sort": {"resources.extras.check:date": 1}},
|
|
39
|
-
{"$limit": slots_left},
|
|
40
|
-
]
|
|
41
|
-
resources += list(Dataset.objects.aggregate(*pipeline))
|
|
42
|
-
|
|
43
|
-
nb_resources = len(resources)
|
|
44
|
-
log.info("Checking %s resources...", nb_resources)
|
|
45
|
-
for idx, dataset_resource in enumerate(resources):
|
|
46
|
-
dataset_obj = Dataset.objects.get(id=dataset_resource["_id"])
|
|
47
|
-
resource_id = dataset_resource["resources"]["_id"]
|
|
48
|
-
rid = uuid.UUID(resource_id)
|
|
49
|
-
resource_obj = get_by(dataset_obj.resources, "id", rid)
|
|
50
|
-
log.info("Checking resource %s (%s/%s)", resource_id, idx + 1, nb_resources)
|
|
51
|
-
if resource_obj.need_check():
|
|
52
|
-
check_resource(resource_obj)
|
|
53
|
-
else:
|
|
54
|
-
log.info("--> Skipping this resource, cache is fresh enough.")
|
|
55
|
-
log.info("Done.")
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
{% extends 'mail/base.html' %}
|
|
2
|
-
{% from 'mail/button.html' import mail_button %}
|
|
3
|
-
|
|
4
|
-
{% block body %}
|
|
5
|
-
<p style="margin: 0;padding: 0;">
|
|
6
|
-
{{ _(
|
|
7
|
-
'We have noticed that your account associated to (%(user_email)s) has been inactive for %(inactivity_years)d years or more'
|
|
8
|
-
' on %(site)s, the open platform for public data.',
|
|
9
|
-
user_email=user.email,
|
|
10
|
-
inactivity_years=config.YEARS_OF_INACTIVITY_BEFORE_DELETION,
|
|
11
|
-
site=config.SITE_TITLE
|
|
12
|
-
)
|
|
13
|
-
}}
|
|
14
|
-
</p>
|
|
15
|
-
<br/>
|
|
16
|
-
<p style="margin: 0;padding: 0;"><b>
|
|
17
|
-
{{ _(
|
|
18
|
-
'If you want to keep your account, please log in with your account on %(home)s.',
|
|
19
|
-
home=homepage_url()
|
|
20
|
-
)
|
|
21
|
-
}}
|
|
22
|
-
</b></p>
|
|
23
|
-
<br/>
|
|
24
|
-
<p style="margin: 0;padding: 0;">
|
|
25
|
-
{{ _(
|
|
26
|
-
'Without logging in, your account will be deleted within %(notify_delay)d days.',
|
|
27
|
-
notify_delay=config.DAYS_BEFORE_ACCOUNT_INACTIVITY_NOTIFY_DELAY
|
|
28
|
-
)
|
|
29
|
-
}}
|
|
30
|
-
</p>
|
|
31
|
-
<br/>
|
|
32
|
-
<p style="margin: 0;padding: 0;">
|
|
33
|
-
{{ _(
|
|
34
|
-
'This account is not tied to your other administration accounts and '
|
|
35
|
-
'you can always re-create an account on the %(site)s platform if necessary.',
|
|
36
|
-
site=config.SITE_TITLE
|
|
37
|
-
)
|
|
38
|
-
}}
|
|
39
|
-
</p>
|
|
40
|
-
{% endblock %}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
{% extends 'mail/base.txt' %}
|
|
2
|
-
|
|
3
|
-
{% block body %}
|
|
4
|
-
{{ _(
|
|
5
|
-
'We have noticed that your account associated to (%(user_email)s) has been inactive for %(inactivity_years)d years or more'
|
|
6
|
-
' on %(site)s, the open platform for public data.',
|
|
7
|
-
user_email=user.email,
|
|
8
|
-
inactivity_years=config.YEARS_OF_INACTIVITY_BEFORE_DELETION,
|
|
9
|
-
site=config.SITE_TITLE
|
|
10
|
-
)
|
|
11
|
-
}}
|
|
12
|
-
|
|
13
|
-
{{ _(
|
|
14
|
-
'If you want to keep your account, please log in with your account on %(home)s.',
|
|
15
|
-
home=homepage_url()
|
|
16
|
-
)
|
|
17
|
-
}}
|
|
18
|
-
|
|
19
|
-
{{ _(
|
|
20
|
-
'Without logging in, your account will be deleted within %(notify_delay)d days.',
|
|
21
|
-
notify_delay=config.DAYS_BEFORE_ACCOUNT_INACTIVITY_NOTIFY_DELAY
|
|
22
|
-
)
|
|
23
|
-
}}
|
|
24
|
-
{{
|
|
25
|
-
_(
|
|
26
|
-
'This account is not tied to your other administration accounts and '
|
|
27
|
-
'you can always re-create an account on the %(site)s platform if necessary',
|
|
28
|
-
site=config.SITE_TITLE
|
|
29
|
-
)
|
|
30
|
-
}}
|
|
31
|
-
{% endblock %}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
{% extends 'mail/base.html' %}
|
|
2
|
-
{% from 'mail/button.html' import mail_button %}
|
|
3
|
-
|
|
4
|
-
{% block body %}
|
|
5
|
-
<p style="margin: 0;padding: 0;">{{
|
|
6
|
-
_('%(user)s has identified your organization "%(name)s" as an association',
|
|
7
|
-
user=(
|
|
8
|
-
'<a href="'|safe
|
|
9
|
-
+ badge.created_by.url_for(_mailCampaign=True)
|
|
10
|
-
+ '">'|safe
|
|
11
|
-
+ badge.created_by.fullname
|
|
12
|
-
+ '</a>'|safe
|
|
13
|
-
),
|
|
14
|
-
name=(
|
|
15
|
-
'<a href="'|safe
|
|
16
|
-
+ organization.url_for(_mailCampaign=True)
|
|
17
|
-
+ '">'|safe
|
|
18
|
-
+ organization.name|string
|
|
19
|
-
+ '</a>'|safe
|
|
20
|
-
)
|
|
21
|
-
) }}.</p>
|
|
22
|
-
<br/>
|
|
23
|
-
<table width="100%" border="0" cellspacing="0" cellpadding="0">
|
|
24
|
-
<tr>
|
|
25
|
-
<td align="center">
|
|
26
|
-
{{ mail_button(
|
|
27
|
-
_('See the badge'),
|
|
28
|
-
organization.url_for(_mailCampaign=True)
|
|
29
|
-
) }}
|
|
30
|
-
</td>
|
|
31
|
-
</tr>
|
|
32
|
-
</table>
|
|
33
|
-
{% endblock %}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
{% extends 'mail/base.txt' %}
|
|
2
|
-
|
|
3
|
-
{% block body %}
|
|
4
|
-
{{ _('%(user)s has identified your organization "%(name)s" as an association',
|
|
5
|
-
name=organization.name,
|
|
6
|
-
user=badge.created_by.fullname
|
|
7
|
-
) }}.
|
|
8
|
-
|
|
9
|
-
{{ _('You can see the badge on this page:') }}
|
|
10
|
-
{{ organization.url_for(_mailCampaign=True) }}
|
|
11
|
-
{% endblock %}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
{% extends 'mail/base.html' %}
|
|
2
|
-
{% from 'mail/button.html' import mail_button %}
|
|
3
|
-
|
|
4
|
-
{% block body %}
|
|
5
|
-
<p style="margin: 0;padding: 0;">{{
|
|
6
|
-
_('%(user)s has certified your organization "%(name)s"',
|
|
7
|
-
user=(
|
|
8
|
-
'<a href="'|safe
|
|
9
|
-
+ badge.created_by.url_for(_mailCampaign=True)
|
|
10
|
-
+ '">'|safe
|
|
11
|
-
+ badge.created_by.fullname
|
|
12
|
-
+ '</a>'|safe
|
|
13
|
-
),
|
|
14
|
-
name=(
|
|
15
|
-
'<a href="'|safe
|
|
16
|
-
+ organization.url_for(_mailCampaign=True)
|
|
17
|
-
+ '">'|safe
|
|
18
|
-
+ organization.name|string
|
|
19
|
-
+ '</a>'|safe
|
|
20
|
-
)
|
|
21
|
-
) }}.</p>
|
|
22
|
-
<br/>
|
|
23
|
-
<table width="100%" border="0" cellspacing="0" cellpadding="0">
|
|
24
|
-
<tr>
|
|
25
|
-
<td align="center">
|
|
26
|
-
{{ mail_button(
|
|
27
|
-
_('See the badge'),
|
|
28
|
-
organization.url_for(_mailCampaign=True)
|
|
29
|
-
) }}
|
|
30
|
-
</td>
|
|
31
|
-
</tr>
|
|
32
|
-
</table>
|
|
33
|
-
{% endblock %}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
{% extends 'mail/base.txt' %}
|
|
2
|
-
|
|
3
|
-
{% block body %}
|
|
4
|
-
{{ _('%(user)s has certified your organization "%(name)s"',
|
|
5
|
-
name=organization.name,
|
|
6
|
-
user=badge.created_by.fullname
|
|
7
|
-
) }}.
|
|
8
|
-
|
|
9
|
-
{{ _('You can see the badge on this page:') }}
|
|
10
|
-
{{ organization.url_for(_mailCampaign=True) }}
|
|
11
|
-
{% endblock %}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
{% extends 'mail/base.html' %}
|
|
2
|
-
{% from 'mail/button.html' import mail_button %}
|
|
3
|
-
|
|
4
|
-
{% block body %}
|
|
5
|
-
<p style="margin: 0;padding: 0;">{{
|
|
6
|
-
_('%(user)s has identified your organization "%(name)s" as a company',
|
|
7
|
-
user=(
|
|
8
|
-
'<a href="'|safe
|
|
9
|
-
+ badge.created_by.url_for(_mailCampaign=True)
|
|
10
|
-
+ '">'|safe
|
|
11
|
-
+ badge.created_by.fullname
|
|
12
|
-
+ '</a>'|safe
|
|
13
|
-
),
|
|
14
|
-
name=(
|
|
15
|
-
'<a href="'|safe
|
|
16
|
-
+ organization.url_for(_mailCampaign=True)
|
|
17
|
-
+ '">'|safe
|
|
18
|
-
+ organization.name|string
|
|
19
|
-
+ '</a>'|safe
|
|
20
|
-
)
|
|
21
|
-
) }}.</p>
|
|
22
|
-
<br/>
|
|
23
|
-
<table width="100%" border="0" cellspacing="0" cellpadding="0">
|
|
24
|
-
<tr>
|
|
25
|
-
<td align="center">
|
|
26
|
-
{{ mail_button(
|
|
27
|
-
_('See the badge'),
|
|
28
|
-
organization.url_for(_mailCampaign=True)
|
|
29
|
-
) }}
|
|
30
|
-
</td>
|
|
31
|
-
</tr>
|
|
32
|
-
</table>
|
|
33
|
-
{% endblock %}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
{% extends 'mail/base.txt' %}
|
|
2
|
-
|
|
3
|
-
{% block body %}
|
|
4
|
-
{{ _('%(user)s has identified your organization "%(name)s" as a company',
|
|
5
|
-
name=organization.name,
|
|
6
|
-
user=badge.created_by.fullname
|
|
7
|
-
) }}.
|
|
8
|
-
|
|
9
|
-
{{ _('You can see the badge on this page:') }}
|
|
10
|
-
{{ organization.url_for(_mailCampaign=True) }}
|
|
11
|
-
{% endblock %}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
{% extends 'mail/base.html' %}
|
|
2
|
-
{% from 'mail/button.html' import mail_button %}
|
|
3
|
-
|
|
4
|
-
{% block body %}
|
|
5
|
-
<p style="margin: 0;padding: 0;">{{
|
|
6
|
-
_('%(user)s has identified your organization "%(name)s" as a local authority',
|
|
7
|
-
user=(
|
|
8
|
-
'<a href="'|safe
|
|
9
|
-
+ badge.created_by.url_for(_mailCampaign=True)
|
|
10
|
-
+ '">'|safe
|
|
11
|
-
+ badge.created_by.fullname
|
|
12
|
-
+ '</a>'|safe
|
|
13
|
-
),
|
|
14
|
-
name=(
|
|
15
|
-
'<a href="'|safe
|
|
16
|
-
+ organization.url_for(_mailCampaign=True)
|
|
17
|
-
+ '">'|safe
|
|
18
|
-
+ organization.name|string
|
|
19
|
-
+ '</a>'|safe
|
|
20
|
-
)
|
|
21
|
-
) }}.</p>
|
|
22
|
-
<br/>
|
|
23
|
-
<table width="100%" border="0" cellspacing="0" cellpadding="0">
|
|
24
|
-
<tr>
|
|
25
|
-
<td align="center">
|
|
26
|
-
{{ mail_button(
|
|
27
|
-
_('See the badge'),
|
|
28
|
-
organization.url_for(_mailCampaign=True)
|
|
29
|
-
) }}
|
|
30
|
-
</td>
|
|
31
|
-
</tr>
|
|
32
|
-
</table>
|
|
33
|
-
{% endblock %}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
{% extends 'mail/base.txt' %}
|
|
2
|
-
|
|
3
|
-
{% block body %}
|
|
4
|
-
{{ _('%(user)s has identified your organization "%(name)s" as a local authority',
|
|
5
|
-
name=organization.name,
|
|
6
|
-
user=badge.created_by.fullname
|
|
7
|
-
) }}.
|
|
8
|
-
|
|
9
|
-
{{ _('You can see the badge on this page:') }}
|
|
10
|
-
{{ organization.url_for(_mailCampaign=True) }}
|
|
11
|
-
{% endblock %}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
{% extends 'mail/base.html' %}
|
|
2
|
-
{% from 'mail/button.html' import mail_button %}
|
|
3
|
-
|
|
4
|
-
{% block body %}
|
|
5
|
-
<p style="margin: 0;padding: 0;">{{
|
|
6
|
-
_('%(user)s has identified your organization "%(name)s" as public service',
|
|
7
|
-
user=(
|
|
8
|
-
'<a href="'|safe
|
|
9
|
-
+ badge.created_by.url_for(_mailCampaign=True)
|
|
10
|
-
+ '">'|safe
|
|
11
|
-
+ badge.created_by.fullname
|
|
12
|
-
+ '</a>'|safe
|
|
13
|
-
),
|
|
14
|
-
name=(
|
|
15
|
-
'<a href="'|safe
|
|
16
|
-
+ organization.url_for(_mailCampaign=True)
|
|
17
|
-
+ '">'|safe
|
|
18
|
-
+ organization.name|string
|
|
19
|
-
+ '</a>'|safe
|
|
20
|
-
)
|
|
21
|
-
) }}.</p>
|
|
22
|
-
<br/>
|
|
23
|
-
<table width="100%" border="0" cellspacing="0" cellpadding="0">
|
|
24
|
-
<tr>
|
|
25
|
-
<td align="center">
|
|
26
|
-
{{ mail_button(
|
|
27
|
-
_('See the badge'),
|
|
28
|
-
organization.url_for(_mailCampaign=True)
|
|
29
|
-
) }}
|
|
30
|
-
</td>
|
|
31
|
-
</tr>
|
|
32
|
-
</table>
|
|
33
|
-
{% endblock %}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
{% extends 'mail/base.txt' %}
|
|
2
|
-
|
|
3
|
-
{% block body %}
|
|
4
|
-
{{ _('%(user)s has identified your organization "%(name)s" as a public service',
|
|
5
|
-
name=organization.name,
|
|
6
|
-
user=badge.created_by.fullname
|
|
7
|
-
) }}.
|
|
8
|
-
|
|
9
|
-
{{ _('You can see the badge on this page:') }}
|
|
10
|
-
{{ organization.url_for(_mailCampaign=True) }}
|
|
11
|
-
{% endblock %}
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
{% extends 'mail/base.html' %}
|
|
2
|
-
{% from 'mail/button.html' import mail_button %}
|
|
3
|
-
|
|
4
|
-
{% block body %}
|
|
5
|
-
<p style="margin: 0;padding: 0;">{{
|
|
6
|
-
_('%(user)s closed an discussion on your %(type)s %(subject)s',
|
|
7
|
-
type=discussion.subject.verbose_name,
|
|
8
|
-
user=(
|
|
9
|
-
'<a href="'|safe
|
|
10
|
-
+ discussion.closed_by_org_or_user.url_for(_mailCampaign=True)
|
|
11
|
-
+ '">'|safe
|
|
12
|
-
+ discussion.closed_by_name
|
|
13
|
-
+ '</a>'|safe
|
|
14
|
-
),
|
|
15
|
-
subject=(
|
|
16
|
-
'<a href="'|safe
|
|
17
|
-
+ discussion.url_for(_mailCampaign=True)
|
|
18
|
-
+ '">'|safe
|
|
19
|
-
+ discussion.subject|string
|
|
20
|
-
+ '</a>'|safe
|
|
21
|
-
)
|
|
22
|
-
)
|
|
23
|
-
}}.</p>
|
|
24
|
-
<br/>
|
|
25
|
-
<p style="margin: 0;padding: 0;">
|
|
26
|
-
<b>{{ _('Title') }}:</b>
|
|
27
|
-
{{ discussion.title }}
|
|
28
|
-
</p>
|
|
29
|
-
|
|
30
|
-
{% if message %}
|
|
31
|
-
<p style="margin: 0;padding: 0;">
|
|
32
|
-
<b>{{ _('Message') }}:</b>
|
|
33
|
-
{{ message.content | markdown }}
|
|
34
|
-
</p>
|
|
35
|
-
{% endif %}
|
|
36
|
-
|
|
37
|
-
<table width="100%" border="0" cellspacing="0" cellpadding="0">
|
|
38
|
-
<tr>
|
|
39
|
-
<td align="center">
|
|
40
|
-
{{ mail_button(
|
|
41
|
-
_('See the discussion'),
|
|
42
|
-
discussion.url_for(_mailCampaign=True)
|
|
43
|
-
) }}
|
|
44
|
-
</td>
|
|
45
|
-
</tr>
|
|
46
|
-
</table>
|
|
47
|
-
{% endblock %}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
{% extends 'mail/base.txt' %}
|
|
2
|
-
|
|
3
|
-
{% block body %}
|
|
4
|
-
{{ _('%(user)s closed an discussion on your %(type)s %(subject)s',
|
|
5
|
-
type=discussion.subject.verbose_name,
|
|
6
|
-
user=discussion.closed_by_name,
|
|
7
|
-
subject=discussion.subject|string
|
|
8
|
-
) }}.
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
{{ _('Title') }}: {{ discussion.title }}
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
{{ _('You can see the discussion on this page:') }}
|
|
15
|
-
{{ discussion.url_for(_mailCampaign=True) }}
|
|
16
|
-
{% endblock %}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
{% extends 'mail/base.html' %}
|
|
2
|
-
{% from 'mail/button.html' import mail_button %}
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
{% block body %}
|
|
6
|
-
<p style="margin: 0;padding: 0;font-family: "Helvetica Neue", "Helvetica", Helvetica, Arial, sans-serif;">
|
|
7
|
-
{{ _('Your membership for the organization "%(org)s" has been refused',
|
|
8
|
-
org=(
|
|
9
|
-
'<a href="'|safe
|
|
10
|
-
+ org.url_for(_mailCampaign=True)
|
|
11
|
-
+ '">'|safe
|
|
12
|
-
+ org.name
|
|
13
|
-
+ '</a>'|safe
|
|
14
|
-
)
|
|
15
|
-
) }}.</p>
|
|
16
|
-
|
|
17
|
-
<br/>
|
|
18
|
-
<p style="margin: 0;padding: 0;"><b>{{ _('Refusal reason') }}:</b></p>
|
|
19
|
-
<p style="margin: 0;padding: 0;">{{ request.refusal_comment }}</p>
|
|
20
|
-
{% endblock %}
|