From 576edd66429ff3ef156b5d1a4904cdcac6058513 Mon Sep 17 00:00:00 2001 From: David Bartley Date: Sat, 2 Feb 2008 23:00:50 -0500 Subject: [PATCH] Convert xml2ics.pl to ics.xsl * Reduces build time by 30% * Remove perl and libxml-dom-perl dependency * Improved date/time handling * Improved text formating --- common.mk.in | 2 +- scripts/xml2ics.pl | 130 -------------------------------------------- scripts/xsltproc.py | 71 +++++++++++++++++++----- xsl/ics.xsl | 62 +++++++++++++++++++++ 4 files changed, 119 insertions(+), 146 deletions(-) delete mode 100755 scripts/xml2ics.pl create mode 100644 xsl/ics.xsl diff --git a/common.mk.in b/common.mk.in index 53ee214..ec3d455 100644 --- a/common.mk.in +++ b/common.mk.in @@ -33,7 +33,7 @@ $(OUTDIR)%.atom: %.xml xsl/atom.xsl $(XSLTPROC) $< $(ROOT)/xsl/atom.xsl $@ $(XSLTARGS) $(OUTDIR)%.ics: %.xml - perl scripts/xml2ics.pl $< > $@ + $(XSLTPROC) $< $(ROOT)/xsl/ics.xsl $@ $(XSLTARGS) $(OUTDIR)%.html: %.html cp -f $< $@ diff --git a/scripts/xml2ics.pl b/scripts/xml2ics.pl deleted file mode 100755 index 7274a8c..0000000 --- a/scripts/xml2ics.pl +++ /dev/null @@ -1,130 +0,0 @@ -#!/usr/bin/perl - -use XML::DOM; -use strict; - -# get the first element under a node of the given tag -# @param node: node under which to look for elements -# @param tag: the tage to look for -# @return: first element under node with the given tag -sub subvalue($$) -{ - my ($class, $tag) = @_; - return value($class->getElementsByTagName($tag)->item(0)); -} - -# get the node value of the first child of a given node -# @param node: whose child to use -# @return: node value of given node's first child -sub value($) -{ - my ($class) = @_; - if (undef == $class) { return undef; } - - my $child = $class->getFirstChild(); - - if (undef == $child) { - return undef; - } - - return $child->getNodeValue(); -} - -print <new(); -my $doc = $parser->parsefile($ARGV[0]); -my @events = $doc->getElementsByTagName("eventitem"); - -foreach my $event (@events) { - my $date = $event->getAttribute("date"); - my $time = $event->getAttribute("time"); - my $talk_title = $event->getAttribute("title"); - $talk_title =~ s/[:;,]//g; - - my $room = $event->getAttribute("room"); - - my $short = subvalue($event, "short"); - $short =~ s/[:;,]//g; - my $abstract = $event->getElementsByTagName("abstract")->item(0)->toString(); - - my $ical_date = `date -d"$date" +%Y%m%d`; - chomp $ical_date; - - my ($ical_start, $ical_end); - - if ($time =~ /(.*)-(.*)/) { - $ical_start = ical_time($1); - $ical_end = ical_time($2); - } else { - $ical_start = ical_time($time); - $ical_end = ical_time("$time + 1 hour"); - } - - $abstract =~ s///; - $abstract =~ s/<\/abstract>//; - $abstract =~ s/\n/ /sg; - - my $ical_abstract = "\"$abstract\""; - -sub ical_time { - my ($ds) = @_; - my $d = `date -d"$ds" +\%H\%M\%S`; - chomp $d; - return $d; -} - -print <$talk_title -- $short -DESCRIPTION:$ical_abstract -END:VEVENT -END_OF_EVENT -} - -print "END:VCALENDAR\n"; - - - - - - - diff --git a/scripts/xsltproc.py b/scripts/xsltproc.py index 1289892..f31bb7e 100755 --- a/scripts/xsltproc.py +++ b/scripts/xsltproc.py @@ -1,5 +1,5 @@ #!/usr/bin/python -import os, sys, urllib, libxml2, libxslt, ldap, time +import os, sys, urllib, libxml2, libxslt, ldap, time, datetime, re # # globals @@ -24,6 +24,12 @@ cscPositions = { } cscYesNo = { True : 'yes', False : 'no' } +def xslArgToString(arg): + if type(arg) == type([]): + return libxml2.xmlNode(arg[0]).getContent() + else: + return arg + # # cscLdapConnect # @@ -35,29 +41,27 @@ def cscLdapConnect(): # # csc:encode-for-uri # -def cscEncodeForUri(ctx, arg): - if type(arg) == type([]): - arg = libxml2.xmlNode(arg[0]).getContent() - return urllib.quote(arg) +def cscEncodeForUri(ctx, uri): + uri = xslArgToString(uri) + return urllib.quote(uri) # # csc:term # -def cscTerm(ctx, arg): - if type(arg) == type([]): - arg = libxml2.xmlNode(arg[0]).getContent() +def cscTerm(ctx, date): + date = xslArgToString(date) try: - [year, month, day] = arg.split("-") + [year, month, day] = date.split("-") term = (int(month) - 1) / 4 return cscTerms[term] + " " + year except: - print "Invalid term '%s'" % arg + print "Invalid date '%s'" % date raise # # csc:member-list # -def cscMemberList(ctx, arg): +def cscMemberList(ctx, _): try: if cscLdap == None: cscLdapConnect() @@ -83,7 +87,7 @@ def cscMemberList(ctx, arg): # # csc:position-list # -def cscPositionList(ctx, arg): +def cscPositionList(ctx, _): try: if cscLdap == None: cscLdapConnect() @@ -119,12 +123,46 @@ def cscPositionList(ctx, arg): print e raise +# +# csc:ical-datetime +# +def cscIcalDatetime(ctx, date, time, addmin = "0"): + date = xslArgToString(date) + time = xslArgToString(time) + addmin = int(xslArgToString(addmin)) + r = re.search("(\d*)-(\d*)-(\d*)", date) + year, month, day = 0, 0, 0 + if r != None: + year, month, day = (int(i) for i in r.groups()) + r = re.search("(\d*):(\d*)\s*([apAP])", time) + hour, minute = (0, 0) + if r != None: + hour, minute = (int(i) for i in r.groups()[:2]) + if r.group(3) in 'pP': + hour += 12 + dt = datetime.datetime(year, month, day, hour, minute) + dt += datetime.timedelta(0, 0, 0, 0, addmin) + return dt.strftime("%Y%m%dT%H%M%S") + +# +# csc:ical-escape +# +def cscIcalEscape(ctx, str): + str = xslArgToString(str) + str = str.replace("\n", " ") + str = str.replace(":", "") + str = str.replace(";", "") + str = str.replace(",", "") + str = re.sub("\s+", " ", str) + str = re.sub("^\s+", "", str) + str = re.sub("\s+$", "", str) + return str + # # csc:email # -def cscEmail(ctx, arg): - if type(arg) == type([]): - str = libxml2.xmlNode(arg[0]).getContent() +def cscEmail(ctx, email): + email = xslArgToString(email) return "_EMAIL_TODO_" # @@ -156,6 +194,8 @@ try: libxslt.registerExtModuleFunction("term", cscUri, cscTerm) libxslt.registerExtModuleFunction("member-list", cscUri, cscMemberList) libxslt.registerExtModuleFunction("position-list", cscUri, cscPositionList) + libxslt.registerExtModuleFunction("ical-datetime", cscUri, cscIcalDatetime) + libxslt.registerExtModuleFunction("ical-escape", cscUri, cscIcalEscape) libxslt.registerExtModuleFunction("email", cscUri, cscEmail) # parse xml/xslt and apply style-sheet @@ -166,4 +206,5 @@ try: ret = style.saveResultToFilename(outFile, res, 0) except Exception, e: + print e sys.exit(1) diff --git a/xsl/ics.xsl b/xsl/ics.xsl new file mode 100644 index 0000000..e05ee77 --- /dev/null +++ b/xsl/ics.xsl @@ -0,0 +1,62 @@ + + + + +BEGIN:VCALENDAR +VERSION:2.0 +X-WR-CALNAME:University of Waterloo Computer Science Club +PRODID:-//Apple Computer, Inc//iCal 2.0//EN +X-WR-RELCALID:3359A191-B19E-4B53-BADC-DFC084FC51C9 +X-WR-TIMEZONE:Canada/Eastern +CALSCALE:GREGORIAN +METHOD:PUBLISH +BEGIN:VTIMEZONE +TZID:Canada/Eastern +LAST-MODIFIED:20060912T200739Z +BEGIN:DAYLIGHT +DTSTART:20060301T070000 +TZOFFSETTO:-0400 +TZOFFSETFROM:+0000 +TZNAME:EDT +END:DAYLIGHT +BEGIN:STANDARD +DTSTART:20061029T020000 +TZOFFSETTO:-0500 +TZOFFSETFROM:-0400 +TZNAME:EST +END:STANDARD +BEGIN:DAYLIGHT +DTSTART:20070311T010000 +TZOFFSETTO:-0400 +TZOFFSETFROM:-0500 +TZNAME:EDT +END:DAYLIGHT +END:VTIMEZONE + +END:VCALENDAR + + + + + + + + + +BEGIN:VEVENT +LOCATION:University of Waterloo - +DTSTAMP:20060912T200708Z +UID:@csclub.uwaterloo.ca +SEQUENCE:11 +DTSTART;TZID=Canada/Eastern: +DTEND;TZID=Canada/Eastern: +SUMMARY: -- +DESCRIPTION: +END:VEVENT + + +