#!/usr/bin/python #This code is public domain. #http://keithdevens.com/weblog/archive/2004/May/03/mail2blog import email,poplib,time,sys,xmlrpclib,os,re email_user='a dedicated mailbox, such as foo@example.com' email_pass='password' blog_user='username' blog_pass='password' xmlrpc_server = 'the location of his MT XML-RPC server' image_dir = '/path/to/where/images/get/saved/to/' slugsep = ',' #his posts have slugs - the subject of the e-mail is dual-purposed to contain the title of the post as well as the slug for the URL from_address = 'his main e-mail address' #make sure that the e-mail comes from this address. This is at least a *tiny* sanity check, though not real security blogid = 1 #his MT blog id sys.stderr = sys.stdout #send tracebacks to browser (used when I was testing this as a CGI) ### Functions ### def writefile(filename, content): if not os.path.exists(filename): f = file(filename, 'wb') f.write(content) f.close() ### End Functions ### mailbox = poplib.POP3('localhost'); mailbox.user(email_user) mailbox.pass_(email_pass) num = len(mailbox.list()[1]) #get number of messages messages = [] for n in range(num): #get raw message message = email.message_from_string('\n'.join(mailbox.retr(n+1)[1])) if message['from'].find(from_address) != -1: messages.append(message) mailbox.dele(n+1) #delete the message after we're done with it, and hope we don't fail below :) mailbox.quit() posts = [] for message in messages: foo = message['subject'].split(slugsep, 1) if len(foo) == 1: #no separator title = foo[0] slug = re.sub(r'(\W+)','-',re.match(r'^(?:\W+)?(.+?)(?:\W+)?$',title).group(1)) else: slug = foo[0] title = foo[1] if not title: #posts must have some title continue #this parses the date from the e-mail, and makes sure the DST setting is derived # from the current DST setting (assigning -1 to the DST setting, # which is position 8 in the tuple, does that) d = list(email.Utils.parsedate(message['date'])); d[8] = -1; d = tuple(d) post = { 'title' : title.strip(), 'mt_keywords' : slug.strip(), 'dateCreated' : xmlrpclib.DateTime(time.mktime(d)), 'images': [] } if message.is_multipart(): payload = message.get_payload() for p in payload: if not p.is_multipart(): #there should be no nesting beyond one level if p.get_main_type() == 'text': #body of the message post['description'] = p.get_payload(decode=True).strip() elif p.get_main_type() == 'image': post['images'].append({'image':p.get_payload(decode=True),'filename':p.get_filename()}) else: post['description'] = message.get_payload(decode=True).strip() posts.append(post) if posts: #save each image to the image_dir for post in posts: for image in post['images']: writefile(image_dir+image['filename'], image['image']) #now that I have the posts, post them to movable-type using XML-RPC server = xmlrpclib.ServerProxy(xmlrpc_server) for post in posts: del(post['images']) server.metaWeblog.newPost(blogid,blog_user,blog_pass,post,True)