Example #1
0
    def construct_header_pile(self, headers=None, normalize=True):
        mail = self._message.get_email()
        if headers is None:
            headers = mail.keys()
        else:
            headers = [k for k in headers if
                       k.lower() == 'tags' or k in mail]

        lines = []
        for key in headers:
            if key in mail:
                if key.lower() in ['cc', 'bcc', 'to']:
                    values = mail.get_all(key)
                    values = [decode_header(
                        v, normalize=normalize) for v in values]
                    lines.append((key, ', '.join(values)))
                else:
                    for value in mail.get_all(key):
                        dvalue = decode_header(value, normalize=normalize)
                        lines.append((key, dvalue))
            elif key.lower() == 'tags':
                logging.debug('want tags header')
                values = []
                for t in self._message.get_tags():
                    tagrep = settings.get_tagstring_representation(t)
                    if t is not tagrep['translated']:
                        t = '%s (%s)' % (tagrep['translated'], t)
                    values.append(t)
                lines.append((key, ', '.join(values)))

        key_att = settings.get_theming_attribute('thread', 'header_key')
        value_att = settings.get_theming_attribute('thread', 'header_value')
        gaps_att = settings.get_theming_attribute('thread', 'header')
        return DictList(lines, key_att, value_att, gaps_att)
Example #2
0
File: thread.py Project: fagga/alot
    def _get_header_widget(self):
        """creates/returns the widget that displays the mail header"""
        all_shown = (self._all_headers == self._displayed_headers)

        if self.headerw and (self.show_all_headers == all_shown):
            return self.headerw

        if self.show_all_headers:
            self._displayed_headers = self._all_headers
        else:
            self._displayed_headers = self._filtered_headers

        mail = self.message.get_email()
        # normalize values if only filtered list is shown
        norm = not (self._displayed_headers == self._all_headers)

        #build lines
        lines = []
        for key in self._displayed_headers:
            logging.debug('want header: %s' % (key))
            if key in mail:
                if key.lower() in ['cc', 'bcc', 'to']:
                    values = mail.get_all(key)
                    values = [decode_header(v, normalize=norm) for v in values]
                    lines.append((key, ', '.join(values)))
                else:
                    for value in mail.get_all(key):
                        dvalue = decode_header(value, normalize=norm)
                        lines.append((key, dvalue))
            elif key.lower() == 'tags':
                logging.debug('want tags header')
                values = []
                for t in self.message.get_tags():
                    tagrep = settings.get_tagstring_representation(t)
                    if t is not tagrep['translated']:
                        t = '%s (%s)' % (tagrep['translated'], t)
                    values.append(t)
                lines.append((key, ', '.join(values)))

        key_att = settings.get_theming_attribute('thread', 'header_key')
        value_att = settings.get_theming_attribute('thread', 'header_value')
        gaps_att = settings.get_theming_attribute('thread', 'header')
        cols = [HeadersList(lines, key_att, value_att, gaps_att)]
        bc = list()
        if self.depth:
            cols.insert(0, self._get_spacer(self.bars_at[1:]))
            bc.append(0)
            cols.insert(1, self._get_arrowhead_aligner())
            bc.append(1)
        self.headerw = urwid.Columns(cols, box_columns=bc)
        return self.headerw
Example #3
0
    def _get_header_widget(self):
        """creates/returns the widget that displays the mail header"""
        all_shown = (self._all_headers == self._displayed_headers)

        if self.headerw and (self.show_all_headers == all_shown):
            return self.headerw

        if self.show_all_headers:
            self._displayed_headers = self._all_headers
        else:
            self._displayed_headers = self._filtered_headers

        mail = self.message.get_email()
        # normalize values if only filtered list is shown
        norm = not (self._displayed_headers == self._all_headers)

        #build lines
        lines = []
        for key in self._displayed_headers:
            logging.debug('want header: %s' % (key))
            if key in mail:
                if key.lower() in ['cc', 'bcc', 'to']:
                    values = mail.get_all(key)
                    values = [decode_header(v, normalize=norm) for v in values]
                    lines.append((key, ', '.join(values)))
                else:
                    for value in mail.get_all(key):
                        dvalue = decode_header(value, normalize=norm)
                        lines.append((key, dvalue))
            elif key.lower() == 'tags':
                logging.debug('want tags header')
                values = []
                for t in self.message.get_tags():
                    tagrep = settings.get_tagstring_representation(t)
                    if t is not tagrep['translated']:
                        t = '%s (%s)' % (tagrep['translated'], t)
                    values.append(t)
                lines.append((key, ', '.join(values)))

        key_att = settings.get_theming_attribute('thread', 'header_key')
        value_att = settings.get_theming_attribute('thread', 'header_value')
        gaps_att = settings.get_theming_attribute('thread', 'header')
        cols = [HeadersList(lines, key_att, value_att, gaps_att)]
        bc = list()
        if self.depth:
            cols.insert(0, self._get_spacer(self.bars_at[1:]))
            bc.append(0)
            cols.insert(1, self._get_arrowhead_aligner())
            bc.append(1)
        self.headerw = urwid.Columns(cols, box_columns=bc)
        return self.headerw
Example #4
0
    def _get_header_widget(self):
        """creates/returns the widget that displays the mail header"""
        all_shown = (self._all_headers == self._displayed_headers)

        if self.headerw and (self.show_all_headers == all_shown):
            return self.headerw

        if self.show_all_headers:
            self._displayed_headers = self._all_headers
        else:
            self._displayed_headers = self._filtered_headers

        mail = self.message.get_email()
        # normalize values if only filtered list is shown
        norm = not (self._displayed_headers == self._all_headers)

        #build lines
        lines = []
        for key in self._displayed_headers:
            if key in mail:
                for value in mail.get_all(key):
                    dvalue = decode_header(value, normalize=norm)
                    lines.append((key, dvalue))

        cols = [HeadersList(lines)]
        bc = list()
        if self.depth:
            cols.insert(0, self._get_spacer(self.bars_at[1:]))
            bc.append(0)
            cols.insert(1, self._get_arrowhead_aligner())
            bc.append(1)
        self.headerw = urwid.Columns(cols, box_columns=bc)
        return self.headerw
