Welcome, guest | Sign In | My Account | Store | Cart

Track commits to CVS repositories as RSS feeds.

Python, 92 lines
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#!/usr/bin/env python
#
# Publish CVS commits to a RSS feed.
#
# This is a Python port of Dave Thomas's commit2rss.rb, because SourceForge
# doesn't support Ruby cvs scripts yet.
#
# To use: checkout your repository's CVSROOT module, edit loginfo, and
# add a line similar to this:
#
#    ALL /path/to/commit2rss.py %{}
# 
# More CVS trigger info at: 
# https://www.cvshome.org/docs/manual/cvs-1.11.17/cvs_18.html#SEC167
# 
# Copyright (c) 2004 Ori Peleg, all rights reserved
#
# Released under the BSD license, available at:
# http://www.opensource.org/licenses/bsd-license.php
#
# Credits:
# - Dave Thomas, for commit2rss.rb: see his post and code at:
#   http://www.pragmaticautomation.com/cgi-bin/pragauto.cgi/Monitor/Loginfo2Rss.rdoc
#
# - Mark Nottingham, for module RSS.py.
#   If RSS.py wasn't included with this file, you can find it at:
#   http://www.mnot.net/python/RSS.py
#   Plus, if you're interested in creating RSS feeds, check out:
#   http://www.mnot.net/rss/tutorial/

DROP_DIR = "/path/to/drop/dir"
ITEMS_TO_KEEP = 10
CHANNEL_LINK = "" # enter link here, if you like

import sys, os, re, time, pwd
from RSS import ns, CollectionChannel

class Publisher:
    def __init__(self, filename, repositoryName):
        self.initChannel(filename, repositoryName)
        self.addItem( self._buildItemDescription() )
        self.removeExcess(ITEMS_TO_KEEP)
        self.write(filename)

    def initChannel(self, filename, repositoryName):
        try: # parse existing channel
            self.channel = CollectionChannel()
            self.channel.parse("file:" + filename)

        except: # create new channel
            title = desc = "Commit summary: %s"%repositoryName
            self.channel = self._createChannel(title, desc, CHANNEL_LINK)

    def addItem(self, description):
        title = time.strftime("%b %d, %H:%M") + " - " + self._getUser()
        self.channel.addItem( self._createItem(title, description) )

    def removeExcess(self, maxItems):
        del self.channel[(ns.rss10, "items")][maxItems:]

    def _createChannel(self, title, description, link):
        fields = { (ns.rss10, "title"):       title,
                   (ns.rss10, "description"): description,
                   (ns.rss10, "link"):        link }

        return CollectionChannel({ (ns.rss10, "channel"): fields })

    def _createItem(self, title, description):
        return { (ns.rss10, "title"):       title,
                 (ns.rss10, "description"): description,
                 (ns.dc,    "date"):        time.ctime() }

    def _buildItemDescription(self):
        def format(line):
            line = re.sub("\n$","", line) # chomp any trailing newline
            if re.match(r"[A-Z].*:\s*$", line):
                return "<p /><b>%s</b><br />" % line
            return "%s<br />" % line

        return "".join([format(line) for line in sys.stdin])

    def _getUser(self):
        try:    return pwd.getpwuid(os.getuid())[0]
        except: return "Unknown uid %s"%os.getuid()

    def write(self, filename):
        open(filename, "w").write( str(self.channel) )

# get the top-level project name
repositoryName = sys.argv[1].split("/")[0]
rssFilename = os.path.join(DROP_DIR, repositoryName+".rss")
Publisher(rssFilename, repositoryName)

Tired of tracking one or more CVS repositories through email messages? Track commits to your repositories as RSS feeds through your favorite aggregator.

Designed to be used through CVS's loginfo hook, but can be modified to run differently (e.g. parse email messages).

Can also work in other sscenarios. _buildItemDescription may have to be modified or removed, it beautifies based on CVS's log message format.

This is a port of Dave Thomas's commit2rss.rb, details at: http://www.pragmaticautomation.com/cgi-bin/pragauto.cgi/Monitor/Loginfo2Rss.rdoc

5 comments

Charles Shapiro 16 years, 7 months ago  # | flag

Ouch, dang it. Maybe I have a version problem. When set up as recommended I get:

Checking in gorey.txt;
/home/cvs/repository/tgncvstests/cshapiro/gorey.txt,v  &lt;--  gorey.txt
initial revision: 1.1
done
Traceback (most recent call last):
  File "/home/cvs/utils/scripts/commit2rss.py", line 93, in ?
    Publisher(rssFilename, repositoryName)
  File "/home/cvs/utils/scripts/commit2rss.py", line 44, in __init__
    self.write(filename)
  File "/home/cvs/utils/scripts/commit2rss.py", line 88, in write
    open(filename, "w").write( str(self.channel) )
  File "/usr/local/lib/python2.3/site-packages/RSS.py", line 248, in __str__
    return self.output(self.listItems())
  File "/usr/local/lib/python2.3/site-packages/RSS.py", line 275, in output
    {(ns.rdf, 'about'): channelMD[(ns.rss10, 'link')]})
  File "/usr/local/lib/python2.3/xml/sax/saxutils.py", line 116, in startElementNS
    name = self._current_context[name[0]] + ":" + name[1]
TypeError: unsupported operand type(s) for +: 'NoneType' and 'str'

I'm pretty green at python, but I did check the xml "__init__.py" file and it seems to show that I'm on version 0.8.2 of the xml stuff.

kindoblue 16 years, 7 months ago  # | flag

with pyXML version >= 0.8.3 the script is working

Charles Shapiro 16 years, 6 months ago  # | flag

Requires XML 0.8.3 or better. Yep, that was it. After a great deal of bureaucratic wrangling, I got 0.8.4 installed on the server in question. Now it runs just fine.

Martin Szugat 16 years, 6 months ago  # | flag

How to set up/debug commit2rss.py on Sourceforge. I have absolutely no plan about Python but I want to use commit2rss.py for my project BioWeka on Sourceforge. I installed and configured it as described:

  • copied both RSS.py and commit2rss.py to /home/groups/b/bi/bioweka/
  • changed DROP_DIR to /home/groups/b/bi/bioweka/htdocs/rss
  • added this line to loginfo: /home/groups/b/bi/bioweka/commit2rss.py
  • commited loginfo
  • made /home/groups/b/bi/bioweka/htdocs/rss writeable

But: There are no files within this directory after I commited changes to the repository. What did I wrong or what didn't I? How to debug it? E.g. call commit2rss.py manual from shell?

David Kilzer 16 years, 5 months ago  # | flag

Using with cvs-1.12.x. If you're using this script with cvs-1.12.x, you need to change '%{}' to '%{p}' in your CVSROOT/loginfo file. Also make sure that 'UseNewInfoFmtStrings=yes' is set in your CVSROOT/config file if you are upgrading from an earlier version of CVS. This will get rid of the warnings about use of deprecated format strings.