c# - Parsing Google calendar to DDay.iCal -


i'm working on application parses google calendar via google api dday.ical

the main attributes, properties handled easily... ev.summary = evt.title.text;

the problem when got recurring event, xml contains field like:

<gd:recurrence>     dtstart;value=date:20100916     dtend;value=date:20100917     rrule:freq=yearly </gd:recurrence> 

or

<gd:recurrence>   dtstart:20100915t220000z   dtend:20100916t220000z   rrule:freq=yearly;bymonth=9;wkst=su" </gd:recurrence> 

using following code:

    string[] lines =  evt.recurrence.value.split(new char[] { '\n', '\r' }, stringsplitoptions.removeemptyentries);                      foreach (string line in lines)                     {                          if (line.startswith("r"))                         {                             recurrencepattern rp = new recurrencepattern(line);                             ev.recurrencerules.add(rp);                         }                         else                          {                             iserializationcontext ctx = new serializationcontext();                             iserializerfactory factory = new dday.ical.serialization.icalendar.serializerfactory();                              icalendarproperty property = new calendarproperty();                              istringserializer serializer = factory.build(property.gettype(), ctx) istringserializer;                              property = (icalendarproperty)serializer.deserialize(new stringreader(line));                              ev.properties.add(property);                             console.out.writeline(property.name + " - " + property.value);                         }                      } 

rrules parsed correctly, problem other property (datetimes) values empty...

here starting point of i'm doing, going off of the rfc-5545 spec's recurrence rule. isn't complete spec , may break given input, should going. think should doable using regex, , heavy recursive decent parser overkill.

rrule:(?:freq=(daily|weekly|secondly|minutely|hourly|daily|weekly|monthly|yearly);)?(?:count=([0-9]+);)?(?:interval=([0-9]+);)?(?:byday=([a-z,]+);)?(?:until=([0-9]+);)?

i building using http://regexstorm.net/tester.

the test input i'm using is:

dtstart;tzid=america/chicago:20140711t133000\ndtend;tzid=america/chicago:20140711t163000\nrrule:freq=weekly;interval=8;byday=fr;until=20141101

dtstart;tzid=america/chicago:20140711t133000\ndtend;tzid=america/chicago:20140711t163000\nrrule:freq=weekly;count=5;interval=8;byday=fr;until=20141101

dtstart;tzid=america/chicago:20140711t133000\ndtend;tzid=america/chicago:20140711t163000\nrrule:freq=weekly;byday=fr;until=20141101

sample matching results like:

index    position    matched string                                                 $1      $2  $3  $4  $5 0        90          rrule:freq=weekly;interval=8;byday=fr;until=20141101           weekly      8   fr  20141101 1        236         rrule:freq=weekly;count=5;interval=8;byday=fr;until=20141101   weekly  5   8   fr  20141101 2        390         rrule:freq=weekly;byday=fr;until=20141101                      weekly          fr  20141101 

usage like:

string freqpattern = @"rrule:(?:freq=(daily|weekly|secondly|minutely|hourly|daily|weekly|monthly|yearly);?)?(?:count=([0-9]+);?)?(?:interval=([0-9]+);?)?(?:byday=([a-z,]+);?)?(?:until=([0-9]+);?)?"; matchcollection mc = regex.matches(rule, freqpattern, system.text.regularexpressions.regexoptions.ignorecase); foreach (match m in mc) {     string frequency = m.groups[1].tostring();     string count = m.groups[2].tostring();     string interval = m.groups[3].tostring();     string byday = m.groups[4].tostring();     string until = m.groups[5].tostring();     system.console.writeline("recurrence => frequency: \"{0}\", count: \"{1}\", interval: \"{2}\", byday: \"{3}\", until: \"{4}\"", frequency, count, interval, byday, until); } 

Comments