diff --git a/imapdedup.py b/imapdedup.py index 4d5f5a4..f6c18bd 100755 --- a/imapdedup.py +++ b/imapdedup.py @@ -44,6 +44,8 @@ class ImapDedupException(Exception): pass +current_path = os.path.dirname(os.path.abspath(__file__)) + # IMAP responses should normally begin 'OK' - we strip that off def check_response(resp): status, value = resp @@ -72,8 +74,11 @@ def get_arguments(args): help='Do not "close" mailbox when done. Some servers will purge deleted messages on a close command.') parser.add_option("-l", "--list", dest="just_list", action="store_true", help="Just list mailboxes") + parser.add_option("-d", "--domains", dest="domains_list", help="Check only mails from listed domains, separate by comma.") + parser.add_option("-L", "--write_log", dest="write_log", action="store_true", + help="Write log to current directory for mails that are touched.") - parser.set_defaults(verbose=False, ssl=False, dry_run=False, no_close=False, just_list=False) + parser.set_defaults(verbose=False, ssl=False, dry_run=False, no_close=False, just_list=False, write_log=False) (options, mboxes) = parser.parse_args(args) if ((not options.server) or (not options.user)) and not options.process: sys.stderr.write("\nError: Must specify server, user, and at least one mailbox.\n\n") @@ -107,7 +112,7 @@ def utf8_header(parsed_message, name): text, encoding = decode_header(parsed_message.get(name,''))[0] # Attempt to handle python 2 and 3 here at least if sys.version_info < (3,0,0): - if not isinstance(text, unicode): + if not isinstance(text, unicode): text = text.decode('utf-8', 'ignore') else: if isinstance(text, bytes): @@ -218,9 +223,19 @@ def process(options, mboxes): # OK - let's get started. # Iterate through a set of named mailboxes and delete the later messages discovered. try: + if options.write_log: + logfile_path = os.path.join(current_path, 'imapdedup.log') + if os.path.exists(logfile_path): + os.remove(logfile_path) + log_file = open(logfile_path, 'w') + p = email.parser.Parser() # can be the same for all mailboxes # Create a list of previously seen message IDs, in any mailbox msg_ids = {} + + if options.domains_list: + print("Checking mails only from domains: %s" % options.domains_list) + for mbox in mboxes: msgs_to_delete = [] # should be reset for each mbox msg_map = {} # should be reset for each mbox @@ -256,6 +271,21 @@ def process(options, mboxes): if options.verbose: print("Checking %s message %s" % (mbox, mnum)) + omit_message = 1 + + if options.domains_list: + for domain in options.domains_list.split(','): + if mp['From'] and mp['From'].find(domain) != -1: + omit_message = domain + + if options.domains_list and omit_message == 1: + if mp['From']: + print("Omitting message from: %s" % mp['From']) + continue + + if options.domains_list and omit_message != 1: + print("Message in domain list: %s, found: %s" % (mp['From'], omit_message)) + # Record the message-ID header (or generate one from other headers) msg_id = get_message_id(mp, options.use_checksum, options.use_id_in_checksum) @@ -271,6 +301,10 @@ def process(options, mboxes): mbox, mnum, msg_ids[msg_id], options.dry_run and "would" or "will")) if options.verbose: print ("Subject: %s\nFrom: %s\nDate: %s\n" % (mp['Subject'], mp['From'], mp['Date'])) + + if options.write_log: + log_file.write("Subject: %s\nFrom: %s\nDate: %s\n\n" % (mp['Subject'], mp['From'], mp['Date'])) + msgs_to_delete.append(mnum) # Otherwise record the fact that we've seen it else: @@ -315,6 +349,8 @@ def process(options, mboxes): print >> sys.stderr, "Error:", e finally: server.logout() + if options.write_log: + log_file.close() def main(args): options, mboxes = get_arguments(args)