#!/usr/bin/env python import sys, getopt, os, popen2 import pickle from StringIO import StringIO # Python 2.3 is required by PyRSS2Gen py_version = sys.version_info if sys.version_info[0:2] < (2,3): sys.stderr.write("Error: Python 2.3 or higher required") sys.exit(1) import datetime try: import PyRSS2Gen except ImportError: sys.stderr.write("Please install PyRSS2Gen before running this script\n") sys.stderr.write("PyRSS2Gen can be downloaded from: \n") sys.stderr.write("http://www.dalkescientific.com/Python/PyRSS2Gen.html\n") def usage(): print "Usage: svn2rss.py [-h|--help] [--svn-path] --revision " print " --repos-path " print " --url --rss-file " print " svn-path : path where svn binaries are installed" print " url : link in the rss item that points to the" print " viewcvs page for the revision" print "" print "Generates a RSS 2.0 file containing commit information." print "Once the maximum number of items is reached, the oldest element" print "is removed. The item title is the Revision number and the item" print "description contains the author, date, log messages and changed" print "paths." if len(sys.argv) == 1: usage() sys.exit(2) try: opts, args = getopt.gnu_getopt(sys.argv[1:],"h", ["help", "svn-path=", "revision=", "repos-path=", "url=", "rss-file="]) except getopt.GetoptError, msg: print msg sys.stderr.write(usage()) sys.exit(2) for opt, arg in opts: if opt in ("-h", "--help"): usage() sys.exit(0) elif opt == "--svn-path": svn_path = arg elif opt == "--revision": commit_rev = arg elif opt == "--repos-path": repos_path = arg elif opt == "--url": url = arg elif opt == "--rss-file": rss_file = arg class SVN2RSS: def __init__(self, svn_path, revision, repos_path, url, rss_file): self.max_items = 20 self.svn_path = svn_path self.revision = revision self.repos_path = repos_path self.url = url self.rss_file = rss_file self.rss_item_desc = self.make_rss_item_desc() self.svnlook = os.path.join(self.svn_path, "svnlook") (file, ext) = os.path.splitext(self.rss_file) self.pickle_file = file + ".pickle" self.rss_item = self.make_rss_item() self.rss = self.make_rss() def make_rss_item_desc(self): from cgi import escape cmd = "svnlook info -r " + self.revision + " " + self.repos_path out, x, y = popen2.popen3(cmd) cmd_out = out.readlines() author = cmd_out[0] Author = "\nAuthor: " + author Date = "
Date: " + cmd_out[1] New_Revision = "
Revision: " + self.revision log = cmd_out[3:] Log = "
Log:
\n
" + escape(''.join (log))
        out.close()
        x.close()
        y.close()
        
        cmd = "svnlook changed -r " + self.revision + " " + self.repos_path
        out, x, y = popen2.popen3(cmd)
        cmd_out = out.readlines()
        changed_files = "
Modified:
\n
"
        for item in cmd_out:
            changed_files = changed_files + item
        item_desc = Author + Date + New_Revision + "\n" + \
                    Log + changed_files + "
" out.close() x.close() y.close() cmd = "svnlook dirs-changed -r " + self.revision + " " + self.repos_path out, x, y = popen2.popen3(cmd) cmd_out = out.readlines() dirs = [] for line in cmd_out: module = line.split('/', 2)[0] if module == '': continue if module not in dirs: dirs.append (module) modules = ', '.join(dirs) logline = "" for line in log: if line.strip () != "": logline = line break item_title = "Revision %s" % (self.revision) if modules != "": item_title += " (%s)" % modules if logline != "": item_title += " - " + escape (logline) out.close() x.close() y.close() return (item_title, item_desc) def pickle(self): s = StringIO() pickle.dump(self.rss, s) f = open(self.pickle_file,"w") f.write (s.getvalue()) f.close() def make_rss_item(self): """ Generate PyRSS2Gen Item from the commit info """ (item_title, item_desc) = self.make_rss_item_desc() item_link = url + "?rev=" + self.revision rss_item = PyRSS2Gen.RSSItem(title = item_title, link = item_link, description = item_desc, guid = PyRSS2Gen.Guid(item_link), pubDate = datetime.datetime.utcnow()) return rss_item def make_rss(self): """ Generate a PyRSS2Gen RSS2 object """ if os.path.exists(self.pickle_file): f = open(self.pickle_file, "r") rss = pickle.load(f) f.close() if len(rss.items) == self.max_items : rss.items.pop() rss.items.insert(0, self.rss_item) else: rss_item = self.rss_item rss = PyRSS2Gen.RSS2( title = "My SVN Commits", link = "http://www.example.com/viewcvs/", description = "Latest SVN commits", lastBuildDate = datetime.datetime.utcnow(), items = [rss_item]) return rss svn2rss = SVN2RSS(svn_path, commit_rev, repos_path, url, rss_file) rss = svn2rss.rss svn2rss.pickle() rss.write_xml(open(rss_file, "w"))