Check mail new logic
- use RECENT flag for search on IMAP server with write access so RECENT flag is deleted on new messages and fetch read only so SEEN flag is not set on fetched messages. - It might work on Exchange 2003 that do not support STORE flag UNSEEN - This change the get_mail loop so now each MailConnection type implement get_next_mail_index because logic is different from IMAP to POP3 connection. darcs-hash:20060207213333-86b55-9c2ccf31fb9ae9e6dd454c907f3188bc6080b817.gz
This commit is contained in:
@@ -850,17 +850,10 @@ class MailComponent(Component):
|
|||||||
+ "@" + account.host)
|
+ "@" + account.host)
|
||||||
account.connect()
|
account.connect()
|
||||||
mail_list = account.get_mail_list()
|
mail_list = account.get_mail_list()
|
||||||
if not mail_list or mail_list[0] == '':
|
|
||||||
num = 0
|
|
||||||
else:
|
|
||||||
num = len(mail_list)
|
|
||||||
# unseen mails checked by external client
|
|
||||||
# TODO : better test to find
|
|
||||||
if num < account.lastmail:
|
|
||||||
account.lastmail = 0
|
|
||||||
if action == mailconnection.RETRIEVE:
|
if action == mailconnection.RETRIEVE:
|
||||||
while account.lastmail < num:
|
mail_index = account.get_next_mail_index(mail_list)
|
||||||
(body, email_from) = account.get_mail(int(mail_list[account.lastmail]))
|
while mail_index is not None:
|
||||||
|
(body, email_from) = account.get_mail(mail_index)
|
||||||
mesg = Message(from_jid = name + "@" + \
|
mesg = Message(from_jid = name + "@" + \
|
||||||
unicode(self.jid), \
|
unicode(self.jid), \
|
||||||
to_jid = jid, \
|
to_jid = jid, \
|
||||||
@@ -868,15 +861,16 @@ class MailComponent(Component):
|
|||||||
subject = account.default_lang_class.new_mail_subject % (email_from), \
|
subject = account.default_lang_class.new_mail_subject % (email_from), \
|
||||||
body = body)
|
body = body)
|
||||||
self.stream.send(mesg)
|
self.stream.send(mesg)
|
||||||
account.lastmail += 1
|
account.get_next_mail_index(mail_list)
|
||||||
else:
|
else:
|
||||||
body = ""
|
body = ""
|
||||||
new_mail_count = 0
|
new_mail_count = 0
|
||||||
while account.lastmail < num:
|
mail_index = account.get_next_mail_index(mail_list)
|
||||||
|
while mail_index:
|
||||||
(tmp_body, from_email) = \
|
(tmp_body, from_email) = \
|
||||||
account.get_mail_summary(int(mail_list[account.lastmail]))
|
account.get_mail_summary(mail_index)
|
||||||
body += tmp_body + "\n----------------------------------\n"
|
body += tmp_body + "\n----------------------------------\n"
|
||||||
account.lastmail += 1
|
mail_index = account.get_next_mail_index(mail_list)
|
||||||
new_mail_count += 1
|
new_mail_count += 1
|
||||||
if body != "":
|
if body != "":
|
||||||
mesg = Message(from_jid = name + "@" + \
|
mesg = Message(from_jid = name + "@" + \
|
||||||
@@ -915,11 +909,7 @@ class MailComponent(Component):
|
|||||||
return
|
return
|
||||||
try:
|
try:
|
||||||
account.connect()
|
account.connect()
|
||||||
mail_list = account.get_mail_list()
|
account.mark_all_as_read()
|
||||||
if not mail_list or mail_list[0] == '':
|
|
||||||
account.lastmail = 0
|
|
||||||
else:
|
|
||||||
account.lastmail = len(mail_list)
|
|
||||||
account.disconnect()
|
account.disconnect()
|
||||||
account.in_error = False
|
account.in_error = False
|
||||||
except Exception,e:
|
except Exception,e:
|
||||||
|
|||||||
@@ -157,7 +157,6 @@ class MailConnection(object):
|
|||||||
self.host = host
|
self.host = host
|
||||||
self.port = port
|
self.port = port
|
||||||
self.ssl = ssl
|
self.ssl = ssl
|
||||||
self.lastmail = 0
|
|
||||||
self.status = "offline"
|
self.status = "offline"
|
||||||
self.connection = None
|
self.connection = None
|
||||||
self.chat_action = RETRIEVE
|
self.chat_action = RETRIEVE
|
||||||
@@ -306,6 +305,13 @@ class MailConnection(object):
|
|||||||
def get_mail_summary(self, index):
|
def get_mail_summary(self, index):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def get_next_mail_index(self, mail_list):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Does not modify server state but just internal JMC state
|
||||||
|
def mark_all_as_read(self):
|
||||||
|
pass
|
||||||
|
|
||||||
def get_action(self):
|
def get_action(self):
|
||||||
mapping = {"online": self.online_action,
|
mapping = {"online": self.online_action,
|
||||||
"chat": self.chat_action,
|
"chat": self.chat_action,
|
||||||
@@ -366,29 +372,35 @@ class IMAPConnection(MailConnection):
|
|||||||
def get_mail_list(self):
|
def get_mail_list(self):
|
||||||
IMAPConnection._logger.debug("Getting mail list")
|
IMAPConnection._logger.debug("Getting mail list")
|
||||||
typ, data = self.connection.select(self.mailbox)
|
typ, data = self.connection.select(self.mailbox)
|
||||||
typ, data = self.connection.search(None, 'UNSEEN')
|
typ, data = self.connection.search(None, 'RECENT')
|
||||||
if typ == 'OK':
|
if typ == 'OK':
|
||||||
return data[0].split(' ')
|
return data[0].split(' ')
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def get_mail(self, index):
|
def get_mail(self, index):
|
||||||
IMAPConnection._logger.debug("Getting mail " + str(index))
|
IMAPConnection._logger.debug("Getting mail " + str(index))
|
||||||
typ, data = self.connection.select(self.mailbox)
|
typ, data = self.connection.select(self.mailbox, True)
|
||||||
typ, data = self.connection.fetch(index, '(RFC822)')
|
typ, data = self.connection.fetch(index, '(RFC822)')
|
||||||
self.connection.store(index, "FLAGS", "UNSEEN")
|
|
||||||
if typ == 'OK':
|
if typ == 'OK':
|
||||||
return self.format_message(email.message_from_string(data[0][1]))
|
return self.format_message(email.message_from_string(data[0][1]))
|
||||||
return u"Error while fetching mail " + str(index)
|
return u"Error while fetching mail " + str(index)
|
||||||
|
|
||||||
def get_mail_summary(self, index):
|
def get_mail_summary(self, index):
|
||||||
IMAPConnection._logger.debug("Getting mail summary " + str(index))
|
IMAPConnection._logger.debug("Getting mail summary " + str(index))
|
||||||
typ, data = self.connection.select(self.mailbox)
|
typ, data = self.connection.select(self.mailbox, True)
|
||||||
typ, data = self.connection.fetch(index, '(RFC822)')
|
typ, data = self.connection.fetch(index, '(RFC822)')
|
||||||
self.connection.store(index, "FLAGS", "UNSEEN")
|
|
||||||
if typ == 'OK':
|
if typ == 'OK':
|
||||||
return self.format_message_summary(email.message_from_string(data[0][1]))
|
return self.format_message_summary(email.message_from_string(data[0][1]))
|
||||||
return u"Error while fetching mail " + str(index)
|
return u"Error while fetching mail " + str(index)
|
||||||
|
|
||||||
|
def get_next_mail_index(self, mail_list):
|
||||||
|
if not mail_list or mail_list[0] == '':
|
||||||
|
return None
|
||||||
|
return mail_list.pop(0)
|
||||||
|
|
||||||
|
def mark_all_as_read(self):
|
||||||
|
self.get_mail_list()
|
||||||
|
|
||||||
type = property(get_type)
|
type = property(get_type)
|
||||||
|
|
||||||
class POP3Connection(MailConnection):
|
class POP3Connection(MailConnection):
|
||||||
@@ -402,6 +414,8 @@ class POP3Connection(MailConnection):
|
|||||||
else:
|
else:
|
||||||
port = 110
|
port = 110
|
||||||
MailConnection.__init__(self, login, password, host, port, ssl)
|
MailConnection.__init__(self, login, password, host, port, ssl)
|
||||||
|
self.__nb_mail = 0
|
||||||
|
self.__lastmail = 0
|
||||||
|
|
||||||
def get_type(self):
|
def get_type(self):
|
||||||
if self.ssl:
|
if self.ssl:
|
||||||
@@ -431,7 +445,12 @@ class POP3Connection(MailConnection):
|
|||||||
def get_mail_list(self):
|
def get_mail_list(self):
|
||||||
POP3Connection._logger.debug("Getting mail list")
|
POP3Connection._logger.debug("Getting mail list")
|
||||||
count, size = self.connection.stat()
|
count, size = self.connection.stat()
|
||||||
return [str(i) for i in range(1, count + 1)]
|
result = [str(i) for i in range(1, count + 1)]
|
||||||
|
if not result or result[0] == '':
|
||||||
|
self.__nb_mail = 0
|
||||||
|
else:
|
||||||
|
self.__nb_mail = len(result)
|
||||||
|
return result
|
||||||
|
|
||||||
def get_mail(self, index):
|
def get_mail(self, index):
|
||||||
POP3Connection._logger.debug("Getting mail " + str(index))
|
POP3Connection._logger.debug("Getting mail " + str(index))
|
||||||
@@ -447,4 +466,17 @@ class POP3Connection(MailConnection):
|
|||||||
return self.format_message_summary(email.message_from_string('\n'.join(data)))
|
return self.format_message_summary(email.message_from_string('\n'.join(data)))
|
||||||
return u"Error while fetching mail " + str(index)
|
return u"Error while fetching mail " + str(index)
|
||||||
|
|
||||||
|
def get_next_mail_index(self, mail_list):
|
||||||
|
if self.__nb_mail == self.__lastmail:
|
||||||
|
return None
|
||||||
|
if self.__nb_mail < self.__lastmail:
|
||||||
|
self.__lastmail = 0
|
||||||
|
result = self.__lastmail
|
||||||
|
self.__lastmail += 1
|
||||||
|
return result
|
||||||
|
|
||||||
|
def mark_all_as_read(self):
|
||||||
|
self.get_mail_list()
|
||||||
|
self.__lastmail = self.__nb_mail
|
||||||
|
|
||||||
type = property(get_type)
|
type = property(get_type)
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ class DummyServer:
|
|||||||
self.real_queries = []
|
self.real_queries = []
|
||||||
|
|
||||||
def serve(self):
|
def serve(self):
|
||||||
|
try:
|
||||||
conn, addr = self.socket.accept()
|
conn, addr = self.socket.accept()
|
||||||
rfile = conn.makefile('rb', -1)
|
rfile = conn.makefile('rb', -1)
|
||||||
if self.responses:
|
if self.responses:
|
||||||
@@ -79,6 +80,10 @@ class DummyServer:
|
|||||||
conn.close()
|
conn.close()
|
||||||
self.socket.close()
|
self.socket.close()
|
||||||
self.socket = None
|
self.socket = None
|
||||||
|
except:
|
||||||
|
type, value, stack = sys.exc_info()
|
||||||
|
print >>sys.stderr, "".join(traceback.format_exception
|
||||||
|
(type, value, stack, 5))
|
||||||
|
|
||||||
def verify_queries(self):
|
def verify_queries(self):
|
||||||
result = True
|
result = True
|
||||||
@@ -95,7 +100,8 @@ class DummyServer:
|
|||||||
else:
|
else:
|
||||||
result = False
|
result = False
|
||||||
print >>sys.stderr, "Expected " + str(queries_len) + \
|
print >>sys.stderr, "Expected " + str(queries_len) + \
|
||||||
" queries, got " + str(len(self.real_queries))
|
" queries, got " + str(len(self.real_queries)) + \
|
||||||
|
"\t" + str(self.real_queries)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
class XMLDummyServer(DummyServer):
|
class XMLDummyServer(DummyServer):
|
||||||
|
|||||||
@@ -236,7 +236,7 @@ class IMAPConnection_TestCase(unittest.TestCase):
|
|||||||
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", \
|
["^[^ ]* SELECT INBOX", \
|
||||||
"^[^ ]* SEARCH UNSEEN"], \
|
"^[^ ]* SEARCH RECENT"], \
|
||||||
lambda self: \
|
lambda self: \
|
||||||
self.assertEquals(self.imap_connection.get_mail_list(), ['9', '10']))
|
self.assertEquals(self.imap_connection.get_mail_list(), ['9', '10']))
|
||||||
|
|
||||||
@@ -247,12 +247,9 @@ class IMAPConnection_TestCase(unittest.TestCase):
|
|||||||
" 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"], \
|
||||||
lambda data: "* 1 FETCH (FLAGS (\UNSEEN))\r\n" + \
|
["^[^ ]* EXAMINE INBOX", \
|
||||||
data.split()[0] + " OK STORE completed\r\n"], \
|
"^[^ ]* FETCH 1 \(RFC822\)"], \
|
||||||
["^[^ ]* SELECT INBOX", \
|
|
||||||
"^[^ ]* FETCH 1 \(RFC822\)", \
|
|
||||||
"^[^ ]* STORE 1 FLAGS \(UNSEEN\)"], \
|
|
||||||
lambda self: self.assertEquals(self.imap_connection.get_mail_summary(1), \
|
lambda self: self.assertEquals(self.imap_connection.get_mail_summary(1), \
|
||||||
(u"From : None\nSubject : None\n\n", \
|
(u"From : None\nSubject : None\n\n", \
|
||||||
u"None")))
|
u"None")))
|
||||||
@@ -264,12 +261,9 @@ class IMAPConnection_TestCase(unittest.TestCase):
|
|||||||
" 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"], \
|
||||||
lambda data: "* 1 FETCH (FLAGS (\UNSEEN))\r\n" + \
|
["^[^ ]* EXAMINE INBOX", \
|
||||||
data.split()[0] + " OK STORE completed\r\n"], \
|
"^[^ ]* FETCH 1 \(RFC822\)",], \
|
||||||
["^[^ ]* SELECT INBOX", \
|
|
||||||
"^[^ ]* FETCH 1 \(RFC822\)", \
|
|
||||||
"^[^ ]* STORE 1 FLAGS \(UNSEEN\)"], \
|
|
||||||
lambda self: self.assertEquals(self.imap_connection.get_mail(1), \
|
lambda self: self.assertEquals(self.imap_connection.get_mail(1), \
|
||||||
(u"From : None\nSubject : None\n\nbody text\r\n\n", \
|
(u"From : None\nSubject : None\n\nbody text\r\n\n", \
|
||||||
u"None")))
|
u"None")))
|
||||||
|
|||||||
Reference in New Issue
Block a user