Exemplo n.º 1
0
    def ItemsToVobject(self):
        """Tests itemsToVObject, which converts Chandler items to vobject."""
        event = Calendar.CalendarEvent(view = self.repo.view)
        event.displayName = "test"
        event.startTime = datetime.datetime(2010, 1, 1, 10)
        event.endTime = datetime.datetime(2010, 1, 1, 11)        

        cal = ICalendar.itemsToVObject(self.repo.view, [event])

        self.assert_(cal.vevent[0].summary[0].value == "test",
         "summary not set properly, summary is %s"
         % cal.vevent[0].summary[0].value)

        start = event.startTime.replace(tzinfo=ICalendar.localtime)

        self.assert_(cal.vevent[0].dtstart[0].value == start,
         "dtstart not set properly, dtstart is %s"
         % cal.vevent[0].summary[0].value)

        event = Calendar.CalendarEvent(view = self.repo.view)
        event.displayName = "test2"
        event.startTime = datetime.datetime(2010, 1, 1)
        event.allDay = True        

        cal = ICalendar.itemsToVObject(self.repo.view, [event])

        self.assert_(cal.vevent[0].dtstart[0].value == datetime.date(2010,1,1),
         "dtstart for allDay event not set properly, dtstart is %s"
         % cal.vevent[0].summary[0].value)
Exemplo n.º 2
0
def itemsToFreeBusy(view, start, end, calname = None):
    """
    Create FREEBUSY components corresponding to all events between start and 
    end.
        
    """
    all = schema.ns("osaf.pim", view).allCollection
    normal    = Calendar.eventsInRange(view, start, end, all)
    recurring = Calendar.recurringEventsInRange(view, start, end, all)
    events = Calendar._sortEvents(itertools.chain(normal, recurring),
                                  attrName='effectiveStartTime')
    
    def toUTC(dt):
        if dt < start: dt = start
        elif dt > end: dt = end
        return translateToTimezone(dt, view.tzinfo.UTC)
    
    cal = vobject.iCalendar()
    
    if calname is not None:
        cal.add('x-wr-calname').value = calname
    vfree = cal.add('vfreebusy')
    vfree.add('dtstart').value = toUTC(start)
    vfree.add('dtend').value   = toUTC(end)
    
    def addFB(event):
        free = vfree.add('freebusy')
        free.fbtype_param = transparencyMap[event.transparency]
        return free

    free = None
    for event in events:
        # ignore anytime events, events with no duration, and fyi events
        if (event.transparency == 'fyi' or
            ((event.anyTime or event.duration == datetime.timedelta(0)) and 
             not event.allDay)):
            continue
        if free is None or free.fbtype_param != \
                           transparencyMap[event.transparency]:
            free = addFB(event)
            free.value = [[toUTC(event.effectiveStartTime),
                           event.effectiveEndTime]]
        else:
            # compress freebusy blocks if possible
            if event.effectiveStartTime <= free.value[-1][1]:
                if event.effectiveEndTime > free.value[-1][1]:
                    free.value[-1][1] = event.effectiveEndTime
            else:
                free.value.append([toUTC(event.effectiveStartTime),
                                   event.effectiveEndTime])

    # once upon a time serialize would convert (date, date) to (date, period)
    # but no longer.  So there's no need to serialize
    # vfree.serialize()

    return cal
Exemplo n.º 3
0
def itemsToFreeBusy(view, start, end, calname=None):
    """
    Create FREEBUSY components corresponding to all events between start and 
    end.
        
    """
    all = schema.ns("osaf.pim", view).allCollection
    normal = Calendar.eventsInRange(view, start, end, all)
    recurring = Calendar.recurringEventsInRange(view, start, end, all)
    events = Calendar._sortEvents(itertools.chain(normal, recurring), attrName="effectiveStartTime")

    def toUTC(dt):
        if dt < start:
            dt = start
        elif dt > end:
            dt = end
        return translateToTimezone(dt, view.tzinfo.UTC)

    cal = vobject.iCalendar()

    if calname is not None:
        cal.add("x-wr-calname").value = calname
    vfree = cal.add("vfreebusy")
    vfree.add("dtstart").value = toUTC(start)
    vfree.add("dtend").value = toUTC(end)

    def addFB(event):
        free = vfree.add("freebusy")
        free.fbtype_param = transparencyMap[event.transparency]
        return free

    free = None
    for event in events:
        # ignore anytime events, events with no duration, and fyi events
        if event.transparency == "fyi" or (
            (event.anyTime or event.duration == datetime.timedelta(0)) and not event.allDay
        ):
            continue
        if free is None or free.fbtype_param != transparencyMap[event.transparency]:
            free = addFB(event)
            free.value = [[toUTC(event.effectiveStartTime), event.effectiveEndTime]]
        else:
            # compress freebusy blocks if possible
            if event.effectiveStartTime <= free.value[-1][1]:
                if event.effectiveEndTime > free.value[-1][1]:
                    free.value[-1][1] = event.effectiveEndTime
            else:
                free.value.append([toUTC(event.effectiveStartTime), event.effectiveEndTime])

    # once upon a time serialize would convert (date, date) to (date, period)
    # but no longer.  So there's no need to serialize
    # vfree.serialize()

    return cal
