From 4e4ab569cf07fabf76339eeace1f6694f3414eff Mon Sep 17 00:00:00 2001 From: mathieui Date: Wed, 30 Apr 2014 01:55:23 +0200 Subject: Fix #2447 (OTR & HTML) -- partial WONTFIX - Guess-parse the OTR messages in search for xhtml upon arrival - add a configurable option to decode it or not - We have XHTML-IM for a reason, and therefore we will *not* implement a full html parser for clients that dump whatever formatting inside the OTR payload (looking at you, pidgin) --- plugins/otr.py | 18 +++++++++++++++--- src/xhtml.py | 12 +++++++----- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/plugins/otr.py b/plugins/otr.py index 3f22687f..96792a4d 100644 --- a/plugins/otr.py +++ b/plugins/otr.py @@ -121,6 +121,11 @@ Configuration .. glossary:: :sorted: + decode_xhtml + **Default:** ``true`` + + Decode embedded XHTML. + keys_dir **Default:** ``$XDG_DATA_HOME/poezio/otr`` @@ -141,8 +146,8 @@ Configuration Log conversations (OTR start/end marker, and messages). -The :term:`allow_v1`, :term:`allow_v2` and :term:`log` configuration -parameters are tab-specific. +The :term:`allow_v1`, :term:`allow_v2`, :term:`decode_html` +and :term:`log` configuration parameters are tab-specific. Important details ----------------- @@ -166,6 +171,7 @@ import curses from potr.context import NotEncryptedError, UnencryptedMessage, ErrorReceived, NotOTRMessage,\ STATE_ENCRYPTED, STATE_PLAINTEXT, STATE_FINISHED, Context, Account, crypt +import xhtml from plugin import BasePlugin from tabs import ConversationTab, DynamicConversationTab, PrivateTab from common import safeJID @@ -463,8 +469,14 @@ class Plugin(BasePlugin): user = None body = txt.decode() + if self.config.get_by_tabname('decode_xhtml', True, msg['from'].bare): + try: + body = xhtml.xhtml_to_poezio_colors(body, force=True) + except: + pass tab.add_message(body, nickname=tab.nick, jid=msg['from'], - forced_user=user, typ=ctx.log, nick_color=theming.get_theme().COLOR_REMOTE_USER) + forced_user=user, typ=ctx.log, + nick_color=theming.get_theme().COLOR_REMOTE_USER) hl(tab) self.core.refresh_window() del msg['body'] diff --git a/src/xhtml.py b/src/xhtml.py index 33a89b5e..48664311 100644 --- a/src/xhtml.py +++ b/src/xhtml.py @@ -281,13 +281,15 @@ def trim(string): return re.sub(whitespace_re, ' ', string) class XHTMLHandler(sax.ContentHandler): - def __init__(self): + def __init__(self, force_ns=False): self.builder = [] self.formatting = [] self.attrs = [] self.list_state = [] self.is_pre = False self.a_start = 0 + # do not care about xhtml-in namespace + self.force_ns = force_ns @property def result(self): @@ -305,7 +307,7 @@ class XHTMLHandler(sax.ContentHandler): self.builder.append(characters if self.is_pre else trim(characters)) def startElementNS(self, name, _, attrs): - if name[0] != XHTML_NS: + if name[0] != XHTML_NS and not self.force_ns: return builder = self.builder @@ -356,7 +358,7 @@ class XHTMLHandler(sax.ContentHandler): self.append_formatting('\x19b') def endElementNS(self, name, _): - if name[0] != XHTML_NS: + if name[0] != XHTML_NS and not self.force_ns: return builder = self.builder @@ -387,13 +389,13 @@ class XHTMLHandler(sax.ContentHandler): if 'title' in attrs: builder.append(' [' + attrs['title'] + ']') -def xhtml_to_poezio_colors(xml): +def xhtml_to_poezio_colors(xml, force=False): if isinstance(xml, str): xml = xml.encode('utf8') elif not isinstance(xml, bytes): xml = ET.tostring(xml) - handler = XHTMLHandler() + handler = XHTMLHandler(force_ns=force) parser = sax.make_parser() parser.setFeature(sax.handler.feature_namespaces, True) parser.setContentHandler(handler) -- cgit v1.2.3