view ImapFeed.py @ 0:2110430f4d7f

Origination. Two critical files for any of this to work, Config.py and LocalAuth.py, aren't included here because they contain sensitive information, so this is effectively broken at the moment. I'll have to do a bit of refactoring and make a second commit.
author Atul Varma <varmaa@toolness.com>
date Fri, 08 Feb 2008 23:53:26 -0600
parents
children df9d4e704257
line wrap: on
line source

import imaplib
import time
from email.feedparser import FeedParser
from email.utils import parsedate
import elementtree.ElementTree as ET

from LocalAuth import IMAP_AUTH
from Config import IMAP_FEEDS

def getImapUnreadMailInfo( server, port, username, password,
                           mailbox = "INBOX", isSsl = True ):
    if isSsl:
        imap = imaplib.IMAP4_SSL( server, port )
    else:
        imap = imaplib.IMAP4( server, port )

    imap.login( username, password )
    imap.select( mailbox )
    typ, msgnums = imap.search( None, "UNSEEN" )
    if typ != "OK":
        raise IOError( "Error searching IMAP folder" )
    msgnums = [ int( num ) for num in msgnums[0].split() ]
    for num in msgnums:
        typ, result = imap.fetch( str(num), "(BODY.PEEK[HEADER])" )
        if typ != "OK":
            raise IOError( "Error fetching IMAP messages" )
        headers = result[0][1]
        parser = FeedParser()
        parser.feed( headers )
        message = parser.close()
        # TODO: Make sure that the timezone info is converted properly.
        timestamp = time.mktime( parsedate(message["Date"]) )
        yield dict( timestamp = timestamp,
                    sender = message["From"],
                    subject = message["Subject"] )
    imap.close()
    imap.logout()

def _addTextNode( element, name, text ):
    subElement = ET.SubElement( element, name )
    subElement.text = text

def makeFeedFromMailInfo( infoIterator, url ):    
    root = ET.Element( "rss" )
    root.set( "version", "2.0" )
    channel = ET.SubElement( root, "channel" )
    for info in infoIterator:
        item = ET.SubElement( channel, "item" )
        _addTextNode( item, "title", info["subject"] )
        _addTextNode( item, "pubDate",
                      time.ctime( info["timestamp"] ) )
        _addTextNode( item, "link", url )
        _addTextNode( item, "description",
                      "From %s" % info["sender"] )
    tree = ET.ElementTree( root )

    import StringIO
    strFile = StringIO.StringIO()
    tree.write( strFile )
    return strFile.getvalue()

def generateFeed( feed, auth ):
    imapParams = dict( server = feed["server"],
                       port = feed["port"],
                       mailbox = feed["mailbox"],
                       isSsl = feed["isSsl"] )
    imapParams.update( auth[imapParams["server"]] )
    open( feed["filename"], "w" ).write(
        makeFeedFromMailInfo( getImapUnreadMailInfo(**imapParams),
                              feed["url"] )
        )

def main():
    for feed in IMAP_FEEDS:
        print "Generating feed for %s (%s)" % ( feed["name"],
                                                feed["filename"] )
        generateFeed( feed, IMAP_AUTH )

if __name__ == "__main__":
    main()