# Path: alot/widgets/ansi.py
# class ANSIText(urwid.WidgetWrap):
# 
#     """Selectable Text widget that interprets ANSI color codes"""
# 
#     def __init__(self, txt,
#                  default_attr=None,
#                  default_attr_focus=None,
#                  ansi_background=True,
#                  mimepart=False,
#                  **kwds):
#         self.mimepart = mimepart
#         ct, focus_map = parse_escapes_to_urwid(txt, default_attr,
#                                                default_attr_focus,
#                                                ansi_background)
#         t = urwid.Text(ct, **kwds)
#         attr_map = {default_attr.background: ''}
#         w = urwid.AttrMap(t, attr_map, focus_map)
#         urwid.WidgetWrap.__init__(self, w)
# 
#     def selectable(self):
#         return True
# 
#     def keypress(self, size, key):
#         return key
# 
# Path: alot/db/utils.py
# def decode_header(header, normalize=False):
#     """
#     decode a header value to a unicode string
# 
#     values are usually a mixture of different substrings
#     encoded in quoted printable using different encodings.
#     This turns it into a single unicode string
# 
#     :param header: the header value
#     :type header: str
#     :param normalize: replace trailing spaces after newlines
#     :type normalize: bool
#     :rtype: str
#     """
#     logging.debug("unquoted header: |%s|", header)
# 
#     valuelist = email.header.decode_header(header)
#     decoded_list = []
#     for v, enc in valuelist:
#         v = string_decode(v, enc)
#         decoded_list.append(string_sanitize(v))
#     value = ''.join(decoded_list)
#     if normalize:
#         value = re.sub(r'\n\s+', r' ', value)
#     return value
# 
# X_SIGNATURE_MESSAGE_HEADER = 'X-Alot-OpenPGP-Signature-Message'
# 
# Path: alot/helper.py
# def string_sanitize(string, tab_width=8):
#     r"""
#     strips, and replaces non-printable characters
# 
#     :param tab_width: number of spaces to replace tabs with. Read from
#                       `globals.tabwidth` setting if `None`
#     :type tab_width: int or `None`
# 
#     >>> string_sanitize(' foo\rbar ', 8)
#     ' foobar '
#     >>> string_sanitize('foo\tbar', 8)
#     'foo     bar'
#     >>> string_sanitize('foo\t\tbar', 8)
#     'foo             bar'
#     """
# 
#     string = string.replace('\r', '')
# 
#     lines = list()
#     for line in string.split('\n'):
#         tab_count = line.count('\t')
# 
#         if tab_count > 0:
#             line_length = 0
#             new_line = list()
#             for i, chunk in enumerate(line.split('\t')):
#                 line_length += len(chunk)
#                 new_line.append(chunk)
# 
#                 if i < tab_count:
#                     next_tab_stop_in = tab_width - (line_length % tab_width)
#                     new_line.append(' ' * next_tab_stop_in)
#                     line_length += next_tab_stop_in
#             lines.append(''.join(new_line))
#         else:
#             lines.append(line)
# 
#     return '\n'.join(lines)


import email
import logging
import urwid
from urwidtrees import Tree, SimpleTree, CollapsibleTree, ArrowTree
from .ansi import ANSIText
from .globals import TagWidget
from .globals import AttachmentWidget
from ..settings.const import settings
from ..db.attachment import Attachment
from ..db.utils import decode_header, X_SIGNATURE_MESSAGE_HEADER
from ..helper import string_sanitize

    def _get_headers(self):
        if self.display_all_headers is True:
            if self._all_headers_tree is None:
                self._all_headers_tree = self.construct_header_pile()
            ret = self._all_headers_tree
        else:
            if self._default_headers_tree is None:
                headers = settings.get('displayed_headers')
                self._default_headers_tree = self.construct_header_pile(
                    headers)
            ret = self._default_headers_tree
        return ret

    def _get_attachments(self):
        if self._attachments is None:
            alist = []
            for a in self._message.get_attachments():
                alist.append((AttachmentWidget(a), None))
            if alist:
                self._attachments = SimpleTree(alist)
        return self._attachments

    def construct_header_pile(self, headers=None, normalize=True):
        mail = self._message.get_email()
        lines = []

        if headers is None:
            # collect all header/value pairs in the order they appear
            for key, value in mail.items():

