Mercurial > libervia-web
diff src/server/blog.py @ 586:3eb3a2c0c011
browser and server side: uses RSM (XEP-0059)
author | souliane <souliane@mailoo.org> |
---|---|
date | Fri, 28 Nov 2014 00:31:27 +0100 |
parents | e588335b6aa8 |
children | c8cca1a373dd |
line wrap: on
line diff
--- a/src/server/blog.py Thu Oct 23 16:56:36 2014 +0200 +++ b/src/server/blog.py Fri Nov 28 00:31:27 2014 +0100 @@ -17,7 +17,7 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. -from sat.core.i18n import _ +from sat.core.i18n import _, D_ from sat_frontends.tools.strings import addURLToText from sat.core.log import getLogger log = getLogger(__name__) @@ -130,25 +130,52 @@ pub_jid = JID(pub_jid_s) d2 = defer.Deferred() item_id = None - try: - max_items = int(request.args['max_items'][0]) - except (ValueError, KeyError): - max_items = 10 + atom = None + rsm_ = {} + if len(request.postpath) > 1: if request.postpath[1] == 'atom.xml': # return the atom feed - d2.addCallbacks(self.render_atom_feed, self.render_error_blog, [request], None, [request, prof_found], None) - self.host.bridge.getLastGroupBlogsAtom(pub_jid.userhost(), max_items, C.SERVICE_PROFILE, d2.callback, d2.errback) - return - try: # check if the given path is a valid UUID - uuid.UUID(request.postpath[1]) - item_id = request.postpath[1] - except ValueError: - pass + atom = True + else: + try: # check if the given path is a valid UUID + uuid.UUID(request.postpath[1]) + item_id = request.postpath[1] + except ValueError: + pass + + # retrieve RSM request data from URL parameters + try: + max_items = int(request.args['max'][0]) + except (ValueError, KeyError): + max_items = C.RSM_MAX_ITEMS if item_id else C.RSM_MAX_COMMENTS + rsm_['max'] = unicode(max_items) + try: + rsm_['index'] = request.args['index'][0] + except (ValueError, KeyError): + try: + rsm_['before'] = request.args['before'][0] + except KeyError: + try: + rsm_['after'] = request.args['after'][0] + except KeyError: + pass + + if atom is not None: + d2.addCallbacks(self.render_atom_feed, self.render_error_blog, [request], None, [request, prof_found], None) + self.host.bridge.getGroupBlogsAtom(pub_jid.userhost(), rsm_, C.SERVICE_PROFILE, d2.callback, d2.errback) + return + d2.addCallbacks(self.render_html_blog, self.render_error_blog, [request, prof_found], None, [request, prof_found], None) - if item_id: # display one message and its comments - self.host.bridge.getGroupBlogsWithComments(pub_jid.userhost(), [item_id], C.SERVICE_PROFILE, d2.callback, d2.errback) - else: # display the last messages without comment - self.host.bridge.getLastGroupBlogs(pub_jid.userhost(), max_items, C.SERVICE_PROFILE, d2.callback, d2.errback) + if item_id: + if max_items > 0: # display one message and its comments + self.host.bridge.getGroupBlogsWithComments(pub_jid.userhost(), [item_id], {}, max_items, C.SERVICE_PROFILE, d2.callback, d2.errback) + else: # display one message, count its comments + self.host.bridge.getGroupBlogs(pub_jid.userhost(), [item_id], {}, True, C.SERVICE_PROFILE, d2.callback, d2.errback) + else: + if max_items == 1: # display one message and its comments + self.host.bridge.getGroupBlogsWithComments(pub_jid.userhost(), [], rsm_, C.RSM_MAX_COMMENTS, C.SERVICE_PROFILE, d2.callback, d2.errback) + else: # display the last messages, count their comments + self.host.bridge.getGroupBlogs(pub_jid.userhost(), [], rsm_, True, C.SERVICE_PROFILE, d2.callback, d2.errback) d1 = defer.Deferred() JID(self.host.bridge.asyncGetParamA('JabberID', 'Connection', 'value', C.SERVER_SECURITY_LIMIT, prof_found, callback=d1.callback, errback=d1.errback)) @@ -158,7 +185,12 @@ def render_html_blog(self, mblog_data, request, profile): """Retrieve the user parameters before actually rendering the static blog - @param mblog_data: list of microblog data or list of couple (microblog data, list of microblog data) + + @param mblog_data (list): couple (list, dict) with: + - a list of microblog data, or a list of couple containing: + - microblog data (main item) + - couple (comments data, RSM response data for the comments) + - RSM response data for the main items @param request: HTTP request @param profile """ @@ -184,7 +216,12 @@ """Actually render the static blog. If mblog_data is a list of dict, we are missing the comments items so we just display the main items. If mblog_data is a list of couple, each couple is associating a main item data with the list of its comments, so we render all. - @param mblog_data: list of microblog data or list of couple (microblog data, list of microblog data) + + @param mblog_data (list): couple (list, dict) with: + - a list of microblog data, or a list of couple containing: + - microblog data (main item) + - couple (comments data, RSM response data for the comments) + - RSM response data for the main items @param options: dict defining the blog's parameters @param request: the HTTP request @profile @@ -225,13 +262,74 @@ 'title': getOption(C.STATIC_BLOG_PARAM_TITLE) or "%s's microblog" % user, 'favicon': os.path.normpath(root_url + getOption('avatar')), 'banner_elt': getImageOption(C.STATIC_BLOG_PARAM_BANNER, getOption(C.STATIC_BLOG_PARAM_TITLE) or user)}) - mblog_data = [(entry if isinstance(entry, tuple) else (entry, [])) for entry in mblog_data] - mblog_data = sorted(mblog_data, key=lambda entry: (-float(entry[0].get('published', 0)))) - for entry in mblog_data: - self.__render_html_entry(entry[0], base_url, request) - comments = sorted(entry[1], key=lambda entry: (float(entry.get('published', 0)))) + mblog_data, main_rsm = mblog_data + display_single = len(mblog_data) == 1 + + # build the navigation links + count = int(main_rsm['count']) if 'count' in main_rsm else 0 + if count > 0: + index = int(main_rsm['index']) + if index > 0: + before_link = ("%(base)s?before=%(item_id)s" % {'base': base_url, 'item_id': main_rsm['first']}).encode('utf-8') + if display_single: + before_link += '&max=1' + tmp_text = D_("Later message") + class_ = 'later_message' + else: + tmp_text = D_("Later messages") + class_ = 'later_messages' + before_tag = """<a href="%(link)s" class="%(class)s">%(text)s</a>""" % {'link': before_link, 'class': class_, 'text': tmp_text} + else: + before_tag = None + if index + len(mblog_data) < count: + after_link = ("%(base)s?after=%(item_id)s" % {'base': base_url, 'item_id': main_rsm['last']}).encode('utf-8') + if display_single: + after_link += '&max=1' + text = D_("Older message") + class_ = 'older_message' + else: + text = D_("Older messages") + class_ = 'older_messages' + after_tag = """<a href="%(link)s" class="%(class)s">%(text)s</a>""" % {'link': after_link, 'class': class_, 'text': text} + else: + after_tag = None + + # display navigation header + request.write("""<div class="header">""") + if before_tag: + request.write(before_tag) + request.write(" ") + if display_single and after_tag: + request.write(after_tag) + request.write("""</div>""") + + mblog_data = [(entry if isinstance(entry, tuple) else (entry, ([], {}))) for entry in mblog_data] + mblog_data = sorted(mblog_data, key=lambda entry: (-float(entry[0].get('updated', 0)))) + for main_data, comments_data in mblog_data: + self.__render_html_entry(main_data, base_url, request) + comments, comments_rsm = comments_data + + # eventually display the link to show all comments + comments_count = int(main_data['comments_count']) + delta = comments_count - len(comments) + if display_single and delta > 0: + link = ("%(base)s/%(item_id)s?max=%(max)s" % {'base': base_url, + 'item_id': main_data['id'], + 'max': main_data['comments_count']}).encode('utf-8') + text = D_("Show %(count)d previous %(comments)s") % {'count': delta, + 'comments': D_('comments') if delta > 1 else D_('comment')} + request.write("""<a href="%(link)s" class="comments_link">%(text)s</a>""" % {'link': link, 'text': text}) + + comments = sorted(comments, key=lambda entry: (float(entry.get('published', 0)))) for comment in comments: self.__render_html_entry(comment, base_url, request) + + # display navigation footer + request.write("""<div class="footer">""") + if not display_single and after_tag: + request.write(after_tag) + request.write("""</div>""") + request.write('</body></html>') request.finish() @@ -244,12 +342,6 @@ timestamp = float(entry.get('published', 0)) datetime_ = datetime.fromtimestamp(timestamp) is_comment = entry['type'] == 'comment' - if is_comment: - author = (_("comment from %s") % entry['author']).encode('utf-8') - item_link = '' - else: - author = ' ' - item_link = ("%(base)s/%(item_id)s" % {'base': base_url, 'item_id': entry['id']}).encode('utf-8') def getText(key): if ('%s_xhtml' % key) in entry: @@ -264,12 +356,31 @@ return elem return """<a href="%(link)s" class="item_link">%(elem)s</a>""" % {'link': item_link, 'elem': elem} - header = addMainItemLink("""<div class="mblog_header"> - <div class="mblog_metadata"> - <div class="mblog_author">%(author)s</div> - <div class="mblog_timestamp">%(date)s</div> - </div> - </div>""" % {'author': author, 'date': datetime_}) + if is_comment: + author = (_("from %s") % entry['author']).encode('utf-8') + item_link = '' + footer = '' + else: + author = ' ' + item_link = ("%(base)s/%(item_id)s" % {'base': base_url, 'item_id': entry['id']}).encode('utf-8') + comments_count = int(entry['comments_count']) + comments_text = (D_('comments') if comments_count > 1 else D_('comment')).encode('utf-8') + footer = addMainItemLink("""<div class="mblog_footer mblog_footer_main"> + <div class="mblog_metadata"> + <div class="mblog_comments">%(count)s %(comments)s</div> + </div> + </div>""" % {'count': comments_count, + 'comments': comments_text}) + + header = """<div class="mblog_header %(class)s"> + <div class="mblog_metadata"> + <div class="mblog_author">%(author)s</div> + <div class="mblog_timestamp">%(date)s</div> + </div> + </div>""" % {'author': author, 'date': datetime_, + 'class': '' if is_comment else 'mblog_header_main'} + if not is_comment: + header = addMainItemLink(header) title = addMainItemLink(getText('title')) body = getText('content') @@ -279,11 +390,12 @@ request.write("""<div class="mblog_entry %(extra_style)s"> %(header)s <span class="mblog_content">%(content)s</span> - </div>""" % - {'extra_style': 'mblog_comment' if entry['type'] == 'comment' else '', - 'item_link': item_link, - 'header': header, - 'content': body}) + %(footer)s + </div>""" % {'extra_style': 'mblog_comment' if entry['type'] == 'comment' else '', + 'item_link': item_link, + 'header': header, + 'content': body, + 'footer': footer}) def render_atom_feed(self, feed, request): request.write(feed.encode('utf-8'))