Basic refactoring and Tom's recommendations
[imap-fix-internaldate] / fix_imap_internaldate.py
index 7aa0675..bd95732 100644 (file)
@@ -13,40 +13,41 @@ This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
-
-Add '-t' argument when running the module for a test mode.
-For a detailed list of each message with a date conflict change
-the 'log_level' in the configuration file from '30' to '20'.
 '''
 
 import sys
 import csv
-import logging
-import configparser
+import logging, configparser
 from date_interpreter import DateInterpreter
 from mail_iterator import MailIterator
 from caching_data import CachingData
 
 def main():
     """Iterates through csv list of users and their mailboxes"""
-    if (len(sys.argv) > 1 and sys.argv[1]=="-t"):
-        test_mode = 1
+    if(len(sys.argv) > 1):
+        if(sys.argv[1]=="--h"):
+            print("The default mode of the script is test mode."
+                  "Add '--u' argument to exit to modify messages."
+                  "For a detailed list of each message with a date conflict change"
+                  "change the 'log_level' in the configuration file from '30' to '20'.")
+            return
+        if(sys.argv[1]=="--u"):
+            test_mode = False
     else:
-        test_mode = 0
+        test_mode = True
 
     config = load_configuration()
-    logging.basicConfig(filename='mailscript.log',
+    logging.basicConfig(filename='fix_imap_internaldate.log',
                         format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
                         level=config.getint('basic_settings', 'log_level'))
 
     date_interp = DateInterpreter()
-    cashing_data = CachingData()
-    logging.warning(cashing_data)
+    caching_data = CachingData()
+    logging.warning("Cache version %s loaded.\n\n", caching_data.version)
     user_reader = csv.DictReader(open("userdata.csv", "r"), delimiter=',')
 
     server = config.get('basic_settings', 'imap_server')
     tolerance = config.getint('basic_settings', 'tolerance')
-    total_per_box = {}
 
     for user in user_reader:
         try:
@@ -56,11 +57,10 @@ def main():
             continue
         for mailbox in session:
             try:
-                #special key to ensure better mailbox uniqueness
-                mailbox_key = mailbox[0].strip('"') + mailbox[1]
+                box = caching_data.retrieve_cached_mailbox(mailbox[0], mailbox[1], user['username'])
                 mail_ids = session.fetch_messages()
-                new_ids = cashing_data.sync_cached_mailbox(user['username'], mailbox_key, mail_ids)
-                #print(len(new_ids), "new out of", len(mail_ids), "in", mailbox)
+                new_ids = box.synchronize(mail_ids)
+                logging.warning("%s non-cached messages found out of %s in %s.\n", len(new_ids), len(mail_ids), box.name)
             except UserWarning as ex:
                 logging.error(ex)
                 continue
@@ -71,8 +71,9 @@ def main():
                     fetched_received_date = session.fetch_received_date(mid)
                     received_date = date_interp.extract_received_date(fetched_received_date)
                     if(received_date==""):
-                        logging.warning("No received date could be found in message uid: %s - mailbox: %s - user: %s.\n",
-                                        mid.decode("utf-8"), mailbox[0], user['username'])
+                        logging.info("No received date could be found in message uid: %s - mailbox: %s - user: %s.\n",
+                                        mid.decode("utf-8"), box.name, box.owner)
+                        box.no_received_field += 1
                         continue
                 except UserWarning as ex:
                     logging.error(ex)
@@ -81,29 +82,24 @@ def main():
                     #print(received_date, internal_date)
                     if(test_mode==0):
                         try:
-                            session.update_message(mid, mailbox[0], received_date)
+                            session.update_message(mid, box.name, received_date)
                         except UserWarning as ex:
                             logging.error(ex)
                             continue
                     else:
                         logging.info("Date conflict found in message uid: %s - mailbox: %s - user: %s.\nInternal date %s is different from received date %s from RECEIVED header:\n%s.",
-                                        mid.decode("utf-8"), mailbox[0], user['username'],
+                                        mid.decode("utf-8"), box.name, box.owner,
                                         internal_date.strftime("%d %b %Y %H:%M:%S"),
                                         received_date.strftime("%d %b %Y %H:%M:%S"),
                                         fetched_received_date[0][1].decode("utf-8").split("Received:")[1])
                     # count total emails for every user and mailbox
-                    user_key = user['username']+'|'+mailbox[0].strip('"')
-                    total_per_box[user_key] = 1 + total_per_box.get(user_key, 0)
+                    box.date_conflicts += 1
             # if all messages were successfully fixed confirm caching
-            cashing_data.commit_cached_mailbox(user['username'], mailbox_key)
+            if(not test_mode):
+                box.confirm_change()
+        
         # final report on date conflicts
-        total_per_user = 0
-        for warning in total_per_box:
-            total_per_user += total_per_box[warning]
-            logging.warning("Total date conflicts to be corrected in a mailbox %s are %s.",
-                         warning.split('|')[1], total_per_box[warning])
-        logging.warning("Total date conflicts to be corrected for user %s are %s.\n",
-                     user['username'], total_per_user)
+        caching_data.report_date_conflicts()
 
 def load_configuration():
     """Loads the script configuration from a file or creates such."""