From b3816a9fd256fa7df25edd46a451ae1cf3756aa1 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Fri, 6 Mar 2020 12:01:33 +0100 Subject: widgets/thread: improve rendering message source Also, stop accessing the email directly. --- alot/widgets/thread.py | 63 +++++++++++++++++++++++++++++++------------------- 1 file changed, 39 insertions(+), 24 deletions(-) (limited to 'alot/widgets') diff --git a/alot/widgets/thread.py b/alot/widgets/thread.py index dcbbd9da..8f771590 100644 --- a/alot/widgets/thread.py +++ b/alot/widgets/thread.py @@ -12,7 +12,6 @@ from .globals import TagWidget from .globals import AttachmentWidget from ..settings.const import settings from ..db.message import X_SIGNATURE_MESSAGE_HEADER -from ..helper import string_sanitize class MessageSummaryWidget(urwid.WidgetWrap): """ @@ -72,21 +71,6 @@ class MessageSummaryWidget(urwid.WidgetWrap): def keypress(self, size, key): return key - -class FocusableText(urwid.WidgetWrap): - """Selectable Text used for nodes in our example""" - def __init__(self, txt, att, att_focus): - t = urwid.Text(txt) - w = urwid.AttrMap(t, att, att_focus) - super().__init__(w) - - def selectable(self): - return True - - def keypress(self, size, key): - return key - - class HeadersWidget(urwid.WidgetWrap): """ A flow widget displaying message headers. @@ -131,6 +115,44 @@ class HeadersWidget(urwid.WidgetWrap): self._w.contents = [(w, ('pack', None)) for w in widgets] +def _make_ascii_trans(): + trans = { + 0x09 : ' ' * 8, # tab + 0x0b : '<\\v>\n', # vertical tab + 0x0c : '<\\f>\n', # form feed + 0x0d : '', # carriage return + } + for i in range(256): + if (i >= 0x20 and i <= 0x7e) or i == 0x0a: + # printables and \n + trans[i] = chr(i) + elif not i in trans: + trans[i] = r'<\x%x>' % i + + return trans + +_ascii_trans = _make_ascii_trans() + +def _ascii_to_printable(data): + """ + Prepare ASCII data for printing. + + :param data: input data + :type data: bytes + :returns: Data suitable for printing. It will contain only printable + characters (U+0020-U+007E) and a newline (U+000A). + :rtype: str + """ + return data.decode('latin1').translate(_ascii_trans) + +class _RawMessageWidget(urwid.WidgetWrap): + """ + A flow widget displaying the "raw" message. + """ + def __init__(self, msg_bytes): + sourcetxt = _ascii_to_printable(msg_bytes) + super().__init__(urwid.Text(sourcetxt)) + class MessageWidget(urwid.WidgetWrap): """ A flow widget displaying the contents of a single :class:`alot.db.Message`. @@ -157,7 +179,7 @@ class MessageWidget(urwid.WidgetWrap): self._message = message self._headers_wgt = self._get_headers() - self._source_wgt = self._get_source() + self._source_wgt = _RawMessageWidget(message.as_bytes()) self._body_wgt = self._get_body() self._attach_wgt = self._get_attachments() @@ -184,13 +206,6 @@ class MessageWidget(urwid.WidgetWrap): self._w.body[:] = widgets - def _get_source(self): - sourcetxt = self._message.get_email().as_string() - sourcetxt = string_sanitize(sourcetxt) - att = settings.get_theming_attribute('thread', 'body') - att_focus = settings.get_theming_attribute('thread', 'body_focus') - return FocusableText(sourcetxt, att, att_focus) - def _get_body(self): attr_body = settings.get_theming_attribute('thread', 'body') attrs_quote = settings.get_quote_theming() -- cgit v1.2.3