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/utils.py
CHANGED
|
@@ -3,7 +3,8 @@ import itertools
|
|
|
3
3
|
import math
|
|
4
4
|
import re
|
|
5
5
|
from collections import Counter
|
|
6
|
-
from datetime import date, datetime
|
|
6
|
+
from datetime import date, datetime, timedelta
|
|
7
|
+
from importlib.metadata import version
|
|
7
8
|
from math import ceil
|
|
8
9
|
from typing import Any, Hashable
|
|
9
10
|
from uuid import UUID, uuid4
|
|
@@ -18,11 +19,16 @@ from faker import Faker
|
|
|
18
19
|
from faker.config import PROVIDERS
|
|
19
20
|
from faker.providers import BaseProvider
|
|
20
21
|
from faker.providers.lorem.la import Provider as LoremProvider
|
|
21
|
-
from flask import abort, request
|
|
22
|
+
from flask import abort, current_app, request
|
|
23
|
+
from mongoengine.fields import BaseQuerySet
|
|
22
24
|
|
|
23
25
|
from udata import tags
|
|
24
26
|
|
|
25
27
|
|
|
28
|
+
def get_udata_version() -> str:
|
|
29
|
+
return version("udata")
|
|
30
|
+
|
|
31
|
+
|
|
26
32
|
def get_by(lst, field, value):
|
|
27
33
|
"""Find an object in a list given a field value"""
|
|
28
34
|
for row in lst:
|
|
@@ -65,7 +71,14 @@ def filter_changed_fields(document, previous, changed_fields: list[str]):
|
|
|
65
71
|
document.reload()
|
|
66
72
|
filtered_changed_fields = []
|
|
67
73
|
for field in changed_fields:
|
|
68
|
-
|
|
74
|
+
# Sometimes, we nullify a field in the clean method (for exemple the `license` when we change
|
|
75
|
+
# the `access_type` of a dataset). This field is then not present in `previous`. Returning `None`
|
|
76
|
+
# is a little bit wrong because we should return the previous value of the `license`. Right now
|
|
77
|
+
# we don't notice license change because `None (not present) == None (removed)` is equal.
|
|
78
|
+
if field not in previous:
|
|
79
|
+
continue
|
|
80
|
+
|
|
81
|
+
previous_value = previous.get(field, None)
|
|
69
82
|
current_value = get_field_value_from_path(document, field)
|
|
70
83
|
# Filter out special case of list reordering, does not support unhashable types
|
|
71
84
|
if (
|
|
@@ -332,7 +345,7 @@ def generate_tags(nb=3) -> [str]:
|
|
|
332
345
|
|
|
333
346
|
def generate_tag() -> str:
|
|
334
347
|
fake_tag: str = faker.word()
|
|
335
|
-
while len(fake_tag) < tags.
|
|
348
|
+
while len(fake_tag) < tags.TAG_MIN_LENGTH:
|
|
336
349
|
fake_tag = faker.word()
|
|
337
350
|
return fake_tag
|
|
338
351
|
|
|
@@ -382,6 +395,55 @@ def id_or_404(object_id):
|
|
|
382
395
|
abort(404)
|
|
383
396
|
|
|
384
397
|
|
|
398
|
+
def get_rss_feed_list(queryset: BaseQuerySet, created_at_field: str) -> list[Any]:
|
|
399
|
+
"""
|
|
400
|
+
Return a list of recent elements for a RSS field.
|
|
401
|
+
|
|
402
|
+
We add a delay before a new element appears in feed in order to allow for post-publication moderation.
|
|
403
|
+
The delay is not taken into account if the element is published by a certified organization.
|
|
404
|
+
"""
|
|
405
|
+
from udata.core.organization.constants import CERTIFIED
|
|
406
|
+
from udata.core.site.models import current_site
|
|
407
|
+
from udata.models import Organization
|
|
408
|
+
|
|
409
|
+
certifed_orgs = Organization.objects(badges__kind=CERTIFIED).only("id")
|
|
410
|
+
|
|
411
|
+
created_delay = datetime.utcnow() - timedelta(
|
|
412
|
+
hours=current_app.config["DELAY_BEFORE_APPEARING_IN_RSS_FEED"]
|
|
413
|
+
)
|
|
414
|
+
elements_with_delay = list(
|
|
415
|
+
queryset.filter(
|
|
416
|
+
**{
|
|
417
|
+
f"{created_at_field}__lte": created_delay,
|
|
418
|
+
"organization__nin": certifed_orgs,
|
|
419
|
+
}
|
|
420
|
+
)
|
|
421
|
+
.order_by(f"-{created_at_field}")
|
|
422
|
+
.limit(current_site.feed_size)
|
|
423
|
+
)
|
|
424
|
+
elements_without_delay = list(
|
|
425
|
+
queryset.filter(organization__in=certifed_orgs)
|
|
426
|
+
.order_by(f"-{created_at_field}")
|
|
427
|
+
.limit(current_site.feed_size)
|
|
428
|
+
)
|
|
429
|
+
|
|
430
|
+
# We need to merge the two lists manually, compensating for the delay, else elements with delay may not show
|
|
431
|
+
# if new elements have been published by certified organization in the meantime
|
|
432
|
+
def get_sort_key(element):
|
|
433
|
+
has_delay = not element.organization or not element.organization.certified
|
|
434
|
+
if has_delay:
|
|
435
|
+
return getattr(element, created_at_field) + timedelta(
|
|
436
|
+
hours=current_app.config["DELAY_BEFORE_APPEARING_IN_RSS_FEED"]
|
|
437
|
+
)
|
|
438
|
+
return getattr(element, created_at_field)
|
|
439
|
+
|
|
440
|
+
elements = sorted(
|
|
441
|
+
[*elements_with_delay, *elements_without_delay], reverse=True, key=get_sort_key
|
|
442
|
+
)[: current_site.feed_size]
|
|
443
|
+
|
|
444
|
+
return elements
|
|
445
|
+
|
|
446
|
+
|
|
385
447
|
def wants_json() -> bool:
|
|
386
448
|
if request.is_json:
|
|
387
449
|
return True
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: udata
|
|
3
|
-
Version:
|
|
3
|
+
Version: 13.0.1.dev21
|
|
4
4
|
Summary: Open data portal
|
|
5
5
|
Author-email: Opendata Team <opendatateam@data.gouv.fr>
|
|
6
6
|
Maintainer-email: Opendata Team <opendatateam@data.gouv.fr>
|
|
@@ -47,7 +47,6 @@ Requires-Dist: flask-cdn==1.5.3
|
|
|
47
47
|
Requires-Dist: flask-gravatar==0.5.0
|
|
48
48
|
Requires-Dist: flask-login==0.6.3
|
|
49
49
|
Requires-Dist: flask-mail==0.10.0
|
|
50
|
-
Requires-Dist: flask-navigation-temp-python-311==0.2.1
|
|
51
50
|
Requires-Dist: flask-principal==0.4.0
|
|
52
51
|
Requires-Dist: flask-restx==1.3.0
|
|
53
52
|
Requires-Dist: flask-security-too==5.1.2
|
|
@@ -96,8 +95,6 @@ Requires-Dist: invoke<3.0,>=2.2.0; extra == "dev"
|
|
|
96
95
|
Requires-Dist: pip-tools<8.0,>=7.4.1; extra == "dev"
|
|
97
96
|
Requires-Dist: pre-commit<5.0,>=4.2.0; extra == "dev"
|
|
98
97
|
Requires-Dist: ruff<1.0,>=0.11.0; extra == "dev"
|
|
99
|
-
Requires-Dist: twine<7.0,>=6.1.0; extra == "dev"
|
|
100
|
-
Requires-Dist: wheel<1.0,>=0.45.1; extra == "dev"
|
|
101
98
|
Provides-Extra: test
|
|
102
99
|
Requires-Dist: faker<38.0,>=37.0.2; extra == "test"
|
|
103
100
|
Requires-Dist: feedparser<7.0,>=6.0.11; extra == "test"
|