calitems.py
changeset 304: 9099246ab759
parent 302:03c221a1f62a
child 317:aac29f4d7588
manifest: 9099246ab759
author: Dan Connolly http://www.w3.org/People/Connolly/
date: Wed Sep 12 15:39:03 2007 -0500 (8 months ago)
permissions: -rw-r--r--
handle flight timezones better
        1 """ calitems.py -- convert RDF calendar to danger JSON
        2 
        3 Usage::
        4 
        5   $ export PYTHONPATH=~/src/swap
        6   $ python calitems.py mycal.rdf > mycal.json
        7   $ python calitems.py --test
        8 
        9 See also doctests for `eachEvent`.
       10 
       11 """
       12 
       13 import simplejson
       14 
       15 from swap import uripath  # http://www.w3.org/2000/10/swap/
       16 from swap.myStore import Namespace, load
       17 
       18 import hipsrv # hmm... move asHiptopDate here?
       19 
       20 def eachEvent(kb, float_tz='America/Chicago'):
       21     """iterate over events in RDF kb, returning danger-style JSON
       22 
       23     @param float_tz: local timezone of the device at the
       24       time of insert/post... at least... I think... it
       25       sure seems wierd.
       26 
       27     supports timed events only
       28     summary, dtstart required
       29     loc, description optional
       30 
       31     >>> kb = _s2f(TestLocal, "http://example/cal1")
       32     >>> e = eachEvent(kb).next()
       33     >>> sorted(e.keys())
       34     ['end_date', 'event_type', 'location', 'notes', 'repeat_type', 'start_date', 'timezone', 'title']
       35     >>> e['notes']
       36     u'Aug. 25 (Saturday) 318 08:00 1215 Yellow Dragons v 1216 BVSC Dragons Community Park West'
       37     >>> e['start_date']
       38     '20070825T130000Z'
       39 
       40     >>> kb = _s2f(TestUTC, "http://example/cal2")
       41     >>> e = eachEvent(kb).next()
       42     >>> sorted(e.keys())
       43     ['end_date', 'event_type', 'notes', 'repeat_type', 'start_date', 'timezone', 'title']
       44     >>> e['notes']
       45     u'2007-09-15 lv PHL 20:40 ar GLA 08:35 SUNDAY US AIRWAYS #768'
       46     >>> e['start_date']
       47     u'20070916T004000Z'
       48     >>> e['timezone']
       49     'America/Chicago'
       50 
       51     """
       52 
       53     # @# these should be module constants, but myStore global
       54     # wierdness seems to interfere.
       55     RDF = Namespace("http://www.w3.org/1999/02/22-rdf-syntax-ns#")
       56     ICAL = Namespace('http://www.w3.org/2002/12/cal/icaltzd#')
       57 
       58     for ev in kb.each(pred = RDF.type, obj = ICAL.Vevent):
       59         titl = unicode(kb.the(subj = ev, pred = ICAL.summary) or '').strip()
       60 
       61         tz = float_tz
       62         dtstart = unicode(kb.the(subj = ev, pred = ICAL.dtstart))
       63         dtend = unicode(kb.the(subj = ev, pred = ICAL.dtend) or '')
       64         
       65         loc = unicode(kb.any(subj = ev, pred = ICAL.location) or '')
       66 
       67         desc = unicode(kb.any(subj = ev, pred = ICAL.description) or '')
       68         desc = ' '.join(desc.split()) # a la xslt normalize-space
       69 
       70 	ety = 1 # timed (not all day), end time (not dur)
       71 
       72 	if not "T" in dtstart: # all-day event
       73 	    ety = 2
       74             tz = None
       75 	    dtstart = "%sT000000Z" % (dtstart.replace("-", ""))
       76 	    if dtend:
       77 		dtend = "%sT000000Z" % (dtend.replace("-", ""))
       78 	elif dtstart.endswith("Z"):
       79             dtstart=dtstart.replace("-", "").replace(":", "")
       80             if dtend:
       81                 dtend=dtend.replace("-", "").replace(":", "")
       82             else:
       83                 dtend=dtstart # hmm... plus 1 hour?
       84         else:
       85 	    dtstart = hipsrv.asHiptopDate(dtstart, tz)
       86             if dtend:
       87                 dtend = hipsrv.asHiptopDate(dtend, tz)
       88             else:
       89                 dtend=dtstart # hmm... plus 1 hour?
       90 
       91 	rec = {
       92             'title': titl,
       93             'start_date': dtstart,
       94             'end_date': dtend,
       95             'notes': desc,
       96             'repeat_type': 0,
       97             'event_type': ety,
       98             }
       99         if tz: rec['timezone'] = tz
      100 	if loc: rec['location'] = loc
      101 
      102         yield rec
      103 
      104 def fn2kb(fn):
      105     import os
      106     addr = uripath.join("file:" + os.getcwd() + "/", fn)
      107     return load(addr)
      108     
      109 def main(argv):
      110     kb = fn2kb(argv[1])
      111     print "@@", kb.size()
      112     print "["
      113     first = True
      114     for e in eachEvent(kb):
      115         if first:
      116             first = False
      117         else:
      118             print ", ",
      119         print simplejson.dumps(e)
      120     print "]"
      121 
      122 
      123 
      124 def _s2f(s, base):
      125     """make a formula from a string.
      126 
      127     Cribbed from llyn.BI_parsedAsN3
      128     should be part of the myStore API, no? yes. TODO
      129 
      130     >>> _s2f("<#sky> <#color> <#blue>.", "http://example/socrates")
      131     {sky color blue}
      132 
      133     ^ that test output depends on the way formulas print themselves.
      134     """
      135     # """ emacs python mode needs help
      136 
      137     from swap.notation3 import SinkParser
      138     from swap.myStore import formula
      139     
      140     graph = formula()
      141     p = SinkParser(graph.store, openFormula=graph, baseURI=base,
      142                    thisDoc="data:@@some-formula-string")
      143     p.startDoc()
      144     p.feed(s)
      145     f = p.endDoc()
      146     f.close()
      147     return f
      148 
      149 
      150 TestLocal = """
      151      @prefix : <http://www.w3.org/2002/12/cal/icaltzd#> .
      152     
      153     <>     a :Vcalendar;
      154          :component  [
      155              a :Vevent;
      156              :description "Aug. 25 (Saturday) 318 08:00 1215 Yellow Dragons v 1216 BVSC Dragons Community Park West";
      157              :dtstart "2007-08-25T08:00:00"^^:dateTime;
      158              :location "Community Park West";
      159              :summary "Soccer Game 1215 Yellow Dragons v 1216 BVSC Dragons";
      160              :url <> ].
      161 
      162 """
      163 
      164 
      165 TestUTC = """
      166     @prefix : <http://www.w3.org/2006/vcard/ns#> .
      167     @prefix SUMO: <http://www.ontologyportal.org/translations/SUMO.owl.txt#> .
      168     @prefix XML: <http://www.w3.org/2001/XMLSchema#> .
      169     @prefix c: <http://www.w3.org/2002/12/cal/icaltzd#> .
      170     @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
      171     @prefix sou: <http://www.w3.org//2007/07dc-lhr/sou19#> .
      172 
      173     sou:ee139866156     a c:Vevent;
      174          SUMO:destination <,2sou19.rdf#GLA>;
      175          SUMO:origin <,2sou19.rdf#PHL>;
      176          c:description "2007-09-15 lv PHL 20:40 ar GLA 08:35 SUNDAY US AIRWAYS #768";
      177          c:dtend "2007-09-16T07:35:00Z"^^XML:dateTime;
      178          c:dtstart "2007-09-16T00:40:00Z"^^XML:dateTime;
      179          c:summary "US AIRWAYS #768";
      180          c:url <https://bwi.flightview.com/fvSabreVT/fvCPL.exe?vthost=1W&acid=76
      181 8&qtype=htm&AL=US&Find1=Track+Flight> .
      182 """
      183 
      184 
      185 def _test():
      186     import doctest
      187     doctest.testmod()
      188 
      189 if __name__ == "__main__":
      190     import sys
      191 
      192     if '--test' in sys.argv:
      193         _test()
      194     else:
      195         main(sys.argv)