udata 10.6.1.dev36082__py2.py3-none-any.whl → 10.6.1.dev36098__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 (100) hide show
  1. udata/api/fields.py +0 -17
  2. udata/auth/views.py +22 -24
  3. udata/core/activity/api.py +1 -1
  4. udata/core/dataservices/api.py +3 -3
  5. udata/core/dataservices/models.py +11 -11
  6. udata/core/dataservices/rdf.py +3 -18
  7. udata/core/dataset/api.py +4 -3
  8. udata/core/dataset/api_fields.py +14 -25
  9. udata/core/dataset/apiv2.py +8 -11
  10. udata/core/dataset/csv.py +2 -2
  11. udata/core/dataset/models.py +18 -20
  12. udata/core/dataset/rdf.py +5 -38
  13. udata/core/dataset/search.py +1 -1
  14. udata/core/discussions/api.py +3 -1
  15. udata/core/discussions/models.py +11 -15
  16. udata/core/linkable.py +16 -0
  17. udata/core/organization/api.py +1 -0
  18. udata/core/organization/api_fields.py +14 -26
  19. udata/core/organization/csv.py +1 -1
  20. udata/core/organization/models.py +13 -16
  21. udata/core/organization/rdf.py +1 -5
  22. udata/core/post/api.py +8 -8
  23. udata/core/post/models.py +9 -16
  24. udata/core/reports/models.py +2 -2
  25. udata/core/reuse/api.py +4 -3
  26. udata/core/reuse/api_fields.py +1 -7
  27. udata/core/reuse/csv.py +1 -1
  28. udata/core/reuse/models.py +15 -22
  29. udata/core/site/rdf.py +2 -3
  30. udata/core/spatial/models.py +2 -9
  31. udata/core/topic/api.py +4 -8
  32. udata/core/topic/apiv2.py +3 -8
  33. udata/core/topic/models.py +0 -5
  34. udata/core/user/api_fields.py +14 -14
  35. udata/core/user/models.py +10 -16
  36. udata/core/user/rdf.py +1 -3
  37. udata/features/territories/models.py +1 -17
  38. udata/rdf.py +1 -2
  39. udata/routing.py +3 -2
  40. udata/settings.py +2 -0
  41. udata/static/chunks/{10.471164b2a9fe15614797.js → 10.8ca60413647062717b1e.js} +3 -3
  42. udata/static/chunks/{10.471164b2a9fe15614797.js.map → 10.8ca60413647062717b1e.js.map} +1 -1
  43. udata/static/chunks/{11.83535504cd650ea08f65.js → 11.0f04e49a40a0a381bcce.js} +3 -3
  44. udata/static/chunks/{11.83535504cd650ea08f65.js.map → 11.0f04e49a40a0a381bcce.js.map} +1 -1
  45. udata/static/chunks/{13.d9c1735d14038b94c17e.js → 13.f29411b06be1883356a3.js} +2 -2
  46. udata/static/chunks/{13.d9c1735d14038b94c17e.js.map → 13.f29411b06be1883356a3.js.map} +1 -1
  47. udata/static/chunks/{17.81c57c0dedf812e43013.js → 17.3bd0340930d4a314ce9c.js} +2 -2
  48. udata/static/chunks/{17.81c57c0dedf812e43013.js.map → 17.3bd0340930d4a314ce9c.js.map} +1 -1
  49. udata/static/chunks/{19.df16abde17a42033a7f8.js → 19.0586efa786ebf09fb288.js} +3 -3
  50. udata/static/chunks/{19.df16abde17a42033a7f8.js.map → 19.0586efa786ebf09fb288.js.map} +1 -1
  51. udata/static/chunks/{8.462bb3029de008497675.js → 8.b966402f5d680d4bdf4a.js} +2 -2
  52. udata/static/chunks/{8.462bb3029de008497675.js.map → 8.b966402f5d680d4bdf4a.js.map} +1 -1
  53. udata/static/chunks/{9.07515e5187f475bce828.js → 9.033d7e190ca9e226a5d0.js} +3 -3
  54. udata/static/chunks/{9.07515e5187f475bce828.js.map → 9.033d7e190ca9e226a5d0.js.map} +1 -1
  55. udata/static/common.js +1 -1
  56. udata/static/common.js.map +1 -1
  57. udata/templates/api/oauth_error.html +1 -1
  58. udata/templates/macros/metadata.html +0 -1
  59. udata/templates/mail/account_inactivity.html +1 -1
  60. udata/templates/mail/account_inactivity.txt +1 -1
  61. udata/templates/mail/badge_added_association.html +3 -3
  62. udata/templates/mail/badge_added_association.txt +1 -1
  63. udata/templates/mail/badge_added_certified.html +3 -3
  64. udata/templates/mail/badge_added_certified.txt +1 -1
  65. udata/templates/mail/badge_added_company.html +3 -3
  66. udata/templates/mail/badge_added_company.txt +1 -1
  67. udata/templates/mail/badge_added_local_authority.html +3 -3
  68. udata/templates/mail/badge_added_local_authority.txt +1 -1
  69. udata/templates/mail/badge_added_public_service.html +3 -3
  70. udata/templates/mail/badge_added_public_service.txt +1 -1
  71. udata/templates/mail/discussion_closed.html +3 -3
  72. udata/templates/mail/discussion_closed.txt +1 -1
  73. udata/templates/mail/frequency_reminder.html +1 -1
  74. udata/templates/mail/frequency_reminder.txt +1 -1
  75. udata/templates/mail/membership_refused.html +1 -1
  76. udata/templates/mail/membership_request.html +3 -3
  77. udata/templates/mail/membership_request.txt +1 -1
  78. udata/templates/mail/new_discussion.html +3 -3
  79. udata/templates/mail/new_discussion.txt +1 -1
  80. udata/templates/mail/new_discussion_comment.html +3 -3
  81. udata/templates/mail/new_discussion_comment.txt +1 -1
  82. udata/templates/mail/new_member.html +2 -2
  83. udata/templates/mail/new_member.txt +1 -1
  84. udata/templates/mail/new_reuse.html +2 -12
  85. udata/templates/mail/new_reuse.txt +1 -3
  86. udata/templates/mail/user_mail_card.html +1 -1
  87. udata/tests/api/test_dataservices_api.py +2 -2
  88. udata/tests/api/test_datasets_api.py +2 -2
  89. udata/tests/api/test_reuses_api.py +2 -2
  90. udata/tests/api/test_topics_api.py +4 -4
  91. udata/tests/dataset/test_dataset_rdf.py +1 -9
  92. udata/tests/test_discussions.py +3 -3
  93. udata/tests/test_mail.py +8 -0
  94. udata/uris.py +28 -7
  95. {udata-10.6.1.dev36082.dist-info → udata-10.6.1.dev36098.dist-info}/METADATA +1 -1
  96. {udata-10.6.1.dev36082.dist-info → udata-10.6.1.dev36098.dist-info}/RECORD +100 -99
  97. {udata-10.6.1.dev36082.dist-info → udata-10.6.1.dev36098.dist-info}/LICENSE +0 -0
  98. {udata-10.6.1.dev36082.dist-info → udata-10.6.1.dev36098.dist-info}/WHEEL +0 -0
  99. {udata-10.6.1.dev36082.dist-info → udata-10.6.1.dev36098.dist-info}/entry_points.txt +0 -0
  100. {udata-10.6.1.dev36082.dist-info → udata-10.6.1.dev36098.dist-info}/top_level.txt +0 -0
