Commit 4e4ab569 authored by mathieui's avatar mathieui

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)
parent c3dd20fc
......@@ -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']
......
......@@ -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)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment