#!/usr/bin/env python # $Id: feed2blosxom.py,v 1.2 2004/08/08 21:54:03 cmg Exp $ # Author: Chris Green # Purpose: convert an RSS feed into dated entries for a bloxsom weblog # Created: Sun Aug 08 18:58:47 EDT 2004 # # # Here's the problem: I use bloglines to read RSS feeds but I don't # want to maintain my blog in their GUI. I suck the RSS Feed from my # blog there and use it to populate a category in my own pyblosxom # blog. # # Usage: feed2blosxom.py -d data/bloglines -u http://www.bloglines.com/blog/ChrisGreen/rss # # Using from crontab: ( run at 7 minutes past every hour ) # # 7 * * * * ~/wcmg/code/feed2blosxom.py -d data/bloglines -u http://www.bloglines.com/blog/ChrisGreen/rss> import sys, os, time, errno sys.path.append("/home/cmg/src/feedparser/") from optparse import OptionParser import feedparser class Feed2Blosxom(object): def __init__(self, feedurl, outdir, statefile=None, refreshrate=60): """ feedurl - Feed to parse outdir - Where to write the log entries to statefile - Name of of file to use for keeping the last entry saved refreshrate - minimum number of minutes to wait before refetching feed """ self._starttime = time.localtime() self._feedurl = feedurl self._refreshrate = refreshrate self._outdir = outdir if statefile is None: statefile = outdir + os.path.sep + "feed2blosxom.state" self._statefile = statefile self._lasttime = self._readState() def _readState(self): ret = time.localtime(0) try: f = open(self._statefile, "r") timestr = f.readline() timetup = tuple(map(int,timestr.split(","))) f.close() if len(timetup) == len(ret): ret = timetup except IOError, e: if e.errno != errno.ENOENT: print "Error reading state! %s" % str(e) except Exception, e: print "Error reading state! %s" % str(e) return ret def _writeState(self): f = open(self._statefile, "w") timestr = ",".join(map(str,self._starttime)) f.write("%s\n" % timestr) f.close() def _writeEntry(self, entry): fname = time.strftime("%Y-%m-%d-%H:%M:%S.txt", entry['modified_parsed']) pathname = self._outdir + os.sep + fname f = open(pathname, "w") f.write("%s\n\n" % entry['title']) f.write(entry['summary_detail']['value']) f.close() t = time.mktime(entry['modified_parsed']) # change the timestamp on the file to when it was created os.utime(pathname, (t,t)) def run(self): if (time.mktime(self._starttime) < (time.mktime(self._lasttime) + (self._refreshrate * 60))): # we're running too soon! return d = feedparser.parse(self._feedurl) if d['status'] != 200: sys.stderr.write("Error getting feed %s: %d\n" % (self._feedurl,d['status'])) sys.exit(2) for entry in d.entries: modified = entry['modified_parsed'] if modified > self._lasttime: self._writeEntry(entry) self._writeState() def main(): parser = OptionParser(usage="%prog [-h] -d -u ", version="%prog 0.1") parser.add_option("-d", "--directory", dest="directory", help="directory where new files are created", metavar="DIR") parser.add_option("-u", "--url", dest="url", help="url of atom or rss feed", metavar="URL") (options, args) = parser.parse_args() if options.directory == None: sys.stderr.write("ERROR: No directory given\n") sys.exit(1) if options.url == None: sys.stderr.write("ERROR: No directory given\n") sys.exit(1) f2b = Feed2Blosxom(feedurl=options.url,outdir=options.directory) f2b.run() if __name__=='__main__': main()