Ejemplo n.º 1
0
    def testUnstamp_THIS(self):
        pim.TaskStamp(self.event).add()
        self.event.rruleset = self.rruleset
        third = self.event.getFirstOccurrence().getNextOccurrence(
        ).getNextOccurrence()

        pim.TaskStamp(pim.CHANGE_THIS(third)).remove()

        self.failUnless(third.modificationFor is not None)
        self.failIf(pim.has_stamp(third, pim.TaskStamp))
        self.failUnless(pim.has_stamp(self.event, pim.TaskStamp))
        self.failUnless(
            pim.has_stamp(self.event.getFirstOccurrence(), pim.TaskStamp))
Ejemplo n.º 2
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
    def setAttributes(self, item, doWho=True):
        try:
            savedItems = self.savedAttrs
        except AttributeError:
            self.savedAttrs = {}

        savedAttrs = SavedAttrs()
        self.savedAttrs[item.itsName] = savedAttrs

        displayName = 'aTitleOrHeadline'
        item.displayName = displayName
        savedAttrs.displayName = displayName

        item.createdOn = self.savedAttrs[
            item.itsName].createdOn = datetime.now(item.itsView.tzinfo.default)

        if has_stamp(item, pim.TaskStamp):
            task = pim.TaskStamp(item)
            # Add some attributes here...

        if has_stamp(item, pim.EventStamp):
            event = pim.EventStamp(item)

        if has_stamp(item, Mail.MailStamp):
            mail = Mail.MailStamp(item)
        """
 def SetAttributeValue(self, item, attributeName, value):
     isStamped = pim.has_stamp(item, pim.TaskStamp)
     if isStamped != (value == self._getStateName(True)):
         # Stamp or unstamp the item
         if isinstance(item, pim.TaskStamp.targetType()):
             stampedObject = pim.TaskStamp(item)
             if isStamped:
                 stampedObject.remove()
             else:
                 stampedObject.add()
Ejemplo n.º 5
0
    def testUpdate(self):
        self.runImport(
            "BEGIN:VCALENDAR",
            "VERSION:2.0",
            "CALSCALE:GREGORIAN",
            "METHOD:PUBLISH",
            "BEGIN:VTODO",
            "DTSTART:20060214T000000",
            "SUMMARY:To Do (Initial)",
            "UID:ED5CAC89-4BEE-4903-8DE8-1AEF6FC1D431",
            "DTSTAMP:20060227T233332Z",
            "SEQUENCE:11",
            "DESCRIPTION:How will I ever get this done?",
            "END:VTODO",
            "END:VCALENDAR",
        )
        self.runImport(
            "BEGIN:VCALENDAR",
            "VERSION:2.0",
            "CALSCALE:GREGORIAN",
            "METHOD:PUBLISH",
            "BEGIN:VTODO",
            "DTSTART:20060214T000000",
            "SUMMARY:To Do (Initial)",
            "X-OSAF-STARRED:TRUE",
            "UID:ED5CAC89-4BEE-4903-8DE8-1AEF6FC1D431",
            "DTSTAMP:20060227T233332Z",
            "SEQUENCE:12",
            "DESCRIPTION:Phew!",
            "STATUS:COMPLETED",
            "DUE;VALUE=DATE:20060327",
            "END:VTODO",
            "END:VCALENDAR",
        )

        self.failUnlessEqual(1, len(self.items))

        item = self.items[0]
        task = pim.TaskStamp(item)

        self.failUnless(pim.has_stamp(task, pim.TaskStamp))
        self.failUnless(pim.has_stamp(task, pim.EventStamp))
        self.failUnlessEqual(item.body, u"Phew!")
        self.failUnlessEqual(
            pim.EventStamp(task).startTime.date(), datetime.date(2006, 3, 27))
        # the update causes a (spurious, but such is life) conflict
        self.failUnlessEqual(task.itsItem.triageStatus, pim.TriageEnum.now)
        # resolve the conflicts
        for c in sharing.getConflicts(task.itsItem):
            c.apply()
        self.failUnlessEqual(task.itsItem.triageStatus, pim.TriageEnum.done)
Ejemplo n.º 6
0
    def testStamp_THISANDFUTURE(self):
        self.event.rruleset = self.rruleset
        third = self.event.getFirstOccurrence().getNextOccurrence(
        ).getNextOccurrence()

        pim.TaskStamp(pim.CHANGE_FUTURE(third)).add()

        self.failIfEqual(third.getMaster(), self.event.getMaster())
        self.failUnless(pim.has_stamp(third, pim.TaskStamp))
        self.failUnless(pim.has_stamp(third.getNextOccurrence(),
                                      pim.TaskStamp))
        self.failIf(pim.has_stamp(self.event, pim.TaskStamp))
        self.failIf(
            pim.has_stamp(self.event.getFirstOccurrence(), pim.TaskStamp))
Ejemplo n.º 7
0
    def testStarred(self):
        self.runImport("BEGIN:VCALENDAR", "VERSION:2.0", "CALSCALE:GREGORIAN",
                       "METHOD:PUBLISH", "BEGIN:VTODO", "X-OSAF-STARRED:TRUE",
                       "DTSTART:20060213T000000", "SUMMARY:A Starred Note",
                       "UID:4A7707B5-6E87-49ED-8871-7A0BD37F0355",
                       "SEQUENCE:26", "DTSTAMP:20080227T163229Z", "END:VTODO",
                       "END:VCALENDAR")
        item = self.items[0]
        task = pim.TaskStamp(item)

        self.failUnless(pim.has_stamp(task, pim.TaskStamp))
        self.failUnless(pim.has_stamp(task, pim.EventStamp))
        self.failUnlessEqual(item.displayName, u"A Starred Note")
        self.failUnlessEqual(task.itsItem.triageStatus, pim.TriageEnum.now)
        self.failIf(task.itsItem.needsReply)
Ejemplo n.º 8
0
    def testStamp_ALL(self):
        self.event.rruleset = self.rruleset
        ruleEnd = self.event.startTime + datetime.timedelta(days=10)
        self.event.rruleset.rrules.first().until = ruleEnd

        occurrences = [self.event.getFirstOccurrence()]
        for i in xrange(10):
            occurrences.append(occurrences[-1].getNextOccurrence())

        pim.TaskStamp(pim.CHANGE_ALL(occurrences[0])).add()

        for event in occurrences:
            self.failUnlessEqual(event.getMaster(), self.event)
        for item in self.event.occurrences:
            self.failUnless(pim.has_stamp(item, pim.TaskStamp))
        self.failUnless(pim.has_stamp(self.event, pim.TaskStamp))
Ejemplo n.º 9
0
    def testStatus(self):
        self.runImport("BEGIN:VCALENDAR", "VERSION:2.0", "CALSCALE:GREGORIAN",
                       "METHOD:PUBLISH", "BEGIN:VTODO",
                       "DTSTART:20060213T000000", "SUMMARY:ToDone",
                       "DTSTAMP:20060227T203912Z",
                       "UID:DD5D311A-F73F-4611-B463-A5766A1BAE5F",
                       "SEQUENCE:6", "STATUS:COMPLETED", "END:VTODO",
                       "END:VCALENDAR")

        self.failUnlessEqual(1, len(self.items))

        item = self.items[0]
        task = pim.TaskStamp(item)

        self.failUnless(pim.has_stamp(task, pim.TaskStamp))
        self.failUnlessEqual(task.summary, u"ToDone")
        self.failUnlessEqual(task.itsItem.triageStatus, pim.TriageEnum.done)
Ejemplo n.º 10
0
    def testNeedsAction(self):
        self.runImport("BEGIN:VCALENDAR", "VERSION:2.0", "CALSCALE:GREGORIAN",
                       "METHOD:PUBLISH", "BEGIN:VTODO", "X-OSAF-STARRED:TRUE",
                       "DTSTART:20060213T000000",
                       "SUMMARY:Really\, do this right away",
                       "DTSTAMP:20060227T203912Z",
                       "UID:1E192668-99F7-4FA1-B1F7-70A05FC8E357",
                       "SEQUENCE:6", "STATUS:NEEDS-ACTION", "END:VTODO",
                       "END:VCALENDAR")

        self.failUnlessEqual(1, len(self.items))

        item = self.items[0]
        task = pim.TaskStamp(item)

        self.failUnless(pim.has_stamp(task, pim.TaskStamp))
        self.failUnlessEqual(task.summary, u"Really, do this right away")
        self.failUnlessEqual(task.itsItem.triageStatus, pim.TriageEnum.now)
        self.failUnless(task.itsItem.needsReply)
Ejemplo n.º 11
0
    def testDescription(self):
        self.runImport(
            "BEGIN:VCALENDAR", "VERSION:2.0", "CALSCALE:GREGORIAN",
            "METHOD:PUBLISH", "BEGIN:VTODO",
            "UID:2C41172C-6812-4848-A9BA-73A827B06E28", "SEQUENCE:7",
            "STATUS:COMPLETED", "SUMMARY:To Do", "X-OSAF-STARRED:true",
            "COMPLETED:20060227T080000Z",
            "DESCRIPTION:This is a very important TODO:\\n\\n\xe2\x80\xa2 Do one thing\\n\xe2\x80\xa2 Do somet",
            " hing else", "END:VTODO", "END:VCALENDAR")

        self.failUnlessEqual(1, len(self.items))

        item = self.items[0]
        task = pim.TaskStamp(item)

        self.failUnless(pim.has_stamp(task, pim.TaskStamp))
        self.failUnlessEqual(
            item.body,
            u"This is a very important TODO:\n\n\u2022 Do one thing\n\u2022 Do something else"
        )
        self.failUnlessEqual(item.triageStatus, pim.TriageEnum.done)
Ejemplo n.º 12
0
    def testCompleted(self):
        self.runImport("BEGIN:VCALENDAR", "VERSION:2.0", "CALSCALE:GREGORIAN",
                       "METHOD:PUBLISH", "BEGIN:VTODO",
                       "DTSTART:20060213T000000", "SUMMARY:ToDoneAndWhen",
                       "DTSTAMP:20060227T203912Z",
                       "UID:DD5D311A-F73F-4619-B463-A5766A1BAE5F",
                       "SEQUENCE:6", "STATUS:COMPLETED",
                       "COMPLETED:20060301T010000Z", "END:VTODO",
                       "END:VCALENDAR")

        self.failUnlessEqual(1, len(self.items))

        item = self.items[0]
        task = pim.TaskStamp(item)

        self.failIf(pim.has_stamp(task, pim.TaskStamp))
        self.failUnlessEqual(task.summary, u"ToDoneAndWhen")
        self.failUnlessEqual(task.itsItem.triageStatus, pim.TriageEnum.done)
        expectedTSC = datetime.datetime(2006, 3, 1, 1, 0, 0, 0, self.utc)
        self.failUnlessEqual(
            task.itsItem.triageStatusChanged,
            Triageable.makeTriageStatusChangedTime(self.view, expectedTSC))
Ejemplo n.º 13
0
def GenerateEventTask(view, days=30, tzinfo=None):
    """ Generate one Task/Event stamped item """
    event = GenerateCalendarEvent(view, days, tzinfo=tzinfo)
    pim.TaskStamp(event).add()
    return event
Ejemplo n.º 14
0
def createItems(paramDict):

    if bool(wx.GetApp()):
        view = QAUITestAppLib.App_ns.itsView
    else:  # when running unit tests there is no app
        view = NullRepositoryView(verify=True)
    tzinfo = view.tzinfo.getDefault()

    totalItems = int(paramDict['textCtrlTotalItems'])

    #get titles to use
    TITLES = getDataFromFile(paramDict['textCtrlTitleSourceFile'])

    #create collections to use
    collectionNames = addRandomWithoutDups(
        getDataFromFile(paramDict['textCtrlCollectionFileName']),
        int(paramDict['textCtrlCollectionCount']))
    sidebarCollections = createCollections(collectionNames, view)

    #determine how many collections each item should participate in
    collectionMembershipIndex = createMembershipIndex(
        paramDict['textCtrlCollectionMembership'], range(totalItems))
    collectionMembershipDict = {}
    ##fill collectionMembershipDict with correct number of collections for each item index
    for i in range(totalItems):
        collectionMembershipDict[i] = addRandomWithoutDups(
            sidebarCollections, collectionMembershipIndex[i])

    #get locations to use
    LOCATIONS = getDataFromFile(paramDict['textCtrlLocationSourceFilePath'])

    #get note field text
    NOTES = getDataFromFile(paramDict['textCtrlNoteSourceFilePath'], note=True)

    itemTypes = percentsToCount(
        totalItems, {
            'mail': int(paramDict['choicePercentMail']),
            'task': int(paramDict['choicePercentTask']),
            'event': int(paramDict['choicePercentEvent'])
        })

    triageStatus = percentsToCount(
        totalItems, {
            'unassigned': int(paramDict['choicePercentUnassignedStatus']),
            'now': int(paramDict['choicePercentNow']),
            'later': int(paramDict['choicePercentLater']),
            'done': int(paramDict['choicePercentDone'])
        },
        randomize=True)
    triageStatusAssignments = percentsToAssignments(triageStatus)
    #convert the string triage value to the triageEnum that can be used to set it
    triageEnums = {
        'now': pim.TriageEnum.now,
        'later': pim.TriageEnum.later,
        'done': pim.TriageEnum.done
    }
    triageStatusUnassigned = []
    for index, status in triageStatusAssignments.iteritems():
        if status == 'unassigned':
            triageStatusUnassigned.append(index)
        else:
            triageStatusAssignments[index] = triageEnums[status]

    recurTypes = percentsToCount(
        itemTypes['event'], {
            'non': int(paramDict['choicePercentNonRecurring']),
            'daily': int(paramDict['choicePercentDaily']),
            'weekly': int(paramDict['choicePercentWeekly']),
            'biweekly': int(paramDict['choicePercentBiWeekly']),
            'monthly': int(paramDict['choicePercentMonthly']),
            'yearly': int(paramDict['choicePercentYearly'])
        },
        randomize=True)

    durationTypes = percentsToCount(
        itemTypes['event'], {
            'allDay': int(paramDict['choicePercentAllDay']),
            'atTime': int(paramDict['choicePercentAtTime']),
            'anyTime': int(paramDict['choicePercentAnyTime']),
            'duration': int(paramDict['choicePercentDuration'])
        },
        randomize=True)

    eventStatus = percentsToCount(
        durationTypes['duration'], {
            'confirmed': int(paramDict['choicePercentConfirmed']),
            'FYI': int(paramDict['choicePercentFYI']),
            'tentative': int(paramDict['choicePercentTentative'])
        },
        randomize=True)
    eventStatusAssignment = percentsToAssignments(eventStatus)

    global startTimes
    startTimes = createStartTimeRange(paramDict['textCtrlTimeOfDay'],
                                      itemTypes['event'])

    startDateText = paramDict['textCtrlStartDate']
    if startDateText:
        y, m, d = startDateText.split(',')
        startDate = datetime(int(y), int(m), int(d))
        y, m, d = paramDict['textCtrlEndDate'].split(',')
        endDate = datetime(int(y), int(m), int(d))
        global dates
        dates = createDateRange(startDate, endDate)

    durationsTimed = createDurationIndex(paramDict['textCtrlDuration'],
                                         durationTypes['duration'])
    itemsWithDuration = durationsTimed.keys()

    relativeReminders, absoluteReminders = createAlarmIndex(
        paramDict['textCtrlAlarmSpec'], itemTypes['event'], totalItems, tzinfo)

    allRecurring = recurTypes['daily'] + recurTypes['weekly'] + recurTypes[
        'biweekly'] + recurTypes['monthly'] + recurTypes['yearly']
    recurenceEndDate = createEndDateIndex(
        paramDict['textCtrlRecurrenceEndDates'], allRecurring)

    # email stuff
    emailAddresses = []
    for firstName in firstNames:
        for lastName in lastNames:
            for domain in domainList:
                emailAddresses.append(firstName + lastName + '@' + domain)
    # get address sources
    if paramDict['textCtrlToFile'] == '':
        toAddresses = emailAddresses
    else:
        toAddresses = getDataFromFile(paramDict['textCtrlToFile'])

    if paramDict['textCtrlCCFileName'] == '':
        ccAddresses = emailAddresses
    else:
        ccAddresses = getDataFromFile(paramDict['textCtrlCCFileName'])

    if paramDict['textCtrlBCCFileName'] == '':
        bccAddresses = emailAddresses
    else:
        bccAddresses = getDataFromFile(paramDict['textCtrlBCCFileName'])

    # make email indexes from specs
    toIndex = createAddressIndex(itemTypes['mail'],
                                 paramDict['textCtrlToSpec'], toAddresses)
    ccIndex = createAddressIndex(itemTypes['mail'],
                                 paramDict['textCtrlCCSpec'], ccAddresses)
    bccIndex = createAddressIndex(itemTypes['mail'],
                                  paramDict['textCtrlBCCSpec'], bccAddresses)

    created = []
    for i in range(totalItems):
        created.append(pim.notes.Note(itsView=view))
        item = created[i]
        item.displayName = random.choice(TITLES)
        item.body = random.choice(NOTES)
        if i not in triageStatusUnassigned:
            item.setTriageStatus(triageStatusAssignments[i])
        if i in absoluteReminders.keys():
            item.setUserReminderTime(
                datetime.combine(date.today(), absoluteReminders[i]))
        if i in itemTypes['mail']:
            mailStampedItem = pim.MailStamp(item)
            mailStampedItem.add()
            if i in toIndex.keys():
                for address in toIndex[i]:
                    mailStampedItem.toAddress.append(
                        Mail.EmailAddress.getEmailAddress(view, address))
            if i in ccIndex.keys():
                for address in ccIndex[i]:
                    mailStampedItem.ccAddress.append(
                        Mail.EmailAddress.getEmailAddress(view, address))
            if i in bccIndex.keys():
                for address in bccIndex[i]:
                    mailStampedItem.bccAddress.append(
                        Mail.EmailAddress.getEmailAddress(view, address))
        if i in itemTypes['task']: pim.TaskStamp(item).add()
        if i in itemTypes['event']:
            eventStampedItem = pim.EventStamp(item)
            eventStampedItem.add()
            if i in itemsWithDuration:  #if its an event with duration then assign status
                eventStampedItem.transparency = eventStatusAssignment[i].lower(
                )
            eventStampedItem.location = Calendar.Location.getLocation(
                view, random.choice(LOCATIONS))
            eventStampedItem.anyTime = i in durationTypes['anyTime']
            eventStampedItem.allDay = i in durationTypes['allDay']
            eventStampedItem.startTime = createStartTime(i, tzinfo)
            if i in durationTypes['atTime']:
                eventStampedItem.duration = timedelta(0)
            else:
                if i in itemsWithDuration:
                    eventStampedItem.duration = durationsTimed[i]
            if i in relativeReminders.keys():
                eventStampedItem.setUserReminderInterval(relativeReminders[i])
            if i in allRecurring:
                ruleItem = RecurrenceRule(None, itsView=view)
                ruleSetItem = RecurrenceRuleSet(None, itsView=view)
                recurFreq = rangeName(i, recurTypes)
                #specail case biweekly
                if recurFreq == 'biweekly':
                    ruleItem.freq = 'weekly'
                    ruleItem.interval = 2
                else:
                    ruleItem.freq = recurFreq
                #add end date
                if i in recurenceEndDate and recurenceEndDate[
                        i]:  # zero means don't use an end date
                    endDateDate = calcEndDate(eventStampedItem.startTime,
                                              recurenceEndDate[i], recurFreq)
                    ruleItem.until = endDateDate
                ruleSetItem.addRule(ruleItem)
                eventStampedItem.rruleset = ruleSetItem
        for collection in collectionMembershipDict[i]:
            collection.add(item)
    return created  #return value used for testing in TestCreateItems.py:TestItemCreation
Ejemplo n.º 15
0
def installParcel(parcel, oldVersion=None):

    pim_ns = schema.ns('osaf.pim', parcel)
    sharing_ns = schema.ns('osaf.sharing', parcel)

    ClientIdentifier.update(parcel, 'clientID')

    ApplicationPrefs.update(parcel, 'prefs')

    AutoRestorePrefs.update(parcel, "autoRestorePrefs")

    message = _(u'User')

    me = pim.Contact.update(
        parcel,
        'me',
        # L10N: The word 'Me' is used to represent the
        #       current Chandler user.
        displayName=_(u'Me'),
        contactName=pim.ContactName.update(
            parcel,
            'meName',
            firstName=u'Chandler',
            #XXX Since the notion of 'me' may be going away
            #    there is no current need to refactor the
            #    last name attribute to the LocalizableString type.
            #    Thus for now will convert the c{Message} object
            #    returned from the c{ChandlerMessageFactory}
            #    to Unicode. This decision will be revisited later.
            lastName=unicode(message),
        ),
        references=[pim_ns.currentContact])

    # The Sidebar collection
    sidebarListCollection = pim.ListCollection.update(
        parcel,
        'sidebarCollection',
        inclusions=[
            pim_ns.allCollection, pim_ns.inCollection, pim_ns.outCollection,
            pim_ns.trashCollection
        ])

    testReply = pim.mail.EmailAddress.update(parcel, 'TestReplyAddress')

    # [i18n] Test Accounts are not displayed to the user and
    # do not require localization
    testSmtp = pim.mail.SMTPAccount.update(parcel,
                                           'TestSMTPAccount',
                                           displayName=u'Test SMTP Account',
                                           password=password.Password.update(
                                               parcel,
                                               'TestSMTPAccountPassword'),
                                           isActive=False)

    pim.mail.IMAPAccount.update(parcel,
                                'TestIMAPAccount',
                                displayName=u'Test IMAP mail',
                                replyToAddress=testReply,
                                password=password.Password.update(
                                    parcel, 'TestIMAPAccountPassword'),
                                isActive=False)

    pim.mail.POPAccount.update(parcel,
                               'TestPOPAccount',
                               displayName=u'Test POP mail',
                               replyToAddress=testReply,
                               defaultSMTPAccount=testSmtp,
                               password=password.Password.update(
                                   parcel, 'TestPOPAccountPassword'),
                               isActive=False)

    osafDev = pim.Contact.update(parcel,
                                 'OSAFContact',
                                 emailAddress=u'*****@*****.**',
                                 contactName=pim.ContactName.update(
                                     parcel,
                                     'OSAFContactName',
                                     firstName=u'OSAF',
                                     lastName=u'Development'))

    # OOTB collections and items (bugs 6545, 11772)
    # http://chandlerproject.org/bin/view/Journal/PreviewOOTBChandlerExperience
    #
    # (1) Don't create these in //parcels, or they won't get dumped
    # (2) Don't create these if reloading, or else there will be endless
    #     duplication of items/events
    # (3) We do want new UUIDs, so different users can share these
    #     collections/items to the same morsecode server
    # (4) The Welcome Event should be created regardless of whether
    #     we're reloading, because summaryblocks references it.
    #     (Maybe there's a better way to have it selected in the
    #      detail view?) -- Grant
    # (5) We create

    triageWhenValues = [datetime.datetime.now(parcel.itsView.tzinfo.default)]

    def changeTriage(itemOrStamp, triageValue):
        triageWhen = triageWhenValues.pop()
        item = getattr(itemOrStamp, 'itsItem', itemOrStamp)
        item.setTriageStatus(triageValue, triageWhen)
        triageWhenValues.append(triageWhen - datetime.timedelta(seconds=5))

    # OOTB item: Welcome Event
    noonToday = datetime.datetime.combine(
        datetime.date.today(),
        datetime.time(12, tzinfo=parcel.itsView.tzinfo.floating))

    WelcomeEvent = pim.EventStamp.update(
        parcel,
        'WelcomeEvent',
        # L10N: The Trademark symbol "TM" is represented in Unicode as U+2122
        displayName=_(u'Welcome to Chandler\u2122'),
        startTime=noonToday,
        duration=datetime.timedelta(minutes=60),
        anyTime=False,
        read=False,
        creator=osafDev,
        location=pim.Location.update(
            parcel,
            "OSAFLocation",
            displayName="Open Source Applications Foundation",
        ),
    )

    # L10N: The Trademark symbol "TM" is represented in Unicode as U+2122
    body = _(
        u"""Welcome to Chandler\u2122 %(version)s. Here is a list of resources to help you get started:

