Beispiel #1
0
def prepareVobj(view, uuid, recordSet, vobjs):
    """
    Determine if a recordset is for a vtodo, or a vevent, then create it.
    
    Modifications may not have event records OR task records, so for
    modifications, check what was done for the master.  This relies on 
    recordsets for masters being processed before modifications.
    
    """
    master_uuid, recurrenceID = translator.splitUUID(view, uuid)
    if recurrenceID is None:
        note, event = hasNoteOrEvent(recordSet)
    else:
        if vobjs.get(master_uuid).name.lower() == 'vevent':
            task, event = False, True
        else:
            task, event = True, False
            
    if event:
        vevent = vobject.newFromBehavior('vevent')
        vevent.isNative = True
        vobjs[uuid] = vevent
    else: # @@@ assert note?
        vtodo = vobject.newFromBehavior('vtodo')
        vtodo.isNative = True
        vobjs[uuid] = vtodo
def prepareVobj(view, uuid, recordSet, vobjs):
    """
    Determine if a recordset is for a vtodo, or a vevent, then create it.
    
    Modifications may not have event records OR task records, so for
    modifications, check what was done for the master.  This relies on 
    recordsets for masters being processed before modifications.
    
    """
    master_uuid, recurrenceID = translator.splitUUID(view, uuid)
    if recurrenceID is None:
        note, event = hasNoteOrEvent(recordSet)
    else:
        if vobjs.get(master_uuid).name.lower() == 'vevent':
            task, event = False, True
        else:
            task, event = True, False

    if event:
        vevent = vobject.newFromBehavior('vevent')
        vevent.isNative = True
        vobjs[uuid] = vevent
    else:  # @@@ assert note?
        vtodo = vobject.newFromBehavior('vtodo')
        vtodo.isNative = True
        vobjs[uuid] = vtodo
    def recordSetsToVObject(cls, view, recordSets, **extra):
        """ Convert a list of record sets to an ICalendar blob """
        vobj_mapping = {}
        cal = vobject.iCalendar()

        masterRecordSets = []
        nonMasterRecordSets = []
        # masters need to be handled first, so modifications have access to them
        for uuid, recordSet in recordSets.iteritems():
            # skip over record sets with neither an EventRecord nor a TaskRecord
            note, event = hasNoteOrEvent(recordSet)
            if note or event:
                uid, recurrenceID = translator.splitUUID(view, uuid)
                if recurrenceID is None:
                    masterRecordSets.append((uuid, recordSet))
                else:
                    nonMasterRecordSets.append((uuid, recordSet))

        injectTopLevel = True
        for uuid, recordSet in chain(masterRecordSets, nonMasterRecordSets):
            prepareVobj(view, uuid, recordSet, vobj_mapping)
            icalExtra = None
            for record in recordSet.inclusions:
                recordHandlers.get(type(record), Nil)(view, record,
                                                      vobj_mapping)
                if type(record) == model.NoteRecord:
                    icalExtra = record.icalExtra

            if icalExtra not in translator.emptyValues:
                injectUnrecognized(icalExtra, cal, vobj_mapping.get(uuid),
                                   injectTopLevel)
                # only include unrecognized content lines once per cluster
                injectTopLevel = False

        # Tweak SEQUENCE for Google
        if extra.get('incrementSequence', False):
            setHigherSequence(vobj_mapping.values())

        cal.vevent_list = [
            obj for obj in vobj_mapping.values()
            if obj.name.lower() == 'vevent'
        ]
        cal.vtodo_list = [
            obj for obj in vobj_mapping.values() if obj.name.lower() == 'vtodo'
        ]

        name = extra.get('name')
        if name is not None:
            cal.add('x-wr-calname').value = name

        if extra.get('monolithic', False):
            # don't add a METHOD to CalDAV serializations, because CalDAV
            # forbids them, but do add one when serializing monolithic ics files
            # because Outlook requires them (bug 7121)
            cal.add('method').value = "PUBLISH"

        #handle icalendarExtra
        return cal
