Introduction
Recently I started playing with Groovy, a dynamic language that — according to the first chapter of the Groovy in Action book — is Python-inspired.
One of the reasons why I find Groovy attractive is that it can be compiled to Java byte code (despite being a dynamic language) i.e. you gain access to all the Java libraries and the capability to deploy on the Java platform without actually having to write Java code.
Groovy is even supported by the Spring Framework. So, if you’re “forced” to work in a Java project in order to make a living but would rather be using a dynamic language then Groovy is definitely worth a look.
Example
Some time ago I wrote a small tool (using Python) that manages my audiocasts. Based on the RSS feeds I am interested in it synchronises
-
the MP3 files on my MP3 player with the ones available on the local hard disk of my computer
-
the MP3 files on my computer (local hard disk) with the ones available on the web
It is also cognizant of the date of an audiocast and will only consider MP3 files that were published on a particular channel N days ago.
I thought building a similar tool in Groovy would be a nice exercise and a good way to get to know the language.
I started playing with the code that parses the RSS (XML) files first and was pleasantly surprised how quickly I was able to get my hands on the data required.
For an example of how an RSS file looks like see e.g. the MacBreak’s weekly RSS file. In essence the top level tag is <channel> with a number of embedded <item> tags. Each item is an audiocast and the data I needed for my purpose is as follows:
- audiocast episode title (
<title> tag)
- publication date (
<pubDate> tag)
- the URL pointing to the MP3 file (
<link> tag)
Depending on the publisher the format of the RSS file may vary slightly. The publication date is e.g. sometimes buried in a <dc:date> tag (where dc is an XML name space pointing to http://purl.org/dc/elements/1.1/).
Likewise, the MP3 file URL is sometimes not contained in a <link> tag but in the url attribute of the <enclosure> tag.
The RSS files on my system are here:
1 bbox33:audiocasts $ pwd
2 /Users/mhr/dl/audio/audiocasts
3 bbox33:audiocasts $ find . -type f -name \\*.rss
4 ./metadata/Cc_zwei.rss
5 ./metadata/Elrep.rss
6 ./metadata/Security_now_.rss
7 ./metadata/Technometria.rss
8 ./metadata/This_week_in_tech.rss
9 ./metadata/Windows_weekly.rss
The Groovy code that finds the RSS files listed above and parses them is as follows:
1 def audioDir = new File("/Users/mhr/dl/audio/audiocasts")
2
3 // initialise RSS files list
4 files = []
5 // find RSS files underneath 'audioDir'
6 audioDir.eachFileRecurse { if (it =~ /.*\.(xml|rss)$/) { files << it } }
7
8 println("\\\n-------- RSS files --------")
9 println files.join('\\\n')
10
11 // iterate over RSS files found
12 for (rssf in files) {
13 println("\\\n-------- $rssf --------")
14 // parse the RSS file
15 def d = new XmlSlurper().parse(rssf)
16 d.declareNamespace(dc:"http://purl.org/dc/elements/1.1/")
17
18 // iterate over item tags in RSS file (take only the first two)
19 d.channel.item[0..1].each {
20 println "==> ${it.title}"
21 if (it.pubDate.toString().trim()) {
22 println "pubDate: ${it.pubDate}"
23 } else {
24 println "dc:date: ${it.'dc:date'}"
25 }
26 if (it.link.toString().trim()) {
27 println "link: ${it.link}"
28 } else {
29 println "url: ${it.enclosure.@url}"
30 }
31 }
32 }
Here’s the output generated by the code above:
1 bbox33:groovy $ groovy xml.groovy
2
3 -------- RSS files --------
4 /Users/mhr/dl/audio/audiocasts/metadata/Cc_zwei.rss
5 /Users/mhr/dl/audio/audiocasts/metadata/Elrep.rss
6 /Users/mhr/dl/audio/audiocasts/metadata/Security_now_.rss
7 /Users/mhr/dl/audio/audiocasts/metadata/Technometria.rss
8 /Users/mhr/dl/audio/audiocasts/metadata/This_week_in_tech.rss
9 /Users/mhr/dl/audio/audiocasts/metadata/Windows_weekly.rss
10
11 -------- /Users/mhr/dl/audio/audiocasts/metadata/Cc_zwei.rss --------
12 ==> CC2 - 62. Folge
13 pubDate: Mon, 13 Aug 2007 20:00:00 +0200 +0200
14 url: http://www.media01-live.de/CC-Zwei-62.mp3
15 ==> CC2 - 61. Folge
16 pubDate: Mon, 06 Aug 2007 20:00:00 +0200 +0200
17 url: http://www.media01-live.de/CC-Zwei-61.mp3
18
19 -------- /Users/mhr/dl/audio/audiocasts/metadata/Elrep.rss --------
20 ==> 36: Lutz Schmitt ^_ber Machinima
21 dc:date: 2007-08-05T21:30:00+01:00
22 link: http://www.elektrischer-reporter.de/index.php/site/film/48/
23 ==> 35: Peter Schaar ^_ber Vorratsdatenspeicherung und Online-Durchsuchungen
24 dc:date: 2007-07-22T21:30:00+01:00
25 link: http://www.elektrischer-reporter.de/index.php/site/film/47/
26
27 -------- /Users/mhr/dl/audio/audiocasts/metadata/Security_now_.rss --------
28 ==> Security Now 104: SteveOs Questions, Your Answers 22 - sponsored by Astaro Corp.
29 pubDate: Thu, 09 Aug 2007 08:22:49 -0700
30 link: http://www.podtrac.com/pts/redirect.mp3/aolradio.podcast.aol.com/sn/SN-104.mp3
31 ==> Security Now 103: Paypal Security Key - sponsored by Astaro Corp.
32 pubDate: Thu, 02 Aug 2007 15:17:58 -0700
33 link: http://www.podtrac.com/pts/redirect.mp3/aolradio.podcast.aol.com/sn/SN-103.mp3
34
35 -------- /Users/mhr/dl/audio/audiocasts/metadata/Technometria.rss --------
36 ==> Scott Lemon, Ben Galbraith - Technometria
37 pubDate: Tue, 14 Aug 2007 00:00:00 CDT
38 link: http://www.itconversations.com/shows/detail1892.html
39 ==> Drew Major - Technometria
40 pubDate: Tue, 7 Aug 2007 00:00:00 CDT
41 link: http://www.itconversations.com/shows/detail1886.html
42
43 -------- /Users/mhr/dl/audio/audiocasts/metadata/This_week_in_tech.rss --------
44 ==> TWiT 109: The Numinous From The Quotidian
45 pubDate: Sun, 12 Aug 2007 22:39:47 -0700
46 link: http://www.podtrac.com/pts/redirect.mp3/aolradio.podcast.aol.com/twit/TWiT0109H.mp3
47 ==> TWiT 108: The Crash of 2007
48 pubDate: Sun, 05 Aug 2007 20:48:59 -0700
49 link: http://www.podtrac.com/pts/redirect.mp3/aolradio.podcast.aol.com/twit/TWiT0108H.mp3
50
51 -------- /Users/mhr/dl/audio/audiocasts/metadata/Windows_weekly.rss --------
52 ==> Windows Weekly 32: Neener Neener Neener
53 pubDate: Fri, 27 Jul 2007 18:49:31 -0700
54 link: http://www.podtrac.com/pts/redirect.mp3/twit.cachefly.net/WW-032.mp3
55 ==> Windows Weekly 31: Computing In The Clouds
56 pubDate: Fri, 20 Jul 2007 08:57:52 -0700
57 link: http://www.podtrac.com/pts/redirect.mp3/twit.cachefly.net/WW-031.mp3
Conclusion
I have not written any substantial code in Groovy yet but my first impressions of the language are favourable. Groovy should be an interesting addition to your arsenal (particularly if you know the Java libraries fairly well).