RSS feeds?

25 views
Skip to first unread message

Trent

unread,
Feb 16, 2010, 11:39:57 AM2/16/10
to ReposStyle
First off, let me say that ReposStyle is an incredible piece of work!
Thank you so much for putting it together!

Has anybody given any thought to providing RSS feeds? It seems that a
variation on the "view history" thing could return an RSS feed
instead. I have found a couple of different XSL files for
transforming SVN log output into RSS, but I didn't have much luck
getting them to work. But since I know next to nothing about XSL
that's not surprising.

Anyway, here are the two xsl files I found:
http://code.google.com/p/pragwatch/source/browse/trunk/Pragwatch.Web/SubversionLog/svnlog.xslt
and
http://svn.activemath.org/AMauthoring/trunk/projects/svnlog-xslt/

I tried to plug the former one in place of log.xsl but Firefox gave me
"Error during XSLT transformation: An unknown XPath extension function
was called." and IE gave me an empty page. Though "xsltproc" accepted
it without complaint. I narrowed it down (by commenting out parts) to
something in the date code (the "rfc822" template).

I'll probably give this another try once I've read up on XSL, but I
thought I'd post here in case someone else has been down this road
before.

++thanks,
trent...

Staffan

unread,
Feb 17, 2010, 1:16:52 AM2/17/10
to repos...@googlegroups.com

Hi Trent,