Beispiel #4
0
    def recordSetsToVObject(cls, view, recordSets, **extra):
        """ Convert a list of record sets to an ICalendar blob """
        vobj_mapping = {}
        cal = vobject.iCalendar()

        masterRecordSets = []
        nonMasterRecordSets = []
        # masters need to be handled first, so modifications have access to them
        for uuid, recordSet in recordSets.iteritems():
            # skip over record sets with neither an EventRecord nor a TaskRecord
            note, event = hasNoteOrEvent(recordSet)
            if note or event:
                uid, recurrenceID = translator.splitUUID(view, uuid)
                if recurrenceID is None:
                    masterRecordSets.append( (uuid, recordSet) )
                else:
                    nonMasterRecordSets.append( (uuid, recordSet) )

        injectTopLevel = True
        for uuid, recordSet in chain(masterRecordSets, nonMasterRecordSets):
            prepareVobj(view, uuid, recordSet, vobj_mapping)
            icalExtra = None
            for record in recordSet.inclusions:
                recordHandlers.get(type(record), Nil)(view, record,
                                                      vobj_mapping)
                if type(record) == model.NoteRecord:
                    icalExtra = record.icalExtra
            
            if icalExtra not in translator.emptyValues:
                injectUnrecognized(icalExtra, cal, vobj_mapping.get(uuid),
                                   injectTopLevel)
                # only include unrecognized content lines once per cluster
                injectTopLevel = False

        # Tweak SEQUENCE for Google
        if extra.get('incrementSequence', False):
            setHigherSequence(vobj_mapping.values())

        cal.vevent_list = [obj for obj in vobj_mapping.values()
                           if obj.name.lower() == 'vevent']
        cal.vtodo_list = [obj for obj in vobj_mapping.values()
                           if obj.name.lower() == 'vtodo']

        name = extra.get('name')
        if name is not None:
            cal.add('x-wr-calname').value = name
            
        if extra.get('monolithic', False):
            # don't add a METHOD to CalDAV serializations, because CalDAV
            # forbids them, but do add one when serializing monolithic ics files
            # because Outlook requires them (bug 7121)
            cal.add('method').value = "PUBLISH"
            
        #handle icalendarExtra
        return cal
def readNoteRecord(view, noteRecord, vobjs):
    vobj = getVobj(noteRecord, vobjs)
    if noteRecord.body not in translator.emptyValues:
        vobj.add('description').value = noteRecord.body
    icalUID = noteRecord.icalUid
    if icalUID in translator.emptyValues:
        # empty icalUID for a master means use uuid, for a modification it means
        # inherit icalUID
        uuid, recurrenceID = translator.splitUUID(view, noteRecord.uuid)
        if recurrenceID is None:
            icalUID = uuid
        else:
            icalUID = vobjs[uuid].uid.value

    vobj.add('uid').value = icalUID
Beispiel #6
0
def readNoteRecord(view, noteRecord, vobjs):
    vobj = getVobj(noteRecord, vobjs)
    if noteRecord.body not in translator.emptyValues:
        vobj.add('description').value = noteRecord.body
    icalUID = noteRecord.icalUid
    if icalUID in translator.emptyValues:
        # empty icalUID for a master means use uuid, for a modification it means
        # inherit icalUID
        uuid, recurrenceID = translator.splitUUID(view, noteRecord.uuid)
        if recurrenceID is None:
            icalUID = uuid
        else:
            icalUID = vobjs[uuid].uid.value

    vobj.add('uid').value = icalUID