Example #5
0
File: thread.py Project: t-8ch/alot
    def apply(self, ui):
        # look if this makes sense: do we have any accounts set up?
        my_accounts = settings.get_accounts()
        if not my_accounts:
            ui.notify('no accounts set', priority='error')
            return

        # get message to forward if not given in constructor
        if not self.message:
            self.message = ui.current_buffer.get_selected_message()
        mail = self.message.get_email()

        envelope = Envelope()

        if self.inline:  # inline mode
            # set body text
            name, address = self.message.get_author()
            timestamp = self.message.get_date()
            qf = settings.get_hook('forward_prefix')
            if qf:
                quote = qf(name, address, timestamp, ui=ui, dbm=ui.dbman)
            else:
                quote = 'Forwarded message from %s (%s):\n' % (name or address,
                                                               timestamp)
            mailcontent = quote
            quotehook = settings.get_hook('text_quote')
            if quotehook:
                mailcontent += quotehook(self.message.accumulate_body())
            else:
                quote_prefix = settings.get('quote_prefix')
                for line in self.message.accumulate_body().splitlines():
                    mailcontent += quote_prefix + line + '\n'

            envelope.body = mailcontent

        else:  # attach original mode
            # attach original msg
            mail.set_type('message/rfc822')
            mail['Content-Disposition'] = 'attachment'
            envelope.attach(Attachment(mail))

        # copy subject
        subject = decode_header(mail.get('Subject', ''))
        subject = 'Fwd: ' + subject
        forward_subject_hook = settings.get_hook('forward_subject')
        if forward_subject_hook:
            subject = forward_subject_hook(subject)
        else:
            fsp = settings.get('forward_subject_prefix')
            if not subject.startswith(('Fwd:', fsp)):
                subject = fsp + subject
        envelope.add('Subject', subject)

        # set From
        realname, address = recipient_to_from(mail, my_accounts)
        envelope.add('From', '%s <%s>' % (realname, address))

        # continue to compose
        ui.apply_command(
            ComposeCommand(envelope=envelope, spawn=self.force_spawn))
Example #6
0
File: thread.py Project: t-8ch/alot
    def apply(self, ui):
        if not self.message:
            self.message = ui.current_buffer.get_selected_message()
        mail = self.message.get_email()
        # set body text
        name, address = self.message.get_author()
        mailcontent = self.message.accumulate_body()
        envelope = Envelope(bodytext=mailcontent)

        # copy selected headers
        to_copy = [
            'Subject', 'From', 'To', 'Cc', 'Bcc', 'In-Reply-To', 'References'
        ]
        for key in to_copy:
            value = decode_header(mail.get(key, ''))
            if value:
                envelope.add(key, value)

        # copy attachments
        for b in self.message.get_attachments():
            envelope.attach(b)

        ui.apply_command(
            ComposeCommand(envelope=envelope,
                           spawn=self.force_spawn,
                           omit_signature=True))
Example #7
0
    def apply(self, ui):
        # look if this makes sense: do we have any accounts set up?
        my_accounts = settings.get_accounts()
        if not my_accounts:
            ui.notify('no accounts set', priority='error')
            return

        # get message to forward if not given in constructor
        if not self.message:
            self.message = ui.current_buffer.get_selected_message()
        mail = self.message.get_email()

        envelope = Envelope()

        if self.inline:  # inline mode
            # set body text
            name, address = self.message.get_author()
            timestamp = self.message.get_date()
            qf = settings.get_hook('forward_prefix')
            if qf:
                quote = qf(name, address, timestamp, ui=ui, dbm=ui.dbman)
            else:
                quote = 'Forwarded message from %s (%s):\n' % (
                    name or address, timestamp)
            mailcontent = quote
            quotehook = settings.get_hook('text_quote')
            if quotehook:
                mailcontent += quotehook(self.message.accumulate_body())
            else:
                quote_prefix = settings.get('quote_prefix')
                for line in self.message.accumulate_body().splitlines():
                    mailcontent += quote_prefix + line + '\n'

            envelope.body = mailcontent

        else:  # attach original mode
            # attach original msg
            mail.set_type('message/rfc822')
            mail['Content-Disposition'] = 'attachment'
            envelope.attach(Attachment(mail))

        # copy subject
        subject = decode_header(mail.get('Subject', ''))
        subject = 'Fwd: ' + subject
        forward_subject_hook = settings.get_hook('forward_subject')
        if forward_subject_hook:
            subject = forward_subject_hook(subject)
        else:
            fsp = settings.get('forward_subject_prefix')
            if not subject.startswith(('Fwd:', fsp)):
                subject = fsp + subject
        envelope.add('Subject', subject)

        # set From
        realname, address = recipient_to_from(mail, my_accounts)
        envelope.add('From', '%s <%s>' % (realname, address))

        # continue to compose
        ui.apply_command(ComposeCommand(envelope=envelope,
                                        spawn=self.force_spawn))
