imio.smartweb.core 1.2.90__py3-none-any.whl → 1.3__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.
- imio/smartweb/core/browser/controlpanel.py +42 -5
- imio/smartweb/core/browser/utils.py +4 -1
- imio/smartweb/core/configure.zcml +5 -1
- imio/smartweb/core/contents/__init__.py +2 -0
- imio/smartweb/core/contents/rest/campaign/__init__.py +0 -0
- imio/smartweb/core/contents/rest/campaign/configure.zcml +80 -0
- imio/smartweb/core/contents/rest/campaign/content.py +83 -0
- imio/smartweb/core/contents/rest/campaign/endpoint.py +211 -0
- imio/smartweb/core/contents/rest/campaign/view.pt +19 -0
- imio/smartweb/core/contents/rest/campaign/view.py +29 -0
- imio/smartweb/core/contents/rest/configure.zcml +1 -0
- imio/smartweb/core/interfaces.py +4 -0
- imio/smartweb/core/overrides.zcml +10 -0
- imio/smartweb/core/profiles/default/metadata.xml +1 -1
- imio/smartweb/core/profiles/ideabox/browserlayer.xml +7 -0
- imio/smartweb/core/profiles/ideabox/metadata.xml +5 -0
- imio/smartweb/core/profiles/ideabox/registry/iaideabox.xml +9 -0
- imio/smartweb/core/profiles/ideabox/types/imio.smartweb.CampaignView.xml +40 -0
- imio/smartweb/core/profiles/ideabox/types/imio.smartweb.Folder.xml +71 -0
- imio/smartweb/core/profiles/ideabox/types.xml +17 -0
- imio/smartweb/core/profiles/ideabox_uninstall/browserlayer.xml +7 -0
- imio/smartweb/core/profiles/ideabox_uninstall/types/imio.smartweb.Folder.xml +25 -0
- imio/smartweb/core/profiles/ideabox_uninstall/types.xml +4 -0
- imio/smartweb/core/profiles/testing/metadata.xml +1 -0
- imio/smartweb/core/profiles/testing/registry.xml +2 -2
- imio/smartweb/core/profiles.zcml +18 -0
- imio/smartweb/core/subscribers.py +27 -1
- imio/smartweb/core/subscribers.zcml +8 -0
- imio/smartweb/core/tests/resources/json_ideabox_campaign.json +222 -0
- imio/smartweb/core/tests/resources/json_ideabox_campaigns.json +425 -0
- imio/smartweb/core/tests/resources/json_ideabox_projects.json +1871 -0
- imio/smartweb/core/tests/test_iadeliberations.py +38 -40
- imio/smartweb/core/tests/test_ideabox.py +120 -0
- imio/smartweb/core/tests/test_procedure.py +7 -3
- imio/smartweb/core/tests/test_rest.py +7 -0
- imio/smartweb/core/tests/test_vocabularies.py +8 -10
- imio/smartweb/core/upgrades/configure.zcml +16 -1
- imio/smartweb/core/upgrades/upgrades.py +64 -0
- imio/smartweb/core/utils.py +33 -0
- imio/smartweb/core/viewlets/actions.py +10 -0
- imio/smartweb/core/viewlets/header_actions.pt +2 -0
- imio/smartweb/core/viewlets/offcanvas.pt +31 -6
- imio/smartweb/core/viewlets/ogptags.py +9 -0
- imio/smartweb/core/viewlets/subsite_logo.pt +1 -1
- imio/smartweb/core/vocabularies.py +35 -4
- imio/smartweb/core/vocabularies.zcml +6 -0
- imio/smartweb/core/webcomponents/build/css/373.smartweb-webcomponents-compiled.css +1 -1
- imio/smartweb/core/webcomponents/build/css/420.smartweb-webcomponents-compiled.css +1 -0
- imio/smartweb/core/webcomponents/build/css/486.smartweb-webcomponents-compiled.css +1 -1
- imio/smartweb/core/webcomponents/build/css/666.smartweb-webcomponents-compiled.css +1 -0
- imio/smartweb/core/webcomponents/build/css/884.smartweb-webcomponents-compiled.css +1 -1
- imio/smartweb/core/webcomponents/build/css/smartweb-webcomponents-compiled.css +1 -1
- imio/smartweb/core/webcomponents/build/js/141.smartweb-webcomponents-compiled.js +2 -0
- imio/smartweb/core/webcomponents/build/js/{828.smartweb-webcomponents-compiled.js.LICENSE.txt → 141.smartweb-webcomponents-compiled.js.LICENSE.txt} +3 -3
- imio/smartweb/core/webcomponents/build/js/15.smartweb-webcomponents-compiled.js +2 -0
- imio/smartweb/core/webcomponents/build/js/21.smartweb-webcomponents-compiled.js +1 -0
- imio/smartweb/core/webcomponents/build/js/218.smartweb-webcomponents-compiled.js +1 -1
- imio/smartweb/core/webcomponents/build/js/218.smartweb-webcomponents-compiled.js.LICENSE.txt +0 -5
- imio/smartweb/core/webcomponents/build/js/373.smartweb-webcomponents-compiled.js +1 -1
- imio/smartweb/core/webcomponents/build/js/486.smartweb-webcomponents-compiled.js +1 -1
- imio/smartweb/core/webcomponents/build/js/666.smartweb-webcomponents-compiled.js +1 -0
- imio/smartweb/core/webcomponents/build/js/799.smartweb-webcomponents-compiled.js +1 -1
- imio/smartweb/core/webcomponents/build/js/824.smartweb-webcomponents-compiled.js +1 -1
- imio/smartweb/core/webcomponents/build/js/884.smartweb-webcomponents-compiled.js +1 -1
- imio/smartweb/core/webcomponents/build/js/919.smartweb-webcomponents-compiled.js +1 -1
- imio/smartweb/core/webcomponents/build/js/922.smartweb-webcomponents-compiled.js +1 -0
- imio/smartweb/core/webcomponents/build/js/smartweb-webcomponents-compiled.js +1 -1
- imio/smartweb/core/webcomponents/package.json +80 -80
- imio/smartweb/core/webcomponents/src/components/Annuaire/Annuaire.scss +1 -0
- imio/smartweb/core/webcomponents/src/components/Campaign/Campaign.jsx +306 -0
- imio/smartweb/core/webcomponents/src/components/Campaign/Campaign.scss +672 -0
- imio/smartweb/core/webcomponents/src/components/Campaign/CampaignCard/CampaignCard.jsx +79 -0
- imio/smartweb/core/webcomponents/src/components/Campaign/CampaignContent/CampaignContent.jsx +193 -0
- imio/smartweb/core/webcomponents/src/components/Campaign/CampaignList/CampaignList.jsx +67 -0
- imio/smartweb/core/webcomponents/src/components/Campaign/Filters/Filter.jsx +259 -0
- imio/smartweb/core/webcomponents/src/components/Campaign/index.js +2 -0
- imio/smartweb/core/webcomponents/src/components/Filters/MainFilter.scss +1 -0
- imio/smartweb/core/webcomponents/src/components/News/NewsContent/NewsContent.jsx +0 -1
- imio/smartweb/core/webcomponents/src/hooks/useAxios.js +45 -9
- imio/smartweb/core/webcomponents/src/index.jsx +2 -0
- imio/smartweb/core/webcomponents/src/index.scss +2 -2
- imio/smartweb/core/webcomponents/src/utils/CampaignMap.jsx +177 -0
- imio/smartweb/core/webcomponents/src/utils/Map.jsx +1 -1
- imio/smartweb/core/webcomponents/src/utils/Map.scss +15 -1
- imio/smartweb/core/webcomponents/src/utils/translation.js +235 -199
- {imio.smartweb.core-1.2.90.dist-info → imio.smartweb.core-1.3.dist-info}/METADATA +18 -1
- {imio.smartweb.core-1.2.90.dist-info → imio.smartweb.core-1.3.dist-info}/RECORD +94 -61
- imio/smartweb/core/webcomponents/build/js/499.smartweb-webcomponents-compiled.js +0 -2
- imio/smartweb/core/webcomponents/build/js/828.smartweb-webcomponents-compiled.js +0 -2
- /imio/smartweb/core/webcomponents/build/js/{499.smartweb-webcomponents-compiled.js.LICENSE.txt → 15.smartweb-webcomponents-compiled.js.LICENSE.txt} +0 -0
- /imio.smartweb.core-1.2.90-py3.12-nspkg.pth → /imio.smartweb.core-1.3-py3.12-nspkg.pth +0 -0
- {imio.smartweb.core-1.2.90.dist-info → imio.smartweb.core-1.3.dist-info}/LICENSE.GPL +0 -0
- {imio.smartweb.core-1.2.90.dist-info → imio.smartweb.core-1.3.dist-info}/LICENSE.rst +0 -0
- {imio.smartweb.core-1.2.90.dist-info → imio.smartweb.core-1.3.dist-info}/WHEEL +0 -0
- {imio.smartweb.core-1.2.90.dist-info → imio.smartweb.core-1.3.dist-info}/namespace_packages.txt +0 -0
- {imio.smartweb.core-1.2.90.dist-info → imio.smartweb.core-1.3.dist-info}/top_level.txt +0 -0
@@ -55,10 +55,8 @@ class TestIADeliberations(ImioSmartwebTestCase):
|
|
55
55
|
),
|
56
56
|
)
|
57
57
|
|
58
|
-
@patch("imio.smartweb.core.subscribers.
|
59
|
-
@patch(
|
60
|
-
"imio.smartweb.core.subscribers.get_iadeliberation_institution_from_registry"
|
61
|
-
)
|
58
|
+
@patch("imio.smartweb.core.subscribers.get_basic_auth_json")
|
59
|
+
@patch("imio.smartweb.core.subscribers.get_value_from_registry")
|
62
60
|
def test_ct_publication_adding(self, m_get_institution, m_get_publication):
|
63
61
|
m_get_institution.return_value = "https://conseil.staging.imio.be/liege"
|
64
62
|
m_get_publication.return_value = self.json_publication_raw_mock
|
@@ -96,41 +94,41 @@ class TestIADeliberations(ImioSmartwebTestCase):
|
|
96
94
|
api.content.delete(obj=obj)
|
97
95
|
self.assertNotIn("publication", parent.objectIds())
|
98
96
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
)
|
103
|
-
def test_publication_view(self, m_get_institution, m_get_publication):
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
97
|
+
# Fix tests : timestamped publication are now a section, not an item in a file section
|
98
|
+
#
|
99
|
+
# @patch("imio.smartweb.core.subscribers.get_iadeliberation_json")
|
100
|
+
# @patch("imio.smartweb.core.subscribers.get_value_from_registry")
|
101
|
+
# def test_publication_view(self, m_get_institution, m_get_publication):
|
102
|
+
# m_get_institution.return_value = "https://conseil.staging.imio.be/liege"
|
103
|
+
# m_get_publication.return_value = self.json_publication_raw_mock
|
104
|
+
# obj = api.content.create(
|
105
|
+
# container=self.files_section,
|
106
|
+
# type="imio.smartweb.Publication",
|
107
|
+
# id="18820593",
|
108
|
+
# )
|
109
|
+
# obj.reindexObject()
|
110
|
+
# title_to_get = (
|
111
|
+
# "Ordonnance concernant des mesures spécifiques en cas de grand froid."
|
112
|
+
# )
|
115
113
|
|
116
|
-
|
117
|
-
|
118
|
-
|
114
|
+
# view = queryMultiAdapter((self.files_section, self.request), name="full_view")
|
115
|
+
# self.assertIn(title_to_get, view())
|
116
|
+
# self.assertNotIn("013400000123949.PDF", view())
|
119
117
|
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
118
|
+
# view = queryMultiAdapter((self.files_section, self.request), name="table_view")
|
119
|
+
# self.assertIn(title_to_get, [item[0]["title"] for item in view.items()])
|
120
|
+
# self.assertEqual(
|
121
|
+
# [
|
122
|
+
# item[0]["publication_attached_file"].get("filename")
|
123
|
+
# for item in view.items()
|
124
|
+
# ][0],
|
125
|
+
# "013400000123949.PDF",
|
126
|
+
# )
|
127
|
+
# self.assertEqual(
|
128
|
+
# [item[0]["publication_document_type"] for item in view.items()][0],
|
129
|
+
# "Ordonnance de police administrative",
|
130
|
+
# )
|
131
|
+
# self.assertEqual(
|
132
|
+
# [item[0]["publication_datetime"] for item in view.items()][0],
|
133
|
+
# "2024-08-14T09:14:31",
|
134
|
+
# )
|
@@ -0,0 +1,120 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
from imio.smartweb.core.contents.rest.base import BaseEndpoint
|
3
|
+
from imio.smartweb.core.contents.rest.campaign.endpoint import CampaignEndpoint
|
4
|
+
from imio.smartweb.core.contents import ICampaignView
|
5
|
+
from imio.smartweb.core.tests.utils import get_json
|
6
|
+
|
7
|
+
from imio.smartweb.core.testing import IMIO_SMARTWEB_CORE_INTEGRATION_TESTING
|
8
|
+
from imio.smartweb.core.testing import ImioSmartwebTestCase
|
9
|
+
from plone import api
|
10
|
+
from plone.app.testing import setRoles
|
11
|
+
from plone.app.testing import TEST_USER_ID
|
12
|
+
from plone.dexterity.interfaces import IDexterityFTI
|
13
|
+
from unittest.mock import patch
|
14
|
+
from zope.component import createObject
|
15
|
+
from zope.component import queryMultiAdapter
|
16
|
+
from zope.component import queryUtility
|
17
|
+
from zope.publisher.browser import TestRequest
|
18
|
+
|
19
|
+
import json
|
20
|
+
import requests_mock
|
21
|
+
|
22
|
+
|
23
|
+
class TestIdeabox(ImioSmartwebTestCase):
|
24
|
+
layer = IMIO_SMARTWEB_CORE_INTEGRATION_TESTING
|
25
|
+
|
26
|
+
def setUp(self):
|
27
|
+
"""Custom shared utility setup for tests."""
|
28
|
+
self.portal = self.layer["portal"]
|
29
|
+
self.request = self.layer["request"]
|
30
|
+
setRoles(self.portal, TEST_USER_ID, ["Manager"])
|
31
|
+
self.folder = api.content.create(
|
32
|
+
container=self.portal,
|
33
|
+
type="imio.smartweb.Folder",
|
34
|
+
title="A Folder",
|
35
|
+
)
|
36
|
+
self.json_campaigns_raw_mock = get_json("resources/json_ideabox_campaigns.json")
|
37
|
+
self.json_campaign_raw_mock = get_json("resources/json_ideabox_campaign.json")
|
38
|
+
|
39
|
+
def test_ct_publication_schema(self):
|
40
|
+
fti = queryUtility(IDexterityFTI, name="imio.smartweb.CampaignView")
|
41
|
+
schema = fti.lookupSchema()
|
42
|
+
self.assertEqual(ICampaignView, schema)
|
43
|
+
|
44
|
+
def test_ct_publication_fti(self):
|
45
|
+
fti = queryUtility(IDexterityFTI, name="imio.smartweb.CampaignView")
|
46
|
+
self.assertTrue(fti)
|
47
|
+
|
48
|
+
def test_ct_publication_factory(self):
|
49
|
+
fti = queryUtility(IDexterityFTI, name="imio.smartweb.CampaignView")
|
50
|
+
factory = fti.factory
|
51
|
+
obj = createObject(factory)
|
52
|
+
self.assertTrue(
|
53
|
+
ICampaignView.providedBy(obj),
|
54
|
+
"ICampaignView not provided by {0}!".format(
|
55
|
+
obj,
|
56
|
+
),
|
57
|
+
)
|
58
|
+
|
59
|
+
@patch("imio.smartweb.core.subscribers.get_basic_auth_json")
|
60
|
+
@patch("imio.smartweb.core.subscribers.get_value_from_registry")
|
61
|
+
@patch("imio.smartweb.core.contents.rest.campaign.content.get_basic_auth_json")
|
62
|
+
@patch("imio.smartweb.core.contents.rest.campaign.content.get_value_from_registry")
|
63
|
+
def test_get_campaign(
|
64
|
+
self,
|
65
|
+
m_get_value_from_registry_namechooser,
|
66
|
+
m_get_basic_auth_json_namechooser,
|
67
|
+
m_get_value_from_registry,
|
68
|
+
m_get_basic_auth_json,
|
69
|
+
):
|
70
|
+
m_get_value_from_registry.return_value = (
|
71
|
+
"https://staging3-formulaires.guichet-citoyen.be/api"
|
72
|
+
)
|
73
|
+
m_get_basic_auth_json.return_value = self.json_campaign_raw_mock
|
74
|
+
|
75
|
+
m_get_value_from_registry_namechooser.return_value = (
|
76
|
+
"https://staging3-formulaires.guichet-citoyen.be/api"
|
77
|
+
)
|
78
|
+
m_get_basic_auth_json_namechooser.return_value = self.json_campaign_raw_mock
|
79
|
+
campaign_view = api.content.create(
|
80
|
+
title="kamoulox",
|
81
|
+
container=self.folder,
|
82
|
+
type="imio.smartweb.CampaignView",
|
83
|
+
linked_campaign="2",
|
84
|
+
)
|
85
|
+
self.assertEqual(campaign_view.title, "Sprint iMio Fall 2024")
|
86
|
+
self.assertEqual(campaign_view.id, "sprint-imio-fall-2024")
|
87
|
+
|
88
|
+
@requests_mock.Mocker()
|
89
|
+
@patch("imio.smartweb.core.subscribers.get_basic_auth_json")
|
90
|
+
@patch("imio.smartweb.core.subscribers.get_value_from_registry")
|
91
|
+
def test_get_projects(self, m_get_value_from_registry, m_get_basic_auth_json, m):
|
92
|
+
m_get_value_from_registry.return_value = (
|
93
|
+
"https://staging3-formulaires.guichet-citoyen.be/api"
|
94
|
+
)
|
95
|
+
m_get_basic_auth_json.return_value = self.json_campaign_raw_mock
|
96
|
+
campaign_view = api.content.create(
|
97
|
+
id="kamoulox",
|
98
|
+
container=self.folder,
|
99
|
+
type="imio.smartweb.CampaignView",
|
100
|
+
linked_campaign="2",
|
101
|
+
)
|
102
|
+
# react additionnal fields request.
|
103
|
+
# form={
|
104
|
+
# "taxonomy_contact_category_for_filtering": ("token"),
|
105
|
+
# "topics": "education",
|
106
|
+
# }
|
107
|
+
|
108
|
+
request = TestRequest()
|
109
|
+
endpoint = CampaignEndpoint(campaign_view, request)
|
110
|
+
url = endpoint.query_url
|
111
|
+
self.assertEqual(
|
112
|
+
url,
|
113
|
+
"https://demo-formulaires.guichet-citoyen.be/api/cards/imio-ideabox-projet/list?campagne=2&full=on&filter-statut=Vote|Enregistr%C3%A9e&filter-statut-operator=in&",
|
114
|
+
)
|
115
|
+
|
116
|
+
m.get(url, text=json.dumps({}))
|
117
|
+
call = endpoint()
|
118
|
+
self.assertEqual(call, {})
|
119
|
+
|
120
|
+
# to be continued
|
@@ -22,7 +22,9 @@ from zope.viewlet.interfaces import IViewletManager
|
|
22
22
|
import json
|
23
23
|
import requests_mock
|
24
24
|
|
25
|
-
|
25
|
+
# formdefs/
|
26
|
+
GUICHET_URL = "https://demo.guichet-citoyen.be/api/"
|
27
|
+
WCS_URL = "https://demo-formulaires.guichet-citoyen.be/api/"
|
26
28
|
|
27
29
|
|
28
30
|
class TestProcedure(ImioSmartwebTestCase):
|
@@ -102,7 +104,8 @@ class TestProcedure(ImioSmartwebTestCase):
|
|
102
104
|
|
103
105
|
@requests_mock.Mocker()
|
104
106
|
def test_procedure_invariant(self, m):
|
105
|
-
|
107
|
+
url = f"{WCS_URL}formdefs/"
|
108
|
+
m.get(url, text=json.dumps(self.json_procedures_raw_mock))
|
106
109
|
request = TestRequest(
|
107
110
|
form={
|
108
111
|
"form.widgets.IBasic.title": "My Procedure",
|
@@ -145,7 +148,8 @@ class TestProcedure(ImioSmartwebTestCase):
|
|
145
148
|
|
146
149
|
@requests_mock.Mocker()
|
147
150
|
def test_procedure_viewlet(self, m):
|
148
|
-
|
151
|
+
url = f"{WCS_URL}formdefs/"
|
152
|
+
m.get(url, text=json.dumps(self.json_procedures_raw_mock))
|
149
153
|
procedure = api.content.create(
|
150
154
|
container=self.portal,
|
151
155
|
type="imio.smartweb.Procedure",
|
@@ -18,6 +18,7 @@ from plone.app.testing import TEST_USER_ID
|
|
18
18
|
from plone.app.testing import TEST_USER_PASSWORD
|
19
19
|
from plone.namedfile.file import NamedBlobImage
|
20
20
|
from plone.restapi.testing import RelativeSession
|
21
|
+
from unittest import mock
|
21
22
|
from unittest.mock import patch
|
22
23
|
from urllib.parse import urlparse
|
23
24
|
from urllib.parse import parse_qs
|
@@ -25,8 +26,10 @@ from zope.component import queryMultiAdapter
|
|
25
26
|
from zope.event import notify
|
26
27
|
from zope.publisher.browser import TestRequest
|
27
28
|
from ZPublisher.pubevents import PubStart
|
29
|
+
from imio.smartweb.core.viewlets.ogptags import OgpTagsViewlet
|
28
30
|
|
29
31
|
import json
|
32
|
+
import os
|
30
33
|
import requests_mock
|
31
34
|
import transaction
|
32
35
|
|
@@ -281,6 +284,7 @@ class SectionsFunctionalTest(ImioSmartwebTestCase):
|
|
281
284
|
self.assertIn('<meta property="og:image:width" content="400">', view())
|
282
285
|
self.assertIn('<meta property="og:image:height" content="400">', view())
|
283
286
|
|
287
|
+
# @mock.patch.dict(os.environ, {"client_id": "Kamoulox", "client_secret": "Kamoulox"})
|
284
288
|
@patch("imio.smartweb.core.viewlets.ogptags.get_wca_token")
|
285
289
|
@patch("imio.smartweb.core.viewlets.ogptags.get_json")
|
286
290
|
def test_render_rest_auth_sources_item(self, mock_get_json, mock_get_wca_token):
|
@@ -304,6 +308,9 @@ class SectionsFunctionalTest(ImioSmartwebTestCase):
|
|
304
308
|
}
|
305
309
|
UID = "3c436a800154449f84797fdb30561297"
|
306
310
|
self.request.form["u"] = UID
|
311
|
+
# viewlet = OgpTagsViewlet(self.portal, self.request, None, None)
|
312
|
+
# viewlet.update()
|
313
|
+
|
307
314
|
view = queryMultiAdapter(
|
308
315
|
(auth_source["content"], self.request), name="view"
|
309
316
|
)
|
@@ -10,6 +10,7 @@ from plone import api
|
|
10
10
|
from unittest.mock import patch
|
11
11
|
|
12
12
|
import json
|
13
|
+
import re
|
13
14
|
import requests
|
14
15
|
import requests_mock
|
15
16
|
|
@@ -38,7 +39,10 @@ class TestVocabularies(ImioSmartwebTestCase):
|
|
38
39
|
|
39
40
|
@requests_mock.Mocker()
|
40
41
|
def test_procedure_keys(self, m):
|
41
|
-
|
42
|
+
GUICHET = re.compile(
|
43
|
+
r"https://demo-formulaires\.guichet-citoyen\.be/api/formdefs/.*"
|
44
|
+
)
|
45
|
+
m.get(GUICHET, text=json.dumps(self.json_procedures_raw_mock))
|
42
46
|
self.assertVocabularyLen("imio.smartweb.vocabulary.PublikProcedures", 3)
|
43
47
|
vocabulary = get_vocabulary("imio.smartweb.vocabulary.PublikProcedures")
|
44
48
|
self.assertEqual(
|
@@ -59,12 +63,8 @@ class TestVocabularies(ImioSmartwebTestCase):
|
|
59
63
|
).title,
|
60
64
|
"Acte de mariage",
|
61
65
|
)
|
62
|
-
api.portal.set_registry_record(
|
63
|
-
"smartweb.url_formdefs_api",
|
64
|
-
"https://demo.guichet-citoyen.be/api/formdefs/?query=kamoulox",
|
65
|
-
)
|
66
66
|
m.get(
|
67
|
-
|
67
|
+
GUICHET,
|
68
68
|
text=json.dumps(self.json_procedures_raw_mock),
|
69
69
|
)
|
70
70
|
self.assertVocabularyLen("imio.smartweb.vocabulary.PublikProcedures", 3)
|
@@ -77,7 +77,7 @@ class TestVocabularies(ImioSmartwebTestCase):
|
|
77
77
|
m.get(GUICHET_URL, status_code=404)
|
78
78
|
self.assertVocabularyLen("imio.smartweb.vocabulary.PublikProcedures", 0)
|
79
79
|
|
80
|
-
api.portal.set_registry_record("smartweb.
|
80
|
+
api.portal.set_registry_record("smartweb.url_ts", "")
|
81
81
|
m.get(GUICHET_URL, text=json.dumps(self.json_procedures_raw_mock))
|
82
82
|
self.assertVocabularyLen("imio.smartweb.vocabulary.PublikProcedures", 0)
|
83
83
|
|
@@ -316,9 +316,7 @@ class TestVocabularies(ImioSmartwebTestCase):
|
|
316
316
|
"Waremme",
|
317
317
|
)
|
318
318
|
|
319
|
-
@patch(
|
320
|
-
"imio.smartweb.core.vocabularies.get_iadeliberation_institution_from_registry"
|
321
|
-
)
|
319
|
+
@patch("imio.smartweb.core.vocabularies.get_value_from_registry")
|
322
320
|
@patch("imio.smartweb.core.vocabularies.get_iadeliberation_url_from_registry")
|
323
321
|
@requests_mock.Mocker()
|
324
322
|
def test_remote_iadeliberations_publications(self, m_url, m_institution, m):
|
@@ -944,6 +944,22 @@
|
|
944
944
|
import_profile="imio.smartweb.core.upgrades:upgrade_1063_to_1064"
|
945
945
|
/>
|
946
946
|
</genericsetup:upgradeSteps>
|
947
|
+
|
948
|
+
<genericsetup:upgradeStep
|
949
|
+
title="Update control panel combo api url"
|
950
|
+
source="1064"
|
951
|
+
destination="1065"
|
952
|
+
handler=".upgrades.update_control_panel_combo_api_url"
|
953
|
+
profile="imio.smartweb.core:default"
|
954
|
+
/>
|
955
|
+
|
956
|
+
<genericsetup:upgradeStep
|
957
|
+
title="Update control panel combo api fieldname"
|
958
|
+
source="1065"
|
959
|
+
destination="1066"
|
960
|
+
handler=".upgrades.update_control_panel_combo_api_fieldname"
|
961
|
+
profile="imio.smartweb.core:default"
|
962
|
+
/>
|
947
963
|
|
948
964
|
<!--genericsetup:upgradeStep
|
949
965
|
title="Check contact itinerary if address was checked in visible blocks"
|
@@ -953,5 +969,4 @@
|
|
953
969
|
handler=".upgrades.migrate_external_links"
|
954
970
|
profile="imio.smartweb.core:default"
|
955
971
|
/-->
|
956
|
-
|
957
972
|
</configure>
|
@@ -2,14 +2,18 @@
|
|
2
2
|
|
3
3
|
from imio.smartweb.core.browser.controlpanel import ISmartwebControlPanel
|
4
4
|
from imio.smartweb.core.contents import IPages
|
5
|
+
from imio.smartweb.locales import SmartwebMessageFactory as _
|
5
6
|
from eea.facetednavigation.interfaces import ICriteria
|
6
7
|
from eea.facetednavigation.subtypes.interfaces import IFacetedNavigable
|
7
8
|
from plone import api
|
8
9
|
from plone.app.imagecropping import PAI_STORAGE_KEY
|
10
|
+
from plone.registry import field
|
11
|
+
from plone.registry import Record
|
9
12
|
from plone.registry.interfaces import IRegistry
|
10
13
|
from zope.annotation.interfaces import IAnnotations
|
11
14
|
from zope.component import getUtility
|
12
15
|
from zope.schema import getFieldNames
|
16
|
+
from zope.schema import TextLine
|
13
17
|
|
14
18
|
import logging
|
15
19
|
|
@@ -227,3 +231,63 @@ def migrate_old_sizes_from_section_text(context):
|
|
227
231
|
logger.info(
|
228
232
|
f"Migrated deprecated scale from {old_scale} to {new_scale} for {obj.absolute_url()}"
|
229
233
|
)
|
234
|
+
|
235
|
+
|
236
|
+
def update_control_panel_combo_api_url(context):
|
237
|
+
url_ts = ""
|
238
|
+
try:
|
239
|
+
url_ts = api.portal.get_registry_record("smartweb.url_formdefs_api") or ""
|
240
|
+
except:
|
241
|
+
logger.info("La clé 'smartweb.url_formdefs_api' a été supprimée.")
|
242
|
+
return
|
243
|
+
url_ts = url_ts.replace("/api", "")
|
244
|
+
url_ts = url_ts.replace("-formulaires", "")
|
245
|
+
api.portal.set_registry_record("smartweb.url_formdefs_api", url_ts)
|
246
|
+
|
247
|
+
|
248
|
+
def update_control_panel_combo_api_fieldname(context):
|
249
|
+
url_ts = ""
|
250
|
+
try:
|
251
|
+
url_ts = api.portal.get_registry_record("smartweb.url_formdefs_api") or ""
|
252
|
+
except:
|
253
|
+
logger.info("La clé 'smartweb.url_formdefs_api' a été supprimée.")
|
254
|
+
registry = getUtility(IRegistry)
|
255
|
+
records = registry.records
|
256
|
+
if "smartweb.url_ts" in records:
|
257
|
+
return
|
258
|
+
logger.info("Adding smartweb.url_ts to registry") # noqa
|
259
|
+
record = Record(
|
260
|
+
field.TextLine(
|
261
|
+
title=_("Url to e-guichet"),
|
262
|
+
description=_("Exemple : https://COMMUNE.guichet-citoyen.be"),
|
263
|
+
required=False,
|
264
|
+
),
|
265
|
+
value=url_ts,
|
266
|
+
)
|
267
|
+
records["smartweb.url_ts"] = record
|
268
|
+
|
269
|
+
record = Record(
|
270
|
+
field.TextLine(
|
271
|
+
title=_(
|
272
|
+
"Username to consume e-guichet ideabox API (get Campaign, projects,...)"
|
273
|
+
),
|
274
|
+
default="ideabox",
|
275
|
+
required=False,
|
276
|
+
)
|
277
|
+
)
|
278
|
+
records["smartweb.iaideabox_api_username"] = record
|
279
|
+
|
280
|
+
record = Record(
|
281
|
+
field.Password(
|
282
|
+
title=_(
|
283
|
+
"Password to consume e-guichet ideabox API (get Campaign, projects,...)"
|
284
|
+
),
|
285
|
+
required=False,
|
286
|
+
)
|
287
|
+
)
|
288
|
+
records["smartweb.iaideabox_api_password"] = record
|
289
|
+
try:
|
290
|
+
del registry.records["smartweb.url_formdefs_api"]
|
291
|
+
logger.info("La clé 'smartweb.url_formdefs_api' a été supprimée.")
|
292
|
+
except KeyError:
|
293
|
+
logger.info("La clé 'smartweb.url_formdefs_api' n'existe pas dans le registre.")
|
imio/smartweb/core/utils.py
CHANGED
@@ -12,6 +12,7 @@ from plone.dexterity.interfaces import IDexterityContent
|
|
12
12
|
from Products.CMFPlone.defaultpage import get_default_page
|
13
13
|
from Products.CMFPlone.interfaces.siteroot import IPloneSiteRoot
|
14
14
|
from Products.CMFPlone.utils import base_hasattr
|
15
|
+
from urllib.parse import urlparse, urlunparse
|
15
16
|
from zope.component import getSiteManager
|
16
17
|
from zope.component import queryMultiAdapter
|
17
18
|
|
@@ -204,6 +205,11 @@ def get_plausible_vars():
|
|
204
205
|
return None
|
205
206
|
|
206
207
|
|
208
|
+
def get_value_from_registry(key):
|
209
|
+
val = api.portal.get_registry_record(key)
|
210
|
+
return val
|
211
|
+
|
212
|
+
|
207
213
|
def get_iadeliberation_url_from_registry():
|
208
214
|
iadeliberation_url = api.portal.get_registry_record("smartweb.iadeliberations_url")
|
209
215
|
return iadeliberation_url
|
@@ -230,6 +236,33 @@ def get_iadeliberation_json(url):
|
|
230
236
|
return json
|
231
237
|
|
232
238
|
|
239
|
+
def get_iaideabox_json(url):
|
240
|
+
user = api.portal.get_registry_record("smartweb.iaideabox_api_username")
|
241
|
+
pwd = api.portal.get_registry_record("smartweb.iaideabox_api_password")
|
242
|
+
usrPass = f"{user}:{pwd}".encode("utf-8")
|
243
|
+
b64Val = base64.b64encode(usrPass)
|
244
|
+
json = get_json(url, auth=f"Basic {b64Val.decode('utf-8')}", timeout=20)
|
245
|
+
return json
|
246
|
+
|
247
|
+
|
248
|
+
def get_basic_auth_json(url, user, pwd):
|
249
|
+
usrPass = f"{user}:{pwd}".encode("utf-8")
|
250
|
+
b64Val = base64.b64encode(usrPass)
|
251
|
+
json = get_json(url, auth=f"Basic {b64Val.decode('utf-8')}", timeout=20)
|
252
|
+
return json
|
253
|
+
|
254
|
+
|
255
|
+
def get_ts_api_url(service="wcs"):
|
256
|
+
url_ts = get_value_from_registry("smartweb.url_ts")
|
257
|
+
parsed_url = urlparse(url_ts)
|
258
|
+
if "wcs" in service:
|
259
|
+
new_netloc = parsed_url.netloc.replace(
|
260
|
+
".guichet-citoyen.be", "-formulaires.guichet-citoyen.be"
|
261
|
+
)
|
262
|
+
api_url = urlunparse(parsed_url._replace(netloc=new_netloc, path="/api"))
|
263
|
+
return api_url
|
264
|
+
|
265
|
+
|
233
266
|
def remove_cache_key(json_data: dict) -> dict:
|
234
267
|
pattern = re.compile(r"&cache_key=[a-f0-9]{32}")
|
235
268
|
if json_data is None:
|
@@ -1,7 +1,10 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
|
3
|
+
from imio.smartweb.locales import SmartwebMessageFactory as _
|
4
|
+
from plone import api
|
3
5
|
from plone.app.layout.viewlets import common
|
4
6
|
from zope.component import getMultiAdapter
|
7
|
+
from zope.i18n import translate
|
5
8
|
from zope.viewlet.interfaces import IViewletManager
|
6
9
|
|
7
10
|
|
@@ -10,7 +13,14 @@ class HeaderActionsViewlet(common.ViewletBase):
|
|
10
13
|
context_state = getMultiAdapter(
|
11
14
|
(self.context, self.request), name="plone_context_state"
|
12
15
|
)
|
16
|
+
language = api.portal.get_current_language(context=self.context)
|
13
17
|
self.actions = context_state.actions("header_actions")
|
18
|
+
for action in self.actions:
|
19
|
+
if action["id"] == "account":
|
20
|
+
action["link_target"] = "_blank"
|
21
|
+
desc = translate(_(action["description"]), target_language=language)
|
22
|
+
new_tab = translate(_("New tab"), target_language=language)
|
23
|
+
action["description"] = f"{desc} ({new_tab})"
|
14
24
|
|
15
25
|
|
16
26
|
class HeaderActionsContainerViewlet(common.ViewletBase):
|
@@ -1,13 +1,38 @@
|
|
1
1
|
<div class="offcanvas offcanvas-start" tabindex="-1" id="offcanvasSearch" aria-labelledby="offcanvasSearchLabel">
|
2
2
|
<div class="offcanvas-header">
|
3
|
-
<button type="button" class="btn-close text-reset" data-bs-dismiss="offcanvas" aria-label="Close"></button>
|
3
|
+
<button type="button" class="btn-close text-reset" data-bs-dismiss="offcanvas" aria-label="Close" tabindex="-1"></button>
|
4
4
|
</div>
|
5
5
|
<div class="offcanvas-body">
|
6
|
-
<div class="search">
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
6
|
+
<div class="search" id="search-container">
|
7
|
+
<template id="search-template">
|
8
|
+
<smartweb-search tal:attributes="current-language view/current_language;
|
9
|
+
query-url view/navroot_url;
|
10
|
+
result-option view/get_search_result_option">
|
11
|
+
</smartweb-search>
|
12
|
+
</template>
|
11
13
|
</div>
|
12
14
|
</div>
|
13
15
|
</div>
|
16
|
+
|
17
|
+
<script>
|
18
|
+
document.addEventListener('DOMContentLoaded', function() {
|
19
|
+
const offcanvas = document.getElementById('offcanvasSearch');
|
20
|
+
const searchContainer = document.getElementById('search-container');
|
21
|
+
const template = document.getElementById('search-template');
|
22
|
+
let searchContent = null;
|
23
|
+
|
24
|
+
offcanvas.addEventListener('show.bs.offcanvas', function () {
|
25
|
+
if (!searchContent) {
|
26
|
+
searchContent = template.content.cloneNode(true);
|
27
|
+
searchContainer.appendChild(searchContent);
|
28
|
+
}
|
29
|
+
});
|
30
|
+
|
31
|
+
offcanvas.addEventListener('hidden.bs.offcanvas', function () {
|
32
|
+
if (searchContent) {
|
33
|
+
searchContainer.innerHTML = '';
|
34
|
+
searchContent = null;
|
35
|
+
}
|
36
|
+
});
|
37
|
+
});
|
38
|
+
</script>
|
@@ -55,6 +55,13 @@ class OgpTagsViewlet(HeaderViewlet):
|
|
55
55
|
self._set_image()
|
56
56
|
|
57
57
|
def set_ogp_informations_for_item(self):
|
58
|
+
result_json = None
|
59
|
+
if (
|
60
|
+
not IDirectoryView.providedBy(self.context)
|
61
|
+
and not IEventsView.providedBy(self.context)
|
62
|
+
and not INewsView.providedBy(self.context)
|
63
|
+
):
|
64
|
+
return result_json
|
58
65
|
uid = self.request.form["u"]
|
59
66
|
auth_source_url = ""
|
60
67
|
endpoint = "@search"
|
@@ -75,6 +82,8 @@ class OgpTagsViewlet(HeaderViewlet):
|
|
75
82
|
client_id = os.environ.get("RESTAPI_NEWS_CLIENT_ID")
|
76
83
|
client_secret = os.environ.get("RESTAPI_NEWS_CLIENT_SECRET")
|
77
84
|
auth = get_wca_token(client_id, client_secret)
|
85
|
+
if not auth:
|
86
|
+
return
|
78
87
|
auth_source_url = f"{auth_source_url}/{endpoint}?UID={uid}&{params}"
|
79
88
|
result_json = get_json(auth_source_url, auth=auth)
|
80
89
|
if result_json:
|
@@ -1,5 +1,5 @@
|
|
1
1
|
<div id="subsite-logo" tal:condition="view/available">
|
2
|
-
<a tal:attributes="href string:${view/subsite_root/absolute_url}">
|
2
|
+
<a tal:attributes="href string:${view/subsite_root/absolute_url}; aria-label string:accueil du sous-site">
|
3
3
|
<img tal:condition="view/show_logo"
|
4
4
|
tal:attributes="src view/get_logo_scale_url;
|
5
5
|
alt view/subsite_root/title;
|