udata 6.2.1.dev26916__py2.py3-none-any.whl → 6.2.1.dev26928__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.

Files changed (27) hide show
  1. udata/core/dataset/apiv2.py +4 -4
  2. udata/core/dataset/rdf.py +13 -4
  3. udata/harvest/tests/dcat/catalog.xml +5 -0
  4. udata/harvest/tests/test_dcat_backend.py +12 -3
  5. udata/static/chunks/{11.c0ccea08914b6b41568e.js → 11.a23c110811a9ac943478.js} +3 -3
  6. udata/static/chunks/{11.c0ccea08914b6b41568e.js.map → 11.a23c110811a9ac943478.js.map} +1 -1
  7. udata/static/chunks/{13.526a25163ababaa44409.js → 13.0889e093f8664e38568c.js} +2 -2
  8. udata/static/chunks/{13.526a25163ababaa44409.js.map → 13.0889e093f8664e38568c.js.map} +1 -1
  9. udata/static/chunks/{16.7901839b4227881947f6.js → 16.f41599478d3e97ad9a30.js} +2 -2
  10. udata/static/chunks/{16.7901839b4227881947f6.js.map → 16.f41599478d3e97ad9a30.js.map} +1 -1
  11. udata/static/chunks/{19.471d5a2a08eef6e5338a.js → 19.2b534a26af8b17e9170b.js} +3 -3
  12. udata/static/chunks/{19.471d5a2a08eef6e5338a.js.map → 19.2b534a26af8b17e9170b.js.map} +1 -1
  13. udata/static/chunks/{5.6b73b3d83a8ff187132d.js → 5.da4db938a6ecf99fccbc.js} +3 -3
  14. udata/static/chunks/{5.6b73b3d83a8ff187132d.js.map → 5.da4db938a6ecf99fccbc.js.map} +1 -1
  15. udata/static/chunks/{6.e56975229e6065f68d2a.js → 6.16bb24fb8240f2746488.js} +3 -3
  16. udata/static/chunks/{6.e56975229e6065f68d2a.js.map → 6.16bb24fb8240f2746488.js.map} +1 -1
  17. udata/static/chunks/{9.534426728626f11f4571.js → 9.3e752966ff14e47e11f2.js} +2 -2
  18. udata/static/chunks/{9.534426728626f11f4571.js.map → 9.3e752966ff14e47e11f2.js.map} +1 -1
  19. udata/static/common.js +1 -1
  20. udata/static/common.js.map +1 -1
  21. udata/tests/apiv2/test_datasets.py +22 -7
  22. {udata-6.2.1.dev26916.dist-info → udata-6.2.1.dev26928.dist-info}/METADATA +3 -1
  23. {udata-6.2.1.dev26916.dist-info → udata-6.2.1.dev26928.dist-info}/RECORD +27 -27
  24. {udata-6.2.1.dev26916.dist-info → udata-6.2.1.dev26928.dist-info}/LICENSE +0 -0
  25. {udata-6.2.1.dev26916.dist-info → udata-6.2.1.dev26928.dist-info}/WHEEL +0 -0
  26. {udata-6.2.1.dev26916.dist-info → udata-6.2.1.dev26928.dist-info}/entry_points.txt +0 -0
  27. {udata-6.2.1.dev26916.dist-info → udata-6.2.1.dev26928.dist-info}/top_level.txt +0 -0
@@ -232,7 +232,7 @@ class DatasetExtrasAPI(API):
232
232
  data.pop(key)
233
233
  # then update the extras with the remaining payload
234
234
  dataset.extras.update(data)
235
- dataset.save()
235
+ dataset.save(signal_kwargs={'ignores': ['post_save']})
236
236
  return dataset.extras
237
237
 
238
238
  @apiv2.secure
@@ -250,7 +250,7 @@ class DatasetExtrasAPI(API):
250
250
  del dataset.extras[key]
251
251
  except KeyError:
