udata 9.2.5.dev32275__py2.py3-none-any.whl → 9.2.5.dev32301__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/commands/fixtures.py +1 -1
  2. udata/core/contact_point/factories.py +1 -0
  3. udata/core/dataservices/rdf.py +7 -2
  4. udata/core/dataset/rdf.py +5 -0
  5. udata/core/organization/constants.py +3 -3
  6. udata/harvest/tests/dcat/catalog.xml +1 -0
  7. udata/harvest/tests/test_dcat_backend.py +3 -2
  8. udata/migrations/2024-10-30-rename-organization-badges.py +27 -0
  9. udata/rdf.py +44 -13
  10. udata/static/chunks/{11.73df0f7db57e9d3760a8.js → 11.727465d72948bc466d43.js} +3 -3
  11. udata/static/chunks/{11.73df0f7db57e9d3760a8.js.map → 11.727465d72948bc466d43.js.map} +1 -1
  12. udata/static/chunks/{19.60553a26cf14db0d477d.js → 19.4f7a5b71ef006ac268c1.js} +3 -3
  13. udata/static/chunks/{19.60553a26cf14db0d477d.js.map → 19.4f7a5b71ef006ac268c1.js.map} +1 -1
  14. udata/static/chunks/{5.5e786cbf357f4e8a84f1.js → 5.448ccace1bf3389d9b38.js} +3 -3
  15. udata/static/chunks/{5.5e786cbf357f4e8a84f1.js.map → 5.448ccace1bf3389d9b38.js.map} +1 -1
  16. udata/static/chunks/{6.342fe2407181b273aac0.js → 6.037369868acc94a7533f.js} +3 -3
  17. udata/static/chunks/{6.342fe2407181b273aac0.js.map → 6.037369868acc94a7533f.js.map} +1 -1
  18. udata/static/common.js +1 -1
  19. udata/static/common.js.map +1 -1
  20. udata/tests/dataset/test_dataset_rdf.py +13 -0
  21. udata/tests/test_rdf.py +24 -0
  22. {udata-9.2.5.dev32275.dist-info → udata-9.2.5.dev32301.dist-info}/METADATA +3 -1
  23. {udata-9.2.5.dev32275.dist-info → udata-9.2.5.dev32301.dist-info}/RECORD +27 -26
  24. {udata-9.2.5.dev32275.dist-info → udata-9.2.5.dev32301.dist-info}/LICENSE +0 -0
  25. {udata-9.2.5.dev32275.dist-info → udata-9.2.5.dev32301.dist-info}/WHEEL +0 -0
  26. {udata-9.2.5.dev32275.dist-info → udata-9.2.5.dev32301.dist-info}/entry_points.txt +0 -0
  27. {udata-9.2.5.dev32275.dist-info → udata-9.2.5.dev32301.dist-info}/top_level.txt +0 -0
@@ -39,7 +39,7 @@ COMMUNITY_RES_URL = "/api/1/datasets/community_resources"
39
39
  DISCUSSION_URL = "/api/1/discussions"
40
40
 
41
41
 
42
- DEFAULT_FIXTURE_FILE_TAG: str = "v2.0.0"
42
+ DEFAULT_FIXTURE_FILE_TAG: str = "v3.0.0"
43
43
  DEFAULT_FIXTURE_FILE: str = f"https://raw.githubusercontent.com/opendatateam/udata-fixtures/{DEFAULT_FIXTURE_FILE_TAG}/results.json" # noqa
44
44
 
45
45
  DEFAULT_FIXTURES_RESULTS_FILENAME: str = "results.json"
@@ -10,4 +10,5 @@ class ContactPointFactory(ModelFactory):
10
10
  model = ContactPoint
11
11
 
12
12
  name = factory.Faker("name")
13
+ contact_form = factory.Faker("url")
13
14
  email = factory.Sequence(lambda n: "contact_point{}@example.com".format(n))
