comparison libervia/pages/blog/view/page_meta.py @ 1322:a0954b6610aa

pages: identities are not using `data_objects` anymore: - identities are now handler directly with the dict received from backend, without using a specific data object. - a new `fillMissingIdentities` method in `LiberivaPage` will help to get all needed identities before rendering the template, and to avoid missing avatar or nickname. - (blog/view): fill missing identities for main blog items, not only for comments
author Goffi <goffi@goffi.org>
date Sun, 02 Aug 2020 17:45:15 +0200
parents 04e7dd6b6f4d
children 1b94a5ab155f
comparison
equal deleted inserted replaced
1321:eb85ef26cb4a 1322:a0954b6610aa
3 import unicodedata 3 import unicodedata
4 import re 4 import re
5 import html 5 import html
6 from libervia.server.constants import Const as C 6 from libervia.server.constants import Const as C
7 from twisted.words.protocols.jabber import jid 7 from twisted.words.protocols.jabber import jid
8 from twisted.internet import defer
9 from sat.tools.common import data_objects
10 from libervia.server import session_iface
11 from sat.core.i18n import _ 8 from sat.core.i18n import _
12 from sat.tools.common.template import safe 9 from sat.tools.common.template import safe
13 from sat.tools.common import uri 10 from sat.tools.common import uri
14 from sat.tools.common import data_format 11 from sat.tools.common import data_format
15 from libervia.server import utils 12 from libervia.server import utils
107 "type": "application/atom+xml", 104 "type": "application/atom+xml",
108 "rel": "alternate", 105 "rel": "alternate",
109 "title": "{service}'s blog".format(service=service)}) 106 "title": "{service}'s blog".format(service=service)})
110 107
111 108
112 @defer.inlineCallbacks 109 async def appendComments(self, request, blog_items, profile):
113 def appendComments(self, blog_items, identities, profile): 110 await self.fillMissingIdentities(
111 request, [i['author_jid'] for i in blog_items['items']])
114 for blog_item in blog_items['items']: 112 for blog_item in blog_items['items']:
115 if identities is not None:
116 author = blog_item['author_jid']
117 if not author:
118 log.warning(_("no author found for item {item_id}").format(
119 item_id=blog_item['id']))
120 else:
121 if author not in identities:
122 id_raw = yield self.host.bridgeCall(
123 'identityGet', author, [], True, profile)
124 identities[author] = data_format.deserialise(id_raw)
125 for comment_data in blog_item['comments']: 113 for comment_data in blog_item['comments']:
126 service = comment_data['service'] 114 service = comment_data['service']
127 node = comment_data['node'] 115 node = comment_data['node']
128 try: 116 try:
129 comments_data = yield self.host.bridgeCall('mbGet', 117 comments_data = await self.host.bridgeCall('mbGet',
130 service, 118 service,
131 node, 119 node,
132 C.NO_LIMIT, 120 C.NO_LIMIT,
133 [], 121 [],
134 {C.KEY_ORDER_BY: C.ORDER_BY_CREATION}, 122 {C.KEY_ORDER_BY: C.ORDER_BY_CREATION},
141 msg=e)) 129 msg=e))
142 continue 130 continue
143 131
144 comments = data_format.deserialise(comments_data) 132 comments = data_format.deserialise(comments_data)
145 comment_data['items'] = comments['items'] 133 comment_data['items'] = comments['items']
146 yield appendComments(self, comments, identities, profile) 134 await appendComments(self, request, comments, profile)
147 135
148 @defer.inlineCallbacks 136 async def getBlogItems(self, request, service, node, item_id, extra, profile):
149 def getBlogItems(self, request, service, node, item_id, extra, profile):
150 try: 137 try:
151 if item_id: 138 if item_id:
152 items_id = [item_id] 139 items_id = [item_id]
153 else: 140 else:
154 items_id = [] 141 items_id = []
155 blog_data = yield self.host.bridgeCall('mbGet', 142 blog_data = await self.host.bridgeCall('mbGet',
156 service.userhost(), 143 service.userhost(),
157 node, 144 node,
158 C.NO_LIMIT, 145 C.NO_LIMIT,
159 items_id, 146 items_id,
160 extra, 147 extra,
168 service = service.userhost(), msg=e))) 155 service = service.userhost(), msg=e)))
169 blog_data = {"items": []} 156 blog_data = {"items": []}
170 else: 157 else:
171 blog_data = data_format.deserialise(blog_data) 158 blog_data = data_format.deserialise(blog_data)
172 159
173 defer.returnValue(blog_data) 160 return blog_data
174 161
175 @defer.inlineCallbacks 162 async def prepare_render(self, request):
176 def prepare_render(self, request):
177 data = self.getRData(request) 163 data = self.getRData(request)
178 page_max = data.get("page_max", 10) 164 page_max = data.get("page_max", 10)
179 # if the comments are not explicitly hidden, we show them 165 # if the comments are not explicitly hidden, we show them
180 service, node, item_id, show_comments = data.get('service', ''), data.get('node', ''), data.get('item'), data.get('show_comments', True) 166 service, node, item_id, show_comments = data.get('service', ''), data.get('node', ''), data.get('item'), data.get('show_comments', True)
181 profile = self.getProfile(request) 167 profile = self.getProfile(request)
194 if tag: 180 if tag:
195 extra['mam_filter_{}'.format(C.MAM_FILTER_CATEGORY)] = tag 181 extra['mam_filter_{}'.format(C.MAM_FILTER_CATEGORY)] = tag
196 182
197 ## main data ## 183 ## main data ##
198 # we get data from backend/XMPP here 184 # we get data from backend/XMPP here
199 blog_items = yield getBlogItems(self, request, service, node, item_id, extra, profile) 185 blog_items = await getBlogItems(self, request, service, node, item_id, extra, profile)
200 186
201 ## navigation ## 187 ## navigation ##
202 # no let's fill service, node and pagination URLs 188 # no let's fill service, node and pagination URLs
203 template_data = request.template_data 189 template_data = request.template_data
204 if 'service' not in template_data: 190 if 'service' not in template_data:
216 # we must return an error 202 # we must return an error
217 self.pageError(request, C.HTTP_NOT_FOUND) 203 self.pageError(request, C.HTTP_NOT_FOUND)
218 204
219 ## identities ## 205 ## identities ##
220 # identities are used to show nice nickname or avatars 206 # identities are used to show nice nickname or avatars
221 identities = self.host.getSessionData(request, session_iface.ISATSession).identities 207 await self.fillMissingIdentities(request, [i['author_jid'] for i in blog_items['items']])
222 208
223 ## Comments ## 209 ## Comments ##
224 # if comments are requested, we need to take them 210 # if comments are requested, we need to take them
225 if show_comments: 211 if show_comments:
226 yield appendComments(self, blog_items, identities, profile) 212 await appendComments(self, request, blog_items, profile)
227 213
228 ## URLs ## 214 ## URLs ##
229 # We will fill items_http_uri and tags_http_uri in template_data with suitable urls 215 # We will fill items_http_uri and tags_http_uri in template_data with suitable urls
230 # if we know the profile, we use it instead of service + blog (nicer url) 216 # if we know the profile, we use it instead of service + blog (nicer url)
231 if target_profile is None: 217 if target_profile is None:
233 blog_base_url_tag = self.getPageByName('blog_view').getURL(service.full(), node or '@', 'tag') 219 blog_base_url_tag = self.getPageByName('blog_view').getURL(service.full(), node or '@', 'tag')
234 else: 220 else:
235 blog_base_url_item = self.getURLByNames([('user', [target_profile]), ('user_blog', ['id'])]) 221 blog_base_url_item = self.getURLByNames([('user', [target_profile]), ('user_blog', ['id'])])
236 blog_base_url_tag = self.getURLByNames([('user', [target_profile]), ('user_blog', ['tag'])]) 222 blog_base_url_tag = self.getURLByNames([('user', [target_profile]), ('user_blog', ['tag'])])
237 # we also set the background image if specified by user 223 # we also set the background image if specified by user
238 bg_img = yield self.host.bridgeCall('asyncGetParamA', 'Background', 'Blog page', 'value', -1, template_data['target_profile']) 224 bg_img = await self.host.bridgeCall('asyncGetParamA', 'Background', 'Blog page', 'value', -1, template_data['target_profile'])
239 if bg_img: 225 if bg_img:
240 template_data['dynamic_style'] = safe(""" 226 template_data['dynamic_style'] = safe("""
241 :root { 227 :root {
242 --bg-img: url("%s"); 228 --bg-img: url("%s");
243 } 229 }
288 if item_id: 274 if item_id:
289 uri_args['item'] = item_id 275 uri_args['item'] = item_id
290 template_data['xmpp_uri'] = uri.buildXMPPUri('pubsub', subtype='microblog', **uri_args) 276 template_data['xmpp_uri'] = uri.buildXMPPUri('pubsub', subtype='microblog', **uri_args)
291 277
292 278
293 @defer.inlineCallbacks 279 async def on_data_post(self, request):
294 def on_data_post(self, request):
295 profile = self.getProfile(request) 280 profile = self.getProfile(request)
296 if profile is None: 281 if profile is None:
297 self.pageError(request, C.HTTP_FORBIDDEN) 282 self.pageError(request, C.HTTP_FORBIDDEN)
298 type_ = self.getPostedData(request, 'type') 283 type_ = self.getPostedData(request, 'type')
299 if type_ == 'comment': 284 if type_ == 'comment':
301 286
302 if not body: 287 if not body:
303 self.pageError(request, C.HTTP_BAD_REQUEST) 288 self.pageError(request, C.HTTP_BAD_REQUEST)
304 comment_data = {"content": body} 289 comment_data = {"content": body}
305 try: 290 try:
306 yield self.host.bridgeCall('mbSend', 291 await self.host.bridgeCall('mbSend',
307 service, 292 service,
308 node, 293 node,
309 data_format.serialise(comment_data), 294 data_format.serialise(comment_data),
310 profile) 295 profile)
311 except Exception as e: 296 except Exception as e: