udata 10.9.1.dev37462__py2.py3-none-any.whl → 10.9.1.dev37604__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 (45) hide show
  1. udata/api/__init__.py +0 -1
  2. udata/core/dataset/api.py +1 -1
  3. udata/core/dataset/search.py +5 -2
  4. udata/core/dataset/tasks.py +2 -5
  5. udata/core/reuse/tasks.py +3 -0
  6. udata/core/topic/__init__.py +1 -0
  7. udata/core/topic/api_fields.py +87 -0
  8. udata/core/topic/apiv2.py +116 -194
  9. udata/core/topic/factories.py +69 -8
  10. udata/core/topic/forms.py +58 -4
  11. udata/core/topic/models.py +65 -20
  12. udata/core/topic/parsers.py +40 -0
  13. udata/core/topic/tasks.py +11 -0
  14. udata/forms/fields.py +8 -1
  15. udata/harvest/backends/dcat.py +41 -20
  16. udata/harvest/tests/test_dcat_backend.py +89 -0
  17. udata/migrations/2025-05-26-migrate-topics-to-elements.py +59 -0
  18. udata/migrations/2025-06-02-delete-topic-name-index.py +19 -0
  19. udata/static/chunks/{11.51d706fb9521c16976bc.js → 11.822f6ccb39c92c796d13.js} +3 -3
  20. udata/static/chunks/{11.51d706fb9521c16976bc.js.map → 11.822f6ccb39c92c796d13.js.map} +1 -1
  21. udata/static/chunks/{13.f29411b06be1883356a3.js → 13.d9c1735d14038b94c17e.js} +2 -2
  22. udata/static/chunks/{13.f29411b06be1883356a3.js.map → 13.d9c1735d14038b94c17e.js.map} +1 -1
  23. udata/static/chunks/{17.3bd0340930d4a314ce9c.js → 17.81c57c0dedf812e43013.js} +2 -2
  24. udata/static/chunks/{17.3bd0340930d4a314ce9c.js.map → 17.81c57c0dedf812e43013.js.map} +1 -1
  25. udata/static/chunks/{8.b966402f5d680d4bdf4a.js → 8.0f42630e6d8ff782928e.js} +2 -2
  26. udata/static/chunks/{8.b966402f5d680d4bdf4a.js.map → 8.0f42630e6d8ff782928e.js.map} +1 -1
  27. udata/static/common.js +1 -1
  28. udata/static/common.js.map +1 -1
  29. udata/tasks.py +1 -0
  30. udata/tests/api/test_datasets_api.py +3 -2
  31. udata/tests/apiv2/test_me_api.py +2 -2
  32. udata/tests/apiv2/test_topics.py +457 -127
  33. udata/tests/dataset/test_dataset_tasks.py +7 -2
  34. udata/tests/reuse/test_reuse_task.py +9 -0
  35. udata/tests/search/test_adapter.py +43 -0
  36. udata/tests/test_topics.py +19 -8
  37. udata/tests/topic/test_topic_tasks.py +27 -0
  38. {udata-10.9.1.dev37462.dist-info → udata-10.9.1.dev37604.dist-info}/METADATA +4 -2
  39. {udata-10.9.1.dev37462.dist-info → udata-10.9.1.dev37604.dist-info}/RECORD +43 -40
  40. udata/core/topic/api.py +0 -145
  41. udata/tests/api/test_topics_api.py +0 -284
  42. {udata-10.9.1.dev37462.dist-info → udata-10.9.1.dev37604.dist-info}/LICENSE +0 -0
  43. {udata-10.9.1.dev37462.dist-info → udata-10.9.1.dev37604.dist-info}/WHEEL +0 -0
  44. {udata-10.9.1.dev37462.dist-info → udata-10.9.1.dev37604.dist-info}/entry_points.txt +0 -0
  45. {udata-10.9.1.dev37462.dist-info → udata-10.9.1.dev37604.dist-info}/top_level.txt +0 -0
@@ -10,6 +10,7 @@ from udata.core.discussions.factories import DiscussionFactory
10
10
  from udata.core.organization.csv import OrganizationCsvAdapter # noqa
11
11
  from udata.core.reuse.csv import ReuseCsvAdapter # noqa
12
12
  from udata.core.tags.csv import TagCsvAdapter # noqa
13
+ from udata.core.topic.models import TopicElement
13
14
  from udata.core.user.factories import UserFactory
14
15
  from udata.harvest.csv import HarvestSourceCsvAdapter # noqa
15
16
  from udata.harvest.models import HarvestItem, HarvestJob
@@ -25,7 +26,10 @@ def test_purge_datasets():
25
26
  Dataset.objects.create(title="keep me"),
26
27
  ]
27
28
 
28
- topic = Topic.objects.create(name="test topic", datasets=datasets)
29
+ topic = Topic.objects.create(name="test topic")
30
+ for d in datasets:
31
+ topic_element = TopicElement(element=d, topic=topic)
32
+ topic_element.save()
29
33
 
30
34
  user = UserFactory()
31
35
  transfer = Transfer.objects.create(
@@ -48,7 +52,8 @@ def test_purge_datasets():
48
52
  assert Transfer.objects.filter(id=transfer.id).count() == 0
49
53
 
50
54
  topic = Topic.objects(name="test topic").first()
51
- assert topic.datasets[0] == datasets[1]
55
+ topic_element = topic.elements.first()
56
+ assert topic_element.element is None
52
57
 
53
58
  assert Discussion.objects.filter(id=discussion.id).count() == 0
54
59
  assert Follow.objects.filter(id=follower.id).count() == 0
@@ -3,6 +3,7 @@ from flask import url_for
3
3
  from udata.core import storages
4
4
  from udata.core.reuse import tasks
5
5
  from udata.core.reuse.factories import ReuseFactory
6
+ from udata.core.topic.models import Topic, TopicElement
6
7
  from udata.core.user.factories import AdminFactory, UserFactory
7
8
  from udata.models import Reuse, Transfer
8
9
  from udata.tests.api import APITestCase
@@ -22,6 +23,10 @@ class ReuseTasksTest(APITestCase):
22
23
  )
23
24
  self.assert200(response)
24
25
 
26
+ topic = Topic.objects.create(name="test topic")
27
+ topic_element = TopicElement(element=reuse, topic=topic)
28
+ topic_element.save()
29
+
25
30
  # Delete reuse
26
31
  response = self.delete(url_for("api.reuse", reuse=reuse))
27
32
  self.assert204(response)
@@ -38,6 +43,10 @@ class ReuseTasksTest(APITestCase):
38
43
 
39
44
  assert Transfer.objects.filter(id=transfer.id).count() == 0
40
45
 
46
+ topic = Topic.objects(name="test topic").first()
47
+ element = topic.elements.first()
48
+ assert element.element is None
49
+
41
50
  # Check reuse's image is deleted
42
51
  self.assertEqual(list(storages.images.list_files()), [])
43
52
 
@@ -14,6 +14,7 @@ from udata.core.dataset.factories import (
14
14
  )
15
15
  from udata.core.dataset.models import Schema
16
16
  from udata.core.dataset.search import DatasetSearch
17
+ from udata.core.topic.factories import TopicElementDatasetFactory, TopicFactory
17
18
  from udata.i18n import gettext as _
18
19
  from udata.search import as_task_param, reindex
19
20
  from udata.search.commands import index_model
@@ -173,3 +174,45 @@ class IndexingLifecycleTest(APITestCase):
173
174
  expected_value = {"document": DatasetSearch.serialize(fake_data), "index": "dataset"}
174
175
  url = f"{current_app.config['SEARCH_SERVICE_API_URL']}/datasets/index"