252
252
  apiv2.abort(404, 'Key not found in existing extras')
253
- dataset.save()
253
+ dataset.save(signal_kwargs={'ignores': ['post_save']})
254
254
  return dataset.extras, 204
255
255
 
256
256
 
@@ -348,7 +348,7 @@ class ResourceExtrasAPI(ResourceMixin, API):
348
348
  data.pop(key)
349
349
  # then update the extras with the remaining payload
350
350
  resource.extras.update(data)
351
- resource.save()
351
+ resource.save(signal_kwargs={'ignores': ['post_save']})
352
352
  return resource.extras
353
353
 
354
354
  @apiv2.secure
@@ -367,5 +367,5 @@ class ResourceExtrasAPI(ResourceMixin, API):
367
367
  del resource.extras[key]
368
368
  except KeyError:
369
369
  apiv2.abort(404, 'Key not found in existing extras')
370
- resource.save()
370
+ resource.save(signal_kwargs={'ignores': ['post_save']})
371
371
  return resource.extras, 204
udata/core/dataset/rdf.py CHANGED
@@ -389,6 +389,7 @@ def remote_url_from_rdf(rdf):
389
389
  except uris.ValidationError:
390
390
  pass
391
391
 
392
+
392
393
  def theme_labels_from_rdf(rdf):
393
394
  for theme in rdf.objects(DCAT.theme):
394
395
  if isinstance(theme, RdfResource):
@@ -399,7 +400,7 @@ def theme_labels_from_rdf(rdf):
399
400
  yield label
400
401
 
401
402
 
402
- def resource_from_rdf(graph_or_distrib, dataset=None):
403
+ def resource_from_rdf(graph_or_distrib, dataset=None, is_additionnal=False):
403
404
  '''
404
405
  Map a Resource domain model to a DCAT/RDF graph
405
406
  '''
@@ -410,9 +411,12 @@ def resource_from_rdf(graph_or_distrib, dataset=None):
410
411
  object=DCAT.Distribution)
411
412
  distrib = graph_or_distrib.resource(node)
412
413
 
413
- download_url = url_from_rdf(distrib, DCAT.downloadURL)
414
- access_url = url_from_rdf(distrib, DCAT.accessURL)
415
- url = safe_unicode(download_url or access_url)
414
+ if not is_additionnal:
415
+ download_url = url_from_rdf(distrib, DCAT.downloadURL)
416
+ access_url = url_from_rdf(distrib, DCAT.accessURL)
417
+ url = safe_unicode(download_url or access_url)
418
+ else:
419
+ url = distrib.identifier.toPython() if isinstance(distrib.identifier, URIRef) else None
416
420
  # we shouldn't create resources without URLs
417
421
  if not url:
418
422
  log.warning(f'Resource without url: {distrib}')
@@ -439,6 +443,8 @@ def resource_from_rdf(graph_or_distrib, dataset=None):
439
443
  resource.checksum = Checksum()
440
444
  resource.checksum.value = rdf_value(checksum, SPDX.checksumValue)
441
445
  resource.checksum.type = algorithm
446
+ if is_additionnal:
447
+ resource.type = 'other'
442
448
 
443
449
  identifier = rdf_value(distrib, DCT.identifier)
444
450
  uri = distrib.identifier.toPython() if isinstance(distrib.identifier, URIRef) else None
@@ -494,6 +500,9 @@ def dataset_from_rdf(graph, dataset=None, node=None):
494
500
  elif isinstance(value, RdfResource):
495
501
  licenses.add(value.identifier.toPython())
496
502
 
503
+ for additionnal in d.objects(DCT.hasPart):
504
+ resource_from_rdf(additionnal, dataset, is_additionnal=True)
505
+
497
506
  default_license = dataset.license or License.default()
498
507
  dataset_license = rdf_value(d, DCT.license)
499
508
  dataset.license = License.guess(dataset_license, *licenses, default=default_license)
@@ -61,6 +61,7 @@
61
61
  <dcat:distribution rdf:resource="http://data.test.org/datasets/1/resources/1"/>
62
62
  <dcterms:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#dateTime">2016-12-14T18:59:02.737480</dcterms:issued>
63
63
  <dcterms:identifier>1</dcterms:identifier>
64
+ <dcterms:hasPart rdf:resource="http://data.test.org/datasets/1/resources/3"/>
64
65
  </dcat:Dataset>
65
66
  </dcat:dataset>
66
67
  <dcat:dataset>
@@ -134,6 +135,10 @@
134
135
  <dcterms:description>A JSON resource</dcterms:description>
135
136
  <dcat:accessURL>http://data.test.org/datasets/3/resources/1/file.json</dcat:accessURL>
136
137
  </dcat:Distribution>
138
+ <foaf:Document rdf:about="http://data.test.org/datasets/1/resources/3">
139
+ <dcterms:title>Resource 1-3</dcterms:title>
140
+ <dcterms:format>JSON</dcterms:format>
141
+ </foaf:Document>
137
142
  <dcterms:Location rdf:about="http://wuEurope.com/"/>
138
143
  <foaf:Organization rdf:about="http://data.test.org/organizations/1">
139
144
  <foaf:name>An Organization</foaf:name>
@@ -297,7 +297,7 @@ class DcatBackendTest:
297
297
  assert dataset.temporal_coverage.start == date(2016, 1, 1)
298
298
  assert dataset.temporal_coverage.end == date(2016, 12, 5)
299
299
 
300
- assert len(dataset.resources) == 2
300
+ assert len(dataset.resources) == 3
301
301
 
302
302
  resource_1 = next(res for res in dataset.resources if res.title == 'Resource 1-1')
303
303
  assert resource_1.filetype == 'remote'
@@ -307,11 +307,20 @@ class DcatBackendTest:
307
307
  assert resource_1.filesize == 12323
308
308
  assert resource_1.description == 'A JSON resource'
309
309
  assert resource_1.url == 'http://data.test.org/datasets/1/resources/1/file.json'
310
+ assert resource_1.type == 'main'
310
311
 
311
312
  resource_2 = next(res for res in dataset.resources if res.title == 'Resource 1-2')
312
313
  assert resource_2.format == 'json'
313
314
  assert resource_2.description == 'A JSON resource'
314
315
  assert resource_2.url == 'http://data.test.org/datasets/1/resources/2/file.json'
316
+ assert resource_2.type == 'main'
317
+
318
+ # Make sure additionnal resource is correctly harvested
319
+ resource_3 = next(res for res in dataset.resources if res.title == 'Resource 1-3')
320
+ assert resource_3.format == 'json'
321
+ assert resource_3.description == ''
322
+ assert resource_3.url == 'http://data.test.org/datasets/1/resources/3'
323
+ assert resource_3.type == 'other'
315
324
 
316
325
  def test_geonetwork_xml_catalog(self, rmock):
317
326
  url = mock_dcat(rmock, 'geonetwork.xml', path='catalog.xml')
@@ -413,7 +422,7 @@ class DcatBackendTest:
413
422
  error = job.errors[0]
414
423
  expected = 'Unable to detect format from extension or mime type'
415
424
  assert error.message == expected
416
-
425
+
417
426
  def test_use_replaced_uris(self, rmock, mocker):
418
427
  mocker.patch.dict(
419
428
  URIS_TO_REPLACE,
@@ -465,7 +474,7 @@ class DcatBackendTest:
465
474
  assert len(job.errors) == 1
466
475
  assert "404 Client Error" in job.errors[0].message
467
476
 
468
-
477
+
469
478
  @pytest.mark.usefixtures('clean_db')
470
479
  @pytest.mark.options(PLUGINS=['csw-dcat'])
471
480
  class CswDcatBackendTest: