? tinderbox-feed.patch
Index: jhbuild/config.py
===================================================================
RCS file: /cvs/gnome/jhbuild/jhbuild/config.py,v
retrieving revision 1.21
diff -u -r1.21 config.py
--- jhbuild/config.py	30 Nov 2004 10:17:15 -0000	1.21
+++ jhbuild/config.py	14 Jun 2005 16:47:45 -0000
@@ -33,7 +33,7 @@
                 'builddir_pattern', 'module_autogenargs', 'module_makeargs',
                 'interact', 'buildscript', 'nonetwork',
                 'alwaysautogen', 'nobuild', 'makeclean', 'makecheck',
-                'use_lib64', 'tinderbox_outputdir', 'sticky_date',
+                'use_lib64', 'tinderbox_outputdir', 'feed_url', 'sticky_date',
                 'tarballdir', 'pretty_print' ]
 
 env_prepends = {}
Index: jhbuild/defaults.jhbuildrc
===================================================================
RCS file: /cvs/gnome/jhbuild/jhbuild/defaults.jhbuildrc,v
retrieving revision 1.16
diff -u -r1.16 defaults.jhbuildrc
--- jhbuild/defaults.jhbuildrc	9 May 2005 05:48:02 -0000	1.16
+++ jhbuild/defaults.jhbuildrc	14 Jun 2005 16:47:45 -0000
@@ -67,6 +67,9 @@
 # where to put tinderbox output
 tinderbox_outputdir = None
 
+# URL for rss feed
+feed_url = 'http://localhost/jhbuild'
+
 # sticky date to perform historic checkouts
 sticky_date = None
 
Index: jhbuild/main.py
===================================================================
RCS file: /cvs/gnome/jhbuild/jhbuild/main.py,v
retrieving revision 1.17
diff -u -r1.17 main.py
--- jhbuild/main.py	11 Dec 2004 17:29:24 -0000	1.17
+++ jhbuild/main.py	14 Jun 2005 16:47:49 -0000
@@ -64,6 +64,7 @@
 
 Options valid for the tinderbox command:
   -o, --output=DIR             directory to save build logs in
+  -u, --url=URL                url where your build logs are kept
 
 Options valid for the list command:
   -r, --show-revision          show which revision will be built
Index: jhbuild/commands/tinderbox.py
===================================================================
RCS file: /cvs/gnome/jhbuild/jhbuild/commands/tinderbox.py,v
retrieving revision 1.7
diff -u -r1.7 tinderbox.py
--- jhbuild/commands/tinderbox.py	23 Mar 2004 08:05:46 -0000	1.7
+++ jhbuild/commands/tinderbox.py	14 Jun 2005 16:47:49 -0000
@@ -28,7 +28,7 @@
     startat = None
     opts, args = getopt.getopt(args, 'acno:s:t:D:',
                                ['autogen', 'clean', 'no-network', 'output=',
-                                'skip=', 'start-at='])
+                                'url=','skip=', 'start-at='])
 
     for opt, arg in opts:
         if opt in ('-a', '--autogen'):
@@ -43,6 +43,8 @@
             startat = arg
         elif opt in ('-o', '--output'):
             config.tinderbox_outputdir = arg
+        elif opt in ('-u', '--url'):
+            config.feed_url = arg
         elif opt == '-D':
             config.sticky_date = arg
 
Index: jhbuild/frontends/tinderbox.py
===================================================================
RCS file: /cvs/gnome/jhbuild/jhbuild/frontends/tinderbox.py,v
retrieving revision 1.11
diff -u -r1.11 tinderbox.py
--- jhbuild/frontends/tinderbox.py	2 Oct 2004 08:41:14 -0000	1.11
+++ jhbuild/frontends/tinderbox.py	14 Jun 2005 16:47:53 -0000
@@ -26,6 +26,7 @@
 index_header = '''<html>
   <head>
     <title>JHBuild Results</title>
+    <link rel="meta" type="application/rss+xml" title="RSS" href="feed.rdf" />
     <style type="text/css">
       .section {
         margin-after: 1.5em;
@@ -105,6 +106,25 @@
 </html>
 '''
 
+feed_header = '''<Channel xmlns="http://purl.org/net/rss1.1#"
+         xmlns:p="http://purl.org/net/rss1.1/payload#"
+         xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+         rdf:about="http://www.xml.com/xml/news.rss"
+         xmlns:dc="http://purl.org/dc/elements/1.1/">
+  <title>JHBuild Results</title>
+  <link>%(url)s</link>
+  <description>
+    This RSS feed lists recent errors build gnome from CVS.
+    %(feedinfo)s
+  </description>
+  <items rdf:parseType="Collection">
+'''
+
+feed_footer = '''
+  </items>
+</Channel>
+'''
+
 def escape(string):
     return string.replace('&','&amp;').replace('<','&lt;').replace('>','&gt;')
 