Exemplo n.º 4
0
    def testNone(self):
        showTZUI = False

        adjustStart, adjustEnd = Calendar.adjustSearchTimes(self.start, None, showTZUI)
        self.failUnless(adjustEnd is None)
        self.failIf(adjustStart is None)
        self.failIfEqual(adjustStart, self.start, "If showTZUI is False, should adjust start")

        adjustStart, adjustEnd = Calendar.adjustSearchTimes(None, self.end, showTZUI)
        self.failUnless(adjustStart is None)
        self.failIf(adjustEnd is None)
        self.failIfEqual(adjustEnd, self.end, "If showTZUI is False, should adjust end")
Exemplo n.º 5
0
def GenerateMailMessage(view, tzinfo=None):
    global M_FROM
    message = Mail.MailMessage(itsView=view)
    body = M_TEXT

    outbound = random.randint(0, 1)
    type = random.randint(1, 8)
    numTo = random.randint(1, 3)

    if M_FROM is None:
        M_FROM = GenerateCalendarParticipant(view)

    message.fromAddress = M_FROM

    for num in range(numTo):
        message.toAddress.append(GenerateCalendarParticipant(view))

    message.subject = random.choice(TITLES)

    if TEST_I18N:
        message.subject = uw(message.subject)

    message.dateSent = datetime.now(tzinfo)

    if outbound:
        message.outgoingMessage()
        message.itsItem.changeEditState(Modification.sent, who=M_FROM)

    else:
        message.incomingMessage()

    if type == EVENT:
        Calendar.EventStamp(message).add()
        body += M_EVENT

    if type == TASK:
        pim.TaskStamp(message).add()
        body += M_TASK

    if type == BOTH:
        Calendar.EventStamp(message).add()
        pim.TaskStamp(message).add()
        body += M_BOTH

    if TEST_I18N:
        body = uw(body)

    message.body = body
    message.itsItem.setTriageStatus(randomEnum(pim.TriageEnum))

    return message.itsItem
Exemplo n.º 6
0
    def testICSSerializer(self):
        """Tests serialization of items to icalendar streams."""
        event = Calendar.CalendarEvent(itsView=self.view)
        event.anyTime = False
        event.summary = uw("test")
        event.startTime = datetime.datetime(2010,
                                            1,
                                            1,
                                            10,
                                            tzinfo=self.view.tzinfo.default)
        event.endTime = datetime.datetime(2010,
                                          1,
                                          1,
                                          11,
                                          tzinfo=self.view.tzinfo.default)

        cal = getVObjectData(self.view, [event.itsItem])

        self.failUnlessEqual(
            cal.vevent.summary.value, uw("test"),
            u"summary not set properly, summary is %s" %
            cal.vevent.summary.value)

        start = event.startTime
        self.assert_(
            cal.vevent.dtstart.value == start,
            "dtstart not set properly, dtstart is %s" %
            cal.vevent.summary.value)

        event = Calendar.CalendarEvent(itsView=self.view)
        event.summary = uw("test2")
        event.startTime = datetime.datetime(2010,
                                            1,
                                            1,
                                            tzinfo=self.view.tzinfo.floating)
        event.allDay = True
        event.duration = datetime.timedelta(1)
        self.assertEqual(event.effectiveEndTime - event.effectiveStartTime,
                         datetime.timedelta(2))
        cal = getVObjectData(self.view, [event.itsItem])

        self.assert_(
            cal.vevent.dtstart.value == datetime.date(2010, 1, 1),
            u"dtstart for allDay event not set properly, dtstart is %s" %
            cal.vevent.summary.value)

        # test bug 9137, multi-day all-day events with
        # duration modulo 1 day == 0 are serialized as 1 day instead of 2
        self.assertEqual(cal.vevent.duration.value, datetime.timedelta(2))
    def testMultidayEdgeCase(self):
        tzinfo = self.sandbox.itsView.tzinfo

        event = Calendar.CalendarEvent(
            itsParent=self.sandbox,
            allDay=True,
            anyTime=False,
            startTime=datetime(2007, 7, 20, tzinfo=tzinfo.floating),
            duration=timedelta(days=0),
        )
        self.failUnlessEqual(event.effectiveStartTime,
                             datetime(2007, 7, 20, tzinfo=tzinfo.floating))
        self.failUnlessEqual(event.effectiveEndTime,
                             datetime(2007, 7, 21, tzinfo=tzinfo.floating))

        event.duration = timedelta(days=1)
        # Really, the following should be 2007/07/21. However, for a while
        # Chandler has treated an all-day event with duration of exactly
        # one day as lasting two days. Jeffrey pointed out that there is
        # import/export code we would need to change in addition to the
        # domain model here. [grant 2007/10/17]
        self.failUnlessEqual(event.effectiveEndTime,
                             datetime(2007, 7, 22, tzinfo=tzinfo.floating))

        event.duration = timedelta(days=2, hours=3)
        self.failUnlessEqual(event.effectiveEndTime,
                             datetime(2007, 7, 23, tzinfo=tzinfo.floating))
    def testAllDay(self):
        event = Calendar.CalendarEvent(itsParent=self.sandbox,
                                       anyTime=False,
                                       allDay=True)
        self.failUnlessEqual(event.effectiveStartTime.timetz(),
                             self.floatingMidnight)
        self.failUnlessEqual(event.effectiveStartTime.date(),
                             event.startTime.date())
        self.failUnlessEqual(event.effectiveEndTime,
                             event.effectiveStartTime + timedelta(days=1))

        event.anyTime = True
        self.failUnlessEqual(event.effectiveStartTime.timetz(),
                             self.floatingMidnight)
        self.failUnlessEqual(event.effectiveStartTime.date(),
                             event.startTime.date())
        self.failUnlessEqual(event.effectiveEndTime,
                             event.effectiveStartTime + timedelta(days=1))

        event.anyTime = event.allDay = False
        self.failUnlessEqual(event.startTime, event.effectiveStartTime)
        self.failUnlessEqual(event.effectiveStartTime.date(),
                             event.startTime.date())
        self.failUnlessEqual(event.effectiveEndTime,
                             event.effectiveStartTime + event.duration)
