Add mmassive e-mail update for performance by using message set STORE command
authorPlamen Dimitrov <plamen.dimitrov@intra2net.com>
Thu, 12 Jul 2012 15:02:34 +0000 (17:02 +0200)
committerPlamen Dimitrov <plamen.dimitrov@intra2net.com>
Thu, 12 Jul 2012 15:02:34 +0000 (17:02 +0200)
imap_mark_seen.py
mail_iterator.py

index caae2e2..eb79123 100644 (file)
@@ -26,6 +26,7 @@ def main():
 
     # prepare simple mail iterator and iterate throug mailboxes
     session = MailIterator(args.server, args.user, psw)
+    total_messages = 0
     for mailbox in session:
         if args.folder != "all folders" and ("INBOX/" + args.folder) not in mailbox[2]:
             continue
@@ -34,16 +35,16 @@ def main():
         except UserWarning as ex:
             logging.error(ex)
             continue
-        for mid in mail_ids:
-            logging.debug("Setting message %s from mailbox %s as seen",
-                            mid.decode('iso-8859-1'), mailbox[2])
-            try:
-                session.set_message_seen(mid.decode('iso-8859-1'))
-            except UserWarning as ex:
-                logging.error(ex)
-                continue
-
-    logging.info("Finished marking messages as seen. Exiting with code %s.", warnings_handler.detected_problems)
+        try:
+            if len(mail_ids) > 0:
+                mail_id_range = min(mail_ids, key=int).decode('iso-8859-1') + ':' + max(mail_ids, key=int).decode('iso-8859-1')
+                session.set_seen_messages(mail_id_range)
+                total_messages += len(mail_ids)
+        except UserWarning as ex:
+            logging.error(ex)
+
+    logging.info("Finished marking %s messages as seen", total_messages)
+    logging.info("Exiting with code %s", warnings_handler.detected_problems)
     return int(warnings_handler.detected_problems > 0)
 
 def configure_args():
index 4fb7bc2..f7c8013 100644 (file)
@@ -76,7 +76,7 @@ class MailIterator:
                 self.mail_con.select(mailbox[2])
                 logging.info("Processing mailbox %s", mailbox[2])
             except self.mail_con.readonly:
-                logging.warning("Mailbox %s is not writable and therefore skipped.", mailbox[2])
+                logging.warning("Mailbox %s is not writable and therefore skipped", mailbox[2])
                 continue
             yield mailbox
 
@@ -88,18 +88,18 @@ class MailIterator:
             self.mail_con.response('SEARCH')
             _result, data = self.mail_con.uid('search', None, "ALL")
         except (self.mail_con.error):
-            raise UserWarning("Could not fetch messages.")
+            raise UserWarning("Could not fetch messages")
         mailid_list = data[0].split()
         return mailid_list
 
-    def set_message_seen(self, mid):
-        """Sets the \\Seen flag for a message."""
+    def set_seen_messages(self, mid_range):
+        """Sets the \\Seen flag for all messages with the respective mids."""
         
         try:
             # Work around unsolicited server responses in imaplib by clearing them
             self.mail_con.response('STORE')
-            _result, data = self.mail_con.uid('STORE', mid, '+FLAGS', "(\Seen)")
-            logging.debug("New flags for message %s are %s", mid, data)
-        except (self.mail_con.error):
-            raise UserWarning("Could not set the flags for the e-mail " + mid.decode('iso-8859-1') + ".")
+            _result, data = self.mail_con.uid('STORE', mid_range, '+FLAGS', "(\Seen)")
+            logging.info("New flags for messages %s are %s", mid_range, data)
+        except (self.mail_con.error) as ex:
+            raise UserWarning("Could not set the flags for some messages: %s", ex)
         self.mail_con.expunge()