To work in RSS clients I'd say the log has to be transformed server
side. I think you could modify a copy of index.php in
repos-web/open/log/ and use the PHP XSL extension
(http://www.php.net/manual/en/book.xsl.php). This could possibly solve
the xpath issues, if that xsl engine is compatible with one of the
stylesheets.

/Staffan

solsson

unread,
Feb 21, 2010, 4:13:26 PM2/21/10
to ReposStyle
On Feb 17, 7:16 am, Staffan <sols...@gmail.com> wrote:

> On Tue, Feb 16, 2010 at 5:39 PM, Trent <trent.a.fis...@gmail.com> wrote:
> > First off, let me say that ReposStyle is an incredible piece of work!
> > Thank you so much for putting it together!
>
> > Has anybody given any thought to providing RSS feeds?  It seems that a
> > variation on the "view history" thing could return an RSS feed
> > instead.  I have found a couple of different XSL files for
> > transforming SVN log output into RSS, but I didn't have much luck
> > getting them to work.  But since I know next to nothing about XSL
> > that's not surprising.
>
> > Anyway, here are the two xsl files I found:
> >http://code.google.com/p/pragwatch/source/browse/trunk/Pragwatch.Web/...

> > and
> >http://svn.activemath.org/AMauthoring/trunk/projects/svnlog-xslt/
>
> > I tried to plug the former one in place of log.xsl but Firefox gave me
> > "Error during XSLT transformation: An unknown XPath extension function
> > was called." and IE gave me an empty page.  Though "xsltproc" accepted
> > it without complaint. I narrowed it down (by commenting out parts) to
> > something in the date code (the "rfc822" template).
>
> > I'll probably give this another try once I've read up on XSL, but I
> > thought I'd post here in case someone else has been down this road
> > before.
>
> > ++thanks,
> > trent...
>
> Hi Trent,
>
> To work in RSS clients I'd say the log has to be transformed server
> side. I think you could modify a copy of index.php in
> repos-web/open/log/ and use the PHP XSL extension
> (http://www.php.net/manual/en/book.xsl.php). This could possibly solve
> the xpath issues, if that xsl engine is compatible with one of the
> stylesheets.
>
> /Staffan

I did a very quick implementation using the first stylesheet you
suggested. The second one gave me syntax errors in php-xsl.

You can find the sample at https://labs.repos.se/data/repos-plugins/trunk/logrss/.
It is called with the same query parameters as the log viewer, for
example http://localhost/repos-plugins/logrss/?base=repo1&target=/

TODO:
* Change the stylesheet headers (the project is GPLv2 so I guess the
stylesheet is too)
* Add rss link and html head tag to the log viewer or the index xslt

/Staffan

Trent

unread,
Feb 23, 2010, 7:52:18 PM2/23/10
to ReposStyle

> You can find the sample athttps://labs.repos.se/data/repos-plugins/trunk/logrss/.


> It is called with the same query parameters as the log viewer, for

> examplehttp://localhost/repos-plugins/logrss/?base=repo1&target=/


>
> TODO:
> * Change the stylesheet headers (the project is GPLv2 so I guess the
> stylesheet is too)
> * Add rss link and html head tag to the log viewer or the index xslt
>
> /Staffan

Actually, I messed around with it as well, and got something working,
though in a different way. I used the second stylesheet and called
xsltproc to generate the rss output. I did this since it looked like
php-xsl is not available in the version of php I have.

The only problem I ran into was including the "link' header so that
the rss icon shows up by the url in the browser. I didn't want it to
show up at the "list of repositories" level. I imitated some
conditionals to do the same thing later on, but no luck. (I know
little about XSLT)

I'm testing these changes, but thus far they seem ok. I can send
along patches if you want them.

trent...

Staffan

unread,
Feb 24, 2010, 2:42:34 AM2/24/10
to repos...@googlegroups.com

Great. Yes please send patches. Your rss icon solution is definitely
needed regardless if php-xsl is used or not.

What version of PHP do you have? I found the php5-xsl package in
macports on OSX and the official package source on debian/ubuntu so I
figured it will be available on most servers. On windows there's
extension=php_xsl.dll in php.ini.

/Staffan

Trent

unread,
Feb 24, 2010, 12:17:52 PM2/24/10
to ReposStyle
On Feb 24, 2:42 am, Staffan <sols...@gmail.com> wrote:

I have php 4.3.9... Yes, I know, it is ancient, but I don't use php,
and never had call to upgrade it.

Anyway, the patch is below. A few explanatory notes:
* I know very little about PHP or XSLT, so forgive any novice
mistakes.
* I may not have the RSS header right, and, regardless, the copyright
header needs to be parametrized.
* The feed icon came from www.feedicons.com
* I have a comment about the <link> header that I couldn't get to work
right.

Index: repos-web/style/global.css
===================================================================
--- repos-web/style/global.css (revision 63)
+++ repos-web/style/global.css (working copy)
@@ -124,6 +124,9 @@
#commandbar #history {
background-image: url('commands/16x16/history.png');
}
+#commandbar #rss {
+ background-image: url('commands/16x16/feed-icon-12x12.png');
+}
#commandbar #download {
background-image: url('commands/16x16/download.png');
}
Index: repos-web/open/log/users.xml
===================================================================
--- repos-web/open/log/users.xml (revision 0)
+++ repos-web/open/log/users.xml (revision 67)
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<users>
+ <user username="USERNAME">
+ <fullname>USER NAME</fullname>
+ <email>USER...@someplace.com</email>
+ </user>
+</users>
Index: repos-web/open/log/rss.xsl
===================================================================
--- repos-web/open/log/rss.xsl (revision 0)
+++ repos-web/open/log/rss.xsl (revision 67)
@@ -0,0 +1,129 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:date="http://exslt.org/dates-and-times" xmlns:func="http://
exslt.org/functions" xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:str="http://exslt.org/strings" extension-element-prefixes="date
func str" version="1.0">
+
+<!--
+svnlog.xslt by Martin Pittenauer / TheCodingMonkeys
+Web: www.codingmonkeys.de, Mail:
m...@codingmonkeys.de
+
+iso->rfc822 date conversion code heavily inspired by Steven
Engelhardt (http://www.deez.info/sengelha/)
+Tested with libxslt.
+-->
+
+
+ <xsl:output omit-xml-declaration="no" indent="yes"
encoding="UTF-8" method="xml" />
+ <xsl:variable name="users" select="document($usersDocument)"/>
+
+ <xsl:template match="log">
+ <rss version="2.0">
+ <channel>
+ <title><xsl:value-of select="$feedname"/></title>
<!-- put your repository name here -->
+
+ <link><xsl:value-of select="$projecturl"/>/</link>
<!-- put your project homepage here -->
+ <description>svn commit log</description>
+ <language>en-us</language>
+ <copyright><xsl:value-of select="$copyright"/></
copyright> <!-- put your company here -->
+ <generator>svnlog.xslt</generator>
+ <xsl:apply-templates select="logentry" />
+
+ </channel>
+ </rss>
+ </xsl:template>
+
+ <xsl:template match="logentry">
+ <xsl:variable name="shortTitle">
+ <xsl:choose>
+ <xsl:when test="contains(msg/text(),'&#xA;')"><xsl:value-of
select="substring-before(msg/text(),'&#xA;')"/></xsl:when>
+ <xsl:otherwise><xsl:value-of select="substring(msg/text(),
0,30)"/></xsl:otherwise>
+ </xsl:choose>
+
+ </xsl:variable>
+ <xsl:variable name="userName" select="author/text()"/>
+ <xsl:variable name="authorName">
+ <xsl:choose>
+ <xsl:when test="$users//user[@username=$userName]/
fullname"><xsl:value-of select="$users//user[@username=$userName]/
fullname"/></xsl:when>
+ <xsl:otherwise><xsl:value-of select="author/text()"/></
xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:variable name="authorEmail">
+
+ <xsl:choose>
+ <xsl:when test="$users//user[@username=$userName]/
email"><xsl:value-of select="$users//user[@username=$userName]/email"/
></xsl:when>
+ <xsl:otherwise><xsl:value-of select="author/text()"/></
xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <item>
+ <title>Revision <xsl:value-of select="@revision"/> by
<xsl:value-of select="$authorName" />: <xsl:value-of
select="$shortTitle" /></title>
+
+ <pubDate>
+ <xsl:call-template name="rfc822">
+ <xsl:with-param name="isodate" select="date" />
+ </xsl:call-template>
+ </pubDate>
+ <!-- According to RSS 2.0 specs, author has to be an
rfc822 valid email address -->
+ <!-- <author><xsl:value-of select="$authorEmail" /></
author> -->
+ <dc:creator><xsl:value-of select="$authorName"/></
dc:creator>
+ <description disable-output-escaping="yes">&lt;div
style="white-space:pre"&gt;<xsl:value-of select="msg" />&lt;/
div&gt;&lt;br/&gt;
+
+ (&lt;em&gt;<xsl:call-template name="rfc822">
+ <xsl:with-param name="isodate" select="date" />
+ </xsl:call-template>&lt;/em&gt;)&lt;br/&gt;&lt;br/
&gt;
+ &lt;table&gt;<xsl:apply-templates select="paths/
path" />&lt;/table&gt;
+ </description>
+
+ </item>
+ </xsl:template>
+
+ <xsl:template match="paths/path">
+ &lt;tr&gt;&lt;td&gt;&lt;strong&gt;<xsl:call-template
name="svncommand"><xsl:with-param name="command" select="@action" /></
xsl:call-template>&lt;/strong&gt;&lt;/td&gt;
+ &lt;td&gt;&amp;nbsp;&lt;a href="<xsl:value-of
select="$repositoryBaseUrl"/><xsl:value-of select="."/>"&gt;<xsl:value-
of select="."/>&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt; <!-- put link to your
repository here -->
+
+ </xsl:template>
+
+ <xsl:template name="rfc822">
+ <xsl:param name="isodate" />
+ <xsl:variable name="dayOfWeek" select="date:day-
abbreviation($isodate)" />
+ <xsl:variable name="day" select="date:day-in-
month($isodate)" />
+ <xsl:variable name="monthAbbr" select="date:month-
abbreviation($isodate)" />
+ <xsl:variable name="year" select="date:year($isodate)" />
+ <xsl:variable name="hour" select="date:hour-in-
day($isodate)" />
+
+ <xsl:variable name="minute" select="date:minute-in-
hour($isodate)" />
+ <xsl:variable name="second" select="round(date:second-in-
minute($isodate))" />
+
+ <xsl:value-of select="$dayOfWeek" />
+ <xsl:text>, </xsl:text>
+ <xsl:value-of select="$day" />
+ <xsl:text> </xsl:text>
+ <xsl:value-of select="$monthAbbr" />
+
+ <xsl:text> </xsl:text>
+ <xsl:value-of select="$year" />
+ <xsl:choose>
+ <xsl:when test="$hour and $minute and $second">
+ <xsl:text> </xsl:text>
+ <xsl:value-of select="str:align($hour, '00',
'right')" />
+ <xsl:text>:</xsl:text>
+
+ <xsl:value-of select="str:align($minute, '00',
'right')" />
+ <xsl:text>:</xsl:text>
+ <xsl:value-of select="str:align($second, '00',
'right')" />
+ <xsl:text> GMT</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text> 00:00:00 GMT</xsl:text>
+
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template name="svncommand">
+ <xsl:param name="command"/>
+ <xsl:choose>
+ <xsl:when test="$command = 'A'">Added</xsl:when>
+ <xsl:when test="$command = 'D'">Deleted</xsl:when>
+
+ <xsl:when test="$command = 'M'">Modified</xsl:when>
+ </xsl:choose>
+ </xsl:template>
+
+</xsl:stylesheet>
Index: repos-web/open/log/index.php
===================================================================
--- repos-web/open/log/index.php (revision 63)
+++ repos-web/open/log/index.php (working copy)
@@ -49,6 +49,29 @@

