#!/usr/bin/python """ p4rss.py - generate RSS 2.0 feed from 10 most recent changes from Perforce. To run it, python p4rss.py > /path/to/rssfile Other options of p4 changes, -i, -u, -s, etc are not supported. see sample.p4rss.xml for sample output. For more information see p4rss.html RSS 2.0 documentation: http://backend.userland.com/rss """ import ConfigParser import marshal import os import re import string import sys import time from email.Utils import formatdate # customization code copied from python cookbook 4.11 p135 # begin-customization # change the values in p4rss.ini _configDefault = { "c.filespec": '//depot/...', "c.title": 'Most recent changes in public Perforce depot', "c.site_url": 'http://public.perforce.com', "c.cgi_url": '/cgi-bin/p4db/changeView.cgi?CH=', "c.maxchanges": "10", "c.maildomain":'' } def loadConfig(file, config = {}): config = config.copy() cp = ConfigParser.ConfigParser() cp.read(file) for sec in cp.sections(): name = string.lower(sec) for opt in cp.options(sec): config[name + "." + string.lower(opt)] = string.strip(cp.get(sec, opt)) return config c = loadConfig("p4rss.ini", _configDefault) # end-of-cusotmization p4changes = 'p4 -G changes -l -m ' + c['c.maxchanges'] + ' ' + c['c.filespec'] #p4changes = 'p4 -G changes -l -m ' + str(maxchanges) + ' ' + path if os.name == 'nt': mode = 'rb' elif os.name == 'posix': mode = 'r' else: raise error, "Only Windows (NT and above) and Unix (POSIX) are supported." stream = os.popen(p4changes, mode) # enttab borrowed from xmllib.py enttab={'<':'<', '>':'>', '&':'&', '"':'"', '\'': '''} def replaceEntity(match): rawEntity=match.group() return enttab[rawEntity] def escapeEntities(s): ent=re.compile('&|>|<|"'"|'"'') return ent.sub(replaceEntity, s) # print RSS 2.0 print "<?xml version='1.0'?>" print "<rss version=\"2.0\">" print "<channel>" print "\t<title>%s</title>" % c['c.title'] print "\t<link>%s</link>" % c['c.site_url'] print "\t<language>en-US</language>" print "\t<description>p4 changes -l -m %s %s in RSS 2.0</description>\n" %(c['c.maxchanges'], c['c.filespec']) print "\t<pubDate>%s</pubDate>" % formatdate(time.time(), True) #time.asctime() try: while 1: dict = marshal.load(stream) print "\t<item>" print "\t\t<title>%s</title>" % dict['change'] print "\t\t<link>%s%s%s</link>" % (c['c.site_url'], c['c.cgi_url'], dict['change']) print "\t\t<pubDate>%s</pubDate>" % formatdate(int(dict['time']), True) print "\t\t<author>%s</author>" % (dict['user']+c['c.maildomain']) print "\t\t<description><![CDATA[%s]]></description>" % (dict['desc']) print "\t</item>" except EOFError: pass print "</channel>" print "</rss>"
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#15 | 3373 | Jay Han |
set popen mode depending on os.name. also changed #! to more usual /usr/bin/python. |
||
#14 | 3361 | Jay Han | stuff description as CDATA and use XSLT substitution to turn \n to <br/> | ||
#13 | 3358 | Jay Han | added email option and updated release.bat | ||
#12 | 3352 | Jay Han | use ConfigParser to read p4rss.ini config file. | ||
#11 | 3340 | Jay Han | pubDate element is now in RFC 822 [2822] format in compliance with RSS 2.0 spec. | ||
#10 | 3339 | Jay Han |
Generate RSS 2.0. Two problems: date should be RFC 882 format and author element should include email. Otherwise p4rss.py generates valid RSS 2.0 output. |
||
#9 | 2834 | Jay Han |
set default file argument to //... (users can supply their own optional arguments) |
||
#8 | 2826 | Jay Han | take an optional file argument to narrow down scope of p4 changes. | ||
#7 | 2815 | Jay Han |
use 'p4 changes -l' rather than do expensive join of p4 changes and describe! Ugh, I cannot believe I missed -l option of p4 changes... |
||
#6 | 2813 | Jay Han | code cleanup | ||
#5 | 2812 | Jay Han | escape &, <, >, ", ' to HTML entities | ||
#4 | 2798 | Jay Han | customization information (or some lame excuses...) | ||
#3 | 2782 | Jay Han | description comes from p4 describe, not the truncated p4 changes output. | ||
#2 | 2781 | Jay Han | pull out doc from p4rss.py, set url to public.perforce.com for now, also add a sample.p4rss.xml. | ||
#1 | 2779 | Jay Han | 1st public cut of p4rss.py |