rss-notification in systray with Groovy

Somewhere in Iceland, own photo (by Christoph Burmeister)

Somewhere in Iceland, own photo (by Christoph Burmeister)

Because my Outlook doesn’t support the rss-format of jenkins-job-feeds, I decided to build up my own rss-client. Simply get the feed as xml-input and compare it to an earlier on.
A nice addon is the systray-notification that pops up whenever a new feed is available.
Of course you could also use it for other feeds, but being honestly, this is just a simple and fast solution to get notified whenever a jenkins-job is running. So nothing serious like feedly or whatever.

Here comes the source for rss-reader.groovy

import java.awt.MenuItem;
import java.awt.PopupMenu;
import java.awt.SystemTray;
import java.awt.Toolkit;
import java.awt.TrayIcon;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JOptionPane;

// setup for proxy
//["http.proxyHost":"your.proxy", "http.proxyPort":"8080"]);

def url = 'http://localhost:10000/job/testproject/rssAll';
def downloadIntervallMs=5000;
def trayIcon='rss.gif';

def popupText='';

// the menu that comes up on right-click
// simple menu with just an Exit-option
PopupMenu menu = new PopupMenu();
MenuItem exit = new MenuItem("Exit");
exit.addActionListener(new ActionListener() {
	public void actionPerformed(ActionEvent e) {
// -------------------------------------------------

// the systray-icon that gets an ActionListener for the 
// show-Message-Dialog on double left-click
TrayIcon icon = new TrayIcon(
	"Java application as a tray icon", 
	new ActionListener() {
	public void actionPerformed(ActionEvent e) {
		JOptionPane.showMessageDialog(null, popupText);
// --------------------------------------------------

// get every intervall a new file after rename the existing file
// then get the difference 
// and push the new entrys to a string that will be displayed in popup
while (true){

	// rename existing file to old fille
	if (new File('old-feed.xml').exists()){
		new File('old-feed.xml').delete();
	if (new File('new-feed.xml').exists()){
		new File('new-feed.xml').renameTo(new File('old-feed.xml'));

	def newFile = new File('new-feed.xml').newOutputStream();
	newFile << new URL(url).openStream()

	// get the feeds from the new file
	def newFeed = new XmlSlurper().parseText(new File('new-feed.xml').text);
	newFeedEntryCount = newFeed.entry.title.size()

	// get the feeds from the old file
	def oldFeed = new XmlSlurper().parseText(new File('old-feed.xml').text);
	oldFeedEntryCount = oldFeed.entry.title.size()

	diff = newFeedEntryCount - oldFeedEntryCount;
	if (diff > 0){		
		popupText = '';
		for (int i=diff; i>0; i--){
			titleText = newFeed.entry.title[i].text();
			linkText =[i].'@href';
			entryData = titleText + " - " + linkText;
			println entryData;
			popupText += entryData + "\n";			
		icon.displayMessage("Attention", popupText, TrayIcon.MessageType.INFO);
	} else {

here comes a small excerpt from the jenkins-feed-xml:

<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="">
	<title>testproject all builds</title>
	<link type="text/html" href="http://localhost:10000/job/testproject/" rel="alternate"/>
		<name>Jenkins Server</name>
		<title>testproject #102 (stable)</title>
		<link type="text/html" href="http://localhost:10000/job/testproject/102/" rel="alternate"/>
		<title>testproject #101 (stable)</title>
		<link type="text/html" href="http://localhost:10000/job/testproject/101/" rel="alternate"/>
		<title>testproject #100 (stable)</title>
		<link type="text/html" href="http://localhost:10000/job/testproject/100/" rel="alternate"/>

the notification:
and the popup on doubleclick on icon: