hacking soccer schedules into hCalendar and into my sidekick
When I gave a microformats+GRDDL talk early this month, I listed my kid's soccer schedules on my wish list slide.
Those soccer schedules are now available. No matter how badly I need them in my sidekick calendar in order to coordinate other family activities, I couldn't bear the thought of manually keying them in. The bane of my existence is doing things that I know the computer could do for me.1998,2002
One of the schedules is in PDF. I toyed with a PDF to excel converter and with google's "view as HTML" cache feature but didn't get very far with those. But the other schedule is on a normal database-backed web site.
It took just 91 lines of XSLT to put hCalendar markup to the page. Each event was a row; I added a tbody element around each row so that I could use the row element as the class="description" element. I used an ASP recipie to figure out how to just add an attribute here and there and leave the rest alone. I didn't get the AM/PM XSLT code right the first time; silly, since I've written it before; I should have copied it, if not factored it out for reuse.
My PDA/cellphone is a t-mobile sidekick. There's a very nice XMLRPC interface to the data, but it went read-only and it's not supported, so I use a ClientForm screen-scraping hack to upload flight schedules and such to my PDA. hipAgent.py (in my palmagent project) gets its data thru a simple command-line interface or thru tab-separated text files. I had a set of eventlines.n3 rules for reducing RDF calendar data to tab-separated format, but its timezone support is quirky and it doesn't handle multi-line descriptions. So I bit the bullet and integrated cwm's RDF reader via the simple myStore API into hipAgent.py. I was simple enough:
elif o in ("--importRDF",): import uripath, os from myStore import load # http://www.w3.org/2000/10/swap/ addr = uripath.join("file:" + os.getcwd() + "/", a) kb = load(addr) importTimedRDF(number, passwd, kb, icon ... from myStore import Namespace RDF = Namespace("http://www.w3.org/1999/02/22-rdf-syntax-ns#") ICAL = Namespace('http://www.w3.org/2002/12/cal/icaltzd#') for ev in kb.each(pred = RDF.type, obj = ICAL.Vevent): titl = unicode(kb.the(subj = ev, pred = ICAL.summary)).encode("utf-8") progress("== found event:", titl) when = str(kb.the(subj = ev, pred = ICAL.dtstart)) dt = when[:10] ti = when[11:16] loc = kb.any(subj = ev, pred = ICAL.location) if loc: loc = unicode(loc).encode("utf-8") desc = kb.any(subj = ev, pred = ICAL.description) if desc: desc = unicode(desc).encode("utf-8") progress("a.addTimedEvent", dt, ti) a.addTimedEvent(dt, ti, titl, desc, 'minutes', 60, #@@hardcoded where=loc)
So I succesfully loaded son's soccer schedule into my sidekick PDA calendar:
- GET the schedule
- tidy it
- add hCalendar markup (vevent, description, summary dtstart, location) using XSLT
- convert to RDF/XML using a GRDDL transform for hCalendar, glean-hcal.xsl
- load into sidekick using hipAgent.py
The folks running the DB-backed web site could add hCalendar markup with even less hassle then I did (though they might have to think a little bit to produce well-formed XHTML), at which point I could reduce the first 4 steps with GRDDL (either via remote service or by adding GRDDL support to hipAgent.py or to cwm's myStore.load() function).