# Path: alot/widgets/ansi.py
# class ANSIText(urwid.WidgetWrap):
# 
#     """Selectable Text widget that interprets ANSI color codes"""
# 
#     def __init__(self, txt,
#                  default_attr=None,
#                  default_attr_focus=None,
#                  ansi_background=True,
#                  mimepart=False,
#                  **kwds):
#         self.mimepart = mimepart
#         ct, focus_map = parse_escapes_to_urwid(txt, default_attr,
#                                                default_attr_focus,
#                                                ansi_background)
#         t = urwid.Text(ct, **kwds)
#         attr_map = {default_attr.background: ''}
#         w = urwid.AttrMap(t, attr_map, focus_map)
#         urwid.WidgetWrap.__init__(self, w)
# 
#     def selectable(self):
#         return True
# 
#     def keypress(self, size, key):
#         return key
# 
# Path: alot/db/utils.py
# def decode_header(header, normalize=False):
#     """
#     decode a header value to a unicode string
# 
#     values are usually a mixture of different substrings
#     encoded in quoted printable using different encodings.
#     This turns it into a single unicode string
# 
#     :param header: the header value
#     :type header: str
#     :param normalize: replace trailing spaces after newlines
#     :type normalize: bool
#     :rtype: str
#     """
#     logging.debug("unquoted header: |%s|", header)
# 
#     valuelist = email.header.decode_header(header)
#     decoded_list = []
#     for v, enc in valuelist:
#         v = string_decode(v, enc)
#         decoded_list.append(string_sanitize(v))
#     value = ''.join(decoded_list)
#     if normalize:
#         value = re.sub(r'\n\s+', r' ', value)
#     return value
# 
# X_SIGNATURE_MESSAGE_HEADER = 'X-Alot-OpenPGP-Signature-Message'
# 
# Path: alot/helper.py
# def string_sanitize(string, tab_width=8):
#     r"""
#     strips, and replaces non-printable characters
# 
#     :param tab_width: number of spaces to replace tabs with. Read from
#                       `globals.tabwidth` setting if `None`
#     :type tab_width: int or `None`
# 
#     >>> string_sanitize(' foo\rbar ', 8)
#     ' foobar '
#     >>> string_sanitize('foo\tbar', 8)
#     'foo     bar'
#     >>> string_sanitize('foo\t\tbar', 8)
#     'foo             bar'
#     """
# 
#     string = string.replace('\r', '')
# 
#     lines = list()
#     for line in string.split('\n'):
#         tab_count = line.count('\t')
# 
#         if tab_count > 0:
#             line_length = 0
#             new_line = list()
#             for i, chunk in enumerate(line.split('\t')):
#                 line_length += len(chunk)
#                 new_line.append(chunk)
# 
#                 if i < tab_count:
#                     next_tab_stop_in = tab_width - (line_length % tab_width)
#                     new_line.append(' ' * next_tab_stop_in)
#                     line_length += next_tab_stop_in
#             lines.append(''.join(new_line))
#         else:
#             lines.append(line)
# 
#     return '\n'.join(lines)


# Path: alot/widgets/thread.py
import email
import logging
import urwid
from urwidtrees import Tree, SimpleTree, CollapsibleTree, ArrowTree
from .ansi import ANSIText
from .globals import TagWidget
from .globals import AttachmentWidget
from ..settings.const import settings
from ..db.attachment import Attachment
from ..db.utils import decode_header, X_SIGNATURE_MESSAGE_HEADER
from ..helper import string_sanitize


    def _get_headers(self):
        if self.display_all_headers is True:
            if self._all_headers_tree is None:
                self._all_headers_tree = self.construct_header_pile()
            ret = self._all_headers_tree
        else:
            if self._default_headers_tree is None:
                headers = settings.get('displayed_headers')
                self._default_headers_tree = self.construct_header_pile(
                    headers)
            ret = self._default_headers_tree
        return ret

    def _get_attachments(self):
        if self._attachments is None:
            alist = []
            for a in self._message.get_attachments():
                alist.append((AttachmentWidget(a), None))
            if alist:
                self._attachments = SimpleTree(alist)
        return self._attachments

    def construct_header_pile(self, headers=None, normalize=True):
        mail = self._message.get_email()
        lines = []

        if headers is None:
            # collect all header/value pairs in the order they appear
            for key, value in mail.items():

                dvalue = decode_header(value, normalize=normalize)