commit 2153130ac8 Author: John Kristensen Date: Sun May 11 01:05:58 2014 +1000 Remove rfc2822.py A majority of the module is not being used, and the one function that is being used can easily be replicated in mailgw.py, meaning that everything related to the rfc2822 module can be removed. diff --git a/roundup/mailgw.py b/roundup/mailgw.py index c3912e5500..79484bd809 100644 --- a/roundup/mailgw.py +++ b/roundup/mailgw.py @@ -84,7 +84,7 @@ import traceback, rfc822 from anypy.email_ import decode_header -from roundup import configuration, hyperdb, date, password, rfc2822, exceptions +from roundup import configuration, hyperdb, date, password, exceptions from roundup.mailer import Mailer, MessageSendError from roundup.i18n import _ from roundup.hyperdb import iter_roles @@ -319,8 +319,9 @@ class Message(mimetools.Message): data = self.fp.read() # Encode message to unicode - charset = rfc2822.unaliasCharset(self.getparam("charset")) + charset = self.getparam("charset") if charset: + charset = charset.lower().replace("windows-", 'cp') # Do conversion only if charset specified - handle # badly-specified charsets edata = unicode(data, charset, 'replace').encode('utf-8') diff --git a/roundup/rfc2822.py b/roundup/rfc2822.py deleted file mode 100644 index 7e016c280f..0000000000 --- a/roundup/rfc2822.py +++ /dev/null @@ -1,166 +0,0 @@ -"""Some rfc822 functions taken from the new (python2.3) "email" module. -""" -__docformat__ = 'restructuredtext' - -import re -from string import letters, digits -from binascii import b2a_base64, a2b_base64 - -ecre = re.compile(r''' - =\? # literal =? - (?P[^?]*?) # non-greedy up to the next ? is the charset - \? # literal ? - (?P[qb]) # either a "q" or a "b", case insensitive - \? # literal ? - (?P.*?) # non-greedy up to the next ?= is the encoded string - \?= # literal ?= - ''', re.VERBOSE | re.IGNORECASE) - -hqre = re.compile(r'^[A-z0-9!"#$%%&\'()*+,-./:;<=>?@\[\]^_`{|}~ ]+$') - -CRLF = '\r\n' - -def base64_decode(s, convert_eols=None): - """Decode a raw base64 string. - - If convert_eols is set to a string value, all canonical email linefeeds, - e.g. "\\r\\n", in the decoded text will be converted to the value of - convert_eols. os.linesep is a good choice for convert_eols if you are - decoding a text attachment. - - This function does not parse a full MIME header value encoded with - base64 (like =?iso-8895-1?b?bmloISBuaWgh?=) -- please use the high - level email.Header class for that functionality. - - Taken from 'email' module - """ - if not s: - return s - - dec = a2b_base64(s) - if convert_eols: - return dec.replace(CRLF, convert_eols) - return dec - -def unquote_match(match): - """Turn a match in the form ``=AB`` to the ASCII character with value - 0xab. - - Taken from 'email' module - """ - s = match.group(0) - return chr(int(s[1:3], 16)) - -def qp_decode(s): - """Decode a string encoded with RFC 2045 MIME header 'Q' encoding. - - This function does not parse a full MIME header value encoded with - quoted-printable (like =?iso-8895-1?q?Hello_World?=) -- please use - the high level email.Header class for that functionality. - - Taken from 'email' module - """ - s = s.replace('_', ' ') - return re.sub(r'=\w{2}', unquote_match, s) - -def _decode_header(header): - """Decode a message header value without converting charset. - - Returns a list of (decoded_string, charset) pairs containing each of the - decoded parts of the header. Charset is None for non-encoded parts of the - header, otherwise a lower-case string containing the name of the character - set specified in the encoded string. - - Taken from 'email' module - """ - # If no encoding, just return the header - header = str(header) - if not ecre.search(header): - return [(header, None)] - - decoded = [] - dec = '' - for line in header.splitlines(): - # This line might not have an encoding in it - if not ecre.search(line): - decoded.append((line, None)) - continue - - parts = ecre.split(line) - while parts: - unenc = parts.pop(0) - if unenc: - if unenc.strip(): - decoded.append((unenc, None)) - if parts: - charset, encoding = [s.lower() for s in parts[0:2]] - encoded = parts[2] - dec = '' - if encoding == 'q': - dec = qp_decode(encoded) - elif encoding == 'b': - dec = base64_decode(encoded) - else: - dec = encoded - - if decoded and decoded[-1][1] == charset: - decoded[-1] = (decoded[-1][0] + dec, decoded[-1][1]) - else: - decoded.append((dec, charset)) - del parts[0:3] - return decoded - -def decode_header(hdr): - """ Decodes rfc2822 encoded header and return utf-8 encoded string - """ - if not hdr: - return None - outs = u"" - for section in _decode_header(hdr): - charset = unaliasCharset(section[1]) - outs += unicode(section[0], charset or 'iso-8859-1', 'replace') - return outs.encode('utf-8') - -def encode_header(header, charset='utf-8'): - """ Will encode in quoted-printable encoding only if header - contains non latin characters - """ - - # Return empty headers unchanged - if not header: - return header - - # return plain header if it is not contains non-ascii characters - if hqre.match(header): - return header - - quoted = '' - #max_encoded = 76 - len(charset) - 7 - for c in header: - # Space may be represented as _ instead of =20 for readability - if c == ' ': - quoted += '_' - # These characters can be included verbatim - elif hqre.match(c) and c not in '_=?': - quoted += c - # Otherwise, replace with hex value like =E2 - else: - quoted += "=%02X" % ord(c) - plain = 0 - - return '=?%s?q?%s?=' % (charset, quoted) - -def unaliasCharset(charset): - if charset: - return charset.lower().replace("windows-", 'cp') - #return charset_table.get(charset.lower(), charset) - return None - -def test(): - print encode_header("Contrary, Mary") - #print unaliasCharset('Windows-1251') - -if __name__ == '__main__': - test() - -# vim: et diff --git a/test/test_mailgw.py b/test/test_mailgw.py index d7c37f3a88..c3aa99003a 100644 --- a/test/test_mailgw.py +++ b/test/test_mailgw.py @@ -31,7 +31,7 @@ SENDMAILDEBUG = os.environ['SENDMAILDEBUG'] from roundup import mailgw, i18n, roundupdb from roundup.mailgw import MailGW, Unauthorized, uidFromAddress, \ parseContent, IgnoreLoop, IgnoreBulk, MailUsageError, MailUsageHelp -from roundup import init, instance, password, rfc2822, __version__ +from roundup import init, instance, password, __version__ from roundup.anypy.sets_ import set #import db_test_base @@ -2521,13 +2521,6 @@ sig i = uidFromAddress(self.db, ('', 'user@foo.com'), 1) self.assertNotEqual(uidFromAddress(self.db, ('', 'user@bar.com'), 1), i) - def testRFC2822(self): - ascii_header = "[issue243] This is a \"test\" - with 'quotation' marks" - unicode_header = '[issue244] \xd0\xb0\xd0\xbd\xd0\xb4\xd1\x80\xd0\xb5\xd0\xb9' - unicode_encoded = '=?utf-8?q?[issue244]_=D0=B0=D0=BD=D0=B4=D1=80=D0=B5=D0=B9?=' - self.assertEqual(rfc2822.encode_header(ascii_header), ascii_header) - self.assertEqual(rfc2822.encode_header(unicode_header), unicode_encoded) - def testRegistrationConfirmation(self): otk = "Aj4euk4LZSAdwePohj90SME5SpopLETL" self.db.getOTKManager().set(otk, username='johannes') diff --git a/test/test_rfc2822.py b/test/test_rfc2822.py deleted file mode 100644 index 0c5e6609c8..0000000000 --- a/test/test_rfc2822.py +++ /dev/null @@ -1,31 +0,0 @@ -from roundup.rfc2822 import decode_header, encode_header - -import unittest, time - -class RFC2822TestCase(unittest.TestCase): - def testDecode(self): - src = 'Re: [it_issue3] '\ - '=?ISO-8859-1?Q?Ren=E9s_[resp=3Dg=2Cstatus=3D?= '\ - '=?ISO-8859-1?Q?feedback]?=' - result = 'Re: [it_issue3] Ren\xc3\xa9s [resp=g,status=feedback]' - self.assertEqual(decode_header(src), result) - - src = 'Re: [it_issue3]'\ - ' =?ISO-8859-1?Q?Ren=E9s_[resp=3Dg=2Cstatus=3D?=' \ - ' =?ISO-8859-1?Q?feedback]?=' - result = 'Re: [it_issue3] Ren\xc3\xa9s [resp=g,status=feedback]' - self.assertEqual(decode_header(src), result) - - def testEncode(self): - src = 'Re: [it_issue3] Ren\xc3\xa9s [status=feedback]' - result = '=?utf-8?q?Re:_[it=5Fissue3]_Ren=C3=A9s_[status=3Dfeedback]?=' - self.assertEqual(encode_header(src), result) - - src = 'Was machen\xc3\xbc und Fragezeichen?' - result = '=?utf-8?q?Was_machen=C3=BC_und_Fragezeichen=3F?=' - self.assertEqual(encode_header(src), result) - -def test_suite(): - suite = unittest.TestSuite() - suite.addTest(unittest.makeSuite(RFC2822TestCase)) - return suite