$url = $repo . $target;

+if ($_REQUEST['format'] == "rss")
+{
+ $cmd = '( echo \'<?xml version="1.0"?><log limit="'.$limit.'">\';
';
+ $cmd .= $svn.' log --xml --verbose --incremental --non-
interactive';
+ $cmd .= ' --limit '.escapeshellarg($limit);
+ $cmd .= ' '.escapeshellarg($url);
+ $cmd .= '; echo \'</log>\' )';
+ // this, of course, assumes xsltproc is installed
+ $cmd .= ' | xsltproc ';
+ $cmd .= ' --param feedname "\'SVN changes for '.$url.'\'"';
+ $cmd .= ' --param copyright "\'Copyright 2010 Oracle America, Inc.
\'"';
+ $cmd .= ' --param projecturl "\''.$url.'\'"';
+ // XXX kludge
+ $cmd .= ' --param repositoryBaseUrl "\'/svn/'.$_REQUEST['base'].'/
$target\'"';
+ $cmd .= ' --param usersDocument "\'users.xml\'"';
+ $cmd .= ' rss.xsl -';
+
+ header('Content-Type: text/xml');
+ //echo($cmd);
+ passthru($cmd);
+ return;
+}
+
// command line, injection safe, svn must be in path, assumes utf-8
shell
$cmd = $svn.' log --xml --verbose --incremental --non-interactive';
$cmd .= ' --limit '.escapeshellarg($limit);
Index: repos-web/view/repos.xsl
===================================================================
--- repos-web/view/repos.xsl (revision 63)
+++ repos-web/view/repos.xsl (working copy)
@@ -54,6 +54,11 @@
<meta http-equiv="Content-Type" content="text/html;
charset=utf-8"/>
<meta name="robots" content="noarchive"/>
<link rel="shortcut icon" href="/favicon.ico"/>
+ <!-- this shouldn't be shown on the
"repository list" page... but this doesn't work
+ <xsl:if test="$logUrl and @rev>0">
+ </xsl:if>
+ -->
+ <link rel="alternate"
type="application/rss+xml" title="rss feed" href="{$logUrl}target={/
svn/index/@path}&amp;format=rssX{@version}X" />
<xsl:call-template name="styletag"/>
<!-- repos metadata for use in plugins -->
<meta name="repos-service" content="index/" />
@@ -94,6 +99,7 @@
<!-- <xsl:if test="$logUrl"> add @rev>0 to hide log for
SVNParentPath and empty repositories -->
<xsl:if test="$logUrl and @rev>0">
<a id="history" class="command translate" href="{$logUrl}target={/
svn/index/@path}">folder history</a>
+ <a id="rss" class="command translate" href="{$logUrl}target={/svn/
index/@path}&amp;format=rss">rss feed</a>
</xsl:if>
<a id="refresh" class="command translate" href="#"
onclick="window.location.reload( true )">refresh</a>
</div>
@@ -132,6 +138,7 @@
<!--Hide the "view history" column in the listing if displaying
SVNParentPath -->
<xsl:if test="$logUrl and /svn/index/@rev &gt; 0">
<a id="history:{$id}" class="action" href="{$logUrl}target={../
@path}/{@href}">view history</a>
+ <a id="rss:{$id}" class="action" href="{$logUrl}target={../
@path}/{@href}&amp;format=rss">rss</a>
</xsl:if>
</div>
<a id="f:{$id}" class="folder" href="{@href}">
@@ -153,6 +160,7 @@
<a id="open:{$id}" class="action" href="{@href}">open</a>
<xsl:if test="$logUrl">
<a id="history:{$id}" class="action" href="{$logUrl}target={../
@path}/{@href}">view history</a>
+ <a id="rss:{$id}" class="action" href="{$logUrl}target={../
@path}/{@href}&amp;format=rss">rss</a>
</xsl:if>
</div>
<a id="f:{$id}" class="file-{$filetype} file" href="{@href}">