Example #8
0
    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
            headers = mail.keys()
            for key, value in mail.items():
                dvalue = decode_header(value, normalize=normalize)
                lines.append((key, dvalue))
        else:
            # only a selection of headers should be displayed.
            # use order of the `headers` parameter
            for key in headers:
                if key in mail:
                    if key.lower() in ['cc', 'bcc', 'to']:
                        values = mail.get_all(key)
                        values = [
                            decode_header(v, normalize=normalize)
                            for v in values
                        ]
                        lines.append((key, ', '.join(values)))
                    else:
                        for value in mail.get_all(key):
                            dvalue = decode_header(value, normalize=normalize)
                            lines.append((key, dvalue))
                elif key.lower() == 'tags':
                    logging.debug('want tags header')
                    values = []
                    for t in self._message.get_tags():
                        tagrep = settings.get_tagstring_representation(t)
                        if t is not tagrep['translated']:
                            t = '%s (%s)' % (tagrep['translated'], t)
                        values.append(t)
                    lines.append((key, ', '.join(values)))

        # OpenPGP pseudo headers
        if mail[X_SIGNATURE_MESSAGE_HEADER]:
            lines.append(('PGP-Signature', mail[X_SIGNATURE_MESSAGE_HEADER]))

        key_att = settings.get_theming_attribute('thread', 'header_key')
        value_att = settings.get_theming_attribute('thread', 'header_value')
        gaps_att = settings.get_theming_attribute('thread', 'header')
        return DictList(lines, key_att, value_att, gaps_att)
Example #9
0
 def get_filename(self):
     """
     return name of attached file.
     If the content-disposition header contains no file name,
     this returns `None`
     """
     extracted_name = decode_header(self.part.get_filename())
     if extracted_name:
         return os.path.basename(extracted_name)
     return None
Example #10
0
    def _get_header_widget(self):
        """creates/returns the widget that displays the mail header"""
        all_shown = (self._all_headers == self._displayed_headers)

        if self.headerw and (self.show_all_headers == all_shown):
            return self.headerw

        if self.show_all_headers:
            self._displayed_headers = self._all_headers
        else:
            self._displayed_headers = self._filtered_headers

        mail = self.message.get_email()
        # normalize values if only filtered list is shown
        norm = not (self._displayed_headers == self._all_headers)

        #build lines
        lines = []
        for key in self._displayed_headers:
            if key in mail:
                if key.lower() in ['cc', 'bcc', 'to']:
                    values = mail.get_all(key)
                    dvalues = [
                        decode_header(v, normalize=norm) for v in values
                    ]
                    lines.append((key, ', '.join(dvalues)))
                else:
                    for value in mail.get_all(key):
                        dvalue = decode_header(value, normalize=norm)
                        lines.append((key, dvalue))

        key_att = settings.get_theming_attribute('thread', 'header_key')
        value_att = settings.get_theming_attribute('thread', 'header_value')
        cols = [HeadersList(lines, key_att, value_att)]
        bc = list()
        if self.depth:
            cols.insert(0, self._get_spacer(self.bars_at[1:]))
            bc.append(0)
            cols.insert(1, self._get_arrowhead_aligner())
            bc.append(1)
        self.headerw = urwid.Columns(cols, box_columns=bc)
        return self.headerw
Example #11
0
    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
            headers = list(mail.keys())
            for key, value in list(mail.items()):
                dvalue = decode_header(value, normalize=normalize)
                lines.append((key, dvalue))
        else:
            # only a selection of headers should be displayed.
            # use order of the `headers` parameter
            for key in headers:
                if key in mail:
                    if key.lower() in ['cc', 'bcc', 'to']:
                        values = mail.get_all(key)
                        values = [decode_header(
                            v, normalize=normalize) for v in values]
                        lines.append((key, ', '.join(values)))
                    else:
                        for value in mail.get_all(key):
                            dvalue = decode_header(value, normalize=normalize)
                            lines.append((key, dvalue))
                elif key.lower() == 'tags':
                    logging.debug('want tags header')
                    values = []
                    for t in self._message.get_tags():
                        tagrep = settings.get_tagstring_representation(t)
                        if t is not tagrep['translated']:
                            t = '%s (%s)' % (tagrep['translated'], t)
                        values.append(t)
                    lines.append((key, ', '.join(values)))

        # OpenPGP pseudo headers
        if mail[X_SIGNATURE_MESSAGE_HEADER]:
            lines.append(('PGP-Signature', mail[X_SIGNATURE_MESSAGE_HEADER]))

        key_att = settings.get_theming_attribute('thread', 'header_key')
        value_att = settings.get_theming_attribute('thread', 'header_value')
        gaps_att = settings.get_theming_attribute('thread', 'header')
        return DictList(lines, key_att, value_att, gaps_att)
Example #12
0
 def get_filename(self):
     """
     return name of attached file.
     If the content-disposition header contains no file name,
     this returns `None`
     """
     fname = self.part.get_filename()
     if fname:
         extracted_name = decode_header(fname)
         if extracted_name:
             return os.path.basename(extracted_name)
     return None
Example #13
0
    def _get_header_widget(self):
        """creates/returns the widget that displays the mail header"""
        all_shown = self._all_headers == self._displayed_headers

        if self.headerw and (self.show_all_headers == all_shown):
            return self.headerw

        if self.show_all_headers:
            self._displayed_headers = self._all_headers
        else:
            self._displayed_headers = self._filtered_headers

        mail = self.message.get_email()
        # normalize values if only filtered list is shown
        norm = not (self._displayed_headers == self._all_headers)

        # build lines
        lines = []
        for key in self._displayed_headers:
            if key in mail:
                if key.lower() in ["cc", "bcc", "to"]:
                    values = mail.get_all(key)
                    values = [decode_header(v, normalize=norm) for v in values]
                    lines.append((key, ", ".join(values)))
                else:
                    for value in mail.get_all(key):
                        dvalue = decode_header(value, normalize=norm)
                        lines.append((key, dvalue))

        key_att = settings.get_theming_attribute("thread", "header_key")
        value_att = settings.get_theming_attribute("thread", "header_value")
        cols = [HeadersList(lines, key_att, value_att)]
        bc = list()
        if self.depth:
            cols.insert(0, self._get_spacer(self.bars_at[1:]))
            bc.append(0)
            cols.insert(1, self._get_arrowhead_aligner())
            bc.append(1)
        self.headerw = urwid.Columns(cols, box_columns=bc)
        return self.headerw