@@ -50,13 +50,13 @@ class TopicsAPITest(APITestCase):
50
50
  for dataset, expected in zip(datasets, [d.fetch() for d in tag_topic_1.datasets]):
51
51
  self.assertEqual(dataset["id"], str(expected.id))
52
52
  self.assertEqual(dataset["title"], str(expected.title))
53
- self.assertIsNotNone(dataset["page"])
53
+ self.assertIsNone(dataset["page"]) # we don't have cdata in tests
54
54
  self.assertIsNotNone(dataset["uri"])
55
55
  reuses = response.json["data"][0]["reuses"]
56
56
  for reuse, expected in zip(reuses, [r.fetch() for r in tag_topic_1.reuses]):
57
57
  self.assertEqual(reuse["id"], str(expected.id))
58
58
  self.assertEqual(reuse["title"], str(expected.title))
59
- self.assertIsNotNone(reuse["page"])
59
+ self.assertIsNone(reuse["page"]) # we don't have cdata in tests
60
60
  self.assertIsNotNone(reuse["uri"])
61
61
  self.assertEqual(len(reuses), 3)
62
62
 
@@ -132,13 +132,13 @@ class TopicsAPITest(APITestCase):
132
132
  for dataset, expected in zip(data["datasets"], [d.fetch() for d in topic.datasets]):
