#!/usr/bin/python import email import gzip import mailbox import md5 import mimetypes import os from datetime import datetime from email.header import decode_header from glob import glob skip = ['multipart/alternative', 'multipart/related', 'multipart/mixed', 'message/delivery-status', 'text/plain', 'text/html'] def decode(header): return decode_header(header)[0][0] def detach(msg): # quick exit if we have seen this entry before id = md5.new(msg['message-id']).hexdigest() if os.path.exists(os.path.join('tally',id)): return # collect eligible attachments attachments = [] for payload in msg.get_payload(): if payload.get_content_type() in skip: continue if payload.get_content_type() == 'image/gif': if len(payload.get_payload(decode=True))<10240: continue attachments.append(payload) if len(attachments) == 0: return # determine output file name prefix prefix = '' if len(attachments) > 1: dirname = datetime(*email.utils.parsedate(msg['date'])[:7]).isoformat() prefix = dirname.replace(':','_').replace('-','_') + os.sep received = os.path.join('received',prefix) if not os.path.exists(received): os.mkdir(received) os.system('svn add ' + received) elif len(attachments) == 1: name=decode(attachments[0].get_filename()) if not name: return if len(name)<16: prefix = decode(msg['from']) if prefix.startswith('"eFax"'): prefix = 'eFax' else: if prefix.find('<')>=0: prefix = prefix.split('<')[1] prefix = prefix.split('@')[0] prefix = prefix + '-' # determine commit message summary = "\n".join([ 'Subject: ' + decode(msg['subject']), 'From: ' + decode(msg['from']), 'Date: ' + msg['date'], 'Message-Id: ' + msg['message-id'], ]) # decode payloads and place add to svn for attachment in attachments: mime = attachment.get_content_type() if mime == 'application/octet-stream': mime = mimetypes.guess_type(decode(attachment.get_filename()))[0] name=decode(attachment.get_filename()).replace(' ','-') content = attachment.get_payload(decode=True) if content: file=os.path.join('received',prefix+name) fh=open(file,'w') fh.write(content) fh.close() os.system('svn add ' + file) os.system('svn propset svn:mime-type ' + mime + ' ' + file) if len(attachments)>1: file = os.path.join('received',prefix) tally = os.path.join('tally',id) fh=open(tally,'w') fh.write(summary + "\n") fh.close() os.system('svn commit --file ' + tally + ' ' + file) if __name__ == "__main__": # determine starting point os.chdir(os.path.join(os.environ['HOME'], 'apmail')) latest = max([os.stat(file).st_mtime for file in glob('secretary/20*')]) # download updates os.system('...elided...') # process updated mbox files for file in glob('secretary/20*'): if latest >= os.stat(file).st_mtime: continue # open gzipped/raw file if file.endswith('.gz'): fh=gzip.open(file) else: fh=open(file) # process each multipart message in the mailbox for msg in iter(mailbox.UnixMailbox(fh, email.message_from_file)): if msg.is_multipart(): detach(msg)