1. Get a tour of Chandler
(http://chandlerproject.org/tour).

2. Learn how to import calendars and set up Chandler to back up and share
(http://chandlerproject.org/getstarted).

3. Back up your data and Share by signing up for a Chandler Hub account
(http://hub.chandlerproject.org/signup).

4. Ask for help by sending mail to mailto:[email protected].

5. Learn more about the project on our wiki
(http://chandlerproject.org/wikihome).

6. Get involved and contribute to the project
(http://chandlerproject.org/getinvolved).

Thank you for trying Chandler!

The Chandler Team""") % {
            'version': version.version
        }

    WelcomeEvent.body = body
    WelcomeEvent.changeEditState(pim.Modification.created)
    changeTriage(WelcomeEvent, pim.TriageEnum.now)
    pim.TaskStamp(WelcomeEvent).add()

    if Globals.options.reload:
        schema.ns('osaf.pim', parcel.itsView).allCollection.add(WelcomeEvent)
    else:
        # OOTB user defined collections: collections should be in mine
        mine = schema.ns("osaf.pim", parcel.itsView).mine

        def makeCollection(name, checked, color):
            collection = pim.SmartCollection(itsView=parcel.itsView,
                                             displayName=name)
            # include collection in overlays, as spec'ed
            UserCollection(collection).checked = checked
            # set the collection color as spec'ed
            UserCollection(collection).setColor(color)

            sidebarListCollection.add(collection)
            mine.addSource(collection)

            return collection

        # OOTB user defined collections: Work, Home and Fun
        work = makeCollection(_(u"Work"), True, u'Blue')
        home = makeCollection(_(u"Home"), True, u'Red')
        fun = makeCollection(_(u"Fun"), False, u'Plum')

        # OOTB shared collection: U.S. Holidays
        holidays = makeCollection(_(u"U.S. Holidays"), True, u'Green')

        holidaysPath = pkg_resources.resource_filename(__name__,
                                                       "us_holidays.ics")
        sharing.importFile(parcel.itsView, holidaysPath, collection=holidays)

        dashboard = schema.ns("osaf.pim", parcel.itsView).allCollection

        # Add Welcome item to OOTB collections
        home.add(WelcomeEvent)
        work.add(WelcomeEvent)

        thisWeek = CalendarUtility.getCalendarRange(noonToday.date())

        def getDayInThisWeek(weekday):

            res = thisWeek[0]
            while res.weekday() != weekday:
                res += datetime.timedelta(days=1)
            return res

        # OOTB item 1: Next dentist appointment?
        event1 = pim.CalendarEvent(
            itsView=parcel.itsView,
            displayName=_(u"Next dentist appointment?"),
            startTime=noonToday.replace(hour=9),
            anyTime=True,
            collections=[home],
            read=True,
        )
        event1.itsItem.changeEditState(pim.Modification.created,
                                       when=noonToday.replace(hour=8))
        changeTriage(event1, pim.TriageEnum.now)

        # OOTB item #2: Tell a friend about Chandler
        item2 = pim.Note(
            itsView=parcel.itsView,
            displayName=_(u"Tell a friend about Chandler"),
            read=True,
            body=_(
                u"""Try sharing a collection with family, friends or colleagues.

Sign up for a Chandler Hub account to get started: http://hub.chandlerproject.org
"""),
        )

        schema.ns("osaf.pim", parcel.itsView).allCollection.add(item2)
        item2.changeEditState(pim.Modification.created,
                              when=noonToday.replace(hour=8))
        changeTriage(item2, pim.TriageEnum.now)

        # OOTB item #3: Write-up
        task3 = pim.Task(
            itsView=parcel.itsView,
            displayName=_(u"Write-up..."),
            collections=[work],
            read=True,
            body=
            _(u"""Start jotting down ideas for that big write-up you should really have started last week!

.
.
.
"""),
        )
        task3.itsItem.changeEditState(pim.Modification.created)
        changeTriage(task3, pim.TriageEnum.now)

        # OOTB item #4: Follow up
        task4 = pim.Task(
            itsView=parcel.itsView,
            displayName=_(u"Follow up with...on..."),
            read=True,
            body=
            _(u"""Maintain a list of things you need to discuss with a colleague:
.
.
.

(Click on the clock icon to add this note to the calendar for the next time you're going to meet with them.)
"""),
        )
        dashboard.add(task4.itsItem)
        task4.itsItem.changeEditState(pim.Modification.created)
        changeTriage(task4, pim.TriageEnum.now)

        # OOTB item #5: Start planning vacation
        task5 = pim.Task(
            itsView=parcel.itsView,
            displayName=_(u"Start planning vacation"),
            read=True,
            collections=[home],
            body=_("""Places you could go?
.
.
.

Activities you'd like to try?
.
.
.

Interesting travel articles?
.
.
.
"""),
        )

        changeTriage(task5, pim.TriageEnum.now)
        task5.itsItem.changeEditState(pim.Modification.created)

        # OOTB item #6: Bi-Weekly Status Report
        event5 = pim.CalendarEvent(
            itsView=parcel.itsView,
            displayName=_(u"Bi-Weekly Status Report"),
            startTime=noonToday,
            anyTime=True,
            read=True,
            collections=[work],
            body=_("""What have you been up to the last couple of weeks?
.
.
.
"""),
        )

        def makeRecurring(event, **kw):
            rule = pim.calendar.Recurrence.RecurrenceRule(
                itsView=parcel.itsView, **kw)

            event.rruleset = pim.calendar.Recurrence.RecurrenceRuleSet(
                itsView=parcel.itsView, rrules=[rule])
            for item in event.modifications:
                changeTriage(item, item._triageStatus)

        pim.TaskStamp(event5).add()
        event5.itsItem.changeEditState(pim.Modification.created)

        makeRecurring(event5, freq='weekly', interval=2)

        # OOTB item #6: Office supplies order
        startTime6 = datetime.datetime.combine(getDayInThisWeek(4),
                                               noonToday.timetz())

        event6 = pim.CalendarEvent(
            itsView=parcel.itsView,
            displayName=_(u"Office supplies order"),
            startTime=startTime6,
            anyTime=True,
            read=True,
            collections=[work],
            body=_(u"""Maintain a list of supplies you need to get every month:
.
.
.

(Share it with others so you can all maintain the list together!)
"""))
        changeTriage(event6, pim.TriageEnum.done)
        event6.itsItem.changeEditState(pim.Modification.created)
        makeRecurring(event6, freq='monthly')

        # OOTB item #7: Salsa class
        startTime7 = noonToday.replace(hour=14, minute=30)
        delta = 14 + startTime7.date().weekday() - 6
        startTime7 -= datetime.timedelta(days=delta)
        until7 = startTime7 + datetime.timedelta(days=28)
        event7 = pim.CalendarEvent(itsView=parcel.itsView,
                                   displayName=_(u"Salsa Class"),
                                   startTime=startTime7,
                                   duration=datetime.timedelta(hours=1),
                                   anyTime=False,
                                   read=True,
                                   collections=[home, fun],
                                   body=_(u"""Assignment for this week:
.
.
.

Remember to bring:
.
.
.
"""))
        event7.itsItem.changeEditState(pim.Modification.created,
                                       when=startTime7)
        changeTriage(event7, pim.TriageEnum.done)
        makeRecurring(event7, freq='weekly', until=until7)

        # A hack to get this occurrence to appear in the dashboard
        event7.getFirstOccurrence().getNextOccurrence().changeThis()
        for m in sorted(event7.modifications,
                        key=lambda o: pim.EventStamp(o).startTime):
            changeTriage(m, m._triageStatus)

        # OOTB item #8: Brunch potluck...
        startTime8 = datetime.datetime.combine(
            getDayInThisWeek(6), datetime.time(11, 0, tzinfo=noonToday.tzinfo))

        event8 = pim.CalendarEvent(
            itsView=parcel.itsView,
            displayName=_(u"Brunch potluck..."),
            startTime=startTime8,
            duration=datetime.timedelta(hours=2),
            anyTime=False,
            read=True,
            collections=[home, fun],
            body=_(u"""Directions
.
.
.

Ideas for games to bring...
.
.
.

Sign up to bring food...
.
.
.
"""),
        )
        changeTriage(event8, event8.autoTriage())
        event8.itsItem.changeEditState(pim.Modification.created)

        # OOTB Item #9: Ideas for presents
        item9 = pim.Note(
            itsView=parcel.itsView,
            displayName=_(u"Ideas for presents"),
            read=True,
            collections=[home],
            body=
            _(u"""Maintain a list of possible presents for family, friends and colleagues so you're never short on ideas!
.
.
.
"""),
        )
        changeTriage(item9, pim.TriageEnum.later)
        item9.changeEditState(pim.Modification.edited)

        # OOTB Item #10: Thank you notes
        item10 = pim.Note(
            itsView=parcel.itsView,
            displayName=_(u"Thank you notes"),
            read=True,
            collections=[home],
            body=
            _(u"""Who do you need to write thank you notes to? and for what reason?
.
.
.


"""),
        )

        changeTriage(item10, pim.TriageEnum.later)
        item10.changeEditState(pim.Modification.created)

        # OOTB Item #11: Movie list
        item11 = pim.Note(
            itsView=parcel.itsView,
            displayName=_(u"Movie list"),
            read=True,
            collections=[fun, home],
            body=_(u"""Movies you want to see:

.
.
.
"""),
        )

        changeTriage(item11, pim.TriageEnum.later)
        item11.changeEditState(pim.Modification.created)

        # OOTB Item #12: Book list
        item12 = pim.Note(
            itsView=parcel.itsView,
            displayName=_(u"Book list"),
            read=True,
            collections=[fun, home],
            body=_(
                u"""Book recommendations you've been meaning to follow up on:

.
.
.
"""),
        )

        changeTriage(item12, pim.TriageEnum.later)
        item12.changeEditState(pim.Modification.created)

        # OOTB Item #13: File taxes
        startTime13 = noonToday.replace(month=4, day=15)
        alarmTime13 = startTime13.replace(day=1)
        if alarmTime13 < noonToday:
            alarmTime13 = alarmTime13.replace(year=alarmTime13.year + 1)
            startTime13 = startTime13.replace(year=startTime13.year + 1)

        event13 = pim.CalendarEvent(
            itsView=parcel.itsView,
            startTime=startTime13,
            displayName=_(u"File taxes!"),
            read=True,
            collections=[home],
            body=_(u"""What forms do you have in hand?
.
.
.

What are you missing?
.
.
.

Questions for your accountant?
.
.
.
"""),
        )

        pim.TaskStamp(event13).add()
        event13.itsItem.changeEditState(pim.Modification.created)
        changeTriage(event13, pim.TriageEnum.later)
        event13.itsItem.userReminderTime = alarmTime13

        # OOTB Item #14: Class Trip: Exhibit on Sound!
        location14 = pim.Location.update(
            parcel,
            "Exploratorium",
            displayName="Exploratorium",
        )

        startTime14 = datetime.datetime.combine(
            getDayInThisWeek(6), datetime.time(15, tzinfo=noonToday.tzinfo))

        event14 = pim.CalendarEvent(
            itsView=parcel.itsView,
            startTime=startTime14,
            displayName=_(u"Class Trip: Exhibit on Sound!"),
            read=True,
            location=location14,
            collections=[fun],
            body=_(u"""Directions...
.
.
.
"""),
        )
        event14.itsItem.changeEditState(pim.Modification.edited,
                                        when=startTime14)
        changeTriage(event14, pim.TriageEnum.done)

        # OOTB Item #15: Download Chandler!
        note15 = pim.Note(
            itsView=parcel.itsView,
            displayName=_(u"Download Chandler!"),
            read=True,
        )
        dashboard.add(note15)
        done15 = datetime.datetime.now(parcel.itsView.tzinfo.default)
        done15 -= datetime.timedelta(minutes=5)
        done15 = done15.replace(second=0, microsecond=0)
        changeTriage(note15, pim.TriageEnum.done)
        note15.changeEditState(pim.Modification.edited, when=done15)

        # Set up sharing for holidays
        share = sharing.Share(itsView=parcel.itsView,
                              mode='get',
                              contents=holidays,
                              established=True)
        filters = set([
            'cid:[email protected]', 'cid:[email protected]',
            'cid:[email protected]', 'cid:[email protected]',
            'cid:[email protected]'
        ])
        share.conduit = sharing.WebDAVMonolithicRecordSetConduit(
            itsParent=share,
            host=u'hub.chandlerproject.org',
            port=443,
            sharePath=u'webcal/collection',
            shareName=u'7febe2f4-324c-11dd-d9e4-0016cbca6aed?ticket=01q75n1sy0',
            useSSL=True,
            filters=filters,
            translator=sharing.SharingTranslator,
            serializer=sharing.ICSSerializer)
        share.conduit.ticketReadOnly = share.conduit.ticket
        sharing.SharedItem(share.contents).add()
        sharing.SharedItem(share.contents).shares.append(share)

    # Set up the main web server
    from osaf import webserver

    startup.Startup.update(parcel,
                           "startServers",
                           invoke="osaf.webserver.start_servers")

    webserver.Server.update(
        parcel,
        "mainServer",
        # Port to listen on.  1888 was the year Raymond Chandler was born.
        port=1888,

        # This path specifies the "doc root" of this web server, and is
        # relative to webserver/servers, but you may also put in an
        # absolute path if you wish.
        #
        path=unicode(os.path.join("parcels", "osaf", "app", "webhome")),
        resources=[
            webserver.Resource.update(
                parcel,
                "lobsResource",
                displayName=u"Lob Server",
                location=u"lobs",
                resourceClass=schema.importString(
                    "osaf.servlets.lobviewer.LobViewerResource"),
            ),
            webserver.Resource.update(
                parcel,
                "photoResource",
                displayName=u"Photo Viewer",
                location=u"photos",
                resourceClass=schema.importString(
                    "osaf.servlets.photo.PhotosResource"),
            ),
            webserver.Resource.update(parcel,
                                      "repoResource",
                                      displayName=u"Repository Viewer",
                                      location=u"repo",
                                      resourceClass=schema.importString(
                                          "osaf.servlets.repo.RepoResource"),
                                      autoView=False),
            webserver.Resource.update(parcel,
                                      "prefResource",
                                      displayName=u'Preference Editor',
                                      location=u"prefs",
                                      resourceClass=schema.importString(
                                          "osaf.servlets.prefs.PrefResource"),
                                      autoView=False),
            webserver.Resource.update(
                parcel,
                "xmlrpcResource",
                displayName=u'XML-RPC Service',
                location=u"xmlrpc",
                resourceClass=schema.importString(
                    "osaf.servlets.xmlrpc.XmlRpcResource"),
                autoView=False),
        ])

    from osaf.app import updates

    # Subtract 15 minutes from lastRun so that in a week's
    # time we don't conflict with the "compact" trask.
    updates.UpdateCheckTask.update(parcel,
                                   'updateCheckTask',
                                   interval=datetime.timedelta(days=1),
                                   lastRun=datetime.datetime.now() -
                                   datetime.timedelta(minutes=15))

    # Compact task should come last
    from osaf.app import compact
    compact.CompactTask.update(parcel, 'compactTask')