Add support for python 3

Re #26
This commit is contained in:
rbas
2014-10-23 23:26:40 +02:00
parent eef6cc99a6
commit 2544ef725d
5 changed files with 67 additions and 53 deletions

View File

@@ -2,4 +2,9 @@ language: python
python: python:
- "2.6" - "2.6"
- "2.7" - "2.7"
- "3.2"
- "3.3"
- "3.4"
install:
- python setup.py -q install
script: nosetests script: nosetests

View File

@@ -1,11 +1,14 @@
from __future__ import unicode_literals
from six import StringIO
import re import re
import StringIO
import email import email
import base64 import base64
import quopri import quopri
import time import time
from datetime import datetime from datetime import datetime
from email.header import decode_header from email.header import decode_header
from imbox.utils import str_encode, str_decode
class Struct(object): class Struct(object):
@@ -26,17 +29,17 @@ def decode_mail_header(value, default_charset='us-ascii'):
try: try:
headers = decode_header(value) headers = decode_header(value)
except email.errors.HeaderParseError: except email.errors.HeaderParseError:
return value.encode(default_charset, 'replace').decode(default_charset) return str_decode(str_encode(value, default_charset, 'replace'), default_charset)
else: else:
for index, (text, charset) in enumerate(headers): for index, (text, charset) in enumerate(headers):
try: try:
headers[index] = text.decode(charset or default_charset, headers[index] = str_decode(text, charset or default_charset,
'replace') 'replace')
except LookupError: except LookupError:
# if the charset is unknown, force default # if the charset is unknown, force default
headers[index] = text.decode(default_charset, 'replace') headers[index] = str_decode(text, default_charset, 'replace')
return u"".join(headers) return ''.join(headers)
def get_mail_addresses(message, header_name): def get_mail_addresses(message, header_name):
@@ -65,7 +68,7 @@ def decode_param(param):
value = quopri.decodestring(code) value = quopri.decodestring(code)
elif type_ == 'B': elif type_ == 'B':
value = base64.decodestring(code) value = base64.decodestring(code)
value = unicode(value, encoding) value = str_encode(value, encoding)
value_results.append(value) value_results.append(value)
if value_results: if value_results:
v = ''.join(value_results) v = ''.join(value_results)
@@ -151,7 +154,7 @@ def parse_email(raw_email):
'content-type'] 'content-type']
parsed_email['headers'] = [] parsed_email['headers'] = []
for key, value in email_dict.iteritems(): for key, value in email_dict.items():
if key.lower() in value_headers_keys: if key.lower() in value_headers_keys:
valid_key_name = key.lower().replace('-', '_') valid_key_name = key.lower().replace('-', '_')

14
imbox/utils.py Normal file
View File

@@ -0,0 +1,14 @@
from six import PY3
if PY3:
def str_encode(value='', encoding=None, errors='strict'):
return str(value, encoding, errors)
def str_decode(value='', encoding=None, errors='strict'):
return bytes(value, encoding, errors).decode('utf-8')
else:
def str_encode(string=u'', encoding=None, errors='strict'):
return unicode(string, encoding, errors)
def str_decode(value='', encoding=None, errors='strict'):
return value.decode(encoding, errors)

View File

@@ -20,6 +20,5 @@ setup(
packages=['imbox'], packages=['imbox'],
package_dir={'imbox':'imbox'}, package_dir={'imbox':'imbox'},
zip_safe=False, zip_safe=False,
install_requires=[], install_requires=['six',],
) )

View File

@@ -1,5 +1,4 @@
import unittest import unittest
import email
from imbox.parser import * from imbox.parser import *
raw_email = """Delivered-To: johndoe@gmail.com raw_email = """Delivered-To: johndoe@gmail.com
@@ -35,10 +34,9 @@ Hi, this is a test email with no <span style="font-weight: bold;">attachments</s
--------------080505090108000500080106-- --------------080505090108000500080106--
""" """
class TestParser(unittest.TestCase): class TestParser(unittest.TestCase):
def test_parse_email(self): def test_parse_email(self):
parsed_email = parse_email(raw_email) parsed_email = parse_email(raw_email)
@@ -47,14 +45,12 @@ class TestParser(unittest.TestCase):
self.assertEqual(u'Tue, 30 Jul 2013 15:56:29 +0300', parsed_email.date) self.assertEqual(u'Tue, 30 Jul 2013 15:56:29 +0300', parsed_email.date)
self.assertEqual(u'<test0@example.com>', parsed_email.message_id) self.assertEqual(u'<test0@example.com>', parsed_email.message_id)
def test_parse_email_ignores_header_casing(self): def test_parse_email_ignores_header_casing(self):
self.assertEqual('one', parse_email('Message-ID: one').message_id) self.assertEqual('one', parse_email('Message-ID: one').message_id)
self.assertEqual('one', parse_email('Message-Id: one').message_id) self.assertEqual('one', parse_email('Message-Id: one').message_id)
self.assertEqual('one', parse_email('Message-id: one').message_id) self.assertEqual('one', parse_email('Message-id: one').message_id)
self.assertEqual('one', parse_email('message-id: one').message_id) self.assertEqual('one', parse_email('message-id: one').message_id)
# TODO - Complete the test suite # TODO - Complete the test suite
def test_parse_attachment(self): def test_parse_attachment(self):
pass pass
@@ -62,8 +58,6 @@ class TestParser(unittest.TestCase):
def test_decode_mail_header(self): def test_decode_mail_header(self):
pass pass
def test_get_mail_addresses(self): def test_get_mail_addresses(self):
to_message_object = email.message_from_string("To: John Doe <johndoe@gmail.com>") to_message_object = email.message_from_string("To: John Doe <johndoe@gmail.com>")
@@ -71,4 +65,3 @@ class TestParser(unittest.TestCase):
from_message_object = email.message_from_string("From: John Smith <johnsmith@gmail.com>") from_message_object = email.message_from_string("From: John Smith <johnsmith@gmail.com>")
self.assertEqual([{'email': 'johnsmith@gmail.com', 'name': u'John Smith'}], get_mail_addresses(from_message_object, 'from')) self.assertEqual([{'email': 'johnsmith@gmail.com', 'name': u'John Smith'}], get_mail_addresses(from_message_object, 'from'))