Exemplo n.º 9
0
 def _createEvent(self, startTime):
     event = Calendar.CalendarEvent(None, itsView=self.view)
     event.startTime = startTime
     event.endTime = event.startTime + timedelta(hours=1)
     event.anyTime = False
     event.summary = uw("Sample event")
     return event    
Exemplo n.º 10
0
 def testEventIndex(self):
     """Make sure eventsInRange works."""
     daysEvents = list(Calendar.eventsInRange(self.view, self.midnight,
                                              self.midnight + timedelta(1))) 
     self.assertEqual(daysEvents[0], self.pacificEvent)
     self.assertEqual(daysEvents[1], self.floatingEvent)
     self.assertEqual(daysEvents[2], self.hawaiiEvent)
    def testDefaultSettings(self):
        defaultTz = TimeZoneInfo.get(self.sandbox.itsView).default
        ROUND = 30

        # A new event, by default, has its startTime set to the current time
        # rounded to a 30-minute boundary
        start = datetime.now(defaultTz)
        event = Calendar.CalendarEvent(itsParent=self.sandbox,
                                       anyTime=False,
                                       allDay=False)
        end = datetime.now(defaultTz)

        # Check that it falls within 30 minutes of now
        self.failUnless(start - timedelta(minutes=ROUND) <= event.startTime
                        and event.startTime <= end + timedelta(minutes=ROUND))

        # Check that the correct rounding occurred
        self.failUnlessEqual(event.startTime.second, 0)
        self.failUnlessEqual(event.startTime.microsecond, 0)
        self.failUnlessEqual(event.startTime.minute % ROUND, 0)

        # Make sure it's in the right timezone
        self.failUnlessEqual(event.startTime.tzinfo, defaultTz)

        # Lastly, check the dates if possible
        if start.date() == end.date():
            self.failUnlessEqual(start.date(), event.startTime.date())

        self.failUnlessEqual(event.effectiveStartTime, event.startTime)
        self.failUnlessEqual(event.effectiveEndTime, event.endTime)
    def testNone(self):
        showTZUI = False

        adjustStart, adjustEnd = Calendar.adjustSearchTimes(
            self.start, None, showTZUI)
        self.failUnless(adjustEnd is None)
        self.failIf(adjustStart is None)
        self.failIfEqual(adjustStart, self.start,
                         "If showTZUI is False, should adjust start")

        adjustStart, adjustEnd = Calendar.adjustSearchTimes(
            None, self.end, showTZUI)
        self.failUnless(adjustStart is None)
        self.failIf(adjustEnd is None)
        self.failIfEqual(adjustEnd, self.end,
                         "If showTZUI is False, should adjust end")
    def setUp(self):

        if not hasattr(RecurrenceConflictTestCase, 'view'):
            super(RecurrenceConflictTestCase, self).setUp()
            RecurrenceConflictTestCase.view = self.view
            del self.view

        view = RecurrenceConflictTestCase.view
        self.sandbox = Item("sandbox", view, None)

        self.pacific = self.view.tzinfo.getInstance("America/Los_Angeles")
        self.floating = self.view.tzinfo.floating
        self.utc = self.view.tzinfo.UTC

        self.start = datetime.datetime(2007, 4, 10, 9, tzinfo=self.floating)

        self.master = Calendar.CalendarEvent(None, itsParent=self.sandbox)
        self.uuid = self.master.itsItem.itsUUID.str16()
        self.master.startTime = self.start
        self.master.anyTime = self.master.allDay = False

        # create a baseline dictionary with keywords for creating an EventRecord
        names = (i.name for i in EventRecord.__fields__ if i.name != 'uuid')
        # default values to NoChange
        self.kwds = dict.fromkeys(names, sharing.NoChange)
 def testAtTime(self):
     event = Calendar.CalendarEvent(itsParent=self.sandbox,
                                    anyTime=False,
                                    allDay=False,
                                    duration=timedelta(0))
     self.failUnlessEqual(event.effectiveStartTime, event.startTime)
     self.failUnlessEqual(event.endTime, event.startTime)
     self.failUnlessEqual(event.effectiveEndTime, event.startTime)