133
133
  self.assertEqual(dataset["id"], str(expected.id))
134
134
  self.assertEqual(dataset["title"], str(expected.title))
135
- self.assertIsNotNone(dataset["page"])
135
+ self.assertIsNone(dataset["page"]) # we don't have cdata by default
136
136
  self.assertIsNotNone(dataset["uri"])
137
137
 
138
138
  for reuse, expected in zip(data["reuses"], [r.fetch() for r in topic.reuses]):
139
139
  self.assertEqual(reuse["id"], str(expected.id))
140
140
  self.assertEqual(reuse["title"], str(expected.title))
141
- self.assertIsNotNone(reuse["page"])
141
+ self.assertIsNone(reuse["page"]) # we don't have cdata by default
142
142
  self.assertIsNotNone(reuse["uri"])
143
143
 
144
144
  self.assertIsNotNone(data.get("created_at"))
@@ -48,7 +48,6 @@ from udata.rdf import (
48
48
  primary_topic_identifier_from_rdf,
49
49
  )
50
50
  from udata.tests.helpers import assert200, assert_redirects
51
- from udata.uris import endpoint_for
52
51
  from udata.utils import faker
53
52
 
54
53
  pytestmark = pytest.mark.usefixtures("app")
@@ -347,14 +346,7 @@ class DatasetToRdfTest:
347
346
  len(list(g.subjects(RDF.type, DCAT.Distribution))) == 4
348
347
  len(list(g.subjects(RDF.type, DCAT.DataService))) == 1
349
348
  dataservice_as_distribution = g.resource(next(g.subjects(DCAT.accessService)))
350
- dataservice_uri = URIRef(
351
- endpoint_for(
352
- "dataservices.show_redirect",
353
- "api.dataservice",
354
- dataservice=dataservice.id,
355
- _external=True,
356
- )
357
- )
349
+ dataservice_uri = URIRef(dataservice.url_for(_useId=True))
358
350
  assert dataservice_as_distribution.value(DCAT.accessURL).identifier == URIRef(
359
351
  dataservice.base_api_url
360
352
  )
@@ -137,7 +137,7 @@ class DiscussionsTest(APITestCase):
137
137
  )
138
138
  self.assert400(response)
139
139
 
140
- @pytest.mark.options(SPAM_WORDS=["spam"])
140
+ @pytest.mark.options(SPAM_WORDS=["spam"], CDATA_BASE_URL="https://data.gouv.fr")
141
141
  def test_spam_in_new_discussion_title(self):
142
142
  self.login()
143
143
  dataset = Dataset.objects.create(title="Test dataset")
@@ -148,7 +148,7 @@ class DiscussionsTest(APITestCase):
148
148
  def check_signal(args):
149
149
  self.assertIsNotNone(discussion_id)
150
150
  self.assertIn(
151
- f"http://local.test/api/1/datasets/{dataset.slug}/#discussion-{discussion_id}",
151
+ f"https://data.gouv.fr/datasets/{dataset.slug}/discussions/?discussion_id={discussion_id}",
152
152
  args[1]["message"],
153
153
  )
154
154
 
