From f00da6493be68582a608617d4ae9cbd3275e3756 Mon Sep 17 00:00:00 2001 From: Mathieu Agopian Date: Wed, 20 Mar 2013 13:22:33 +0100 Subject: [PATCH] use special flags (keywords) instead of FLAGGED for mail states --- docs/source/index.rst | 6 ++++++ mailbot/livetests/test_mail_received.py | 25 ++++++++++++++++++++----- mailbot/mailbot.py | 13 ++++++++++--- mailbot/tests/test_mailbot.py | 13 ++++++++++--- 4 files changed, 46 insertions(+), 11 deletions(-) diff --git a/docs/source/index.rst b/docs/source/index.rst index b3aac47..b33ba8f 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -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 ---------------- diff --git a/mailbot/livetests/test_mail_received.py b/mailbot/livetests/test_mail_received.py index 88ed7c9..0398ab5 100644 --- a/mailbot/livetests/test_mail_received.py +++ b/mailbot/livetests/test_mail_received.py @@ -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): diff --git a/mailbot/mailbot.py b/mailbot/mailbot.py index bc797e4..fcd76f5 100644 --- a/mailbot/mailbot.py +++ b/mailbot/mailbot.py @@ -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']) diff --git a/mailbot/tests/test_mailbot.py b/mailbot/tests/test_mailbot.py index 185fee8..1681d48 100644 --- a/mailbot/tests/test_mailbot.py +++ b/mailbot/tests/test_mailbot.py @@ -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'])