diff options
Diffstat (limited to 'alot/mail')
-rw-r--r-- | alot/mail/reply.py | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/alot/mail/reply.py b/alot/mail/reply.py new file mode 100644 index 00000000..0e7d897e --- /dev/null +++ b/alot/mail/reply.py @@ -0,0 +1,129 @@ +# This file is released under the GNU GPL, version 3 or a later revision. +# For further details see the COPYING file + +import email.policy +from email.utils import getaddresses +import logging + +from . import headers as HDR + +from ..helper import formataddr +from ..settings.const import settings + +ACT_REPLY = 'reply' +ACT_BOUNCE = 'bounce' +ACT_FWD = 'forward' + +def determine_account(headers, action = ACT_REPLY): + """ + Determine the local account to use for acting on a message with the given + headers. + + :param headers: headers of the email to inspect + :type headers: `db.message._MessageHeaders` + :param action: intended use case: one of the ACT_* constants + :type action: str + :returns: 2-tuple of (from address, account) + """ + # get accounts + my_accounts = settings.get_accounts() + assert my_accounts, 'no accounts set!' + + # extract list of addresses to check for my address + # X-Envelope-To and Envelope-To are used to store the recipient address + # if not included in other fields + # Process the headers in order of importance: if a mail was sent with + # account X, with account Y in e.g. CC or delivered-to, make sure that + # account X is the one selected and not account Y. + for candidate_header in settings.get("reply_account_header_priority"): + candidate_addresses = getaddresses(headers.get_all(candidate_header)) + + logging.debug('candidate addresses: %s', candidate_addresses) + # pick the most important account that has an address in candidates + # and use that account's realname and the address found here + for account in my_accounts: + for seen_name, seen_address in candidate_addresses: + if account.matches_address(seen_address): + if settings.get(action + '_force_realname'): + realname = account.realname + else: + realname = seen_name + if settings.get(action + '_force_address'): + address = str(account.address) + else: + address = seen_address + + logging.debug('using realname: "%s"', realname) + logging.debug('using address: %s', address) + + from_value = formataddr((realname, address)) + return from_value, account + + # revert to default account if nothing found + account = my_accounts[0] + realname = account.realname + address = account.address + logging.debug('using realname: "%s"', realname) + logging.debug('using address: %s', address) + + from_value = formataddr((realname, str(address))) + return from_value, account + + +def subject(message): + subject = message.headers.get(HDR.SUBJECT) or '' + 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 + + return subject + +def body_text(message, ui): + name, address = message.get_author() + timestamp = message.date + qf = settings.get_hook('reply_prefix') + if qf: + mail = email.message_from_bytes(message.as_bytes(), + policy = email.policy.SMTP) + quotestring = qf(name, address, timestamp, + message=mail, 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(message.get_body_text()) + else: + quote_prefix = settings.get('quote_prefix') + for line in message.get_body_text().splitlines(): + mailcontent += quote_prefix + line + '\n' + + return mailcontent + +def references(message): + old_references = message.headers.get(HDR.REFERENCES) + references = [] + + if old_references: + references = old_references.split() + # limit to 16 references, including the one we add + del references[1:-14] + + references.append('<%s>' % message.id) + return ' '.join(references) + +def mail_followup_to(recipients): + if not settings.get('followup_to'): + return None + + lists = settings.get('mailinglists') + + # check if any recipient address matches a known mailing list + if any(addr in lists for n, addr in getaddresses(recipients)): + followupto = ', '.join(recipients) + logging.debug('mail followup to: %s', followupto) + return followupto |