Example #1
0
    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
Example #2
0
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
Example #3
0
    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
Example #4
0
 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
Example #5
0
    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
Example #6
0
    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
Example #7
0
    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
Example #8
0
    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)
Example #9
0
    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)
Example #10
0
    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
Example #11
0
  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'
Example #12
0
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
Example #13
0
    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
Example #14
0
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
Example #15
0
    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
Example #16
0
    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)
Example #17
0
    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
Example #18
0
    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
Example #19
0
    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
Example #20
0
    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
Example #21
0
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
Example #22
0
    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
Example #23
0
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
Example #24
0
    def __pack_recurrence(self,rec_element):
        rec = CNode('Recurrence')
        rec.add_child(rec_element)
        rec.add_child(CNode('NoEndRecurrence'))

        return rec
Example #25
0
 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
Example #26
0
 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'
Example #27
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
Example #28
0
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
Example #29
0
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)
Example #30
0
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
Example #31
0
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