imio.smartweb.core 1.3__py3-none-any.whl → 1.3.2__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/configure.zcml +16 -0
- imio/smartweb/core/browser/search/search.py +15 -0
- imio/smartweb/core/browser/sitemap.py +162 -110
- imio/smartweb/core/contents/rest/base.py +5 -2
- imio/smartweb/core/contents/rest/campaign/endpoint.py +3 -3
- imio/smartweb/core/contents/rest/directory/endpoint.py +11 -3
- imio/smartweb/core/contents/rest/events/endpoint.py +11 -3
- imio/smartweb/core/contents/rest/news/endpoint.py +11 -3
- imio/smartweb/core/contents/rest/search/endpoint.py +4 -1
- imio/smartweb/core/contents/rest/utils.py +3 -3
- imio/smartweb/core/interfaces.py +2 -0
- imio/smartweb/core/profiles/default/metadata.xml +1 -1
- imio/smartweb/core/profiles/default/types/imio.smartweb.SectionTimestampedPublications.xml +4 -0
- imio/smartweb/core/profiles/default/types.xml +1 -0
- imio/smartweb/core/profiles/default/workflows.xml +1 -0
- imio/smartweb/core/tests/test_ideabox.py +33 -1
- imio/smartweb/core/tests/test_rest.py +1 -3
- imio/smartweb/core/tests/test_sitemap.py +98 -40
- imio/smartweb/core/tests/test_vocabulary.py +18 -0
- imio/smartweb/core/upgrades/configure.zcml +19 -0
- imio/smartweb/core/upgrades/profiles/1061_to_1062/types/imio.smartweb.SectionTimestampedPublications.xml +1 -5
- imio/smartweb/core/upgrades/profiles/1066_to_1067/types/imio.smartweb.SectionTimestampedPublications.xml +39 -0
- imio/smartweb/core/viewlets/offcanvas.pt +2 -0
- imio/smartweb/core/webcomponents/build/css/919.smartweb-webcomponents-compiled.css +1 -1
- imio/smartweb/core/webcomponents/build/js/373.smartweb-webcomponents-compiled.js +1 -1
- imio/smartweb/core/webcomponents/build/js/666.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 -1
- imio/smartweb/core/webcomponents/src/components/Search/Search.jsx +54 -9
- imio/smartweb/core/webcomponents/src/components/Search/Search.scss +9 -0
- imio/smartweb/core/webcomponents/src/utils/translation.js +12 -0
- {imio.smartweb.core-1.3.dist-info → imio.smartweb.core-1.3.2.dist-info}/METADATA +27 -1
- {imio.smartweb.core-1.3.dist-info → imio.smartweb.core-1.3.2.dist-info}/RECORD +39 -38
- /imio.smartweb.core-1.3-py3.12-nspkg.pth → /imio.smartweb.core-1.3.2-py3.12-nspkg.pth +0 -0
- {imio.smartweb.core-1.3.dist-info → imio.smartweb.core-1.3.2.dist-info}/LICENSE.GPL +0 -0
- {imio.smartweb.core-1.3.dist-info → imio.smartweb.core-1.3.2.dist-info}/LICENSE.rst +0 -0
- {imio.smartweb.core-1.3.dist-info → imio.smartweb.core-1.3.2.dist-info}/WHEEL +0 -0
- {imio.smartweb.core-1.3.dist-info → imio.smartweb.core-1.3.2.dist-info}/namespace_packages.txt +0 -0
- {imio.smartweb.core-1.3.dist-info → imio.smartweb.core-1.3.2.dist-info}/top_level.txt +0 -0
@@ -96,6 +96,22 @@
|
|
96
96
|
layer="imio.smartweb.core.interfaces.IImioSmartwebCoreLayer"
|
97
97
|
/>
|
98
98
|
|
99
|
+
<adapter
|
100
|
+
factory="imio.smartweb.core.browser.sitemap.SitemapNavtreeStrategy"
|
101
|
+
provides="imio.smartweb.core.browser.sitemap.ISmartwebNavtreeStrategy"
|
102
|
+
for="*
|
103
|
+
imio.smartweb.core.interfaces.IImioSmartwebCoreLayer"
|
104
|
+
/>
|
105
|
+
|
106
|
+
<browser:page
|
107
|
+
name="sitemap_builder_view"
|
108
|
+
for="*"
|
109
|
+
class=".sitemap.CatalogSiteMap"
|
110
|
+
allowed_attributes="siteMap"
|
111
|
+
permission="zope.Public"
|
112
|
+
layer="imio.smartweb.core.interfaces.IImioSmartwebCoreLayer"
|
113
|
+
/>
|
114
|
+
|
99
115
|
<browser:page
|
100
116
|
name="events_view"
|
101
117
|
for="*"
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
|
3
|
+
from imio.smartweb.core.contents.rest.search.endpoint import get_default_view_url
|
3
4
|
from plone import api
|
4
5
|
from Products.CMFPlone.browser.search import Search
|
5
6
|
from Products.CMFPlone.utils import normalizeString
|
@@ -68,6 +69,20 @@ class Search(Search):
|
|
68
69
|
|
69
70
|
return json.dumps(response)
|
70
71
|
|
72
|
+
@property
|
73
|
+
def are_views_available(self):
|
74
|
+
news = False if get_default_view_url("news") == "" else True
|
75
|
+
events = False if get_default_view_url("events") == "" else True
|
76
|
+
directory = False if get_default_view_url("directory") == "" else True
|
77
|
+
return json.dumps({"news": news, "events": events, "directory": directory})
|
78
|
+
|
79
|
+
@property
|
80
|
+
def context_user_has_roles(self):
|
81
|
+
# is current user has more role(s) than just authenticated
|
82
|
+
if len(api.user.get_roles()) > 1:
|
83
|
+
return True
|
84
|
+
return False
|
85
|
+
|
71
86
|
@property
|
72
87
|
def current_language(self):
|
73
88
|
return api.portal.get_current_language()[:2]
|
@@ -1,49 +1,111 @@
|
|
1
|
+
from Acquisition import aq_inner
|
1
2
|
from BTrees.OOBTree import OOBTree
|
2
|
-
from imio.smartweb.core.
|
3
|
-
from imio.smartweb.core.
|
4
|
-
from imio.smartweb.core.
|
5
|
-
from imio.smartweb.core.
|
6
|
-
from
|
7
|
-
from plone import api
|
8
|
-
from plone.base.interfaces import IPloneSiteRoot
|
3
|
+
from imio.smartweb.core.contents.rest.directory.endpoint import DirectoryEndpointGet
|
4
|
+
from imio.smartweb.core.contents.rest.events.endpoint import EventsEndpointGet
|
5
|
+
from imio.smartweb.core.contents.rest.news.endpoint import NewsEndpointGet
|
6
|
+
from imio.smartweb.core.interfaces import IImioSmartwebCoreLayer
|
7
|
+
from plone.app.layout.navigation.navtree import buildFolderTree
|
9
8
|
from plone.app.layout.sitemap.sitemap import SiteMapView
|
10
|
-
from plone.
|
9
|
+
from plone.base.interfaces import IPloneSiteRoot
|
10
|
+
from plone.memoize import ram
|
11
|
+
from Products.CMFPlone.browser.navigation import CatalogSiteMap as BaseCatalogSiteMap
|
12
|
+
from Products.CMFPlone.browser.navtree import (
|
13
|
+
SitemapNavtreeStrategy as BaseSitemapNavtreeStrategy,
|
14
|
+
)
|
15
|
+
from Products.CMFPlone.browser.navtree import (
|
16
|
+
SitemapQueryBuilder as BaseSitemapQueryBuilder,
|
17
|
+
)
|
11
18
|
from Products.CMFCore.utils import getToolByName
|
12
19
|
from Products.CMFPlone.utils import normalizeString
|
13
|
-
from zope.component import
|
20
|
+
from zope.component import getMultiAdapter
|
21
|
+
from zope.interface import implementer
|
22
|
+
from zope.interface import Interface
|
14
23
|
|
15
24
|
import logging
|
25
|
+
import Missing
|
26
|
+
import time
|
16
27
|
|
17
28
|
logger = logging.getLogger("imio.smartweb.core")
|
18
29
|
|
19
30
|
|
31
|
+
FRIENDLY_TYPES = [
|
32
|
+
"Collection",
|
33
|
+
"Image",
|
34
|
+
"Link",
|
35
|
+
"imio.smartweb.Folder",
|
36
|
+
"imio.smartweb.Page",
|
37
|
+
"imio.smartweb.PortalPage",
|
38
|
+
"imio.smartweb.Procedure",
|
39
|
+
"imio.smartweb.CirkwiView",
|
40
|
+
"imio.smartweb.DirectoryView",
|
41
|
+
"imio.smartweb.EventsView",
|
42
|
+
"imio.smartweb.NewsView",
|
43
|
+
]
|
44
|
+
|
45
|
+
|
46
|
+
def cache_key(method, obj, request):
|
47
|
+
"""We cache data from authentic sources for the sitemap (.xml.gz) for 2 hours."""
|
48
|
+
return f"sitemap_{obj.UID()}_{time.time() // 7200}"
|
49
|
+
|
50
|
+
|
51
|
+
@ram.cache(cache_key)
|
52
|
+
def get_endpoint_data(obj, request):
|
53
|
+
endpoint_mapping = {
|
54
|
+
"imio.smartweb.DirectoryView": DirectoryEndpointGet,
|
55
|
+
"imio.smartweb.EventsView": EventsEndpointGet,
|
56
|
+
"imio.smartweb.NewsView": NewsEndpointGet,
|
57
|
+
}
|
58
|
+
endpoint_class = endpoint_mapping.get(obj.portal_type)
|
59
|
+
if not endpoint_class:
|
60
|
+
return {}
|
61
|
+
|
62
|
+
endpoint = endpoint_class()
|
63
|
+
batch_size = 1000 if obj.portal_type == "imio.smartweb.DirectoryView" else 365
|
64
|
+
return (
|
65
|
+
endpoint.reply_for_given_object(
|
66
|
+
obj, request, fullobjects=0, batch_size=batch_size
|
67
|
+
)
|
68
|
+
or {}
|
69
|
+
)
|
70
|
+
|
71
|
+
|
72
|
+
def format_sitemap_items(items, base_url):
|
73
|
+
"""Format items for sitemap(.xml.gz)"""
|
74
|
+
formatted_items = []
|
75
|
+
for item in items:
|
76
|
+
item_id = normalizeString(item.get("title"))
|
77
|
+
item_uid = item.get("id")
|
78
|
+
lastmod = item.get("modified") or "1970-01-01T00:00:00Z"
|
79
|
+
formatted_items.append(
|
80
|
+
{
|
81
|
+
"loc": f"{base_url}/{item_id}?u={item_uid}",
|
82
|
+
"lastmod": lastmod,
|
83
|
+
"Title": item.get("title"),
|
84
|
+
"Description": item.get("description", ""),
|
85
|
+
"getURL": f"{base_url}/{item_id}?u={item_uid}",
|
86
|
+
"getRemoteUrl": Missing.Value,
|
87
|
+
"currentItem": False,
|
88
|
+
"currentParent": False,
|
89
|
+
"normalized_review_state": "published",
|
90
|
+
"normalized_portal_type": "imio-smartweb-authsources-item",
|
91
|
+
}
|
92
|
+
)
|
93
|
+
return formatted_items
|
94
|
+
|
95
|
+
|
20
96
|
class CustomSiteMapView(SiteMapView):
|
97
|
+
"""Custom sitemap view. (get items for sitemap.xml.gz)"""
|
21
98
|
|
22
99
|
def objects(self):
|
23
100
|
"""Returns the data to create the sitemap."""
|
24
|
-
|
25
|
-
friendlytypes = [
|
26
|
-
"Link",
|
27
|
-
"imio.smartweb.Folder",
|
28
|
-
"LIF",
|
29
|
-
"LRF",
|
30
|
-
"imio.smartweb.Page",
|
31
|
-
"imio.smartweb.Procedure",
|
32
|
-
"File",
|
33
|
-
"Collection",
|
34
|
-
"imio.smartweb.PortalPage",
|
35
|
-
"Image",
|
36
|
-
"imio.smartweb.CirkwiView",
|
37
|
-
]
|
101
|
+
friendlytypes = FRIENDLY_TYPES
|
38
102
|
|
39
103
|
catalog = getToolByName(self.context, "portal_catalog")
|
40
|
-
query = {
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
registry.get("plone.types_use_view_action_in_listings", [])
|
46
|
-
)
|
104
|
+
query = {
|
105
|
+
"portal_type": getToolByName(
|
106
|
+
self.context, "plone_utils"
|
107
|
+
).getUserFriendlyTypes(friendlytypes)
|
108
|
+
}
|
47
109
|
|
48
110
|
is_plone_site_root = IPloneSiteRoot.providedBy(self.context)
|
49
111
|
if not is_plone_site_root:
|
@@ -56,93 +118,83 @@ class CustomSiteMapView(SiteMapView):
|
|
56
118
|
value = (item.modified.micros(), item.modified.ISO8601())
|
57
119
|
default_page_modified[key] = value
|
58
120
|
|
59
|
-
# The plone site root is not catalogued.
|
60
121
|
if is_plone_site_root:
|
61
122
|
loc = self.context.absolute_url()
|
62
123
|
date = self.context.modified()
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
modified = max(modified, default_modified)
|
68
|
-
lastmod = modified[1]
|
69
|
-
yield {
|
70
|
-
"loc": loc,
|
71
|
-
"lastmod": lastmod,
|
72
|
-
# 'changefreq': 'always',
|
73
|
-
# hourly/daily/weekly/monthly/yearly/never
|
74
|
-
# 'prioriy': 0.5, # 0.0 to 1.0
|
75
|
-
}
|
124
|
+
modified = max(
|
125
|
+
(date.micros(), date.ISO8601()), default_page_modified.get(loc, (0, ""))
|
126
|
+
)
|
127
|
+
yield {"loc": loc, "lastmod": modified[1]}
|
76
128
|
|
77
129
|
query["is_default_page"] = False
|
78
130
|
for item in catalog.searchResults(query):
|
79
131
|
loc = item.getURL()
|
80
132
|
date = item.modified
|
81
|
-
|
82
|
-
|
83
|
-
default_modified = default_page_modified.get(loc, None)
|
84
|
-
if default_modified is not None:
|
85
|
-
modified = max(modified, default_modified)
|
86
|
-
lastmod = modified[1]
|
87
|
-
if item.portal_type in typesUseViewActionInListings:
|
88
|
-
loc += "/view"
|
89
|
-
yield {
|
90
|
-
"loc": loc,
|
91
|
-
"lastmod": lastmod,
|
92
|
-
}
|
93
|
-
|
94
|
-
auth_sources = {
|
95
|
-
"directory": {
|
96
|
-
"entity_reg_var": "smartweb.directory_entity_uid",
|
97
|
-
"main_rest_view": "smartweb.default_directory_view",
|
98
|
-
"vocabulary": "imio.smartweb.vocabulary.RemoteDirectoryEntities",
|
99
|
-
"url": DIRECTORY_URL,
|
100
|
-
},
|
101
|
-
"events": {
|
102
|
-
"entity_reg_var": "smartweb.events_entity_uid",
|
103
|
-
"main_rest_view": "smartweb.default_events_view",
|
104
|
-
"vocabulary": "imio.smartweb.vocabulary.RemoteEventsEntities",
|
105
|
-
"url": EVENTS_URL,
|
106
|
-
},
|
107
|
-
"news": {
|
108
|
-
"entity_reg_var": "smartweb.news_entity_uid",
|
109
|
-
"main_rest_view": "smartweb.default_news_view",
|
110
|
-
"vocabulary": "imio.smartweb.vocabulary.RemoteNewsEntities",
|
111
|
-
"url": NEWS_URL,
|
112
|
-
},
|
113
|
-
}
|
114
|
-
for auth_source_key, auth_source_value in auth_sources.items():
|
115
|
-
entity_uid = api.portal.get_registry_record(
|
116
|
-
auth_source_value.get("entity_reg_var")
|
117
|
-
)
|
118
|
-
if entity_uid is None:
|
119
|
-
return self.request.response.setStatus(404, "No entity found")
|
120
|
-
entity_id = get_entity_id(auth_source_value.get("vocabulary"), entity_uid)
|
121
|
-
auth_source_uid = api.portal.get_registry_record(
|
122
|
-
f"smartweb.default_{auth_source_key}_view", default=None
|
133
|
+
modified = max(
|
134
|
+
(date.micros(), date.ISO8601()), default_page_modified.get(loc, (0, ""))
|
123
135
|
)
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
136
|
+
yield {"loc": loc, "lastmod": modified[1]}
|
137
|
+
|
138
|
+
brains = catalog(
|
139
|
+
portal_type=[
|
140
|
+
"imio.smartweb.EventsView",
|
141
|
+
"imio.smartweb.NewsView",
|
142
|
+
"imio.smartweb.DirectoryView",
|
143
|
+
]
|
144
|
+
)
|
145
|
+
for brain in brains:
|
146
|
+
obj = brain.getObject()
|
147
|
+
data = get_endpoint_data(obj, obj.REQUEST)
|
148
|
+
yield from format_sitemap_items(data.get("items", {}), obj.absolute_url())
|
149
|
+
|
150
|
+
|
151
|
+
@implementer(IImioSmartwebCoreLayer)
|
152
|
+
class CatalogSiteMap(BaseCatalogSiteMap):
|
153
|
+
def siteMap(self):
|
154
|
+
context = aq_inner(self.context)
|
155
|
+
|
156
|
+
queryBuilder = SitemapQueryBuilder(context)
|
157
|
+
query = queryBuilder()
|
158
|
+
strategy = getMultiAdapter((context, self), ISmartwebNavtreeStrategy)
|
159
|
+
base_folder_tree = buildFolderTree(
|
160
|
+
context, obj=context, query=query, strategy=strategy
|
161
|
+
)
|
162
|
+
|
163
|
+
for child in base_folder_tree.get("children"):
|
164
|
+
obj = child.get("item").getObject()
|
165
|
+
data = get_endpoint_data(obj, obj.REQUEST)
|
166
|
+
if not data:
|
139
167
|
continue
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
168
|
+
child["children"] = format_sitemap_items(
|
169
|
+
data.get("items", []), obj.absolute_url()
|
170
|
+
)
|
171
|
+
|
172
|
+
return base_folder_tree
|
173
|
+
|
174
|
+
|
175
|
+
class SitemapQueryBuilder(BaseSitemapQueryBuilder):
|
176
|
+
"""Builds the request for the sitemap with custom content types."""
|
177
|
+
|
178
|
+
def __init__(self, context):
|
179
|
+
self.context = context
|
180
|
+
|
181
|
+
def __call__(self):
|
182
|
+
query = {}
|
183
|
+
custom_query = getattr(self.context, "getCustomNavQuery", None)
|
184
|
+
if custom_query and callable(custom_query):
|
185
|
+
query = custom_query()
|
186
|
+
query["portal_type"] = FRIENDLY_TYPES
|
187
|
+
query["review_state"] = "published"
|
188
|
+
return query
|
189
|
+
|
190
|
+
|
191
|
+
class ISmartwebNavtreeStrategy(Interface):
|
192
|
+
"""Marker interface for the smartweb navtree strategy."""
|
193
|
+
|
194
|
+
|
195
|
+
@implementer(ISmartwebNavtreeStrategy)
|
196
|
+
class SitemapNavtreeStrategy(BaseSitemapNavtreeStrategy):
|
197
|
+
|
198
|
+
def nodeFilter(self, node):
|
199
|
+
# Return all nodes in sitemap even if they are exclude from nav
|
200
|
+
return True
|
@@ -15,9 +15,12 @@ class BaseEndpoint(object):
|
|
15
15
|
language = "fr"
|
16
16
|
remote_endpoint = ""
|
17
17
|
|
18
|
-
def __init__(self, context, request):
|
18
|
+
def __init__(self, context, request, fullobjects=1, batch_size=0):
|
19
|
+
|
19
20
|
self.context = context
|
20
21
|
self.request = request
|
22
|
+
self.fullobjects = fullobjects
|
23
|
+
self.batch_size = batch_size
|
21
24
|
|
22
25
|
def __call__(self):
|
23
26
|
results = get_json(self.query_url, timeout=20)
|
@@ -46,7 +49,7 @@ class BaseEndpoint(object):
|
|
46
49
|
item[f"{field}_full_scale"] = (
|
47
50
|
f"{item['@id']}/@@images/{field}/?cache_key={modified_hash}"
|
48
51
|
)
|
49
|
-
|
52
|
+
item.pop(field, None)
|
50
53
|
|
51
54
|
def construct_query_string(self, params):
|
52
55
|
params = "&".join(params)
|
@@ -107,7 +107,7 @@ class CampaignEndpoint(BaseTsEndpoint):
|
|
107
107
|
extra_params = [f"{k}={v}" for k, v in self.request.form.items()]
|
108
108
|
extra_params = "&".join(extra_params)
|
109
109
|
campaign_id = self.context.linked_campaign
|
110
|
-
url = f"{wcs_api}/cards/imio-ideabox-projet/list?campagne={campaign_id}&full=on&filter-statut=Vote|Enregistr%C3%A9e&filter-statut-operator=in&{extra_params}"
|
110
|
+
url = f"{wcs_api}/cards/imio-ideabox-projet/list?filter-campagne={campaign_id}&full=on&filter-statut=Vote|Enregistr%C3%A9e&filter-statut-operator=in&{extra_params}"
|
111
111
|
return url
|
112
112
|
|
113
113
|
|
@@ -124,7 +124,7 @@ class ZonesEndpoint(BaseTsEndpoint):
|
|
124
124
|
def query_url(self):
|
125
125
|
wcs_api = get_ts_api_url("wcs")
|
126
126
|
campaign_id = self.context.linked_campaign
|
127
|
-
return f"{wcs_api}/cards/imio-ideabox-zone/list?campagne={campaign_id}"
|
127
|
+
return f"{wcs_api}/cards/imio-ideabox-zone/list?filter-campagne={campaign_id}"
|
128
128
|
|
129
129
|
|
130
130
|
@implementer(IExpandableElement)
|
@@ -140,7 +140,7 @@ class TsTopicsEndpoint(BaseTsEndpoint):
|
|
140
140
|
def query_url(self):
|
141
141
|
wcs_api = get_ts_api_url("wcs")
|
142
142
|
campaign_id = self.context.linked_campaign
|
143
|
-
return f"{wcs_api}/cards/imio-ideabox-theme/list?campagne={campaign_id}"
|
143
|
+
return f"{wcs_api}/cards/imio-ideabox-theme/list?filter-campagne={campaign_id}"
|
144
144
|
|
145
145
|
|
146
146
|
@implementer(IExpandableElement)
|
@@ -13,7 +13,7 @@ from zope.interface import Interface
|
|
13
13
|
|
14
14
|
class BaseDirectoryEndpoint(BaseEndpoint):
|
15
15
|
def __call__(self):
|
16
|
-
results = super(BaseDirectoryEndpoint, self).__call__()
|
16
|
+
results = super(BaseDirectoryEndpoint, self).__call__() or {}
|
17
17
|
if not results.get("items"):
|
18
18
|
return results
|
19
19
|
orientation = self.context.orientation
|
@@ -45,10 +45,13 @@ class BaseDirectoryEndpoint(BaseEndpoint):
|
|
45
45
|
"metadata_fields=taxonomy_contact_category",
|
46
46
|
"metadata_fields=topics",
|
47
47
|
"metadata_fields=has_leadimage",
|
48
|
-
"fullobjects=
|
48
|
+
"fullobjects={}".format(self.fullobjects),
|
49
49
|
"sort_on=sortable_title",
|
50
|
-
"b_size={}".format(self.context.nb_results),
|
51
50
|
]
|
51
|
+
if self.batch_size == 0:
|
52
|
+
params.append("b_size={}".format(self.context.nb_results))
|
53
|
+
else:
|
54
|
+
params.append("b_size={}".format(self.batch_size))
|
52
55
|
if self.context.selected_categories is not None:
|
53
56
|
for category in self.context.selected_categories:
|
54
57
|
params.append(f"taxonomy_contact_category.query={category}")
|
@@ -74,6 +77,11 @@ class DirectoryEndpointGet(BaseService):
|
|
74
77
|
def reply(self):
|
75
78
|
return DirectoryEndpoint(self.context, self.request)()
|
76
79
|
|
80
|
+
def reply_for_given_object(self, obj, request, fullobjects=1, batch_size=0):
|
81
|
+
return DirectoryEndpoint(
|
82
|
+
obj, request, fullobjects=fullobjects, batch_size=batch_size
|
83
|
+
)()
|
84
|
+
|
77
85
|
|
78
86
|
class DirectoryFiltersEndpointGet(BaseService):
|
79
87
|
def reply(self):
|
@@ -12,7 +12,7 @@ from zope.interface import Interface
|
|
12
12
|
|
13
13
|
class BaseEventsEndpoint(BaseEndpoint):
|
14
14
|
def __call__(self):
|
15
|
-
results = super(BaseEventsEndpoint, self).__call__()
|
15
|
+
results = super(BaseEventsEndpoint, self).__call__() or {}
|
16
16
|
if not results or not results.get("items"):
|
17
17
|
return results
|
18
18
|
orientation = self.context.orientation
|
@@ -43,9 +43,12 @@ class BaseEventsEndpoint(BaseEndpoint):
|
|
43
43
|
"metadata_fields=has_leadimage",
|
44
44
|
"metadata_fields=UID",
|
45
45
|
"sort_on=event_dates",
|
46
|
-
"fullobjects=
|
47
|
-
"b_size={}".format(self.context.nb_results),
|
46
|
+
"fullobjects={}".format(self.fullobjects),
|
48
47
|
]
|
48
|
+
if self.batch_size == 0:
|
49
|
+
params.append("b_size={}".format(self.context.nb_results))
|
50
|
+
else:
|
51
|
+
params.append("b_size={}".format(self.batch_size))
|
49
52
|
if self.context.selected_event_types is not None:
|
50
53
|
for event_type in self.context.selected_event_types:
|
51
54
|
params.append(f"event_type={event_type}")
|
@@ -70,6 +73,11 @@ class EventsEndpointGet(BaseService):
|
|
70
73
|
def reply(self):
|
71
74
|
return EventsEndpoint(self.context, self.request)()
|
72
75
|
|
76
|
+
def reply_for_given_object(self, obj, request, fullobjects=1, batch_size=0):
|
77
|
+
return EventsEndpoint(
|
78
|
+
obj, request, fullobjects=fullobjects, batch_size=batch_size
|
79
|
+
)()
|
80
|
+
|
73
81
|
|
74
82
|
class EventsFiltersEndpointGet(BaseService):
|
75
83
|
def reply(self):
|
@@ -12,7 +12,7 @@ from zope.interface import Interface
|
|
12
12
|
|
13
13
|
class BaseNewsEndpoint(BaseEndpoint):
|
14
14
|
def __call__(self):
|
15
|
-
results = super(BaseNewsEndpoint, self).__call__()
|
15
|
+
results = super(BaseNewsEndpoint, self).__call__() or {}
|
16
16
|
if not results.get("items"):
|
17
17
|
return results
|
18
18
|
orientation = self.context.orientation
|
@@ -46,9 +46,12 @@ class BaseNewsEndpoint(BaseEndpoint):
|
|
46
46
|
"metadata_fields=UID",
|
47
47
|
"sort_on=effective",
|
48
48
|
"sort_order=descending",
|
49
|
-
"
|
50
|
-
"fullobjects=1",
|
49
|
+
"fullobjects={}".format(self.fullobjects),
|
51
50
|
]
|
51
|
+
if self.batch_size == 0:
|
52
|
+
params.append("b_size={}".format(self.context.nb_results))
|
53
|
+
else:
|
54
|
+
params.append("b_size={}".format(self.batch_size))
|
52
55
|
params = self.construct_query_string(params)
|
53
56
|
url = f"{NEWS_URL}/{self.remote_endpoint}?{params}"
|
54
57
|
return url
|
@@ -70,6 +73,11 @@ class NewsEndpointGet(BaseService):
|
|
70
73
|
def reply(self):
|
71
74
|
return NewsEndpoint(self.context, self.request)()
|
72
75
|
|
76
|
+
def reply_for_given_object(self, obj, request, fullobjects=1, batch_size=0):
|
77
|
+
return NewsEndpoint(
|
78
|
+
obj, request, fullobjects=fullobjects, batch_size=batch_size
|
79
|
+
)()
|
80
|
+
|
73
81
|
|
74
82
|
class NewsFiltersEndpointGet(BaseService):
|
75
83
|
def reply(self):
|
@@ -57,7 +57,10 @@ def get_default_view_url(view_type):
|
|
57
57
|
if not record:
|
58
58
|
return ""
|
59
59
|
with api.env.adopt_user(username="admin"):
|
60
|
-
|
60
|
+
obj = api.content.get(UID=record)
|
61
|
+
if not obj:
|
62
|
+
return ""
|
63
|
+
return obj.absolute_url()
|
61
64
|
|
62
65
|
|
63
66
|
def get_views_mapping(navigation_root):
|
@@ -69,10 +69,10 @@ def get_auth_sources_response(
|
|
69
69
|
"v": wf_status,
|
70
70
|
},
|
71
71
|
],
|
72
|
-
"metadata_fields": ["title", "modified"],
|
72
|
+
"metadata_fields": ["title", "modified", "id"],
|
73
73
|
"sort_on": "effective",
|
74
74
|
"sort_order": "descending",
|
75
|
-
"fullobjects":
|
75
|
+
"fullobjects": False,
|
76
76
|
"b_start": 0,
|
77
77
|
"b_size": 4000,
|
78
78
|
}
|
@@ -81,7 +81,7 @@ def get_auth_sources_response(
|
|
81
81
|
auth = get_wca_token(client_id, client_secret)
|
82
82
|
headers = {
|
83
83
|
"Accept": "application/json",
|
84
|
-
"Content-Type": "
|
84
|
+
"Content-Type": "application/json",
|
85
85
|
"Authorization": auth,
|
86
86
|
}
|
87
87
|
url = f"{url}/@querystring-search"
|
imio/smartweb/core/interfaces.py
CHANGED
@@ -5,6 +5,7 @@ from collective.messagesviewlet.interfaces import ICollectiveMessagesviewletLaye
|
|
5
5
|
from collective.solr.browser.interfaces import IThemeSpecific
|
6
6
|
from imio.smartweb.common.interfaces import IImioSmartwebCommonLayer
|
7
7
|
from plone.app.contenttypes.interfaces import IPloneAppContenttypesLayer
|
8
|
+
from Products.CMFPlone.browser.interfaces import ISiteMap
|
8
9
|
from zope.interface import Interface
|
9
10
|
|
10
11
|
|
@@ -22,6 +23,7 @@ class IImioSmartwebCoreLayer(
|
|
22
23
|
ILayerSpecific,
|
23
24
|
IThemeSpecific,
|
24
25
|
ICollectiveMessagesviewletLayer,
|
26
|
+
ISiteMap,
|
25
27
|
):
|
26
28
|
"""Marker interface that defines a browser layer."""
|
27
29
|
|
@@ -27,5 +27,6 @@
|
|
27
27
|
<object meta_type="Dexterity FTI" name="imio.smartweb.SectionSendinblue"/>
|
28
28
|
<object meta_type="Dexterity FTI" name="imio.smartweb.SectionSlide"/>
|
29
29
|
<object meta_type="Dexterity FTI" name="imio.smartweb.SectionText"/>
|
30
|
+
<object meta_type="Dexterity FTI" name="imio.smartweb.SectionTimestampedPublications"/>
|
30
31
|
<object meta_type="Dexterity FTI" name="imio.smartweb.SectionVideo"/>
|
31
32
|
</object>
|
@@ -19,6 +19,7 @@
|
|
19
19
|
<type type_id="imio.smartweb.SectionSlide"/>
|
20
20
|
<type type_id="imio.smartweb.SectionNews"/>
|
21
21
|
<type type_id="imio.smartweb.SectionText"/>
|
22
|
+
<type type_id="imio.smartweb.SectionTimestampedPublications"/>
|
22
23
|
<type type_id="imio.smartweb.SectionVideo"/>
|
23
24
|
</bindings>
|
24
25
|
</object>
|
@@ -85,6 +85,38 @@ class TestIdeabox(ImioSmartwebTestCase):
|
|
85
85
|
self.assertEqual(campaign_view.title, "Sprint iMio Fall 2024")
|
86
86
|
self.assertEqual(campaign_view.id, "sprint-imio-fall-2024")
|
87
87
|
|
88
|
+
# CampaignNameChooser : Give th Title to our object thanks to e-guichet object Title.
|
89
|
+
@patch("imio.smartweb.core.subscribers.get_basic_auth_json")
|
90
|
+
@patch("imio.smartweb.core.subscribers.get_value_from_registry")
|
91
|
+
@patch("imio.smartweb.core.contents.rest.campaign.content.get_basic_auth_json")
|
92
|
+
@patch("imio.smartweb.core.contents.rest.campaign.content.get_value_from_registry")
|
93
|
+
def test_campaign_name_chooser(
|
94
|
+
self,
|
95
|
+
m_get_value_from_registry_namechooser,
|
96
|
+
m_get_basic_auth_json_namechooser,
|
97
|
+
m_get_value_from_registry,
|
98
|
+
m_get_basic_auth_json,
|
99
|
+
):
|
100
|
+
from imio.smartweb.core.contents.rest.campaign.content import CampaignView
|
101
|
+
from zope.component import queryAdapter
|
102
|
+
from zope.container.interfaces import INameChooser
|
103
|
+
|
104
|
+
m_get_value_from_registry.return_value = (
|
105
|
+
"https://staging3-formulaires.guichet-citoyen.be/api"
|
106
|
+
)
|
107
|
+
m_get_basic_auth_json.return_value = self.json_campaign_raw_mock
|
108
|
+
|
109
|
+
m_get_value_from_registry_namechooser.return_value = (
|
110
|
+
"https://staging3-formulaires.guichet-citoyen.be/api"
|
111
|
+
)
|
112
|
+
m_get_basic_auth_json_namechooser.return_value = self.json_campaign_raw_mock
|
113
|
+
campaign_view = CampaignView(id="test-campaign", title=None)
|
114
|
+
campaign_view.linked_campaign = "2"
|
115
|
+
name_chooser = queryAdapter(self.folder, INameChooser)
|
116
|
+
generated_id = name_chooser.chooseName(None, campaign_view)
|
117
|
+
self.assertEqual(campaign_view.title, "Sprint iMio Fall 2024")
|
118
|
+
self.assertEqual(generated_id, "sprint-imio-fall-2024")
|
119
|
+
|
88
120
|
@requests_mock.Mocker()
|
89
121
|
@patch("imio.smartweb.core.subscribers.get_basic_auth_json")
|
90
122
|
@patch("imio.smartweb.core.subscribers.get_value_from_registry")
|
@@ -110,7 +142,7 @@ class TestIdeabox(ImioSmartwebTestCase):
|
|
110
142
|
url = endpoint.query_url
|
111
143
|
self.assertEqual(
|
112
144
|
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&",
|
145
|
+
"https://demo-formulaires.guichet-citoyen.be/api/cards/imio-ideabox-projet/list?filter-campagne=2&full=on&filter-statut=Vote|Enregistr%C3%A9e&filter-statut-operator=in&",
|
114
146
|
)
|
115
147
|
|
116
148
|
m.get(url, text=json.dumps({}))
|