Retrieve mail list for IMAP and POP3 accounts

darcs-hash:20080226194326-86b55-75c821b0474733504a86e66ddf6881af1ec9b431.gz
This commit is contained in:
David Rousselie
2008-02-26 20:43:26 +01:00
parent ebaa5bdc82
commit 9f24171943
5 changed files with 340 additions and 235 deletions

View File

@@ -1,6 +1,6 @@
## ##
## setup.py ## setup.py
## Login : <dax@happycoders.org> ## Login : David Rousselie <dax@happycoders.org>
## Started on Tue Apr 17 21:12:33 2007 David Rousselie ## Started on Tue Apr 17 21:12:33 2007 David Rousselie
## $Id$ ## $Id$
## ##

View File

@@ -221,7 +221,7 @@ class MailFeeder(Feeder):
self.__logger.debug("\t" + _account.login \ self.__logger.debug("\t" + _account.login \
+ "@" + _account.host) + "@" + _account.host)
_account.connect() _account.connect()
mail_list = _account.get_mail_list() mail_list = _account.get_new_mail_list()
default_lang_class = _account.default_lang_class default_lang_class = _account.default_lang_class
if action == MailAccount.RETRIEVE: if action == MailAccount.RETRIEVE:
# TODO : use generator (yield) # TODO : use generator (yield)

View File

@@ -288,7 +288,7 @@ class MailComponent_TestCase(JCLTestCase):
account11.lastcheck = 1 account11.lastcheck = 1
account11.interval = 2 account11.interval = 2
account11.password = "password" account11.password = "password"
account11.get_mail_list = lambda: [] account11.get_new_mail_list = lambda: []
result = self.comp.handler.feeder.feed(account11) result = self.comp.handler.feeder.feed(account11)
self.assertNotEquals(account11.error, None) self.assertNotEquals(account11.error, None)
self.assertEquals(len(result), 0) self.assertEquals(len(result), 0)
@@ -312,7 +312,7 @@ class MailComponent_TestCase(JCLTestCase):
account11.lastcheck = 1 account11.lastcheck = 1
account11.interval = 2 account11.interval = 2
account11.password = "password" account11.password = "password"
account11.get_mail_list = lambda: [] account11.get_new_mail_list = lambda: []
result = self.comp.handler.feeder.feed(account11) result = self.comp.handler.feeder.feed(account11)
self.assertEquals(account11.error, None) self.assertEquals(account11.error, None)
self.assertEquals(result, []) self.assertEquals(result, [])
@@ -336,7 +336,7 @@ class MailComponent_TestCase(JCLTestCase):
account11.lastcheck = 1 account11.lastcheck = 1
account11.interval = 2 account11.interval = 2
account11.password = "password" account11.password = "password"
account11.get_mail_list = lambda: [0, 1] account11.get_new_mail_list = lambda: [0, 1]
account11.get_mail = mock_get_mail account11.get_mail = mock_get_mail
result = self.comp.handler.feeder.feed(account11) result = self.comp.handler.feeder.feed(account11)
self.assertEquals(account11.error, None) self.assertEquals(account11.error, None)
@@ -370,7 +370,7 @@ class MailComponent_TestCase(JCLTestCase):
account11.lastcheck = 1 account11.lastcheck = 1
account11.interval = 2 account11.interval = 2
account11.password = "password" account11.password = "password"
account11.get_mail_list = lambda: [] account11.get_new_mail_list = lambda: []
result = self.comp.handler.feeder.feed(account11) result = self.comp.handler.feeder.feed(account11)
self.assertEquals(account11.error, None) self.assertEquals(account11.error, None)
self.assertEquals(result, []) self.assertEquals(result, [])
@@ -394,7 +394,7 @@ class MailComponent_TestCase(JCLTestCase):
account11.lastcheck = 1 account11.lastcheck = 1
account11.interval = 2 account11.interval = 2
account11.password = "password" account11.password = "password"
account11.get_mail_list = lambda: [0, 1] account11.get_new_mail_list = lambda: [0, 1]
account11.get_mail_summary = mock_get_mail_summary account11.get_mail_summary = mock_get_mail_summary
result = self.comp.handler.feeder.feed(account11) result = self.comp.handler.feeder.feed(account11)
self.assertEquals(account11.error, None) self.assertEquals(account11.error, None)

View File

