use special flags (keywords) instead of FLAGGED for mail states

This commit is contained in:
Mathieu Agopian
2013-03-20 13:22:33 +01:00
parent 4031fa6c9b
commit f00da6493b
4 changed files with 46 additions and 11 deletions

View File

@@ -147,6 +147,12 @@ If each provided rule (either as a class parameter or using the register)
matches the mail's subject, from, to, cc and body, the callback will be
triggered.
Mails are flagged according to their state, in the ``process_messages`` method:
* ``UNPROCESSED``: MailBot hasn't started looking at this mail
* ``PROCESSING``: MailBot is checking callbacks, and triggering them if needed
* ``PROCESSED``: MailBot is done with this mail, and won't process it anymore
Specifying rules
----------------

View File

@@ -1,7 +1,6 @@
# -*- coding: utf-8 -*-
from email import message_from_string
from imapclient import FLAGGED
from os.path import dirname, join
from .. import register, MailBot, Callback
@@ -62,19 +61,35 @@ class MailReceivedTest(MailBotTestCase):
{1: {'SEQ': 1, 'RFC822': '\r\n'},
2: {'FLAGS': ('\\Seen',), 'SEQ': 2, 'RFC822': '\r\n'}})
def test_mark_processing(self):
self.mb.client.append(self.home_folder,
message_from_string('').as_string())
ids = self.mb.client.search(['NOT KEYWORD PROCESSING'])
self.assertEqual(ids, [1])
self.mb.mark_processing(1)
self.assertEquals(self.mb.client.get_flags([1]), {1: ('PROCESSING',)})
ids = self.mb.client.search(['KEYWORD PROCESSING'])
self.assertEqual(ids, [1])
ids = self.mb.client.search(['NOT KEYWORD PROCESSING'])
self.assertEqual(ids, [])
def test_mark_processed(self):
self.mb.client.append(self.home_folder,
message_from_string('').as_string())
ids = self.mb.client.search(['UNDELETED'])
ids = self.mb.client.search(['NOT KEYWORD PROCESSED'])
self.assertEqual(ids, [1])
self.mb.mark_processing(1)
self.mb.mark_processed(1)
self.assertEquals(self.mb.client.get_flags([1]), {1: (FLAGGED,)})
ids = self.mb.client.search(['FLAGGED'])
self.assertEquals(self.mb.client.get_flags([1]), {1: ('PROCESSED',)})
ids = self.mb.client.search(['KEYWORD PROCESSED'])
self.assertEqual(ids, [1])
ids = self.mb.client.search(['UNFLAGGED'])
ids = self.mb.client.search(['NOT KEYWORD PROCESSED'])
self.assertEqual(ids, [])
def test_process_messages(self):

View File

@@ -2,7 +2,7 @@
from email import message_from_string
from imapclient import IMAPClient, FLAGGED
from imapclient import IMAPClient
class MailBot(object):
@@ -25,7 +25,8 @@ class MailBot(object):
def get_message_ids(self):
"""Return the list of IDs of messages to process."""
return self.client.search(['UNFLAGGED'])
return self.client.search(['NOT KEYWORD PROCESSED',
'NOT KEYWORD PROCESSING'])
def get_messages(self):
"""Return the list of messages to process."""
@@ -44,11 +45,17 @@ class MailBot(object):
messages = self.get_messages()
for uid, msg in messages.items():
self.mark_processing(uid)
message = message_from_string(msg['RFC822'])
for callback_class, rules in CALLBACKS_MAP.items():
self.process_message(message, callback_class, rules)
self.mark_processed(uid)
def mark_processing(self, uid):
"""Mark the message corresponding to uid as processed."""
self.client.add_flags([uid], ['PROCESSING'])
def mark_processed(self, uid):
"""Mark the message corresponding to uid as processed."""
self.client.add_flags([uid], [FLAGGED])
self.client.remove_flags([uid], ['PROCESSING'])
self.client.add_flags([uid], ['PROCESSED'])

View File

@@ -1,6 +1,5 @@
# -*- coding: utf-8 -*-
from imapclient import FLAGGED
from mock import patch, sentinel, Mock, DEFAULT, call
from . import MailBotTestCase
@@ -42,7 +41,8 @@ class MailBotTest(MailBotClientTest):
res = self.bot.get_message_ids()
self.bot.client.search.assert_called_once_with(['UNFLAGGED'])
self.bot.client.search.assert_called_once_with(
['NOT KEYWORD PROCESSED', 'NOT KEYWORD PROCESSING'])
self.assertEqual(res, sentinel.id_list)
def test_get_messages(self):
@@ -104,7 +104,14 @@ class MailBotTest(MailBotClientTest):
call(sentinel.mail2, sentinel.callback2, sentinel.rules2)],
any_order=True)
def test_mark_processing(self):
self.bot.mark_processing(sentinel.id)
self.bot.client.add_flags.assert_called_once_with([sentinel.id],
['PROCESSING'])
def test_mark_processed(self):
self.bot.mark_processed(sentinel.id)
self.bot.client.remove_flags.assert_called_once_with([sentinel.id],
['PROCESSING'])
self.bot.client.add_flags.assert_called_once_with([sentinel.id],
[FLAGGED])
['PROCESSED'])