@@ -8,6 +8,7 @@ from udata.rdf import (
8
8
  DCAT,
9
9
  DCT,
10
10
  contact_point_from_rdf,
11
+ contact_point_to_rdf,
11
12
  namespace_manager,
12
13
  rdf_value,
13
14
  remote_url_from_rdf,
@@ -116,7 +117,7 @@ def dataservice_to_rdf(dataservice: Dataservice, graph=None):
116
117
  d.set(DCT.issued, Literal(dataservice.created_at))
117
118
 
118
119
  if dataservice.base_api_url:
119
- d.set(DCAT.endpointURL, Literal(dataservice.base_api_url))
120
+ d.set(DCAT.endpointURL, URIRef(dataservice.base_api_url))
120
121
 
121
122
  if dataservice.harvest and dataservice.harvest.remote_url:
122
123
  d.set(DCAT.landingPage, URIRef(dataservice.harvest.remote_url))
@@ -134,7 +135,7 @@ def dataservice_to_rdf(dataservice: Dataservice, graph=None):
134
135
  )
135
136
 
136
137
  if dataservice.endpoint_description_url:
137
- d.set(DCAT.endpointDescription, Literal(dataservice.endpoint_description_url))
138
+ d.set(DCAT.endpointDescription, URIRef(dataservice.endpoint_description_url))
138
139
 
139
140
  for tag in dataservice.tags:
140
141
  d.add(DCAT.keyword, Literal(tag))
@@ -147,4 +148,8 @@ def dataservice_to_rdf(dataservice: Dataservice, graph=None):
147
148
  for dataset in dataservice.datasets:
148
149
  d.add(DCAT.servesDataset, dataset_to_graph_id(dataset))
149
150
 
151
+ contact_point = contact_point_to_rdf(dataservice.contact_point, graph)
152
+ if contact_point:
153
+ d.set(DCAT.contactPoint, contact_point)
154
+
150
155
  return d
