view src/pages/common/blog/page_meta.py @ 948:c20ac29d869f

pages (common/blog): don't fail if an error is raised while getting comment
author Goffi <goffi@goffi.org>
date Tue, 23 May 2017 00:06:03 +0200
parents 92f0eeb6dc72
children 36e9747520fd
line wrap: on
line source

#!/usr/bin/env python2.7
# -*- coding: utf-8 -*-
from libervia.server.constants import Const as C
from twisted.words.protocols.jabber import jid
from twisted.internet import defer
from sat.tools.common import data_objects
from libervia.server import session_iface
from sat.core.i18n import _
from sat.core.log import getLogger
import urllib
log = getLogger('pages/common/blog')

"""generic blog (with service/node provided)"""
name = u'blog'
template = u"blog/articles.html"
uri_handlers = {(u'pubsub', u'microblog'): 'microblog_uri'}


def microblog_uri(self, uri_data):
    service = urllib.quote_plus(uri_data[u'path'])
    node = urllib.quote_plus(uri_data[u'node'])
    return service + u'/' + node


def parse_url(self, request):
    """URL is /[service]/[node]

    if [node] is not found, default namespace is used
    if both [service] and [node] are not found, default service is used too
    """
    data = self.getRData(request)

    try:
        service = self.nextPath(request)
    except IndexError:
        data['service'] = u''
    else:
        try:
            data[u"service"] = jid.JID(service)
        except Exception:
            log.warning(_(u"bad service entered: {}").format(service))
            self.pageError(request, C.HTTP_BAD_REQUEST)

    try:
        data['node'] = self.nextPath(request)
    except IndexError:
        data['node'] = u''


@defer.inlineCallbacks
def appendComments(self, blog_items, identities, profile):
    for blog_item in blog_items:
        if identities is not None:
            author = blog_item.author_jid
            if author not in identities:
                identities[author] = yield self.host.bridge.identityGet(author, profile)
        for comment_data in blog_item.comments:
            service = comment_data[u'service']
            node = comment_data[u'node']
            try:
                comments_data = yield self.host.bridge.mbGet(
                                      service,
                                      node,
                                      C.NO_LIMIT,
                                      [],
                                      {},
                                      profile)
            except Exception as e:
                log.warning(_(u"Can't get comments at {node} (service: {service}): {msg}").format(
                    service=service,
                    node=node,
                    msg=e))
                continue

            comments = data_objects.BlogItems(comments_data)
            blog_item.appendCommentsItems(comments)
            yield appendComments(self, comments, identities, profile)


@defer.inlineCallbacks
def prepare_render(self, request):
    data = self.getRData(request)
    # if the comments are not explicitly hidden, we show them
    service, node, show_comments = data.get(u'service', u''), data.get(u'node', u''), data.get(u'show_comments', True)
    profile = self.getProfile(request)
    if profile is None:
        profile = C.SERVICE_PROFILE

    try:
        blog_data = yield self.host.bridge.mbGet(
                              service.userhost(),
                              node,
                              10,
                              [],
                              {},
                              profile)
    except Exception as e:
        # FIXME: need a better way to test errors in bridge errback
        if u"forbidden" in unicode(e):
            self.pageError(request, 401)
        else:
            raise e

    items = data_objects.BlogItems(blog_data)
    template_data = request.template_data
    identities = template_data[u'identities'] = self.host.getSessionData(request, session_iface.ISATSession).identities

    if show_comments:
        yield appendComments(self, items, identities, profile)

    template_data[u'items'] = items
    template_data[u'allow_commenting'] = u'simple'


@defer.inlineCallbacks
def on_data_post(self, request):
    profile = self.getProfile(request)
    if profile is None:
        self.pageError(request, C.HTTP_UNAUTHORIZED)
    type_ = self.getPostedData(request, u'type')
    if type_ == u'comment':
        service, node, body = self.getPostedData(request, (u'service', u'node', u'body'))

        if not body:
            self.pageError(request, C.HTTP_BAD_REQUEST)
        comment_data = {u"content": body}
        try:
            yield self.host.bridge.mbSend(service, node, comment_data, profile)
        except Exception as e:
            if u"forbidden" in unicode(e):
                self.pageError(request, 401)
            else:
                raise e
    else:
        log.warning(_(u"Unhandled data type: {}").format(type_))