Edgewall Software

Ticket #2014: Notify.patch

File Notify.patch, 3.9 KB (added by eblot, 7 years ago)

Other patch with better header encoding

  • trac/Notify.py

     
    2323import md5 
    2424import time 
    2525import smtplib 
     26import re 
    2627 
    2728 
    2829class Notify: 
     
    7879    def __init__(self, env): 
    7980        Notify.__init__(self, env) 
    8081 
     82        from email.Charset import Charset, SHORTEST, QP, BASE64 
     83        self._charset = Charset() 
     84        self._charset.header_encoding = BASE64 
     85        self._charset.body_encoding = BASE64 
     86        self._charset.input_charset = self._charset.output_charset = 'utf-8' 
     87        self._charset.input_codec = self._charset.output_codec = 'utf-8' 
     88        self._addr_re = re.compile("^\s*(.*)\s+<([\w\d_\-\.]+@[\w\d_\-\.]+)>\s*$"); 
     89 
    8190        # Get the email addresses of all known users 
    8291        self.email_map = {} 
    8392        for username, name, email in self.env.get_known_users(self.db): 
     
    113122        emails = [x[1] for x in  email.Utils.getaddresses([str(txt)])] 
    114123        return filter(lambda x: x.find('@') > -1, emails) 
    115124 
     125    def format_header(self, name, email=None): 
     126        from email.Header import Header 
     127        try: 
     128            name = unicode(name, 'ascii') 
     129        except UnicodeDecodeError: 
     130            name = Header(name, self._charset) 
     131        if not email: 
     132            return name 
     133        else: 
     134            return "%s <%s>" % (name, email) 
     135 
     136    def add_headers(self, msg, headers): 
     137        for h in headers: 
     138            value = headers[h] 
     139            if isinstance(value, tuple): 
     140                msg[h] = self.format_header(value[0], value[1]) 
     141                continue 
     142            mo = self._addr_re.match(value) 
     143            if mo: 
     144                msg[h] = self.format_header(mo.group(1), mo.group(2)) 
     145                continue 
     146            msg[h] = self.format_header(value) 
     147 
    116148    def begin_send(self): 
    117149        self.server = smtplib.SMTP(self.smtp_server, self.smtp_port) 
    118150        if self.user_name: 
     
    120152 
    121153    def send(self, rcpt, mime_headers={}): 
    122154        from email.MIMEText import MIMEText 
    123         from email.Header import Header 
    124         from email.Utils import formatdate 
     155        from email.Utils import formatdate, formataddr 
     156 
    125157        body = self.hdf.render(self.template_name) 
     158        projname = self.config.get('project','name') 
     159 
     160        headers = {} 
     161        headers['X-Mailer'] = 'Trac %s, by Edgewall Software' % __version__ 
     162        headers['X-Trac-Version'] =  __version__ 
     163        headers['X-Trac-Project'] =  projname 
     164        headers['X-URL'] = self.config.get('project','url') 
     165        headers['Subject'] = self.subject 
     166        headers['From'] = (projname, self.from_email) 
     167        headers['Sender'] = self.from_email 
     168        headers['Reply-To'] = self.replyto_email 
     169        headers['To'] = rcpt 
     170        headers['Date'] = formatdate() 
     171 
    126172        msg = MIMEText(body, 'plain', 'utf-8') 
    127         msg['X-Mailer'] = 'Trac %s, by Edgewall Software' % __version__ 
    128         msg['X-Trac-Version'] =  __version__ 
    129         projname = self.config.get('project','name') 
    130         msg['X-Trac-Project'] =  projname 
    131         msg['X-URL'] =  self.config.get('project','url') 
    132         msg['Subject'] = Header(self.subject, 'utf-8') 
    133         msg['From'] = '%s <%s>' % (projname, self.from_email) 
    134         msg['Sender'] = self.from_email 
    135         msg['Reply-To'] = self.replyto_email 
    136         msg['To'] = rcpt 
    137         msg['Date'] = formatdate() 
    138         for hdr in mime_headers.keys(): 
    139             msg[hdr] = mime_headers[hdr] 
     173        self.add_headers(msg, headers); 
     174        self.add_headers(msg, mime_headers); 
     175 
    140176        self.env.log.debug("Sending SMTP notification to %s on port %d" 
    141177                           % (self.smtp_server, self.smtp_port)) 
    142178        self.server.sendmail(self.from_email, [rcpt], msg.as_string())