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.
- tasks/__init__.py +109 -107
- tasks/helpers.py +18 -18
- udata/__init__.py +4 -4
- udata/admin/views.py +5 -5
- udata/api/__init__.py +111 -134
- udata/api/commands.py +45 -37
- udata/api/errors.py +5 -4
- udata/api/fields.py +23 -21
- udata/api/oauth2.py +55 -74
- udata/api/parsers.py +15 -15
- udata/api/signals.py +1 -1
- udata/api_fields.py +137 -89
- udata/app.py +58 -55
- udata/assets.py +5 -5
- udata/auth/__init__.py +37 -26
- udata/auth/forms.py +23 -15
- udata/auth/helpers.py +1 -1
- udata/auth/mails.py +3 -3
- udata/auth/password_validation.py +19 -15
- udata/auth/views.py +94 -68
- udata/commands/__init__.py +71 -69
- udata/commands/cache.py +7 -7
- udata/commands/db.py +201 -140
- udata/commands/dcat.py +36 -30
- udata/commands/fixtures.py +100 -84
- udata/commands/images.py +21 -20
- udata/commands/info.py +17 -20
- udata/commands/init.py +10 -10
- udata/commands/purge.py +12 -13
- udata/commands/serve.py +41 -29
- udata/commands/static.py +16 -18
- udata/commands/test.py +20 -20
- udata/commands/tests/fixtures.py +26 -24
- udata/commands/worker.py +31 -33
- udata/core/__init__.py +12 -12
- udata/core/activity/__init__.py +0 -1
- udata/core/activity/api.py +59 -49
- udata/core/activity/models.py +28 -26
- udata/core/activity/signals.py +1 -1
- udata/core/activity/tasks.py +16 -10
- udata/core/badges/api.py +6 -6
- udata/core/badges/commands.py +14 -13
- udata/core/badges/fields.py +8 -5
- udata/core/badges/forms.py +7 -4
- udata/core/badges/models.py +16 -31
- udata/core/badges/permissions.py +1 -3
- udata/core/badges/signals.py +2 -2
- udata/core/badges/tasks.py +3 -2
- udata/core/badges/tests/test_commands.py +10 -10
- udata/core/badges/tests/test_model.py +24 -31
- udata/core/contact_point/api.py +19 -18
- udata/core/contact_point/api_fields.py +21 -14
- udata/core/contact_point/factories.py +2 -2
- udata/core/contact_point/forms.py +7 -6
- udata/core/contact_point/models.py +3 -5
- udata/core/dataservices/api.py +26 -21
- udata/core/dataservices/factories.py +13 -11
- udata/core/dataservices/models.py +35 -40
- udata/core/dataservices/permissions.py +4 -4
- udata/core/dataservices/rdf.py +40 -17
- udata/core/dataservices/tasks.py +4 -3
- udata/core/dataset/actions.py +10 -10
- udata/core/dataset/activities.py +21 -23
- udata/core/dataset/api.py +321 -298
- udata/core/dataset/api_fields.py +443 -271
- udata/core/dataset/apiv2.py +305 -229
- udata/core/dataset/commands.py +38 -36
- udata/core/dataset/constants.py +61 -54
- udata/core/dataset/csv.py +70 -74
- udata/core/dataset/events.py +39 -32
- udata/core/dataset/exceptions.py +8 -4
- udata/core/dataset/factories.py +57 -65
- udata/core/dataset/forms.py +87 -63
- udata/core/dataset/models.py +336 -280
- udata/core/dataset/permissions.py +9 -6
- udata/core/dataset/preview.py +15 -17
- udata/core/dataset/rdf.py +156 -122
- udata/core/dataset/search.py +92 -77
- udata/core/dataset/signals.py +1 -1
- udata/core/dataset/tasks.py +63 -54
- udata/core/discussions/actions.py +5 -5
- udata/core/discussions/api.py +124 -120
- udata/core/discussions/factories.py +2 -2
- udata/core/discussions/forms.py +9 -7
- udata/core/discussions/metrics.py +1 -3
- udata/core/discussions/models.py +25 -24
- udata/core/discussions/notifications.py +18 -14
- udata/core/discussions/permissions.py +3 -3
- udata/core/discussions/signals.py +4 -4
- udata/core/discussions/tasks.py +24 -28
- udata/core/followers/api.py +32 -33
- udata/core/followers/models.py +9 -9
- udata/core/followers/signals.py +3 -3
- udata/core/jobs/actions.py +7 -7
- udata/core/jobs/api.py +99 -92
- udata/core/jobs/commands.py +48 -49
- udata/core/jobs/forms.py +11 -11
- udata/core/jobs/models.py +6 -6
- udata/core/metrics/__init__.py +2 -2
- udata/core/metrics/commands.py +34 -30
- udata/core/metrics/models.py +2 -4
- udata/core/metrics/signals.py +1 -1
- udata/core/metrics/tasks.py +3 -3
- udata/core/organization/activities.py +12 -15
- udata/core/organization/api.py +167 -174
- udata/core/organization/api_fields.py +183 -124
- udata/core/organization/apiv2.py +32 -32
- udata/core/organization/commands.py +20 -22
- udata/core/organization/constants.py +11 -11
- udata/core/organization/csv.py +17 -15
- udata/core/organization/factories.py +8 -11
- udata/core/organization/forms.py +32 -26
- udata/core/organization/metrics.py +2 -1
- udata/core/organization/models.py +87 -67
- udata/core/organization/notifications.py +18 -14
- udata/core/organization/permissions.py +10 -11
- udata/core/organization/rdf.py +14 -14
- udata/core/organization/search.py +30 -28
- udata/core/organization/signals.py +7 -7
- udata/core/organization/tasks.py +42 -61
- udata/core/owned.py +38 -27
- udata/core/post/api.py +82 -81
- udata/core/post/constants.py +8 -5
- udata/core/post/factories.py +4 -4
- udata/core/post/forms.py +13 -14
- udata/core/post/models.py +20 -22
- udata/core/post/tests/test_api.py +30 -32
- udata/core/reports/api.py +8 -7
- udata/core/reports/constants.py +1 -3
- udata/core/reports/models.py +10 -10
- udata/core/reuse/activities.py +15 -19
- udata/core/reuse/api.py +123 -126
- udata/core/reuse/api_fields.py +120 -85
- udata/core/reuse/apiv2.py +11 -10
- udata/core/reuse/constants.py +23 -23
- udata/core/reuse/csv.py +18 -18
- udata/core/reuse/factories.py +5 -9
- udata/core/reuse/forms.py +24 -21
- udata/core/reuse/models.py +55 -51
- udata/core/reuse/permissions.py +2 -2
- udata/core/reuse/search.py +49 -46
- udata/core/reuse/signals.py +1 -1
- udata/core/reuse/tasks.py +4 -5
- udata/core/site/api.py +47 -50
- udata/core/site/factories.py +2 -2
- udata/core/site/forms.py +4 -5
- udata/core/site/models.py +94 -63
- udata/core/site/rdf.py +14 -14
- udata/core/spam/api.py +16 -9
- udata/core/spam/constants.py +4 -4
- udata/core/spam/fields.py +13 -7
- udata/core/spam/models.py +27 -20
- udata/core/spam/signals.py +1 -1
- udata/core/spam/tests/test_spam.py +6 -5
- udata/core/spatial/api.py +72 -80
- udata/core/spatial/api_fields.py +73 -58
- udata/core/spatial/commands.py +67 -64
- udata/core/spatial/constants.py +3 -3
- udata/core/spatial/factories.py +37 -54
- udata/core/spatial/forms.py +27 -26
- udata/core/spatial/geoids.py +17 -17
- udata/core/spatial/models.py +43 -47
- udata/core/spatial/tasks.py +2 -1
- udata/core/spatial/tests/test_api.py +115 -130
- udata/core/spatial/tests/test_fields.py +74 -77
- udata/core/spatial/tests/test_geoid.py +22 -22
- udata/core/spatial/tests/test_models.py +5 -7
- udata/core/spatial/translations.py +16 -16
- udata/core/storages/__init__.py +16 -18
- udata/core/storages/api.py +66 -64
- udata/core/storages/tasks.py +7 -7
- udata/core/storages/utils.py +15 -15
- udata/core/storages/views.py +5 -6
- udata/core/tags/api.py +17 -14
- udata/core/tags/csv.py +4 -4
- udata/core/tags/models.py +8 -5
- udata/core/tags/tasks.py +11 -13
- udata/core/tags/views.py +4 -4
- udata/core/topic/api.py +84 -73
- udata/core/topic/apiv2.py +157 -127
- udata/core/topic/factories.py +3 -4
- udata/core/topic/forms.py +12 -14
- udata/core/topic/models.py +14 -19
- udata/core/topic/parsers.py +26 -26
- udata/core/user/activities.py +30 -29
- udata/core/user/api.py +151 -152
- udata/core/user/api_fields.py +132 -100
- udata/core/user/apiv2.py +7 -7
- udata/core/user/commands.py +38 -38
- udata/core/user/factories.py +8 -9
- udata/core/user/forms.py +14 -11
- udata/core/user/metrics.py +2 -2
- udata/core/user/models.py +68 -69
- udata/core/user/permissions.py +4 -5
- udata/core/user/rdf.py +7 -8
- udata/core/user/tasks.py +2 -2
- udata/core/user/tests/test_user_model.py +24 -16
- udata/cors.py +99 -0
- udata/db/tasks.py +2 -1
- udata/entrypoints.py +35 -31
- udata/errors.py +2 -1
- udata/event/values.py +6 -6
- udata/factories.py +2 -2
- udata/features/identicon/api.py +5 -6
- udata/features/identicon/backends.py +48 -55
- udata/features/identicon/tests/test_backends.py +4 -5
- udata/features/notifications/__init__.py +0 -1
- udata/features/notifications/actions.py +9 -9
- udata/features/notifications/api.py +17 -13
- udata/features/territories/__init__.py +12 -10
- udata/features/territories/api.py +14 -15
- udata/features/territories/models.py +23 -28
- udata/features/transfer/actions.py +8 -11
- udata/features/transfer/api.py +84 -77
- udata/features/transfer/factories.py +2 -1
- udata/features/transfer/models.py +11 -12
- udata/features/transfer/notifications.py +19 -15
- udata/features/transfer/permissions.py +5 -5
- udata/forms/__init__.py +5 -2
- udata/forms/fields.py +164 -172
- udata/forms/validators.py +19 -22
- udata/forms/widgets.py +9 -13
- udata/frontend/__init__.py +31 -26
- udata/frontend/csv.py +68 -58
- udata/frontend/markdown.py +40 -44
- udata/harvest/actions.py +89 -77
- udata/harvest/api.py +294 -238
- udata/harvest/backends/__init__.py +4 -4
- udata/harvest/backends/base.py +128 -111
- udata/harvest/backends/dcat.py +80 -66
- udata/harvest/commands.py +56 -60
- udata/harvest/csv.py +8 -8
- udata/harvest/exceptions.py +6 -3
- udata/harvest/filters.py +24 -23
- udata/harvest/forms.py +27 -28
- udata/harvest/models.py +88 -80
- udata/harvest/notifications.py +15 -10
- udata/harvest/signals.py +13 -13
- udata/harvest/tasks.py +11 -10
- udata/harvest/tests/factories.py +23 -24
- udata/harvest/tests/test_actions.py +136 -166
- udata/harvest/tests/test_api.py +220 -214
- udata/harvest/tests/test_base_backend.py +117 -112
- udata/harvest/tests/test_dcat_backend.py +380 -308
- udata/harvest/tests/test_filters.py +33 -22
- udata/harvest/tests/test_models.py +11 -14
- udata/harvest/tests/test_notifications.py +6 -7
- udata/harvest/tests/test_tasks.py +7 -6
- udata/i18n.py +237 -78
- udata/linkchecker/backends.py +5 -11
- udata/linkchecker/checker.py +23 -22
- udata/linkchecker/commands.py +4 -6
- udata/linkchecker/models.py +6 -6
- udata/linkchecker/tasks.py +18 -20
- udata/mail.py +21 -21
- udata/migrations/2020-07-24-remove-s-from-scope-oauth.py +9 -8
- udata/migrations/2020-08-24-add-fs-filename.py +9 -8
- udata/migrations/2020-09-28-update-reuses-datasets-metrics.py +5 -4
- udata/migrations/2020-10-16-migrate-ods-resources.py +9 -10
- udata/migrations/2021-04-08-update-schema-with-new-structure.py +8 -7
- udata/migrations/2021-05-27-fix-default-schema-name.py +7 -6
- udata/migrations/2021-07-05-remove-unused-badges.py +17 -15
- udata/migrations/2021-07-07-update-schema-for-community-resources.py +7 -6
- udata/migrations/2021-08-17-follow-integrity.py +5 -4
- udata/migrations/2021-08-17-harvest-integrity.py +13 -12
- udata/migrations/2021-08-17-oauth2client-integrity.py +5 -4
- udata/migrations/2021-08-17-transfer-integrity.py +5 -4
- udata/migrations/2021-08-17-users-integrity.py +9 -8
- udata/migrations/2021-12-14-reuse-topics.py +7 -6
- udata/migrations/2022-04-21-improve-extension-detection.py +8 -7
- udata/migrations/2022-09-22-clean-inactive-harvest-datasets.py +16 -14
- udata/migrations/2022-10-10-add-fs_uniquifier-to-user-model.py +6 -6
- udata/migrations/2022-10-10-migrate-harvest-extras.py +36 -26
- udata/migrations/2023-02-08-rename-internal-dates.py +46 -28
- udata/migrations/2024-01-29-fix-reuse-and-dataset-with-private-None.py +10 -8
- udata/migrations/2024-03-22-migrate-activity-kwargs-to-extras.py +6 -4
- udata/migrations/2024-06-11-fix-reuse-datasets-references.py +7 -6
- udata/migrations/__init__.py +123 -105
- udata/models/__init__.py +4 -4
- udata/mongo/__init__.py +13 -11
- udata/mongo/badges_field.py +3 -2
- udata/mongo/datetime_fields.py +13 -12
- udata/mongo/document.py +17 -16
- udata/mongo/engine.py +15 -16
- udata/mongo/errors.py +2 -1
- udata/mongo/extras_fields.py +30 -20
- udata/mongo/queryset.py +12 -12
- udata/mongo/slug_fields.py +38 -28
- udata/mongo/taglist_field.py +1 -2
- udata/mongo/url_field.py +5 -5
- udata/mongo/uuid_fields.py +4 -3
- udata/notifications/__init__.py +1 -1
- udata/notifications/mattermost.py +10 -9
- udata/rdf.py +167 -188
- udata/routing.py +40 -45
- udata/search/__init__.py +18 -19
- udata/search/adapter.py +17 -16
- udata/search/commands.py +44 -51
- udata/search/fields.py +13 -20
- udata/search/query.py +23 -18
- udata/search/result.py +9 -10
- udata/sentry.py +21 -19
- udata/settings.py +262 -198
- udata/sitemap.py +8 -6
- udata/storage/s3.py +20 -13
- udata/tags.py +4 -5
- udata/tasks.py +43 -42
- udata/tests/__init__.py +9 -6
- udata/tests/api/__init__.py +8 -6
- udata/tests/api/test_auth_api.py +395 -321
- udata/tests/api/test_base_api.py +33 -35
- udata/tests/api/test_contact_points.py +7 -9
- udata/tests/api/test_dataservices_api.py +211 -158
- udata/tests/api/test_datasets_api.py +823 -812
- udata/tests/api/test_follow_api.py +13 -15
- udata/tests/api/test_me_api.py +95 -112
- udata/tests/api/test_organizations_api.py +301 -339
- udata/tests/api/test_reports_api.py +35 -25
- udata/tests/api/test_reuses_api.py +134 -139
- udata/tests/api/test_swagger.py +5 -5
- udata/tests/api/test_tags_api.py +18 -25
- udata/tests/api/test_topics_api.py +94 -94
- udata/tests/api/test_transfer_api.py +53 -48
- udata/tests/api/test_user_api.py +128 -141
- udata/tests/apiv2/test_datasets.py +290 -198
- udata/tests/apiv2/test_me_api.py +10 -11
- udata/tests/apiv2/test_organizations.py +56 -74
- udata/tests/apiv2/test_swagger.py +5 -5
- udata/tests/apiv2/test_topics.py +69 -87
- udata/tests/cli/test_cli_base.py +8 -8
- udata/tests/cli/test_db_cli.py +21 -19
- udata/tests/dataservice/test_dataservice_tasks.py +8 -12
- udata/tests/dataset/test_csv_adapter.py +44 -35
- udata/tests/dataset/test_dataset_actions.py +2 -3
- udata/tests/dataset/test_dataset_commands.py +7 -8
- udata/tests/dataset/test_dataset_events.py +36 -29
- udata/tests/dataset/test_dataset_model.py +224 -217
- udata/tests/dataset/test_dataset_rdf.py +142 -131
- udata/tests/dataset/test_dataset_tasks.py +15 -15
- udata/tests/dataset/test_resource_preview.py +10 -13
- udata/tests/features/territories/__init__.py +9 -13
- udata/tests/features/territories/test_territories_api.py +71 -91
- udata/tests/forms/test_basic_fields.py +7 -7
- udata/tests/forms/test_current_user_field.py +39 -66
- udata/tests/forms/test_daterange_field.py +31 -39
- udata/tests/forms/test_dict_field.py +28 -26
- udata/tests/forms/test_extras_fields.py +102 -76
- udata/tests/forms/test_form_field.py +8 -8
- udata/tests/forms/test_image_field.py +33 -26
- udata/tests/forms/test_model_field.py +134 -123
- udata/tests/forms/test_model_list_field.py +7 -7
- udata/tests/forms/test_nested_model_list_field.py +117 -79
- udata/tests/forms/test_publish_as_field.py +36 -65
- udata/tests/forms/test_reference_field.py +34 -53
- udata/tests/forms/test_user_forms.py +23 -21
- udata/tests/forms/test_uuid_field.py +6 -10
- udata/tests/frontend/__init__.py +9 -6
- udata/tests/frontend/test_auth.py +7 -6
- udata/tests/frontend/test_csv.py +81 -96
- udata/tests/frontend/test_hooks.py +43 -43
- udata/tests/frontend/test_markdown.py +211 -191
- udata/tests/helpers.py +32 -37
- udata/tests/models.py +2 -2
- udata/tests/organization/test_csv_adapter.py +21 -16
- udata/tests/organization/test_notifications.py +11 -18
- udata/tests/organization/test_organization_model.py +13 -13
- udata/tests/organization/test_organization_rdf.py +29 -22
- udata/tests/organization/test_organization_tasks.py +16 -17
- udata/tests/plugin.py +79 -73
- udata/tests/reuse/test_reuse_model.py +21 -21
- udata/tests/reuse/test_reuse_task.py +11 -13
- udata/tests/search/__init__.py +11 -12
- udata/tests/search/test_adapter.py +60 -70
- udata/tests/search/test_query.py +16 -16
- udata/tests/search/test_results.py +10 -7
- udata/tests/site/test_site_api.py +11 -16
- udata/tests/site/test_site_metrics.py +20 -30
- udata/tests/site/test_site_model.py +4 -5
- udata/tests/site/test_site_rdf.py +94 -78
- udata/tests/test_activity.py +17 -17
- udata/tests/test_cors.py +62 -0
- udata/tests/test_discussions.py +292 -299
- udata/tests/test_i18n.py +37 -40
- udata/tests/test_linkchecker.py +91 -85
- udata/tests/test_mail.py +13 -17
- udata/tests/test_migrations.py +219 -180
- udata/tests/test_model.py +164 -157
- udata/tests/test_notifications.py +17 -17
- udata/tests/test_owned.py +14 -14
- udata/tests/test_rdf.py +25 -23
- udata/tests/test_routing.py +89 -93
- udata/tests/test_storages.py +137 -128
- udata/tests/test_tags.py +44 -46
- udata/tests/test_topics.py +7 -7
- udata/tests/test_transfer.py +42 -49
- udata/tests/test_uris.py +160 -161
- udata/tests/test_utils.py +79 -71
- udata/tests/user/test_user_rdf.py +5 -9
- udata/tests/workers/test_jobs_commands.py +57 -58
- udata/tests/workers/test_tasks_routing.py +23 -29
- udata/tests/workers/test_workers_api.py +125 -131
- udata/tests/workers/test_workers_helpers.py +6 -6
- udata/tracking.py +4 -6
- udata/uris.py +45 -46
- udata/utils.py +68 -66
- udata/wsgi.py +1 -1
- {udata-9.1.2.dev30355.dist-info → udata-9.1.2.dev30454.dist-info}/METADATA +7 -3
- udata-9.1.2.dev30454.dist-info/RECORD +706 -0
- udata-9.1.2.dev30355.dist-info/RECORD +0 -704
- {udata-9.1.2.dev30355.dist-info → udata-9.1.2.dev30454.dist-info}/LICENSE +0 -0
- {udata-9.1.2.dev30355.dist-info → udata-9.1.2.dev30454.dist-info}/WHEEL +0 -0
- {udata-9.1.2.dev30355.dist-info → udata-9.1.2.dev30454.dist-info}/entry_points.txt +0 -0
- {udata-9.1.2.dev30355.dist-info → udata-9.1.2.dev30454.dist-info}/top_level.txt +0 -0
udata/core/dataset/factories.py
CHANGED
|
@@ -1,33 +1,28 @@
|
|
|
1
|
-
import factory
|
|
2
|
-
|
|
3
1
|
import json
|
|
4
2
|
from os.path import join
|
|
5
3
|
|
|
6
|
-
|
|
7
|
-
from udata.factories import ModelFactory
|
|
8
|
-
|
|
9
|
-
from .models import Dataset, Resource, Checksum, CommunityResource, License
|
|
4
|
+
import factory
|
|
10
5
|
|
|
6
|
+
from udata.app import ROOT_DIR
|
|
11
7
|
from udata.core.organization.factories import OrganizationFactory
|
|
12
8
|
from udata.core.spatial.factories import SpatialCoverageFactory
|
|
9
|
+
from udata.factories import ModelFactory
|
|
10
|
+
|
|
11
|
+
from .models import Checksum, CommunityResource, Dataset, License, Resource
|
|
13
12
|
|
|
14
13
|
|
|
15
14
|
class DatasetFactory(ModelFactory):
|
|
16
15
|
class Meta:
|
|
17
16
|
model = Dataset
|
|
18
17
|
|
|
19
|
-
title = factory.Faker(
|
|
20
|
-
description = factory.Faker(
|
|
21
|
-
frequency =
|
|
18
|
+
title = factory.Faker("sentence")
|
|
19
|
+
description = factory.Faker("text")
|
|
20
|
+
frequency = "unknown"
|
|
22
21
|
resources = factory.LazyAttribute(lambda o: ResourceFactory.build_batch(o.nb_resources))
|
|
23
22
|
|
|
24
23
|
class Params:
|
|
25
|
-
geo = factory.Trait(
|
|
26
|
-
|
|
27
|
-
)
|
|
28
|
-
visible = factory.Trait(
|
|
29
|
-
resources=factory.LazyAttribute(lambda o: [ResourceFactory()])
|
|
30
|
-
)
|
|
24
|
+
geo = factory.Trait(spatial=factory.SubFactory(SpatialCoverageFactory))
|
|
25
|
+
visible = factory.Trait(resources=factory.LazyAttribute(lambda o: [ResourceFactory()]))
|
|
31
26
|
org = factory.Trait(
|
|
32
27
|
organization=factory.SubFactory(OrganizationFactory),
|
|
33
28
|
)
|
|
@@ -42,19 +37,19 @@ class ChecksumFactory(ModelFactory):
|
|
|
42
37
|
class Meta:
|
|
43
38
|
model = Checksum
|
|
44
39
|
|
|
45
|
-
type =
|
|
46
|
-
value = factory.Faker(
|
|
40
|
+
type = "sha1"
|
|
41
|
+
value = factory.Faker("sha1")
|
|
47
42
|
|
|
48
43
|
|
|
49
44
|
class BaseResourceFactory(ModelFactory):
|
|
50
|
-
title = factory.Faker(
|
|
51
|
-
description = factory.Faker(
|
|
52
|
-
filetype =
|
|
53
|
-
type =
|
|
54
|
-
url = factory.Faker(
|
|
45
|
+
title = factory.Faker("sentence")
|
|
46
|
+
description = factory.Faker("text")
|
|
47
|
+
filetype = "file"
|
|
48
|
+
type = "documentation"
|
|
49
|
+
url = factory.Faker("url")
|
|
55
50
|
checksum = factory.SubFactory(ChecksumFactory)
|
|
56
|
-
mime = factory.Faker(
|
|
57
|
-
filesize = factory.Faker(
|
|
51
|
+
mime = factory.Faker("mime_type", category="text")
|
|
52
|
+
filesize = factory.Faker("pyint")
|
|
58
53
|
|
|
59
54
|
|
|
60
55
|
class CommunityResourceFactory(BaseResourceFactory):
|
|
@@ -71,21 +66,24 @@ class LicenseFactory(ModelFactory):
|
|
|
71
66
|
class Meta:
|
|
72
67
|
model = License
|
|
73
68
|
|
|
74
|
-
id = factory.Faker(
|
|
75
|
-
title = factory.Faker(
|
|
76
|
-
url = factory.Faker(
|
|
69
|
+
id = factory.Faker("unique_string")
|
|
70
|
+
title = factory.Faker("sentence")
|
|
71
|
+
url = factory.Faker("uri")
|
|
72
|
+
|
|
77
73
|
|
|
78
|
-
class ResourceSchemaMockData
|
|
74
|
+
class ResourceSchemaMockData:
|
|
79
75
|
@staticmethod
|
|
80
76
|
def get_mock_data():
|
|
81
|
-
return json.load(open(join(ROOT_DIR,
|
|
82
|
-
|
|
77
|
+
return json.load(open(join(ROOT_DIR, "tests", "schemas.json")))
|
|
78
|
+
|
|
83
79
|
@staticmethod
|
|
84
|
-
def get_all_schemas_from_mock_data(with_datapackage_info
|
|
85
|
-
|
|
80
|
+
def get_all_schemas_from_mock_data(with_datapackage_info=True):
|
|
81
|
+
"""
|
|
86
82
|
with_datapackage_info is here to allow testing with or without marshalling (marshalling add None for inexistant datapackage_* fields)
|
|
87
|
-
|
|
88
|
-
schemas = ResourceSchemaMockData.get_expected_assignable_schemas_from_mock_data(
|
|
83
|
+
"""
|
|
84
|
+
schemas = ResourceSchemaMockData.get_expected_assignable_schemas_from_mock_data(
|
|
85
|
+
with_datapackage_info
|
|
86
|
+
)
|
|
89
87
|
|
|
90
88
|
datapackage = {
|
|
91
89
|
"name": "etalab/schema-irve",
|
|
@@ -95,28 +93,25 @@ class ResourceSchemaMockData():
|
|
|
95
93
|
"schema_type": "datapackage",
|
|
96
94
|
"contact": "contact@transport.beta.gouv.fr",
|
|
97
95
|
"examples": [],
|
|
98
|
-
"labels": [
|
|
99
|
-
"Socle Commun des Donn\u00e9es Locales",
|
|
100
|
-
"transport.data.gouv.fr"
|
|
101
|
-
],
|
|
96
|
+
"labels": ["Socle Commun des Donn\u00e9es Locales", "transport.data.gouv.fr"],
|
|
102
97
|
"consolidation_dataset_id": "5448d3e0c751df01f85d0572",
|
|
103
98
|
"versions": [
|
|
104
99
|
{
|
|
105
100
|
"version_name": "2.2.0",
|
|
106
|
-
"schema_url": "https://schema.data.gouv.fr/schemas/etalab/schema-irve/2.2.0/datapackage.json"
|
|
101
|
+
"schema_url": "https://schema.data.gouv.fr/schemas/etalab/schema-irve/2.2.0/datapackage.json",
|
|
107
102
|
},
|
|
108
103
|
{
|
|
109
104
|
"version_name": "2.2.1",
|
|
110
|
-
"schema_url": "https://schema.data.gouv.fr/schemas/etalab/schema-irve/2.2.1/datapackage.json"
|
|
105
|
+
"schema_url": "https://schema.data.gouv.fr/schemas/etalab/schema-irve/2.2.1/datapackage.json",
|
|
111
106
|
},
|
|
112
107
|
{
|
|
113
108
|
"version_name": "2.3.0",
|
|
114
|
-
"schema_url": "https://schema.data.gouv.fr/schemas/etalab/schema-irve/2.3.0/datapackage.json"
|
|
109
|
+
"schema_url": "https://schema.data.gouv.fr/schemas/etalab/schema-irve/2.3.0/datapackage.json",
|
|
115
110
|
},
|
|
116
111
|
{
|
|
117
112
|
"version_name": "2.3.1",
|
|
118
|
-
"schema_url": "https://schema.data.gouv.fr/schemas/etalab/schema-irve/2.3.1/datapackage.json"
|
|
119
|
-
}
|
|
113
|
+
"schema_url": "https://schema.data.gouv.fr/schemas/etalab/schema-irve/2.3.1/datapackage.json",
|
|
114
|
+
},
|
|
120
115
|
],
|
|
121
116
|
"external_doc": "https://doc.transport.data.gouv.fr/producteurs/infrastructures-de-recharge-de-vehicules-electriques-irve",
|
|
122
117
|
"external_tool": None,
|
|
@@ -129,12 +124,12 @@ class ResourceSchemaMockData():
|
|
|
129
124
|
datapackage["datapackage_description"] = None
|
|
130
125
|
|
|
131
126
|
return [datapackage] + schemas
|
|
132
|
-
|
|
127
|
+
|
|
133
128
|
@staticmethod
|
|
134
|
-
def get_expected_assignable_schemas_from_mock_data(with_datapackage_info
|
|
135
|
-
|
|
129
|
+
def get_expected_assignable_schemas_from_mock_data(with_datapackage_info=True):
|
|
130
|
+
"""
|
|
136
131
|
with_datapackage_info is here to allow testing with or without marshalling (marshalling add None for inexistant datapackage_* fields)
|
|
137
|
-
|
|
132
|
+
"""
|
|
138
133
|
schemas = [
|
|
139
134
|
{
|
|
140
135
|
"name": "etalab/schema-irve-statique",
|
|
@@ -145,31 +140,28 @@ class ResourceSchemaMockData():
|
|
|
145
140
|
"contact": "contact@transport.beta.gouv.fr",
|
|
146
141
|
"examples": [
|
|
147
142
|
{
|
|
148
|
-
|
|
149
|
-
|
|
143
|
+
"title": "Exemple de fichier IRVE valide",
|
|
144
|
+
"path": "https://github.com/etalab/schema-irve/raw/v2.2.1/exemple-valide.csv",
|
|
150
145
|
}
|
|
151
146
|
],
|
|
152
|
-
"labels": [
|
|
153
|
-
"Socle Commun des Donn\u00e9es Locales",
|
|
154
|
-
"transport.data.gouv.fr"
|
|
155
|
-
],
|
|
147
|
+
"labels": ["Socle Commun des Donn\u00e9es Locales", "transport.data.gouv.fr"],
|
|
156
148
|
"consolidation_dataset_id": "5448d3e0c751df01f85d0572",
|
|
157
149
|
"versions": [
|
|
158
150
|
{
|
|
159
151
|
"version_name": "2.2.0",
|
|
160
|
-
"schema_url": "https://schema.data.gouv.fr/schemas/etalab/schema-irve-statique/2.2.0/schema-statique.json"
|
|
152
|
+
"schema_url": "https://schema.data.gouv.fr/schemas/etalab/schema-irve-statique/2.2.0/schema-statique.json",
|
|
161
153
|
},
|
|
162
154
|
{
|
|
163
155
|
"version_name": "2.2.1",
|
|
164
|
-
"schema_url": "https://schema.data.gouv.fr/schemas/etalab/schema-irve-statique/2.2.1/schema-statique.json"
|
|
165
|
-
}
|
|
156
|
+
"schema_url": "https://schema.data.gouv.fr/schemas/etalab/schema-irve-statique/2.2.1/schema-statique.json",
|
|
157
|
+
},
|
|
166
158
|
],
|
|
167
159
|
"external_doc": "https://doc.transport.data.gouv.fr/producteurs/infrastructures-de-recharge-de-vehicules-electriques-irve",
|
|
168
160
|
"external_tool": None,
|
|
169
161
|
"homepage": "https://github.com/etalab/schema-irve.git",
|
|
170
162
|
"datapackage_title": "Infrastructures de recharges pour v\u00e9hicules \u00e9lectriques (IRVE)",
|
|
171
163
|
"datapackage_name": "etalab/schema-irve",
|
|
172
|
-
"datapackage_description": "data package contenant 2 sch\u00e9mas : IRVE statique et IRVE dynamique"
|
|
164
|
+
"datapackage_description": "data package contenant 2 sch\u00e9mas : IRVE statique et IRVE dynamique",
|
|
173
165
|
},
|
|
174
166
|
{
|
|
175
167
|
"name": "139bercy/format-commande-publique",
|
|
@@ -184,29 +176,29 @@ class ResourceSchemaMockData():
|
|
|
184
176
|
"versions": [
|
|
185
177
|
{
|
|
186
178
|
"version_name": "1.3.0",
|
|
187
|
-
"schema_url": "https://schema.data.gouv.fr/schemas/139bercy/format-commande-publique/1.3.0/sch\u00e9mas/json/contrats-concessions.json"
|
|
179
|
+
"schema_url": "https://schema.data.gouv.fr/schemas/139bercy/format-commande-publique/1.3.0/sch\u00e9mas/json/contrats-concessions.json",
|
|
188
180
|
},
|
|
189
181
|
{
|
|
190
182
|
"version_name": "1.4.0",
|
|
191
|
-
"schema_url": "https://schema.data.gouv.fr/schemas/139bercy/format-commande-publique/1.4.0/marches.json"
|
|
183
|
+
"schema_url": "https://schema.data.gouv.fr/schemas/139bercy/format-commande-publique/1.4.0/marches.json",
|
|
192
184
|
},
|
|
193
185
|
{
|
|
194
186
|
"version_name": "1.5.0",
|
|
195
|
-
"schema_url": "https://schema.data.gouv.fr/schemas/139bercy/format-commande-publique/1.5.0/marches.json"
|
|
187
|
+
"schema_url": "https://schema.data.gouv.fr/schemas/139bercy/format-commande-publique/1.5.0/marches.json",
|
|
196
188
|
},
|
|
197
189
|
{
|
|
198
190
|
"version_name": "2.0.0",
|
|
199
|
-
"schema_url": "https://schema.data.gouv.fr/schemas/139bercy/format-commande-publique/2.0.0/marches.json"
|
|
191
|
+
"schema_url": "https://schema.data.gouv.fr/schemas/139bercy/format-commande-publique/2.0.0/marches.json",
|
|
200
192
|
},
|
|
201
193
|
{
|
|
202
194
|
"version_name": "2.0.1",
|
|
203
|
-
"schema_url": "https://schema.data.gouv.fr/schemas/139bercy/format-commande-publique/2.0.1/marches.json"
|
|
204
|
-
}
|
|
195
|
+
"schema_url": "https://schema.data.gouv.fr/schemas/139bercy/format-commande-publique/2.0.1/marches.json",
|
|
196
|
+
},
|
|
205
197
|
],
|
|
206
198
|
"external_doc": None,
|
|
207
199
|
"external_tool": None,
|
|
208
200
|
"homepage": "https://github.com/139bercy/format-commande-publique",
|
|
209
|
-
}
|
|
201
|
+
},
|
|
210
202
|
]
|
|
211
203
|
|
|
212
204
|
if with_datapackage_info:
|
|
@@ -214,4 +206,4 @@ class ResourceSchemaMockData():
|
|
|
214
206
|
schemas[1]["datapackage_name"] = None
|
|
215
207
|
schemas[1]["datapackage_description"] = None
|
|
216
208
|
|
|
217
|
-
return schemas
|
|
209
|
+
return schemas
|
udata/core/dataset/forms.py
CHANGED
|
@@ -1,46 +1,59 @@
|
|
|
1
1
|
from mongoengine import ValidationError
|
|
2
2
|
|
|
3
|
+
from udata.core.spatial.forms import SpatialCoverageField
|
|
4
|
+
from udata.core.storages import resources
|
|
3
5
|
from udata.forms import ModelForm, fields, validators
|
|
4
6
|
from udata.i18n import lazy_gettext as _
|
|
5
|
-
|
|
6
|
-
from udata.core.storages import resources
|
|
7
|
-
from udata.core.spatial.forms import SpatialCoverageField
|
|
8
7
|
from udata.mongo.errors import FieldValidationError
|
|
9
8
|
|
|
10
|
-
from .models import (
|
|
11
|
-
Dataset, Resource, Schema, License, Checksum, CommunityResource,
|
|
12
|
-
)
|
|
13
9
|
from .constants import (
|
|
14
|
-
|
|
15
|
-
|
|
10
|
+
CHECKSUM_TYPES,
|
|
11
|
+
DEFAULT_FREQUENCY,
|
|
12
|
+
DESCRIPTION_SIZE_LIMIT,
|
|
13
|
+
LEGACY_FREQUENCIES,
|
|
14
|
+
RESOURCE_FILETYPES,
|
|
15
|
+
RESOURCE_TYPES,
|
|
16
|
+
TITLE_SIZE_LIMIT,
|
|
17
|
+
UPDATE_FREQUENCIES,
|
|
18
|
+
)
|
|
19
|
+
from .models import (
|
|
20
|
+
Checksum,
|
|
21
|
+
CommunityResource,
|
|
22
|
+
Dataset,
|
|
23
|
+
License,
|
|
24
|
+
Resource,
|
|
25
|
+
Schema,
|
|
16
26
|
)
|
|
17
27
|
|
|
18
|
-
__all__ = (
|
|
28
|
+
__all__ = ("DatasetForm", "ResourceForm", "CommunityResourceForm")
|
|
29
|
+
|
|
19
30
|
|
|
20
31
|
class ChecksumForm(ModelForm):
|
|
21
32
|
model_class = Checksum
|
|
22
33
|
choices = list(zip(CHECKSUM_TYPES, CHECKSUM_TYPES))
|
|
23
|
-
type = fields.SelectField(choices=choices, default=
|
|
24
|
-
value = fields.StringField(_(
|
|
34
|
+
type = fields.SelectField(choices=choices, default="sha1")
|
|
35
|
+
value = fields.StringField(_("Checksum value"), [validators.DataRequired()])
|
|
25
36
|
|
|
26
37
|
|
|
27
38
|
def normalize_format(data):
|
|
28
|
-
|
|
39
|
+
"""Normalize format field: strip and lowercase"""
|
|
29
40
|
if data:
|
|
30
41
|
return data.strip().lower()
|
|
31
42
|
|
|
32
43
|
|
|
33
44
|
class SchemaForm(ModelForm):
|
|
34
45
|
model_class = Schema
|
|
35
|
-
url = fields.URLField(_(
|
|
36
|
-
name = fields.StringField(_(
|
|
37
|
-
version = fields.StringField(_(
|
|
46
|
+
url = fields.URLField(_("URL of the schema"))
|
|
47
|
+
name = fields.StringField(_("Name of the schema"))
|
|
48
|
+
version = fields.StringField(_("Version of the schema"))
|
|
38
49
|
|
|
39
|
-
def validate(self, extra_validators
|
|
50
|
+
def validate(self, extra_validators=None):
|
|
40
51
|
validation = super().validate(extra_validators)
|
|
41
52
|
|
|
42
53
|
try:
|
|
43
|
-
Schema(url=self.url.data, name=self.name.data, version=self.version.data).clean(
|
|
54
|
+
Schema(url=self.url.data, name=self.name.data, version=self.version.data).clean(
|
|
55
|
+
check_schema_in_catalog=True
|
|
56
|
+
)
|
|
44
57
|
except FieldValidationError as err:
|
|
45
58
|
field = getattr(self, err.field)
|
|
46
59
|
field.errors.append(err.message)
|
|
@@ -51,32 +64,38 @@ class SchemaForm(ModelForm):
|
|
|
51
64
|
|
|
52
65
|
class BaseResourceForm(ModelForm):
|
|
53
66
|
title = fields.StringField(
|
|
54
|
-
_(
|
|
67
|
+
_("Title"), [validators.DataRequired(), validators.Length(max=TITLE_SIZE_LIMIT)]
|
|
68
|
+
)
|
|
55
69
|
description = fields.MarkdownField(
|
|
56
|
-
_(
|
|
70
|
+
_("Description"), [validators.Length(max=DESCRIPTION_SIZE_LIMIT)]
|
|
71
|
+
)
|
|
57
72
|
filetype = fields.RadioField(
|
|
58
|
-
_(
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
73
|
+
_("File type"),
|
|
74
|
+
[validators.DataRequired()],
|
|
75
|
+
choices=list(RESOURCE_FILETYPES.items()),
|
|
76
|
+
default="file",
|
|
77
|
+
description=_("Whether the resource is an uploaded file, " "a remote file or an API"),
|
|
78
|
+
)
|
|
62
79
|
type = fields.RadioField(
|
|
63
|
-
_(
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
_(
|
|
80
|
+
_("Type"),
|
|
81
|
+
[validators.DataRequired()],
|
|
82
|
+
choices=list(RESOURCE_TYPES.items()),
|
|
83
|
+
default="other",
|
|
84
|
+
description=_("Resource type (documentation, API...)"),
|
|
85
|
+
)
|
|
86
|
+
url = fields.UploadableURLField(_("URL"), [validators.DataRequired()], storage=resources)
|
|
68
87
|
format = fields.StringField(
|
|
69
|
-
_(
|
|
88
|
+
_("Format"),
|
|
70
89
|
filters=[normalize_format],
|
|
71
90
|
)
|
|
72
91
|
checksum = fields.FormField(ChecksumForm)
|
|
73
92
|
mime = fields.StringField(
|
|
74
|
-
_(
|
|
75
|
-
description=_(
|
|
76
|
-
|
|
93
|
+
_("Mime type"),
|
|
94
|
+
description=_("The mime type associated to the extension. " "(ex: text/plain)"),
|
|
95
|
+
)
|
|
77
96
|
filesize = fields.IntegerField(
|
|
78
|
-
_(
|
|
79
|
-
|
|
97
|
+
_("Size"), [validators.optional()], description=_("The file size in bytes")
|
|
98
|
+
)
|
|
80
99
|
extras = fields.ExtrasField()
|
|
81
100
|
schema = fields.FormField(SchemaForm)
|
|
82
101
|
|
|
@@ -90,67 +109,72 @@ class ResourceForm(BaseResourceForm):
|
|
|
90
109
|
class CommunityResourceForm(BaseResourceForm):
|
|
91
110
|
model_class = CommunityResource
|
|
92
111
|
|
|
93
|
-
dataset = fields.DatasetField(_(
|
|
112
|
+
dataset = fields.DatasetField(_("Related dataset"))
|
|
94
113
|
owner = fields.CurrentUserField()
|
|
95
|
-
organization = fields.PublishAsField(_(
|
|
114
|
+
organization = fields.PublishAsField(_("Publish as"))
|
|
96
115
|
|
|
97
116
|
|
|
98
117
|
def map_legacy_frequencies(form, field):
|
|
99
|
-
|
|
118
|
+
"""Map legacy frequencies to new ones"""
|
|
100
119
|
if field.data in LEGACY_FREQUENCIES:
|
|
101
120
|
field.data = LEGACY_FREQUENCIES[field.data]
|
|
102
121
|
|
|
103
122
|
|
|
104
123
|
def validate_contact_point(form, field):
|
|
105
|
-
|
|
124
|
+
"""Validates contact point with dataset's org or owner"""
|
|
106
125
|
from udata.models import ContactPoint
|
|
126
|
+
|
|
107
127
|
if field.data:
|
|
108
128
|
if form.organization.data:
|
|
109
129
|
contact_point = ContactPoint.objects(
|
|
110
|
-
id=field.data.id, organization=form.organization.data
|
|
130
|
+
id=field.data.id, organization=form.organization.data
|
|
131
|
+
).first()
|
|
111
132
|
elif form.owner.data:
|
|
112
|
-
contact_point = ContactPoint.objects(
|
|
113
|
-
id=field.data.id, owner=form.owner.data).first()
|
|
133
|
+
contact_point = ContactPoint.objects(id=field.data.id, owner=form.owner.data).first()
|
|
114
134
|
if not contact_point:
|
|
115
|
-
raise validators.ValidationError(
|
|
135
|
+
raise validators.ValidationError(
|
|
136
|
+
_("Wrong contact point id or contact point ownership mismatch")
|
|
137
|
+
)
|
|
116
138
|
|
|
117
139
|
|
|
118
140
|
class DatasetForm(ModelForm):
|
|
119
141
|
model_class = Dataset
|
|
120
142
|
|
|
121
143
|
title = fields.StringField(
|
|
122
|
-
_(
|
|
123
|
-
|
|
124
|
-
|
|
144
|
+
_("Title"), [validators.DataRequired(), validators.Length(max=TITLE_SIZE_LIMIT)]
|
|
145
|
+
)
|
|
146
|
+
acronym = fields.StringField(_("Acronym"), description=_("An optional acronym"))
|
|
125
147
|
description = fields.MarkdownField(
|
|
126
|
-
_(
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
148
|
+
_("Description"),
|
|
149
|
+
[validators.DataRequired(), validators.Length(max=DESCRIPTION_SIZE_LIMIT)],
|
|
150
|
+
description=_("The details about the dataset " "(collection process, specifics...)."),
|
|
151
|
+
)
|
|
152
|
+
license = fields.ModelSelectField(_("License"), model=License, allow_blank=True)
|
|
131
153
|
frequency = fields.SelectField(
|
|
132
|
-
_(
|
|
133
|
-
choices=list(UPDATE_FREQUENCIES.items()),
|
|
154
|
+
_("Update frequency"),
|
|
155
|
+
choices=list(UPDATE_FREQUENCIES.items()),
|
|
156
|
+
default=DEFAULT_FREQUENCY,
|
|
134
157
|
validators=[validators.optional()],
|
|
135
158
|
preprocessors=[map_legacy_frequencies],
|
|
136
|
-
description=_(
|
|
137
|
-
|
|
159
|
+
description=_("The frequency at which data are updated."),
|
|
160
|
+
)
|
|
161
|
+
frequency_date = fields.DateTimeField(_("Expected frequency date"))
|
|
138
162
|
deleted = fields.DateTimeField()
|
|
139
163
|
archived = fields.DateTimeField()
|
|
140
164
|
temporal_coverage = fields.DateRangeField(
|
|
141
|
-
_(
|
|
142
|
-
|
|
165
|
+
_("Temporal coverage"), description=_("The period covered by the data")
|
|
166
|
+
)
|
|
143
167
|
spatial = SpatialCoverageField(
|
|
144
|
-
_(
|
|
145
|
-
|
|
146
|
-
tags = fields.TagField(_(
|
|
168
|
+
_("Spatial coverage"), description=_("The geographical area covered by the data.")
|
|
169
|
+
)
|
|
170
|
+
tags = fields.TagField(_("Tags"), description=_("Some taxonomy keywords"))
|
|
147
171
|
private = fields.BooleanField(
|
|
148
|
-
_(
|
|
149
|
-
description=_(
|
|
150
|
-
|
|
172
|
+
_("Private"),
|
|
173
|
+
description=_("Restrict the dataset visibility to you or " "your organization only."),
|
|
174
|
+
)
|
|
151
175
|
|
|
152
176
|
owner = fields.CurrentUserField()
|
|
153
|
-
organization = fields.PublishAsField(_(
|
|
177
|
+
organization = fields.PublishAsField(_("Publish as"))
|
|
154
178
|
extras = fields.ExtrasField()
|
|
155
179
|
resources = fields.NestedModelList(ResourceForm)
|
|
156
180
|
contact_point = fields.ContactPointField(validators=[validate_contact_point])
|