Example #14
0
 def __init__(self, dbman, msg, thread=None):
     """
     :param dbman: db manager that is used for further lookups
     :type dbman: alot.db.DBManager
     :param msg: the wrapped message
     :type msg: notmuch.database.Message
     :param thread: this messages thread (will be looked up later if `None`)
     :type thread: :class:`~alot.db.Thread` or `None`
     """
     self._dbman = dbman
     self._id = msg.get_message_id()
     self._thread_id = msg.get_thread_id()
     self._thread = thread
     casts_date = lambda: datetime.fromtimestamp(msg.get_date())
     self._datetime = helper.safely_get(casts_date, ValueError, None)
     self._filename = msg.get_filename()
     author = helper.safely_get(lambda: msg.get_header('From'),
                                NullPointerError)
     self._from = decode_header(author)
     self._email = None  # will be read upon first use
     self._attachments = None  # will be read upon first use
     self._tags = set(msg.get_tags())
Example #15
0
File: message.py Project: a3nm/alot
 def __init__(self, dbman, msg, thread=None):
     """
     :param dbman: db manager that is used for further lookups
     :type dbman: alot.db.DBManager
     :param msg: the wrapped message
     :type msg: notmuch.database.Message
     :param thread: this messages thread (will be looked up later if `None`)
     :type thread: :class:`~alot.db.Thread` or `None`
     """
     self._dbman = dbman
     self._id = msg.get_message_id()
     self._thread_id = msg.get_thread_id()
     self._thread = thread
     casts_date = lambda: datetime.fromtimestamp(msg.get_date())
     self._datetime = helper.safely_get(casts_date,
                                       ValueError, None)
     self._filename = msg.get_filename()
     author = helper.safely_get(lambda: msg.get_header('From'),
                                    NullPointerError)
     self._from = decode_header(author)
     self._email = None  # will be read upon first use
     self._attachments = None  # will be read upon first use
     self._tags = set(msg.get_tags())
Example #16
0
    def apply(self, ui):
        if not self.message:
            self.message = ui.current_buffer.get_selected_message()
        mail = self.message.get_email()
        # set body text
        name, address = self.message.get_author()
        mailcontent = self.message.accumulate_body()
        envelope = Envelope(bodytext=mailcontent)

        # copy selected headers
        to_copy = ['Subject', 'From', 'To', 'Cc', 'Bcc', 'In-Reply-To',
                   'References']
        for key in to_copy:
            value = decode_header(mail.get(key, ''))
            if value:
                envelope.add(key, value)

        # copy attachments
        for b in self.message.get_attachments():
            envelope.attach(b)

        ui.apply_command(ComposeCommand(envelope=envelope,
                                        spawn=self.force_spawn,
                                        omit_signature=True))
Example #17
0
File: thread.py Project: vrs/alot
    def apply(self, ui):
        # get message to forward if not given in constructor
        if not self.message:
            self.message = ui.current_buffer.get_selected_message()
        mail = self.message.get_email()

        envelope = Envelope()

        if self.inline:  # inline mode
            # set body text
            name, address = self.message.get_author()
            timestamp = self.message.get_date()
            qf = settings.get_hook('forward_prefix')
            if qf:
                quote = qf(name, address, timestamp, ui=ui, dbm=ui.dbman)
            else:
                quote = 'Forwarded message from %s (%s):\n' % (
                    name or address, timestamp)
            mailcontent = quote
            quotehook = settings.get_hook('text_quote')
            if quotehook:
                mailcontent += quotehook(self.message.accumulate_body())
            else:
                quote_prefix = settings.get('quote_prefix')
                for line in self.message.accumulate_body().splitlines():
                    mailcontent += quote_prefix + line + '\n'

            envelope.body = mailcontent

            for a in self.message.get_attachments():
                envelope.attach(a)

        else:  # attach original mode
            # attach original msg
            original_mail = Message()
            original_mail.set_type('message/rfc822')
            original_mail['Content-Disposition'] = 'attachment'
            original_mail.set_payload(email_as_string(mail))
            envelope.attach(Attachment(original_mail))

        # copy subject
        subject = decode_header(mail.get('Subject', ''))
        subject = 'Fwd: ' + subject
        forward_subject_hook = settings.get_hook('forward_subject')
        if forward_subject_hook:
            subject = forward_subject_hook(subject)
        else:
            fsp = settings.get('forward_subject_prefix')
            if not subject.startswith(('Fwd:', fsp)):
                subject = fsp + subject
        envelope.add('Subject', subject)

        # set From-header and sending account
        try:
            from_header, account = determine_sender(mail, 'reply')
        except AssertionError as e:
            ui.notify(e.message, priority='error')
            return
        envelope.add('From', from_header)

        # continue to compose
        ui.apply_command(ComposeCommand(envelope=envelope,
                                        spawn=self.force_spawn))
Example #18
0
 def test_continuation_newlines_can_be_normalized(self):
     text = 'first\nsecond\n third\n\tfourth\n \t  fifth'
     expected = u'first\nsecond third fourth fifth'
     actual = utils.decode_header(text, normalize=True)
     self.assertEqual(actual, expected)
Example #19
0
 def _test(self, teststring, expected):
     actual = utils.decode_header(teststring)
     self.assertEqual(actual, expected)
