Fallback to DATE header to correct messages without RECEIVED header as new option...
authorPlamen Dimitrov <plamen.dimitrov@intra2net.com>
Mon, 2 Jul 2012 10:12:45 +0000 (12:12 +0200)
committerPlamen Dimitrov <plamen.dimitrov@intra2net.com>
Mon, 2 Jul 2012 10:12:45 +0000 (12:12 +0200)
src/fix_imap_internaldate.py
src/mail_iterator.py

index 0f751b9..56516c9 100644 (file)
@@ -73,6 +73,8 @@ def load_configuration():
         config.set('basic_settings', 'console_log_level', logging.INFO)
         config.set('basic_settings', 'imap_server', 'imap.company.com')
         config.set('basic_settings', 'tolerance_mins', 30)
+        config.set('basic_settings', 'skip_shared_folders', "ON")
+        config.set('basic_settings', 'fallback_to_date_header', "OFF")
         with open(CONFIG_FILENAME, 'w') as configfile:
             config.write(configfile)
             configfile.write("# 0 NOTSET, 10 DEBUG, 20 INFO, 30 WARNING, 40 ERROR, 50 CRITICAL")
@@ -128,25 +130,35 @@ def synchronize_csv(config, test_mode):
                 try:
                     fetched_internal_date = session.fetch_internal_date(mid)
                     internal_date = date_parser.extract_internal_date(fetched_internal_date)
-                    fetched_received_date = session.fetch_received_date(mid)
-                    received_date = date_parser.extract_received_date(fetched_received_date)
-                    if(received_date==""):
+                    fetched_correct_date = session.fetch_received_date(mid)
+                    correct_date = date_parser.extract_received_date(fetched_correct_date)
+                    # check for empty received headers
+                    if(correct_date == ""):
                         logging.debug("No received date could be found in message uid: %s - mailbox: %s - user: %s.",
                                         mid.decode('iso-8859-1'), box.name, box.owner)
                         box.no_received_field += 1
-                        continue
+                        # correct these messages if required and override received_date from basic date
+                        if(config.get('basic_settings', 'fallback_to_date_header') == "ON"):
+                            fetched_correct_date = session.fetch_basic_date(mid)
+                            correct_date = date_parser.extract_received_date(fetched_correct_date)
+                        else:
+                            # skip synchronization for this message
+                            continue
+                    else:
+                        # preserve only the first received line as fetched if everything is ok
+                        fetched_correct_date = fetched_correct_date.split("Received:")[1]
                 except UserWarning as ex:
                     logging.error(ex)
                     continue
-                if(date_parser.compare_dates(received_date, internal_date, tolerance)):
-                    logging.warning("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.",
+                if(date_parser.compare_dates(correct_date, internal_date, tolerance)):
+                    logging.warning("Date conflict found in message uid: %s - mailbox: %s - user: %s.\nInternal date %s is different from extracted date %s from header:\n%s.",
                                     mid.decode('iso-8859-1'), 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.split("Received:")[1])
+                                    correct_date.strftime("%d %b %Y %H:%M:%S"),
+                                    fetched_correct_date)
                     if(not test_mode):
                         try:
-                            session.update_message(mid, box.name, received_date)
+                            session.update_message(mid, box.name, correct_date)
                         except UserWarning as ex:
                             logging.error(ex)
                             continue
index 3ebe01b..133426d 100644 (file)
@@ -99,6 +99,14 @@ class MailIterator:
             raise UserWarning("Could not fetch the received header of message" + mid.decode('iso-8859-1') + ".")
         return data[0][1].decode('iso-8859-1')
 
+    def fetch_basic_date(self, mid):
+        """Fetches the basic date of a message, returns bytes reponse."""
+        try:
+            result, data = self.mail_con.uid('fetch', mid, '(BODY.PEEK[HEADER.FIELDS (DATE)])')
+        except:
+            raise UserWarning("Could not fetch the date header of message" + mid.decode('iso-8859-1') + ".")
+        return data[0][1].decode('iso-8859-1')        
+
     def update_message(self, mid, mailbox, internal_date):
         """Replaces a message with one with correct internal date."""
         internal_date_seconds = time.mktime(internal_date.timetuple())