@@ -579,7 +579,7 @@ class DiscussionsTest(APITestCase):
579
579
  with assert_not_emit(on_new_discussion_comment):
580
580
 
581
581
  def check_signal(args):
582
- self.assertIn(discussion.external_url, args[1]["message"])
582
+ self.assertIn(discussion.url_for(), args[1]["message"])
583
583
 
584
584
  with assert_emit(on_new_potential_spam, assertions_callback=check_signal):
585
585
  response = self.post(
udata/tests/test_mail.py CHANGED
@@ -57,6 +57,10 @@ class MailSendTest(TestCase, DBTestMixin):
57
57
  @pytest.mark.frontend
58
58
  class MailCampaignTest:
59
59
  def test_send_mail_campaign_link_new_member(self, app):
60
+ # MTM campaign are only added on web URL (not API ones generated when
61
+ # no front-end is configured)
62
+ app.config["CDATA_BASE_URL"] = "https://www.data.gouv.fr"
63
+
60
64
  org = OrganizationFactory()
61
65
  recipient = UserFactory(email="recipient@udata")
62
66
 
@@ -88,6 +92,10 @@ class MailCampaignTest:
88
92
  assert "mtm_campaign=data-gouv-fr" in message.html
89
93
 
90
94
  def test_send_mail_campaign_link_badge_added_company(self, app):
95
+ # MTM campaign are only added on web URL (not API ones generated when
96
+ # no front-end is configured)
97
+ app.config["CDATA_BASE_URL"] = "https://www.data.gouv.fr"
98
+
91
99
  app.config["SEND_MAIL"] = True
92
100
  org = OrganizationFactory()
93
101
  org.add_badge("company")
udata/uris.py CHANGED
@@ -1,10 +1,12 @@
1
1
  import re
2
+ from typing import Optional
3
+ from urllib.parse import urlencode, urljoin, urlparse, urlunparse
2
4
 
3
5
  from flask import current_app, url_for
4
6
  from netaddr import AddrFormatError, IPAddress
5
- from werkzeug.routing import BuildError
6
7
 
7
8
  from udata.i18n import _
9
+ from udata.mail import get_mail_campaign_dict
8
10
  from udata.settings import Defaults
9
11
 
10
12
  URL_REGEX = re.compile(
@@ -66,14 +68,33 @@ def config_for(value, key):
66
68
  return getattr(Defaults, key)
67
69
 
68
70
 
69
- def endpoint_for(endpoint, fallback_endpoint=None, **values):
70
- try:
71
- return url_for(endpoint, **values)
72
- except BuildError:
73
- if fallback_endpoint:
74
- return url_for(fallback_endpoint, **values)
71
+ def homepage_url(**kwargs) -> str:
72
+ return cdata_url("/", **kwargs) or url_for("api.site", **kwargs)
73
+
74
+
75
+ def cdata_url(uri: str, **kwargs) -> Optional[str]:
76
+ base_url = current_app.config["CDATA_BASE_URL"]
77
+ if not base_url:
75
78
  return None
76
79
 
80
+ if kwargs.pop("_mailCampaign", False):
81
+ kwargs.update(get_mail_campaign_dict())
82
+
83
+ uri = uri.rstrip("/")
84
+ append = kwargs.pop("append", None)
85
+ if append:
86
+ uri += f"/{append.lstrip('/')}"
87
+
88
+ url = urljoin(base_url, uri)
89
+ if not url.endswith("/"):
90
+ url += "/"
91
+
92
+ url_parts = list(urlparse(url))
93
+ url_parts[4] = urlencode(
94
+ {k: v for k, v in kwargs.items() if not k.startswith("_")}
95
+ ) # index 4 is the query params
96
+ return urlunparse(url_parts)
97
+
77
98
 
78
99
  def idna(string):
79
100
  return string.encode("idna").decode("utf8")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: udata
3
- Version: 10.6.1.dev36082
3
+ Version: 10.6.1.dev36098
4
4
  Summary: Open data portal
5
5
  Home-page: https://github.com/opendatateam/udata
6
6
  Author: Opendata Team