Beliebte Suchanfragen
|
//

iCalender Dateiverarbeitung, Groovy!

18.8.2009 | 3 Minuten Lesezeit

Heute Nacht wollte ich eigentlich planen, welche Sessions ich auf der Agile 2009 besuchen möchte, die nächste Woche in Chicago stattfindet. I freue mich schon sehr auf die Konferenz und kann mich nur schwer zwischen den vielen Sessions entscheiden, weil ich so viele verpassen werde! Planung erfordert natürlich ein mindestmaß an Organisation. Auf der Homepage der Konferenz kann man sich durch das Importieren von iCalendar-Dateien die Termine der Sessions in den Kalender einpflegen. Eine großartige Idee … die leider nicht funktioniert, wenn man in einer anderen Zeitzone als Chicago lebt, oder Outlook als seinen Kalender benutzt. Meine Vermutung ist, dass eines der beiden Kriterien auf die meisten Benutzer zutrifft. Deshalb frage ich mich ernsthaft wie gut das Feature auf der Webseite getestet wurde. Naja, egal, mir hat es in den Fingern gekribbelt und ich habe einen Blick in dieSpezifikationen von iCalendar geworfen und ein kleines Groovy-Skript fabriziert, dass die bestehenden iCalendar-Dateien konvertiert.

>> Alle sessions sind konvertiert und können hier heruntergeladen werden. Fertig um in den Kalender importiert zu werden – auch nach Outlook.

Es gab mit den originären Dateien zwei Probleme. Hier ist eine Beispieldatei:

1BEGIN:VCALENDAR
2VERSION:2.0
3PRODID:Agile2009
4METHOD:PUBLISH
5CALSCALE:GREGORIAN
6X-WR-CALNAME:Agile2009
7X-WR-CALDESC:Agile2009
8BEGIN:VEVENT
9UID:1220
10DTSTART:20090825T140000
11DTEND:20090825T173000
12SUMMARY:User Stories for Agile Requirements
13LOCATION:Columbus IJ
14URL;VALUE=URI:http://agile2009.agilealliance.org/node/1220
15DTSTAMP:20090209T022940Z
16LAST-UPDATED:20090723T173948Z
17END:VEVENT
18END:VCALENDAR

Zeitzonen

Die Start- und Endzeit beinhalten keine Information über die Zeitzone, also wird die lokale Zeit angenommen. iCalender spezifiziert, dass die Zeit UTC ist, wenn ein „Z“ angehangen wird. Die Transformation ist also sehr einfach: fünf Stunden draufzählen um von Chicago zu UTC zukommen, und ein „Z“ anhängen.

Outlook

Das zweite Problem wird offenbar, wenn man versucht mehr als eine Session in Outlook zu importieren. Beim ersten Mal erstellt Outlook automatisch einen neuen Kalender „Agile2009“. Cool. Bei der zweiten Session landet diese aber wieder in einem neuen Kalender „Agile2009 (1)“. Extrem uncool. Um das zu beheben, müssen die beiden Properties X-WR-CALNAME und X-WR-CALDESC entfernt werden. Dies scheint leider ein bekanntes Problem mit Outlook zu sein . Zum Glück lässt sich das ebenfalls einfach beheben.

Groovy

Um die Konvertierung zu automatisieren, habe ich ein kleines Groovy-Skript geschrieben, welches sich erst alle gültigen Session-IDs besorgt, dann die iCalendar-Dateien herunterlädt und die beiden Fehler behebt, und mir auch noch den Text ausgibt, den ich in unser WordPress kopieren muss. Das Skript kann mit Sicherheit noch verbessert werden, aber es tut erstmal seinen Job. Was ich wirklich liebe an Groovy, ist die Möglichkeit Strings wie ein Array zu zerschneiden, und dabei mit negativen Indexen auch von hinten zählen zu können, sowie die Möglichkeiten durch das regex-Handling, das macht Aufgaben wie diese um ein Vielfaches einfacher 🙂

1public class ConvertCalendar{
2 
3private static final String VCAL_TIME_FMT = "yyyyMMdd'T'HHmmss";
4 
5public static void main(def args){
6// use the smartphone page to get all valid session numbers
7// http://agile2009.pairwith.us/sessions
8InputStream sessionStream = new URL("http://agile2009.pairwith.us/sessions").openConnection().inputStream
9 
10String sessions = org.apache.commons.io.IOUtils.toString(sessionStream);
11 
12List calList = new ArrayList();
13 
14// href="/sessions/5107"
15sessions.eachMatch(/href="\/sessions\/\d{1,4}"/) {
16    InputStream calendarStream = new URL("http://agile2009.agilealliance.org/session_ical/" + it[16 .. -2]).openConnection().inputStream
17    String calendar = org.apache.commons.io.IOUtils.toString(calendarStream);
18 
19    File calendarFile = new File("./cals/temp - calendar.ics");
20    def calendarFileWriter = new FileWriter(calendarFile)
21    def calendarFileName = "";
22    calendar.eachLine {
23        def vCalLine = it;
24        if (vCalLine ==~ /^X-WR-CALNAME:.*/ || vCalLine ==~ /^X-WR-CALDESC:.*/) {
25            // ignore that line
26        } else if (vCalLine ==~ /^DTSTART:.*/ ) {
27            def origDate = Date.parse(VCAL_TIME_FMT, vCalLine[-15..-1])
28            vCalLine = vCalLine[0..-16] + DateUtils.addHours(origDate,5).format(VCAL_TIME_FMT) + "Z";
29            calendarFileWriter.write("${vCalLine}\n")
30            calendarFileName = origDate.format("yyyy-MM-dd'T'HHmm");
31        } else if (vCalLine ==~ /^DTEND:.*/) {
32            def origDate = Date.parse(VCAL_TIME_FMT, vCalLine[-15..-1])
33            vCalLine = vCalLine[0..-16] + DateUtils.addHours(origDate,5).format(VCAL_TIME_FMT) + "Z";
34            calendarFileWriter.write("${vCalLine}\n")
35        } else if (vCalLine ==~ /^SUMMARY:.*/) {
36            calendarFileName = calendarFileName + " " + vCalLine[8..-1].replaceAll("[^\\w\\s]", "")
37            println "Processing " + calendarFileName
38            calendarFileWriter.write("${vCalLine}\n")
39        } else {
40            calendarFileWriter.write("${vCalLine}\n")
41        }
42    }
43    calendarFileWriter.close();
44    calendarFile.renameTo(new File("./cals/"+calendarFileName+".ics"))
45 
46    calList.add(calendarFileName+".ics")
47    calendarStream.close();
48}
49 
50println "Text to paste into Wordpress after uploading: "
51println "<ul>"
52Collections.sort(calList)
53calList.each {
54    println "<li><a href="https://blog.codecentric.de/en/2009/08/english-international-calendar-file-processing-its-groovy-2/">${it}</a></li>"
55}
56println "</ul>"
57 
58}}
|

Beitrag teilen

//

Weitere Artikel in diesem Themenbereich

Entdecke spannende weiterführende Themen und lass dich von der codecentric Welt inspirieren.

//

Gemeinsam bessere Projekte umsetzen.

Wir helfen deinem Unternehmen.

Du stehst vor einer großen IT-Herausforderung? Wir sorgen für eine maßgeschneiderte Unterstützung. Informiere dich jetzt.

Hilf uns, noch besser zu werden.

Wir sind immer auf der Suche nach neuen Talenten. Auch für dich ist die passende Stelle dabei.