Example #20
0
    def apply(self, ui):
        # look if this makes sense: do we have any accounts set up?
        my_accounts = settings.get_accounts()
        if not my_accounts:
            ui.notify('no accounts set', priority='error')
            return

        # get message to forward if not given in constructor
        if not self.message:
            self.message = ui.current_buffer.get_selected_message()
        mail = self.message.get_email()

        # set body text
        name, address = self.message.get_author()
        timestamp = self.message.get_date()
        qf = settings.get_hook('reply_prefix')
        if qf:
            quotestring = qf(name, address, timestamp, ui=ui, dbm=ui.dbman)
        else:
            quotestring = 'Quoting %s (%s)\n' % (name, timestamp)
        mailcontent = quotestring
        for line in self.message.accumulate_body().splitlines():
            mailcontent += '>' + line + '\n'

        envelope = Envelope(bodytext=mailcontent)

        # copy subject
        subject = decode_header(mail.get('Subject', ''))
        if not subject.startswith('Re:'):
            subject = 'Re: ' + subject
        envelope.add('Subject', subject)

        # set From
        realname, address = recipient_to_from(mail, my_accounts)
        envelope.add('From', '%s <%s>' % (realname, address))

        # set To
        sender = mail['Reply-To'] or mail['From']
        recipients = [sender]
        my_addresses = settings.get_addresses()
        if self.groupreply:
            if sender != mail['From']:
                recipients.append(mail['From'])
            cleared = self.clear_my_address(my_addresses, mail.get('To', ''))
            recipients.append(cleared)

            # copy cc for group-replies
            if 'Cc' in mail:
                cc = self.clear_my_address(my_addresses, mail['Cc'])
                envelope.add('Cc', decode_header(cc))

        to = ', '.join(recipients)
        logging.debug('reply to: %s' % to)
        envelope.add('To', decode_header(to))

        # set In-Reply-To header
        envelope.add('In-Reply-To', '<%s>' % self.message.get_message_id())

        # set References header
        old_references = mail.get('References', '')
        if old_references:
            old_references = old_references.split()
            references = old_references[-8:]
            if len(old_references) > 8:
                references = old_references[:1] + references
            references.append('<%s>' % self.message.get_message_id())
            envelope.add('References', ' '.join(references))
        else:
            envelope.add('References', '<%s>' % self.message.get_message_id())

        # continue to compose
        ui.apply_command(ComposeCommand(envelope=envelope,
                                        spawn=self.force_spawn))
Example #21
0
    def apply(self, ui):
        # get message to forward if not given in constructor
        if not self.message:
            self.message = ui.current_buffer.get_selected_message()
        mail = self.message.get_email()

        # set body text
        name, address = self.message.get_author()
        timestamp = self.message.get_date()
        qf = settings.get_hook('reply_prefix')
        if qf:
            quotestring = qf(name, address, timestamp, ui=ui, dbm=ui.dbman)
        else:
            quotestring = 'Quoting %s (%s)\n' % (name or address, timestamp)
        mailcontent = quotestring
        quotehook = settings.get_hook('text_quote')
        if quotehook:
            mailcontent += quotehook(self.message.accumulate_body())
        else:
            quote_prefix = settings.get('quote_prefix')
            for line in self.message.accumulate_body().splitlines():
                mailcontent += quote_prefix + line + '\n'

        envelope = Envelope(bodytext=mailcontent)

        # copy subject
        subject = decode_header(mail.get('Subject', ''))
        reply_subject_hook = settings.get_hook('reply_subject')
        if reply_subject_hook:
            subject = reply_subject_hook(subject)
        else:
            rsp = settings.get('reply_subject_prefix')
            if not subject.lower().startswith(('re:', rsp.lower())):
                subject = rsp + subject
        envelope.add('Subject', subject)

        # set From-header and sending account
        try:
            from_header, account = determine_sender(mail, 'reply')
        except AssertionError as e:
            ui.notify(e.message, priority='error')
            return
        envelope.add('From', from_header)

        # set To
        sender = mail['Reply-To'] or mail['From']
        my_addresses = settings.get_addresses()
        sender_address = parseaddr(sender)[1]
        cc = ''

        # check if reply is to self sent message
        if sender_address in my_addresses:
            recipients = [mail['To']]
            emsg = 'Replying to own message, set recipients to: %s' \
                % recipients
            logging.debug(emsg)
        else:
            recipients = [sender]

        if self.groupreply:
            # make sure that our own address is not included
            # if the message was self-sent, then our address is not included
            MFT = mail.get_all('Mail-Followup-To', [])
            followupto = self.clear_my_address(my_addresses, MFT)
            if followupto and settings.get('honor_followup_to'):
                logging.debug('honor followup to: %s', followupto)
                recipients = [followupto]
                # since Mail-Followup-To was set, ignore the Cc header
            else:
                if sender != mail['From']:
                    recipients.append(mail['From'])

                # append To addresses if not replying to self sent message
                if sender_address not in my_addresses:
                    cleared = self.clear_my_address(
                        my_addresses, mail.get_all('To', []))
                    recipients.append(cleared)

                # copy cc for group-replies
                if 'Cc' in mail:
                    cc = self.clear_my_address(
                        my_addresses, mail.get_all('Cc', []))
                    envelope.add('Cc', decode_header(cc))

        to = ', '.join(recipients)
        logging.debug('reply to: %s' % to)
        envelope.add('To', decode_header(to))

        # if any of the recipients is a mailinglist that we are subscribed to,
        # set Mail-Followup-To header so that duplicates are avoided
        if settings.get('followup_to'):
            # to and cc are already cleared of our own address
            allrecipients = [to] + [cc]
            lists = settings.get('mailinglists')
            # check if any recipient address matches a known mailing list
            if any([addr in lists for n, addr in getaddresses(allrecipients)]):
                followupto = ', '.join(allrecipients)
                logging.debug('mail followup to: %s' % followupto)
                envelope.add('Mail-Followup-To', decode_header(followupto))

        # set In-Reply-To header
        envelope.add('In-Reply-To', '<%s>' % self.message.get_message_id())

        # set References header
        old_references = mail.get('References', '')
        if old_references:
            old_references = old_references.split()
            references = old_references[-8:]
            if len(old_references) > 8:
                references = old_references[:1] + references
            references.append('<%s>' % self.message.get_message_id())
            envelope.add('References', ' '.join(references))
        else:
            envelope.add('References', '<%s>' % self.message.get_message_id())

        # continue to compose
        ui.apply_command(ComposeCommand(envelope=envelope,
                                        spawn=self.force_spawn))
Example #22
0
 def test_continuation_newlines_can_be_normalized(self):
     text = 'first\nsecond\n third\n\tfourth\n \t  fifth'
     expected = u'first\nsecond third fourth fifth'
     actual = utils.decode_header(text, normalize=True)
     self.assertEqual(actual, expected)
Example #23
0
 def _test(self, teststring, expected):
     actual = utils.decode_header(teststring)
     self.assertEqual(actual, expected)
Example #24
0
    def apply(self, ui):
        # get message to forward if not given in constructor
        if not self.message:
            self.message = ui.current_buffer.get_selected_message()
        mail = self.message.get_email()

        # set body text
        name, address = self.message.get_author()
        timestamp = self.message.get_date()
        qf = settings.get_hook('reply_prefix')
        if qf:
            quotestring = qf(name, address, timestamp, ui=ui, dbm=ui.dbman)
        else:
            quotestring = 'Quoting %s (%s)\n' % (name or address, timestamp)
        mailcontent = quotestring
        quotehook = settings.get_hook('text_quote')
        if quotehook:
            mailcontent += quotehook(self.message.accumulate_body())
        else:
            quote_prefix = settings.get('quote_prefix')
            for line in self.message.accumulate_body().splitlines():
                mailcontent += quote_prefix + line + '\n'

        envelope = Envelope(bodytext=mailcontent)

        # copy subject
        subject = decode_header(mail.get('Subject', ''))
        reply_subject_hook = settings.get_hook('reply_subject')
        if reply_subject_hook:
            subject = reply_subject_hook(subject)
        else:
            rsp = settings.get('reply_subject_prefix')
            if not subject.lower().startswith(('re:', rsp.lower())):
                subject = rsp + subject
        envelope.add('Subject', subject)

        # Auto-detect ML
        auto_replyto_mailinglist = settings.get('auto_replyto_mailinglist')
        if mail['List-Id'] and self.listreply is None:
            # mail['List-Id'] is need to enable reply-to-list
            self.listreply = auto_replyto_mailinglist
        elif mail['List-Id'] and self.listreply is True:
            self.listreply = True
        elif self.listreply is False:
            # In this case we only need the sender
            self.listreply = False

        # set From-header and sending account
        try:
            from_header, account = determine_sender(mail, 'reply')
        except AssertionError as e:
            ui.notify(e.message, priority='error')
            return
        envelope.add('From', from_header)

        # set To
        sender = mail['Reply-To'] or mail['From']
        my_addresses = settings.get_addresses()
        sender_address = parseaddr(sender)[1]
        cc = ''

        # check if reply is to self sent message
        if sender_address in my_addresses:
            recipients = [mail['To']]
            emsg = 'Replying to own message, set recipients to: %s' \
                % recipients
            logging.debug(emsg)
        else:
            recipients = [sender]

        if self.groupreply:
            # make sure that our own address is not included
            # if the message was self-sent, then our address is not included
            MFT = mail.get_all('Mail-Followup-To', [])
            followupto = self.clear_my_address(my_addresses, MFT)
            if followupto and settings.get('honor_followup_to'):
                logging.debug('honor followup to: %s', followupto)
                recipients = [followupto]
                # since Mail-Followup-To was set, ignore the Cc header
            else:
                if sender != mail['From']:
                    recipients.append(mail['From'])

                # append To addresses if not replying to self sent message
                if sender_address not in my_addresses:
                    cleared = self.clear_my_address(
                        my_addresses, mail.get_all('To', []))
                    recipients.append(cleared)

                # copy cc for group-replies
                if 'Cc' in mail:
                    cc = self.clear_my_address(
                        my_addresses, mail.get_all('Cc', []))
                    envelope.add('Cc', decode_header(cc))

        to = ', '.join(recipients)
        logging.debug('reply to: %s' % to)

        if self.listreply:
            # To choose the target of the reply --list
            # Reply-To is standart reply target RFC 2822:, RFC 1036: 2.2.1
            # X-BeenThere is needed by sourceforge ML also winehq
            # X-Mailing-List is also standart and is used by git-send-mail
            to = mail['Reply-To'] or mail['X-BeenThere'] or mail['X-Mailing-List']
            # Some mail server (gmail) will not resend you own mail, so you have
            # to deal with the one in sent
            if to is None:
                to = mail['To']
            logging.debug('mail list reply to: %s' % to)
            # Cleaning the 'To' in this case
            if envelope.get('To') is not None:
                envelope.__delitem__('To')

        # Finally setup the 'To' header
        envelope.add('To', decode_header(to))

        # if any of the recipients is a mailinglist that we are subscribed to,
        # set Mail-Followup-To header so that duplicates are avoided
        if settings.get('followup_to'):
            # to and cc are already cleared of our own address
            allrecipients = [to] + [cc]
            lists = settings.get('mailinglists')
            # check if any recipient address matches a known mailing list
            if any([addr in lists for n, addr in getaddresses(allrecipients)]):
                followupto = ', '.join(allrecipients)
                logging.debug('mail followup to: %s' % followupto)
                envelope.add('Mail-Followup-To', decode_header(followupto))

        # set In-Reply-To header
        envelope.add('In-Reply-To', '<%s>' % self.message.get_message_id())

        # set References header
        old_references = mail.get('References', '')
        if old_references:
            old_references = old_references.split()
            references = old_references[-8:]
            if len(old_references) > 8:
                references = old_references[:1] + references
            references.append('<%s>' % self.message.get_message_id())
            envelope.add('References', ' '.join(references))
        else:
            envelope.add('References', '<%s>' % self.message.get_message_id())

        # continue to compose
        encrypt = mail.get_content_subtype() == 'encrypted'
        ui.apply_command(ComposeCommand(envelope=envelope,
                                        spawn=self.force_spawn,
                                        encrypt=encrypt))
Example #25
0
File: thread.py Project: t-8ch/alot
    def apply(self, ui):
        # look if this makes sense: do we have any accounts set up?
        my_accounts = settings.get_accounts()
        if not my_accounts:
            ui.notify('no accounts set', priority='error')
            return

        # get message to forward if not given in constructor
        if not self.message:
            self.message = ui.current_buffer.get_selected_message()
        mail = self.message.get_email()

        # set body text
        name, address = self.message.get_author()
        timestamp = self.message.get_date()
        qf = settings.get_hook('reply_prefix')
        if qf:
            quotestring = qf(name, address, timestamp, ui=ui, dbm=ui.dbman)
        else:
            quotestring = 'Quoting %s (%s)\n' % (name or address, timestamp)
        mailcontent = quotestring
        quotehook = settings.get_hook('text_quote')
        if quotehook:
            mailcontent += quotehook(self.message.accumulate_body())
        else:
            quote_prefix = settings.get('quote_prefix')
            for line in self.message.accumulate_body().splitlines():
                mailcontent += quote_prefix + line + '\n'

        envelope = Envelope(bodytext=mailcontent)

        # copy subject
        subject = decode_header(mail.get('Subject', ''))
        reply_subject_hook = settings.get_hook('reply_subject')
        if reply_subject_hook:
            subject = reply_subject_hook(subject)
        else:
            rsp = settings.get('reply_subject_prefix')
            if not subject.startswith(('Re:', rsp)):
                subject = rsp + subject
        envelope.add('Subject', subject)

        # set From
        realname, address = recipient_to_from(mail, my_accounts)
        envelope.add('From', '%s <%s>' % (realname, address))

        # set To
        sender = mail['Reply-To'] or mail['From']
        recipients = [sender]
        my_addresses = settings.get_addresses()
        if self.groupreply:
            if sender != mail['From']:
                recipients.append(mail['From'])
            cleared = self.clear_my_address(my_addresses, mail.get('To', ''))
            recipients.append(cleared)

            # copy cc for group-replies
            if 'Cc' in mail:
                cc = self.clear_my_address(my_addresses, mail['Cc'])
                envelope.add('Cc', decode_header(cc))

        to = ', '.join(recipients)
        logging.debug('reply to: %s' % to)
        envelope.add('To', decode_header(to))

        # set In-Reply-To header
        envelope.add('In-Reply-To', '<%s>' % self.message.get_message_id())

        # set References header
        old_references = mail.get('References', '')
        if old_references:
            old_references = old_references.split()
            references = old_references[-8:]
            if len(old_references) > 8:
                references = old_references[:1] + references
            references.append('<%s>' % self.message.get_message_id())
            envelope.add('References', ' '.join(references))
        else:
            envelope.add('References', '<%s>' % self.message.get_message_id())

        # continue to compose
        ui.apply_command(
            ComposeCommand(envelope=envelope, spawn=self.force_spawn))
Example #26
0
    def apply(self, ui):
        # get message to forward if not given in constructor
        if not self.message:
            self.message = ui.current_buffer.get_selected_message()
        mail = self.message.get_email()

        # set body text
        name, address = self.message.get_author()
        timestamp = self.message.get_date()
        qf = settings.get_hook('reply_prefix')
        if qf:
            quotestring = qf(name, address, timestamp, ui=ui, dbm=ui.dbman)
        else:
            quotestring = 'Quoting %s (%s)\n' % (name or address, timestamp)
        mailcontent = quotestring
        quotehook = settings.get_hook('text_quote')
        if quotehook:
            mailcontent += quotehook(self.message.accumulate_body())
        else:
            quote_prefix = settings.get('quote_prefix')
            for line in self.message.accumulate_body().splitlines():
                mailcontent += quote_prefix + line + '\n'

        envelope = Envelope(bodytext=mailcontent)

        # copy subject
        subject = decode_header(mail.get('Subject', ''))
        reply_subject_hook = settings.get_hook('reply_subject')
        if reply_subject_hook:
            subject = reply_subject_hook(subject)
        else:
            rsp = settings.get('reply_subject_prefix')
            if not subject.startswith(('Re:', rsp)):
                subject = rsp + subject
        envelope.add('Subject', subject)

        # set From-header and sending account
        try:
            from_header, account = determine_sender(mail, 'reply')
        except AssertionError as e:
            ui.notify(e.message, priority='error')
            return
        envelope.add('From', from_header)

        # set To
        sender = mail['Reply-To'] or mail['From']
        recipients = [sender]
        my_addresses = settings.get_addresses()
        if self.groupreply:
            if sender != mail['From']:
                recipients.append(mail['From'])
            cleared = self.clear_my_address(my_addresses, mail.get('To', ''))
            recipients.append(cleared)

            # copy cc for group-replies
            if 'Cc' in mail:
                cc = self.clear_my_address(my_addresses, mail['Cc'])
                envelope.add('Cc', decode_header(cc))

        to = ', '.join(recipients)
        logging.debug('reply to: %s' % to)
        envelope.add('To', decode_header(to))

        # set In-Reply-To header
        envelope.add('In-Reply-To', '<%s>' % self.message.get_message_id())

        # set References header
        old_references = mail.get('References', '')
        if old_references:
            old_references = old_references.split()
            references = old_references[-8:]
            if len(old_references) > 8:
                references = old_references[:1] + references
            references.append('<%s>' % self.message.get_message_id())
            envelope.add('References', ' '.join(references))
        else:
            envelope.add('References', '<%s>' % self.message.get_message_id())

        # continue to compose
        ui.apply_command(ComposeCommand(envelope=envelope,
                                        spawn=self.force_spawn))
Example #27
0
    def apply(self, ui):
        # get message to forward if not given in constructor
        if not self.message:
            self.message = ui.current_buffer.get_selected_message()
        mail = self.message.get_email()

        envelope = Envelope()

        if self.inline:  # inline mode
            # set body text
            name, address = self.message.get_author()
            timestamp = self.message.get_date()
            qf = settings.get_hook('forward_prefix')
            if qf:
                quote = qf(name, address, timestamp, ui=ui, dbm=ui.dbman)
            else:
                quote = 'Forwarded message from %s (%s):\n' % (
                    name or address, timestamp)
            mailcontent = quote
            quotehook = settings.get_hook('text_quote')
            if quotehook:
                mailcontent += quotehook(self.message.accumulate_body())
            else:
                quote_prefix = settings.get('quote_prefix')
                for line in self.message.accumulate_body().splitlines():
                    mailcontent += quote_prefix + line + '\n'

            envelope.body = mailcontent

            for a in self.message.get_attachments():
                envelope.attach(a)

        else:  # attach original mode
            # attach original msg
            original_mail = Message()
            original_mail.set_type('message/rfc822')
            original_mail['Content-Disposition'] = 'attachment'
            original_mail.set_payload(email_as_string(mail))
            envelope.attach(Attachment(original_mail))

        # copy subject
        subject = decode_header(mail.get('Subject', ''))
        subject = 'Fwd: ' + subject
        forward_subject_hook = settings.get_hook('forward_subject')
        if forward_subject_hook:
            subject = forward_subject_hook(subject)
        else:
            fsp = settings.get('forward_subject_prefix')
            if not subject.startswith(('Fwd:', fsp)):
                subject = fsp + subject
        envelope.add('Subject', subject)

        # set From-header and sending account
        try:
            from_header, account = determine_sender(mail, 'reply')
        except AssertionError as e:
            ui.notify(e.message, priority='error')
            return
        envelope.add('From', from_header)

        # continue to compose
        ui.apply_command(ComposeCommand(envelope=envelope,
                                        spawn=self.force_spawn))
Example #28
0
    def apply(self, ui):
        # get message to forward if not given in constructor
        if not self.message:
            self.message = ui.current_buffer.get_selected_message()
        mail = self.message.get_email()

        # set body text
        name, address = self.message.get_author()
        timestamp = self.message.get_date()
        qf = settings.get_hook('reply_prefix')
        if qf:
            quotestring = qf(name, address, timestamp, ui=ui, dbm=ui.dbman)
        else:
            quotestring = 'Quoting %s (%s)\n' % (name or address, timestamp)
        mailcontent = quotestring
        quotehook = settings.get_hook('text_quote')
        if quotehook:
            mailcontent += quotehook(self.message.accumulate_body())
        else:
            quote_prefix = settings.get('quote_prefix')
            for line in self.message.accumulate_body().splitlines():
                mailcontent += quote_prefix + line + '\n'

        envelope = Envelope(bodytext=mailcontent)

        # copy subject
        subject = decode_header(mail.get('Subject', ''))
        reply_subject_hook = settings.get_hook('reply_subject')
        if reply_subject_hook:
            subject = reply_subject_hook(subject)
        else:
            rsp = settings.get('reply_subject_prefix')
            if not subject.lower().startswith(('re:', rsp.lower())):
                subject = rsp + subject
        envelope.add('Subject', subject)

        # set From-header and sending account
        try:
            from_header, account = determine_sender(mail, 'reply')
        except AssertionError as e:
            ui.notify(e.message, priority='error')
            return
        envelope.add('From', from_header)

        # set To
        sender = mail['Reply-To'] or mail['From']
        my_addresses = settings.get_addresses()
        sender_address = parseaddr(sender)[1]
        cc = ''

        # check if reply is to self sent message
        if sender_address in my_addresses:
            recipients = [mail['To']]
            emsg = 'Replying to own message, set recipients to: %s' \
                % recipients
            logging.debug(emsg)
        else:
            recipients = [sender]

        if self.groupreply:
            # make sure that our own address is not included
            # if the message was self-sent, then our address is not included
            MFT = mail.get_all('Mail-Followup-To', [])
            followupto = self.clear_my_address(my_addresses, MFT)
            if followupto and settings.get('honor_followup_to'):
                logging.debug('honor followup to: %s', followupto)
                recipients = [followupto]
                # since Mail-Followup-To was set, ignore the Cc header
            else:
                if sender != mail['From']:
                    recipients.append(mail['From'])

                # append To addresses if not replying to self sent message
                if sender_address not in my_addresses:
                    cleared = self.clear_my_address(my_addresses,
                                                    mail.get_all('To', []))
                    recipients.append(cleared)

                # copy cc for group-replies
                if 'Cc' in mail:
                    cc = self.clear_my_address(my_addresses,
                                               mail.get_all('Cc', []))
                    envelope.add('Cc', decode_header(cc))

        to = ', '.join(recipients)
        logging.debug('reply to: %s' % to)
        envelope.add('To', decode_header(to))

        # if any of the recipients is a mailinglist that we are subscribed to,
        # set Mail-Followup-To header so that duplicates are avoided
        if settings.get('followup_to'):
            # to and cc are already cleared of our own address
            allrecipients = [to] + [cc]
            lists = settings.get('mailinglists')
            # check if any recipient address matches a known mailing list
            if any([addr in lists for n, addr in getaddresses(allrecipients)]):
                followupto = ', '.join(allrecipients)
                logging.debug('mail followup to: %s' % followupto)
                envelope.add('Mail-Followup-To', decode_header(followupto))

        # set In-Reply-To header
        envelope.add('In-Reply-To', '<%s>' % self.message.get_message_id())

        # set References header
        old_references = mail.get('References', '')
        if old_references:
            old_references = old_references.split()
            references = old_references[-8:]
            if len(old_references) > 8:
                references = old_references[:1] + references
            references.append('<%s>' % self.message.get_message_id())
            envelope.add('References', ' '.join(references))
        else:
            envelope.add('References', '<%s>' % self.message.get_message_id())

        # continue to compose
        ui.apply_command(
            ComposeCommand(envelope=envelope, spawn=self.force_spawn))