Exemplo n.º 15
0
    def testExportRecurrence(self):
        eastern = self.view.tzinfo.getInstance("America/New_York")
        start = datetime.datetime(2005, 2, 1, tzinfo=eastern)
        vevent = vobject.icalendar.RecurringComponent(name='VEVENT')
        vevent.behavior = vobject.icalendar.VEvent

        vevent.add('dtstart').value = start

        ruleSetItem = self._makeRecurrenceRuleSet()
        vevent.rruleset = ruleSetItem.createDateUtilFromRule(start)

        self.assertEqual(vevent.rrule.value, 'FREQ=DAILY')

        event = Calendar.CalendarEvent(itsView=self.view)
        event.anyTime = False
        event.summary = uw("blah")
        event.startTime = start
        event.endTime = datetime.datetime(2005, 2, 1, 1, tzinfo=eastern)

        event.rruleset = self._makeRecurrenceRuleSet(
            datetime.datetime(2005, 3, 1, tzinfo=eastern),
            freq='weekly',
            byweekday=[
                WeekdayAndPositionStruct(i, 0) for i in "tuesday", "thursday"
            ])

        vcalendar = getVObjectData(self.view, [event.itsItem])

        self.assertEqual(vcalendar.vevent.dtstart.serialize(),
                         'DTSTART;TZID=America/New_York:20050201T000000\r\n')
        vcalendar.vevent = vcalendar.vevent.transformFromNative()
        self.assertEqual(
            vcalendar.vevent.rrule.serialize(),
            'RRULE:FREQ=WEEKLY;BYDAY=TU,TH;UNTIL=20050302T045900Z\r\n')

        # move the second occurrence one day later
        nextEvent = event.getFirstOccurrence().getNextOccurrence()
        nextEvent.changeThis(
            pim.EventStamp.startTime.name,
            datetime.datetime(2005, 2, 9, tzinfo=self.view.tzinfo.floating))

        nextEvent.getNextOccurrence().deleteThis()

        vcalendar = getVObjectData(self.view, [event.itsItem, nextEvent])
        for ev in vcalendar.vevent_list:
            if hasattr(ev, 'recurrence_id'):
                modified = ev
            else:
                master = ev
        self.assertEqual(modified.dtstart.serialize(),
                         'DTSTART:20050209T000000\r\n')
        self.assertEqual(
            modified.recurrence_id.serialize(),
            'RECURRENCE-ID;TZID=America/New_York:20050203T000000\r\n')
        self.assertEqual(master.exdate.serialize(),
                         'EXDATE;TZID=America/New_York:20050210T000000\r\n')
        vcalendar.behavior.generateImplicitParameters(vcalendar)
        self.assertEqual(vcalendar.vtimezone.tzid.value, "America/New_York")
Exemplo n.º 16
0
    def testTimeFields(self):
        """ Test time related fields and methods """

        self.loadParcel("parcel:osaf.pim.calendar")

        # Test getDuration
        view = self.rep.view
        firstItem = Calendar.CalendarEvent(view=view)
        firstItem.anyTime = False
        firstItem.startTime = datetime(2003, 2, 1, 10)
        firstItem.endTime = datetime(2003, 2, 1, 11, 30)
        self.assertEqual(firstItem.duration, timedelta(hours=1.5))

        # Test setDuration
        secondItem = Calendar.CalendarEvent(view=view)
        secondItem.anyTime = False
        secondItem.startTime = datetime(2003, 3, 5, 9)
        secondItem.duration = timedelta(hours=1.5)
        self.assertEqual(secondItem.endTime,
                         datetime(2003, 3, 5, 10, 30))

        # Test changeStartTime
        firstItem.ChangeStart(datetime(2003, 3, 4, 12, 45))
        self.assertEqual(firstItem.duration, timedelta(hours=1.5))
        self.assertEqual(firstItem.startTime, datetime(2003, 3, 4, 12, 45))

        # Test reminderTime
        firstItem.SetReminderDelta(timedelta(minutes=-30))
        self.assertEqual(firstItem.reminderTime, datetime(2003, 3, 4, 12, 15))
        firstItem.SetReminderDelta(None)
        self.failIf(firstItem.hasLocalAttributeValue('reminderTime'))

        # Test allDay
        firstItem.allDay = True
        self.assertEqual(firstItem.allDay, True)
        firstItem.allDay = False
        self.assertEqual(firstItem.allDay, False)

        # Test anyTime
        firstItem.anyTime = True
        self.assertEqual(firstItem.anyTime, True)
        firstItem.anyTime = False
        self.assertEqual(firstItem.anyTime, False)
Exemplo n.º 17
0
    def testCreate(self):
        eventCreateDict = {
            'itsView': self.view,
            'summary': u'event creation test',
            Note.icalUID.name: u'abcdef',
            'startTime': datetime.datetime(1996, 11, 11)
        }
        event = Calendar.CalendarEvent(**eventCreateDict)

        self.failUnlessEqual(u'abcdef', event.itsItem.icalUID)
Exemplo n.º 18
0
 def testReorderFloating(self):
     """Changes to floating time should cause events to be reindexed."""
     self.tzInfoItem.default = self.eastern
     daysEvents = list(Calendar.eventsInRange(self.view, self.midnight,
                                              self.midnight + timedelta(1)))
     #print [i.startTime for i in daysEvents]
     self.assertEqual(daysEvents[0], self.easternEvent)
     self.assertEqual(daysEvents[1], self.floatingEvent)
     self.assertEqual(daysEvents[2], self.pacificEvent)
     self.assertEqual(daysEvents[3], self.hawaiiEvent)