175
176
  mock_req.assert_called_with(url, json=expected_value)
177
+
178
+
179
+ class DatasetSearchAdapterTest(APITestCase):
180
+ def test_serialize_includes_topic_ids(self):
181
+ """Test that DatasetSearch.serialize includes topic_ids in the serialized document"""
182
+ dataset = DatasetFactory()
183
+ topic1 = TopicFactory()
184
+ topic2 = TopicFactory()
185
+
186
+ TopicElementDatasetFactory(element=dataset, topic=topic1)
187
+ TopicElementDatasetFactory(element=dataset, topic=topic2)
188
+
189
+ serialized = DatasetSearch.serialize(dataset)
190
+
191
+ assert "topics" in serialized
192
+ assert len(serialized["topics"]) == 2
193
+ assert str(topic1.id) in serialized["topics"]
194
+ assert str(topic2.id) in serialized["topics"]
195
+
196
+ def test_serialize_empty_topics_for_dataset_without_topics(self):
197
+ """Test that DatasetSearch.serialize returns empty topics list for dataset without topics"""
198
+ dataset = DatasetFactory()
199
+
200
+ serialized = DatasetSearch.serialize(dataset)
201
+
202
+ assert "topics" in serialized
203
+ assert serialized["topics"] == []
204
+
205
+ def test_serialize_deduplicates_topic_ids(self):
206
+ """Test that DatasetSearch.serialize deduplicates topic IDs when same topic appears multiple times"""
207
+ dataset = DatasetFactory()
208
+ topic = TopicFactory()
209
+
210
+ # Create multiple topic elements for the same topic
211
+ TopicElementDatasetFactory(element=dataset, topic=topic)
212
+ TopicElementDatasetFactory(element=dataset, topic=topic)
213
+
214
+ serialized = DatasetSearch.serialize(dataset)
215
+
216
+ assert "topics" in serialized
217
+ assert len(serialized["topics"]) == 1
218
+ assert str(topic.id) in serialized["topics"]
@@ -1,8 +1,14 @@
1
1
  import pytest
2
+ from mongoengine.errors import ValidationError
2
3
 
3
- from udata.core.dataset.factories import DatasetFactory
4
+ from udata.core.discussions.factories import DiscussionFactory
4
5
  from udata.core.topic.activities import UserCreatedTopic, UserUpdatedTopic
5
- from udata.core.topic.factories import TopicFactory
6
+ from udata.core.topic.factories import (
7
+ TopicElementDatasetFactory,
8
+ TopicElementFactory,
9
+ TopicFactory,
10
+ TopicWithElementsFactory,
11
+ )
6
12
  from udata.core.topic.models import Topic
7
13
  from udata.search import reindex
8
14
  from udata.tests.helpers import assert_emit
@@ -27,26 +33,25 @@ class TopicModelTest:
27
33
  modules = ["admin"]
28
34
 
29
35
  def test_pre_save(self, job_reindex):
30
- topic = TopicFactory(datasets=[])
31
- dataset = DatasetFactory()
36
+ topic = TopicFactory()
32
37
 
33
38
  topic.name = "new_name"
34
39
  topic.save()
35
40
  job_reindex.assert_not_called()
36
41
 
37
- topic.datasets = [dataset]
42
+ TopicElementDatasetFactory(topic=topic)
38
43
  topic.save()
39
44
  job_reindex.assert_called()
40
45
 
41
- topic.datasets = []
46
+ topic.elements.delete()
42
47
  topic.save()
43
48
  job_reindex.assert_called()
44
49
 
45
50
  @pytest.mark.options(SEARCH_SERVICE_API_URL="smtg")
46
51
  def test_pre_save_reindex(self, job_reindex_undelayed):
47
52
  """This will call the real reindex method and thus bubble up errors"""
48
- # creates a topic with datasets, thus calls reindex
49
- TopicFactory()
53
+ # creates a topic with elements, thus calls reindex
54
+ TopicWithElementsFactory()
50
55
  job_reindex_undelayed.assert_called()
51
56
 
52
57
  def test_topic_activities(self, api, mocker):
@@ -64,3 +69,9 @@ class TopicModelTest:
64
69
  topic.name = "new name"
65
70
  topic.save()
66
71
  mock_updated.assert_called()
72
+
73
+ def test_topic_element_wrong_class(self):
74
+ # use a model instance that is not supported
75
+ with pytest.raises(ValidationError):
76
+ topic = TopicFactory()
77
+ TopicElementFactory(topic=topic, element=DiscussionFactory())
@@ -0,0 +1,27 @@
1
+ import pytest
2
+
3
+ from udata.core.dataset.tasks import purge_datasets
4
+ from udata.core.reuse.tasks import purge_reuses
5
+ from udata.core.topic.factories import TopicWithElementsFactory
6
+ from udata.core.topic.tasks import purge_topics_elements
7
+
8
+ pytestmark = pytest.mark.usefixtures("clean_db")
9
+
10
+
11
+ def test_purge_topics_elements():
12
+ topic = TopicWithElementsFactory()
13
+ assert len(topic.elements) > 0
14
+ for element in topic.elements:
15
+ element.title = None
16
+ element.save()
17
+ element.element.deleted = "2023-01-01"
18
+ element.element.save()
19
+ topic.save()
20
+ # remove the dataset elements marked as deleted
21
+ purge_datasets()
22
+ # remove the reuse elements marked as deleted
23
+ purge_reuses()
24
+ # remove the topic elements that have neither title nor element
25
+ purge_topics_elements()
26
+ topic.reload()
27
+ assert len(topic.elements) == 0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: udata
3
- Version: 10.9.1.dev37462
3
+ Version: 10.9.1.dev37604
4
4
  Summary: Open data portal
5
5
  Home-page: https://github.com/opendatateam/udata
6
6
  Author: Opendata Team
@@ -102,6 +102,7 @@ Requires-Dist: regex==2024.11.6
102
102
  Requires-Dist: requests==2.32.3
103
103
  Requires-Dist: rpds-py==0.23.1
104
104
  Requires-Dist: s3transfer==0.6.2
105
+ Requires-Dist: saxonche==12.8.0
105
106
  Requires-Dist: sentry-sdk[flask]==2.23.1
106
107
  Requires-Dist: six==1.17.0
107
108
  Requires-Dist: speaklater==1.3
@@ -143,7 +144,7 @@ It is collectively taken care of by members of the
143
144
 
144
145
  ## Current (in progress)
145
146
 
146
- - Nothing yet
147
+ - Change CSW harvesters XML processor from lxml to saxonche [#3380](https://github.com/opendatateam/udata/pull/3380)
147
148
 
148
149
  ## 10.9.0 (2025-08-28)
149
150
 
@@ -232,6 +233,7 @@ It is collectively taken care of by members of the
232
233
  - Allow global admins to manually run harvesters in production [#3340](https://github.com/opendatateam/udata/pull/3340)
233
234
  - Add monthly metrics to datasets, dataservices, reuses and organizations [#3342](https://github.com/opendatateam/udata/pull/3342)
234
235
  - Fix user avatar deletion [#3346](https://github.com/opendatateam/udata/pull/3346)
236
+ - **breaking change** feat: topic elements [#3318](https://github.com/opendatateam/udata/pull/3318)
235
237
 
236
238
  ## 10.4.2 (2025-06-05)
237
239
 
@@ -16,7 +16,7 @@ udata/sentry.py,sha256=ekcxqUSqxfM98TtvCsPaOoX5i2l6PEcYt7kb4l3od-Q,3223
16
16
  udata/settings.py,sha256=hKYOF3kHONuPGRkypE_dqHAyQLuxN85FjK--7l5abho,19668
17
17
  udata/sitemap.py,sha256=oRRWoPI7ZsFFnUAOqGT1YuXFFKHBe8EcRnUCNHD7xjM,979
18
18
  udata/tags.py,sha256=ydq4uokd6bzdeGVSpEXASVtGvDfO2LfQs9mptvvKJCM,631
19
- udata/tasks.py,sha256=yTYBJG5bzEChX27p3MSqurSji84rg7w7OUvK4vuPRfY,5080
19
+ udata/tasks.py,sha256=Sv01dhvATtq_oHOBp3J1j1VT1HQe0Pab7zxwIeIdKoo,5122
20
20
  udata/terms.md,sha256=nFx978tUQ3vTEv6POykXaZvcQ5e_gcvmO4ZgcfbSWXo,187
21
21
  udata/tracking.py,sha256=WOcqA1RlHN8EPFuEc2kNau54mec4-pvi-wUFrMXevzg,345
22
22
  udata/uris.py,sha256=1wOrsxu6lmZJ1h4634kNHjqOjaOO0D5cIWKF_v_Gtn4,4264
@@ -25,7 +25,7 @@ udata/worker.py,sha256=K-Wafye5-uXP4kQlffRKws2J9YbJ6m6n2QjcVsY8Nsg,118
25
25
  udata/wsgi.py,sha256=MY8en9K9eDluvJYUxTdzqSDoYaDgCVZ69ZcUvxAvgqA,77
26
26
  udata/admin/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
27
27
  udata/admin/views.py,sha256=00fI1O55apOlwIc0li2BdvEEGMd5l5isd5A_eHvzu3Y,331
28
- udata/api/__init__.py,sha256=GcyTqsyNV4yAxF2pcF3x3sUZnbeOD0AzlawjBBUS1sE,11988
28
+ udata/api/__init__.py,sha256=Rs1V6KqWUcZliZnoIrVKtq15Bfb8ZaOVOFuGhcv0SK8,11948
29
29
  udata/api/commands.py,sha256=LJ4u-yhGij7QuH7OR92u3n7BEptqWMjDwMnG8pqdBxo,3523
30
30
  udata/api/errors.py,sha256=P_UigBf6HAL73LbXKULagmp5Cuw-H1Ms6LmXxOmFIeg,211
31
31
  udata/api/fields.py,sha256=w3qpMGntcOQa5bwFenZNJrnIoEZGZkEhRq0OwWFHsgc,3801
@@ -96,7 +96,7 @@ udata/core/dataservices/tasks.py,sha256=d2tG1l6u8-eUKUYBOgnCsQLbLmLgJXU-DOzZWhhL
96
96
  udata/core/dataset/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
97
97
  udata/core/dataset/actions.py,sha256=mX6xox0PiMrbcAPZ3VZsI26rfM-ciYfEXxN6sqqImKA,1222
98
98
  udata/core/dataset/activities.py,sha256=RtY06G6FiEMr8NY26kaYKCXwGdcGtBJv2U8kWgFTRxE,3048
99
- udata/core/dataset/api.py,sha256=-9-JevxZqc30QNCx-7n0QYcYdXIetuyH45Y9E9qRkzs,35598
99
+ udata/core/dataset/api.py,sha256=IsR47VqEad6MeiLEZDLl6IeoIUl7mBLKXuTG1eUl6FE,35608
100
100
  udata/core/dataset/api_fields.py,sha256=brOvQ2TliZMEYphgkoUvw9F1G_eirX_eg5BZBJM3jko,17912
101
101
  udata/core/dataset/apiv2.py,sha256=ZRKYnF9QCv2cHEHea6JYbbwwCzvzA8csrFOMHNN4PAk,21019
102
102
  udata/core/dataset/commands.py,sha256=__hPAk_6iHtgMnEG51ux0vbNWJHxUjXhi1ukH4hF5jY,3714
@@ -112,9 +112,9 @@ udata/core/dataset/permissions.py,sha256=zXQ6kU-Ni3Pl5tDtat-ZPupug9InsNeCN7xRLc2
112
112
  udata/core/dataset/preview.py,sha256=qXmd4-nKvIPtcKLrMqC-aJne4-vMIiq_NubpX39D6I0,855
113
113
  udata/core/dataset/rdf.py,sha256=KuVSS5EAZVBG8ZZhBVE9ZiXIuPGQsabRWN5WSLYJa4E,30911
114
114
  udata/core/dataset/recommendations.py,sha256=DlGSLU8D0nW6Ds1rjBav1WxC-0VW5yOCjkO5w-ltFcI,7171
115
- udata/core/dataset/search.py,sha256=6Lh6jjptvOLMZWdPAZ7US5-Kd-E12a2Weh2eVsMPe0E,5960
115
+ udata/core/dataset/search.py,sha256=0reOKadjjqeL9ujOAGfiVBFBX5lx7vHotDbvaWPaUN0,6068
116
116
  udata/core/dataset/signals.py,sha256=WN4sV-lJlNsRkhcnhoy0SYJvCoYmK_5QFYZd1u-h4gs,161
117
- udata/core/dataset/tasks.py,sha256=Fx1w3YtU8uXR6tSy7IYQQ8Bae54ROVvAObrJgbEiWwI,9655
117
+ udata/core/dataset/tasks.py,sha256=q4T_71NHmxOg-pfgouiiGm3L577rn9nGBBRf6sMF7zM,9556
118
118
  udata/core/dataset/transport.py,sha256=ihCXirY1dZjOfXKbf9HRCJTfIOc75rM1McwbeGjsW6A,1296
119
119
  udata/core/discussions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
120
120
  udata/core/discussions/actions.py,sha256=kjdBLDIeu0yWTSxQGgOpN1WoxUqbMygn4SiBk_S9T5I,1051
@@ -196,7 +196,7 @@ udata/core/reuse/models.py,sha256=qlvf6eFHgaQMECa2rDKEfGvu8FOjhrkKrtQYC_GLb8Q,89
196
196
  udata/core/reuse/permissions.py,sha256=j-ancS7gvLl5vJu0TNYqpYD-2So-UzoDE4IHLxRoMGg,621
197
197
  udata/core/reuse/search.py,sha256=y1DwXYkBMBwuhn62CULkU1NNo89IYp0Ae7U01jcnjBY,3137
198
198
  udata/core/reuse/signals.py,sha256=nDrEUpYKN0AdYiEbrR0z3nzXzjaRcD8SAMutwIDsQPM,155
199
- udata/core/reuse/tasks.py,sha256=oyi6SGNfCKRLLuS-tLUCs_jcfa43jOn4Wuzq65Vnj8A,1529
199
+ udata/core/reuse/tasks.py,sha256=cc6f06HMFCDHRsdgsG09FBYsITNQ8xzdZjE-pMY61a0,1688
200
200
  udata/core/site/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
201
201
  udata/core/site/api.py,sha256=N_3vthEY_bYeYgs1cOYp9n4mFyuSx7UK0COPoSNZDm8,7546
202
202
  udata/core/site/factories.py,sha256=O0nLFmjrFyemzcs-YwNukq5nqd383KBGrgL5bOQsGbA,378
@@ -238,15 +238,16 @@ udata/core/tags/csv.py,sha256=lfFGt596-f_rdBedhVqZLZHdW69pDfcU2_YTFcXjmWM,290
238
238
  udata/core/tags/models.py,sha256=xzBoNwqBG5A5Ou83DWT858ccbTCkNnim_xBWgy1oyz4,550
239
239
  udata/core/tags/tasks.py,sha256=QBIhdubFxTzYgKxR2BdpD7yAEvaemOpt_G19OuzQvZE,952
240
240
  udata/core/tags/views.py,sha256=gFbUmLDkv1uDvxPRCPTZBq0TBknEckbNTPKr8WrZMAM,380
241
- udata/core/topic/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
241
+ udata/core/topic/__init__.py,sha256=ukZuuCjuQNEPxiw1jkphohAVJtdDqWGDi-cAb2QdpRo,23
242
242
  udata/core/topic/activities.py,sha256=Pcqhs-OxmSV2NlN18GyV12z9AW8tfS8glgwwmchcbpQ,1022
243
- udata/core/topic/api.py,sha256=j3h-iBjfczWHGVEd5_vhIwN00ytOBREuqKZ-ejS_T5Y,5313
244
- udata/core/topic/apiv2.py,sha256=SeWyRlQZ-vCYrFIpdG7tti1fyR1bXN1CT0DsjURXjIY,10276
245
- udata/core/topic/factories.py,sha256=RpUpwLd2gYwwS0vc7FcbQ-4tC0FSsAg7O8bPgozYKgE,684
246
- udata/core/topic/forms.py,sha256=NGC_k6PRw8uswEHaXW1Q3ih_2sx2-dNUY--LD-me80Y,973
247
- udata/core/topic/models.py,sha256=IWDDXBnk38iMd3Hm3G4ZKxipqEYcRGRfoq3VuxsZOqM,2417
248
- udata/core/topic/parsers.py,sha256=ugkBd-w8TewInqowNF2w36UPwKYMYluK4U-grkAu-wg,2411
243
+ udata/core/topic/api_fields.py,sha256=KMJ27v4u-hOLJYY7gV2gnXfAPxcUWkQasOkcqTZTAbk,3324
244
+ udata/core/topic/apiv2.py,sha256=RyJIA9UEMURyyuh4gt_yHkAxIM2OwUroGctp-1PVk94,6393
245
+ udata/core/topic/factories.py,sha256=6UYvt4Rf0dxP1pec1ySQySiq82A58VN0uo-7mnbFnuw,2767
246
+ udata/core/topic/forms.py,sha256=3eYdFVcA3YSNaILnk65uOHtXKA6ngy4IMgDibr_hkzk,2993
247
+ udata/core/topic/models.py,sha256=FdNJViwPNoPNfSdcvcCxI_dbQ71zdaj4wF9lRuGhd3I,3755
248
+ udata/core/topic/parsers.py,sha256=leQtzLtEIV-0lCu_ibsygJoE2e6qAWzpDPer4BhPPjM,3878
249
249
  udata/core/topic/permissions.py,sha256=RtFPPlxuU_Bv7ip6LDO4AoPrKFnIOEs9cCMXaSSmEdk,118
250
+ udata/core/topic/tasks.py,sha256=_OrPfuZ9rKENp4p4IkoyV-Yqp9bxI3nNxhpfKrbgl-w,357
250
251
  udata/core/user/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
251
252
  udata/core/user/activities.py,sha256=d91G45XEgoxYUJetkSjVolSM-nqmNSuM5b-6geayGE4,3338
252
253
  udata/core/user/api.py,sha256=Ld0o7ERMYNNTT6wQu9QEQgEng3CmwikyZj9YVj7DTgU,13474
@@ -286,7 +287,7 @@ udata/features/transfer/models.py,sha256=sFmdbEHL7eUxYe2XdtjZ2zhrUWOW_ryP_5T_8N1
286
287
  udata/features/transfer/notifications.py,sha256=jeH5buqTuWcokgXfEj-EZ7C3YCrtw-NikfrH2bqFyHM,1121
287
288
  udata/features/transfer/permissions.py,sha256=0Iwt_I3S3QACpq4Ba6Ovb8RUBuozj2pbXDtFFp9jdLI,953
288
289
  udata/forms/__init__.py,sha256=OXNShgt05tADLYQ-cXPdB16qQtj2i48GxSsCVdR6cfI,843
289
- udata/forms/fields.py,sha256=Wzf2FDLPkQcrUWvf8vqT0putvrFPu7kA3jREdSPPA_0,29689
290
+ udata/forms/fields.py,sha256=UezHtGuuYsk0FWFpmztWXlPUB4Wf1Rf9IX9ANM796l0,30016
290
291
  udata/forms/validators.py,sha256=CRgmB6oow5O8LDR45LajlJJ9HX3RBCI08fapoWMH1vo,2727
291
292
  udata/forms/widgets.py,sha256=XMVxBlQMGfb0nQvqwLMsAVcEdsBdaZGQZ82F81FdmlM,1332
292
293
  udata/frontend/__init__.py,sha256=JvHfZSLZ-6j38NV7ci47IoJY1FNnzAhPbG0Q40DSt3s,6882
@@ -305,7 +306,7 @@ udata/harvest/signals.py,sha256=3AhFHMPIFH5vz01NX5ycR_RWH14MXFWnCT6__LSa-QI,1338
305
306
  udata/harvest/tasks.py,sha256=id5YmHIhnkgez0LVC1fNg_6Yz1Sp0jrvQ1caslVOWdY,1722
306
307
  udata/harvest/backends/__init__.py,sha256=QjoFfBJfpw_xgk5YYWI1SgKJOMEmTMlxSfW79GNkSTI,459
307
308
  udata/harvest/backends/base.py,sha256=2wyfw83e3xGQcHnQI-z26g1dg-uVtWcDgzsBk7iGX3Y,17480
308
- udata/harvest/backends/dcat.py,sha256=rhqHyAS8zyRI5oHtUZkbELA4H1I4DVY0yuu_5NtL_Bg,18203
309
+ udata/harvest/backends/dcat.py,sha256=Qa4lRoLaTMRS9OFlCyKfQXGQ2rEQf0VomqzsL14L03g,19432
309
310
  udata/harvest/backends/maaf.py,sha256=N7ty8ZWO9pfKPtZRk1wTaJ5pY6qi-0-GtF1p8jiYiY4,8102
310
311
  udata/harvest/backends/maaf.xsd,sha256=vEyG8Vqw7Yn_acjRdXjqUJgxOj4pv8bibep-FX-f3BQ,18322
311
312
  udata/harvest/backends/ckan/__init__.py,sha256=JE7Qa7kX7Yd8OvmJnAO_NupZe0tqYyhhkgJ-iGNxX64,35
@@ -319,7 +320,7 @@ udata/harvest/tests/person.jsonld,sha256=I7Ynh-PQlNeD51I1LrCgYOEjhL-WBeb65xzIE_s
319
320
  udata/harvest/tests/test_actions.py,sha256=oXNTwDuSHtlVANRcsNyq3J33u4XU_jM9o67FbZjLCys,24860
320
321
  udata/harvest/tests/test_api.py,sha256=gSuICkPy3KVRUhHAyudXVf_gLwiB7SoriUp3DLXWDdA,21611
321
322
  udata/harvest/tests/test_base_backend.py,sha256=ow8ecGtD836mUqyPWYjkS5nx0STyT5RMLgBdDyOhts4,19233
322
- udata/harvest/tests/test_dcat_backend.py,sha256=I8D6nKVYCXmS-pJb0OoeROtUXFI4Ua3HPO_VI0j-vZA,43836
323
+ udata/harvest/tests/test_dcat_backend.py,sha256=H1nx820EuI3GXJGhrbhRhkjBsQvsfYoO0olJyVT2LsA,48166
323
324
  udata/harvest/tests/test_filters.py,sha256=PT2qopEIoXsqi8MsNDRuhNH7jGXiQo8r0uJrCOUd4aM,2465
324
325
  udata/harvest/tests/test_models.py,sha256=f9NRR2_S4oZFgF8qOumg0vv-lpnEBJbI5vNtcwFdSqM,831
325
326
  udata/harvest/tests/test_notifications.py,sha256=MMzTzkv-GXMNFeOwAi31rdTsAXyLCLOSna41zOtaJG0,816
@@ -388,6 +389,8 @@ udata/migrations/2025-01-05-dataservices-fields-changes.py,sha256=HlqHg3sG3rk3sY
388
389
  udata/migrations/2025-03-20-save-quality-for-datasets.py,sha256=FPTfGVByXSHr18V4RFlktC7t-H-5rgEcZQMTRpMrGqo,607
389
390
  udata/migrations/2025-04-24-topic-featured-default-false.py,sha256=t4OyhehtPQiosKtAo9SWRWm3ObGUHvqD_roXQ34vIH4,369
390
391
  udata/migrations/2025-05-22-purge-duplicate-activities.py,sha256=iemQwEWtbxedtpkeTFIeoNP7WcY7ntnDrjUClPzzWfg,4212
392
+ udata/migrations/2025-05-26-migrate-topics-to-elements.py,sha256=fc1XdIDKPs3r6aJUqpK52CvnKaekfxSMO6XitvRn_j0,1998
393
+ udata/migrations/2025-06-02-delete-topic-name-index.py,sha256=hqUarnHFFdFDhjblZPabmcv09V25oOCwLPEd_17hYsI,400
391
394
  udata/migrations/2025-06-18-clean-spatial-coverages.py,sha256=aKg9HQwCmHDJSXAGD02w0bjTvauUrFU_FEtrMeyLMcA,683
392
395
  udata/migrations/2025-07-18-compute-last-update.py,sha256=K3wSSl9oC8TRbHlvgKeekgPB9fMMVgll1NXtxGUiNyI,680
393
396
  udata/migrations/2025-07-18-redo-count-discussion.py,sha256=BOFTjf0zq_ahnVlYQC-d8fuoLixxyk2vP6JYJXhmvbs,941
@@ -470,8 +473,8 @@ udata/static/admin.css,sha256=gPM7oSehylBXQXyv0-gQ1LuyJiI1STQ_swM4CHjq_cs,185748
470
473
  udata/static/admin.css.map,sha256=dzFd_AL3pQPFiww5oRwqnubDGJ9HNtYuAaiggLTjjB0,627543
471
474
  udata/static/admin.js,sha256=iQnNCFKqwiSIMyJIeDBAD_gEwv8fABrzK5CoK3PZZME,1330409
472
475
  udata/static/admin.js.map,sha256=09cK62bu_h0M4ajLf-Y2-sQCUFYPWKRw1PCQWQvfQyM,8518351
473
- udata/static/common.js,sha256=UNzKlONvL59dK3c7TX-cvk_9ypFu4KxEmluNTc4ggQE,2252
474
- udata/static/common.js.map,sha256=bLIoaHyqssIqlyk2dXEZEUzmpFl58bcoAnl9CqpXmNI,14137
476
+ udata/static/common.js,sha256=ZOT3mSuhbPQBJfXkdFeJ5Mwof1MDEpKwVLmIE0q1Yj0,2252
477
+ udata/static/common.js.map,sha256=fUEgdR5QnV_hfo6YBRQCwa-NU6XCNQ1ZYx_TZKfyG5w,14137
475
478
  udata/static/fontawesome-webfont.eot,sha256=e_yrbbmdXPvxcFygU23ceFhUMsxfpBu9etDwCQM7KXk,165742
476
479
  udata/static/fontawesome-webfont.svg,sha256=rWFXkmwWIrpOHQPUePFUE2hSS_xG9R5C_g2UX37zI-Q,444379
477
480
  udata/static/fontawesome-webfont.ttf,sha256=qljzPyOaD7AvXHpsRcBD16msmgkzNYBmlOzW1O3A1qg,165548
@@ -490,20 +493,20 @@ udata/static/chunks/1.0a96f54313c89e541ccb.js,sha256=A-lYXUeTLFOd_al9J_EpYMsbJZR
490
493
  udata/static/chunks/1.0a96f54313c89e541ccb.js.map,sha256=Z4uWu-Bwj4JnQ49hqzkbRrfbtRUm65X93JQyDV6aLTM,1741737
491
494
  udata/static/chunks/10.471164b2a9fe15614797.js,sha256=sZ7HhLG8c-gdmtSlZHmjt7-vtu0AIGy89qZmAduSEyM,414740
492
495
  udata/static/chunks/10.471164b2a9fe15614797.js.map,sha256=qmVKIeXYE9_GW-vnDrt0oj0KbUXURInBUvc9i6mZRuo,2736059
493
- udata/static/chunks/11.51d706fb9521c16976bc.js,sha256=7vyFwTUxeDitXti-Nm29VxQfCphUgO5i9cQwdbztJJg,395562
494
- udata/static/chunks/11.51d706fb9521c16976bc.js.map,sha256=Bu6vERhr4jiQ6PRN53Ynh8wME5stIE1SC794VSsINrs,2268951
496
+ udata/static/chunks/11.822f6ccb39c92c796d13.js,sha256=-TQiPAFdVoJCJTMixRPbDZGqE_foggEP5Ss7I4WpeHI,395562
497
+ udata/static/chunks/11.822f6ccb39c92c796d13.js.map,sha256=3phLOvJp-zaUY1X4U68YgMFSVR49b_ovjd1vjVSL828,2268951
495
498
  udata/static/chunks/12.1be61e0201691821bff6.js,sha256=oveRcMtBsi97LUeAX86LjSAEVIpNxfWGHVovetKfPTw,421097
496
499
  udata/static/chunks/12.1be61e0201691821bff6.js.map,sha256=ikkgGwMdOXW4ZXyucmqrxLqJQHIcXJJoMMNt01QFrZM,2442221
497
- udata/static/chunks/13.f29411b06be1883356a3.js,sha256=QbmoNI_MwccyLEaOLPe4KyWDA5mrQRrRaGd9Z72zQp0,420590
498
- udata/static/chunks/13.f29411b06be1883356a3.js.map,sha256=dB1whN7IEM_S4baXdZTTOBnXTGuzdB3ZCT9xbQK5sao,2430624
500
+ udata/static/chunks/13.d9c1735d14038b94c17e.js,sha256=QVscBipWMC9Md3G5mvxJ0Ttp2a_kq9CUrScayDf-DKQ,420590
501
+ udata/static/chunks/13.d9c1735d14038b94c17e.js.map,sha256=h3Gf_NXW-92D3fAPWhWqreisjA81it3Cek_BR1gwpOY,2430624
499
502
  udata/static/chunks/14.bc3f6bc0a67517e7b30f.js,sha256=SLlPbF5r7gOcZKPibWUh5BmsKF1jN8FwOUbiZ8i76EU,290368
500
503
  udata/static/chunks/14.bc3f6bc0a67517e7b30f.js.map,sha256=3Lg42qlM8-ho4unygukS9WvltNoIDJkMuTP7erZmYEI,1636918
501
504
  udata/static/chunks/15.2f5d8e3d4aa4c46188d7.js,sha256=gcYH_y6xCl3LbMKg_epxR5IntnEk7X119Evs9up1i7Q,138967
502
505
  udata/static/chunks/15.2f5d8e3d4aa4c46188d7.js.map,sha256=RPoT4EwQaWz3-puzfSV9kx511PK7RYPmveQFImM2BgA,702620
503
506
  udata/static/chunks/16.aaa39ef2d7e82594efc8.js,sha256=1J9T7hgzq1culb_vcXcRvMwt59pJx5Yv-oTU8mUoQDs,228559
504
507
  udata/static/chunks/16.aaa39ef2d7e82594efc8.js.map,sha256=Oc67ghT4gTY2r8H_cfy3tS6o-WyjvXkVc4xXqq0yBcQ,1574395
505
- udata/static/chunks/17.3bd0340930d4a314ce9c.js,sha256=GWiultMJSKhkUkGbVAcSGUe1wg_AGWfgGmtb7HcH_eI,236702
506
- udata/static/chunks/17.3bd0340930d4a314ce9c.js.map,sha256=2vbovBs6N5jhEwnxLB4jTyZYgvsdG_KS7p9_ILBJ46w,1289996
508
+ udata/static/chunks/17.81c57c0dedf812e43013.js,sha256=M1V_pkNZWVlgT1jGryWe5cOBp2r9LiIJEyHuKkQTPGA,236702
509
+ udata/static/chunks/17.81c57c0dedf812e43013.js.map,sha256=xx4zs3EBZKfoouMTgh6Xb7q1OlEqzDyeeGtv5pWknFg,1289996
507
510
  udata/static/chunks/18.56444ebd2456a4ba2201.js,sha256=o78S_10_0k6kL0HbpDlbKZ5tZ-DCe6Y9XBex-SFS_s4,50384
508
511
  udata/static/chunks/18.56444ebd2456a4ba2201.js.map,sha256=Xdv5UJ1TG-LZIlUjZm-yv59KA1omSq2dr8Ukfec46UE,277805
509
512
  udata/static/chunks/19.ba0bb2baa40e899d440b.js,sha256=ESwFM9065ZNvuifusnl5vmGgHulP6RxBdqibRyXQIT0,203418
@@ -544,8 +547,8 @@ udata/static/chunks/6.92d7c2ec6d20005774ef.js,sha256=eXj-jYWDzaarjd9Po3yyvn7LzrK
544
547
  udata/static/chunks/6.92d7c2ec6d20005774ef.js.map,sha256=pMOAT-eXv1-ZmX7znOM6g4XayThbbgmoJWq37YXuWWo,3783190
545
548
  udata/static/chunks/7.896bbffe39433bb598f7.js,sha256=C1NrGe6wrptQFYCCmITtx12dGqfaO7136-9BD6m05Ts,157150
546
549
  udata/static/chunks/7.896bbffe39433bb598f7.js.map,sha256=aZB8qYRkX4oqSugjG69tMlv64YIW5LPXF_8uACMHMTw,813014
547
- udata/static/chunks/8.b966402f5d680d4bdf4a.js,sha256=7Hq8-lE7FGVS2IFhvdS34wIqAEJVaHTMtYKoQ7C5zwM,222856
548
- udata/static/chunks/8.b966402f5d680d4bdf4a.js.map,sha256=-yRBjA6nFGHyjrxrX6glZT04Vak-HXcEw3KHmXKxu5o,1205076
550
+ udata/static/chunks/8.0f42630e6d8ff782928e.js,sha256=LVQ9LUV4GkfCx3EbPTDjQfFFA0A0vn5TNLFn5r8FxFI,222856
551
+ udata/static/chunks/8.0f42630e6d8ff782928e.js.map,sha256=dOD3Yyy9ee1RfkxMW392HNEHOD5mGkBLWTuC25JaX7M,1205076
549
552
  udata/static/chunks/9.07515e5187f475bce828.js,sha256=mJ8H3nJBaPXY1-hxWPdOD8-hQwP3k6prsfPwf_5wuas,416716
550
553
  udata/static/chunks/9.07515e5187f475bce828.js.map,sha256=7cfRtXVGvJwrNXWVE8xaLjvQQoy9xgR6fIOmlPDJSDA,2746303
551
554
  udata/storage/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -646,7 +649,7 @@ udata/tests/test_rdf.py,sha256=XlUjRFcvTeZx1DTwwHL4pHQTcFDcAuQzaGOY_jJMDL4,4863
646
649
  udata/tests/test_routing.py,sha256=jtCZuT229WhGvJU843DtzIrdUXN5f7dym-hwz5dOFLo,10844
647
650
  udata/tests/test_storages.py,sha256=OG_PnKtPlZmmhKnbbLrvL-EMEg35wAMsTC76jVEAOLU,9602
648
651
  udata/tests/test_tags.py,sha256=y8x17-m_opa8YKjOWU60Xz6FR20FpBz61e7JJeyTwzM,3748
649
- udata/tests/test_topics.py,sha256=XDRoSJbSc0s0dHNDC4-4WB4shhxxf_8nHhG6LkRbgmI,2045
652
+ udata/tests/test_topics.py,sha256=YcD2NNqB2R4A5uZF5DG1MyumtsZmTE-wceo1R40U7cI,2432
650
653
  udata/tests/test_transfer.py,sha256=_0pBwYs3T7OSZ7bO3KmQ81SjwCJyT4EVf8YYHXOkwdk,7779
651
654
  udata/tests/test_uris.py,sha256=MxafZ0SyzSNRomVpZnH1ChzWaHOi1MQiXe1gmKnBc6o,8517
652
655
  udata/tests/test_utils.py,sha256=3BGnlvw-GOE6tLHQteo-uUeYuzq4rsjePOuytFGkpOg,7967
@@ -656,7 +659,7 @@ udata/tests/api/test_auth_api.py,sha256=OMRlY0OQt60j5N4A-N3HdWTuffOjRlFHkz5a3jJF
656
659
  udata/tests/api/test_base_api.py,sha256=2w_vz0eEuq3P3aN-ByvxGc3VZAo7XtgatFfcrzf2uEU,2244
657
660
  udata/tests/api/test_contact_points.py,sha256=Sbb486RTN7HVycna_XB60OnURPSNc7xUity26XsYA4k,8766
658
661
  udata/tests/api/test_dataservices_api.py,sha256=PGl-817qFAHXmIjb3qzpFzp7sVXSq8gwEzG-g01Qnn8,31025
659
- udata/tests/api/test_datasets_api.py,sha256=R4xX1wNTCwA97XUrVHgPwdPPRXICVCrzSknW9PU1V68,101118
662
+ udata/tests/api/test_datasets_api.py,sha256=tq7Yob-KkDmxpcfMSWxMsj-M24CBDa0C_9AxjeLc4eA,101193
660
663
  udata/tests/api/test_fields.py,sha256=OW85Z5MES5HeWOpapeem8OvR1cIcrqW-xMWpdZO4LZ8,1033
661
664
  udata/tests/api/test_follow_api.py,sha256=4nFXG5pZ_Hf2PJ4KEdHJX_uggjc9RpB8v0fidkAcw9I,5792
662
665
  udata/tests/api/test_me_api.py,sha256=YPd8zmR3zwJKtpSqz8nY1nOOMyXs66INeBwyhg5D0Us,13846
@@ -665,15 +668,14 @@ udata/tests/api/test_reports_api.py,sha256=fCSz9NwMXBs6cxdXBVVI6y564AtovmZYw3xkg
665
668
  udata/tests/api/test_reuses_api.py,sha256=8yhs1y_EDzusSV86bb7M7V9-qw-Al1JFecLs33AR8GU,27225
666
669
  udata/tests/api/test_swagger.py,sha256=eE6La9qdTYTIUFevRVPJgtj17Jq_8uOlsDwzCNR0LL8,760
667
670
  udata/tests/api/test_tags_api.py,sha256=36zEBgthVEn6pctJ0kDgPmEaUr-iqRAHeZRcRG2LEXQ,2425
668
- udata/tests/api/test_topics_api.py,sha256=rnOpMn3BQ5fKVzaBTRzhOKcnwNJe7hiDIEIe2fUXRLk,12320
669
671
  udata/tests/api/test_transfer_api.py,sha256=-OLv-KjyLZL14J8UHl-ak_sYUj6wFiZWyoXC2SMXmEQ,7503
670
672
  udata/tests/api/test_user_api.py,sha256=hfDHOv5F81tehbc5u3dYH5rAyYgzgHGCWVcGR3kLIZw,16591
671
673
  udata/tests/apiv2/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
672
674
  udata/tests/apiv2/test_datasets.py,sha256=5HYB3UWWKRsIoLx007ZJ1Bx0IU7YzK-_z8VtoM2ZxXw,22659
673
- udata/tests/apiv2/test_me_api.py,sha256=RAgu5iKGB3Pp8cDN-427ovly-VOz5MTL4GpPZ1NcVXI,1418
675
+ udata/tests/apiv2/test_me_api.py,sha256=WgUjujSnIlISUkM5t-lfg-D0mmz-eX1hSsSwjuxqbJg,1417
674
676
  udata/tests/apiv2/test_organizations.py,sha256=os_43s-coSRqjgY-5fAjSiRlB3g2685u7d-Es0aOhks,6390
675
677
  udata/tests/apiv2/test_swagger.py,sha256=RKedaq-2UeyEuxlmUaAN7pmEe-lQYYmpDUVc8HF3CH4,785
676
- udata/tests/apiv2/test_topics.py,sha256=KwWAMta-C_MgwxBOwfUuPqxkO--SHvvth_c9VFGt2zA,11644
678
+ udata/tests/apiv2/test_topics.py,sha256=CJPzcYoMUxiZmxLNYhmd9BxQ8kEzecJXTeq0LddzU0Y,25669
677
679
  udata/tests/cli/test_cli_base.py,sha256=0a3U_5ROp1lCTG8d6TpCjF4nbKVNerAeLO0VxU-NTUk,321
678
680
  udata/tests/cli/test_db_cli.py,sha256=xFVHQAk2bmQQzFr31TK2JThOP6p0wvxzexMhM_IcdME,2219
679
681
  udata/tests/contact_point/test_contact_point_models.py,sha256=b8vraZPPrs9LeQMWLnOCrpI02sXMEM_BcMJXKTeAuAw,923
@@ -690,7 +692,7 @@ udata/tests/dataset/test_dataset_events.py,sha256=hlrpoOiBbnX_COUI9Pzdqlp45GZZDq
690
692
  udata/tests/dataset/test_dataset_model.py,sha256=nxAE7SH9HZEHWsNSFwclfxQbS7XN5gvv_D93KlDTW04,35474
691
693
  udata/tests/dataset/test_dataset_rdf.py,sha256=EM8n5itELqFe0wmYfav6LTNQjBLKMW4KDWOUf-2_K3c,45110
692
694
  udata/tests/dataset/test_dataset_recommendations.py,sha256=K52HXGXi9DuUSiSRQWpqTrsFCkYbv7K3upNp0fFp5v8,7068
693
- udata/tests/dataset/test_dataset_tasks.py,sha256=n1W2Pg0ez02d66zQG3N93kh7dpR2yLMRDqUI6PnPaI0,3088
695
+ udata/tests/dataset/test_dataset_tasks.py,sha256=SwSv-hDSXgs1xXtvtaePQ6fa6_d4ZpHo-oahDRinvPg,3271
694
696
  udata/tests/dataset/test_resource_preview.py,sha256=AxSF8cnG6bhy2pz9Fi3PfEzdLlNhZ0xrp9dr6yrt31A,2051
695
697
  udata/tests/dataset/test_transport_tasks.py,sha256=BYr1WPV0Crirzb2jC_wAV4y_pzImRCAS4zYZ7qvCDeY,2964
696
698
  udata/tests/features/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -729,9 +731,9 @@ udata/tests/organization/test_organization_rdf.py,sha256=Uf-OgXV615wLUHfcBTmp9QF
729
731
  udata/tests/organization/test_organization_tasks.py,sha256=9Ta-f4R3RoKdARYUFWHO4pE1nijceTHzyEvI34lYBJo,2876
730
732
  udata/tests/reuse/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
731
733
  udata/tests/reuse/test_reuse_model.py,sha256=PtdC39JrDCtF9iSfYSH98115309Q-E8aKn4s6rZCqCY,4662
732
- udata/tests/reuse/test_reuse_task.py,sha256=4gMsKHjGafb6kpRKnqF167Htd-Ff0tRD4iQajW1e_lg,1380
734
+ udata/tests/reuse/test_reuse_task.py,sha256=VHu9WfpBZ7cIdEb_DJxS0jcnhIUGrtNYwcysmnRNkcU,1725
733
735
  udata/tests/search/__init__.py,sha256=ub8kS6vG9EjzkJ-9sAR7j1eLSYpud1Gzry4MQ8fpgxM,1493
734
- udata/tests/search/test_adapter.py,sha256=mi-M53JQSPYxU8ahkqtfyIrIyhz_cC_ATdLbWWa3onM,6941
736
+ udata/tests/search/test_adapter.py,sha256=4Sh8T-a8TYRMWUNe93WkVOy2b5q7i5hvjFUjXbX3UZw,8648
735
737
  udata/tests/search/test_query.py,sha256=aFZKFTJjlih5csy3eNp4MxL5hg13NqiIsrS5bCTOLrI,2182
736
738
  udata/tests/search/test_results.py,sha256=vHMkywoW6SQKGy5OtCriYpSo-KbVEdjVzOf8un2mjZE,2043
737
739
  udata/tests/site/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -740,6 +742,7 @@ udata/tests/site/test_site_csv_exports.py,sha256=hrUthkJw8yoSpEZNDHfzZIMEoXSBFos
740
742
  udata/tests/site/test_site_metrics.py,sha256=KxlilOUeAbBta7HwD4mB4ybDWBmRB-3UVrLunvRGoGg,2362
741
743
  udata/tests/site/test_site_model.py,sha256=CNE-jP48guJpRlh4D3rQGruu2hSRliQaLOnBmzkHMnI,2181
742
744
  udata/tests/site/test_site_rdf.py,sha256=zlw7leYc7azfrC6JwDjKiy3wixQzTpo-lDOm-Dg_kXw,13092
745
+ udata/tests/topic/test_topic_tasks.py,sha256=mO1wTmO001q9qVQFTE5Yy6Lhc6UTvdbOw5rBOHaph8M,871
743
746
  udata/tests/user/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
744
747
  udata/tests/user/test_user_rdf.py,sha256=BRdv9ivLLUQoImFOuIohDoZAQXMXCruaNJ37siKul5o,1771
745
748
  udata/tests/user/test_user_tasks.py,sha256=n7pMKRjkP7mtf-3nK9jaPC0VjM7EGJuxxPBkIXiJXgI,5573
@@ -763,9 +766,9 @@ udata/translations/pt/LC_MESSAGES/udata.mo,sha256=U0abG-nBwCIoYxRZNsc4KOLeIRSqTV
763
766
  udata/translations/pt/LC_MESSAGES/udata.po,sha256=eCG35rMzYLHXyLbsnLSexS1g0N_K-WpNHqrt_8y6I4E,48590
764
767
  udata/translations/sr/LC_MESSAGES/udata.mo,sha256=IBcCAdmcvkeK7ZeRBNRI-wJ0jzWNM0eXM5VXAc1frWI,28692
765
768
  udata/translations/sr/LC_MESSAGES/udata.po,sha256=yFxHEEB4behNwQ7JnyoYheiCKLNnMS_NV4guzgyzWcE,55332
766
- udata-10.9.1.dev37462.dist-info/LICENSE,sha256=V8j_M8nAz8PvAOZQocyRDX7keai8UJ9skgmnwqETmdY,34520
767
- udata-10.9.1.dev37462.dist-info/METADATA,sha256=79i8fh1td_WOPrh2iAFJ4QsGcJLN2kzMofmzg8Ottx8,154704
768
- udata-10.9.1.dev37462.dist-info/WHEEL,sha256=Kh9pAotZVRFj97E15yTA4iADqXdQfIVTHcNaZTjxeGM,110
769
- udata-10.9.1.dev37462.dist-info/entry_points.txt,sha256=v2u12qO11i2lyLNIp136WmLJ-NHT-Kew3Duu8J-AXPM,614
770
- udata-10.9.1.dev37462.dist-info/top_level.txt,sha256=39OCg-VWFWOq4gCKnjKNu-s3OwFlZIu_dVH8Gl6ndHw,12
771
- udata-10.9.1.dev37462.dist-info/RECORD,,
769
+ udata-10.9.1.dev37604.dist-info/LICENSE,sha256=V8j_M8nAz8PvAOZQocyRDX7keai8UJ9skgmnwqETmdY,34520
770
+ udata-10.9.1.dev37604.dist-info/METADATA,sha256=NfXyG49jFG3mtFK41jVQ3MfRAAzPnDHrFt5afWY9l_g,154939
771
+ udata-10.9.1.dev37604.dist-info/WHEEL,sha256=Kh9pAotZVRFj97E15yTA4iADqXdQfIVTHcNaZTjxeGM,110
772
+ udata-10.9.1.dev37604.dist-info/entry_points.txt,sha256=v2u12qO11i2lyLNIp136WmLJ-NHT-Kew3Duu8J-AXPM,614
773
+ udata-10.9.1.dev37604.dist-info/top_level.txt,sha256=39OCg-VWFWOq4gCKnjKNu-s3OwFlZIu_dVH8Gl6ndHw,12
774
+ udata-10.9.1.dev37604.dist-info/RECORD,,
udata/core/topic/api.py DELETED
@@ -1,145 +0,0 @@
1
- import mongoengine
2
- from flask import url_for
3
- from flask_security import current_user
4
-
5
- from udata.api import API, api, fields
6
- from udata.core.dataset.api_fields import dataset_fields
7
- from udata.core.discussions.models import Discussion
8
- from udata.core.organization.api_fields import org_ref_fields
9
- from udata.core.reuse.models import Reuse
10
- from udata.core.spatial.api_fields import spatial_coverage_fields
11
- from udata.core.topic.parsers import TopicApiParser
12
- from udata.core.topic.permissions import TopicEditPermission
13
- from udata.core.user.api_fields import user_ref_fields
14
-
15
- from .forms import TopicForm
16
- from .models import Topic
17
-
18
- DEFAULT_SORTING = "-created_at"
19
-
20
- ns = api.namespace("topics", "Topics related operations")
21
-
22
- topic_fields = api.model(
23
- "Topic",
24
- {
25
- "id": fields.String(description="The topic identifier"),
26
- "name": fields.String(description="The topic name", required=True),
27
- "slug": fields.String(description="The topic permalink string", readonly=True),
28
- "description": fields.Markdown(
29
- description="The topic description in Markdown", required=True
30
- ),
31
- "tags": fields.List(
32
- fields.String, description="Some keywords to help in search", required=True
33
- ),
34
- "datasets": fields.List(
35
- fields.Nested(dataset_fields),
36
- description="The topic datasets",
37
- attribute=lambda o: [d.fetch() for d in o.datasets],
38
- ),
39
- "reuses": fields.List(
40
- fields.Nested(Reuse.__read_fields__),
41
- description="The topic reuses",
42
- attribute=lambda o: [r.fetch() for r in o.reuses],
43
- ),
44
- "featured": fields.Boolean(description="Is the topic featured"),
45
- "private": fields.Boolean(description="Is the topic private"),
46
- "created_at": fields.ISODateTime(description="The topic creation date", readonly=True),
47
- "spatial": fields.Nested(
48
- spatial_coverage_fields, allow_null=True, description="The spatial coverage"
49
- ),
50
- "last_modified": fields.ISODateTime(
51
- description="The topic last modification date", readonly=True
52
- ),
53
- "organization": fields.Nested(
54
- org_ref_fields,
55
- allow_null=True,
56
- description="The publishing organization",
57
- readonly=True,
58
- ),
59
- "owner": fields.Nested(
60
- user_ref_fields, description="The owner user", readonly=True, allow_null=True
61
- ),
62
- "uri": fields.String(
63
- attribute=lambda t: url_for("api.topic", topic=t),
64
- description="The topic API URI",
65
- readonly=True,
66
- ),
67
- "extras": fields.Raw(description="Extras attributes as key-value pairs"),
68
- },
69
- mask="*,datasets{id,title,uri,page},reuses{id,title,image,image_thumbnail,uri,page}",
70
- )
71
-
72
- topic_page_fields = api.model("TopicPage", fields.pager(topic_fields))
73
-
74
- topic_parser = TopicApiParser()
75
-
76
-
77
- @ns.route("/", endpoint="topics")
78
- class TopicsAPI(API):
79
- """
80
- Warning: querying a list with a topic containing a lot of related objects (datasets, reuses)
81
- will fail/take a lot of time because every object is dereferenced. Use api v2 if you can.
82
- """
83
-
84
- @api.doc("list_topics")
85
- @api.expect(topic_parser.parser)
86
- @api.marshal_with(topic_page_fields)
87
- def get(self):
88
- """List all topics"""
89
- args = topic_parser.parse()
90
- topics = Topic.objects.visible_by_user(current_user, mongoengine.Q(private__ne=True))
91
- topics = topic_parser.parse_filters(topics, args)
92
- sort = args["sort"] or ("$text_score" if args["q"] else None) or DEFAULT_SORTING
93
- return topics.order_by(sort).paginate(args["page"], args["page_size"])
94
-
95
- @api.secure
96
- @api.doc("create_topic")
97
- @api.expect(topic_fields)
98
- @api.marshal_with(topic_fields)
99
- @api.response(400, "Validation error")
100
- def post(self):
101
- """Create a topic"""
102
- form = api.validate(TopicForm)
103
- return form.save(), 201
104
-
105
-
106
- @ns.route("/<topic:topic>/", endpoint="topic")
107
- @api.param("topic", "The topic ID or slug")
108
- @api.response(404, "Object not found")
109
- class TopicAPI(API):
110
- """
111
- Warning: querying a topic containing a lot of related objects (datasets, reuses)
112
- will fail/take a lot of time because every object is dereferenced. Use api v2 if you can.
113
- """
114
-
115
- @api.doc("get_topic")
116
- @api.marshal_with(topic_fields)
117
- def get(self, topic):
118
- """Get a given topic"""
119
- return topic
120
-
121
- @api.secure
122
- @api.doc("update_topic")
123
- @api.expect(topic_fields)
124
- @api.marshal_with(topic_fields)
125
- @api.response(400, "Validation error")
126
- @api.response(403, "Forbidden")
127
- def put(self, topic):
128
- """Update a given topic"""
129
- if not TopicEditPermission(topic).can():
130
- api.abort(403, "Forbidden")
131
- form = api.validate(TopicForm, topic)
132
- return form.save()
133
-
134
- @api.secure
135
- @api.doc("delete_topic")
136
- @api.response(204, "Object deleted")
137
- @api.response(403, "Forbidden")
138
- def delete(self, topic):
139
- """Delete a given topic"""
140
- if not TopicEditPermission(topic).can():
141
- api.abort(403, "Forbidden")
142
- # Remove discussions linked to the topic
143
- Discussion.objects(subject=topic).delete()
144
- topic.delete()
145
- return "", 204