1from pyparsing import Optional, oneOf, Literal, Word, printables, Group, OneOrMore, ZeroOrMore 2 3""" 4A simple parser for calendar (*.ics) files, 5as exported by the Mozilla calendar. 6 7Any suggestions and comments welcome. 8 9Version: 0.1 10Copyright: Petri Savolainen <firstname.lastname@iki.fi> 11License: Free for any use 12""" 13 14 15# TERMINALS 16 17BEGIN = Literal("BEGIN:").suppress() 18END = Literal("END:").suppress() 19valstr = printables + "\xe4\xf6\xe5\xd6\xc4\xc5 " 20 21EQ = Literal("=").suppress() 22SEMI = Literal(";").suppress() 23COLON = Literal(":").suppress() 24 25EVENT = Literal("VEVENT").suppress() 26CALENDAR = Literal("VCALENDAR").suppress() 27ALARM = Literal("VALARM").suppress() 28 29# TOKENS 30 31CALPROP = oneOf("VERSION PRODID METHOD") 32ALMPROP = oneOf("TRIGGER") 33EVTPROP = oneOf("X-MOZILLA-RECUR-DEFAULT-INTERVAL \ 34 X-MOZILLA-RECUR-DEFAULT-UNITS \ 35 UID DTSTAMP LAST-MODIFIED X RRULE EXDATE") 36 37propval = Word(valstr) 38typeval = Word(valstr) 39typename = oneOf("VALUE MEMBER FREQ UNTIL INTERVAL") 40 41proptype = Group(SEMI + typename + EQ + typeval).suppress() 42 43calprop = Group(CALPROP + ZeroOrMore(proptype) + COLON + propval) 44almprop = Group(ALMPROP + ZeroOrMore(proptype) + COLON + propval) 45evtprop = Group(EVTPROP + ZeroOrMore(proptype) + COLON + propval).suppress() \ 46 | "CATEGORIES" + COLON + propval.setResultsName("categories") \ 47 | "CLASS" + COLON + propval.setResultsName("class") \ 48 | "DESCRIPTION" + COLON + propval.setResultsName("description") \ 49 | "DTSTART" + proptype + COLON + propval.setResultsName("begin") \ 50 | "DTEND" + proptype + COLON + propval.setResultsName("end") \ 51 | "LOCATION" + COLON + propval.setResultsName("location") \ 52 | "PRIORITY" + COLON + propval.setResultsName("priority") \ 53 | "STATUS" + COLON + propval.setResultsName("status") \ 54 | "SUMMARY" + COLON + propval.setResultsName("summary") \ 55 | "URL" + COLON + propval.setResultsName("url") \ 56 57calprops = Group(OneOrMore(calprop)).suppress() 58evtprops = Group(OneOrMore(evtprop)) 59almprops = Group(OneOrMore(almprop)).suppress() 60 61alarm = BEGIN + ALARM + almprops + END + ALARM 62event = BEGIN + EVENT + evtprops + Optional(alarm) + END + EVENT 63events = Group(OneOrMore(event)) 64calendar = BEGIN + CALENDAR + calprops + ZeroOrMore(event) + END + CALENDAR 65calendars = OneOrMore(calendar) 66 67 68# PARSE ACTIONS 69 70def gotEvent(s,loc,toks): 71 for event in toks: 72 print(event.dump()) 73 74event.setParseAction(gotEvent) 75 76 77# MAIN PROGRAM 78 79if __name__=="__main__": 80 81 calendars.parseFile("mozilla.ics") 82