Exemplo n.º 19
0
    def testWithoutTimeZones(self):
        showTZUI = False
        adjustStart, adjustEnd = Calendar.adjustSearchTimes(self.start, self.end, showTZUI)

        self.failIfEqual(adjustStart, self.start, "If showTZUI is False, should adjust start")
        self.failIfEqual(adjustEnd, self.end, "If showTZUI is False, should adjust end")

        expected = [adjustStart, self.dt2, self.start, self.dt1, self.end, adjustEnd]
        sortedTimes = sorted(expected, key=lambda dt: dt.replace(tzinfo=None))
        self.failUnlessEqual(
            sortedTimes, expected, "Misordered datetimes: got %s; expected %s" % (expected, sortedTimes)
        )
Exemplo n.º 20
0
    def testWithTimeZones(self):
        showTZUI = True
        adjustStart, adjustEnd = Calendar.adjustSearchTimes(self.start, self.end, showTZUI)

        self.failUnlessEqual(adjustStart, self.start, "If showTZUI is True, shouldn't adjust start")
        self.failUnlessEqual(adjustEnd, self.end, "If showTZUI is True, shouldn't adjust end")

        expected = [self.dt1, adjustStart, self.dt2, adjustEnd]
        sortedTimes = sorted(expected)
        self.failUnlessEqual(
            sortedTimes, expected, "Misordered datetimes: got %s; expected %s" % (expected, sortedTimes)
        )
Exemplo n.º 21
0
    def __init__(self, view, type, logger):
        if not type in ["Event", "Note", "Task", "MailMessage", "Collection"]:
            return
        else:
            self.isNote = self.isEvent = self.isTask = self.isMessage = self.allDay = False
            self.logger = logger
            now = datetime.now()
            if type == "Event": # New Calendar Event
                # set up the expected data dictionary with the default values
                self.expected_field_dict = {"displayName" : "New Event", "startTime" : now, "endTime" : now, "duration" : timedelta(minutes=60)}
                # create a default Calendar Event
                item = Calendar.CalendarEvent(view=view)
                item.startTime = self.expected_field_dict["startTime"] # because startTime is needed befor duration
                self.isEvent = True
            elif type == "Note": # New Note
                # set up the expected data dictionary with the default values
                self.expected_field_dict = {"displayName" : "New Note", "createdOn" : now}
                # create a default Note
                item = pim.Note(view=view)
                self.isNote = True
            elif type == "Task": # New Task
                # set up the expected data dictionary with the default values
                self.expected_field_dict = {"displayName" : "New Task", "createdOn" : now}
                # create a default Task
                item = pim.Task(view=view)
                self.isTask = True
            elif type == "MailMessage": # New Mail Message
                # set up the expected data dictionary with the default values
                email = Mail.EmailAddress(view=view)
                email.emailAddress = 'me'
                self.expected_field_dict = {"subject" : "untitled", "dateSent" : now, "fromAddress" : email}
                # create a default Message
                item = Mail.MailMessage(view=view)
                self.isMessage = True
            elif type == "Collection": # New Collection
                # set up the expected data dictionary with the default values
                self.expected_field_dict = {"displayName" : "Untitled"}
                # create a default Collection
                item = pim.ItemCollection(view=view)
                
                
            # fields affectation
            for field in self.expected_field_dict.keys():
                setattr(item, field, self.expected_field_dict[field])

            self.item = item

            if type =="Collection":
                Sgf.SidebarAdd(self.item)
                Sgf.SidebarSelect(self.item)
            else:
                Sgf.SummaryViewSelect(self.item)
    def testDeleteItem(self):
        """ Test calendar event deletion """

        view = self.sandbox.itsView
        event = Calendar.CalendarEvent(itsParent=self.sandbox)
        item = event.itsItem
        path = item.itsPath
        item.delete()
        del item
        self.sandbox.itsView.commit()

        itemShouldBeGone = view.find(path)
        self.assertEqual(itemShouldBeGone, None)
Exemplo n.º 23
0
    def testUpdate(self):
        uid = u'on-a-limo-to-milano-solo-gigolos-dont-nod'

        task = pim.Task(itsView=self.view)
        task.itsItem.icalUID = uid

        event = Calendar.CalendarEvent(itsView=self.view,
                                       startTime=datetime.datetime(2000, 1, 1))

        event.itsItem.icalUID = uid
        del task.itsItem.icalUID  # Necessary?

        self.failUnless(event.itsItem is sharing.findUID(self.view, uid))
    def testDayBoundary(self):
        tzinfo = self.sandbox.itsView.tzinfo

        event = Calendar.CalendarEvent(
            itsParent=self.sandbox,
            allDay=True,
            anyTime=False,
            startTime=datetime(2007, 10, 16, 23, 30, tzinfo=tzinfo.default),
            duration=timedelta(hours=1),
        )
        self.failUnlessEqual(event.effectiveStartTime,
                             datetime(2007, 10, 16, tzinfo=tzinfo.floating))
        self.failUnlessEqual(event.effectiveEndTime,
                             datetime(2007, 10, 17, tzinfo=tzinfo.floating))
Exemplo n.º 25
0
    def testProxy(self):
        self.failIf(self.event.isProxy())
        
        proxy = Calendar.getProxy(self.event)
        self.assert_(proxy.isProxy())
        self.assertEqual(proxy, self.event)
        self.assertEqual(proxy.currentlyModifying, None)

        proxy.rruleset = self._createRuleSetItem('weekly')
        self.assert_(self.event in proxy.rruleset.events)
        self.assertEqual(proxy.getNextOccurrence().occurrenceFor, self.event)
        self.assertEqual(len(list(proxy._generateRule())), self.weekly['count'])
        
        proxy.startTime = self.start + timedelta(days=1)