Scott Grayban

unread,
Feb 24, 2010, 2:21:21 PM2/24/10
to repos...@googlegroups.com
Please attach the patches to the email or upload them to the files section. Adding them to the email ruins the format of a patch file.

Scott Grayban


Trent said the following on 02/24/2010 09:17 AM:

Trent Fisher

unread,
Feb 24, 2010, 4:34:08 PM2/24/10
to repos...@googlegroups.com
> Please attach the patches to the email or upload them to the files section.
> Adding them to the email ruins the format of a patch file.

Sorry about that, I was replying on the Google Groups interface where
there is no ability to attach. I should have known better and just
sent an email... like this.

trent...

patch

Scott Grayban

unread,
Feb 25, 2010, 11:13:17 AM2/25/10
to repos...@googlegroups.com
Thanks that works much better :)

Scott


Trent Fisher said the following on 02/24/2010 01:34 PM:

solsson

unread,
Mar 8, 2010, 2:54:31 AM3/8/10
to ReposStyle

I've updated the plugin (sort of) solution to use the same stylesheet
and parameters that you do. It's better because rss meta is
customizable. I've also added your xsltproc command solution as
fallback for servers that don't have php5-xsl. See
https://labs.repos.se/data/repos-plugins/trunk/logrss/.

For this to be a pluign rather than a patch I need to find a clean way
to add the command and the link header to the index xslt. I'm thinking
a single javascript inclusion like the dateformat plugin.

/Staffan

Reply all
Reply to author
Forward
0 new messages