Esempio n. 1
0
def GenerateNote(view):
    """ Generate one Note item """
    note = pim.Note(view=view)
    note.displayName = random.choice(TITLES)
    delta = timedelta(days=random.randint(0, 5), hours=random.randint(0, 24))
    note.createdOn = datetime.now() + delta
    return note
    def testSmartCollection(self):
        trash = self.trash
        coll1 = SmartCollection(itsView=self.view, trash=trash)
        coll2 = SmartCollection(itsView=self.view, trash=trash)
        coll3 = SmartCollection(itsView=self.view, trash=trash)
        note = pim.Note(itsView=self.view)

        # Ensure that removing an item from its last collection puts it into
        # the trash
        coll1.add(note)
        self.assert_(note in coll1)
        self.assert_(note not in trash)
        coll1.remove(note)
        self.assert_(note not in coll1)
        self.assert_(note in trash)

        # Ensure that adding an item to the trash removes it from all
        # collections
        coll1.add(note)
        coll2.add(note)
        self.assert_(note in coll1)
        self.assert_(note in coll2)
        trash.add(note)
        self.assert_(note not in coll1)
        self.assert_(note not in coll2)

        # Ensure that then removing it from the trash puts it back in those
        # collections (only if it was there before)
        trash.remove(note)
        self.assert_(note in coll1)
        self.assert_(note in coll2)
        self.assert_(note not in coll3)
Esempio n. 3
0
def GenerateNote(view, mainView, args):
    """ Generate one Note item """
    note = pim.Note(view=view)
    #displayName
    if args[0] == '*':  # semi-random data
        note.displayName = random.choice(TITLES)
    elif not args[0] == '':
        note.displayName = args[0]
    else:
        note.displayName = 'untitled'  #default value
    #createdOn
    note.createdOn = ReturnCompleteDatetime(args[2], args[3])
    #collection
    if args[1] == '*':  # semi-random data
        collectionsDict.values()[random.randint(0,
                                                len(collectionsDict) -
                                                1)].add(note)
    elif not args[1] == '':
        collectionNames = string.split(args[1], ';')
        for name in collectionNames:
            if collectionsDict.has_key(name):
                collectionsDict[name].add(note)
            else:
                GenerateCollection(view, mainView, [name])
                collectionsDict[name].add(note)

    return note
    def _makeEvent(self, displayName, startTime):
        note = pim.Note(itsView=self.app_ns.itsView)
        note.displayName = displayName
        note.setTriageStatus(pim.TriageEnum.later)

        self.collection.item.add(note)
        evt = pim.EventStamp(note)
        evt.add()
        evt.allDay = False
        evt.anyTime = False
        evt.startTime = startTime
        return evt
Esempio n. 5
0
def GenerateNote(view, tzinfo=None):
    """ Generate one Note item """
    note = pim.Note(itsView=view)
    note.displayName = random.choice(TITLES)

    if TEST_I18N:
        note.displayName = uw(note.displayName)

    delta = timedelta(days=random.randint(0, 5), hours=random.randint(0, 24))
    note.createdOn = datetime.now(tzinfo) + delta
    note.setTriageStatus(randomEnum(pim.TriageEnum))
    return note
Esempio n. 6
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)
Esempio n. 7
0
 def xmlrpc_note(self, title, body, viewName=None):
     view = getServletView(self.repositoryView.repository, viewName)
     view.refresh()
     note = pim.Note(itsView=view, displayName=title, body=body)
     event = pim.EventStamp(note)
     event.add()
     event.startTime = datetime.datetime.now(tz=view.tzinfo.floating)
     event.duration = datetime.timedelta(minutes=60)
     event.anyTime = False
     allCollection = schema.ns('osaf.pim', view).allCollection
     allCollection.add(note)
     view.commit()
     return "OK" # ???
Esempio n. 8
0
    def testInsufficientPrivileges(self):
        item = pim.Note(itsParent=self.sandbox, displayName=u"Hi, mom!")
        try:
            self.cosmoConduit.raiseCosmoError(
                """<?xml version='1.0' encoding='UTF-8'?>
<mc:error xmlns:mc="http://osafoundation.org/mc/">
<mc:insufficient-privileges>
<mc:target-uuid>%s</mc:target-uuid>
<mc:required-privilege>READ</mc:required-privilege>
</mc:insufficient-privileges>
</mc:error>
""" % (item.itsUUID.str16()))
        except sharing.errors.ForbiddenItem, e:
            self.failUnless(unicode(e).find(item.displayName) != -1)
            self.failUnlessEqual(e.uuid, item.itsUUID.str16())
    def PrepareTestData(self):

        view0 = self.views[0]

        item0 = pim.Note(itsView=view0)
        item0.displayName = "test displayName"
        item0.body = "test body"
        self.itemuuid = item0.itsUUID.str16()

        coll = pim.ListCollection(itsView=view0, displayName="Collection a")
        coll.add(item0)
        self.coluuida = coll.itsUUID.str16()

        coll = pim.ListCollection(itsView=view0, displayName="Collection b")
        coll.add(item0)
        self.coluuidb = coll.itsUUID.str16()
