def visit_vtimezone(self,ics): tz = CNode(name='TimeZone') baseoffset_e = CNode(name='BaseOffset',content='PT0M') tz.add_child(baseoffset_e) if len(ics.children) == 1: # Just add a base offset std_e = ics.children[0] # TODO: fix this else: tz_s = self.__convert_timezone(ics.search('standard')) tz.add_child(tz_s) tz_d = self.__convert_timezone(ics.search('daylight')) tz.add_child(tz_d) tzid = gen_tz_id(tz) tz.attr['TimeZoneName'] = tzid tzid_e = CNode(name='tzid',content=tzid) tz.add_child(tzid_e) self.timezone_ids[ics.attr['tzid']] = tzid return tz
def maybe_date2ics(dt): """If dt is a date, convert it to a VALUE=DATE:somedate ical value""" if type(dt) == datetime.date: n = CNode('with-attr', content=dt) n.attr['value'] = 'DATE' return n else: return dt
def _create_field_uri(self,uri): """Add a field URI to updates. Warning: An item corresponding to `uri' must be added to self.updates after a call to this method """ u = CNode('FieldURI') u.attr['FieldURI'] = uri return u
def timeconv(dt): # (See erebusconv.py) maybe_cnode = maybe_date2ics(dt) if type(maybe_cnode) == CNode: return maybe_cnode else: c = CNode('with_attr', content=dt) c.attr['tzid'] = tzid.content return c
def __init__(self,cnode): self.calendar = CNode(name='calendar') self.timezones = CNode(name='timezones') self.timezone_ids = {} self.events = CNode(name='events') self.calendar.add_child(self.timezones) self.calendar.add_child(self.events) ToLowerCaseVisitor().visit(cnode) self.ics = cnode
def visit_any(self,eci): """Copy the entire tree from here""" if eci.name == 'MeetingTimeZone': new_name = 'TimeZone' else: new_name = eci.name ci = CNode(name=new_name) ci.content = eci.content for c in eci.children: ci.add_child(self.visit(c)) return ci
def __convert_timezone(self,ics): if ics.name == 'standard': tz_e = CNode(name='Standard') elif ics.name == 'daylight': tz_e = CNode(name='Daylight') else: raise ValueError("Unknown timezone type: %s", ics.name) offset = utcoffset2vDDD(ics.attr['tzoffsetto'], negate=True) offset_e = CNode(name='Offset',content=offset) tz_e.add_child(offset_e) rrule = ics.attr['rrule'] start = ics.attr['dtstart'] if rrule: rec = rrule2recurrence(rrule, start) tz_e.add_child(rec.children[0]) time = start.dt timestr = "%.2d:%.2d:%.2d" %(time.hour, time.minute, time.second) time_e = CNode(name='Time',content=timestr) tz_e.add_child(time_e) return tz_e
def __init__(self,cnode): self.calendar = CNode(name='calendar') self.timezones = CNode(name='timezones') self.events = CNode(name='events') self.calendar.add_child(self.timezones) self.calendar.add_child(self.events) # Strip namespace from cnode StripNamespaceVisitor().visit(cnode) self.ews_calendaritems = [] for item in cnode.search('CalendarItem',all=True,keep_depth=True): self.ews_calendaritems.append(item)
def visit_any(self,e): """Check the trans table""" if self.trans.has_key(e.name): (p,c) = self._make_parent(['CalendarItem']) c.add_child(e) uri = self._create_field_uri(self.trans[e.name]) setitem = CNode('SetItemField') setitem.add_child(uri) setitem.add_child(p) self.updates.add_child(setitem) # Visit children for c in e.children: self.visit(c)
def visit_event(self,cnode): e = CNode('vevent') def conv(ebus, icaln, f): if not cnode.attr.has_key(ebus): return ebus_v = cnode.attr[ebus] new = f(ebus_v) #if not new: return e.attr[icaln] = new conv('summary', 'summary', identity) conv('class', 'class', identity) conv('location', 'location', identity) conv('description', 'description', identity) tzid = cnode.search('tzid') if not tzid: # just copy timeconv = maybe_date2ics else: def timeconv(dt): # (See erebusconv.py) maybe_cnode = maybe_date2ics(dt) if type(maybe_cnode) == CNode: return maybe_cnode else: c = CNode('with_attr', content=dt) c.attr['tzid'] = tzid.content return c conv('timestamp', 'dtstamp', timeconv) conv('start', 'dtstart', timeconv) conv('end', 'dtend', timeconv) # get uid (if exchange type) itemid = cnode.search('exchange_id') if itemid: e.attr['uid'] = "*****@*****.**" % itemid.attr['id'] rec = cnode.search('Recurrence') if rec: rrule = self.visit(rec) e.attr['rrule'] = rrule.attr['rrule'] return e
def Insert(self, data, flag = 1): node = CNode(data,None,None) if self.__size == 0: self.__current = self.__first = self.__last = node self.__size += 1 elif flag == 0: self.__size += 1 ##################### #add a la izquierda # ##################### #como insertamos a izquierda, el nodo derecho sera current node.setRight(self.__current) #cogemos el nodo izquierdo a current if self.__current != self.__first: leftApunt = self.__current.getLeft() #se lo asignamos al node node.setLeft(leftApunt) #asignamos node al que antes era nodo izquierdo de current leftApunt.setRight(node) #asignamos node como nodo a la izquierda de current self.__current.setLeft(node) #y asignamos current al nuevo node if self.__current == self.__first: self.__current = node self.__first = self.__current else: self.__current = node elif flag == 1: self.__size += 1 ##################### #add a la derecha # ##################### #como insertamos a la derecha, el nodo izquierdo sera current node.setLeft(self.__current) if self.__last != self.__current: rightApunt = self.__current.getRight() #se lo asignamos a node node.setRight(rightApunt) #asignamos node al que antes era nodo derecho de current rightApunt.setLeft(node) #asignamos node como nodo a la derecha de current self.__current.setRight(node) #y asignamos current al nuevo node if self.__current == self.__last: self.__current = node self.__last = self.__current else: self.__current = node else: print 'Flag erroneo'
def xml2cnode(xml): """Convert an arbitrary xml structure to a tree of cnodes xml: xml.etree.ElementTree.Element type return: CNode """ r = CNode(name=xml.tag) r.content = xml.text for k,v in xml.attrib.iteritems(): r.attr[k] = v for c in xml.getchildren(): e = xml2cnode(c) r.add_child(e) return r
def __convert_timezone(self,e_tz,name,base_offset): tz_e = CNode(name) offset_str = e_tz.search('Offset').content offset = (- vDDDTypes.from_ical(offset_str)) + base_offset tz_e.attr['tzoffsetto'] = offset _time = xs_time2time(e_tz.search('Time').content) dt = datetime(1970, 1, 1, _time.hour, _time.minute, _time.second) tz_e.attr['dtstart'] = dt rec = e_tz.children[1] if "Recurrence" in rec.name: rec = self.visit(self.__pack_recurrence(rec)) tz_e.attr['rrule'] = rec.attr['rrule'] else: raise ValueError("Did not find recurrence element in timezone") return tz_e
def ical2cnode(ical): """Convert an ical calendar to a tree of cnodes ical: icalendar.Calendar return CNode """ r = CNode(name=ical.name) for k,v in ical.iteritems(): r.attr[k] = v for child in ical.walk(): if child == ical: continue cnode = ical2cnode(child) if cnode.content != '': r.add_child(cnode) return r
def visit_Recurrence(self,rec_node): rec = CNode('recurrence') rec_pattern = rec_node.children[0] rec_range = rec_node.children[1] rrule = {} rec_type = rec_pattern.name if rec_type == 'DailyRecurrence': daily_recpattern2rrule(rec_node, rrule) elif rec_type == 'WeeklyRecurrence': weekly_recpattern2rrule(rec_node, rrule) elif rec_type == 'RelativeMonthlyRecurrence': rel_monthly_recpattern2rrule(rec_node, rrule) elif rec_type == 'AbsoluteMonthlyRecurrence': abs_monthly_recpattern2rrule(rec_node, rrule) elif rec_type == 'RelativeYearlyRecurrence': rel_yearly_recpattern2rrule(rec_node, rrule) elif rec_type == 'AbsoluteYearlyRecurrence': abs_yearly_recpattern2rrule(rec_node, rrule) else: raise ValueError("unknown recurrence pattern: %s" % rec_type) range_type = rec_range.content if range_type == 'NumberedRecurrence': count = rec_range.search('NumberOfOccurrences').content rrule['COUNT'] = count elif range_type == 'EndDateRecurrence': enddate = rec_range.search('EndDate').content rrule['UNTIL'] = xs_date2datetime(enddate) else: # NoEndRecurrence is the default in iCalendar pass rec.attr['rrule'] = rrule return rec
def _make_parent(self,path): """Make a "tree" of CNodes as a parent for an update value, Example: self._make_parent(['CalendarItem','Subject']) => a CNode('Subject') node with a CNode('CalendarItem') parent returns: (topmost parent, the last child), in the example: (the Subject CNode, the CalendarItem CNode) """ child = CNode(path.pop()) c = child while len(path): p = CNode(path.pop()) p.add_child(c) c = p parent = c return (parent, child)
def visit_vevent(self,ics): event = CNode(name='event') def conv(icaln, ebus, f): if not ics.attr.has_key(icaln): return ics_e = ics.attr[icaln] if not ics_e: return new = f(ics_e) if not new: return event.attr[ebus] = new conv('uid', 'ical_uid', identity) conv('summary', 'summary', identity) conv('dtstart', 'start', vDDD2dt) conv('dtend', 'end', vDDD2dt) conv('class', 'class', identity) conv('location', 'location', identity) conv('dtstamp', 'timestamp', vDDD2dt) conv('description', 'description', identity) if ics.attr.has_key('rrule'): rec = rrule2recurrence(ics.attr['rrule'], event.attr['start']) if rec: event.add_child(rec) rec_range = rrule2range(ics.attr['rrule'], event.attr['start']) rec.add_child(rec_range) if type(ics.attr['dtstart']) != datetime.date and \ ics.attr['dtstart'].params.has_key('tzid'): i_tzid = ics.attr['dtstart'].params['tzid'] tz = self.timezone_ids[i_tzid] tz_e = CNode(name='tzid',content=tz) event.add_child(tz_e) return event
def create_item(self, item): if not item.search('event'): return ewsitem = Erebus2EWSVisitor(item).run() xml = cnode2xml(ewsitem) print ToStringVisitor(with_types=True).visit(ewsitem) tmpnam= os.tmpnam() + '.xml' print "Writing query to " + tmpnam f = open(tmpnam,'w') f.write(ET.tostring(xml)) f.close() res = self.query.create_items(ET.tostring(xml)) cn = xml2cnode(ET.XML(res)) StripNamespaceVisitor().visit(cn) eid = CNode('exchange_id') itemid = cn.search('ItemId') eid.attr['id'] = itemid.attr['Id'] eid.attr['changekey'] = itemid.attr['ChangeKey'] return eid
def RegCmd(self, arg_strCmd, arg_strHelpInfo, arg_fCmdProc): oNodeArray = [] oKeywordArray = arg_strCmd.split(' ') #準備待註冊命令的節點串 for strKeyword in oKeywordArray: #新建一個節點 #strKeyword裡可能帶有$、[]等等特殊標識,由Node處理 if 0 < VOS.Len(strKeyword): oNode = CNode.CMD_Node(arg_strKeyword=strKeyword) oNodeArray.append(oNode) #串接起來 self.MakeCmdNodesLink(oNodeArray) def AppendCmdProc(arg_oNodeArray=None, arg_fCmdProc=None): if (None == arg_oNodeArray) or (None == arg_fCmdProc): return def GetLastRequiredNode(arg_oNodeArray=None): for oNode in reversed(arg_oNodeArray): if True == oNode.IsRequired(): return oNode return #獲取最後一個必填節點 oNode = GetLastRequiredNode(arg_oNodeArray) if None != oNode: oNode.m_fCmdProc = arg_fCmdProc return #加上回調函式 AppendCmdProc(oNodeArray, arg_fCmdProc) self.Insert(oNodeArray) return
def visit_any(self,eci): """Copy the entire tree from here""" if eci.name == 'TimeZone': new_name = 'MeetingTimeZone' else: new_name = eci.name ci = CNode(name=new_name) for k,v in eci.attr.iteritems(): ci.attr[k] = v if eci.content != None: ci.content = str(eci.content) else: ci.content = None for c in eci.children: ci.add_child(self.visit(c)) return ci
def rrule2yearly_recpattern(rrule,interval_e,event_start=None): """Convert a YEARLY iCalendar recurrence to Erebus RecurrencePattern rrule: the iCalendar recurrence rule interval_e: the interval element """ if rrule.has_key('byday') and rrule.has_key('bymonth'): recpattern = CNode(name='RelativeYearlyRecurrence') dow_e, weekindex_e = byday2rel_month(rrule['byday'][0]) if rrule['bymonth']: m = int(rrule['bymonth'][0]) month = ex_months[m] elif event_start: month = xsdt2ex_month(event_start) else: ValueError, "neither BYMONTH or event_start is available" month_e = CNode(name='Month', content=month) recpattern.add_child(dow_e) recpattern.add_child(weekindex_e) recpattern.add_child(month_e) else: recpattern = CNode(name='AbsoluteYearlyRecurrence') dtstart = event_start monthday = dtstart.day monthday_e = CNode(name='DayOfMonth', content=str(monthday)) month_e = dt2ex_month(event_start) recpattern.add_child(monthday_e) recpattern.add_child(month_e) return recpattern
def visit_TimeZone(self,cnode): standard = cnode.search('Standard') daylight = cnode.search('Daylight') tz_e = CNode('vtimezone') tz_e.attr['tzid'] = cnode.search('tzid').content base_offset_str = cnode.search('BaseOffset').content # Exchange does some wacky negation of its timezones base_offset = (- vDDDTypes.from_ical(base_offset_str)) if not standard and not daylight: # Make a timezone with the base offset only (required by # the rfc) std_e = CNode('standard') std_e.attr['tzoffsetfrom'] = base_offset std_e.attr['tzoffsetto'] = base_offset std_e.attr['dtstart'] = datetime(1970,01,01) tz_e.add_child(std_e) if standard: std_e = self.__convert_timezone(standard,'standard',base_offset) tz_e.add_child(std_e) if daylight: dayl_e = self.__convert_timezone(daylight,'daylight',base_offset) tz_e.add_child(dayl_e) # Set offsetfrom both ways std_e.attr['tzoffsetfrom'] = dayl_e.attr['tzoffsetto'] dayl_e.attr['tzoffsetfrom'] = std_e.attr['tzoffsetto'] else: std_e.attr['tzoffsetfrom'] = vDDDTypes.from_ical('PT0M') return tz_e
def rrule2range(rrule, starttime): """Convert a rrule to a RecurrenceRange tree""" startdate = datetime2xsdt(starttime) startdate = xs_dateTime2xs_date(startdate) startdate_e = CNode('StartDate',content=startdate) if rrule.has_key('count'): recrange = CNode('NumberedRecurrence') count_e = CNode('NumberOfOccurences', content=rrule['count']) recrange.add_child(startdate_e) recrange.add_child(count_e) elif rrule.has_key('until'): recrange = CNode('EndDateRecurrence') enddate = ical2xsdt(rrule['until']) enddate = xs_dateTime2xs_date(enddate) enddate_e = CNode('EndDate',content=enddate) recrange.add_child(startdate_e) recrange.add_child(enddate_e) else: recrange = CNode('NoEndRecurrence') recrange.add_child(startdate_e) return recrange
def __pack_recurrence(self,rec_element): rec = CNode('Recurrence') rec.add_child(rec_element) rec.add_child(CNode('NoEndRecurrence')) return rec
def run(self): self.ews = Erebus2SimpleEWSVisitor(self.ebus).run() self.updates = CNode('Updates') self.visit(self.ews) AddNamespaceVisitor(self.updates,types).run() return self.updates
def __init__(self,cnode=None): self.ebus = cnode self.cal = CNode('vcalendar') self.cal.attr['prodid'] = '-//Erebus//hig.no//' self.cal.attr['version'] = '2.0'
class Erebus2ICSVisitor(CNodeVisitor): def __init__(self,cnode=None): self.ebus = cnode self.cal = CNode('vcalendar') self.cal.attr['prodid'] = '-//Erebus//hig.no//' self.cal.attr['version'] = '2.0' def run(self, ebus=None): if ebus: self.ebus = ebus for tz in self.accept(self.ebus, 'TimeZone'): self.cal.add_child(tz) for e in self.accept(self.ebus, 'event'): self.cal.add_child(e) return self.cal def __pack_recurrence(self,rec_element): rec = CNode('Recurrence') rec.add_child(rec_element) rec.add_child(CNode('NoEndRecurrence')) return rec def __convert_timezone(self,e_tz,name,base_offset): tz_e = CNode(name) offset_str = e_tz.search('Offset').content offset = (- vDDDTypes.from_ical(offset_str)) + base_offset tz_e.attr['tzoffsetto'] = offset _time = xs_time2time(e_tz.search('Time').content) dt = datetime(1970, 1, 1, _time.hour, _time.minute, _time.second) tz_e.attr['dtstart'] = dt rec = e_tz.children[1] if "Recurrence" in rec.name: rec = self.visit(self.__pack_recurrence(rec)) tz_e.attr['rrule'] = rec.attr['rrule'] else: raise ValueError("Did not find recurrence element in timezone") return tz_e def visit_TimeZone(self,cnode): standard = cnode.search('Standard') daylight = cnode.search('Daylight') tz_e = CNode('vtimezone') tz_e.attr['tzid'] = cnode.search('tzid').content base_offset_str = cnode.search('BaseOffset').content # Exchange does some wacky negation of its timezones base_offset = (- vDDDTypes.from_ical(base_offset_str)) if not standard and not daylight: # Make a timezone with the base offset only (required by # the rfc) std_e = CNode('standard') std_e.attr['tzoffsetfrom'] = base_offset std_e.attr['tzoffsetto'] = base_offset std_e.attr['dtstart'] = datetime(1970,01,01) tz_e.add_child(std_e) if standard: std_e = self.__convert_timezone(standard,'standard',base_offset) tz_e.add_child(std_e) if daylight: dayl_e = self.__convert_timezone(daylight,'daylight',base_offset) tz_e.add_child(dayl_e) # Set offsetfrom both ways std_e.attr['tzoffsetfrom'] = dayl_e.attr['tzoffsetto'] dayl_e.attr['tzoffsetfrom'] = std_e.attr['tzoffsetto'] else: std_e.attr['tzoffsetfrom'] = vDDDTypes.from_ical('PT0M') return tz_e def visit_event(self,cnode): e = CNode('vevent') def conv(ebus, icaln, f): if not cnode.attr.has_key(ebus): return ebus_v = cnode.attr[ebus] new = f(ebus_v) #if not new: return e.attr[icaln] = new conv('summary', 'summary', identity) conv('class', 'class', identity) conv('location', 'location', identity) conv('description', 'description', identity) tzid = cnode.search('tzid') if not tzid: # just copy timeconv = maybe_date2ics else: def timeconv(dt): # (See erebusconv.py) maybe_cnode = maybe_date2ics(dt) if type(maybe_cnode) == CNode: return maybe_cnode else: c = CNode('with_attr', content=dt) c.attr['tzid'] = tzid.content return c conv('timestamp', 'dtstamp', timeconv) conv('start', 'dtstart', timeconv) conv('end', 'dtend', timeconv) # get uid (if exchange type) itemid = cnode.search('exchange_id') if itemid: e.attr['uid'] = "*****@*****.**" % itemid.attr['id'] rec = cnode.search('Recurrence') if rec: rrule = self.visit(rec) e.attr['rrule'] = rrule.attr['rrule'] return e def visit_Recurrence(self,rec_node): rec = CNode('recurrence') rec_pattern = rec_node.children[0] rec_range = rec_node.children[1] rrule = {} rec_type = rec_pattern.name if rec_type == 'DailyRecurrence': daily_recpattern2rrule(rec_node, rrule) elif rec_type == 'WeeklyRecurrence': weekly_recpattern2rrule(rec_node, rrule) elif rec_type == 'RelativeMonthlyRecurrence': rel_monthly_recpattern2rrule(rec_node, rrule) elif rec_type == 'AbsoluteMonthlyRecurrence': abs_monthly_recpattern2rrule(rec_node, rrule) elif rec_type == 'RelativeYearlyRecurrence': rel_yearly_recpattern2rrule(rec_node, rrule) elif rec_type == 'AbsoluteYearlyRecurrence': abs_yearly_recpattern2rrule(rec_node, rrule) else: raise ValueError("unknown recurrence pattern: %s" % rec_type) range_type = rec_range.content if range_type == 'NumberedRecurrence': count = rec_range.search('NumberOfOccurrences').content rrule['COUNT'] = count elif range_type == 'EndDateRecurrence': enddate = rec_range.search('EndDate').content rrule['UNTIL'] = xs_date2datetime(enddate) else: # NoEndRecurrence is the default in iCalendar pass rec.attr['rrule'] = rrule return rec
def create_exchange_id(eid, e_chkey=None): n = CNode("exchange_id") n.attr["id"] = eid if e_chkey: n.attr["changekey"] = e_chkey return n
class Erebus2EWSUpdate(CNodeVisitor): """Make an Update item, to update an item in the Exchange calendar. This is an internal class used by ExchangeBackend """ trans = { 'Subject': 'item:Subject', 'Start': 'calendar:Start', 'End': 'calendar:End', 'IsAllDayEvent': 'calendar:IsAllDayEvent', 'Location': 'calendar:Location', 'MeetingTimeZone': 'calendar:MeetingTimeZone', 'Sensitivity': 'item:Sensitivity', 'DateTimeCreated': 'item:DateTimeCreated', 'Body': 'item:Body'} def __init__(self,cnode): self.ebus = cnode def run(self): self.ews = Erebus2SimpleEWSVisitor(self.ebus).run() self.updates = CNode('Updates') self.visit(self.ews) AddNamespaceVisitor(self.updates,types).run() return self.updates def _create_field_uri(self,uri): """Add a field URI to updates. Warning: An item corresponding to `uri' must be added to self.updates after a call to this method """ u = CNode('FieldURI') u.attr['FieldURI'] = uri return u def _make_parent(self,path): """Make a "tree" of CNodes as a parent for an update value, Example: self._make_parent(['CalendarItem','Subject']) => a CNode('Subject') node with a CNode('CalendarItem') parent returns: (topmost parent, the last child), in the example: (the Subject CNode, the CalendarItem CNode) """ child = CNode(path.pop()) c = child while len(path): p = CNode(path.pop()) p.add_child(c) c = p parent = c return (parent, child) def visit_any(self,e): """Check the trans table""" if self.trans.has_key(e.name): (p,c) = self._make_parent(['CalendarItem']) c.add_child(e) uri = self._create_field_uri(self.trans[e.name]) setitem = CNode('SetItemField') setitem.add_child(uri) setitem.add_child(p) self.updates.add_child(setitem) # Visit children for c in e.children: self.visit(c)
class ICS2ErebusVisitor(CNodeVisitor): def __init__(self,cnode): self.calendar = CNode(name='calendar') self.timezones = CNode(name='timezones') self.timezone_ids = {} self.events = CNode(name='events') self.calendar.add_child(self.timezones) self.calendar.add_child(self.events) ToLowerCaseVisitor().visit(cnode) self.ics = cnode def run(self): timezones = self.accept(self.ics, 'vtimezone') events = self.accept(self.ics, 'vevent') for e in timezones: self.timezones.add_child(e) for e in events: self.events.add_child(e) return self.calendar def __convert_timezone(self,ics): if ics.name == 'standard': tz_e = CNode(name='Standard') elif ics.name == 'daylight': tz_e = CNode(name='Daylight') else: raise ValueError("Unknown timezone type: %s", ics.name) offset = utcoffset2vDDD(ics.attr['tzoffsetto'], negate=True) offset_e = CNode(name='Offset',content=offset) tz_e.add_child(offset_e) rrule = ics.attr['rrule'] start = ics.attr['dtstart'] if rrule: rec = rrule2recurrence(rrule, start) tz_e.add_child(rec.children[0]) time = start.dt timestr = "%.2d:%.2d:%.2d" %(time.hour, time.minute, time.second) time_e = CNode(name='Time',content=timestr) tz_e.add_child(time_e) return tz_e def visit_vtimezone(self,ics): tz = CNode(name='TimeZone') baseoffset_e = CNode(name='BaseOffset',content='PT0M') tz.add_child(baseoffset_e) if len(ics.children) == 1: # Just add a base offset std_e = ics.children[0] # TODO: fix this else: tz_s = self.__convert_timezone(ics.search('standard')) tz.add_child(tz_s) tz_d = self.__convert_timezone(ics.search('daylight')) tz.add_child(tz_d) tzid = gen_tz_id(tz) tz.attr['TimeZoneName'] = tzid tzid_e = CNode(name='tzid',content=tzid) tz.add_child(tzid_e) self.timezone_ids[ics.attr['tzid']] = tzid return tz def visit_vevent(self,ics): event = CNode(name='event') def conv(icaln, ebus, f): if not ics.attr.has_key(icaln): return ics_e = ics.attr[icaln] if not ics_e: return new = f(ics_e) if not new: return event.attr[ebus] = new conv('uid', 'ical_uid', identity) conv('summary', 'summary', identity) conv('dtstart', 'start', vDDD2dt) conv('dtend', 'end', vDDD2dt) conv('class', 'class', identity) conv('location', 'location', identity) conv('dtstamp', 'timestamp', vDDD2dt) conv('description', 'description', identity) if ics.attr.has_key('rrule'): rec = rrule2recurrence(ics.attr['rrule'], event.attr['start']) if rec: event.add_child(rec) rec_range = rrule2range(ics.attr['rrule'], event.attr['start']) rec.add_child(rec_range) if type(ics.attr['dtstart']) != datetime.date and \ ics.attr['dtstart'].params.has_key('tzid'): i_tzid = ics.attr['dtstart'].params['tzid'] tz = self.timezone_ids[i_tzid] tz_e = CNode(name='tzid',content=tz) event.add_child(tz_e) return event
def rrule2recurrence(rrule, starttime): freq = rrule['freq'][0] if rrule.has_key('INTERVAL'): interval = rrule['INTERVAL'][0] else: interval = 1 interval_e = CNode(name='Interval', content=interval) recurrence_e = CNode(name='Recurrence') if freq == 'YEARLY': recpattern_e = rrule2yearly_recpattern(rrule, interval_e, starttime) recurrence_e.add_child(recpattern_e) elif freq == 'MONTHLY': if rrule.has_key('BYDAY'): # When more than one day, it is impossible to do in # Exchange (except if all days are in the same week) day = rrule['byday'][0] recpattern_e = CNode(name='RelativeMonthlyRecurrence') dow_e, weekindex_e = byday2rel_month(day) recpattern_e.add_child(interval_e) recpattern_e.add_child(dow_e) recpattern_e.add_child(weekindex_e) recurrence_e.add_child(recpattern_e) else: recpattern_e = CNode(name='AbsoluteMonthlyRecurrence') if rrule.has_key('BYMONTHDAY'): mday = str(rrule['BYMONTHDAY'][0]) else: mday = str(starttime.day) dayofmonth = CNode(name='DayOfMonth',content=mday) recpattern_e.add_child(dayofmonth) recurrence_e.add_child(recpattern_e) elif freq == 'WEEKLY' or \ (freq == 'DAILY' and rrule.has_key('BYDAY')): recpattern_e = CNode(name='WeeklyRecurrence') daysofweek_e = CNode(name='DaysOfWeek') if rrule.has_key('WKST') or rrule.has_key('BYDAY'): if rrule.has_key('WKST'): # TODO: really? ical_days = rrule['WKST'] else: ical_days = rrule['BYDAY'] days = [weekday_ical2xml(w) for w in ical_days] daysofweek_e.content = " ".join(days) else: wkday = dt2xml_weekday(starttime) daysofweek_e.content = wkday recpattern_e.add_child(interval_e) recpattern_e.add_child(daysofweek_e) recurrence_e.add_child(recpattern_e) elif freq == 'DAILY': recpattern_e = CNode(name='DailyRecurrence') recpattern_e.add_child(interval_e) recurrence_e.add_child(recpattern_e) return recurrence_e