Exemplo n.º 26
0
def GenerateCalendarEvent(view, days=30, tzinfo=None):
    if tzinfo is None:
        tzinfo = view.tzinfo.floating
    event = Calendar.CalendarEvent(itsView=view)
    event.summary = random.choice(HEADLINES)

    if TEST_I18N:
        event.summary = uw(event.summary)

    # Choose random days, hours
    startDelta = timedelta(days=random.randint(0, days),
                           hours=random.randint(0, 24))

    now = datetime.now(tzinfo)
    closeToNow = datetime(now.year,
                          now.month,
                          now.day,
                          now.hour,
                          int(now.minute / 30) * 30,
                          tzinfo=now.tzinfo)
    event.startTime = closeToNow + startDelta

    # Events are anyTime by default. Give a 5% chance of allDay instead,
    # or 90% of a normal event.
    r = random.randint(0, 100)
    if r < 95:  # 5% chance that we'll leave anyTime on
        event.anyTime = False
    if r < 5:  # 5% chance of allDay
        event.allDay = True

    # Choose random minutes
    event.duration = timedelta(minutes=random.choice(DURATIONS))

    # Maybe a nice reminder?
    reminderInterval = random.choice(REMINDERS)
    if reminderInterval is not None:
        event.userReminderInterval = timedelta(minutes=-reminderInterval)

    # Add a location to 2/3 of the events
    if random.randrange(3) > 0:
        if TEST_I18N:
            event.location = Calendar.Location.getLocation(
                view, uw(random.choice(LOCATIONS)))
        else:
            event.location = Calendar.Location.getLocation(
                view, random.choice(LOCATIONS))

    event.itsItem.importance = random.choice(pim.ImportanceEnum.values)
    event.itsItem.setTriageStatus(randomEnum(pim.TriageEnum))
    return event.itsItem
Exemplo n.º 27
0
    def testDeleteItem(self):

        """ Test calendar event deletion """

        self.loadParcel("parcel:osaf.pim.calendar")

        view = self.rep.view
        item = Calendar.CalendarEvent(view=view)
        path = item.itsPath
        item.delete()
        del item
        itemShouldBeGone = view.find(path)
        self.assertEqual(itemShouldBeGone, None)
        view.commit()
Exemplo n.º 28
0
    def testProxy(self):
        self.failIf(self.event.isProxy())

        proxy = Calendar.getProxy(self.event)
        self.assert_(proxy.isProxy())
        self.assertEqual(proxy, self.event)
        self.assertEqual(proxy.currentlyModifying, None)

        proxy.rruleset = self._createRuleSetItem('weekly')
        self.assert_(self.event in proxy.rruleset.events)
        self.assertEqual(proxy.getNextOccurrence().occurrenceFor, self.event)
        self.assertEqual(len(list(proxy._generateRule())),
                         self.weekly['count'])

        proxy.startTime = self.start + timedelta(days=1)
    def testTimeFields(self):
        """ Test time related fields and methods """

        # Test getting duration, setting endTime
        defaultTz = self.sandbox.itsView.tzinfo.default
        firstEvent = Calendar.CalendarEvent(itsParent=self.sandbox)
        firstEvent.anyTime = False
        firstEvent.startTime = datetime(2003, 2, 1, 10, tzinfo=defaultTz)
        firstEvent.endTime = datetime(2003, 2, 1, 11, 30, tzinfo=defaultTz)
        self.assertEqual(firstEvent.duration, timedelta(hours=1.5))

        # Test setting duration and getting endTime
        secondEvent = Calendar.CalendarEvent(itsParent=self.sandbox)
        secondEvent.anyTime = False
        secondEvent.startTime = datetime(2003, 3, 5, 9, tzinfo=defaultTz)
        secondEvent.duration = timedelta(hours=1.5)
        self.assertEqual(secondEvent.endTime,
                         datetime(2003, 3, 5, 10, 30, tzinfo=defaultTz))

        # Test changing startTime (shouldn't change duration)
        firstEvent.startTime = datetime(2003, 3, 4, 12, 45, tzinfo=defaultTz)
        self.assertEqual(firstEvent.duration, timedelta(hours=1.5))
        self.assertEqual(firstEvent.startTime,
                         datetime(2003, 3, 4, 12, 45, tzinfo=defaultTz))

        # Test allDay
        firstEvent.allDay = True
        self.assertEqual(firstEvent.allDay, True)
        firstEvent.allDay = False
        self.assertEqual(firstEvent.allDay, False)

        # Test anyTime
        firstEvent.anyTime = True
        self.assertEqual(firstEvent.anyTime, True)
        firstEvent.anyTime = False
        self.assertEqual(firstEvent.anyTime, False)
 def testTimed(self):
     event = Calendar.CalendarEvent(
         itsParent=self.sandbox,
         anyTime=False,
         allDay=False,
         startTime=datetime(2006,
                            11,
                            4,
                            13,
                            25,
                            tzinfo=self.sandbox.itsView.tzinfo.default),
         duration=timedelta(hours=1))
     self.failUnlessEqual(event.effectiveStartTime, event.startTime)
     self.failUnlessEqual(event.endTime - timedelta(hours=1),
                          event.startTime)
     self.failUnlessEqual(event.effectiveEndTime, event.endTime)
    def testWithTimeZones(self):
        showTZUI = True
        adjustStart, adjustEnd = Calendar.adjustSearchTimes(
            self.start, self.end, showTZUI)

        self.failUnlessEqual(adjustStart, self.start,
                             "If showTZUI is True, shouldn't adjust start")
        self.failUnlessEqual(adjustEnd, self.end,
                             "If showTZUI is True, shouldn't adjust end")

        expected = [self.dt1, adjustStart, self.dt2, adjustEnd]
        sortedTimes = sorted(expected)
        self.failUnlessEqual(
            sortedTimes, expected,
            "Misordered datetimes: got %s; expected %s" %
            (expected, sortedTimes))