@@ -29,6 +29,7 @@ from email.Header import Header
from email.MIMEText import MIMEText from email.MIMEText import MIMEText
from email.MIMEMultipart import MIMEMultipart from email.MIMEMultipart import MIMEMultipart
import traceback import traceback
import types
import poplib import poplib
import imaplib import imaplib
@@ -238,6 +239,32 @@ class MailAccount(PresenceAccount):
get_presence_actions_fields = classmethod(_get_presence_actions_fields) get_presence_actions_fields = classmethod(_get_presence_actions_fields)
def get_decoded_header(self, header, charset_hint=None):
decoded_header = email.Header.decode_header(header)
decoded_header_str = u""
for i in range(len(decoded_header)):
try:
if decoded_header[i][1]:
charset_hint = decoded_header[i][1]
decoded_header_str += unicode(decoded_header[i][0].decode(\
decoded_header[i][1]))
else:
decoded_header_str += unicode(decoded_header[i][0].decode(\
MailAccount.default_encoding))
except Exception,e:
try:
decoded_header_str += unicode(decoded_header[i][0])
except Exception, e:
try:
decoded_header_str += unicode(decoded_header[i][0].decode(\
"iso-8859-1"))
except Exception, e:
type, value, stack = sys.exc_info()
print >>sys.stderr, \
"".join(traceback.format_exception
(type, value, stack, 5))
return (decoded_header_str, charset_hint)
def get_decoded_part(self, part, charset_hint): def get_decoded_part(self, part, charset_hint):
content_charset = part.get_content_charset() content_charset = part.get_content_charset()
result = u"" result = u""
@@ -265,64 +292,12 @@ class MailAccount(PresenceAccount):
return result return result
def format_message(self, email_msg, include_body = True): def format_message(self, email_msg, include_body=True):
from_decoded = email.Header.decode_header(email_msg["From"]) (email_from, charset_hint) = self.get_decoded_header(email_msg["From"])
charset_hint = None result = u"From : " + email_from + "\n"
email_from = u"" (email_subject, charset_hint) = self.get_decoded_header(email_msg["Subject"],
result = u"From : " charset_hint)
for i in range(len(from_decoded)): result += u"Subject : " + email_subject + "\n\n"
try:
if from_decoded[i][1]:
charset_hint = from_decoded[i][1]
email_from += unicode(from_decoded[i][0].decode(\
from_decoded[i][1]))
else:
email_from += unicode(from_decoded[i][0].decode(\
MailAccount.default_encoding))
except Exception,e:
try:
email_from += unicode(from_decoded[i][0])
except Exception, e:
try:
email_from += unicode(from_decoded[i][0].decode(\
"iso-8859-1"))
except Exception, e:
type, value, stack = sys.exc_info()
print >>sys.stderr, \
"".join(traceback.format_exception
(type, value, stack, 5))
result += email_from + u"\n"
subject_decoded = email.Header.decode_header(email_msg["Subject"])
result += u"Subject : "
for i in range(len(subject_decoded)):
try:
if subject_decoded[i][1]:
charset_hint = subject_decoded[i][1]
result += unicode(subject_decoded[i][0].decode(\
subject_decoded[i][1]))
else:
result += unicode(subject_decoded[i][0].decode(\
MailAccount.default_encoding))
except Exception,e:
try:
result += unicode(subject_decoded[i][0])
except Exception, e:
try:
result += unicode(subject_decoded[i][0].decode(\
"iso-8859-1"))
except Exception, e:
if charset_hint is not None:
try:
result += unicode(subject_decoded[i][0].decode(\
charset_hint))
except Exception, e:
type, value, stack = sys.exc_info()
print >>sys.stderr, \
"".join(traceback.format_exception
(type, value, stack, 5))
result += u"\n\n"
if include_body: if include_body:
action = { action = {
@@ -349,7 +324,10 @@ class MailAccount(PresenceAccount):
def disconnect(self): def disconnect(self):
raise NotImplementedError raise NotImplementedError
def get_mail_list(self): def get_mail_list_summary(self, start_index=0, end_index=20):
raise NotImplementedError
def get_new_mail_list(self):
raise NotImplementedError raise NotImplementedError
def get_mail(self, index): def get_mail(self, index):
@@ -432,9 +410,26 @@ class IMAPAccount(MailAccount):
self.connection.logout() self.connection.logout()
self.connected = False self.connected = False
def get_mail_list(self): def get_mail_list_summary(self, start_index=1, end_index=20):
self.__logger.debug("Getting mail list summary")
typ, count = self.connection.select(self._get_real_mailbox(), True)
result = []
if typ == "OK":
typ, data = self.connection.fetch(str(start_index) + ":" +
str(end_index),
"RFC822.header")
if typ == 'OK':
index = start_index
for _email in data:
if isinstance(_email, types.TupleType) and len(_email) == 2:
subject_header = self.get_decoded_header(email.message_from_string(_email[1])["Subject"])[0]
result.append((str(index), subject_header))
index += 1
return result
def get_new_mail_list(self):
self.__logger.debug("Getting mail list") self.__logger.debug("Getting mail list")
typ, data = self.connection.select(self._get_real_mailbox()) typ, data = self.connection.select(self._get_real_mailbox(), True)
typ, data = self.connection.search(None, 'RECENT') typ, data = self.connection.search(None, 'RECENT')
if typ == 'OK': if typ == 'OK':
return data[0].split(' ') return data[0].split(' ')
@@ -442,7 +437,7 @@ class IMAPAccount(MailAccount):
def get_mail(self, index): def get_mail(self, index):
self.__logger.debug("Getting mail " + str(index)) self.__logger.debug("Getting mail " + str(index))
typ, data = self.connection.select(self.mailbox, True) typ, data = self.connection.select(self._get_real_mailbox(), True)
typ, data = self.connection.fetch(index, '(RFC822)') typ, data = self.connection.fetch(index, '(RFC822)')
if typ == 'OK': if typ == 'OK':
return self.format_message(\ return self.format_message(\
@@ -451,8 +446,8 @@ class IMAPAccount(MailAccount):
def get_mail_summary(self, index): def get_mail_summary(self, index):
self.__logger.debug("Getting mail summary " + str(index)) self.__logger.debug("Getting mail summary " + str(index))
typ, data = self.connection.select(self.mailbox, True) typ, data = self.connection.select(self._get_real_mailbox(), True)
typ, data = self.connection.fetch(index, '(RFC822)') typ, data = self.connection.fetch(index, '(RFC822.header)')
if typ == 'OK': if typ == 'OK':
return self.format_message_summary(\ return self.format_message_summary(\
email.message_from_string(data[0][1])) email.message_from_string(data[0][1]))
@@ -465,7 +460,7 @@ class IMAPAccount(MailAccount):
return None return None
def mark_all_as_read(self): def mark_all_as_read(self):
self.get_mail_list() self.get_new_mail_list()
type = property(get_type) type = property(get_type)
@@ -525,7 +520,8 @@ class IMAPAccount(MailAccount):
self.delimiter = match.group(2) self.delimiter = match.group(2)
else: else:
self.disconnect() self.disconnect()
raise Exception("Cannot find mailbox " + self.mailbox) raise Exception("Cannot find delimiter for mailbox "
+ self.mailbox)
else: else:
self.disconnect() self.disconnect()
raise Exception("Cannot find mailbox " + self.mailbox) raise Exception("Cannot find mailbox " + self.mailbox)
@@ -578,9 +574,24 @@ class POP3Account(MailAccount):
self.connection.quit() self.connection.quit()
self.connected = False self.connected = False
def get_mail_list(self): def get_mail_list_summary(self, start_index=0, end_index=20):
self.__logger.debug("Getting mail list") self.__logger.debug("Getting mail list")
count, size = self.connection.stat() count, size = self.connection.stat()
result = []
for index in xrange(1, count + 1):
(ret, data, octets) = self.connection.top(index, 0)
if ret[0:3] == '+OK':
subject_header = self.get_decoded_header(email.message_from_string('\n'.join(data))["Subject"])[0]
result.append((str(index), subject_header))
try:
self.connection.rset()
except:
pass
return result
def get_new_mail_list(self):
self.__logger.debug("Getting new mail list")
count, size = self.connection.stat()
self.nb_mail = count self.nb_mail = count
return [str(i) for i in range(1, count + 1)] return [str(i) for i in range(1, count + 1)]
@@ -621,7 +632,7 @@ class POP3Account(MailAccount):
return None return None
def mark_all_as_read(self): def mark_all_as_read(self):
self.get_mail_list() self.get_new_mail_list()
self.lastmail = self.nb_mail self.lastmail = self.nb_mail
@@ -719,16 +730,16 @@ class SMTPAccount(Account):
def create_email(self, from_email, to_email, subject, body, other_headers=None): def create_email(self, from_email, to_email, subject, body, other_headers=None):
"""Create new email""" """Create new email"""
email = MIMEText(body) _email = MIMEText(body)
if subject is None: if subject is None:
subject = "" subject = ""
email['Subject'] = Header(str(subject)) _email['Subject'] = Header(str(subject))
email['From'] = Header(str(from_email)) _email['From'] = Header(str(from_email))
email['To'] = Header(str(to_email)) _email['To'] = Header(str(to_email))
if other_headers is not None: if other_headers is not None:
for header_name in other_headers.keys(): for header_name in other_headers.keys():
email[header_name] = Header(other_headers[header_name]) _email[header_name] = Header(other_headers[header_name])
return email return _email
def __say_hello(self, connection): def __say_hello(self, connection):
if not (200 <= connection.ehlo()[0] <= 299): if not (200 <= connection.ehlo()[0] <= 299):
@@ -736,10 +747,10 @@ class SMTPAccount(Account):
if not (200 <= code <= 299): if not (200 <= code <= 299):
raise SMTPHeloError(code, resp) raise SMTPHeloError(code, resp)
def send_email(self, email): def send_email(self, _email):
"""Send email according to current account parameters""" """Send email according to current account parameters"""
self.__logger.debug("Sending email:\n" self.__logger.debug("Sending email:\n"
+ str(email)) + str(_email))
smtp_connection = smtplib.SMTP() smtp_connection = smtplib.SMTP()
if self.__logger.getEffectiveLevel() == logging.DEBUG: if self.__logger.getEffectiveLevel() == logging.DEBUG:
smtp_connection.set_debuglevel(1) smtp_connection.set_debuglevel(1)
@@ -768,6 +779,6 @@ class SMTPAccount(Account):
current_error = error current_error = error
if current_error is not None: if current_error is not None:
raise current_error raise current_error
smtp_connection.sendmail(str(email['From']), str(email['To']), smtp_connection.sendmail(str(_email['From']), str(_email['To']),
email.as_string()) _email.as_string())
smtp_connection.quit() smtp_connection.quit()

View File

@@ -54,70 +54,78 @@ class MailAccount_TestCase(PresenceAccount_TestCase):
test_get_decoded_part_not_encoded = \ test_get_decoded_part_not_encoded = \
make_test((False, False, False), \ make_test((False, False, False), \
lambda self, email: self.account.get_decoded_part(email, None), \ lambda self, email: \
self.account.get_decoded_part(email, None),
u"Not encoded single part") u"Not encoded single part")
test_get_decoded_part_encoded = \ test_get_decoded_part_encoded = \
make_test((True, False, False), \ make_test((True, False, False),
lambda self, email: self.account.get_decoded_part(email, None), \ lambda self, email: \
self.account.get_decoded_part(email, None),
u"Encoded single part with 'iso-8859-15' charset (éàê)") u"Encoded single part with 'iso-8859-15' charset (éàê)")
test_format_message_summary_not_encoded = \ test_format_message_summary_not_encoded = \
make_test((False, False, True), \ make_test((False, False, True),
lambda self, email: self.account.format_message_summary(email), \ lambda self, email: \
(u"From : not encoded from\nSubject : not encoded subject\n\n", \ self.account.format_message_summary(email),
(u"From : not encoded from\nSubject : not encoded subject\n\n",
u"not encoded from")) u"not encoded from"))
test_format_message_summary_encoded = \ test_format_message_summary_encoded = \
make_test((True, False, True), \ make_test((True, False, True),
lambda self, email: self.account.format_message_summary(email), \ lambda self, email: \
self.account.format_message_summary(email),
(u"From : encoded from (éàê)\nSubject : encoded subject " + \ (u"From : encoded from (éàê)\nSubject : encoded subject " + \
u"(éàê)\n\n", \ u"(éàê)\n\n",
u"encoded from (éàê)")) u"encoded from (éàê)"))
test_format_message_summary_partial_encoded = \ test_format_message_summary_partial_encoded = \
make_test((True, False, True), \ make_test((True, False, True),
lambda self, email: \ lambda self, email: \
email.replace_header("Subject", \ email.replace_header("Subject",
"\" " + str(email["Subject"]) \ "\" " + str(email["Subject"]) \
+ " \" not encoded part") or \ + " \" not encoded part") or \
email.replace_header("From", \ email.replace_header("From",
"\" " + str(email["From"]) \ "\" " + str(email["From"]) \
+ " \" not encoded part") or \ + " \" not encoded part") or \
self.account.format_message_summary(email), \ self.account.format_message_summary(email),
(u"From : \"encoded from (éàê)\" not encoded part\nSubject " + \ (u"From : \"encoded from (éàê)\" not encoded part\nSubject " + \
u": \"encoded subject (éàê)\" not encoded part\n\n", \ u": \"encoded subject (éàê)\" not encoded part\n\n",
u"\"encoded from (éàê)\" not encoded part")) u"\"encoded from (éàê)\" not encoded part"))
test_format_message_single_not_encoded = \ test_format_message_single_not_encoded = \
make_test((False, False, True), \ make_test((False, False, True),
lambda self, email: self.account.format_message(email), \ lambda self, email: \
self.account.format_message(email),
(u"From : not encoded from\nSubject : not encoded subject" + \ (u"From : not encoded from\nSubject : not encoded subject" + \
u"\n\nNot encoded single part\n", \ u"\n\nNot encoded single part\n",
u"not encoded from")) u"not encoded from"))
test_format_message_single_encoded = \ test_format_message_single_encoded = \
make_test((True, False, True), \ make_test((True, False, True),
lambda self, email: self.account.format_message(email), \ lambda self, email: \
self.account.format_message(email),
(u"From : encoded from (éàê)\nSubject : encoded subject " + \ (u"From : encoded from (éàê)\nSubject : encoded subject " + \
u"(éàê)\n\nEncoded single part with 'iso-8859-15' charset" + \ u"(éàê)\n\nEncoded single part with 'iso-8859-15' charset" + \
u" (éàê)\n", \ u" (éàê)\n",
u"encoded from (éàê)")) u"encoded from (éàê)"))
test_format_message_multi_not_encoded = \ test_format_message_multi_not_encoded = \
make_test((False, True, True), \ make_test((False, True, True),
lambda self, email: self.account.format_message(email), \ lambda self, email: \
self.account.format_message(email),
(u"From : not encoded from\nSubject : not encoded subject" + \ (u"From : not encoded from\nSubject : not encoded subject" + \
u"\n\nNot encoded multipart1\nNot encoded multipart2\n", \ u"\n\nNot encoded multipart1\nNot encoded multipart2\n",
u"not encoded from")) u"not encoded from"))
test_format_message_multi_encoded = \ test_format_message_multi_encoded = \
make_test((True, True, True), \ make_test((True, True, True),
lambda self, email: self.account.format_message(email), \ lambda self, email: \
self.account.format_message(email),
(u"From : encoded from (éàê)\nSubject : encoded subject (éà" + \ (u"From : encoded from (éàê)\nSubject : encoded subject (éà" + \
u"ê)\n\nutf-8 multipart1 with no charset (éàê)" + \ u"ê)\n\nutf-8 multipart1 with no charset (éàê)" + \
u"\nEncoded multipart2 with 'iso-8859-15' charset (éàê)\n" + \ u"\nEncoded multipart2 with 'iso-8859-15' charset (éàê)\n" + \
u"Encoded multipart3 with no charset (éàê)\n", \ u"Encoded multipart3 with no charset (éàê)\n",
u"encoded from (éàê)")) u"encoded from (éàê)"))
class POP3Account_TestCase(InheritableAccount_TestCase): class POP3Account_TestCase(InheritableAccount_TestCase):
@@ -161,42 +169,60 @@ class POP3Account_TestCase(InheritableAccount_TestCase):
"Sended queries does not match expected queries.") "Sended queries does not match expected queries.")
return inner return inner
test_connection = make_test() test_connection = make_test
test_get_mail_list = \ test_get_mail_list_summary = \
make_test(["+OK 2 20\r\n",
"+OK 10 octets\r\n" + \
"From: user@test.com\r\n" + \
"Subject: mail subject 1\r\n.\r\n",
"+OK 10 octets\r\n" + \
"From: user@test.com\r\n" + \
"Subject: mail subject 2\r\n.\r\n",
"+OK\r\n"],
["STAT\r\n",
"TOP 1 0\r\n",
"TOP 2 0\r\n",
"RSET\r\n"],
lambda self: \
self.assertEquals(self.pop3_account.get_mail_list_summary(),
[("1", "mail subject 1"),
("2", "mail subject 2")]))
test_get_new_mail_list = \
make_test(["+OK 2 20\r\n"], make_test(["+OK 2 20\r\n"],
["STAT\r\n"], ["STAT\r\n"],
lambda self: \ lambda self: \
self.assertEquals(self.pop3_account.get_mail_list(), self.assertEquals(self.pop3_account.get_new_mail_list(),
["1", "2"])) ["1", "2"]))
test_get_mail_summary = \ test_get_mail_summary = \
make_test(["+OK 10 octets\r\n" + make_test(["+OK 10 octets\r\n" + \
"From: user@test.com\r\n" + "From: user@test.com\r\n" + \
"Subject: subject test\r\n\r\n" + "Subject: subject test\r\n\r\n" + \
"mymessage\r\n.\r\n", "mymessage\r\n.\r\n",
"+OK\r\n"], "+OK\r\n"],
["RETR 1\r\n", ["RETR 1\r\n",
"RSET\r\n"], "RSET\r\n"],
lambda self: \ lambda self: \
self.assertEquals(self.pop3_account.get_mail_summary(1), self.assertEquals(self.pop3_account.get_mail_summary(1),
(u"From : user@test.com\n" + (u"From : user@test.com\n" + \
u"Subject : subject test\n\n", u"Subject : subject test\n\n",
u"user@test.com"))) u"user@test.com")))
test_get_mail = \ test_get_mail = \
make_test(["+OK 10 octets\r\n" + make_test(["+OK 10 octets\r\n" + \
"From: user@test.com\r\n" + "From: user@test.com\r\n" + \
"Subject: subject test\r\n\r\n" + "Subject: subject test\r\n\r\n" + \
"mymessage\r\n.\r\n", "mymessage\r\n.\r\n",
"+OK\r\n"], "+OK\r\n"],
["RETR 1\r\n", ["RETR 1\r\n",
"RSET\r\n"], \ "RSET\r\n"],
lambda self: \ lambda self: \
self.assertEquals(self.pop3_account.get_mail(1), \ self.assertEquals(self.pop3_account.get_mail(1),
(u"From : user@test.com\n" + \ (u"From : user@test.com\n" + \
u"Subject : subject test\n\n" + \ u"Subject : subject test\n\n" + \
u"mymessage\n", \ u"mymessage\n",
u"user@test.com"))) u"user@test.com")))
test_unsupported_reset_command_get_mail_summary = \ test_unsupported_reset_command_get_mail_summary = \
@@ -204,13 +230,13 @@ class POP3Account_TestCase(InheritableAccount_TestCase):
"From: user@test.com\r\n" + \ "From: user@test.com\r\n" + \
"Subject: subject test\r\n\r\n" + \ "Subject: subject test\r\n\r\n" + \
"mymessage\r\n.\r\n", "mymessage\r\n.\r\n",
"-ERR unknown command\r\n"], \ "-ERR unknown command\r\n"],
["RETR 1\r\n", ["RETR 1\r\n",
"RSET\r\n"], \ "RSET\r\n"],
lambda self: \ lambda self: \
self.assertEquals(self.pop3_account.get_mail_summary(1), \ self.assertEquals(self.pop3_account.get_mail_summary(1),
(u"From : user@test.com\n" + \ (u"From : user@test.com\n" + \
u"Subject : subject test\n\n", \ u"Subject : subject test\n\n",
u"user@test.com"))) u"user@test.com")))
test_unsupported_reset_command_get_mail = \ test_unsupported_reset_command_get_mail = \
@@ -218,14 +244,14 @@ class POP3Account_TestCase(InheritableAccount_TestCase):
"From: user@test.com\r\n" + \ "From: user@test.com\r\n" + \
"Subject: subject test\r\n\r\n" + \ "Subject: subject test\r\n\r\n" + \
"mymessage\r\n.\r\n", "mymessage\r\n.\r\n",
"-ERR unknown command\r\n"], \ "-ERR unknown command\r\n"],
["RETR 1\r\n", ["RETR 1\r\n",
"RSET\r\n"], \ "RSET\r\n"],
lambda self: \ lambda self: \
self.assertEquals(self.pop3_account.get_mail(1), \ self.assertEquals(self.pop3_account.get_mail(1),
(u"From : user@test.com\n" + \ (u"From : user@test.com\n" + \
u"Subject : subject test\n\n" + \ u"Subject : subject test\n\n" + \
u"mymessage\n", \ u"mymessage\n",
u"user@test.com"))) u"user@test.com")))
class IMAPAccount_TestCase(InheritableAccount_TestCase): class IMAPAccount_TestCase(InheritableAccount_TestCase):
@@ -278,21 +304,43 @@ class IMAPAccount_TestCase(InheritableAccount_TestCase):
test_func = self.make_test() test_func = self.make_test()
test_func() test_func()
def test_get_mail_list(self): def test_get_mail_list_summary(self):
test_func = self.make_test([lambda data: "* 42 EXISTS\n* 1 RECENT\n* OK" +\ test_func = self.make_test(\
" [UNSEEN 9]\n* FLAGS (\Deleted \Seen\*)\n*" +\ [lambda data: "* 42 EXISTS\r\n* 1 RECENT\r\n* OK" +\
" OK [PERMANENTFLAGS (\Deleted \Seen\*)\n" + \ " [UNSEEN 9]\r\n* FLAGS (\Deleted \Seen\*)\r\n*" +\
" OK [PERMANENTFLAGS (\Deleted \Seen\*)\r\n" + \
data.split()[0] + \ data.split()[0] + \
" OK [READ-WRITE] SELECT completed\n", \ " OK [READ-WRITE] SELECT completed\r\n",
lambda data: "* SEARCH 9 10 \n" + \ lambda data: "* 1 FETCH ((RFC822.header) {38}\r\n" + \
data.split()[0] + " OK SEARCH completed\n"], \ "Subject: mail subject 1\r\n\r\nbody text\r\n)\r\n" + \
["^[^ ]* SELECT INBOX", \ "* 2 FETCH ((RFC822.header) {38}\r\n" + \
"^[^ ]* SEARCH RECENT"], \ "Subject: mail subject 2\r\n\r\nbody text\r\n)\r\n" + \
data.split()[0] + " OK FETCH completed\r\n"],
["^[^ ]* EXAMINE INBOX",
"^[^ ]* FETCH 1:20 RFC822.header"],
lambda self: \ lambda self: \
self.assertEquals(self.imap_account.get_mail_list(), ['9', '10'])) self.assertEquals(self.imap_account.get_mail_list_summary(),
[('1', 'mail subject 1'),
('2', 'mail subject 2')]))
test_func() test_func()
def test_get_mail_list_delimiter1(self): def test_get_new_mail_list(self):
test_func = self.make_test(\
[lambda data: "* 42 EXISTS\n* 1 RECENT\n* OK" + \
" [UNSEEN 9]\n* FLAGS (\Deleted \Seen\*)\n*" + \
" OK [PERMANENTFLAGS (\Deleted \Seen\*)\n" + \
data.split()[0] + \
" OK [READ-WRITE] SELECT completed\n",
lambda data: "* SEARCH 9 10 \n" + \
data.split()[0] + " OK SEARCH completed\n"],
["^[^ ]* EXAMINE INBOX",
"^[^ ]* SEARCH RECENT"],
lambda self: \
self.assertEquals(self.imap_account.get_new_mail_list(),
['9', '10']))
test_func()
def test_get_new_mail_list_delimiter1(self):
self.imap_account.mailbox = "INBOX/dir1/subdir2" self.imap_account.mailbox = "INBOX/dir1/subdir2"
self.imap_account.delimiter = "." self.imap_account.delimiter = "."
test_func = self.make_test( \ test_func = self.make_test( \
@@ -300,16 +348,17 @@ class IMAPAccount_TestCase(InheritableAccount_TestCase):
" [UNSEEN 9]\n* FLAGS (\Deleted \Seen\*)\n*" + \ " [UNSEEN 9]\n* FLAGS (\Deleted \Seen\*)\n*" + \
" OK [PERMANENTFLAGS (\Deleted \Seen\*)\n" + \ " OK [PERMANENTFLAGS (\Deleted \Seen\*)\n" + \
data.split()[0] + \ data.split()[0] + \
" OK [READ-WRITE] SELECT completed\n", \ " OK [READ-WRITE] SELECT completed\n",
lambda data: "* SEARCH 9 10 \n" + \ lambda data: "* SEARCH 9 10 \n" + \
data.split()[0] + " OK SEARCH completed\n"], \ data.split()[0] + " OK SEARCH completed\n"],
["^[^ ]* SELECT \"?INBOX\.dir1\.subdir2\"?", ["^[^ ]* EXAMINE \"?INBOX\.dir1\.subdir2\"?",
"^[^ ]* SEARCH RECENT"], \ "^[^ ]* SEARCH RECENT"],
lambda self: \ lambda self: \
self.assertEquals(self.imap_account.get_mail_list(), ['9', '10'])) self.assertEquals(self.imap_account.get_new_mail_list(),
['9', '10']))
test_func() test_func()
def test_get_mail_list_delimiter2(self): def test_get_new_mail_list_delimiter2(self):
self.imap_account.mailbox = "INBOX/dir1/subdir2" self.imap_account.mailbox = "INBOX/dir1/subdir2"
self.imap_account.delimiter = "/" self.imap_account.delimiter = "/"
test_func = self.make_test( \ test_func = self.make_test( \
@@ -317,44 +366,89 @@ class IMAPAccount_TestCase(InheritableAccount_TestCase):
" [UNSEEN 9]\n* FLAGS (\Deleted \Seen\*)\n*" + \ " [UNSEEN 9]\n* FLAGS (\Deleted \Seen\*)\n*" + \
" OK [PERMANENTFLAGS (\Deleted \Seen\*)\n" + \ " OK [PERMANENTFLAGS (\Deleted \Seen\*)\n" + \
data.split()[0] + \ data.split()[0] + \
" OK [READ-WRITE] SELECT completed\n", \ " OK [READ-WRITE] SELECT completed\n",
lambda data: "* SEARCH 9 10 \n" + \ lambda data: "* SEARCH 9 10 \n" + \
data.split()[0] + " OK SEARCH completed\n"], \ data.split()[0] + " OK SEARCH completed\n"],
["^[^ ]* SELECT \"?INBOX/dir1/subdir2\"?", ["^[^ ]* EXAMINE \"?INBOX/dir1/subdir2\"?",
"^[^ ]* SEARCH RECENT"], \ "^[^ ]* SEARCH RECENT"],
lambda self: \ lambda self: \
self.assertEquals(self.imap_account.get_mail_list(), ['9', '10'])) self.assertEquals(self.imap_account.get_new_mail_list(),
['9', '10']))
test_func() test_func()
def test_get_mail_summary(self): def test_get_mail_summary(self):
test_func = self.make_test([lambda data: "* 42 EXISTS\r\n* 1 RECENT\r\n* OK" +\ test_func = self.make_test(\
[lambda data: "* 42 EXISTS\r\n* 1 RECENT\r\n* OK" +\
" [UNSEEN 9]\r\n* FLAGS (\Deleted \Seen\*)\r\n*" +\ " [UNSEEN 9]\r\n* FLAGS (\Deleted \Seen\*)\r\n*" +\
" OK [PERMANENTFLAGS (\Deleted \Seen\*)\r\n" + \ " OK [PERMANENTFLAGS (\Deleted \Seen\*)\r\n" + \
data.split()[0] + \ data.split()[0] + \
" OK [READ-WRITE] SELECT completed\r\n", \ " OK [READ-WRITE] SELECT completed\r\n",
lambda data: "* 1 FETCH ((RFC822) {12}\r\nbody" + \ lambda data: "* 1 FETCH ((RFC822) {12}\r\nbody" + \
" text\r\n)\r\n" + \ " text\r\n)\r\n" + \
data.split()[0] + " OK FETCH completed\r\n"], data.split()[0] + " OK FETCH completed\r\n"],
["^[^ ]* EXAMINE INBOX", ["^[^ ]* EXAMINE INBOX",
"^[^ ]* FETCH 1 \(RFC822\)"], "^[^ ]* FETCH 1 \(RFC822.header\)"],
lambda self: self.assertEquals(self.imap_account.get_mail_summary(1), lambda self: \
self.assertEquals(self.imap_account.get_mail_summary(1),
(u"From : None\nSubject : None\n\n",
u"None")))
test_func()
def test_get_mail_summary_delimiter(self):
self.imap_account.mailbox = "INBOX/dir1/subdir2"
self.imap_account.delimiter = "."
test_func = self.make_test(\
[lambda data: "* 42 EXISTS\r\n* 1 RECENT\r\n* OK" +\
" [UNSEEN 9]\r\n* FLAGS (\Deleted \Seen\*)\r\n*" +\
" OK [PERMANENTFLAGS (\Deleted \Seen\*)\r\n" + \
data.split()[0] + \
" OK [READ-WRITE] SELECT completed\r\n",
lambda data: "* 1 FETCH ((RFC822) {12}\r\nbody" + \
" text\r\n)\r\n" + \
data.split()[0] + " OK FETCH completed\r\n"],
["^[^ ]* EXAMINE \"?INBOX\.dir1\.subdir2\"?",
"^[^ ]* FETCH 1 \(RFC822.header\)"],
lambda self: \
self.assertEquals(self.imap_account.get_mail_summary(1),
(u"From : None\nSubject : None\n\n", (u"From : None\nSubject : None\n\n",
u"None"))) u"None")))
test_func() test_func()
def test_get_mail(self): def test_get_mail(self):
test_func = self.make_test([lambda data: "* 42 EXISTS\r\n* 1 RECENT\r\n* OK" +\ test_func = self.make_test(\
" [UNSEEN 9]\r\n* FLAGS (\Deleted \Seen\*)\r\n*" +\ [lambda data: "* 42 EXISTS\r\n* 1 RECENT\r\n* OK" + \
" [UNSEEN 9]\r\n* FLAGS (\Deleted \Seen\*)\r\n*" + \
" OK [PERMANENTFLAGS (\Deleted \Seen\*)\r\n" + \ " OK [PERMANENTFLAGS (\Deleted \Seen\*)\r\n" + \
data.split()[0] + \ data.split()[0] + \
" OK [READ-WRITE] SELECT completed\r\n", \ " OK [READ-WRITE] SELECT completed\r\n",
lambda data: "* 1 FETCH ((RFC822) {11}\r\nbody" + \ lambda data: "* 1 FETCH ((RFC822) {11}\r\nbody" + \
" text\r\n)\r\n" + \ " text\r\n)\r\n" + \
data.split()[0] + " OK FETCH completed\r\n"], \ data.split()[0] + " OK FETCH completed\r\n"],
["^[^ ]* EXAMINE INBOX", \ ["^[^ ]* EXAMINE INBOX",
"^[^ ]* FETCH 1 \(RFC822\)",], \ "^[^ ]* FETCH 1 \(RFC822\)"],
lambda self: self.assertEquals(self.imap_account.get_mail(1), \ lambda self: \
(u"From : None\nSubject : None\n\nbody text\r\n\n", \ self.assertEquals(self.imap_account.get_mail(1),
(u"From : None\nSubject : None\n\nbody text\r\n\n",
u"None")))
test_func()
def test_get_mail_delimiter(self):
self.imap_account.mailbox = "INBOX/dir1/subdir2"
self.imap_account.delimiter = "."
test_func = self.make_test(\
[lambda data: "* 42 EXISTS\r\n* 1 RECENT\r\n* OK" + \
" [UNSEEN 9]\r\n* FLAGS (\Deleted \Seen\*)\r\n*" + \
" OK [PERMANENTFLAGS (\Deleted \Seen\*)\r\n" + \
data.split()[0] + \
" OK [READ-WRITE] SELECT completed\r\n",
lambda data: "* 1 FETCH ((RFC822) {11}\r\nbody" + \
" text\r\n)\r\n" + \
data.split()[0] + " OK FETCH completed\r\n"],
["^[^ ]* EXAMINE \"?INBOX\.dir1\.subdir2\"?",
"^[^ ]* FETCH 1 \(RFC822\)"],
lambda self: \
self.assertEquals(self.imap_account.get_mail(1),
(u"From : None\nSubject : None\n\nbody text\r\n\n",
u"None"))) u"None")))
test_func() test_func()
@@ -576,7 +670,7 @@ class SMTPAccount_TestCase(Account_TestCase):
None, None, None, None, None, None, None, None,
None, None, None, None, None, None, None, None,
"250 OK\r\n"], "250 OK\r\n"],
["ehlo \[127.0.0.1\]\r\n", ["ehlo \[127.0...1\]\r\n",
"mail FROM:<" + str(email['From']) + ">.*", "mail FROM:<" + str(email['From']) + ">.*",
"rcpt TO:<" + str(email['To']) + ">\r\n", "rcpt TO:<" + str(email['To']) + ">\r\n",
"data\r\n"] + "data\r\n"] +
@@ -609,8 +703,8 @@ class SMTPAccount_TestCase(Account_TestCase):
None, None, None, None, None, None, None, None,
None, None, None, None, None, None, None, None,
"250 OK\r\n"], "250 OK\r\n"],
["ehlo \[127.0.0.1\]\r\n", ["ehlo \[127.0...1\]\r\n",
"helo \[127.0.0.1\]\r\n", "helo \[127.0...1\]\r\n",
"mail FROM:<" + str(email['From']) + ">.*", "mail FROM:<" + str(email['From']) + ">.*",
"rcpt TO:<" + str(email['To']) + ">\r\n", "rcpt TO:<" + str(email['To']) + ">\r\n",
"data\r\n"] + "data\r\n"] +
@@ -647,7 +741,7 @@ class SMTPAccount_TestCase(Account_TestCase):
None, None, None, None, None, None, None, None,
None, None, None, None, None, None, None, None,
"250 OK\r\n"], "250 OK\r\n"],
["ehlo \[127.0.0.1\]\r\n", ["ehlo \[127.0...1\]\r\n",
"AUTH CRAM-MD5\r\n", "AUTH CRAM-MD5\r\n",
".*\r\n", ".*\r\n",
"mail FROM:<" + str(email['From']) + ">.*", "mail FROM:<" + str(email['From']) + ">.*",
@@ -688,7 +782,7 @@ class SMTPAccount_TestCase(Account_TestCase):
None, None, None, None, None, None, None, None,
None, None, None, None, None, None, None, None,
"250 OK\r\n"], "250 OK\r\n"],
["ehlo \[127.0.0.1\]\r\n", ["ehlo \[127.0...1\]\r\n",
"AUTH CRAM-MD5\r\n", "AUTH CRAM-MD5\r\n",
".*\r\n", ".*\r\n",
"AUTH LOGIN .*\r\n", "AUTH LOGIN .*\r\n",