@@ -119,6 +139,7 @@
             os.makedirs(self.outputdir)
 
         os.environ['TERM'] = 'dumb'
+        self.url = config.feed_url
 
     def timestamp(self):
         tm = time.time()
@@ -147,7 +168,6 @@
         '''executes a command, and returns the error code'''
         assert self.modulefp, 'not currently building a module'
 
-        
         self.modulefp.write('<pre>')
         self.modulefp.write('<span class="command">%s</span>\n'
                             % escape(command))
@@ -207,16 +227,23 @@
         info.append(('Start Time', self.timestamp()))
 
         buildplatform = '<table>\n'
+        feedinfo = ''
         for (key, val) in info:
             buildplatform += '<tr><th align="left">%s</th><td>%s</td></tr>\n' \
                              % (key, val)
+            feedinfo += '%s : %s\n    ' % (key, val)
         buildplatform += '</table>\n'
-        
+
         self.indexfp = open(os.path.join(self.outputdir, 'index.html'), 'w')
+        self.feedfp = open(os.path.join(self.outputdir, 'feed.rdf'), 'w')
 
         self.indexfp.write(index_header % { 'buildplatform': buildplatform })
         self.indexfp.flush()
 
+        self.feedfp.write(feed_header %
+                                    { 'feedinfo': feedinfo, 'url': self.url })
+        self.feedfp.flush()
+
     def end_build(self, failures):
         self.indexfp.write('<tr>'
                            '<td>%s</td>'
@@ -233,6 +260,10 @@
         self.indexfp.close()
         self.indexfp = None
 
+        self.feedfp.write(feed_footer)
+        self.feedfp.close()
+        self.feedfp = None
+
     def start_module(self, module):
         self.modulefilename='%s.html' % module.replace('/','_')
         self.indexfp.write('<tr>'
@@ -243,6 +274,20 @@
         self.modulefp = open(os.path.join(self.outputdir,
                                           self.modulefilename), 'w')
         self.modulefp.write(buildlog_header % { 'module': module })
+        self.feedfp.write('    <item rdf:about="%s/%s">\n'
+                          '      <title>%s</title>\n'
+                          '      <link>%s/%s</link>\n'
+                          '      <dc:date>%s</dc:date>\n'
+                          '      <dc:subject>GNOME</dc:subject>\n'
+                          '      <dc:subject>%s</dc:subject>\n'
+                          '      <p:payload rdf:parseType="Literal"\n'
+                          '          xmlns="http://www.w3.org/1999/xhtml">\n'
+                              % (self.url, self.modulefilename,
+                                 module,
+                                 self.url, self.modulefilename,
+                                 self.timestamp(),
+                                 module))
+
     def end_module(self, module, failed):
         if failed:
             self.message('Failed')
@@ -254,21 +299,40 @@
         self.indexfp.write('</td>\n')
         if failed:
             self.indexfp.write('<td class="failure">failed</td>\n')
+            self.feedfp.write('      </p:payload>\n'
+                              '      <description>\n'
+                              '        %s - failed\n'
+                              '      </description>\n' % module)
         else:
             self.indexfp.write('<td class="success">ok</td>\n')
+            self.feedfp.write('      </p:payload>\n'
+                              '      <description>\n'
+                              '        %s - ok\n'
+                              '      </description>\n' % module)
         self.indexfp.write('</tr>\n\n')
+        self.feedfp.write('    </item>\n')
         self.indexfp.flush()
 
     def start_phase(self, module, state):
         self.modulefp.write('<a name="%s"></a>\n' % state)
+
     def end_phase(self, module, state, error):
+        self.feedfp.write('        <p>\n')
         if error:
             self.indexfp.write('<a class="failure" title="%s" href="%s#%s">%s</a>\n'
                                % (error, self.modulefilename, state, state))
+            self.modulefilename='%s.html' % module.replace('/','_')
+            self.feedfp.write('          <a class="failure"\n'
+                              '             href="%s/%s#%s">%s - %s</a>\n'
+                               % (self.url, self.modulefilename, state,
+                                  state, error))
         else:
             self.indexfp.write('<a class="success" href="%s#%s">%s</a>\n'
                                % (self.modulefilename, state, state))
+            self.feedfp.write('          %s - passed\n' % (state))
+        self.feedfp.write('        </p>\n')
         self.indexfp.flush()
+        self.feedfp.flush()
 
     def handle_error(self, module, state, nextstate, error, altstates):
         '''handle error during build'''
