Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
"""
-import sys, os, os.path, re
+import sys, os, os.path, re, email.Utils
from stgit.exception import *
from stgit.utils import *
from stgit.out import *
return patches
def name_email(address):
- p = parse_name_email(address)
- if p:
+ p = email.Utils.parseaddr(address)
+ if p[1]:
return p
else:
raise CmdException('Incorrect "name <email>"/"email (name)" string: %s'
else:
raise CmdException('Incorrect "name <email> date" string: %s' % address)
-def address_or_alias(addr_str):
- """Return the address if it contains an e-mail address or look up
+def address_or_alias(addr_pair):
+ """Return a name-email tuple the e-mail address is valid or look up
the aliases in the config files.
"""
- def __address_or_alias(addr):
- if not addr:
- return None
- if addr.find('@') >= 0:
- # it's an e-mail address
- return addr
- alias = config.get('mail.alias.'+addr)
- if alias:
- # it's an alias
- return alias
- raise CmdException, 'unknown e-mail alias: %s' % addr
-
- addr_list = [__address_or_alias(addr.strip())
- for addr in addr_str.split(',')]
- return ', '.join([addr for addr in addr_list if addr])
+ addr = addr_pair[1]
+ if '@' in addr:
+ # it's an e-mail address
+ return addr_pair
+ alias = config.get('mail.alias.' + addr)
+ if alias:
+ # it's an alias
+ return name_email(alias)
+ raise CmdException, 'unknown e-mail alias: %s' % addr
def prepare_rebase(crt_series):
# pop all patches
sender = str(git.user())
except git.GitException:
sender = str(git.author())
-
if not sender:
raise CmdException, 'unknown sender details'
+ sender = email.Utils.parseaddr(sender)
+
+ return email.Utils.formataddr(address_or_alias(sender))
- return address_or_alias(sender)
+def __addr_list(msg, header):
+ return [addr for name, addr in
+ email.Utils.getaddresses(msg.get_all(header, []))]
def __parse_addresses(msg):
"""Return a two elements tuple: (from, [to])
"""
- def __addr_list(msg, header):
- return [name_addr[1] for name_addr in
- email.Utils.getaddresses(msg.get_all(header, []))]
-
from_addr_list = __addr_list(msg, 'From')
if len(from_addr_list) == 0:
raise CmdException, 'No "From" address'
if len(to_addr_list) == 0:
raise CmdException, 'No "To/Cc/Bcc" addresses'
- return (from_addr_list[0], to_addr_list)
+ return (from_addr_list[0], set(to_addr_list))
def __send_message_sendmail(sendmail, msg):
"""Send the message using the sendmail command.
"""Build the address headers and check existing headers in the
template.
"""
- def __replace_header(header, addr):
- if addr:
- crt_addr = msg[header]
- del msg[header]
-
- if crt_addr:
- msg[header] = address_or_alias(', '.join([crt_addr, addr]))
- else:
- msg[header] = address_or_alias(addr)
+ def __addr_pairs(msg, header, extra):
+ pairs = email.Utils.getaddresses(msg.get_all(header, []) + extra)
+ # remove pairs without an address and resolve the aliases
+ return [address_or_alias(p) for p in pairs if p[1]]
+
+ def __update_header(header, addr = '', ignore = ()):
+ addr_pairs = __addr_pairs(msg, header, [addr])
+ del msg[header]
+ # remove the duplicates and filter the addresses
+ addr_dict = dict((addr, email.Utils.formataddr((name, addr)))
+ for name, addr in addr_pairs if addr not in ignore)
+ if addr_dict:
+ msg[header] = ', '.join(addr_dict.itervalues())
+ return set(addr_dict.iterkeys())
to_addr = ''
cc_addr = ''
+ extra_cc_addr = ''
bcc_addr = ''
autobcc = config.get('stgit.autobcc') or ''
if options.to:
to_addr = ', '.join(options.to)
if options.cc:
- cc_addr = ', '.join(options.cc + extra_cc)
- cc_addr = ', '.join(options.cc + extra_cc)
- elif extra_cc:
- cc_addr = ', '.join(extra_cc)
+ cc_addr = ', '.join(options.cc)
+ if extra_cc:
+ extra_cc_addr = ', '.join(extra_cc)
if options.bcc:
bcc_addr = ', '.join(options.bcc + [autobcc])
elif autobcc:
bcc_addr = autobcc
- __replace_header('To', to_addr)
- __replace_header('Cc', cc_addr)
- __replace_header('Bcc', bcc_addr)
+ # if an address is on a header, ignore it from the rest
+ to_set = __update_header('To', to_addr)
+ cc_set = __update_header('Cc', cc_addr, to_set)
+ bcc_set = __update_header('Bcc', bcc_addr, to_set.union(cc_set))
+
+ # --auto generated addresses, don't include the sender
+ from_set = __update_header('From')
+ __update_header('Cc', extra_cc_addr, to_set.union(bcc_set).union(from_set))
+
+ # update other address headers
+ __update_header('Reply-To')
+ __update_header('Mail-Reply-To')
+ __update_header('Mail-Followup-To')
def __get_signers_list(msg):
"""Return the address list generated from signed-off-by and