Mercurial > libervia-web
comparison src/server/blog.py @ 727:3bd097380da7
server side (blog): fixes displaying the avatar
author | souliane <souliane@mailoo.org> |
---|---|
date | Mon, 05 Oct 2015 09:15:47 +0200 |
parents | e949b7c7ed9c |
children | 9d35d75566fb |
comparison
equal
deleted
inserted
replaced
726:e949b7c7ed9c | 727:3bd097380da7 |
---|---|
72 | 72 |
73 def __init__(self, host): | 73 def __init__(self, host): |
74 self.host = host | 74 self.host = host |
75 Resource.__init__(self) | 75 Resource.__init__(self) |
76 TemplateProcessor.__init__(self, host) | 76 TemplateProcessor.__init__(self, host) |
77 self.host.bridge.register('entityDataUpdated', self.entityDataUpdatedCb) | 77 self.host.bridge.register('entityDataUpdated', self.entityDataUpdatedHandler) |
78 self.host.bridge.register('actionResult', self.actionResultCb) # FIXME: actionResult is to be removed | |
79 self.avatars_cache = {} | 78 self.avatars_cache = {} |
80 self.waiting_deferreds = {} | 79 self.waiting_deferreds = {} |
81 | 80 |
82 def entityDataUpdatedCb(self, entity_jid_s, key, value, dummy): | 81 def entityDataUpdatedHandler(self, entity_s, key, value, dummy): |
83 """Retrieve the avatar we've been waiting for and fires the callback | 82 """Retrieve the avatar we've been waiting for and fires the callback. |
84 for self.getAvatar to return. | 83 |
85 | 84 @param entity_s (str): JID of the contact |
86 @param entity_jid_s (str): JID of the contact | |
87 @param key (str): entity data key | 85 @param key (str): entity data key |
88 @param value (str): entity data value | 86 @param value (str): entity data value |
89 @param dummy (str): that would be C.SERVICE_PROFILE | 87 @param dummy (str): that would be C.SERVICE_PROFILE |
90 """ | 88 """ |
91 if key != 'avatar': | 89 if key != "avatar": |
92 return | 90 return |
93 entity_jid_s = entity_jid_s.lower() | 91 log.debug(_(u"Received a new avatar for entity %s") % entity_s) |
94 log.debug(_(u"Received a new avatar for entity %s") % entity_jid_s) | 92 |
95 avatar = C.AVATARS_DIR + value | 93 url = os.path.join(C.AVATARS_DIR, value) |
96 self.avatars_cache[entity_jid_s] = avatar | 94 self.avatars_cache[entity_s] = url |
95 self.waiting_deferreds[entity_s].callback(url) | |
96 del self.waiting_deferreds[entity_s] | |
97 | |
98 def getAvatarURL(self, pub_jid): | |
99 """Return avatar of a jid if in cache, else ask for it. | |
100 | |
101 @param pub_jid (JID): publisher JID | |
102 @return: deferred avatar URL (unicode) | |
103 """ | |
104 bare_jid_s = pub_jid.userhost() | |
97 try: | 105 try: |
98 self.waiting_deferreds[entity_jid_s][1].callback(avatar) | 106 url = self.avatars_cache[bare_jid_s] |
99 del self.waiting_deferreds[entity_jid_s] | |
100 except KeyError: | 107 except KeyError: |
101 pass | 108 self.avatars_cache[bare_jid_s] = '' # avoid to request the vcard several times |
102 | 109 self.host.bridge.getCard(bare_jid_s, C.SERVICE_PROFILE) |
103 def actionResultCb(self, answer_type, action_id, data, dummy): | 110 d = defer.Deferred() |
104 """Fires the callback for self.getAvatar to return | 111 self.waiting_deferreds[bare_jid_s] = d |
105 | 112 return d |
106 @param answer_type (str): 'SUPPRESS' or another value that we would ignore | 113 return defer.succeed(url if url else C.DEFAULT_AVATAR_URL) |
107 @param action_id (str): the request ID | |
108 @param data (dict): ignored | |
109 @param dummy (str): that would be C.SERVICE_PROFILE | |
110 """ | |
111 # FIXME: actionResult is to be removed. For now we use it to get notified | |
112 # when the requested vCard hasn't been found. Replace with the new system. | |
113 if answer_type != 'SUPPRESS': | |
114 return | |
115 try: | |
116 entity_jid_s = [key for (key, value) in self.waiting_deferreds.items() if value[0] == action_id][0] | |
117 except IndexError: # impossible to guess the entity | |
118 return | |
119 log.debug(_(u"Using default avatar for entity %s") % entity_jid_s) | |
120 self.avatars_cache[entity_jid_s] = C.DEFAULT_AVATAR_URL | |
121 self.waiting_deferreds[entity_jid_s][1].callback(C.DEFAULT_AVATAR_URL) | |
122 del self.waiting_deferreds[entity_jid_s] | |
123 | |
124 def getAvatar(self, profile): | |
125 """Get the avatar of the given profile | |
126 | |
127 @param profile(unicode): %(doc_profile)s | |
128 @return: deferred avatar path, relative to the server's root | |
129 """ | |
130 jid_s = (profile + '@' + self.host.bridge.getNewAccountDomain()).lower() | |
131 if jid_s in self.avatars_cache: | |
132 return defer.succeed(self.avatars_cache[jid_s]) | |
133 # FIXME: request_id is no more needed when actionResult is removed | |
134 request_id = self.host.bridge.getCard(jid_s, C.SERVICE_PROFILE) | |
135 self.waiting_deferreds[jid_s] = (request_id, defer.Deferred()) | |
136 return self.waiting_deferreds[jid_s][1] | |
137 | 114 |
138 def render_GET(self, request): | 115 def render_GET(self, request): |
139 if not request.postpath: | 116 if not request.postpath: |
140 return self.useTemplate(request, "static_blog_error", {'message': "You must indicate a nickname"}) | 117 return self.useTemplate(request, "static_blog_error", {'message': "You must indicate a nickname"}) |
141 | 118 |
163 | 140 |
164 if request.atom: | 141 if request.atom: |
165 self.host.bridge.mbGetAtom(pub_jid.userhost(), NS_MICROBLOG, max_items, item_ids, | 142 self.host.bridge.mbGetAtom(pub_jid.userhost(), NS_MICROBLOG, max_items, item_ids, |
166 request.extra_dict, C.SERVICE_PROFILE, | 143 request.extra_dict, C.SERVICE_PROFILE, |
167 lambda feed: self.render_atom_feed(feed, request), | 144 lambda feed: self.render_atom_feed(feed, request), |
168 lambda failure: self.render_error_blog(failure, request, profile)) | 145 lambda failure: self.render_error_blog(failure, request, pub_jid)) |
169 elif request.item_id: | 146 elif request.item_id: |
170 self.getItemById(pub_jid, request.item_id, request.extra_dict, | 147 self.getItemById(pub_jid, request.item_id, request.extra_dict, |
171 request.extra_comments_dict, request, profile) | 148 request.extra_comments_dict, request, profile) |
172 else: | 149 else: |
173 self.getItems(pub_jid, max_items, request.extra_dict, | 150 self.getItems(pub_jid, max_items, request.extra_dict, |
255 metadata['rsm_first'] = metadata['rsm_last'] = item["id"] | 232 metadata['rsm_first'] = metadata['rsm_last'] = item["id"] |
256 | 233 |
257 def gotComments(comments): | 234 def gotComments(comments): |
258 # build the items as self.getItems would do it (and as self.render_html_blog expects them to be) | 235 # build the items as self.getItems would do it (and as self.render_html_blog expects them to be) |
259 comments = [(item['comments_service'], item['comments_node'], "", comments[0], comments[1])] | 236 comments = [(item['comments_service'], item['comments_node'], "", comments[0], comments[1])] |
260 self.render_html_blog([(item, comments)], metadata, request, profile) | 237 self.render_html_blog([(item, comments)], metadata, request, pub_jid, profile) |
261 | 238 |
262 # get the comments | 239 # get the comments |
263 max_comments = int(extra_comments_dict['rsm_max']) | 240 max_comments = int(extra_comments_dict['rsm_max']) |
264 self.host.bridge.mbGet(item['comments_service'], item['comments_node'], max_comments, [], | 241 self.host.bridge.mbGet(item['comments_service'], item['comments_node'], max_comments, [], |
265 extra_comments_dict, C.SERVICE_PROFILE, callback=gotComments) | 242 extra_comments_dict, C.SERVICE_PROFILE, callback=gotComments) |
286 def getResultCb(data, rt_session): | 263 def getResultCb(data, rt_session): |
287 remaining, results = data | 264 remaining, results = data |
288 for result in results: | 265 for result in results: |
289 service, node, failure, items, metadata = result | 266 service, node, failure, items, metadata = result |
290 if not failure: | 267 if not failure: |
291 self.render_html_blog(items, metadata, request, profile) | 268 self.render_html_blog(items, metadata, request, pub_jid, profile) |
292 | 269 |
293 if remaining: | 270 if remaining: |
294 self._getResults(rt_session) | 271 self._getResults(rt_session) |
295 | 272 |
296 def getResult(rt_session): | 273 def getResult(rt_session): |
297 self.host.bridge.mbGetFromManyWithCommentsRTResult(rt_session, C.SERVICE_PROFILE, | 274 self.host.bridge.mbGetFromManyWithCommentsRTResult(rt_session, C.SERVICE_PROFILE, |
298 callback=lambda data: getResultCb(data, rt_session), | 275 callback=lambda data: getResultCb(data, rt_session), |
299 errback=lambda failure: self.render_error_blog(failure, request, profile)) | 276 errback=lambda failure: self.render_error_blog(failure, request, pub_jid)) |
300 | 277 |
301 max_comments = int(extra_comments_dict['rsm_max']) | 278 max_comments = int(extra_comments_dict['rsm_max']) |
302 self.host.bridge.mbGetFromManyWithComments(C.JID, [pub_jid.userhost()], max_items, | 279 self.host.bridge.mbGetFromManyWithComments(C.JID, [pub_jid.userhost()], max_items, |
303 max_comments, extra_dict, extra_comments_dict, | 280 max_comments, extra_dict, extra_comments_dict, |
304 C.SERVICE_PROFILE, callback=getResult) | 281 C.SERVICE_PROFILE, callback=getResult) |
305 | 282 |
306 def render_html_blog(self, items, metadata, request, profile): | 283 def render_html_blog(self, items, metadata, request, pub_jid, profile): |
307 """Retrieve the user parameters before actually rendering the static blog | 284 """Retrieve the user parameters before actually rendering the static blog |
308 | 285 |
309 @param items(list[tuple(dict, list)]): same as in self.__render_html_blog | 286 @param items(list[tuple(dict, list)]): same as in self.__render_html_blog |
310 @param metadata(dict): original node metadata | 287 @param metadata(dict): original node metadata |
311 @param request: HTTP request | 288 @param request: HTTP request |
312 @param profile | 289 @param pub_jid (JID): publisher JID |
290 @param profile (unicode): %(doc_profile)s | |
313 """ | 291 """ |
314 d_list = [] | 292 d_list = [] |
315 options = {} | 293 options = {} |
316 | 294 |
317 def getCallback(param_name): | 295 def getCallback(param_name): |
318 d = defer.Deferred() | 296 d = defer.Deferred() |
319 d.addCallback(lambda value: options.update({param_name: value})) | 297 d.addCallback(lambda value: options.update({param_name: value})) |
320 d_list.append(d) | 298 d_list.append(d) |
321 return d.callback | 299 return d.callback |
322 | 300 |
323 eb = lambda failure: self.render_error_blog(failure, request, profile) | 301 eb = lambda failure: self.render_error_blog(failure, request, pub_jid) |
324 | 302 |
325 self.getAvatar(profile).addCallbacks(getCallback('avatar'), eb) | 303 self.getAvatarURL(pub_jid).addCallbacks(getCallback('avatar'), eb) |
326 for param_name in (C.STATIC_BLOG_PARAM_TITLE, C.STATIC_BLOG_PARAM_BANNER, C.STATIC_BLOG_PARAM_KEYWORDS, C.STATIC_BLOG_PARAM_DESCRIPTION): | 304 for param_name in (C.STATIC_BLOG_PARAM_TITLE, C.STATIC_BLOG_PARAM_BANNER, C.STATIC_BLOG_PARAM_KEYWORDS, C.STATIC_BLOG_PARAM_DESCRIPTION): |
327 self.host.bridge.asyncGetParamA(param_name, C.STATIC_BLOG_KEY, 'value', C.SERVER_SECURITY_LIMIT, profile, callback=getCallback(param_name), errback=eb) | 305 self.host.bridge.asyncGetParamA(param_name, C.STATIC_BLOG_KEY, 'value', C.SERVER_SECURITY_LIMIT, profile, callback=getCallback(param_name), errback=eb) |
328 | 306 |
329 cb = lambda dummy: self.__render_html_blog(items, metadata, options, request, profile) | 307 cb = lambda dummy: self.__render_html_blog(items, metadata, options, request, pub_jid) |
330 defer.DeferredList(d_list).addCallback(cb) | 308 defer.DeferredList(d_list).addCallback(cb) |
331 | 309 |
332 def __render_html_blog(self, items, metadata, options, request, profile): | 310 def __render_html_blog(self, items, metadata, options, request, pub_jid): |
333 """Actually render the static blog. | 311 """Actually render the static blog. |
334 | 312 |
335 If mblog_data is a list of dict, we are missing the comments items so we just | 313 If mblog_data is a list of dict, we are missing the comments items so we just |
336 display the main items. If mblog_data is a list of couple, each couple is | 314 display the main items. If mblog_data is a list of couple, each couple is |
337 associating a main item data with the list of its comments, so we render all. | 315 associating a main item data with the list of its comments, so we render all. |
345 - comments(list[dict]): list of microblog data | 323 - comments(list[dict]): list of microblog data |
346 - comments_metadata(dict): metadata of the comment node | 324 - comments_metadata(dict): metadata of the comment node |
347 @param metadata(dict): original node metadata | 325 @param metadata(dict): original node metadata |
348 @param options: dict defining the blog's parameters | 326 @param options: dict defining the blog's parameters |
349 @param request: the HTTP request | 327 @param request: the HTTP request |
350 @param profile | 328 @param pub_jid (JID): publisher JID |
351 """ | 329 """ |
352 if not isinstance(options, dict): | 330 if not isinstance(options, dict): |
353 options = {} | 331 options = {} |
354 user = sanitizeHtml(profile) | 332 user = sanitizeHtml(pub_jid.user) |
355 root_url = '../' * len(request.postpath) | 333 root_url = '../' * len(request.postpath) |
356 base_url = root_url + 'blog/' + user | 334 base_url = root_url + 'blog/' + user |
357 | 335 |
358 def getOption(key): | 336 def getOption(key): |
359 return sanitizeHtml(options[key]) if key in options else '' | 337 return sanitizeHtml(options[key]) if key in options else '' |
398 | 376 |
399 def render_atom_feed(self, feed, request): | 377 def render_atom_feed(self, feed, request): |
400 request.write(feed.encode('utf-8')) | 378 request.write(feed.encode('utf-8')) |
401 request.finish() | 379 request.finish() |
402 | 380 |
403 def render_error_blog(self, error, request, profile): | 381 def render_error_blog(self, error, request, pub_jid): |
404 request.write(self.useTemplate(request, "static_blog_error", {'message': "Can't access requested data"})) | 382 request.write(self.useTemplate(request, "static_blog_error", {'message': "Can't access requested data"})) |
405 request.finish() | 383 request.finish() |
406 | 384 |
407 | 385 |
408 class NavigationLinks(object): | 386 class NavigationLinks(object): |