udata 10.3.2.dev34895__py2.py3-none-any.whl → 10.3.2.dev34905__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/core/topic/models.py +1 -1
- udata/core/topic/parsers.py +4 -0
- udata/migrations/2025-04-24-topic-featured-default-false.py +15 -0
- udata/tests/api/test_topics_api.py +13 -2
- udata/tests/apiv2/test_topics.py +13 -2
- {udata-10.3.2.dev34895.dist-info → udata-10.3.2.dev34905.dist-info}/METADATA +2 -2
- {udata-10.3.2.dev34895.dist-info → udata-10.3.2.dev34905.dist-info}/RECORD +11 -10
- {udata-10.3.2.dev34895.dist-info → udata-10.3.2.dev34905.dist-info}/LICENSE +0 -0
- {udata-10.3.2.dev34895.dist-info → udata-10.3.2.dev34905.dist-info}/WHEEL +0 -0
- {udata-10.3.2.dev34895.dist-info → udata-10.3.2.dev34905.dist-info}/entry_points.txt +0 -0
- {udata-10.3.2.dev34895.dist-info → udata-10.3.2.dev34905.dist-info}/top_level.txt +0 -0
udata/core/topic/models.py
CHANGED
|
@@ -21,7 +21,7 @@ class Topic(db.Document, Owned, db.Datetimed):
|
|
|
21
21
|
datasets = db.ListField(db.LazyReferenceField("Dataset", reverse_delete_rule=db.PULL))
|
|
22
22
|
reuses = db.ListField(db.LazyReferenceField("Reuse", reverse_delete_rule=db.PULL))
|
|
23
23
|
|
|
24
|
-
featured = db.BooleanField()
|
|
24
|
+
featured = db.BooleanField(default=False)
|
|
25
25
|
private = db.BooleanField()
|
|
26
26
|
extras = db.ExtrasField()
|
|
27
27
|
|
udata/core/topic/parsers.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
from bson.objectid import ObjectId
|
|
2
|
+
from flask_restx.inputs import boolean
|
|
2
3
|
|
|
3
4
|
from udata.api import api
|
|
4
5
|
from udata.api.parsers import ModelApiParser
|
|
@@ -20,6 +21,7 @@ class TopicApiParser(ModelApiParser):
|
|
|
20
21
|
self.parser.add_argument("granularity", type=str, location="args")
|
|
21
22
|
self.parser.add_argument("organization", type=str, location="args")
|
|
22
23
|
self.parser.add_argument("owner", type=str, location="args")
|
|
24
|
+
self.parser.add_argument("featured", type=boolean, location="args")
|
|
23
25
|
|
|
24
26
|
@staticmethod
|
|
25
27
|
def parse_filters(topics, args):
|
|
@@ -38,6 +40,8 @@ class TopicApiParser(ModelApiParser):
|
|
|
38
40
|
topics = topics.filter(spatial__zones=args["geozone"])
|
|
39
41
|
if args.get("granularity"):
|
|
40
42
|
topics = topics.filter(spatial__granularity=args["granularity"])
|
|
43
|
+
if args.get("featured") is not None:
|
|
44
|
+
topics = topics.filter(featured=args["featured"])
|
|
41
45
|
if args.get("organization"):
|
|
42
46
|
if not ObjectId.is_valid(args["organization"]):
|
|
43
47
|
api.abort(400, "Organization arg must be an identifier")
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This migration updates Topic.featured to False when it is None.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import logging
|
|
6
|
+
|
|
7
|
+
from udata.models import Topic
|
|
8
|
+
|
|
9
|
+
log = logging.getLogger(__name__)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def migrate(db):
|
|
13
|
+
log.info("Processing topics...")
|
|
14
|
+
count = Topic.objects(featured__exists=False).update(featured=False)
|
|
15
|
+
log.info(f"\tConverted {count} topics from `featured=None` to `featured=False`")
|
|
@@ -28,12 +28,13 @@ class TopicsAPITest(APITestCase):
|
|
|
28
28
|
private_topic = TopicFactory(private=True)
|
|
29
29
|
geozone_topic = TopicFactory(spatial=SpatialCoverageFactory(zones=[paca.id]))
|
|
30
30
|
granularity_topic = TopicFactory(spatial=SpatialCoverageFactory(granularity="country"))
|
|
31
|
+
featured_topic = TopicFactory(featured=True)
|
|
31
32
|
owner_topic = TopicFactory(owner=owner)
|
|
32
33
|
org_topic = TopicFactory(organization=org)
|
|
33
34
|
|
|
34
35
|
response = self.get(url_for("api.topics"))
|
|
35
36
|
self.assert200(response)
|
|
36
|
-
self.assertEqual(len(response.json["data"]),
|
|
37
|
+
self.assertEqual(len(response.json["data"]), 8)
|
|
37
38
|
|
|
38
39
|
response = self.get(url_for("api.topics", q="topic-for"))
|
|
39
40
|
self.assert200(response)
|
|
@@ -69,7 +70,7 @@ class TopicsAPITest(APITestCase):
|
|
|
69
70
|
|
|
70
71
|
response = self.get(url_for("api.topics", include_private="true"))
|
|
71
72
|
self.assert200(response)
|
|
72
|
-
self.assertEqual(len(response.json["data"]),
|
|
73
|
+
self.assertEqual(len(response.json["data"]), 8)
|
|
73
74
|
# we're not logged in, so the private topic does not appear
|
|
74
75
|
self.assertNotIn(str(private_topic.id), [t["id"] for t in response.json["data"]])
|
|
75
76
|
|
|
@@ -83,6 +84,16 @@ class TopicsAPITest(APITestCase):
|
|
|
83
84
|
self.assertEqual(len(response.json["data"]), 1)
|
|
84
85
|
self.assertIn(str(granularity_topic.id), [t["id"] for t in response.json["data"]])
|
|
85
86
|
|
|
87
|
+
response = self.get(url_for("api.topics", featured="true"))
|
|
88
|
+
self.assert200(response)
|
|
89
|
+
self.assertEqual(len(response.json["data"]), 1)
|
|
90
|
+
self.assertIn(str(featured_topic.id), [t["id"] for t in response.json["data"]])
|
|
91
|
+
|
|
92
|
+
response = self.get(url_for("api.topics", featured="false"))
|
|
93
|
+
self.assert200(response)
|
|
94
|
+
self.assertEqual(len(response.json["data"]), 7)
|
|
95
|
+
self.assertNotIn(str(featured_topic.id), [t["id"] for t in response.json["data"]])
|
|
96
|
+
|
|
86
97
|
response = self.get(url_for("api.topics", owner=owner.id))
|
|
87
98
|
self.assert200(response)
|
|
88
99
|
self.assertEqual(len(response.json["data"]), 1)
|
udata/tests/apiv2/test_topics.py
CHANGED
|
@@ -25,13 +25,14 @@ class TopicsAPITest(APITestCase):
|
|
|
25
25
|
private_topic = TopicFactory(private=True)
|
|
26
26
|
geozone_topic = TopicFactory(spatial=SpatialCoverageFactory(zones=[paca.id]))
|
|
27
27
|
granularity_topic = TopicFactory(spatial=SpatialCoverageFactory(granularity="country"))
|
|
28
|
+
featured_topic = TopicFactory(featured=True)
|
|
28
29
|
owner_topic = TopicFactory(owner=owner)
|
|
29
30
|
org_topic = TopicFactory(organization=org)
|
|
30
31
|
|
|
31
32
|
response = self.get(url_for("apiv2.topics_list"))
|
|
32
33
|
assert response.status_code == 200
|
|
33
34
|
data = response.json["data"]
|
|
34
|
-
assert len(data) ==
|
|
35
|
+
assert len(data) == 8
|
|
35
36
|
|
|
36
37
|
hateoas_fields = ["rel", "href", "type", "total"]
|
|
37
38
|
assert all(k in data[0]["datasets"] for k in hateoas_fields)
|
|
@@ -57,7 +58,7 @@ class TopicsAPITest(APITestCase):
|
|
|
57
58
|
|
|
58
59
|
response = self.get(url_for("api.topics", include_private="true"))
|
|
59
60
|
assert response.status_code == 200
|
|
60
|
-
assert len(response.json["data"]) ==
|
|
61
|
+
assert len(response.json["data"]) == 8
|
|
61
62
|
# we're not logged in, so the private topic does not appear
|
|
62
63
|
assert str(private_topic.id) not in [t["id"] for t in response.json["data"]]
|
|
63
64
|
|
|
@@ -71,6 +72,16 @@ class TopicsAPITest(APITestCase):
|
|
|
71
72
|
assert len(response.json["data"]) == 1
|
|
72
73
|
assert str(granularity_topic.id) in [t["id"] for t in response.json["data"]]
|
|
73
74
|
|
|
75
|
+
response = self.get(url_for("api.topics", featured="true"))
|
|
76
|
+
assert response.status_code == 200
|
|
77
|
+
assert len(response.json["data"]) == 1
|
|
78
|
+
assert str(featured_topic.id) in [t["id"] for t in response.json["data"]]
|
|
79
|
+
|
|
80
|
+
response = self.get(url_for("api.topics", featured="false"))
|
|
81
|
+
assert response.status_code == 200
|
|
82
|
+
assert len(response.json["data"]) == 7
|
|
83
|
+
assert str(featured_topic.id) not in [t["id"] for t in response.json["data"]]
|
|
84
|
+
|
|
74
85
|
response = self.get(url_for("api.topics", owner=owner.id))
|
|
75
86
|
assert response.status_code == 200
|
|
76
87
|
assert len(response.json["data"]) == 1
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: udata
|
|
3
|
-
Version: 10.3.2.
|
|
3
|
+
Version: 10.3.2.dev34905
|
|
4
4
|
Summary: Open data portal
|
|
5
5
|
Home-page: https://github.com/opendatateam/udata
|
|
6
6
|
Author: Opendata Team
|
|
@@ -141,7 +141,7 @@ It is collectively taken care of by members of the
|
|
|
141
141
|
|
|
142
142
|
## Current (in progress)
|
|
143
143
|
|
|
144
|
-
-
|
|
144
|
+
- feat(topics): add featured filter in API [#3301](https://github.com/opendatateam/udata/pull/3301)
|
|
145
145
|
|
|
146
146
|
## 10.3.1 (2025-04-29)
|
|
147
147
|
|
|
@@ -231,8 +231,8 @@ udata/core/topic/api.py,sha256=xVBp3EFOAEWQlt2CQvII9gq21qeIK048pSkh1uTmdBo,5472
|
|
|
231
231
|
udata/core/topic/apiv2.py,sha256=9-CdR-xcVp7yS7664PgRCsAthxg1VgpKgoAaVlEhF6k,10461
|
|
232
232
|
udata/core/topic/factories.py,sha256=RpUpwLd2gYwwS0vc7FcbQ-4tC0FSsAg7O8bPgozYKgE,684
|
|
233
233
|
udata/core/topic/forms.py,sha256=NGC_k6PRw8uswEHaXW1Q3ih_2sx2-dNUY--LD-me80Y,973
|
|
234
|
-
udata/core/topic/models.py,sha256=
|
|
235
|
-
udata/core/topic/parsers.py,sha256=
|
|
234
|
+
udata/core/topic/models.py,sha256=X-jScC_mMNdZp0hQ_SD-NBHsIPS8aYqpq99x6l4dKz4,2052
|
|
235
|
+
udata/core/topic/parsers.py,sha256=ugkBd-w8TewInqowNF2w36UPwKYMYluK4U-grkAu-wg,2411
|
|
236
236
|
udata/core/topic/permissions.py,sha256=RtFPPlxuU_Bv7ip6LDO4AoPrKFnIOEs9cCMXaSSmEdk,118
|
|
237
237
|
udata/core/user/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
238
238
|
udata/core/user/activities.py,sha256=x-mSiwx7TzM2ci6KMkMiNx0sFs8J3LTJNbigtE8cA0s,2807
|
|
@@ -363,6 +363,7 @@ udata/migrations/2024-11-19-keep-only-local_authority-if-also-public_service-org
|
|
|
363
363
|
udata/migrations/2024-12-05-contact-point-is-now-a-list.py,sha256=il2qSFhOTq-YhqhFaq_5OwysUlKXaK_En-qGP6v9rf0,1065
|
|
364
364
|
udata/migrations/2025-01-05-dataservices-fields-changes.py,sha256=HlqHg3sG3rk3sYVrOwAlXMNhTmTKd1YT82P-gXOqmZM,4647
|
|
365
365
|
udata/migrations/2025-03-20-save-quality-for-datasets.py,sha256=FPTfGVByXSHr18V4RFlktC7t-H-5rgEcZQMTRpMrGqo,607
|
|
366
|
+
udata/migrations/2025-04-24-topic-featured-default-false.py,sha256=t4OyhehtPQiosKtAo9SWRWm3ObGUHvqD_roXQ34vIH4,369
|
|
366
367
|
udata/migrations/__init__.py,sha256=RBCBDaTlLjuMs_Qzwji6Z6T4r7FCGXhESKoxQbT5qAA,11221
|
|
367
368
|
udata/models/__init__.py,sha256=txbZwa-lRG3mq99eQ9E5YcFWiNUdjDVSyJJvlqUMFfs,1413
|
|
368
369
|
udata/mongo/__init__.py,sha256=y4Rv-kq3o_kcEulcNpePLzocXPBNpx3Jd82G-VZPaMc,1421
|
|
@@ -634,7 +635,7 @@ udata/tests/api/test_reports_api.py,sha256=fCSz9NwMXBs6cxdXBVVI6y564AtovmZYw3xkg
|
|
|
634
635
|
udata/tests/api/test_reuses_api.py,sha256=d8mtUrDURIfnUK-sLogvAP-rOID2FDJ0UVTM0ravQ-Q,24642
|
|
635
636
|
udata/tests/api/test_swagger.py,sha256=eE6La9qdTYTIUFevRVPJgtj17Jq_8uOlsDwzCNR0LL8,760
|
|
636
637
|
udata/tests/api/test_tags_api.py,sha256=36zEBgthVEn6pctJ0kDgPmEaUr-iqRAHeZRcRG2LEXQ,2425
|
|
637
|
-
udata/tests/api/test_topics_api.py,sha256=
|
|
638
|
+
udata/tests/api/test_topics_api.py,sha256=beIPbDA8PHo4FZogeio-j1MO6Eatt9oFSlp-aHpgEtQ,12200
|
|
638
639
|
udata/tests/api/test_transfer_api.py,sha256=-OLv-KjyLZL14J8UHl-ak_sYUj6wFiZWyoXC2SMXmEQ,7503
|
|
639
640
|
udata/tests/api/test_user_api.py,sha256=hfDHOv5F81tehbc5u3dYH5rAyYgzgHGCWVcGR3kLIZw,16591
|
|
640
641
|
udata/tests/apiv2/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -642,7 +643,7 @@ udata/tests/apiv2/test_datasets.py,sha256=zjTtjY7lJKOOjiV698RqGvRMuuMxY2dMhEcnhO
|
|
|
642
643
|
udata/tests/apiv2/test_me_api.py,sha256=RAgu5iKGB3Pp8cDN-427ovly-VOz5MTL4GpPZ1NcVXI,1418
|
|
643
644
|
udata/tests/apiv2/test_organizations.py,sha256=os_43s-coSRqjgY-5fAjSiRlB3g2685u7d-Es0aOhks,6390
|
|
644
645
|
udata/tests/apiv2/test_swagger.py,sha256=RKedaq-2UeyEuxlmUaAN7pmEe-lQYYmpDUVc8HF3CH4,785
|
|
645
|
-
udata/tests/apiv2/test_topics.py,sha256=
|
|
646
|
+
udata/tests/apiv2/test_topics.py,sha256=KwWAMta-C_MgwxBOwfUuPqxkO--SHvvth_c9VFGt2zA,11644
|
|
646
647
|
udata/tests/cli/test_cli_base.py,sha256=0a3U_5ROp1lCTG8d6TpCjF4nbKVNerAeLO0VxU-NTUk,321
|
|
647
648
|
udata/tests/cli/test_db_cli.py,sha256=_AZM_sZjePJw9ZaymuQoEAKXyX_EYz-S1PekxrMhMpU,1764
|
|
648
649
|
udata/tests/contact_point/test_contact_point_models.py,sha256=b8vraZPPrs9LeQMWLnOCrpI02sXMEM_BcMJXKTeAuAw,923
|
|
@@ -724,9 +725,9 @@ udata/translations/pt/LC_MESSAGES/udata.mo,sha256=xmSQ7RTl9XV24Vq3A7f_NIRDrOJwbs
|
|
|
724
725
|
udata/translations/pt/LC_MESSAGES/udata.po,sha256=PXrrhfIjZxheUotQan9VVh1fvNHSzeMAitaouIHaR7U,46793
|
|
725
726
|
udata/translations/sr/LC_MESSAGES/udata.mo,sha256=1pAf_rXvbOoO_jjZmH77GbzvdT_YtPTJKFumMnMto2g,29169
|
|
726
727
|
udata/translations/sr/LC_MESSAGES/udata.po,sha256=AalMHaFLZobKmuAnZ4X1rQtk46NdW2rktMFQHD5DTcM,53768
|
|
727
|
-
udata-10.3.2.
|
|
728
|
-
udata-10.3.2.
|
|
729
|
-
udata-10.3.2.
|
|
730
|
-
udata-10.3.2.
|
|
731
|
-
udata-10.3.2.
|
|
732
|
-
udata-10.3.2.
|
|
728
|
+
udata-10.3.2.dev34905.dist-info/LICENSE,sha256=V8j_M8nAz8PvAOZQocyRDX7keai8UJ9skgmnwqETmdY,34520
|
|
729
|
+
udata-10.3.2.dev34905.dist-info/METADATA,sha256=QiDRRN48mYIZG81xHTE5nGxk_NGPyHQ4m0OuGHcV9Qk,145008
|
|
730
|
+
udata-10.3.2.dev34905.dist-info/WHEEL,sha256=Kh9pAotZVRFj97E15yTA4iADqXdQfIVTHcNaZTjxeGM,110
|
|
731
|
+
udata-10.3.2.dev34905.dist-info/entry_points.txt,sha256=ETvkR4r6G1duBsh_V_fGWENQy17GTFuobi95MYBAl1A,498
|
|
732
|
+
udata-10.3.2.dev34905.dist-info/top_level.txt,sha256=39OCg-VWFWOq4gCKnjKNu-s3OwFlZIu_dVH8Gl6ndHw,12
|
|
733
|
+
udata-10.3.2.dev34905.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|