#!/usr/bin/env python import os import sys import stat from os.path import join, getsize import email from email import Parser import re import mhlib import tempfile if sys.hexversion < 0x020300F0: # require version 2.1 or greater raise "python version 2.3 or higher required" if len(sys.argv) < 2 or len(sys.argv) > 3: print "Error expected one argument: Path to MH folder to read in" sys.exit(1) pass mh_folder_name = sys.argv[1] ###################################################################### # init_ ###################################################################### # add_uid_rewrite_msg() # # This function will re-write the given message file adding a line to the # headers that contains the given uid & folder uid. # # We do this re-write by creating a new file and copying the old file to the # new file line by line. When we are done, we rename the new file on top of the # old file thus replacing it. # # We could have just used the python email module to make it easier but then we # would have to have an entire copy of the message in memory and there is a # decent chance that the re-written message would have subtle differences from # the original (that probably would not matter.. but it seems like a lot of # work to just add a single line to a message.) # # I am worried about this taking a long time for those really huge messages # that come down the pike every now and then. I imagine this would not be a # problem if this were in its own thread. Naturally would need some sort of # locking mechanism on this particular message. # def add_uid_rewrite_msg(folder, msg_no, uid, folder_uid): mh_folder_full_name = folder.getfullname() msg_file_name = os.path.join(mh_folder_full_name, '%d' % msg_num) f_orig = file(msg_file_name, 'r') (fd_new, new_msg_file_name) = tempfile.mkstemp( prefix = ".mis-temp-", dir = mh_folder_full_name) f_new = os.fdopen(fd_new,'w') # Read a line from the file one at a time. # We write the line out to the new file. At the first blank line in the # header we insert our uid/folder_uid value. # spit_blank_line = True while True: # Don't strip the line before we test for the end condition, # because whitespace-only header lines are RFC compliant # continuation lines. line = f_orig.readline() if not line: # We hit the end of the file (and we are still in the header.. # break # Chop off the end of the line character. If we then have an empty # string then we have reached the end of the headers line = line.splitlines()[0] if not line: break # If we find an existing x-mh-imap-server-uid header, we chuck it. # We will be replacing it with our new header. Since we did not reach # the end of the headers we need to tell the rest of our copy routine # not to put a blank line after this header (otherwise we will end up # with two blank lines, one quite possibly in a very wrong place) # if line.startswith('X-MHImap-Server-UID'): spit_blank_line = False break # Otherwise we have here header line we do not care about. Write it to # the replacement file. # f_new.write(line + '\n') # We have reached the point where we will be inserting our new uid # header. Create the string and write it out. Then if spit_blank_line is # True add in the blank line we need between the header and the body. # header = 'X-MHImapServer-UID: %d.%d\n' % (folder_uid, uid) f_new.write(header) if spit_blank_line: f_new.write('\n') # And now copy the rest of the lines from the original message to the new # message until we run out of lines to copy. # while True: line = f_orig.readline() if not line: break # Ut, this is the end of the file. f_new.write(line) # And that is it for copying the file. Rename the new file over the old # file and close both handles. # os.rename(new_msg_file_name, msg_file_name) f_orig.close() f_new.close() # Create our top level MH object. # mh = mhlib.MH() folders = mh.listallfolders() msg_ids = {} # See if the folder being asked for exists in our list of folders # if mh_folder_name not in folders: print "Error: folder %s does not exist." % mh_folder_name sys.exit(1) # Okay, get all the messages in this folder and print out the Message-ID of # them. # mh_folder = mh.openfolder(mh_folder_name) mh_folder_full_name = mh_folder.getfullname() msg_uid = 1 mh_folder_uid = 1 for msg_num in mh_folder.listmessages(): msg_file_path = mh_folder.getmessagefilename(msg_num) fp = file(msg_file_path, 'r') msg = Parser.Parser().parse(fp = fp, headersonly = True) fp.close() if 'x-mhimapserver-uid' in msg: uid = msg['x-mhimapserver-uid'] print 'Message %d - UID: %s' % (msg_num, uid) if uid in msg_ids: print '\tDuplicate uid id! Message %d' % \ msg_ids[uid] else: msg_ids[uid] = msg_num else: print 'Message %d had no message-id. Setting to %d' % \ (msg_num, msg_uid) msg_uid += 1 add_uid_rewrite_msg(mh_folder, msg_num, msg_uid, mh_folder_uid) ## file_status = os.stat(file_path) ## # If it is a directory print it out and get its last mod time ## if stat.S_ISDIR(file_status[stat.ST_MODE]): ## print "Folder: ", file_name, " Time of last mod: ", \ ## file_status[stat.ST_MTIME] ## continue ## # Only look at files that are integers, aka: '^[0-9]+$' ## if msg_re.search(file_name) == None: ## continue ## fp = file(file_path, 'r') ## msg = Parser.Parser().parse(fp = fp, headersonly = True) ## fp.close() #### if 'message-id' in msg: #### print 'Message-ID: ', msg['message-id']