def readEventRecord(view, eventRecord, vobjs):
    vevent = getVobj(eventRecord, vobjs)
    master = None

    uuid, recurrenceID = translator.splitUUID(view, eventRecord.uuid)
    if recurrenceID is not None:
        master = vobjs[uuid]
        m_start = master.dtstart
        anyTime = False
        if getattr(m_start, 'value_param', '') == 'DATE':
            recurrenceID = recurrenceID.date()
            anyTime = (getattr(m_start, 'x_osaf_anytime_param', '') == 'TRUE')
        elif recurrenceID.tzinfo == view.tzinfo.floating:
            recurrenceID = recurrenceID.replace(tzinfo=None)
        elif recurrenceID.tzinfo == view.tzinfo.UTC:
            # convert UTC recurrence-id (which is legal, but unusual in
            # iCalendar) to the master's dtstart timezone
            tzid = getattr(m_start, 'tzid_param', None)
            if tzid is not None:
                tzinfo = view.tzinfo.getInstance(tzid)
                recurrenceID = recurrenceID.astimezone(tzinfo)
        vevent.add('recurrence-id').value = recurrenceID

    if eventRecord.dtstart in translator.emptyValues:
        if recurrenceID is not None:
            dtstart = vevent.add('dtstart')
            dtstart.value = recurrenceID
            if anyTime:
                dtstart.x_osaf_anytime_param = "TRUE"
    else:
        vevent.dtstart = textLineToContentLine("DTSTART" + eventRecord.dtstart)
        pruneDateTimeParam(vevent.dtstart)
        registerTZID(view, vevent.dtstart)

    for name in ['duration', 'status', 'location']:
        eimValue = getattr(eventRecord, name)
        if eimValue not in translator.emptyValues:
            line = vevent.add(name)
            line.value = eimValue
            line.isNative = False

    if hasattr(vevent, 'duration'):
        vevent.duration.value = vevent.duration.value.upper()
    elif recurrenceID:
        vevent.add('duration').value = master.duration.value
        vevent.duration.isNative = False

    timestamp = datetime.utcnow()
    vevent.add('dtstamp').value = timestamp.replace(tzinfo=view.tzinfo.UTC)
    # rruleset
    for rule_name in ('rrule', 'exrule'):
        rules = []
        record_value = getattr(eventRecord, rule_name)
        if record_value not in translator.emptyValues:
            for rule_value in record_value.split(':'):
                rule_value = freq_first(rule_value)
                # EIM concatenates multiple rules with :
                rules.append(
                    textLineToContentLine(rule_name + ":" + rule_value))
        vevent.contents[rule_name] = rules

    for date_name in ('rdate', 'exdate'):
        record_value = getattr(eventRecord, date_name)
        if record_value not in translator.emptyValues:
            # multiple dates should always be on one line
            setattr(vevent, date_name,
                    textLineToContentLine(date_name + record_value))
            pruneDateTimeParam(getattr(vevent, date_name))
Beispiel #8
0
def readEventRecord(view, eventRecord, vobjs):
    vevent = getVobj(eventRecord, vobjs)
    master = None
    
    uuid, recurrenceID = translator.splitUUID(view, eventRecord.uuid)
    if recurrenceID is not None:
        master = vobjs[uuid]
        m_start = master.dtstart
        anyTime = False
        if getattr(m_start, 'value_param', '') == 'DATE':
            recurrenceID = recurrenceID.date()
            anyTime = (getattr(m_start, 'x_osaf_anytime_param', '') == 'TRUE')
        elif recurrenceID.tzinfo == view.tzinfo.floating:
            recurrenceID = recurrenceID.replace(tzinfo=None)
        elif recurrenceID.tzinfo == view.tzinfo.UTC:
            # convert UTC recurrence-id (which is legal, but unusual in
            # iCalendar) to the master's dtstart timezone
            tzid = getattr(m_start, 'tzid_param', None)
            if tzid is not None:
                tzinfo = view.tzinfo.getInstance(tzid)
                recurrenceID = recurrenceID.astimezone(tzinfo)
        vevent.add('recurrence-id').value = recurrenceID
        
    if eventRecord.dtstart in translator.emptyValues:
        if recurrenceID is not None:
            dtstart = vevent.add('dtstart')
            dtstart.value = recurrenceID
            if anyTime:
                dtstart.x_osaf_anytime_param = "TRUE"
    else:
        vevent.dtstart = textLineToContentLine("DTSTART" +
                                               eventRecord.dtstart)
        pruneDateTimeParam(vevent.dtstart)
        registerTZID(view, vevent.dtstart)

    for name in ['duration', 'status', 'location']:
        eimValue = getattr(eventRecord, name)
        if eimValue not in translator.emptyValues:
            line = vevent.add(name)
            line.value = eimValue
            line.isNative = False

    if hasattr(vevent, 'duration'):
        vevent.duration.value = vevent.duration.value.upper()
    elif recurrenceID:
        vevent.add('duration').value = master.duration.value
        vevent.duration.isNative = False
        
    timestamp = datetime.utcnow()
    vevent.add('dtstamp').value = timestamp.replace(tzinfo=view.tzinfo.UTC)
    # rruleset
    for rule_name in ('rrule', 'exrule'):
        rules = []
        record_value = getattr(eventRecord, rule_name)
        if record_value not in translator.emptyValues:
            for rule_value in record_value.split(':'):
                rule_value = freq_first(rule_value)
                # EIM concatenates multiple rules with :
                rules.append(textLineToContentLine(rule_name + ":" + rule_value))
        vevent.contents[rule_name] = rules

    for date_name in ('rdate', 'exdate'):
        record_value = getattr(eventRecord, date_name)
        if record_value not in translator.emptyValues:
            # multiple dates should always be on one line
            setattr(vevent, date_name, 
                    textLineToContentLine(date_name + record_value))
            pruneDateTimeParam(getattr(vevent, date_name))