Esempio n. 10
0
    def testNotes(self):
        """ Simple test for creating instances of note related kinds """

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

        def _verifyNote(note):
            self.assertEqual(note.displayName, "sample note")

            reader = note.body.getReader()
            self.assertEqual(reader.read(), "more elaborate sample note body")
            reader.close()

        # Test the globals
        notesPath = Path('//parcels/osaf/pim')
        view = self.rep.view

        self.assertEqual(pim.Note.getKind(view),
                         view.find(Path(notesPath, 'Note')))

        # Construct sample items
        noteItem = pim.Note("noteItem", view=view)

        # Double check kinds
        self.assertEqual(noteItem.itsKind, pim.Note.getKind(view))

        # Literal properties
        noteItem.displayName = "sample note"

        # Lob property
        lobType = noteItem.getAttributeAspect('body', 'type')

        # when data is unicode, encoding defaults to utf-8
        noteItem.body = lobType.makeValue(u"more elaborate sample note body")

        _verifyNote(noteItem)

        self._reopenRepository()

        contentItemParent = self.rep.findPath("//userdata")

        noteItem = contentItemParent.getItemChild("noteItem")

        _verifyNote(noteItem)
Esempio n. 11
0
def process_create(view, subcommand, text):
    if subcommand == 'note':
        note = pim.Note(itsView=view, displayName=text)
        view.commit()
    elif subcommand == 'event':
        first_space = text.find(' ')
        s = text[:first_space]
        second_space = text.find(' ', first_space + 1)
        l = text[first_space + 1:second_space]
        data = text[second_space + 1:]

        start = parse_datetime(s)
        length = parse_timedelta(l)
        task = Calendar.CalendarEvent(itsView=view,
                                      startTime=start,
                                      duration=length)
        view.commit()
    elif subcommand == 'task':
        task = pim.Task(itsView=view, displayName=text)
        view.commit()
    else:
        print "illegal create subcomand"
    def testNotes(self):
        """ Simple test for creating instances of note related kinds """

        self.loadParcel("osaf.pim")

        def _verifyNote(note):
            self.assertEqual(note.displayName, uw("sample note"))

            self.assertEqual(note.body, uw("more elaborate sample note body"))

        # Test the globals
        notesPath = Path('//parcels/osaf/pim')
        view = self.view

        self.assertEqual(pim.Note.getKind(view),
                         view.find(Path(notesPath, 'Note')))

        # Construct sample items
        noteItem = pim.Note("noteItem", itsView=view)

        # Double check kinds
        self.assertEqual(noteItem.itsKind, pim.Note.getKind(view))

        # Literal properties
        noteItem.displayName = uw("sample note")

        noteItem.body = uw("more elaborate sample note body")

        _verifyNote(noteItem)

        self._reopenRepository()
        view = self.view
        contentItemParent = view.findPath("//userdata")

        noteItem = contentItemParent.getItemChild("noteItem")

        _verifyNote(noteItem)
    def PrepareTestData(self):

        item0 = pim.Note(itsView=self.views[0])
        item0.displayName = "test displayName"
        item0.body = "test body"
        self.uuid = item0.itsUUID.str16()
    def testStamping(self):
        view = self.sandbox.itsView

        # Get the stamp kinds
        mailStamp = Mail.MailStamp
        taskStamp = pim.TaskStamp
        eventStamp = Calendar.EventStamp
        noteKind = pim.Note.getKind(view)

        # start out with a Note
        aNote = pim.Note("noteItem1", itsParent=self.sandbox)
        self.setAttributes(aNote, doWho=False)
        self.assertAttributes(aNote)
        add = 'add'
        remove = 'remove'

        # stamp everything on and off the note
        self.traverseStampSquence(aNote,
                                  ((add, mailStamp), (add, taskStamp),
                                   (add, eventStamp), (remove, eventStamp),
                                   (remove, taskStamp), (remove, mailStamp)))

        # stamp everything on again, remove in a different order
        self.traverseStampSquence(aNote,
                                  ((add, mailStamp), (add, taskStamp),
                                   (add, eventStamp), (remove, mailStamp),
                                   (remove, taskStamp), (remove, eventStamp)))
        self.assertAttributes(aNote)

        # Create a Task, and do all kinds of stamping on it
        aTask = pim.Task("aTask", itsParent=self.sandbox).itsItem
        self.setAttributes(aTask)

        self.traverseStampSquence(aTask,
                                  ((add, eventStamp), (remove, taskStamp)))
        # now it's an Event

        self.traverseStampSquence(aTask,
                                  ((add, mailStamp), (remove, mailStamp)))

        self.traverseStampSquence(aTask,
                                  ((add, mailStamp), (add, taskStamp),
                                   (remove, mailStamp), (remove, taskStamp)))

        self.traverseStampSquence(aTask,
                                  ((add, taskStamp), (add, mailStamp),
                                   (remove, mailStamp), (remove, taskStamp)))

        self.traverseStampSquence(aTask,
                                  ((add, mailStamp), (remove, eventStamp)))
        # now it's a Mail

        self.traverseStampSquence(aTask,
                                  ((add, taskStamp), (remove, mailStamp)))
        # it's a Task again

        self.traverseStampSquence(aTask,
                                  ((add, mailStamp), (remove, taskStamp)))

        self.traverseStampSquence(aTask,
                                  ((add, taskStamp), (remove, mailStamp)))
        # it's a Task again

        self.traverseStampSquence(aTask,
                                  ((add, eventStamp), (remove, taskStamp),
                                   (add, mailStamp), (remove, eventStamp),
                                   (add, taskStamp), (remove, mailStamp)))
        self.failUnless(has_stamp(aTask, taskStamp))

        # check stamping on an Event
        anEvent = Calendar.CalendarEvent("anEvent",
                                         itsParent=self.sandbox).itsItem
        self.setAttributes(anEvent)

        # round-robin its Kind back to event
        self.traverseStampSquence(anEvent,
                                  ((add, mailStamp), (remove, eventStamp),
                                   (add, taskStamp), (remove, mailStamp),
                                   (add, eventStamp), (remove, taskStamp)))
        self.failUnless(has_stamp(anEvent, eventStamp))

        # check stamping on a Mail Message
        aMessage = Mail.MailMessage("aMessage", itsParent=self.sandbox).itsItem
        self.setAttributes(aMessage)
        self.traverseStampSquence(aMessage,
                                  ((add, eventStamp), (add, taskStamp),
                                   (remove, eventStamp), (remove, taskStamp)))
        self.failUnless(has_stamp(aMessage, mailStamp))

        # now mixin some arbitrary Kind
        #anotherKind = view.findPath('//parcels/osaf/framework/blocks/Block')

        # stamp an event, mail, task with another kind
        #aNote.StampKind(add, anotherKind)
        #aTask.StampKind(add, anotherKind)
        #anEvent.StampKind(add, anotherKind)
        #aMessage.StampKind(add, anotherKind)

        #self.assertKinds(aNote, (noteKind, anotherKind))
        #self.assertKinds(aTask, (taskKind, anotherKind))
        #self.assertKinds(anEvent, (eventKind, anotherKind))
        #self.assertKinds(aMessage, (mailKind, anotherKind))

        # unstamp with another kind
        #aNote.StampKind(remove, anotherKind)
        #aTask.StampKind(remove, anotherKind)
        #anEvent.StampKind(remove, anotherKind)
        #aMessage.StampKind(remove, anotherKind)

        # see that they still have their attributes
        #self.assertKinds(aNote, (noteKind, ))
        #self.assertKinds(aTask, (taskKind, ))
        #self.assertKinds(anEvent, (eventKind, ))
        #self.assertKinds(aMessage, (mailKind, ))

        # Test some failure cases
        # These cases should produce suitable warning messages in Chandler.log
        if testFailureCases:
            anotherEvent = Calendar.CalendarEvent(
                "anotherEvent", itsParent=self.sandbox).itsItem
            self.setAttributes(anotherEvent)
            self.failUnless(has_stamp(anotherEvent, eventStamp))
            # Could use assertRaises here, but it's syntax with respect to parameters is
            #   not clear with my complex arguments, so try/except/else is more readable.
            try:
                # double stamping
                self.traverseStampSquence(anotherEvent,
                                          ((add, mailStamp), (add, mailStamp)))
            except StampAlreadyPresentError:
                pass
            else:
                self.failUnless(False,
                                "Double stamping should raise an exception!")

            try:
                # unstamping something not present
                self.traverseStampSquence(anotherEvent,
                                          ((remove, taskStamp), ))
            except StampNotPresentError:
                pass
            else:
                self.failUnless(
                    False,
                    "Unstamping a stamp not present should raise an exception!"
                )
            # Test for Bug:6151: Make sure items don't disappear
            # from the all collection if they're unstamped
            #
            # Make an email ...
            aMessage = Mail.MailMessage("aNewMessage", itsParent=self.sandbox)
            self.setAttributes(aMessage.itsItem)

            # Make sure it's in "Out"
            aMessage.fromMe = True
            outCollection = schema.ns("osaf.pim", view).outCollection

            self.failUnless(aMessage.itsItem in outCollection)

            # unstamp its emailness
            self.traverseStampSquence(aMessage.itsItem,
                                      (('add', taskStamp),
                                       ('remove', mailStamp)))

            allCollection = schema.ns("osaf.pim", view).allCollection
            self.failUnless(aMessage.itsItem in allCollection)
    def testRemoveItem(self):
        # Simulate removing an item from a not-mine collection, ensuring it
        # doesn't go into the All collection, but rather moves to the Trash
        # if it's not in any other collections

        trash = self.trash
        notes = KindCollection(itsView=self.view,
                               kind=pim.Note.getKind(self.view),
                               recursive=True)
        mine = UnionCollection(itsView=self.view)
        myNotes = IntersectionCollection(itsView=self.view,
                                         sources=(mine, notes))

        all = SmartCollection(itsView=self.view,
                              source=myNotes,
                              exclusions=trash,
                              trash=None)

        # coll2 and coll3 are 'mine', coll1 is not
        coll1 = SmartCollection(itsView=self.view, trash=trash)
        coll2 = SmartCollection(itsView=self.view, trash=trash)
        mine.addSource(coll2)
        coll3 = SmartCollection(itsView=self.view, trash=trash)
        mine.addSource(coll3)

        note = pim.Note(itsView=self.view)

        # note is only in a not-mine collection, so removing it from that
        # collection should put it in the trash, and not appear in all
        coll1.add(note)
        self.assert_(note in coll1)
        self.assert_(note not in all)
        coll1.remove(note)
        self.assert_(note not in coll1)
        self.assert_(note not in all)
        self.assert_(note in trash)

        # note is in two collections, one of them a not-mine, so it
        # should appear in 'all' and not the trash
        coll1.add(note)
        coll2.add(note)
        self.assert_(note in coll1)
        self.assert_(note in coll2)
        self.assert_(note not in trash)
        self.assert_(note in all)

        # removing note from the only not-mine collection should not move the
        # item to trash, and the item should appear in all
        coll1.remove(note)
        self.assert_(note not in coll1)
        self.assert_(note in coll2)
        self.assert_(note not in trash)
        self.assert_(note in all)

        # removing note from one not-mine collection, but having it still
        # remain in another not-mine collection should not have the item go
        # to trash, but it will appear in all
        coll1.add(note)
        coll3.add(note)
        mine.removeSource(coll3)
        self.assert_(note in coll1)
        self.assert_(note in coll2)
        self.assert_(note in coll3)
        self.assert_(note not in trash)
        self.assert_(note in all)
        coll3.remove(note)
        self.assert_(note in coll1)
        self.assert_(note in coll2)
        self.assert_(note not in coll3)
        self.assert_(note not in trash)
        self.assert_(note in all)
    def RoundTrip(self):

        filename = "tmp_dump_file"

        view0 = self.views[0]
        view1 = self.views[1]

        # uuids to dump; add your items to this:
        uuids = set()

        # Prepare test data

        coll0 = pim.SmartCollection("testCollection",
                                    itsView=view0,
                                    displayName="Test Collection")
        uuids.add(coll0.itsUUID)

        titles = [
            u"dunder",
            u"mifflin",
        ]

        tzinfo = view0.tzinfo.floating
        createdOn = datetime.datetime(2007, 3, 1, 10, 0, 0, 0, tzinfo)
        lastModified = datetime.datetime(2007, 3, 1, 12, 0, 0, 0, tzinfo)
        email = "*****@*****.**"
        emailAddress = pim.EmailAddress.getEmailAddress(view0, email)

        count = len(titles)
        for i in xrange(count):
            n = pim.Note(itsView=view0)
            n.createdOn = createdOn
            n.displayName = titles[i % count]
            n.body = u"Here is the body"
            n.lastModifiedBy = emailAddress
            n.lastModified = lastModified
            coll0.add(n)
            uuids.add(n.itsUUID)

        # Read/unread items
        readNote = pim.Note(itsView=view0, read=True)
        unreadNote = pim.Note(itsView=view0, read=False)

        # "Private" items
        publicNote = pim.Note(itsView=view0, private=False)
        privateNote = pim.Note(itsView=view0, private=True)

        # Mine/Not-Mine/Dashboard

        directlyInDashboard = pim.Note(itsView=view0)
        dashboard = schema.ns("osaf.pim", view0).allCollection
        dashboard.add(directlyInDashboard)

        aMineCollection = pim.SmartCollection(itsView=view0)
        schema.ns('osaf.pim', view0).mine.addSource(aMineCollection)
        inMine = pim.Note(itsView=view0)
        aMineCollection.add(inMine)

        aNotMineCollection = pim.SmartCollection(itsView=view0)
        inNotMine = pim.Note(itsView=view0)
        aNotMineCollection.add(inNotMine)

        trash = schema.ns("osaf.pim", view0).trashCollection
        trashTestCollection = pim.SmartCollection(itsView=view0)
        trashedItem = pim.Note(itsView=view0)
        trashTestCollection.add(trashedItem)
        trash.add(trashedItem)
        self.assert_(trashedItem in trashTestCollection.inclusions)
        self.assert_(trashedItem not in trashTestCollection)
        self.assert_(trashedItem in trash)

        # Sharing related items
        account0 = sharing.CosmoAccount(itsView=view0,
                                        host="chandler.o11n.org",
                                        port=8080,
                                        path="/cosmo",
                                        username="******",
                                        password=Password(itsView=view0),
                                        useSSL=True)
        waitForDeferred(account0.password.encryptPassword('4cc0unt0'))
        uuids.add(account0.itsUUID)
        cosmo_conduit0 = sharing.CosmoConduit(
            itsView=view0,
            account=account0,
            shareName=coll0.itsUUID.str16(),
            translator=sharing.SharingTranslator,
            serializer=sharing.EIMMLSerializer)
        uuids.add(cosmo_conduit0.itsUUID)
        cosmo_share0 = sharing.Share(itsView=view0,
                                     contents=coll0,
                                     conduit=cosmo_conduit0)
        uuids.add(cosmo_share0.itsUUID)

        hub_account0 = sharing.HubAccount(
            itsView=view0,
            username="******",
            password=Password(itsView=view0),
        )
        waitForDeferred(hub_account0.password.encryptPassword('4cc0unt0'))
        uuids.add(hub_account0.itsUUID)

        inmemory_conduit0 = sharing.InMemoryDiffRecordSetConduit(
            itsView=view0,
            shareName="in_memory",
            translator=sharing.SharingTranslator,
            serializer=sharing.EIMMLSerializer)
        uuids.add(inmemory_conduit0.itsUUID)

        inmemory_share0 = sharing.Share(itsView=view0,
                                        conduit=inmemory_conduit0,
                                        contents=coll0)
        uuids.add(inmemory_share0.itsUUID)

        # Create some State objects
        inmemory_share0.create()
        view0.commit()
        inmemory_share0.sync()
        for state in inmemory_share0.states:
            uuids.add(state.itsUUID)
        # Set one of the states to be a pendingRemoval
        pendingRemoval = state.itsUUID
        state.pendingRemoval = True

        # Peer states
        peerNote = pim.Note(itsView=view0)
        peerAddress = pim.EmailAddress(
            itsView=view0,
            fullName="Michael Scott",
            emailAddress="*****@*****.**")
        peerState = sharing.State(
            itsView=view0,
            conflictFor=peerNote,
            peer=peerAddress,
        )
        sharing.SharedItem(peerNote).add()
        sharedPeerNote = sharing.SharedItem(peerNote)
        sharedPeerNote.peerStates = []
        sharedPeerNote.peerStates.append(peerState,
                                         peerAddress.itsUUID.str16())
        uuids.add(peerNote.itsUUID)
        uuids.add(peerAddress.itsUUID)
        uuids.add(peerState.itsUUID)

        # Sharing proxy
        proxy = sharing.getProxy(view0)
        proxy.host = "host"
        proxy.port = 123
        proxy.username = "******"
        proxy.passwd = "password"
        proxy.active = True
        proxy.useAuth = True
        proxy.bypass = "******"
        uuids.add(proxy.itsUUID)

        # Online state
        schema.ns('osaf.app', view0).prefs.isOnline = False
        schema.ns('osaf.sharing', view0).prefs.isOnline = False

        #Mail Accounts

        imapAddress = mail.EmailAddress.getEmailAddress(
            view0, "*****@*****.**", "test")

        popAddress = mail.EmailAddress.getEmailAddress(view0, "*****@*****.**",
                                                       "test1")

        smtpOldAddress = mail.EmailAddress.getEmailAddress(
            view0, "*****@*****.**", "test2")

        smtpNewAddress = mail.EmailAddress.getEmailAddress(
            view0, "*****@*****.**", "test3")

        testFolder = mail.IMAPFolder(itsView=view0,
                                     displayName="TestFolder",
                                     folderName="INBOX.TestFolder",
                                     folderType="MAIL")

        queuedMessage0 = pim.MailStamp(pim.Note(itsView=view0))
        queuedMessage0.add()

        queuedMessage0.subject = "Test for SMTP Queue"

        uuids.add(queuedMessage0.itsItem.itsUUID)

        imapaccount0 = mail.IMAPAccount(
            itsView=view0,
            displayName="IMAP Test",
            host="localhost",
            port=143,
            username="******",
            password=Password(itsView=view0),
            connectionSecurity="TLS",
            numRetries=2,
            pollingFrequency=300,
            isActive=False,
            replyToAddress=imapAddress,
            folders=[testFolder],
        )
        waitForDeferred(imapaccount0.password.encryptPassword('imap4acc0unt0'))

        uuids.add(imapaccount0.itsUUID)

        popaccount0 = mail.POPAccount(
            itsView=view0,
            displayName="POP Test",
            host="localhost",
            port=110,
            username="******",
            password=Password(itsView=view0),
            connectionSecurity="NONE",
            numRetries=3,
            pollingFrequency=200,
            isActive=True,
            replyToAddress=popAddress,
        )
        waitForDeferred(popaccount0.password.encryptPassword('pop4acc0unt0'))

        uuids.add(popaccount0.itsUUID)

        smtpaccount0 = mail.SMTPAccount(
            itsView=view0,
            displayName="SMTP Test",
            host="localhost",
            port=587,
            username="******",
            password=Password(itsView=view0),
            connectionSecurity="SSL",
            numRetries=5,
            pollingFrequency=500,
            isActive=True,
            fromAddress=smtpOldAddress,
            useAuth=True,
            messageQueue=[queuedMessage0.itsItem],
        )
        waitForDeferred(smtpaccount0.password.encryptPassword('smtp4acc0unt0'))

        # This orphans smtpOldAddress leaving it as
        # an old me address which is stored in the
        # meEmailAddressCollection.
        # The purpose of this is to test dump and reload
        # of the meEmailAddressCollection.
        smtpaccount0.fromAddress = smtpNewAddress

        uuids.add(smtpaccount0.itsUUID)

        #Take the mail service offline
        schema.ns("osaf.pim", view0).MailPrefs.isOnline = False

        # Calendar prefs
        pref = schema.ns('osaf.pim', view0).TimezonePrefs
        pref.showUI = True  # change from default
        pref.showPrompt = False  # change from default

        pref = schema.ns('osaf.framework.blocks.calendar', view0).calendarPrefs
        pref.hourHeightMode = "auto"
        pref.visibleHours = 20

        # TODO: TimeZoneInfo

        # passwords
        pw = Password(itsView=view0)
        waitForDeferred(pw.encryptPassword('foobar'))
        uuids.add(pw.itsUUID)
        # password prefs
        mpwPrefs = schema.ns("osaf.framework.MasterPassword",
                             view0).masterPasswordPrefs
        MasterPassword._change('', 'secret', view0, mpwPrefs)
        mpwPrefs.timeout = 10

        # backup on quit preference
        backupPrefs = schema.ns("osaf.app", view0).prefs
        self.assertFalse(hasattr(backupPrefs, 'backupOnQuit'))
        backupPrefs.backupOnQuit = True

        # tip of the day prefs
        self.assertFalse(backupPrefs.showTip)
        self.assertEqual(backupPrefs.tipIndex, 0)
        backupPrefs.tipIndex = 1

        # Ensure sidebar is loaded in view1
        sidebar1 = schema.ns("osaf.app", view1).sidebarCollection

        try:

            dumpreload.dump(view0, filename)
            dumpreload.reload(view1, filename, testmode=True)

            # Ensure the items are now in view1
            for uuid in uuids:
                item0 = view0.findUUID(uuid)
                item1 = view1.findUUID(uuid)

                self.assert_(item1 is not None)
                if hasattr(item0, 'displayName'):
                    self.assertEqual(item0.displayName, item1.displayName)
                if hasattr(item0, 'body'):
                    self.assertEqual(item0.body, item1.body)

            # Verify ContentItem.read
            self.assert_(view1.findUUID(readNote.itsUUID).read is True)
            self.assert_(view1.findUUID(unreadNote.itsUUID).read is False)

            # Verify ContentItem.private
            self.assert_(view1.findUUID(publicNote.itsUUID).private is False)
            self.assert_(view1.findUUID(privateNote.itsUUID).private is True)

            # Verify Mine/Not-Mine/Dashboard
            dashboard = schema.ns("osaf.pim", view1).allCollection
            self.assert_(
                view1.findUUID(directlyInDashboard.itsUUID) in
                dashboard.inclusions)

            self.assert_(view1.findUUID(inMine.itsUUID) in dashboard)
            self.assert_(view1.findUUID(inNotMine.itsUUID) not in dashboard)

            # Verify collection membership:
            coll1 = view1.findUUID(coll0.itsUUID)
            for item0 in coll0:
                item1 = view1.findUUID(item0.itsUUID)
                self.assert_(item1 in coll1)

            # Verify trash membership
            trash = schema.ns("osaf.pim", view1).trashCollection
            trashedItem = view1.findUUID(trashedItem.itsUUID)
            self.assert_(trashedItem in trash)
            trashTestCollection = view1.findUUID(trashTestCollection.itsUUID)
            self.assert_(trashedItem not in trashTestCollection)
            self.assert_(trashedItem in trashTestCollection.inclusions)

            # Verify passwords
            pw1 = view1.findUUID(pw.itsUUID)
            self.assertEqual(waitForDeferred(pw1.decryptPassword('secret')),
                             'foobar')

            mpwPrefs1 = schema.ns("osaf.framework.MasterPassword",
                                  view1).masterPasswordPrefs
            self.assertEqual(mpwPrefs1.masterPassword, True)
            self.assertEqual(mpwPrefs1.timeout, 10)

            pwPrefs1 = schema.ns("osaf.framework.password",
                                 view1).passwordPrefs
            self.assertEqual(
                len(
                    waitForDeferred(
                        pwPrefs1.dummyPassword.decryptPassword('secret'))), 16)
            self.assertEqual(str(pwPrefs1.dummyPassword.itsUUID),
                             'dd555441-9ddc-416c-b55a-77b073c7bd15')
            dummyByUUID = view1.findUUID(
                'dd555441-9ddc-416c-b55a-77b073c7bd15')
            self.assertEqual(dummyByUUID, pwPrefs1.dummyPassword)

            count = 0
            for item in Password.iterItems(view0):
                waitForDeferred(item.decryptPassword('secret'))
                count += 1

            count1 = 0
            for item in Password.iterItems(view1):
                waitForDeferred(item.decryptPassword('secret'))
                count1 += 1

            self.assertEqual(count + 2, count1)  # XXX Shouldn't count==count1?

            # Verify sharing
            account1 = view1.findUUID(account0.itsUUID)
            self.assertEquals(account1.host, "chandler.o11n.org")
            self.assertEquals(account1.port, 8080)
            self.assertEquals(account1.path, "/cosmo")
            self.assertEquals(account1.username, "test")
            self.assertEquals(account1.useSSL, True)
            self.assertEquals(
                waitForDeferred(account1.password.decryptPassword('secret')),
                '4cc0unt0')

            hub_account1 = view1.findUUID(hub_account0.itsUUID)
            self.assert_(isinstance(hub_account0, sharing.HubAccount))

            inmemory_share1 = view1.findUUID(inmemory_share0.itsUUID)
            self.assert_(inmemory_share1 is not None)
            self.assertEqual(inmemory_share0.contents.itsUUID,
                             inmemory_share1.contents.itsUUID)
            self.assertEqual(inmemory_share0.conduit.syncToken,
                             inmemory_share1.conduit.syncToken)
            for state0 in inmemory_share0.states:
                state1 = view1.findUUID(state0.itsUUID)
                self.assert_(state1 in inmemory_share1.states)
                self.assertEqual(state0.agreed, state1.agreed)
                self.assertEqual(state0.pending, state1.pending)
                self.assertEqual(state1.pendingRemoval,
                                 state1.itsUUID == pendingRemoval)
            for item0 in coll0:
                item1 = view1.findUUID(item0.itsUUID)
                sharedItem1 = sharing.SharedItem(item1)
                self.assert_(inmemory_share1 in sharedItem1.sharedIn)

            # Peer states
            peerNote1 = view1.findUUID(peerNote.itsUUID)
            sharedPeerNote1 = sharing.SharedItem(peerNote1)
            peerAddress1 = view1.findUUID(peerAddress.itsUUID)
            peerState1 = view1.findUUID(peerState.itsUUID)
            self.assert_(peerState1 in sharedPeerNote1.peerStates)
            self.assertEquals(sharedPeerNote1.peerStates.getAlias(peerState1),
                              peerAddress1.itsUUID.str16())
            self.assert_(peerState1 in sharedPeerNote1.conflictingStates)
            self.assert_(isinstance(peerAddress1, pim.EmailAddress))

            proxy1 = view1.findUUID(proxy.itsUUID)
            self.assertEquals(proxy1.host, "host")
            self.assertEquals(proxy1.port, 123)
            self.assertEquals(proxy1.username, "username")
            self.assertEquals(proxy1.bypass, "192.168.1, localhost")

            pw = waitForDeferred(proxy1.password.decryptPassword('secret'))
            self.assertEquals(pw, "password")
            self.assertEquals(proxy1.active, True)
            self.assertEquals(proxy1.useAuth, True)

            self.assertEquals(
                schema.ns('osaf.app', view1).prefs.isOnline, False)
            self.assertEquals(
                schema.ns('osaf.sharing', view1).prefs.isOnline, False)

            # Verify Calendar prefs
            pref = schema.ns('osaf.pim', view1).TimezonePrefs
            self.assertEqual(pref.showUI, True)
            self.assertEqual(pref.showPrompt, False)

            pref = schema.ns('osaf.framework.blocks.calendar',
                             view1).calendarPrefs
            self.assertEqual(pref.hourHeightMode, "auto")
            self.assertEqual(pref.visibleHours, 20)

            #Verify Mail Accounts

            imapaccount1 = view1.findUUID(imapaccount0.itsUUID)
            self.assertEquals(imapaccount1.host, "localhost")
            self.assertEquals(imapaccount1.port, 143)
            self.assertEquals(imapaccount1.username, "test")
            self.assertEquals(imapaccount1.connectionSecurity, "TLS")
            self.assertEquals(imapaccount1.numRetries, 2)
            self.assertEquals(imapaccount1.pollingFrequency, 300)
            self.assertEquals(imapaccount1.isActive, False)
            self.assertEquals(imapaccount1.replyToAddress.format(),
                              imapAddress.format())
            self.assertEquals(
                waitForDeferred(
                    imapaccount1.password.decryptPassword('secret')),
                'imap4acc0unt0')

            folder = imapaccount1.folders.first()
            self.assertEquals(folder.displayName, "TestFolder")
            self.assertEquals(folder.folderName, "INBOX.TestFolder")
            self.assertEquals(folder.folderType, "MAIL")

            popaccount1 = view1.findUUID(popaccount0.itsUUID)

            self.assertEquals(popaccount1.host, "localhost")
            self.assertEquals(popaccount1.port, 110)
            self.assertEquals(popaccount1.username, "test1")
            self.assertEquals(popaccount1.connectionSecurity, "NONE")
            self.assertEquals(popaccount1.numRetries, 3)
            self.assertEquals(popaccount1.pollingFrequency, 200)
            self.assertEquals(popaccount1.isActive, True)
            self.assertEquals(popaccount1.replyToAddress.format(),
                              popAddress.format())
            self.assertEquals(
                waitForDeferred(
                    popaccount1.password.decryptPassword('secret')),
                'pop4acc0unt0')

            smtpaccount1 = view1.findUUID(smtpaccount0.itsUUID)

            self.assertEquals(smtpaccount1.host, "localhost")
            self.assertEquals(smtpaccount1.port, 587)
            self.assertEquals(smtpaccount1.username, "test2")
            self.assertEquals(smtpaccount1.connectionSecurity, "SSL")
            self.assertEquals(smtpaccount1.numRetries, 5)
            self.assertEquals(smtpaccount1.pollingFrequency, 500)
            self.assertEquals(smtpaccount1.isActive, True)
            self.assertEquals(smtpaccount1.useAuth, True)
            self.assertEquals(smtpaccount1.fromAddress.format(),
                              smtpNewAddress.format())
            self.assertEquals(
                waitForDeferred(
                    smtpaccount1.password.decryptPassword('secret')),
                'smtp4acc0unt0')

            queuedMessage1 = smtpaccount1.messageQueue[0]

            self.assertEquals(queuedMessage1.itsUUID,
                              queuedMessage0.itsItem.itsUUID)
            self.assertEquals(
                schema.ns("osaf.pim", view1).MailPrefs.isOnline, False)

            col = schema.ns("osaf.pim", view1).meEmailAddressCollection

            found = False
            oldAddr = smtpOldAddress.format()

            # Confirm that the old email address smtpOldAddress
            # is in the meEmailAddressCollection for calculating
            # the MailStamp.fromMe and MailStamp.toMe attributes
            for ea in col:
                if ea.format() == oldAddr:
                    found = True
                    break

            self.assertTrue(found)

            # backup on quit preference
            backupPrefs1 = schema.ns("osaf.app", view1).prefs
            self.assertTrue(backupPrefs1.backupOnQuit)

            # tip of the day prefs
            self.assertFalse(backupPrefs1.showTip)
            self.assertEqual(backupPrefs1.tipIndex, 1)

        finally:
            try:
                os.remove(filename)
            except:
                pass
Esempio n. 17
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')