udata 13.0.1.dev12__py3-none-any.whl → 14.4.1.dev7__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/api/__init__.py +2 -8
- udata/api_fields.py +35 -4
- udata/app.py +30 -50
- udata/auth/__init__.py +29 -6
- udata/auth/forms.py +8 -6
- udata/auth/views.py +6 -3
- udata/commands/__init__.py +2 -14
- udata/commands/db.py +13 -25
- udata/commands/info.py +0 -16
- udata/commands/serve.py +3 -11
- udata/commands/tests/test_fixtures.py +9 -9
- udata/core/access_type/api.py +1 -1
- udata/core/access_type/constants.py +12 -8
- udata/core/activity/api.py +5 -6
- udata/core/avatars/api.py +43 -0
- udata/core/avatars/test_avatar_api.py +30 -0
- udata/core/badges/tests/test_commands.py +6 -6
- udata/core/csv.py +5 -0
- udata/core/dataservices/models.py +15 -3
- udata/core/dataservices/tasks.py +7 -0
- udata/core/dataset/api.py +2 -0
- udata/core/dataset/models.py +2 -2
- udata/core/dataset/permissions.py +31 -0
- udata/core/dataset/tasks.py +50 -10
- udata/core/discussions/models.py +1 -0
- udata/core/metrics/__init__.py +0 -6
- udata/core/organization/api.py +8 -5
- udata/core/organization/mails.py +1 -1
- udata/core/organization/models.py +9 -1
- udata/core/organization/notifications.py +84 -0
- udata/core/organization/permissions.py +1 -1
- udata/core/organization/tasks.py +3 -0
- udata/core/pages/tests/test_api.py +32 -0
- udata/core/post/api.py +24 -69
- udata/core/post/models.py +84 -16
- udata/core/post/tests/test_api.py +24 -1
- udata/core/reports/api.py +18 -0
- udata/core/reports/models.py +42 -2
- udata/core/reuse/models.py +1 -1
- udata/core/reuse/tasks.py +7 -0
- udata/core/site/models.py +2 -6
- udata/core/spatial/commands.py +2 -4
- udata/core/spatial/forms.py +2 -2
- udata/core/spatial/models.py +0 -10
- udata/core/spatial/tests/test_api.py +1 -36
- udata/core/user/models.py +15 -2
- udata/cors.py +2 -5
- udata/db/migrations.py +279 -0
- udata/features/notifications/api.py +7 -18
- udata/features/notifications/models.py +56 -0
- udata/features/notifications/tasks.py +25 -0
- udata/flask_mongoengine/engine.py +0 -4
- udata/frontend/__init__.py +3 -122
- udata/frontend/markdown.py +2 -1
- udata/harvest/actions.py +24 -9
- udata/harvest/api.py +30 -22
- udata/harvest/backends/__init__.py +21 -9
- udata/harvest/backends/base.py +29 -3
- udata/harvest/backends/ckan/harvesters.py +13 -2
- udata/harvest/backends/dcat.py +3 -0
- udata/harvest/backends/maaf.py +1 -0
- udata/harvest/commands.py +39 -4
- udata/harvest/filters.py +17 -6
- udata/harvest/forms.py +9 -6
- udata/harvest/models.py +16 -0
- udata/harvest/permissions.py +27 -0
- udata/harvest/tasks.py +3 -5
- udata/harvest/tests/ckan/test_ckan_backend.py +35 -2
- udata/harvest/tests/ckan/test_ckan_backend_errors.py +1 -1
- udata/harvest/tests/ckan/test_ckan_backend_filters.py +1 -1
- udata/harvest/tests/ckan/test_dkan_backend.py +1 -1
- udata/harvest/tests/dcat/udata.xml +6 -6
- udata/harvest/tests/factories.py +1 -1
- udata/harvest/tests/test_actions.py +63 -8
- udata/harvest/tests/test_api.py +278 -123
- udata/harvest/tests/test_base_backend.py +88 -1
- udata/harvest/tests/test_dcat_backend.py +60 -13
- udata/harvest/tests/test_filters.py +6 -0
- udata/i18n.py +11 -273
- udata/mail.py +5 -1
- udata/migrations/2025-10-31-create-membership-request-notifications.py +55 -0
- udata/migrations/2025-11-13-delete-user-email-index.py +25 -0
- udata/migrations/2025-12-04-add-uuid-to-discussion-messages.py +28 -0
- udata/models/__init__.py +0 -8
- udata/mongo/slug_fields.py +1 -1
- udata/rdf.py +45 -6
- udata/routing.py +2 -10
- udata/sentry.py +4 -10
- udata/settings.py +23 -17
- udata/tasks.py +4 -3
- udata/templates/mail/message.html +5 -31
- udata/tests/__init__.py +28 -12
- udata/tests/api/__init__.py +108 -21
- udata/tests/api/test_activities_api.py +36 -0
- udata/tests/api/test_auth_api.py +121 -95
- udata/tests/api/test_base_api.py +7 -4
- udata/tests/api/test_dataservices_api.py +29 -1
- udata/tests/api/test_datasets_api.py +45 -21
- udata/tests/api/test_organizations_api.py +192 -197
- udata/tests/api/test_reports_api.py +157 -0
- udata/tests/api/test_reuses_api.py +147 -147
- udata/tests/api/test_security_api.py +12 -12
- udata/tests/api/test_swagger.py +4 -4
- udata/tests/api/test_tags_api.py +8 -8
- udata/tests/api/test_user_api.py +13 -1
- udata/tests/apiv2/test_swagger.py +4 -4
- udata/tests/apiv2/test_topics.py +1 -1
- udata/tests/cli/test_cli_base.py +8 -9
- udata/tests/dataset/test_dataset_commands.py +4 -4
- udata/tests/dataset/test_dataset_model.py +66 -26
- udata/tests/dataset/test_dataset_rdf.py +99 -5
- udata/tests/dataset/test_resource_preview.py +0 -1
- udata/tests/frontend/test_auth.py +24 -1
- udata/tests/frontend/test_csv.py +0 -3
- udata/tests/helpers.py +37 -27
- udata/tests/organization/test_notifications.py +67 -2
- udata/tests/plugin.py +6 -261
- udata/tests/site/test_site_csv_exports.py +22 -10
- udata/tests/test_activity.py +9 -9
- udata/tests/test_cors.py +1 -1
- udata/tests/test_dcat_commands.py +2 -2
- udata/tests/test_discussions.py +5 -5
- udata/tests/test_migrations.py +181 -481
- udata/tests/test_notifications.py +15 -57
- udata/tests/test_notifications_task.py +43 -0
- udata/tests/test_owned.py +81 -1
- udata/tests/test_storages.py +25 -19
- udata/tests/test_topics.py +77 -61
- udata/tests/test_uris.py +33 -0
- udata/tests/workers/test_jobs_commands.py +23 -23
- udata/translations/ar/LC_MESSAGES/udata.mo +0 -0
- udata/translations/ar/LC_MESSAGES/udata.po +187 -108
- udata/translations/de/LC_MESSAGES/udata.mo +0 -0
- udata/translations/de/LC_MESSAGES/udata.po +187 -108
- udata/translations/es/LC_MESSAGES/udata.mo +0 -0
- udata/translations/es/LC_MESSAGES/udata.po +187 -108
- udata/translations/fr/LC_MESSAGES/udata.mo +0 -0
- udata/translations/fr/LC_MESSAGES/udata.po +188 -109
- udata/translations/it/LC_MESSAGES/udata.mo +0 -0
- udata/translations/it/LC_MESSAGES/udata.po +187 -108
- udata/translations/pt/LC_MESSAGES/udata.mo +0 -0
- udata/translations/pt/LC_MESSAGES/udata.po +187 -108
- udata/translations/sr/LC_MESSAGES/udata.mo +0 -0
- udata/translations/sr/LC_MESSAGES/udata.po +187 -108
- udata/translations/udata.pot +215 -106
- udata/uris.py +0 -2
- udata/utils.py +5 -0
- udata-14.4.1.dev7.dist-info/METADATA +109 -0
- {udata-13.0.1.dev12.dist-info → udata-14.4.1.dev7.dist-info}/RECORD +153 -166
- {udata-13.0.1.dev12.dist-info → udata-14.4.1.dev7.dist-info}/entry_points.txt +3 -5
- udata/core/followers/views.py +0 -15
- udata/core/post/forms.py +0 -30
- udata/entrypoints.py +0 -93
- udata/features/identicon/__init__.py +0 -0
- udata/features/identicon/api.py +0 -13
- udata/features/identicon/backends.py +0 -131
- udata/features/identicon/tests/__init__.py +0 -0
- udata/features/identicon/tests/test_backends.py +0 -18
- udata/features/territories/__init__.py +0 -49
- udata/features/territories/api.py +0 -25
- udata/features/territories/models.py +0 -51
- udata/flask_mongoengine/json.py +0 -38
- udata/migrations/__init__.py +0 -367
- udata/templates/mail/base.html +0 -105
- udata/templates/mail/base.txt +0 -6
- udata/templates/mail/button.html +0 -3
- udata/templates/mail/layouts/1-column.html +0 -19
- udata/templates/mail/layouts/2-columns.html +0 -20
- udata/templates/mail/layouts/center-panel.html +0 -16
- udata/tests/cli/test_db_cli.py +0 -68
- udata/tests/features/territories/__init__.py +0 -20
- udata/tests/features/territories/test_territories_api.py +0 -185
- udata/tests/frontend/test_hooks.py +0 -149
- udata-13.0.1.dev12.dist-info/METADATA +0 -133
- {udata-13.0.1.dev12.dist-info → udata-14.4.1.dev7.dist-info}/WHEEL +0 -0
- {udata-13.0.1.dev12.dist-info → udata-14.4.1.dev7.dist-info}/licenses/LICENSE +0 -0
- {udata-13.0.1.dev12.dist-info → udata-14.4.1.dev7.dist-info}/top_level.txt +0 -0
|
@@ -1,185 +0,0 @@
|
|
|
1
|
-
import pytest
|
|
2
|
-
from flask import url_for
|
|
3
|
-
|
|
4
|
-
from udata.core.spatial.factories import GeoZoneFactory
|
|
5
|
-
from udata.tests.api import APITestCase
|
|
6
|
-
from udata.tests.features.territories import (
|
|
7
|
-
create_geozones_fixtures,
|
|
8
|
-
create_old_new_regions_fixtures,
|
|
9
|
-
)
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
@pytest.mark.options(
|
|
13
|
-
ACTIVATE_TERRITORIES=True,
|
|
14
|
-
HANDLED_LEVELS=("fr:commune", "fr:departement", "fr:region", "country"),
|
|
15
|
-
)
|
|
16
|
-
class TerritoriesAPITest(APITestCase):
|
|
17
|
-
def setUp(self):
|
|
18
|
-
self.paca, self.bdr, self.arles = create_geozones_fixtures()
|
|
19
|
-
|
|
20
|
-
def test_suggest_no_parameter(self):
|
|
21
|
-
response = self.get(url_for("api.suggest_territory"))
|
|
22
|
-
self.assert400(response)
|
|
23
|
-
|
|
24
|
-
def test_suggest_empty(self):
|
|
25
|
-
response = self.get(url_for("api.suggest_territory", q="tes"))
|
|
26
|
-
self.assert200(response)
|
|
27
|
-
self.assertEqual(response.json, [])
|
|
28
|
-
response = self.get(url_for("api.suggest_territory", q="test"))
|
|
29
|
-
self.assert200(response)
|
|
30
|
-
self.assertEqual(response.json, [])
|
|
31
|
-
|
|
32
|
-
def test_suggest_town(self):
|
|
33
|
-
response = self.get(url_for("api.suggest_territory", q="arle"))
|
|
34
|
-
self.assert200(response)
|
|
35
|
-
result = response.json[0]
|
|
36
|
-
self.assertEqual(result["title"], self.arles.name)
|
|
37
|
-
self.assertEqual(result["id"], self.arles.id)
|
|
38
|
-
self.assertIn("page", result)
|
|
39
|
-
|
|
40
|
-
def test_suggest_town_five_letters(self):
|
|
41
|
-
response = self.get(url_for("api.suggest_territory", q="arles"))
|
|
42
|
-
self.assert200(response)
|
|
43
|
-
result = response.json[0]
|
|
44
|
-
self.assertEqual(result["title"], self.arles.name)
|
|
45
|
-
self.assertEqual(result["id"], self.arles.id)
|
|
46
|
-
self.assertIn("page", result)
|
|
47
|
-
|
|
48
|
-
def test_suggest_town_by_insee_code(self):
|
|
49
|
-
response = self.get(url_for("api.suggest_territory", q="13004"))
|
|
50
|
-
self.assert200(response)
|
|
51
|
-
result = response.json[0]
|
|
52
|
-
self.assertEqual(result["id"], self.arles.id)
|
|
53
|
-
self.assertEqual(result["title"], self.arles.name)
|
|
54
|
-
|
|
55
|
-
def test_suggest_towns(self):
|
|
56
|
-
arles_sur_tech = GeoZoneFactory(
|
|
57
|
-
id="fr:commune:66009", level="fr:commune", name="Arles-sur-Tech", code="66009"
|
|
58
|
-
)
|
|
59
|
-
response = self.get(url_for("api.suggest_territory", q="arles"))
|
|
60
|
-
self.assert200(response)
|
|
61
|
-
results = response.json
|
|
62
|
-
self.assertEqual(len(results), 2)
|
|
63
|
-
# Arles must be first given the population.
|
|
64
|
-
self.assertEqual(results[0]["id"], self.arles.id)
|
|
65
|
-
self.assertEqual(results[1]["id"], arles_sur_tech.id)
|
|
66
|
-
|
|
67
|
-
def test_suggest_county(self):
|
|
68
|
-
response = self.get(url_for("api.suggest_territory", q="bouche"))
|
|
69
|
-
self.assert200(response)
|
|
70
|
-
result = response.json[0]
|
|
71
|
-
self.assertEqual(result["title"], self.bdr.name)
|
|
72
|
-
self.assertEqual(result["id"], self.bdr.id)
|
|
73
|
-
self.assertIn("page", result)
|
|
74
|
-
|
|
75
|
-
def test_suggest_region(self):
|
|
76
|
-
response = self.get(url_for("api.suggest_territory", q="prov"))
|
|
77
|
-
self.assert200(response)
|
|
78
|
-
result = response.json[0]
|
|
79
|
-
self.assertEqual(result["title"], self.paca.name)
|
|
80
|
-
self.assertEqual(result["id"], self.paca.id)
|
|
81
|
-
self.assertIn("page", result)
|
|
82
|
-
|
|
83
|
-
def test_suggest_old_new_region(self):
|
|
84
|
-
lr, occitanie = create_old_new_regions_fixtures()
|
|
85
|
-
response = self.get(url_for("api.suggest_territory", q="langue"))
|
|
86
|
-
self.assert200(response)
|
|
87
|
-
self.assertEqual(len(response.json), 2)
|
|
88
|
-
result = response.json[0]
|
|
89
|
-
self.assertEqual(result["title"], occitanie.name)
|
|
90
|
-
self.assertEqual(result["id"], occitanie.id)
|
|
91
|
-
result = response.json[1]
|
|
92
|
-
self.assertEqual(result["title"], lr.name)
|
|
93
|
-
self.assertEqual(result["id"], lr.id)
|
|
94
|
-
|
|
95
|
-
def test_suggest_county_by_id(self):
|
|
96
|
-
response = self.get(url_for("api.suggest_territory", q="13"))
|
|
97
|
-
self.assert200(response)
|
|
98
|
-
result = response.json[0]
|
|
99
|
-
self.assertEqual(result["id"], self.bdr.id)
|
|
100
|
-
self.assertEqual(result["title"], self.bdr.name)
|
|
101
|
-
|
|
102
|
-
def test_suggest_town_and_county(self):
|
|
103
|
-
bouchet = GeoZoneFactory(
|
|
104
|
-
id="fr:commune:26054", level="fr:commune", name="Bouchet", code="26054"
|
|
105
|
-
)
|
|
106
|
-
response = self.get(url_for("api.suggest_territory", q="bouche"))
|
|
107
|
-
self.assert200(response)
|
|
108
|
-
results = response.json
|
|
109
|
-
self.assertEqual(len(results), 2)
|
|
110
|
-
|
|
111
|
-
self.assertEqual(results[0]["id"], bouchet.id)
|
|
112
|
-
self.assertEqual(results[1]["id"], self.bdr.id)
|
|
113
|
-
|
|
114
|
-
def test_suggest_drom_com(self):
|
|
115
|
-
guyane = GeoZoneFactory(
|
|
116
|
-
id="fr:departement:973", level="fr:departement", name="Guyane", code="973"
|
|
117
|
-
)
|
|
118
|
-
response = self.get(url_for("api.suggest_territory", q="guya"))
|
|
119
|
-
self.assert200(response)
|
|
120
|
-
results = response.json
|
|
121
|
-
self.assertEqual(len(results), 1)
|
|
122
|
-
self.assertEqual(results[0]["id"], guyane.id)
|
|
123
|
-
|
|
124
|
-
def test_suggest_drom_com_by_code(self):
|
|
125
|
-
guyane = GeoZoneFactory(
|
|
126
|
-
id="fr:departement:973", level="fr:departement", name="Guyane", code="973"
|
|
127
|
-
)
|
|
128
|
-
response = self.get(url_for("api.suggest_territory", q="973"))
|
|
129
|
-
self.assert200(response)
|
|
130
|
-
results = response.json
|
|
131
|
-
self.assertEqual(len(results), 1)
|
|
132
|
-
self.assertEqual(results[0]["id"], guyane.id)
|
|
133
|
-
|
|
134
|
-
def test_suggest_corsica(self):
|
|
135
|
-
bastia = GeoZoneFactory(
|
|
136
|
-
id="fr:commune:2b033", level="fr:commune", name="Bastia", code="2b033"
|
|
137
|
-
)
|
|
138
|
-
response = self.get(url_for("api.suggest_territory", q="basti"))
|
|
139
|
-
self.assert200(response)
|
|
140
|
-
results = response.json
|
|
141
|
-
self.assertEqual(len(results), 1)
|
|
142
|
-
self.assertEqual(results[0]["id"], bastia.id)
|
|
143
|
-
|
|
144
|
-
def test_suggest_corsica_by_code(self):
|
|
145
|
-
bastia = GeoZoneFactory(
|
|
146
|
-
id="fr:commune:2b033", level="fr:commune", name="Bastia", code="2b033"
|
|
147
|
-
)
|
|
148
|
-
response = self.get(url_for("api.suggest_territory", q="2b033"))
|
|
149
|
-
self.assert200(response)
|
|
150
|
-
results = response.json
|
|
151
|
-
self.assertEqual(len(results), 1)
|
|
152
|
-
self.assertEqual(results[0]["id"], bastia.id)
|
|
153
|
-
|
|
154
|
-
def test_suggest_corsica_by_county_code(self):
|
|
155
|
-
haute_corse = GeoZoneFactory(
|
|
156
|
-
id="fr:departement:2b", level="fr:departement", name="Haute-Corse", code="2b"
|
|
157
|
-
)
|
|
158
|
-
response = self.get(url_for("api.suggest_territory", q="2b"))
|
|
159
|
-
self.assert200(response)
|
|
160
|
-
results = response.json
|
|
161
|
-
self.assertEqual(len(results), 1)
|
|
162
|
-
self.assertEqual(results[0]["id"], haute_corse.id)
|
|
163
|
-
|
|
164
|
-
def test_not_suggest_country(self):
|
|
165
|
-
GeoZoneFactory(id="country:fr", level="country", name="France")
|
|
166
|
-
response = self.get(url_for("api.suggest_territory", q="fra"))
|
|
167
|
-
self.assert200(response)
|
|
168
|
-
results = response.json
|
|
169
|
-
self.assertEqual(len(results), 0)
|
|
170
|
-
response = self.get(url_for("api.suggest_territory", q="fran"))
|
|
171
|
-
self.assert200(response)
|
|
172
|
-
results = response.json
|
|
173
|
-
self.assertEqual(len(results), 0)
|
|
174
|
-
response = self.get(url_for("api.suggest_territory", q="franc"))
|
|
175
|
-
self.assert200(response)
|
|
176
|
-
results = response.json
|
|
177
|
-
self.assertEqual(len(results), 0)
|
|
178
|
-
|
|
179
|
-
def test_suggest_unicode(self):
|
|
180
|
-
response = self.get(url_for("api.suggest_territory", q="Bouches-du-Rhône"))
|
|
181
|
-
self.assert200(response)
|
|
182
|
-
result = response.json[0]
|
|
183
|
-
self.assertEqual(result["title"], self.bdr.name)
|
|
184
|
-
self.assertEqual(result["id"], self.bdr.id)
|
|
185
|
-
self.assertIn("page", result)
|
|
@@ -1,149 +0,0 @@
|
|
|
1
|
-
import pytest
|
|
2
|
-
from flask import Blueprint, render_template_string, url_for
|
|
3
|
-
|
|
4
|
-
from udata.frontend import template_hook
|
|
5
|
-
from udata.tests.api import PytestOnlyAPITestCase
|
|
6
|
-
from udata.tests.helpers import assert200
|
|
7
|
-
|
|
8
|
-
bp = Blueprint("hooks_tests", __name__, url_prefix="/hooks_tests")
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
@template_hook
|
|
12
|
-
def single(ctx):
|
|
13
|
-
return "single"
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
@template_hook
|
|
17
|
-
def hello(ctx, name):
|
|
18
|
-
return "Hello {}".format(name)
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
@template_hook
|
|
22
|
-
def kwargs(ctx, **kwargs):
|
|
23
|
-
return ", ".join(sorted("{0}={1}".format(k, v) for k, v in kwargs.items()))
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
@template_hook("multiple")
|
|
27
|
-
def first(ctx):
|
|
28
|
-
return "first"
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
@template_hook("multiple")
|
|
32
|
-
def second(ctx):
|
|
33
|
-
return "second"
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
@template_hook("conditionnal", when=lambda ctx: True)
|
|
37
|
-
def true(ctx):
|
|
38
|
-
return "true"
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
@template_hook("conditionnal", when=lambda ctx: False)
|
|
42
|
-
def false(ctx):
|
|
43
|
-
return "false"
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
@bp.route("/empty/render")
|
|
47
|
-
def render_empty():
|
|
48
|
-
return render_template_string('{{ hook("empty") }}')
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
@bp.route("/empty/iter")
|
|
52
|
-
def iter_empty():
|
|
53
|
-
return render_template_string('{% for w in hook("empty") %}<{{ w }}>{% endfor %}')
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
@bp.route("/hello")
|
|
57
|
-
def render_hello():
|
|
58
|
-
return render_template_string('{{ hook("hello", "world") }}')
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
@bp.route("/kwargs")
|
|
62
|
-
def render_kwargs():
|
|
63
|
-
return render_template_string('{{ hook("kwargs", key="value", other=42) }}')
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
@bp.route("/single/render")
|
|
67
|
-
def render_single():
|
|
68
|
-
return render_template_string('{{ hook("single") }}')
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
@bp.route("/single/iter")
|
|
72
|
-
def iter_single():
|
|
73
|
-
return render_template_string('{% for w in hook("single") %}<{{ w }}>{% endfor %}')
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
@bp.route("/multiple/render")
|
|
77
|
-
def render_multiple():
|
|
78
|
-
return render_template_string('{{ hook("multiple") }}')
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
@bp.route("/multiple/iter")
|
|
82
|
-
def iter_multiple():
|
|
83
|
-
return render_template_string('{% for w in hook("multiple") %}<{{ w }}>{% endfor %}')
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
@bp.route("/conditionnal/render")
|
|
87
|
-
def render_conditionnal():
|
|
88
|
-
return render_template_string('{{ hook("conditionnal") }}')
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
@bp.route("/conditionnal/iter")
|
|
92
|
-
def iter_conditionnal():
|
|
93
|
-
return render_template_string('{% for w in hook("conditionnal") %}<{{ w }}>{% endfor %}')
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
class HooksTest(PytestOnlyAPITestCase):
|
|
97
|
-
@pytest.fixture(autouse=True)
|
|
98
|
-
def setup_func(self, app):
|
|
99
|
-
app.register_blueprint(bp)
|
|
100
|
-
|
|
101
|
-
def test_empty_template_hook(self, client):
|
|
102
|
-
response = client.get(url_for("hooks_tests.render_empty"))
|
|
103
|
-
assert200(response)
|
|
104
|
-
assert b"" == response.data
|
|
105
|
-
|
|
106
|
-
def test_iter_empty_template_hook(self, client):
|
|
107
|
-
response = client.get(url_for("hooks_tests.iter_empty"))
|
|
108
|
-
assert200(response)
|
|
109
|
-
assert b"" == response.data
|
|
110
|
-
|
|
111
|
-
def test_single_template_hook(self, client):
|
|
112
|
-
response = client.get(url_for("hooks_tests.render_single"))
|
|
113
|
-
assert200(response)
|
|
114
|
-
assert b"single" == response.data
|
|
115
|
-
|
|
116
|
-
def test_iter_single_template_hook(self, client):
|
|
117
|
-
response = client.get(url_for("hooks_tests.iter_single"))
|
|
118
|
-
assert200(response)
|
|
119
|
-
assert b"<single>" == response.data
|
|
120
|
-
|
|
121
|
-
def test_multiple_template_hooks(self, client):
|
|
122
|
-
response = client.get(url_for("hooks_tests.render_multiple"))
|
|
123
|
-
assert200(response)
|
|
124
|
-
assert b"firstsecond" == response.data
|
|
125
|
-
|
|
126
|
-
def test_iter_multiple_template_hooks(self, client):
|
|
127
|
-
response = client.get(url_for("hooks_tests.iter_multiple"))
|
|
128
|
-
assert200(response)
|
|
129
|
-
assert b"<first><second>" == response.data
|
|
130
|
-
|
|
131
|
-
def test_conditionnal_template_hooks(self, client):
|
|
132
|
-
response = client.get(url_for("hooks_tests.render_conditionnal"))
|
|
133
|
-
assert200(response)
|
|
134
|
-
assert b"true" == response.data
|
|
135
|
-
|
|
136
|
-
def test_iter_conditionnal_template_hooks(self, client):
|
|
137
|
-
response = client.get(url_for("hooks_tests.iter_conditionnal"))
|
|
138
|
-
assert200(response)
|
|
139
|
-
assert b"<true>" == response.data
|
|
140
|
-
|
|
141
|
-
def test_arguments(self, client):
|
|
142
|
-
response = client.get(url_for("hooks_tests.render_hello"))
|
|
143
|
-
assert200(response)
|
|
144
|
-
assert b"Hello world" == response.data
|
|
145
|
-
|
|
146
|
-
def test_kwargs(self, client):
|
|
147
|
-
response = client.get(url_for("hooks_tests.render_kwargs"))
|
|
148
|
-
assert200(response)
|
|
149
|
-
assert b"key=value, other=42" == response.data
|
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: udata
|
|
3
|
-
Version: 13.0.1.dev12
|
|
4
|
-
Summary: Open data portal
|
|
5
|
-
Author-email: Opendata Team <opendatateam@data.gouv.fr>
|
|
6
|
-
Maintainer-email: Opendata Team <opendatateam@data.gouv.fr>
|
|
7
|
-
License: MIT
|
|
8
|
-
Project-URL: Homepage, https://github.com/opendatateam/udata
|
|
9
|
-
Project-URL: Repository, https://github.com/opendatateam/udata
|
|
10
|
-
Project-URL: Documentation, https://udata.readthedocs.io/
|
|
11
|
-
Project-URL: Bug Tracker, https://github.com/opendatateam/udata/issues
|
|
12
|
-
Keywords: udata,open data,portal,data
|
|
13
|
-
Classifier: Development Status :: 5 - Production/Stable
|
|
14
|
-
Classifier: Programming Language :: Python
|
|
15
|
-
Classifier: Environment :: Web Environment
|
|
16
|
-
Classifier: Operating System :: OS Independent
|
|
17
|
-
Classifier: Intended Audience :: Developers
|
|
18
|
-
Classifier: Topic :: System :: Software Distribution
|
|
19
|
-
Classifier: Programming Language :: Python :: 3
|
|
20
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
21
|
-
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
-
Classifier: Programming Language :: Python :: 3.13
|
|
23
|
-
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
24
|
-
Classifier: License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)
|
|
25
|
-
Requires-Python: <3.14,>=3.11
|
|
26
|
-
Description-Content-Type: text/markdown
|
|
27
|
-
License-File: LICENSE
|
|
28
|
-
Requires-Dist: authlib==1.5.1
|
|
29
|
-
Requires-Dist: awesome-slugify==1.6.5
|
|
30
|
-
Requires-Dist: babel==2.17.0
|
|
31
|
-
Requires-Dist: bcrypt==4.3.0
|
|
32
|
-
Requires-Dist: bleach[css]==6.2.0
|
|
33
|
-
Requires-Dist: blinker==1.5
|
|
34
|
-
Requires-Dist: boto3==1.26.102
|
|
35
|
-
Requires-Dist: botocore==1.29.165
|
|
36
|
-
Requires-Dist: celery==5.4.0
|
|
37
|
-
Requires-Dist: celerybeat-mongo==0.2.0
|
|
38
|
-
Requires-Dist: click==8.1.8
|
|
39
|
-
Requires-Dist: cryptography==44.0.2
|
|
40
|
-
Requires-Dist: email-validator==2.2.0
|
|
41
|
-
Requires-Dist: factory-boy==3.3.3
|
|
42
|
-
Requires-Dist: feedgenerator==2.1.0
|
|
43
|
-
Requires-Dist: flask==2.1.2
|
|
44
|
-
Requires-Dist: flask-babel==4.0.0
|
|
45
|
-
Requires-Dist: flask-caching==2.3.1
|
|
46
|
-
Requires-Dist: flask-cdn==1.5.3
|
|
47
|
-
Requires-Dist: flask-gravatar==0.5.0
|
|
48
|
-
Requires-Dist: flask-login==0.6.3
|
|
49
|
-
Requires-Dist: flask-mail==0.10.0
|
|
50
|
-
Requires-Dist: flask-principal==0.4.0
|
|
51
|
-
Requires-Dist: flask-restx==1.3.0
|
|
52
|
-
Requires-Dist: flask-security-too==5.1.2
|
|
53
|
-
Requires-Dist: flask-sitemap==0.4.0
|
|
54
|
-
Requires-Dist: flask-storage~=1.4.0
|
|
55
|
-
Requires-Dist: flask-wtf==1.2.2
|
|
56
|
-
Requires-Dist: geojson==3.2.0
|
|
57
|
-
Requires-Dist: geomet==1.1.0
|
|
58
|
-
Requires-Dist: html2text==2024.2.26
|
|
59
|
-
Requires-Dist: humanfriendly==10.0
|
|
60
|
-
Requires-Dist: importlib-resources==6.5.2
|
|
61
|
-
Requires-Dist: itsdangerous==2.2.0
|
|
62
|
-
Requires-Dist: jinja2==3.1.6
|
|
63
|
-
Requires-Dist: jsonschema==4.23.0
|
|
64
|
-
Requires-Dist: kombu[redis]==5.5.0
|
|
65
|
-
Requires-Dist: langdetect==1.0.9
|
|
66
|
-
Requires-Dist: levenshtein==0.27.1
|
|
67
|
-
Requires-Dist: lxml==5.3.1
|
|
68
|
-
Requires-Dist: markupsafe==2.1.2
|
|
69
|
-
Requires-Dist: mistune==3.1.3
|
|
70
|
-
Requires-Dist: mongoengine==0.29.1
|
|
71
|
-
Requires-Dist: netaddr==1.3.0
|
|
72
|
-
Requires-Dist: pillow==9.2.0
|
|
73
|
-
Requires-Dist: pydenticon==0.3.1
|
|
74
|
-
Requires-Dist: pymongo==4.11.3
|
|
75
|
-
Requires-Dist: python-dateutil==2.9.0.post0
|
|
76
|
-
Requires-Dist: pytz==2025.1
|
|
77
|
-
Requires-Dist: rdflib==7.1.3
|
|
78
|
-
Requires-Dist: redis==5.2.1
|
|
79
|
-
Requires-Dist: requests==2.32.4
|
|
80
|
-
Requires-Dist: saxonche==12.8.0
|
|
81
|
-
Requires-Dist: sentry-sdk[flask]==2.23.1
|
|
82
|
-
Requires-Dist: speaklater==1.3
|
|
83
|
-
Requires-Dist: tlds==2025022800
|
|
84
|
-
Requires-Dist: typing-extensions==4.12.2
|
|
85
|
-
Requires-Dist: tzdata==2025.1
|
|
86
|
-
Requires-Dist: urlextract==1.9.0
|
|
87
|
-
Requires-Dist: urllib3==1.26.20
|
|
88
|
-
Requires-Dist: voluptuous==0.15.2
|
|
89
|
-
Requires-Dist: werkzeug==2.2.3
|
|
90
|
-
Requires-Dist: wtforms[email]==3.2.1
|
|
91
|
-
Requires-Dist: wtforms-json==0.3.5
|
|
92
|
-
Provides-Extra: dev
|
|
93
|
-
Requires-Dist: flask-shell-ipython<1.0,>=0.5.3; extra == "dev"
|
|
94
|
-
Requires-Dist: invoke<3.0,>=2.2.0; extra == "dev"
|
|
95
|
-
Requires-Dist: pip-tools<8.0,>=7.4.1; extra == "dev"
|
|
96
|
-
Requires-Dist: pre-commit<5.0,>=4.2.0; extra == "dev"
|
|
97
|
-
Requires-Dist: ruff<1.0,>=0.11.0; extra == "dev"
|
|
98
|
-
Provides-Extra: test
|
|
99
|
-
Requires-Dist: faker<38.0,>=37.0.2; extra == "test"
|
|
100
|
-
Requires-Dist: feedparser<7.0,>=6.0.11; extra == "test"
|
|
101
|
-
Requires-Dist: httpretty<2.0,>=1.1.4; extra == "test"
|
|
102
|
-
Requires-Dist: mock<6.0,>=5.2.0; extra == "test"
|
|
103
|
-
Requires-Dist: pytest<9.0,>=8.3.5; extra == "test"
|
|
104
|
-
Requires-Dist: pytest-env<2.0,>=1.1.5; extra == "test"
|
|
105
|
-
Requires-Dist: pytest-flask<2.0,>=1.3.0; extra == "test"
|
|
106
|
-
Requires-Dist: pytest-mock<4.0,>=3.14.0; extra == "test"
|
|
107
|
-
Requires-Dist: pytest-sugar<2.0,>=1.0.0; extra == "test"
|
|
108
|
-
Requires-Dist: requests-mock<2.0,>=1.12.1; extra == "test"
|
|
109
|
-
Provides-Extra: doc
|
|
110
|
-
Requires-Dist: mkdocs<2.0,>=1.6.1; extra == "doc"
|
|
111
|
-
Provides-Extra: report
|
|
112
|
-
Requires-Dist: coverage[toml]<8.0,>=7.7.0; extra == "report"
|
|
113
|
-
Requires-Dist: flake8<8.0,>=7.1.2; extra == "report"
|
|
114
|
-
Requires-Dist: pytest-cov<8.0,>=7.0.0; extra == "report"
|
|
115
|
-
Dynamic: license-file
|
|
116
|
-
|
|
117
|
-
<p align="center"><img src="https://i.imgur.com/rlRox1c.png"></p>
|
|
118
|
-
|
|
119
|
-
udata
|
|
120
|
-
=====
|
|
121
|
-
|
|
122
|
-
Customizable and skinnable social platform dedicated to (open) data.
|
|
123
|
-
|
|
124
|
-
The [full documentation][readthedocs-url] is hosted on Read the Docs.
|
|
125
|
-
|
|
126
|
-
udata is maintained by [data.gouv.fr](https://data.gouv.fr/), the
|
|
127
|
-
French public agency in charge of open data. data.gouv.fr is responsible
|
|
128
|
-
for publishing udata's roadmap and for building consensus around it.
|
|
129
|
-
|
|
130
|
-
It is collectively taken care of by members of the
|
|
131
|
-
[OpenDataTeam](https://github.com/opendatateam).
|
|
132
|
-
|
|
133
|
-
[readthedocs-url]: https://udata.readthedocs.io/en/stable/
|
|
File without changes
|
|
File without changes
|
|
File without changes
|