Exemplo n.º 32
0
    def testFindEventUID(self):
        uid = u'123'

        self.failUnless(sharing.findUID(self.view, uid) is None)

        event = Calendar.CalendarEvent(itsView=self.view,
                                       displayName=u"event test",
                                       startTime=datetime.datetime(
                                           2010, 1, 1, 10),
                                       duration=datetime.timedelta(hours=2))

        self.failUnless(sharing.findUID(self.view, uid) is None)

        item = event.itsItem
        setattr(item, Note.icalUID.name, uid)

        self.failUnless(sharing.findUID(self.view, uid) is item)
    def testWithoutTimeZones(self):
        showTZUI = False
        adjustStart, adjustEnd = Calendar.adjustSearchTimes(
            self.start, self.end, showTZUI)

        self.failIfEqual(adjustStart, self.start,
                         "If showTZUI is False, should adjust start")
        self.failIfEqual(adjustEnd, self.end,
                         "If showTZUI is False, should adjust end")

        expected = [
            adjustStart, self.dt2, self.start, self.dt1, self.end, adjustEnd
        ]
        sortedTimes = sorted(expected, key=lambda dt: dt.replace(tzinfo=None))
        self.failUnlessEqual(
            sortedTimes, expected,
            "Misordered datetimes: got %s; expected %s" %
            (expected, sortedTimes))
Exemplo n.º 34
0
    def setUp(self):
        super(RecurringEventTest, self).setUp()
        self.start = datetime(2005, 7, 4, 13)  #1PM, July 4, 2005

        self.weekly = {
            'end': datetime(2005, 11, 14, 13),
            'start': self.start,
            'count': 20
        }

        self.monthly = {
            'end': datetime(2005, 11, 4, 13),
            'start': self.start,
            'count': 5
        }
        self.event = Calendar.CalendarEvent(None, view=self.rep.view)
        self.event.startTime = self.start
        self.event.endTime = self.event.startTime + timedelta(hours=1)
        self.event.anyTime = False
        self.event.displayName = "Sample event"
    def setFreeBusy(self):

        if self._recalcCount == 0:
            zerotime = time(tzinfo=self.blockItem.itsView.tzinfo.default)
            start = self.GetStartDate()
            start = datetime.combine(start, zerotime)

            # ugh, why can't timedelta just support months?
            end = minical.MonthDelta(start, 3)
            end = datetime.combine(end, zerotime)

            if self.HasPendingEventChanges():
                addedItems, removedItems, changedItems = \
                           self.GetPendingChanges(False)

                if len(removedItems) + len(changedItems) > 0:
                    self._recalcCount += 1
                    self._eventsToAdd.clear()
                else:
                    for item in addedItems:
                        if not isDead(item):
                            if (not has_stamp(item, EventStamp)):
                                continue
                            event = Calendar.EventStamp(item)
                            if event.rruleset is not None:
                                # new recurring events should
                                self._recalcCount += 1
                                self._eventsToAdd.clear()
                                break
                            elif (event.isBetween(start, end)
                                  and event.transparency == 'confirmed'):
                                self._eventsToAdd.add(event)

            else:
                self._eventsToAdd.clear()

        if self._eventsToAdd:
            self._recalcCount += 1

        if self._recalcCount or self._eventsToAdd:
            self.Refresh()