udata/core/dataset/rdf.py CHANGED
@@ -35,6 +35,7 @@ from udata.rdf import (
35
35
  SPDX,
36
36
  TAG_TO_EU_HVD_CATEGORIES,
37
37
  contact_point_from_rdf,
38
+ contact_point_to_rdf,
38
39
  namespace_manager,
39
40
  rdf_unique_values,
40
41
  rdf_value,
@@ -258,6 +259,10 @@ def dataset_to_rdf(dataset, graph=None):
258
259
  if publisher:
259
260
  d.set(DCT.publisher, publisher)
260
261
 
262
+ contact_point = contact_point_to_rdf(dataset.contact_point, graph)
263
+ if contact_point:
264
+ d.set(DCAT.contactPoint, contact_point)
265
+
261
266
  return d
262
267
 
263
268
 
@@ -19,9 +19,9 @@ BIGGEST_LOGO_SIZE = LOGO_SIZES[0]
19
19
 
20
20
  PUBLIC_SERVICE = "public-service"
21
21
  CERTIFIED = "certified"
22
- ASSOCIATION = "Association"
23
- COMPANY = "Company"
24
- LOCAL_AUTHORITY = "Local authority"
22
+ ASSOCIATION = "association"
23
+ COMPANY = "company"
24
+ LOCAL_AUTHORITY = "local-authority"
25
25
 
26
26
  TITLE_SIZE_LIMIT = 350
27
27
  DESCRIPTION_SIZE_LIMIT = 100000
@@ -115,6 +115,7 @@
115
115
  <vcard:Organization rdf:about="http://data.test.org/contacts/1">
116
116
  <vcard:fn>Organization contact</vcard:fn>
117
117
  <vcard:hasEmail>mailto: hello@its.me</vcard:hasEmail>
118
+ <vcard:hasUrl>https://data.support.com</vcard:hasUrl>
118
119
  </vcard:Organization>
119
120
  <dcterms:PeriodOfTime rdf:about="file:///base/data/home/apps/s%7Erdf-translator/2.408516547054015808/temporal-1">
120
121
  <schema:startDate rdf:datatype="http://www.w3.org/2001/XMLSchema#dateTime">2016-12-05T00:00:00</schema:startDate>
@@ -517,8 +517,9 @@ class DcatBackendTest:
517
517
  assert dataset.temporal_coverage is not None
518
518
  assert dataset.temporal_coverage.start == date(2016, 1, 1)
519
519
  assert dataset.temporal_coverage.end == date(2016, 12, 5)
520
- assert dataset.contact_point["email"] == "hello@its.me"
521
- assert dataset.contact_point["name"] == "Organization contact"
520
+ assert dataset.contact_point.email == "hello@its.me"
521
+ assert dataset.contact_point.name == "Organization contact"
522
+ assert dataset.contact_point.contact_form == "https://data.support.com"
522
523
  assert dataset.frequency is None
523
524
  # test dct:license nested in distribution
524
525
  assert dataset.license.id == "lov1"
@@ -0,0 +1,27 @@
1
+ """
2
+ This migration renames the organization badges for coherent cases
3
+ """
4
+
5
+ import logging
6
+
7
+ from udata.core.organization.constants import ASSOCIATION, COMPANY, LOCAL_AUTHORITY
8
+ from udata.models import Organization
9
+
10
+ log = logging.getLogger(__name__)
11
+
12
+
13
+ mapping_legacy_to_actual = {
14
+ "Association": ASSOCIATION,
15
+ "Company": COMPANY,
16
+ "Local authority": LOCAL_AUTHORITY,
17
+ }
18
+
19
+
20
+ def migrate(db):
21
+ log.info("Processing Organizations...")
22
+
23
+ for legacy, actual in mapping_legacy_to_actual.items():
24
+ count = Organization.objects(badges__kind=legacy).update(set__badges__S__kind=actual)
25
+ log.info(f"Renamed badge {actual} for {count} Organization objects.")
26
+
27
+ log.info("Done")
udata/rdf.py CHANGED
@@ -7,7 +7,7 @@ import re
7
7
  from html.parser import HTMLParser
8
8
 
9
9
  from flask import abort, current_app, request, url_for
10
- from rdflib import Graph, Literal, URIRef
10
+ from rdflib import BNode, Graph, Literal, URIRef
11
11
  from rdflib.namespace import (
12
12
  DCTERMS,
13
13
  FOAF,
@@ -28,6 +28,7 @@ from udata.frontend.markdown import parse_html
28
28
  from udata.models import Schema
29
29
  from udata.mongo.errors import FieldValidationError
30
30
  from udata.tags import slug as slugify_tag
31
+ from udata.uris import endpoint_for
31
32
 
32
33
  log = logging.getLogger(__name__)
33
34
 
@@ -301,22 +302,52 @@ def contact_point_from_rdf(rdf, dataset):
301
302
  or rdf_value(contact_point, VCARD.email)
302
303
  or rdf_value(contact_point, DCAT.email)
303
304
  )
304
- if not email:
305
+ email = email.replace("mailto:", "").strip() if email else None
306
+ contact_form = rdf_value(contact_point, VCARD.hasUrl)
307
+ if not email and not contact_form:
305
308
  return
306
- email = email.replace("mailto:", "").strip()
307
309
  if dataset.organization:
308
- contact_point = ContactPoint.objects(
309
- name=name, email=email, organization=dataset.organization
310
- ).first()
311
- return (
312
- contact_point
313
- or ContactPoint(name=name, email=email, organization=dataset.organization).save()
310
+ contact, _ = ContactPoint.objects.get_or_create(
311
+ name=name, email=email, contact_form=contact_form, organization=dataset.organization
314
312
  )
315
313
  elif dataset.owner:
316
- contact_point = ContactPoint.objects(
317
- name=name, email=email, owner=dataset.owner
318
- ).first()
319
- return contact_point or ContactPoint(name=name, email=email, owner=dataset.owner).save()
314
+ contact, _ = ContactPoint.objects.get_or_create(
315
+ name=name, email=email, contact_form=contact_form, owner=dataset.owner
316
+ )
317
+ else:
318
+ contact = None
319
+ return contact
320
+
321
+
322
+ def contact_point_to_rdf(contact, graph=None):
323
+ """
324
+ Map a contact point to a DCAT/RDF graph
325
+ """
326
+ if not contact:
327
+ return None
328
+
329
+ graph = graph or Graph(namespace_manager=namespace_manager)
330
+
331
+ if contact.id:
332
+ id = URIRef(
333
+ endpoint_for(
334
+ "api.contact_point",
335
+ contact_point=contact.id,
336
+ _external=True,
337
+ )
338
+ )
339
+ else:
340
+ id = BNode()
341
+
342
+ node = graph.resource(id)
343
+ node.set(RDF.type, VCARD.Kind)
344
+ if contact.name:
345
+ node.set(VCARD.fn, Literal(contact.name))
346
+ if contact.email:
347
+ node.set(VCARD.hasEmail, URIRef(f"mailto:{contact.email}"))
348
+ if contact.contact_form:
349
+ node.set(VCARD.hasUrl, URIRef(contact.contact_form))
350
+ return node
320
351
 
321
352
 
322
353
  def primary_topic_identifier_from_rdf(graph: Graph, resource: RdfResource):