Commit 1a844d50 authored by lovetox's avatar lovetox
Browse files

Refactor XHTML code

- setXHTML expects now a body Node
- getXHTML returns the html Node
- Add XHTMLData struct
parent a335c9ec
Loading
Loading
Loading
Loading
+13 −1
Changes for nbxmpp/modules/message.py: 13 added lines, 1 removed line.
Original line number Diff line number Diff line
@@ -19,8 +19,10 @@ import logging

from nbxmpp.protocol import NodeProcessed
from nbxmpp.protocol import NS_DATA
from nbxmpp.protocol import NS_XHTML
from nbxmpp.structs import StanzaHandler
from nbxmpp.structs import StanzaIDData
from nbxmpp.structs import XHTMLData
from nbxmpp.util import error_factory
from nbxmpp.const import MessageType

@@ -79,7 +81,17 @@ class BaseMessage:
        forms = stanza.getTags('x', namespace=NS_DATA)
        if forms:
            properties.forms = forms
        properties.xhtml = stanza.getXHTML()

        xhtml = stanza.getXHTML()
        if xhtml is None:
            return

        if xhtml.getTag('body', namespace=NS_XHTML) is None:
            log.warning('xhtml without body found')
            log.warning(stanza)
            return

        properties.xhtml = XHTMLData(xhtml)

    @staticmethod
    def _parse_type(stanza):
+14 −0
Changes for nbxmpp/modules/misc.py: 14 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ from nbxmpp.protocol import NS_FORWARD
from nbxmpp.protocol import NS_MUC_USER
from nbxmpp.protocol import NS_MAM_1
from nbxmpp.protocol import NS_MAM_2
from nbxmpp.protocol import NS_XHTML
from nbxmpp.protocol import NodeProcessed
from nbxmpp.protocol import InvalidFrom
from nbxmpp.protocol import InvalidStanza
@@ -118,3 +119,16 @@ def unwrap_mam(stanza, own_jid):
                            archive=stanza.getFrom(),
                            namespace=result.getNamespace(),
                            timestamp=delay_timestamp)


def build_xhtml_body(xhtml, xmllang=None):
    try:
        if xmllang is not None:
            body = '<body xmlns="%s" xml:lang="%s">%s</body>' % (
                NS_XHTML, xmllang, xhtml)
        else:
            body = '<body xmlns="%s">%s</body>' % (NS_XHTML, xhtml)
    except Exception as error:
        log.error('Error while building xhtml node: %s', error)
        return None
    return body
+15 −35
Changes for nbxmpp/protocol.py: 15 added lines, 35 removed lines.
Original line number Diff line number Diff line
@@ -26,7 +26,6 @@ from base64 import b64encode
from precis_i18n import get_profile
from nbxmpp.stringprepare import nameprep
from nbxmpp.simplexml import Node
from nbxmpp.simplexml import NodeBuilder

def ascii_upper(s):
    return s.upper()
@@ -1232,7 +1231,7 @@ class Message(Protocol):
                payload=payload, timestamp=timestamp, xmlns=xmlns, node=node)
        if body:
            self.setBody(body)
        if xhtml:
        if xhtml is not None:
            self.setXHTML(xhtml)
        if subject is not None:
            self.setSubject(subject)
@@ -1243,22 +1242,8 @@ class Message(Protocol):
        """
        return self.getTagData('body')

    def getXHTML(self, xmllang=None):
        """
        Return serialized xhtml-im element text of the message

        TODO: Returning a DOM could make rendering faster.
        """
        xhtml = self.getTag('html', namespace=NS_XHTML_IM)
        if xhtml:
            if xmllang:
                body = xhtml.getTag('body',
                                    namespace=NS_XHTML,
                                    attrs={'xml:lang': xmllang})
            else:
                body = xhtml.getTag('body', namespace=NS_XHTML)
            return str(body)
        return None
    def getXHTML(self):
        return self.getTag('html', namespace=NS_XHTML_IM)

    def getSubject(self):
        """
@@ -1293,25 +1278,20 @@ class Message(Protocol):
        Set the text of the message"""
        self.setTagData('body', val)

    def setXHTML(self, val, xmllang=None):
        """
        Sets the xhtml text of the message (XEP-0071). The parameter is the
        "inner html" to the body.
        """
        try:
            if xmllang:
                dom = NodeBuilder('<body xmlns="%s" xml:lang="%s">%s</body>' \
                    % (NS_XHTML, xmllang, val)).getDom()
    def setXHTML(self, body, add=False):
        if isinstance(body, str):
            body = Node(node=body)
        if add:
            xhtml = self.getTag('html', namespace=NS_XHTML_IM)
            if xhtml is not None:
                xhtml.addChild(node=body)
            else:
                dom = NodeBuilder('<body xmlns="%s">%s</body>' % (NS_XHTML,
                    val), 0).getDom()
            if self.getTag('html'):
                self.getTag('html').addChild(node=dom)
                self.addChild('html', namespace=NS_XHTML_IM, payload=body)
        else:
                self.setTag('html', namespace=NS_XHTML_IM).addChild(node=dom)
        except Exception as e:
            print("Error" + str(e))
            # FIXME: log. we could not set xhtml (parse error, whatever)
            xhtml_nodes = self.getTags('html', namespace=NS_XHTML_IM)
            for xhtml in xhtml_nodes:
                self.delChild(xhtml)
            self.addChild('html', namespace=NS_XHTML_IM, payload=body)

    def setSubject(self, val):
        """
+24 −0
Changes for nbxmpp/structs.py: 24 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ from nbxmpp.protocol import NS_MAM_2
from nbxmpp.protocol import NS_MUC
from nbxmpp.protocol import NS_MUC_INFO
from nbxmpp.protocol import NS_CLIENT
from nbxmpp.protocol import NS_XHTML
from nbxmpp.protocol import Protocol
from nbxmpp.const import MessageType
from nbxmpp.const import AvatarState
@@ -831,3 +832,26 @@ class PresenceProperties:
            return self.muc_user.role
        except Exception:
            return None


class XHTMLData:
    def __init__(self, xhtml):
        self._bodys = {}
        for body in xhtml.getTags('body', namespace=NS_XHTML):
            lang = body.getXmlLang()
            self._bodys[lang] = body

    def get_body(self, pref_lang=None):
        if pref_lang is not None:
            body = self._bodys.get(pref_lang)
            if body is not None:
                return str(body)

        body = self._bodys.get('en')
        if body is not None:
            return str(body)

        body = self._bodys.get(None)
        if body is not None:
            return str(body)
        return str(self._bodys.popitem()[1])