Exemplo n.º 36
0
def updateFreebusyFromVObject(view, text, busyCollection, activity=None):
    """
    Take a string, create or update freebusy events in busyCollection from that
    stream.

    Truncate differing existing freebusy events that overlap the start or end
    times.

    Returns (freebusystart, freebusyend, calname).

    """

    newItemParent = view.findPath("//userdata")

    countNew = 0
    countUpdated = 0

    freebusystart = freebusyend = None

    Calendar.ensureIndexed(busyCollection)

    # iterate over calendars, usually only one, but more are allowed
    for calendar in vobject.readComponents(text, validate=True, ignoreUnreadable=True):
        calname = calendar.getChildValue("x_wr_calname")

        for vfreebusy in calendar.vfreebusy_list:
            # RPI's server originally didn't put a VERSION:2.0 line in its
            # freebusy response.  vobject's behavior is set when a VERSION is
            # found.  Tolerate servers that export technically illegal but still
            # readable vfreebusy components
            if vfreebusy.behavior is None:
                vfreebusy.behavior = vobject.icalendar.VFreeBusy
                vfreebusy.transformToNative()

            start = vfreebusy.getChildValue("dtstart")
            end = vfreebusy.getChildValue("dtend")
            if freebusystart is None or freebusystart > start:
                freebusystart = start
            if freebusyend is None or freebusyend < end:
                freebusyend = end

            # create a list of busy blocks tuples sorted by start time
            busyblocks = []
            for fb in getattr(vfreebusy, "freebusy_list", []):
                status = getattr(fb, "fbtype_param", "BUSY").upper()
                for blockstart, duration in fb.value:
                    blockstart = translateToTimezone(blockstart, view.tzinfo.default)
                    bisect.insort(busyblocks, (blockstart, duration, status))

            # eventsInRange sorts by start time, recurring events aren't allowed
            # so we don't bother to fetch them
            existing = Calendar.eventsInRange(view, start, end, busyCollection)
            existing = itertools.chain(existing, [None])

            oldEvent = existing.next()
            for blockstart, duration, status in busyblocks:
                while oldEvent is not None and oldEvent.startTime < blockstart:
                    # this assumes no freebusy blocks overlap freebusystart
                    oldEvent.delete()
                    oldEvent = existing.next()
                if oldEvent is not None and oldEvent.startTime == blockstart:
                    oldEvent.transparency = reverseTransparencyMap[status]
                    oldEvent.duration = duration
                    countUpdated += 1
                    oldEvent = existing.next()
                else:
                    vals = {
                        "startTime": blockstart,
                        "transparency": reverseTransparencyMap[status],
                        "duration": duration,
                        "isFreeBusy": True,
                        "anyTime": False,
                        "summary": "",
                    }
                    eventItem = CalendarEvent(None, newItemParent, **vals)
                    busyCollection.add(eventItem.itsItem)
                    countNew += 1

    logger.info("...iCalendar import of %d new freebusy blocks, %d updated", countNew, countUpdated)

    return freebusystart, freebusyend, calname
Exemplo n.º 37
0
    def _doBusyCalculations(self):

        view = self.blockItem.itsView
        startDate = self.GetStartDate()

        endDate = minical.MonthDelta(startDate, 3)

        busyFractions = {}
        defaultTzinfo = view.tzinfo.default

        tzEnabled = schema.ns("osaf.pim", view).TimezonePrefs.showUI

        # The exact algorithm for the busy state is yet to be determined.
        # For now, just  get the confirmed items on a given day and calculate
        # their total duration.  As long as there is at least one event the
        # busy bar should be at least 1/4 height (so that it is visible).
        # A 100% full day is assumed to be 12 hours worth of appointments.

        def updateBusy(event, start):
            # Broken out into a separate function because we're going
            # to call it for each non-recurring events, and for each
            # individual occurrence of all the recurring events.
            # In the case of the latter, event may be the master, or
            # a modification; we're trying to avoid creating all the
            # items for individual computed occurrences.
            if event.transparency == "confirmed" and (
                event.allDay or (not event.anyTime and event.duration != zero_delta)
            ):

                assert start.tzinfo is not None

                # If timezones are enabled, we need to convert to the
                # default tzinfo here, so that date() below refers to
                # the correct timezone.
                if tzEnabled:
                    start = start.astimezone(defaultTzinfo)
                else:
                    start = start.replace(tzinfo=defaultTzinfo)

                offset = (start.date() - startDate).days

                midnightStart = datetime.combine(start.date(), time(0, tzinfo=defaultTzinfo))
                if event.allDay:
                    days = event.duration.days + 1
                else:
                    days = (start + event.duration - midnightStart).days + 1

                for day in xrange(days):
                    if event.allDay:
                        hours = 12.0
                    else:
                        today = midnightStart + timedelta(day)
                        dayStart = max(start, today)
                        earliestEnd = max(start + event.duration, today)
                        dayEnd = min(earliestEnd, today + one_day)
                        duration = dayEnd - dayStart
                        assert duration >= zero_delta
                        hours = duration.seconds / 3600 + 24 * duration.days

                    # We set a minimum "Busy" value of 0.25 for any
                    # day with a confirmed event.
                    fraction = busyFractions.get(offset + day, 0.0)
                    fraction = max(fraction, 0.25)
                    fraction += hours / 12.0

                    busyFractions[offset + day] = min(fraction, 1.0)

        if len(self._eventsToAdd) > 0:
            # First, set up busyFractions to contain the
            # existing values for all the dates of events
            # we're about to add
            for newEvent in self._eventsToAdd:
                newEventStartTimeDate = newEvent.startTime.date()
                offset = (newEventStartTimeDate - startDate).days

                busyFractions[offset] = self.GetBusy(newEventStartTimeDate)

            # Now, update them all
            for newEvent in self._eventsToAdd:
                updateBusy(newEvent, newEvent.startTime)

            # Finally, update the UI
            for offset, busy in busyFractions.iteritems():
                eventDate = startDate + timedelta(days=offset)
                self.SetBusy(eventDate, busy)
        else:

            # Largely, this code is stolen from CalendarCanvas.py; it
            # would be good to refactor it at some point.
            self.blockItem.EnsureIndexes()

            startOfDay = time(0, tzinfo=view.tzinfo.default)
            startDatetime = datetime.combine(startDate, startOfDay)
            endDatetime = datetime.combine(endDate, startOfDay)

            events = self.blockItem.contents
            view = self.blockItem.itsView

            for event, start in Calendar.iterBusyInfo(view, startDatetime, endDatetime, events):
                updateBusy(event, start)

            # Next, try to find all generated events in the given
            # datetime range

            offset = 0
            while startDate < endDate:
                self.SetBusy(startDate, busyFractions.get(offset, 0.0))
                startDate += one_day
                offset += 1