udata 7.0.8.dev28841__py2.py3-none-any.whl → 9.0.1.dev29390__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/__init__.py +1 -1
- udata/api/__init__.py +6 -4
- udata/api/oauth2.py +2 -1
- udata/api_fields.py +254 -0
- udata/commands/purge.py +8 -2
- udata/core/badges/models.py +2 -1
- udata/core/dataservices/__init__.py +0 -0
- udata/core/dataservices/api.py +92 -0
- udata/core/dataservices/models.py +142 -0
- udata/core/dataservices/permissions.py +7 -0
- udata/core/dataservices/tasks.py +25 -0
- udata/core/dataset/apiv2.py +2 -0
- udata/core/dataset/csv.py +8 -1
- udata/core/dataset/models.py +1 -0
- udata/core/dataset/rdf.py +77 -15
- udata/core/metrics/commands.py +18 -3
- udata/core/metrics/models.py +2 -3
- udata/core/organization/api_fields.py +28 -3
- udata/core/organization/csv.py +5 -3
- udata/core/organization/models.py +3 -1
- udata/core/owned.py +39 -2
- udata/core/reuse/csv.py +3 -0
- udata/core/site/api.py +4 -1
- udata/core/spatial/api.py +5 -10
- udata/core/spatial/models.py +7 -2
- udata/core/spatial/tasks.py +7 -0
- udata/core/spatial/tests/test_api.py +26 -0
- udata/core/user/api.py +11 -7
- udata/core/user/models.py +13 -2
- udata/harvest/backends/base.py +93 -103
- udata/harvest/backends/dcat.py +65 -90
- udata/harvest/tasks.py +3 -13
- udata/harvest/tests/dcat/bnodes.xml +10 -1
- udata/harvest/tests/dcat/catalog.xml +1 -0
- udata/harvest/tests/factories.py +13 -6
- udata/harvest/tests/test_actions.py +2 -2
- udata/harvest/tests/test_base_backend.py +9 -5
- udata/harvest/tests/test_dcat_backend.py +17 -1
- udata/rdf.py +4 -0
- udata/routing.py +6 -0
- udata/settings.py +4 -1
- udata/static/admin.css +2 -2
- udata/static/admin.css.map +1 -1
- udata/static/chunks/{0.6f1698738c9b0618b673.js → 0.93c3ae13b5b94753ee80.js} +3 -3
- udata/static/chunks/0.93c3ae13b5b94753ee80.js.map +1 -0
- udata/static/chunks/{14.f4037a917d5364cb564b.js → 14.e64890872b31c55fcdf7.js} +2 -2
- udata/static/chunks/14.e64890872b31c55fcdf7.js.map +1 -0
- udata/static/chunks/{2.7c89fae92899be371ed3.js → 2.614b3e73b072982fd9b1.js} +2 -2
- udata/static/chunks/2.614b3e73b072982fd9b1.js.map +1 -0
- udata/static/chunks/{5.3dc97ea195d251881552.js → 5.48417db6b33328fa9d6a.js} +2 -2
- udata/static/chunks/5.48417db6b33328fa9d6a.js.map +1 -0
- udata/static/common.js +1 -1
- udata/static/common.js.map +1 -1
- udata/tasks.py +1 -0
- udata/tests/api/__init__.py +3 -0
- udata/tests/api/test_dataservices_api.py +236 -0
- udata/tests/api/test_organizations_api.py +78 -5
- udata/tests/api/test_user_api.py +47 -13
- udata/tests/dataservice/test_dataservice_tasks.py +46 -0
- udata/tests/dataset/test_dataset_rdf.py +17 -2
- udata/tests/plugin.py +5 -0
- udata/tests/site/test_site_rdf.py +16 -0
- {udata-7.0.8.dev28841.dist-info → udata-9.0.1.dev29390.dist-info}/METADATA +27 -1
- {udata-7.0.8.dev28841.dist-info → udata-9.0.1.dev29390.dist-info}/RECORD +68 -60
- udata/core/metrics/api.py +0 -10
- udata/static/chunks/0.6f1698738c9b0618b673.js.map +0 -1
- udata/static/chunks/14.f4037a917d5364cb564b.js.map +0 -1
- udata/static/chunks/2.7c89fae92899be371ed3.js.map +0 -1
- udata/static/chunks/5.3dc97ea195d251881552.js.map +0 -1
- {udata-7.0.8.dev28841.dist-info → udata-9.0.1.dev29390.dist-info}/LICENSE +0 -0
- {udata-7.0.8.dev28841.dist-info → udata-9.0.1.dev29390.dist-info}/WHEEL +0 -0
- {udata-7.0.8.dev28841.dist-info → udata-9.0.1.dev29390.dist-info}/entry_points.txt +0 -0
- {udata-7.0.8.dev28841.dist-info → udata-9.0.1.dev29390.dist-info}/top_level.txt +0 -0
udata/harvest/tests/factories.py
CHANGED
|
@@ -6,9 +6,10 @@ from flask.signals import Namespace
|
|
|
6
6
|
|
|
7
7
|
from udata.factories import ModelFactory
|
|
8
8
|
from udata.core.dataset.factories import DatasetFactory
|
|
9
|
+
from udata.core.dataset.models import Dataset
|
|
9
10
|
|
|
10
11
|
from .. import backends
|
|
11
|
-
from ..models import HarvestSource, HarvestJob
|
|
12
|
+
from ..models import HarvestItem, HarvestSource, HarvestJob
|
|
12
13
|
|
|
13
14
|
|
|
14
15
|
def dtfactory(start, end):
|
|
@@ -55,14 +56,20 @@ class FactoryBackend(backends.BaseBackend):
|
|
|
55
56
|
backends.HarvestFeature('toggled', 'Toggled', 'A togglable', True),
|
|
56
57
|
)
|
|
57
58
|
|
|
58
|
-
def
|
|
59
|
+
def inner_harvest(self):
|
|
59
60
|
mock_initialize.send(self)
|
|
60
61
|
for i in range(self.config.get('count', DEFAULT_COUNT)):
|
|
61
|
-
self.
|
|
62
|
+
self.process_dataset(str(i))
|
|
63
|
+
if self.is_done():
|
|
64
|
+
return
|
|
62
65
|
|
|
63
|
-
def
|
|
64
|
-
mock_process.send(self, item=item)
|
|
65
|
-
|
|
66
|
+
def inner_process_dataset(self, item: HarvestItem):
|
|
67
|
+
mock_process.send(self, item=item.remote_id)
|
|
68
|
+
|
|
69
|
+
dataset = self.get_dataset(item.remote_id)
|
|
70
|
+
dataset.title = f'dataset-{item.remote_id}'
|
|
71
|
+
|
|
72
|
+
return dataset
|
|
66
73
|
|
|
67
74
|
|
|
68
75
|
class MockBackendsMixin(object):
|
|
@@ -580,7 +580,7 @@ class ExecutionTestMixin(MockBackendsMixin):
|
|
|
580
580
|
|
|
581
581
|
def test_error_on_item(self):
|
|
582
582
|
def process(self, item):
|
|
583
|
-
if item
|
|
583
|
+
if item == '1':
|
|
584
584
|
raise ValueError('test')
|
|
585
585
|
|
|
586
586
|
source = HarvestSourceFactory(backend='factory')
|
|
@@ -723,7 +723,7 @@ class HarvestPreviewTest(MockBackendsMixin):
|
|
|
723
723
|
|
|
724
724
|
def test_preview_with_error_on_item(self):
|
|
725
725
|
def process(self, item):
|
|
726
|
-
if item
|
|
726
|
+
if item == '1':
|
|
727
727
|
raise ValueError('test')
|
|
728
728
|
|
|
729
729
|
source = HarvestSourceFactory(backend='factory')
|
|
@@ -5,6 +5,7 @@ from urllib.parse import urlparse
|
|
|
5
5
|
from dateutil.parser import parse
|
|
6
6
|
from voluptuous import Schema
|
|
7
7
|
|
|
8
|
+
from udata.harvest.models import HarvestItem
|
|
8
9
|
from udata.utils import faker
|
|
9
10
|
from udata.core.dataset import tasks
|
|
10
11
|
from udata.core.dataset.factories import DatasetFactory
|
|
@@ -31,12 +32,16 @@ class FakeBackend(BaseBackend):
|
|
|
31
32
|
HarvestFeature('enabled', 'A test feature enabled by default', default=True),
|
|
32
33
|
)
|
|
33
34
|
|
|
34
|
-
def
|
|
35
|
+
def inner_harvest(self):
|
|
35
36
|
for i in range(self.source.config.get('nb_datasets', 3)):
|
|
36
|
-
|
|
37
|
+
remote_id = f'fake-{i}'
|
|
38
|
+
self.process_dataset(remote_id)
|
|
39
|
+
if self.is_done():
|
|
40
|
+
return
|
|
37
41
|
|
|
38
|
-
def
|
|
42
|
+
def inner_process_dataset(self, item: HarvestItem):
|
|
39
43
|
dataset = self.get_dataset(item.remote_id)
|
|
44
|
+
|
|
40
45
|
for key, value in DatasetFactory.as_dict(visible=True).items():
|
|
41
46
|
setattr(dataset, key, value)
|
|
42
47
|
if self.source.config.get('last_modified'):
|
|
@@ -219,8 +224,7 @@ class BaseBackendTest:
|
|
|
219
224
|
assert 'archived_at' not in dataset_no_arch.harvest
|
|
220
225
|
|
|
221
226
|
# test unarchive: archive manually then relaunch harvest
|
|
222
|
-
|
|
223
|
-
dataset = Dataset.objects.get(**q)
|
|
227
|
+
dataset = Dataset.objects.get(**{'harvest__remote_id': 'fake-1'})
|
|
224
228
|
dataset.archived = datetime.utcnow()
|
|
225
229
|
dataset.harvest.archived = 'not-on-remote'
|
|
226
230
|
dataset.harvest.archived_at = datetime.utcnow()
|
|
@@ -240,6 +240,19 @@ class DcatBackendTest:
|
|
|
240
240
|
actions.purge_jobs()
|
|
241
241
|
assert get_from_json(current_app.config.get('HARVEST_GRAPHS_S3_BUCKET'), job.data['filename']) is None
|
|
242
242
|
|
|
243
|
+
@pytest.mark.options(SCHEMA_CATALOG_URL='https://example.com/schemas', HARVEST_MAX_ITEMS=2)
|
|
244
|
+
def test_harvest_max_items(self, rmock):
|
|
245
|
+
rmock.get('https://example.com/schemas', json=ResourceSchemaMockData.get_mock_data())
|
|
246
|
+
|
|
247
|
+
filename = 'bnodes.xml'
|
|
248
|
+
url = mock_dcat(rmock, filename)
|
|
249
|
+
org = OrganizationFactory()
|
|
250
|
+
source = HarvestSourceFactory(backend='dcat', url=url, organization=org)
|
|
251
|
+
|
|
252
|
+
actions.run(source.slug)
|
|
253
|
+
|
|
254
|
+
assert Dataset.objects.count() == 2
|
|
255
|
+
assert HarvestJob.objects.first().status == 'done'
|
|
243
256
|
|
|
244
257
|
@pytest.mark.options(SCHEMA_CATALOG_URL='https://example.com/schemas')
|
|
245
258
|
def test_harvest_spatial(self, rmock):
|
|
@@ -255,7 +268,7 @@ class DcatBackendTest:
|
|
|
255
268
|
datasets = {d.harvest.dct_identifier: d for d in Dataset.objects}
|
|
256
269
|
|
|
257
270
|
assert datasets['1'].spatial == None
|
|
258
|
-
assert datasets['2'].spatial.geom == {'type': 'MultiPolygon', 'coordinates': [[[[4
|
|
271
|
+
assert datasets['2'].spatial.geom == {'type': 'MultiPolygon', 'coordinates': [[[[-6,51],[10,51],[10,40],[-6,40],[-6,51]]], [[[4, 45], [4, 46], [4, 46], [4, 45], [4, 45]]], [[[159, -25.], [159, -11], [212, -11], [212, -25.], [159, -25.]]]]}
|
|
259
272
|
assert datasets['3'].spatial == None
|
|
260
273
|
|
|
261
274
|
@pytest.mark.options(SCHEMA_CATALOG_URL='https://example.com/schemas')
|
|
@@ -440,6 +453,9 @@ class DcatBackendTest:
|
|
|
440
453
|
assert dataset.extras["harvest"]["dct:accessRights"] == "http://inspire.ec.europa.eu/metadata-codelist/LimitationsOnPublicAccess/INSPIRE_Directive_Article13_1e"
|
|
441
454
|
assert dataset.extras["harvest"]["dct:provenance"] == ["Description de la provenance des données"]
|
|
442
455
|
|
|
456
|
+
assert 'observation-de-la-terre-et-environnement' in dataset.tags
|
|
457
|
+
assert 'hvd' in dataset.tags
|
|
458
|
+
|
|
443
459
|
dataset = Dataset.objects.get(harvest__dct_identifier='1')
|
|
444
460
|
# test html abstract description support
|
|
445
461
|
assert dataset.description == '# h1 title\n\n## h2 title\n\n **and bold text**'
|
udata/rdf.py
CHANGED
|
@@ -21,6 +21,7 @@ log = logging.getLogger(__name__)
|
|
|
21
21
|
# Extra Namespaces
|
|
22
22
|
ADMS = Namespace('http://www.w3.org/ns/adms#')
|
|
23
23
|
DCAT = Namespace('http://www.w3.org/ns/dcat#')
|
|
24
|
+
DCATAP = Namespace('http://data.europa.eu/r5r/')
|
|
24
25
|
HYDRA = Namespace('http://www.w3.org/ns/hydra/core#')
|
|
25
26
|
SCHEMA = Namespace('http://schema.org/')
|
|
26
27
|
SCV = Namespace('http://purl.org/NET/scovo#')
|
|
@@ -35,6 +36,7 @@ VCARD = Namespace('http://www.w3.org/2006/vcard/ns#')
|
|
|
35
36
|
|
|
36
37
|
namespace_manager = NamespaceManager(Graph())
|
|
37
38
|
namespace_manager.bind('dcat', DCAT)
|
|
39
|
+
namespace_manager.bind('dcatap', DCATAP)
|
|
38
40
|
namespace_manager.bind('dct', DCT)
|
|
39
41
|
namespace_manager.bind('foaf', FOAF)
|
|
40
42
|
namespace_manager.bind('foaf', FOAF)
|
|
@@ -98,6 +100,8 @@ RDF_EXTENSIONS = {
|
|
|
98
100
|
# Includes control characters, unicode surrogate characters and unicode end-of-plane non-characters
|
|
99
101
|
ILLEGAL_XML_CHARS = '[\x00-\x08\x0b\x0c\x0e-\x1F\uD800-\uDFFF\uFFFE\uFFFF]'
|
|
100
102
|
|
|
103
|
+
HVD_LEGISLATION = 'http://data.europa.eu/eli/reg_impl/2023/138/oj'
|
|
104
|
+
|
|
101
105
|
|
|
102
106
|
def guess_format(string):
|
|
103
107
|
'''Guess format given an extension or a mime-type'''
|
udata/routing.py
CHANGED
|
@@ -10,6 +10,7 @@ from werkzeug.urls import url_quote
|
|
|
10
10
|
from udata import models
|
|
11
11
|
from udata.mongo import db
|
|
12
12
|
from udata.core.spatial.models import GeoZone
|
|
13
|
+
from udata.core.dataservices.models import Dataservice
|
|
13
14
|
from udata.i18n import ISO_639_1_CODES
|
|
14
15
|
|
|
15
16
|
|
|
@@ -121,6 +122,10 @@ class DatasetConverter(ModelConverter):
|
|
|
121
122
|
model = models.Dataset
|
|
122
123
|
|
|
123
124
|
|
|
125
|
+
class DataserviceConverter(ModelConverter):
|
|
126
|
+
model = Dataservice
|
|
127
|
+
|
|
128
|
+
|
|
124
129
|
class CommunityResourceConverter(ModelConverter):
|
|
125
130
|
model = models.CommunityResource
|
|
126
131
|
|
|
@@ -222,6 +227,7 @@ def init_app(app):
|
|
|
222
227
|
app.url_map.converters['pathlist'] = PathListConverter
|
|
223
228
|
app.url_map.converters['uuid'] = UUIDConverter
|
|
224
229
|
app.url_map.converters['dataset'] = DatasetConverter
|
|
230
|
+
app.url_map.converters['dataservice'] = DataserviceConverter
|
|
225
231
|
app.url_map.converters['crid'] = CommunityResourceConverter
|
|
226
232
|
app.url_map.converters['org'] = OrganizationConverter
|
|
227
233
|
app.url_map.converters['reuse'] = ReuseConverter
|
udata/settings.py
CHANGED
|
@@ -269,7 +269,10 @@ class Defaults(object):
|
|
|
269
269
|
# S3 connection details
|
|
270
270
|
S3_URL = None
|
|
271
271
|
S3_ACCESS_KEY_ID = None
|
|
272
|
-
S3_SECRET_ACCESS_KEY = None
|
|
272
|
+
S3_SECRET_ACCESS_KEY = None
|
|
273
|
+
|
|
274
|
+
# Specific support for hvd (map HVD categories URIs to keywords)
|
|
275
|
+
HVD_SUPPORT = True
|
|
273
276
|
|
|
274
277
|
ACTIVATE_TERRITORIES = False
|
|
275
278
|
# The order is important to compute parents/children, smaller first.
|