udata 10.1.3.dev34195__py2.py3-none-any.whl → 10.1.3.dev34219__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.
- udata/core/dataset/api.py +18 -3
- udata/core/dataset/forms.py +8 -4
- udata/core/dataset/models.py +6 -0
- udata/static/chunks/{10.471164b2a9fe15614797.js → 10.8ca60413647062717b1e.js} +3 -3
- udata/static/chunks/{10.471164b2a9fe15614797.js.map → 10.8ca60413647062717b1e.js.map} +1 -1
- udata/static/chunks/{11.55ab79044cda0271b595.js → 11.b6f741fcc366abfad9c4.js} +3 -3
- udata/static/chunks/{11.55ab79044cda0271b595.js.map → 11.b6f741fcc366abfad9c4.js.map} +1 -1
- udata/static/chunks/{13.f29411b06be1883356a3.js → 13.2d06442dd9a05d9777b5.js} +2 -2
- udata/static/chunks/{13.f29411b06be1883356a3.js.map → 13.2d06442dd9a05d9777b5.js.map} +1 -1
- udata/static/chunks/{17.3bd0340930d4a314ce9c.js → 17.e8e4caaad5cb0cc0bacc.js} +2 -2
- udata/static/chunks/{17.3bd0340930d4a314ce9c.js.map → 17.e8e4caaad5cb0cc0bacc.js.map} +1 -1
- udata/static/chunks/{19.3e0e8651d948e04b8cf2.js → 19.f03a102365af4315f9db.js} +3 -3
- udata/static/chunks/{19.3e0e8651d948e04b8cf2.js.map → 19.f03a102365af4315f9db.js.map} +1 -1
- udata/static/chunks/{8.494b003a94383b142c18.js → 8.778091d55cd8ea39af6b.js} +2 -2
- udata/static/chunks/{8.494b003a94383b142c18.js.map → 8.778091d55cd8ea39af6b.js.map} +1 -1
- udata/static/chunks/{9.07515e5187f475bce828.js → 9.033d7e190ca9e226a5d0.js} +3 -3
- udata/static/chunks/{9.07515e5187f475bce828.js.map → 9.033d7e190ca9e226a5d0.js.map} +1 -1
- udata/static/common.js +1 -1
- udata/static/common.js.map +1 -1
- udata/tests/api/test_datasets_api.py +58 -0
- udata/tests/dataset/test_dataset_model.py +14 -0
- {udata-10.1.3.dev34195.dist-info → udata-10.1.3.dev34219.dist-info}/METADATA +3 -1
- {udata-10.1.3.dev34195.dist-info → udata-10.1.3.dev34219.dist-info}/RECORD +27 -27
- {udata-10.1.3.dev34195.dist-info → udata-10.1.3.dev34219.dist-info}/LICENSE +0 -0
- {udata-10.1.3.dev34195.dist-info → udata-10.1.3.dev34219.dist-info}/WHEEL +0 -0
- {udata-10.1.3.dev34195.dist-info → udata-10.1.3.dev34219.dist-info}/entry_points.txt +0 -0
- {udata-10.1.3.dev34195.dist-info → udata-10.1.3.dev34219.dist-info}/top_level.txt +0 -0
udata/core/dataset/api.py
CHANGED
|
@@ -62,7 +62,12 @@ from .exceptions import (
|
|
|
62
62
|
SchemasCacheUnavailableException,
|
|
63
63
|
SchemasCatalogNotFoundException,
|
|
64
64
|
)
|
|
65
|
-
from .forms import
|
|
65
|
+
from .forms import (
|
|
66
|
+
CommunityResourceForm,
|
|
67
|
+
DatasetForm,
|
|
68
|
+
ResourceFormWithoutId,
|
|
69
|
+
ResourcesListForm,
|
|
70
|
+
)
|
|
66
71
|
from .models import (
|
|
67
72
|
Checksum,
|
|
68
73
|
CommunityResource,
|
|
@@ -379,8 +384,9 @@ class ResourcesAPI(API):
|
|
|
379
384
|
def post(self, dataset):
|
|
380
385
|
"""Create a new resource for a given dataset"""
|
|
381
386
|
ResourceEditPermission(dataset).test()
|
|
382
|
-
form = api.validate(
|
|
387
|
+
form = api.validate(ResourceFormWithoutId)
|
|
383
388
|
resource = Resource()
|
|
389
|
+
|
|
384
390
|
if form._fields.get("filetype").data != "remote":
|
|
385
391
|
api.abort(400, "This endpoint only supports remote resources")
|
|
386
392
|
form.populate_obj(resource)
|
|
@@ -545,10 +551,19 @@ class ResourceAPI(ResourceMixin, API):
|
|
|
545
551
|
"""Update a given resource on a given dataset"""
|
|
546
552
|
ResourceEditPermission(dataset).test()
|
|
547
553
|
resource = self.get_resource_or_404(dataset, rid)
|
|
548
|
-
form = api.validate(
|
|
554
|
+
form = api.validate(ResourceFormWithoutId, resource)
|
|
555
|
+
|
|
556
|
+
# ensure filetype is not modified after creation
|
|
557
|
+
if (
|
|
558
|
+
form._fields.get("filetype").data
|
|
559
|
+
and form._fields.get("filetype").data != resource.filetype
|
|
560
|
+
):
|
|
561
|
+
abort(400, "Cannot modify filetype after creation")
|
|
562
|
+
|
|
549
563
|
# ensure API client does not override url on self-hosted resources
|
|
550
564
|
if resource.filetype == "file":
|
|
551
565
|
form._fields.get("url").data = resource.url
|
|
566
|
+
|
|
552
567
|
# populate_obj populates existing resource object with the content of the form.
|
|
553
568
|
# update_resource saves the updated resource dict to the database
|
|
554
569
|
# the additional dataset.save is required as we update the last_modified date.
|
udata/core/dataset/forms.py
CHANGED
|
@@ -72,7 +72,7 @@ class BaseResourceForm(ModelForm):
|
|
|
72
72
|
[validators.DataRequired()],
|
|
73
73
|
choices=list(RESOURCE_FILETYPES.items()),
|
|
74
74
|
default="file",
|
|
75
|
-
description=_("Whether the resource is an uploaded file,
|
|
75
|
+
description=_("Whether the resource is an uploaded file, a remote file or an API"),
|
|
76
76
|
)
|
|
77
77
|
type = fields.RadioField(
|
|
78
78
|
_("Type"),
|
|
@@ -89,7 +89,7 @@ class BaseResourceForm(ModelForm):
|
|
|
89
89
|
checksum = fields.FormField(ChecksumForm)
|
|
90
90
|
mime = fields.StringField(
|
|
91
91
|
_("Mime type"),
|
|
92
|
-
description=_("The mime type associated to the extension.
|
|
92
|
+
description=_("The mime type associated to the extension. (ex: text/plain)"),
|
|
93
93
|
)
|
|
94
94
|
filesize = fields.IntegerField(
|
|
95
95
|
_("Size"), [validators.optional()], description=_("The file size in bytes")
|
|
@@ -104,6 +104,10 @@ class ResourceForm(BaseResourceForm):
|
|
|
104
104
|
id = fields.UUIDField()
|
|
105
105
|
|
|
106
106
|
|
|
107
|
+
class ResourceFormWithoutId(BaseResourceForm):
|
|
108
|
+
model_class = Resource
|
|
109
|
+
|
|
110
|
+
|
|
107
111
|
class CommunityResourceForm(BaseResourceForm):
|
|
108
112
|
model_class = CommunityResource
|
|
109
113
|
|
|
@@ -145,7 +149,7 @@ class DatasetForm(ModelForm):
|
|
|
145
149
|
description = fields.MarkdownField(
|
|
146
150
|
_("Description"),
|
|
147
151
|
[validators.DataRequired(), validators.Length(max=DESCRIPTION_SIZE_LIMIT)],
|
|
148
|
-
description=_("The details about the dataset
|
|
152
|
+
description=_("The details about the dataset (collection process, specifics...)."),
|
|
149
153
|
)
|
|
150
154
|
license = fields.ModelSelectField(_("License"), model=License, allow_blank=True)
|
|
151
155
|
frequency = fields.SelectField(
|
|
@@ -168,7 +172,7 @@ class DatasetForm(ModelForm):
|
|
|
168
172
|
tags = fields.TagField(_("Tags"), description=_("Some taxonomy keywords"))
|
|
169
173
|
private = fields.BooleanField(
|
|
170
174
|
_("Private"),
|
|
171
|
-
description=_("Restrict the dataset visibility to you or
|
|
175
|
+
description=_("Restrict the dataset visibility to you or your organization only."),
|
|
172
176
|
)
|
|
173
177
|
|
|
174
178
|
owner = fields.CurrentUserField()
|
udata/core/dataset/models.py
CHANGED
|
@@ -638,6 +638,9 @@ class Dataset(WithMetrics, DatasetBadgeMixin, Owned, db.Document):
|
|
|
638
638
|
if self.frequency in LEGACY_FREQUENCIES:
|
|
639
639
|
self.frequency = LEGACY_FREQUENCIES[self.frequency]
|
|
640
640
|
|
|
641
|
+
if len(set(res.id for res in self.resources)) != len(self.resources):
|
|
642
|
+
raise MongoEngineValidationError(f"Duplicate resource ID in dataset #{self.id}.")
|
|
643
|
+
|
|
641
644
|
for key, value in self.extras.items():
|
|
642
645
|
if not key.startswith("custom:"):
|
|
643
646
|
continue
|
|
@@ -897,6 +900,9 @@ class Dataset(WithMetrics, DatasetBadgeMixin, Owned, db.Document):
|
|
|
897
900
|
def add_resource(self, resource):
|
|
898
901
|
"""Perform an atomic prepend for a new resource"""
|
|
899
902
|
resource.validate()
|
|
903
|
+
if resource.id in [r.id for r in self.resources]:
|
|
904
|
+
raise MongoEngineValidationError("Cannot add resource with already existing ID")
|
|
905
|
+
|
|
900
906
|
self.update(
|
|
901
907
|
__raw__={"$push": {"resources": {"$each": [resource.to_mongo()], "$position": 0}}}
|
|
902
908
|
)
|