[Chandler-dev] Re: [commits] (grant) [12207] r13792@Pro-Grammar (orig r12108): bear | 2006-10-26 16:32:18 -0700

Grant Baillie grant at osafoundation.org
Thu Nov 2 09:51:07 PST 2006


Oh, crap.

I'll fix that.

--Grant

On 2 Nov, 2006, at 09:39, Jeffrey Harris wrote:

> Hmm, was that really what you wanted to do?
>
> commits at osafoundation.org wrote:
>> Revision
>>     12207 <http://viewcvs.osafoundation.org/chandler? 
>> view=rev&rev=12207>
>> Author
>>     grant
>> Date
>>     2006-11-02 09:34:07 -0800 (Thu, 02 Nov 2006)
>>
>>
>>       Log Message
>>
>> r13792 at Pro-Grammar (orig r12108): bear | 2006-10-26 16:32:18 -0700
>> Setting version info for trunk to 0.7alpha5.dev
>>
>> r13794 at Pro-Grammar (orig r12109): bkirsch | 2006-10-26 16:49:49 -0700
>> fixes bug [Bug 7163
>> <http://bugzilla.osafoundation.org/show_bug.cgi?id=7163>] Mail marked
>> read on IMAP server when Chandler syncs by unsetting the \Seen  
>> flag on
>> the IMAP Server
>> r13795 at Pro-Grammar (orig r12110): heikki | 2006-10-26 17:14:30 -0700
>> Need to set TIME variable on Linux as well or startup timings  
>> won't work.
>> r13796 at Pro-Grammar (orig r12111): vajda | 2006-10-26 17:49:18 -0700
>> - fixed bug 7112 <http://bugzilla.osafoundation.org/show_bug.cgi? 
>> id=7112>
>> (http://bugzilla.osafoundation.org/show_bug.cgi?id=7112)
>> (Import calendar performance regression with r12016)
>> - introduced 'init' monitor op code used during initial value setting
>>
>> r13798 at Pro-Gr ammar (orig r12113): vajda | 2006-10-26 17:59:56 -0700
>> - upgraded build to chandlerdb 0.6-53 (bug 7126
>> <http://bugzilla.osafoundation.org/show_bug.cgi?id=7126>)
>>
>> r13799 at Pro-Grammar (orig r12114): vajda | 2006-10-26 18:07:27 -0700
>> - added 'plugins' target to Makefile
>>
>> r13801 at Pro-Grammar (orig r12116): bear | 2006-10-26 19:23:37 -0700
>> Reverting change made in revision 12114
>> <http://viewcvs.osafoundation.org/chandler?view=rev&rev=12114> to  
>> add a
>> plugins target. The change broke the sub-targets that tbox uses.
>>
>> r13807 at Pro-Grammar (orig r12117): vajda | 2006-10-26 20:16:21 -0700
>> put back Makefile, removing the missing plugin
>> r13810 at Pro-Grammar (orig r12120): morgen | 2006-10-27 10:31:11 -0700
>> (trunk) Fix for bug 7199
>> <http://bugzilla.osafoundation.org/show_bug.cgi?id=7199> (Incomplete
>> events), r=capps
>>
>> r13811 at Pro-Grammar (orig r12121): heikki | 2006-10-27 10:52:12 -0700
>> vobject is actually Jeffrey's code.
>> r13813 at Pro-Grammar (orig r12123): morgen | 2006-10-27 13:50:34 -0700
>> Copy the cached resource list, since get( ) makes modifications to it
>> along the way, and we want put( ) to get a pristine copy
>>
>> r13814 at Pro-Grammar (orig r12124): heikki | 2006-10-27 14:10:51 -0700
>> Bug 6785 <http://bugzilla.osafoundation.org/show_bug.cgi?id=6785>,
>> do_tests.sh should output test output as it is happening, r=bear.
>> r13816 at Pro-Grammar (orig r12126): heikki | 2006-10-27 15:44:29 -0700
>> Bug 6751 <http://bugzilla.osafoundation.org/show_bug.cgi?id=6751>,  
>> tests
>> should stop on first error. Functional tests patch by Dan, r=heikki.
>> Other changes by heikki, r=bear.
>> r13819 at Pro-Grammar (orig r12129): heikki | 2006-10-27 16:21:09 -0700
>> Ignore more stuff.
>> r13823 at Pro-Grammar (orig r12133): vajda | 2006-10-27 17:47:16 -0700
>> - fixed bug 7215 <http://
>> bugzilla.osafoundation.org/show_bug.cgi?id=7215> on trunk
>> (http://bugzilla.osafoundation.org/show_bug.cgi?id=7215)
>> (AssertionError: (<UUID: ec00d6d0-7d4e-11da-b55b-000e35a7c68a>, 'item
>> not found', <UUID: ec00d6d0-7d4e-11da-b55b-000e35a7c68a>))
>> - reworked AppCollection's schema to not create an exclusions  
>> ListCollection
>>
>> r13824 at Pro-Grammar (orig r12134): morgen | 2006-10-27 17:51:28 -0700
>> One less call to EventStamp()
>>
>> r13826 at Pro-Grammar (orig r12136): jeffrey | 2006-10-30 11:04:21 -0800
>> - Commit Darshana's fix for bug 7078
>> <http://bugzilla.osafoundation.org/show_bug.cgi?id=7078>, the year  
>> 2099
>> doesn't work.
>> Changed date editors to use four digit years, and updated the
>> parsedatetime module
>>
>> r13835 at Pro-Grammar (orig r12141): jeffrey | 2006-10-30 12:53:06 -0800
>> - Fix test failures caused by changing the way date attribute  
>> editors work
>> (and an inexplicable failure in TestRemoveFromTrashOnImport caused  
>> by an
>> old, and seemingly no longer necessary workaround)
>>
>> r13840 at Pro-Grammar (orig r12144): heikki | 2006-10-30 15:25:59 -0800
>> Change Chandler sharing tests to test temporarily against
>> https://osaf.us. This
>> will give us some more coverage on Chandler+Cosmo 0.5.0  
>> combination, as
>> well as
>> giving us some additional SSL testing.
>>
>> In a couple of week's time (barring any problems), we intend to  
>> migrate
>> qacosmo
>> to Cosmo 0.5.0 and switch Chandler back to that. The next step is to
>> make Chandler
>> test against some dedicated Chandler-sharing-test-server instance,
>> perhaps cosmo-test.
>> r13841 at Pro-Grammar (orig r12145): vajda | 2006-10-30 15:28:14 -0800
>> - fixed bug 7240
>> <http://bugzilla.osafoundation.org/show_bug.cgi?id=7240> on trunk
>> (http://bugzilla.osafoundation.org/show_bug.cgi?id=7240)
>> (instantiateItem s hould accept a "values" dict)
>>
>> r13843 at Pro-Grammar (orig r12147): morgen | 2006-10-30 15:31:04 -0800
>> (Trunk) Fix for bug 7230
>> <http://bugzilla.osafoundation.org/show_bug.cgi?id=7230> (Incomplete
>> events when subscribing to a calendar that a non-Chandler client like
>> CosmoUI has created events in) r=grant
>>
>> r13846 at Pro-Grammar (orig r12149): vajda | 2006-10-30 17:38:01 -0800
>> - upgraded build to chandlerdb 0.6-54
>>
>> r13848 at Pro-Grammar (orig r12151): morgen | 2006-10-30 18:03:36 -0800
>> Fix for bug 7224
>> <http://bugzilla.osafoundation.org/show_bug.cgi?id=7224> (Platform in
>> Chandler HTTP user-agent)
>>
>> r13853 at Pro-Grammar (orig r12152): bear | 2006-10-30 20:23:36 -0800
>> Enabling ConfigObj for Chandler use. This change also enables the
>> install of python-only eggs.
>> bug 6949 <http://bugzilla.osafoundation.org/show_bug.cgi?id=6949>
>>
>> r13857 at Pro-Grammar (or ig r12156): bear | 2006-10-30 20:42:44 -0800
>> make the PYEGGS download target a dependency to the install-plugin- 
>> core
>> so that the new eggs will be downloaded if the install target is
>> requested in an environment that has already been installed.
>>
>> r13858 at Pro-Grammar (orig r12157): bear | 2006-10-30 21:29:15 -0800
>> merging the two find's that purge pyc's and pyo's to a single find
>> (thanks Grant)
>> bug 7234 <http://bugzilla.osafoundation.org/show_bug.cgi?id=7234>
>>
>> r13859 at Pro-Grammar (orig r12158): bear | 2006-10-30 22:23:53 -0800
>> bug 7234 <http://bugzilla.osafoundation.org/show_bug.cgi?id=7234>  
>> redux
>> - completely missed the -delete option to find in Grant's example
>> Will post part two of the fix tomorrow - the different external/
>> Makefile's that had the same pattern
>>
>> r13862 at Pro-Grammar (orig r12161): grant | 2006-10-31 09:01:33 -0800
>> r13776 at Pro-Grammar: grant | 2006-10-25 19:01:01 -07 00
>> First cut at a "Purge" button in Chandler:
>>
>> - Issues:
>>
>> + Needs a real icon.
>> + Does the "Purge" button purge all your items, or just the
>> ones in the currently selected collection?
>> + Is it active all the time, or only when the dashboard view is  
>> visible?
>>
>>
>> r13863 at Pro-Grammar (orig r12162): grant | 2006-10-31 09:02:13 -0800
>>
>> r13864 at Pro-Grammar (orig r12163): grant | 2006-10-31 09:02:18 -0800
>>
>> r13865 at Pro-Grammar (orig r12164): grant | 2006-10-31 09:02:23 -0800
>> r13782 at Pro-Grammar: grant | 2006-10-25 21:03:58 -0700
>> Purge button icon
>>
>> r13866 at Pro-Grammar (orig r12165): grant | 2006-10-31 09:02:27 -0800
>> r13783 at Pro-Grammar: grant | 2006-10-25 21:07:19 -0700
>> Remove commented-out UpdateUI for Purge events.
>>
>>
>> r13867 at Pro-Grammar (orig r12166): grant | 2006-10-31 09:02:33 -0800
>> r13784 at Pro- Grammar: grant | 2006-10-25 21:29:41 -0700
>> Terminology change: editedTriageStatus --> unpurgedTriageStatus
>>
>> r13868 at Pro-Grammar (orig r12167): grant | 2006-10-31 09:02:41 -0800
>>
>> r13869 at Pro-Grammar (orig r12168): grant | 2006-10-31 09:02:46 -0800
>>
>> r13870 at Pro-Grammar (orig r12169): grant | 2006-10-31 09:02:50 -0800
>>
>> r13871 at Pro-Grammar (orig r12170): grant | 2006-10-31 09:02:54 -0800
>> r13850 at Pro-Grammar: grant | 2006-10-30 18:21:47 -0800
>> I need to change the schema version, too
>>
>> r13875 at Pro-Grammar (orig r12174): pje | 2006-10-31 09:51:41 -0800
>> Initial checkin of Phase 1 and partial Phase 2 implementation of  
>> the EIM
>> API.
>> (Includes a copy of simplegeneric==0.6 from the Cheeseshop, which  
>> should be
>> replaced at some point with an egg-based dependency in the Makefile.)
>> See EIM.txt for documentation of the current features.
>>
>> r13876 at Pro-Grammar (orig r12175): mm mm | 2006-10-31 10:08:16 -0800
>> ix bug 6729 <http://bugzilla.osafoundation.org/show_bug.cgi?id=6729>
>> r13877 at Pro-Grammar (orig r12176): mmmm | 2006-10-31 10:10:54 -0800
>> Partial Fix bug 6729
>> <http://bugzilla.osafoundation.org/show_bug.cgi?id=6729>: The save
>> settings feature does not work with Unicode. r=jeffrey, bkirsch.
>> r13878 at Pro-Grammar (orig r12177): mmmm | 2006-10-31 10:11:25 -0800
>> Partial Fix bug 6729
>> <http://bugzilla.osafoundation.org/show_bug.cgi?id=6729>: The save
>> settings feature does not work with Unicode. r=jeffrey, bkirsch.
>> r13879 at Pro-Grammar (orig r12178): pje | 2006-10-31 10:45:35 -0800
>> Attempt to fix import problem on tbox.
>>
>> r13880 at Pro-Grammar (orig r12179): bkirsch | 2006-10-31 12:00:40 -0800
>> Streamlines mail code for Preview by no longer storing attachments  
>> and
>> rfc2822 data. These values will not be used by Chandler for  
>> Preview and
>> removing the storage of them i ncreases disk space and  
>> performance. The
>> hasMimeParts boolean attribute on MailStamp has also been removed.
>> r13881 at Pro-Grammar (orig r12180): stearns | 2006-10-31 12:35:50 -0800
>> Fix bug 7229 <http://bugzilla.osafoundation.org/show_bug.cgi? 
>> id=7229>:
>> extend TestReminderProcessing test period (from 3 seconds to 15)  
>> to deal
>> with slower machines and background tasks.
>>
>> r13882 at Pro-Grammar (orig r12181): mmmm | 2006-10-31 12:39:24 -0800
>> Partial Fix bug 6729
>> <http://bugzilla.osafoundation.org/show_bug.cgi?id=6729>: The save
>> settings feature does not work with Unicode. r=morgen, bkirsch.
>> r13883 at Pro-Grammar (orig r12182): heikki | 2006-10-31 12:53:02 -0800
>> Bug 6837 <http://bugzilla.osafoundation.org/show_bug.cgi?id=6837>,  
>> need
>> a little space between the Restart and Close button in the
>> feedback dialog, most visible on the Mac.
>> r13884 at Pro-Grammar (orig r12183): mmmm | 2006-10-31 13:04:59 -0800*
>> Partial Fix bug 6729
>> <http://bugzilla.osafoundation.org/show_bug.cgi?id=6729>: The save
>> settings feature does not work with Unicode. r=morgen, bkirsch.
>> r13885 at Pro-Grammar (orig r12184): heikki | 2006-10-31 14:17:30 -0800
>> Ignore configobj*.egg
>> r13886 at Pro-Grammar (orig r12185): vajda | 2006-10-31 14:41:41 -0800
>> - added missing _self.cursor variable initializations
>>
>> r13887 at Pro-Grammar (orig r12186): bear | 2006-10-31 14:46:05 -0800
>> Change the install location for PYEGGS from CHANDLERHOME to the  
>> normal
>> site-packages directory.
>> bug 7264 <http://bugzilla.osafoundation.org/show_bug.cgi?id=7264>
>>
>> r13888 at Pro-Grammar (orig r12187): vajda | 2006-10-31 14:56:25 -0800
>> - remove potential filter attribute duplicates
>>
>> r13889 at Pro-Grammar (orig r12188): vajda | 2006-10-31 15:18:56 -0800
>> - added attribute name hash clash check to kind.c.allNames caching
>>
>> r1 3890 at Pro-Grammar (orig r12189): heikki | 2006-10-31 20:44:03 -0800
>> Bug 7268 <http://bugzilla.osafoundation.org/show_bug.cgi?id=7268>,  
>> add
>> NOTICE.txt to distribution, r=bear.
>> r13892 at Pro-Grammar (orig r12191): dan | 2006-11-01 08:30:02 -0800
>> Change the way the CATS logger reports times. Elapsed times are  
>> reported
>> only in seconds (bug 6935
>> <http://bugzilla.osafoundation.org/show_bug.cgi?id=6935>), and  
>> accuracy
>> of times is limited to 1/100 of a second (bug 6934
>> <http://bugzilla.osafoundation.org/show_bug.cgi?id=6934>)
>> r13896 at Pro-Grammar (orig r12195): bear | 2006-11-01 09:33:12 -0800
>> Removing obsolete ChangeLog and platform specific README's
>> bug 7116 <http://bugzilla.osafoundation.org/show_bug.cgi?id=7116>,  
>> patch
>> by heikki, r=bear
>>
>> r13904 at Pro-Grammar (orig r12203): heikki | 2006-11-01 15:38:39 -0800
>> Make the feedback window a singleton to avoid the cases where we  
>> end up
>> wit h
>> multiple feedback windows up at the same time, r=robin.
>>
>> The idea for the singleton implementation from
>> http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52558
>> r13905 at Pro-Grammar (orig r12204): jeffrey | 2006-11-01 15:44:19 -0800
>> - Fix traceback when drawing swatches in lozenges, variable names in
>> ConfigParser
>> aren't case sensitive but they are in ConfigObj. So this typo went
>> undiscovered
>> till now...
>>
>> r13906 at Pro-Grammar (orig r12205): jeffrey | 2006-11-01 18:05:23 -0800
>> - Commit Darshana's implementation of bug 7198
>> <http://bugzilla.osafoundation.org/show_bug.cgi?id=7198>, parse  
>> item body
>> for date times when stamping as an event
>> *
>>
>>
>>       *Modified Paths*
>>
>>     * *branches/0.7alpha4/chandler/Chandler.py
>>       <#branches07alpha4chandlerChandlerpy>*
>>     * *branches/0.7alpha4/chandler/Makefile
>>       <#branches07alpha4chandlerMakefile>*
>>     * *branches/0.7alpha4/chandler/NOTICE.txt
>>       <#branches07alpha4chandlerNOTICEtxt>*
>>     * *branches/0.7alpha4/chandler/application/Utility.py
>>       <#branches07alpha4chandlerapplicationUtilitypy>*
>>     * *branches/0.7alpha4/chandler/application/feedback.py
>>       <#branches07alpha4chandlerapplicationfeedbackpy>*
>>     * *branches/0.7alpha4/chandler/application/feedback.xrc
>>       <#branches07alpha4chandlerapplicationfeedbackxrc>*
>>     * *branches/0.7alpha4/chandler/application/styles.conf
>>       <#branches07alpha4chandlerapplicationstylesconf>*
>>     * *branches/0.7alpha4/chandler/application/styles.py
>>       <#branches07alpha4chandlerapplicationstylespy>*
>>     * *branches/0.7alpha4/chandler/parcels/osaf/framework/ 
>> attributeEditors/AttributeEditors.py
>>        
>> <#branches07alpha4chandlerparcelsosafframeworkattributeEditorsAttribu 
>> teEditorspy>*
>>     * *branches/0.7alpha4/chandler/parcels/osaf/framework/blocks/ 
>> calendar/CalendarCanvas.py
>>        
>> <#branches07alpha4chandlerparcelsosafframeworkblockscalendarCalendarC 
>> anvaspy>*
>>     * *branches/0.7alpha4/chandler/parcels/osaf/mail/constants.py
>>       <#branches07alpha4chandlerparcelsosafmailconstantspy>*
>>     * *branches/0.7alpha4/chandler/parcels/osaf/mail/imap.py
>>       <#branches07alpha4chandlerparcelsosafmailimappy>*
>>     * *branches/0.7alpha4/chandler/parcels/osaf/mail/message.py
>>       <#branches07alpha4chandlerparcelsosafmailmessagepy>*
>>     * *branches/0.7alpha4/chandler/parcels/osaf/mail/tests/ 
>> TestMessage.py
>>       <#branches07alpha4chandlerparcelsosafmailtestsTestMessagepy>*
>>     * *branches/0.7alpha4/chandler/parcels/osaf/pim/calendar/ 
>> Calendar.py
>>       <#branches07alpha4chandlerparcelsosafpimcalendarCalendarpy>*
>>     * *branches/0.7alpha4/chandler/parcels/osaf/pim/calendar/ 
>> DateTimeUtil.py
>>        
>> <#branches07alpha4chandlerparcelsosafpimcalendarDateTimeUtilpy>*
>>     * *branches/0.7alpha4/chandler/parcels/osaf/pim/calendar/tests/ 
>> TestFormatters.py
>>        
>> <#branches07alpha4chandlerparcelsosafpimcalendartestsTestFormatterspy 
>> >*
>>     * *branches/0.7alpha4/chandler/parcels/osaf/pim/collections.py
>>       <#branches07alpha4chandlerparcelsosafpimcollectionspy>*
>>     * *branches/0.7alpha4/chandler/parcels/osaf/pim/items.py
>>       <#branches07alpha4chandlerparcelsosafpimitemspy>*
>>     * *branches/0.7alpha4/chandler/parcels/osaf/pim/mail.py
>>       <#branches07alpha4chandlerparcelsosafpimmailpy>*
>>     * *branches/0.7alpha4/chandler/parcels/osaf/pim/tests/ 
>> TestStamping.py
>>       <#branches07alpha4chandlerparcelsosafpimtestsTestStampingpy>*
>>     * *branches/0.7alpha4/chandler/parcels/osaf/servlets/xmlrpc.py
>>       <#branches07alpha4chandlerparcelsosafservletsxmlrpcpy>*
>>     * *branches/0.7alpha4/chandler/parcels/osaf/settings.py
>>       <#branches07alpha4chandlerparcelsosafsettingspy>*
>>     * *branches/0.7alpha4/chandler/parcels/osaf/sharing/Sharing.py
>>       <#branches07alpha4chandlerparcelsosafsharingSharingpy>*
>>     * *branches/0.7alpha4/chandler/parcels/osaf/sharing/tests/bad.xml
>>       <#branches07alpha4chandlerparcelsosafsharingtestsbadxml>*
>>     * *branches/0.7alpha4/chandler/parcels/osaf/sharing/tests/ 
>> compatibility/ComplexMail.xml
>>        
>> <#branches07alpha4chandlerparcelsosafsharingtestscompatibilityComplex 
>> Mailxml>*
>>     * *branches/0.7alpha4/chandler/parcels/osaf/sharing/tests/ 
>> compatibility/Mail.xml
>>        
>> <#branches07alpha4chandlerparcelsosafsharingtestscompatibilityMailxml 
>> >*
>>     * *branches/0.7alpha4/chandler/parcels/osaf/sharing/tests/ 
>> compatibility/MailedEventTask.xml
>>        
>> <#branches07alpha4chandlerparcelsosafsharingtestscompatibilityMailedE 
>> ventTaskxml>*
>>     * *branches/0.7alpha4/chandler/parcels/osaf/sharing/tests/ 
>> compatibility/TestXMLCompatibility.py
>>        
>> <#branches07alpha4chandlerparcelsosafsharingtestscompatibilityTestXML 
>> Compatibilitypy>*
>>     * *branches/0.7alpha4/chandler/parcels/osaf/views/detail/ 
>> detail.py
>>       <#branches07alpha4chandlerparcelsosafviewsdetaildetailpy>*
>>     * *branches/0.7alpha4/chandler/parcels/osaf/views/main/ 
>> Dashboard.py
>>       <#branches07alpha4chandlerparcelsosafviewsmainDashboardpy>*
>>     * *branches/0.7alpha4/chandler/parcels/osaf/views/main/events.py
>>       <#branches07alpha4chandlerparcelsosafviewsmaineventspy>*
>>     * *branches/0.7alpha4/chandler/parcels/osaf/views/main/ 
>> mainblocks.py
>>       <#branches07alpha4chandlerparcelsosafviewsmainmainblockspy>*
>>     * *branches/0.7alpha4/chandler/repository/item/Item.py
>>       <#branches07alpha4chandlerrepositoryitemItempy>*
>>     * *branches/0.7alpha4/chandler/repository/item/Monitors.py
>>       <#branches07alpha4chandlerrepositoryitemMonitorspy>*
>>     * *branches/0.7alpha4/chandler/repository/item/Sets.py
>>       <#branches07alpha4chandlerrepositoryitemSetspy>*
>>     * *branches/0.7alpha4/chandler/repository/item/Values.py
>>       <#branches07alpha4chandlerrepositoryitemValuespy>*
>>     * *branches/0.7alpha4/chandler/repository/persistence/ 
>> DBContainer.py
>>       <#branches07alpha4chandlerrepositorypersistenceDBContainerpy>*
>>     * *branches/0.7alpha4/chandler/repository/persistence/DBRefs.py
>>       <#branches07alpha4chandlerrepositorypersistenceDBRefspy>*
>>     * *branches/0.7alpha4/chandler/repository/persistence/ 
>> DBRepositoryView.py
>>        
>> <#branches07alpha4chandlerrepositorypersistenceDBRepositoryViewpy>*
>>     * *branches/0.7alpha4/chandler/repository/persistence/ 
>> RepositoryError.py
>>        
>> <#branches07alpha4chandlerrepositorypersistenceRepositoryErrorpy>*
>>     * *branches/0.7alpha4/chandler/repository/persistence/ 
>> RepositoryView.py
>>        
>> <#branches07alpha4chandlerrepositorypersistenceRepositoryViewpy>*
>>     * *branches/0.7alpha4/chandler/repository/schema/Kind.py
>>       <#branches07alpha4chandlerrepositoryschemaKindpy>*
>>     * *branches/0.7alpha4/chandler/repository/schema/Types.py
>>       <#branches07alpha4chandlerrepositoryschemaTypespy>*
>>     * *branches/0.7alpha4/chandler/tools/QAUITestAppLib.py
>>       <#branches07alpha4chandlertoolsQAUITestAppLibpy>*
>>     * *branches/0.7alpha4/chandler/tools/cats/Functional/ 
>> TestCreateAccounts.py
>>        
>> <#branches07alpha4chandlertoolscatsFunctionalTestCreateAccountspy>*
>>     * *branches/0.7alpha4/chandler/tools/cats/Functional/ 
>> TestEventStacking.py
>>        
>> <#branches07alpha4chandlertoolscatsFunctionalTestEventStackingpy>*
>>     * *branches/0.7alpha4/chandler/tools/cats/Functional/ 
>> TestMoveToTrash.py
>>        
>> <#branches07alpha4chandlertoolscatsFunctionalTestMoveToTrashpy>*
>>     * *branches/0.7alpha4/chandler/tools/cats/Functional/ 
>> TestNewEvent.py
>>       <#branches07alpha4chandlertoolscatsFunctionalTestNewEventpy>*
>>     * *branches/0.7alpha4/chandler/tools/cats/Functional/ 
>> TestRecurringEvent.py
>>        
>> <#branches07alpha4chandlertoolscatsFunctionalTestRecurringEventpy>*
>>     * *branches/0.7alpha4/chandler/tools/cats/Functional/ 
>> TestReminderProcessing.py
>>        
>> <#branches07alpha4chandlertoolscatsFunctionalTestReminderProcessingpy 
>> >*
>>     * *branches/0.7alpha4/chandler/tools/cats/Functional/ 
>> TestRemoveFromTrashOnImport.py
>>        
>> <#branches07alpha4chandlertoolscatsFunctionalTestRemoveFromTrashOnImp 
>> ortpy>*
>>     * *branches/0.7alpha4/chandler/tools/cats/framework/ 
>> ChandlerTestLib.py
>>       <#branches07alpha4chandlertoolscatsframeworkChandlerTestLibpy>*
>>     * *branches/0.7alpha4/chandler/tools/cats/framework/TestOutput.py
>>       <#branches07alpha4chandlertoolscatsframeworkTestOutputpy>*
>>     * *branches/0.7alpha4/chandler/tools/cats/framework/runTests.py
>>       <#branches07alpha4chandlertoolscatsframeworkrunTestspy>*
>>     * *branches/0.7alpha4/chandler/tools/do_tests.sh
>>       <#branches07alpha4chandlertoolsdo_testssh>*
>>     * *branches/0.7alpha4/chandler/util/task.py
>>       <#branches07alpha4chandlerutiltaskpy>*
>>     * *branches/0.7alpha4/chandler/version.py
>>       <#branches07alpha4chandlerversionpy>*
>>
>>
>>       *Added Paths*
>>
>>     * *branches/0.7alpha4/chandler/Chandler.egg-info/resources/ 
>> images/ApplicationBarTriage.png
>>        
>> <#branches07alpha4chandlerChandleregginforesourcesimagesApplicationBa 
>> rTriagepng>*
>>     * *branches/0.7alpha4/chandler/parcels/osaf/sharing/EIM.txt
>>       <#branches07alpha4chandlerparcelsosafsharingEIMtxt>*
>>     * *branches/0.7alpha4/chandler/parcels/osaf/sharing/eim.py
>>       <#branches07alpha4chandlerparcelsosafsharingeimpy>*
>>     * *branches/0.7alpha4/chandler/parcels/osaf/sharing/ 
>> simplegeneric.py
>>       <#branches07alpha4chandlerparcelsosafsharingsimplegenericpy>*
>>     * *branches/0.7alpha4/chandler/parcels/osaf/sharing/tests/ 
>> TestEIM.py
>>       <#branches07alpha4chandlerparcelsosafsharingtestsTestEIMpy>*
>>
>>
>>       *Property Changed*
>>
>>     * *branches/0.7alpha4/chandler/*
>>
>>
>>       *Diff*
>>
>> * *
>>
>>
>>         *Property changes: branches/0.7alpha4/chandler*
>>
>> *Name: svn:ignore
>>    - __repository__*
>> debug
>> release
>> docs
>> dist
>> build
>> .settings
>> .project
>> cacert.pem
>> randpool.dat
>> profile.dat
>> Chandler-project.wpu
>> Chandler-project-debug.wpu
>> site.py
>> setuptools*.egg
>> *.pyc
>> *.pyo
>> *.log
>> *.inst
>> *.gz
>> *.md5
>> *.lock
>> *.exe
>> *.diff
>> *.patch
>> *.prof
>> *.egg-link
>> *.pth
>>    + __repository__*
>> debug
>> release
>> docs
>> dist
>> build
>> .settings
>> .project
>> cacert.pem
>> randpool.dat
>> profile.dat
>> Chandler-project.wpu
>> Chandler-project-debug.wpu
>> site.py
>> setuptools*.egg
>> configobj*.egg
>> *.pyc
>> *.pyo
>> *.log
>> *.inst
>> *.gz
>> *.md5
>> *.lock
>> *.exe
>> *.diff
>> *.patch
>> *.prof
>> *.egg-link
>> *.pth
>> test_profile
>> chandler
>> chandlerDebug
>> chandler.ini
>> Name: svk:merge
>>    - 8c82eac9-66b6-4f75-afda-ac985f890e1b:/projects/stamping/ 
>> chandler:13086
>> bfa2d993-0e2c-4a41-9bab-303d141a821e:/local/stamping/chandler:7577
>>    + 3c49585b-f0f7-0310-b5f9-dfe92a88fbfe:/trunk/chandler:12205
>> 8c82eac9-66b6-4f75-afda-ac985f890e1b:/fixes/purge/chandler:13850
>> 8c82eac9-66b6-4f75-afda-ac985f890e1b:/projects/stamping/chandler: 
>> 13086
>> bfa2d993-0e2c-4a41-9bab-303d141a821e:/local/stamping/chandler:7577
>> *
>>
>> * *
>>
>>
>>         *Added:
>>         branches/0.7alpha4/chandler/Chandler.egg-info/resources/ 
>> images/ApplicationBarTriage.png*
>>
>> *(Binary files differ)
>> *
>>
>> *Property changes on:
>> branches/0.7alpha4/chandler/Chandler.egg-info/resources/images/ 
>> ApplicationBarTriage.png
>> ___________________________________________________________________
>> Name: svn:mime-type + image/png ** *
>>
>>
>>         *Modified: branches/0.7alpha4/chandler/Chandler.py (12206  
>> => 12207)*
>>
>> *--- branches/0.7alpha4/chandler/Chandler.py	2006-11-02 02:32:00  
>> UTC (rev 12206)
>> +++ branches/0.7alpha4/chandler/Chandler.py	2006-11-02 17:34:07  
>> UTC (rev 12207)
>> **@@ -120,10 +120,8 @@
>> **                 # See if we already have a window up, and if  
>> so, reuse it
>>                  from application import feedback
>>                  feedback.destroyAppOnClose = True
>> **-                win = feedback.activeWindow
>> -                if win is None:
>> -                    win = feedback.FeedbackWindow()
>> -                    win.CreateOutputWindow('')
>> **+                win = feedback.FeedbackWindow()
>> +                win.CreateOutputWindow('')
>> **                 for line in backtrace:
>>                      win.write(line)
>>                  if not app.IsMainLoopRunning():
>> *
>>
>> * *
>>
>>
>>         *Modified: branches/0.7alpha4/chandler/Makefile (12206 =>  
>> 12207)*
>>
>> *--- branches/0.7alpha4/chandler/Makefile	2006-11-02 02:32:00 UTC  
>> (rev 12206)
>> +++ branches/0.7alpha4/chandler/Makefile	2006-11-02 17:34:07 UTC  
>> (rev 12207)
>> **@@ -16,6 +16,8 @@
>> **                 Chandler-PhotoPlugin \
>>                  EggTranslations-Plugin
>>
>> **+PYEGGS = $(CHANDLERARCHIVES)/configobj-4.3.2-py$(PYTHON_VER).egg
>> +
>> ** # When a version changes, the ARCHIVES lists below needs to be  
>> updated.
>>  # these get installed into release or debug
>>  ARCHIVES = $(CHANDLERARCHIVES)/Launchers-$(SNAP)-0.8-$(BP)G.tar.gz \
>> **@@ -29,7 +31,7 @@
>> **            $(CHANDLERARCHIVES)/pychecker-$(SNAP)-0.8.13-$(BP) 
>> 6.tar.gz \
>>             $(CHANDLERARCHIVES)/PyICU-$(SNAP)-0.5-62-$(BP)5.tar.gz \
>>             $(CHANDLERARCHIVES)/PyLucene-$(SNAP)-2.0.0-2-$(BP) 
>> 1.tar.gz \
>> **-           $(CHANDLERARCHIVES)/twisted-$(SNAP)-r15399-$(BP) 
>> 4.tar.gz \
>> **+           $(CHANDLERARCHIVES)/twisted-$(SNAP)-r15399-$(BP) 
>> 5.tar.gz \
>> **            $(CHANDLERARCHIVES)/wxPython-$(SNAP)-2.7.0.0-r113-$ 
>> (BP)1.tar.gz \
>>             $(CHANDLERARCHIVES)/zopeinterface-$(SNAP)-3.1.0c1-$(BP) 
>> 4.tar.gz \
>>             $(CHANDLERARCHIVES)/dateutil-$(SNAP)-1.1-$(BP)3.tar.gz \
>> **@@ -39,7 +41,7 @@
>> **            $(CHANDLERARCHIVES)/astng-$(SNAP)-0.16.0-$(BP) 
>> 3.tar.gz \
>>             $(CHANDLERARCHIVES)/common-$(SNAP)-0.15.0-$(BP)4.tar.gz \
>>             $(CHANDLERARCHIVES)/pylint-$(SNAP)-0.11.0-$(BP)3.tar.gz \
>> **-           $(CHANDLERARCHIVES)/parsedatetime-$(SNAP)-0.7.4-$(BP) 
>> 1.tar.gz
>> **+           $(CHANDLERARCHIVES)/parsedatetime-$(SNAP)-0.8.0-$(BP) 
>> 1.tar.gz
>> **
>>  OS         = $(shell uname)
>>  PYTHON_VER = 2.4
>> **@@ -130,7 +132,7 @@
>> **     endif
>>  endif
>>
>> **-# readline is only needed for OSX
>> **+# readline is only needed for OS X
>> ** ifeq ($(OS),Darwin)
>>      ARCHIVES += $(CHANDLERARCHIVES)/readline-$(SNAP)-5.1-$(BP) 
>> 2.tar.gz
>>  endif
>> **@@ -146,8 +148,9 @@
>> **     CURL=curl $(CHANDLER_CURL_OPTIONS) -f -o
>>  endif
>>
>> **-HOST = builds.osafoundation.org
>> -URL  = http://$(HOST)/external/$(PLATFORM)
>> **+HOST  = builds.osafoundation.org
>> +URL   = http://$(HOST)/external
>> +P_URL = $(URL)/$(PLATFORM)
>> **
>>  SETUPTOOLS_EGG  = $(CHANDLERARCHIVES)/setuptools-0.6c4dev_r52047- 
>> py2.4.egg
>>  SETUPTOOLS_ABS  = $(SETUPTOOLS_EGG)
>> **@@ -178,6 +181,11 @@
>> **                 $(addprefix $(C_BIN)/$(SNAP)/, \
>>                              $(notdir $(ARCHIVES))))
>>
>> **+PYEGGS_INST = \
>> +    $(addsuffix .inst, \
>> +                $(addprefix $(C_BIN)/$(SNAP)/, \
>> +                            $(notdir $(PYEGGS))))
>> +
>> ** downloads: $(ARCHIVES)
>>
>>  $(addprefix binaries-, $(BUILD_PLUGINS)):
>> **@@ -211,15 +219,25 @@
>> **
>>  $(ARCHIVES):
>>  	mkdir -p $(CHANDLERARCHIVES)
>> **-	$(CURL) $@ $(URL)/$(notdir $@)
>> **+	$(CURL) $@ $(P_URL)/$(notdir $@)
>> **
>>  $(ARCHIVES_INST):
>>  	tar -C $(C_BIN) -xvzf $(CHANDLERARCHIVES)/$(notdir $(basename $@))
>>  	touch $@
>>
>> **+$(PYEGGS):
>> +	mkdir -p $(CHANDLERARCHIVES)
>> +	$(CURL) $@ $(P_URL)/$(notdir $@)
>> +
>> +$(PYEGGS_INST):
>> +	MACOSX_DEPLOYMENT_TARGET= PYTHONPATH='$(PLUGIN_INST)'  
>> CHANDLERHOME='$(CHANDLERHOME)' $(PYTHON_BIN) \
>> +      -c "from setuptools.command.easy_install import main; main 
>> ()" \
>> +      $(CHANDLERARCHIVES)/$(notdir $(basename $@))
>> +	touch $@
>> +
>> ** $(SETUPTOOLS_EGG):
>>  	mkdir -p $(CHANDLERARCHIVES)
>> **-	$(CURL) $@ http://$(HOST)/external/$(notdir $@)
>> **+	$(CURL) $@ $(URL)/$(notdir $@)
>> **
>>  setuptools: $(SETUPTOOLS_EGG)
>>  	MACOSX_DEPLOYMENT_TARGET= PYTHONPATH='$(PLUGIN_INST)'  
>> CHANDLERHOME='$(CHANDLERHOME)' $(PYTHON_BIN) \
>> **@@ -240,13 +258,15 @@
>> **
>>  install-core: $(ARCHIVES) $(ARCHIVES_INST) manifest_exe
>>
>> **-install-plugin-core: setuptools chandler-locale-data
>> **+install-plugin-core: $(SETUPTOOLS_EGG) $(PYEGGS) setuptools  
>> chandler-locale-data $(PYEGGS_INST)
>> **
>> **-install: install-core install-plugin-core build-plugins
>> **+plugins: install-plugin-core build-plugins
>> **
>> **+install: install-core plugins
>> +
>> ** distrib: install-core install-plugin-core distrib-plugins
>>
>> **-download: $(ARCHIVES) $(SETUPTOOLS_EGG)
>> **+download: $(ARCHIVES) $(SETUPTOOLS_EGG) $(PYEGGS)
>> **
>>  # to install individual binaries, for example: make chandlerdb
>>
>> **@@ -296,8 +316,7 @@
>> ** 	rm -rf $(C_BIN)/$(SNAP)
>>  	rm -rf __repository__
>>  	rm -f chandler.log randpool.dat
>> **-	find . -name '*.pyc' | xargs rm -f
>> -	find . -name '*.pyo' | xargs rm -f
>> **+	find . -name '*.py[co]' -delete
>> **
>>  distclean: clean
>>  	rm -rf $(C_BIN)/debug
>> *
>>
>> * *
>>
>>
>>         *Modified: branches/0.7alpha4/chandler/NOTICE.txt (12206  
>> => 12207)*
>>
>> *--- branches/0.7alpha4/chandler/NOTICE.txt	2006-11-02 02:32:00  
>> UTC (rev 12206)
>> +++ branches/0.7alpha4/chandler/NOTICE.txt	2006-11-02 17:34:07 UTC  
>> (rev 12207)
>> **@@ -214,6 +214,42 @@
>> **      */
>>
>>
>> **+external/configobj
>> +
>> +    Copyright (c) 2003-2006, Michael Foord
>> +    All rights reserved.
>> +    E-mail : fuzzyman AT voidspace DOT org DOT uk
>> +
>> +    Redistribution and use in source and binary forms, with or  
>> without
>> +    modification, are permitted provided that the following  
>> conditions are
>> +    met:
>> +
>> +
>> +     * Redistributions of source code must retain the above  
>> copyright
>> +       notice, this list of conditions and the following disclaimer.
>> +
>> +     * Redistributions in binary form must reproduce the above
>> +       copyright notice, this list of conditions and the following
>> +       disclaimer in the documentation and/or other materials  
>> provided
>> +       with the distribution.
>> +
>> +     * Neither the name of Michael Foord nor the name of Voidspace
>> +       may be used to endorse or promote products derived from this
>> +       software without specific prior written permission.
>> +
>> +    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND  
>> CONTRIBUTORS
>> +    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT  
>> NOT
>> +    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND  
>> FITNESS FOR
>> +    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE  
>> COPYRIGHT
>> +    OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,  
>> INCIDENTAL,
>> +    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
>> +    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS  
>> OF USE,
>> +    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED  
>> AND ON ANY
>> +    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,  
>> OR TORT
>> +    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF  
>> THE USE
>> +    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH  
>> DAMAGE.
>> +
>> +
>> ** external/dateutil
>>
>>      B. TERMS AND CONDITIONS FOR ACCESSING OR OTHERWISE USING PYTHON
>> **@@ -686,7 +722,7 @@
>> **     (zlib format), rfc1951.txt (deflate format) and rfc1952.txt  
>> (gzip format).
>>
>>
>> **-external/readline
>> **+external/readline (OS X)
>> **
>>      /* Copyright (C) 1987-2005 Free Software Foundation, Inc.
>>
>> **@@ -768,8 +804,7 @@
>> **     /*  
>> ====================================================================
>>       * The Apache Software License, Version 1.1
>>       *
>> **-     * Copyright (c) 2000 The Apache Software Foundation.  All  
>> rights
>> -     * reserved.
>> **+     * Copyright (c) 2004-2006 Jeffrey Harris.  All rights  
>> reserved.
>> **      *
>>       * Redistribution and use in source and binary forms, with or  
>> without
>>       * modification, are permitted provided that the following  
>> conditions
>> *
>>
>> * *
>>
>>
>>         *Modified: branches/0.7alpha4/chandler/application/Utility.py
>>         (12206 => 12207)*
>>
>> *--- branches/0.7alpha4/chandler/application/Utility.py	2006-11-02  
>> 02:32:00 UTC (rev 12206)
>> +++ branches/0.7alpha4/chandler/application/Utility.py	2006-11-02  
>> 17:34:07 UTC (rev 12207)
>> **@@ -33,7 +33,7 @@
>> ** # with your name (and some helpful text). The comment's really  
>> there just to
>>  # cause Subversion to warn you of a conflict when you update, in  
>> case someone
>>  # else changes it at the same time you do (that's why it's on the  
>> same line).
>> **-SCHEMA_VERSION = "268" # grant: Rebuild to get consistency  
>> after observers weren't working (bug 7170)
>> **+SCHEMA_VERSION = "270" # grant: "Purge" button (bug 6329)
>> **
>>
>>  logger = None # initialized in initLogging()
>> **@@ -170,6 +170,7 @@
>> **         'chandlerTestMask': ('-M', '--chandlerTestMask', 's',  
>> 3, None, '0=print all, 1=hide reports, 2=also hide actions, 3=also  
>> hide test names'),
>>          'chandlerPerformanceTests': ('', '-- 
>> chandlerPerformanceTests', 's', None, None,  
>> 'file:TestClass,file2:TestClass2 to be executed by performance new  
>> framework'),
>>          'chandlerTestLogfile': ('', '--chandlerTestLogfile', 's',  
>> None, None, 'file for chandlerTests output'),
>> **+        'continueTestsOnFailure': ('-F','-- 
>> continueTestsOnFailure', 'b', False, None, 'Do not stop functional  
>> test suite on first failure'),
>> **         'scriptTimeout': ('-s', '--scriptTimeout', 's', 0,   
>> None, 'script file timeout'),
>>          'catsProfile':('',   '--catsProfile','s', None,  None,  
>> 'file for hotshot profile of script execution'),
>>          'catsPerfLog':('',   '--catsPerfLog','s', None,  None,  
>> 'file to output a performance number'),
>> **@@ -636,38 +637,30 @@
>> **
>>  def fileConfig(fname, defaults=None):
>>      """
>> **-    Read the logging configuration from a ConfigParser-format  
>> file.
>> **+    Read the logging configuration from a ConfigObj-format file.
>> **
>>      This can be called several times from an application,  
>> allowing an end user
>>      the ability to select from various pre-canned configurations  
>> (if the
>>      developer provides a mechanism to present the choices and  
>> load the chosen
>>      configuration).
>> **-    In versions of ConfigParser which have the readfp method  
>> [typically
>> -    shipped in 2.x versions of Python], you can pass in a file- 
>> like object
>> -    rather than a filename, in which case the file-like object  
>> will be read
>> -    using readfp.
>> **     """
>> **-    import ConfigParser
>> **+    from configobj import ConfigObj
>> **
>> **-    cp = ConfigParser.ConfigParser(defaults)
>> -    if hasattr(cp, 'readfp') and hasattr(fname, 'readline'):
>> -        cp.readfp(fname)
>> -    else:
>> -        cp.read(fname)
>> **+    cp = ConfigObj(fname, encoding="UTF8")
>> **     #first, do the formatters...
>> **-    flist = cp.get("formatters", "keys")
>> **+    flist = cp[u"formatters"][u"keys"]
>> **     if len(flist):
>> **-        flist = string.split(flist, ",")
>> **+        flist = flist.split(",")
>> **         formatters = {}
>>          for form in flist:
>> **-            sectname = "formatter_%s" % form
>> -            opts = cp.options(sectname)
>> -            if "format" in opts:
>> -                fs = cp.get(sectname, "format", 1)
>> **+            sectname = u"formatter_%s" % form
>> +            section = cp[sectname]
>> +            if section.has_key(u"format"):
>> +                fs = section[u"format"]
>> **             else:
>>                  fs = None
>> **-            if "datefmt" in opts:
>> -                dfs = cp.get(sectname, "datefmt", 1)
>> **+            if section.has_key("datefmt"):
>> +                dfs = section[u"datefmt"]
>> **             else:
>>                  dfs = None
>>              f = logging.Formatter(fs, dfs)
>> **@@ -680,33 +673,33 @@
>> **             #first, lose the existing handlers...
>>              logging._handlers.clear()
>>              #now set up the new ones...
>> **-            hlist = cp.get("handlers", "keys")
>> **+            hlist = cp[u"handlers"][u"keys"]
>> **             if len(hlist):
>> **-                hlist = string.split(hlist, ",")
>> **+                hlist = hlist.split(",")
>> **                 handlers = {}
>>                  fixups = [] #for inter-handler references
>>                  for hand in hlist:
>>                      try:
>> **-                        sectname = "handler_%s" % hand
>> -                        klass = cp.get(sectname, "class")
>> -                        opts = cp.options(sectname)
>> -                        if "formatter" in opts:
>> -                            fmt = cp.get(sectname, "formatter")
>> **+                        sectname = u"handler_%s" % hand
>> +                        section = cp[sectname]
>> +                        klass = section[u"class"]
>> +                        if section.has_key(u"formatter"):
>> +                            fmt = section[u"formatter"]
>> **                         else:
>>                              fmt = ""
>>                          klass = eval(klass, vars(logging))
>> **-                        args = cp.get(sectname, "args")
>> **+                        args = section[u"args"]
>> **                         args = eval(args, vars(logging))
>>                          h = apply(klass, args)
>> **-                        if "level" in opts:
>> -                            level = cp.get(sectname, "level")
>> **+                        if section.has_key(u"level"):
>> +                            level = section[u"level"]
>> **                             h.setLevel(logging._levelNames[level])
>>                          if len(fmt):
>>                              h.setFormatter(formatters[fmt])
>>                          #temporary hack for FileHandler and  
>> MemoryHandler.
>>                          if klass == logging.handlers.MemoryHandler:
>> **-                            if "target" in opts:
>> -                                target = cp.get(sectname,"target")
>> **+                            if section.has_key(u"target"):
>> +                                target = section[u"target"]
>> **                             else:
>>                                  target = ""
>>                              if len(target): #the target handler  
>> may not be loaded yet, so keep for later...
>> **@@ -720,19 +713,18 @@
>> **                     t = fixup[1]
>>                      h.setTarget(handlers[t])
>>              #at last, the loggers...first the root...
>> **-            llist = cp.get("loggers", "keys")
>> **+            llist = cp[u"loggers"][u"keys"]
>> **             llist = string.split(llist, ",")
>>              llist.remove("root")
>> **-            sectname = "logger_root"
>> **+            section = cp[u"logger_root"]
>> **             root = logging.root
>>              log = root
>> **-            opts = cp.options(sectname)
>> -            if "level" in opts:
>> -                level = cp.get(sectname, "level")
>> **+            if section.has_key(u"level"):
>> +                level = section[u"level"]
>> **                 log.setLevel(logging._levelNames[level])
>>              for h in root.handlers[:]:
>>                  root.removeHandler(h)
>> **-            hlist = cp.get(sectname, "handlers")
>> **+            hlist = section[u"handlers"]
>> **             if len(hlist):
>>                  hlist = string.split(hlist, ",")
>>                  for hand in hlist:
>> **@@ -749,24 +741,24 @@
>> **             existing = root.manager.loggerDict.keys()
>>              #now set up the new ones...
>>              for log in llist:
>> **-                sectname = "logger_%s" % log
>> -                qn = cp.get(sectname, "qualname")
>> -                opts = cp.options(sectname)
>> -                if "propagate" in opts:
>> -                    propagate = cp.getint(sectname, "propagate")
>> **+                sectname = u"logger_%s" % log
>> +                section = cp[sectname]
>> +                qn = section[u"qualname"]
>> +                if section.has_key(u"propagate"):
>> +                    propagate = section.as_int(u"propagate")
>> **                 else:
>>                      propagate = 1
>>                  logger = logging.getLogger(qn)
>>                  if qn in existing:
>>                      existing.remove(qn)
>> **-                if "level" in opts:
>> -                    level = cp.get(sectname, "level")
>> **+                if section.has_key(u"level"):
>> +                    level = section[u"level"]
>> **                     logger.setLevel(logging._levelNames[level])
>>                  for h in logger.handlers[:]:
>>                      logger.removeHandler(h)
>>                  logger.propagate = propagate
>>                  logger.disabled = 0
>> **-                hlist = cp.get(sectname, "handlers")
>> **+                hlist = section[u"handlers"]
>> **                 if len(hlist):
>>                      hlist = string.split(hlist, ",")
>>                      for hand in hlist:
>> *
>>
>> * *
>>
>>
>>         *Modified: branches/0.7alpha4/chandler/application/ 
>> feedback.py
>>         (12206 => 12207)*
>>
>> *--- branches/0.7alpha4/chandler/application/feedback.py	 
>> 2006-11-02 02:32:00 UTC (rev 12206)
>> +++ branches/0.7alpha4/chandler/application/feedback.py	2006-11-02  
>> 17:34:07 UTC (rev 12207)
>> **@@ -22,7 +22,6 @@
>> **
>>  LOGLINES = 500
>>
>> **-activeWindow = None
>> ** destroyAppOnClose = False
>>
>>  def initRuntimeLog(profileDir):
>> **@@ -57,6 +56,11 @@
>> **     An error dialog that would be shown in case there is an  
>> uncaught
>>      exception. The user can send the error report back to us as  
>> well.
>>      """
>> **+    def __call__(self, *args, **kw):
>> +        # Make this a Singleton to avoid the problem of multiple  
>> feedback
>> +        # windows popping up at the same time
>> +        return self
>> +
>> **     def _fillOptionalSection(self):
>>          try:
>>              # columns
>> **@@ -182,9 +186,6 @@
>> **         self.frame.text.AppendText(st)
>>
>>      def CreateOutputWindow(self, st):
>> **-        global activeWindow
>> -        activeWindow = self
>> -
>> **         self.frame = xrcFRAME(None)
>>          self.text = self.frame.text # superclass expects self.text
>>          try:
>> **@@ -304,7 +305,8 @@
>> **         else:
>>              self.frame.sendButton.SetLabel(_(u'Sent'))
>>              self.logReport(body, response.read())
>> **-
>> **+
>> +FeedbackWindow = FeedbackWindow()
>> **
>>  def buildXML(comments, email, optional, required):
>>      """
>> *
>>
>> * *
>>
>>
>>         *Modified: branches/0.7alpha4/chandler/application/ 
>> feedback.xrc
>>         (12206 => 12207)*
>>
>> *--- branches/0.7alpha4/chandler/application/feedback.xrc	 
>> 2006-11-02 02:32:00 UTC (rev 12206)
>> +++ branches/0.7alpha4/chandler/application/feedback.xrc	 
>> 2006-11-02 17:34:07 UTC (rev 12207)
>> **@@ -140,6 +140,8 @@
>> **               <object class="wxButton" name="restartButton">
>>                  <label>&amp;Restart</label>
>>                </object>
>> **+              <flag>wxRIGHT</flag>
>> +              <border>8</border>
>> **             </object>
>>              <object class="sizeritem">
>>                <object class="wxButton" name="closeButton">
>> *
>>
>> * *
>>
>>
>>         *Modified: branches/0.7alpha4/chandler/application/ 
>> styles.conf
>>         (12206 => 12207)*
>>
>> *--- branches/0.7alpha4/chandler/application/styles.conf	 
>> 2006-11-02 02:32:00 UTC (rev 12206)
>> +++ branches/0.7alpha4/chandler/application/styles.conf	2006-11-02  
>> 17:34:07 UTC (rev 12207)
>> **@@ -1,18 +1,18 @@
>> ** [preview]
>> **-#RRGGBB hex values for text colors in the Preview Area
>> -UnSelectedText = #000000
>> -UnSelectedTextBackground = #FFFFFF
>> **+# rgbRRGGBB hex values for text colors in the Preview Area
>> +UnSelectedText = rgb000000
>> +UnSelectedTextBackground = rgbFFFFFF
>> **
>> **-SelectedText = #000000
>> -SelectedTextBackground = #FFFFFF
>> **+SelectedText = rgb000000
>> +SelectedTextBackground = rgbFFFFFF
>> **
>>  [summary]
>> **-SectionBackground = #cccccc
>> -SectionLabel = #000000
>> -SectionCount = #888888
>> -SectionSample_triageStatus_now = #00cc00
>> -SectionSample_triageStatus_later = #ffcc00
>> -SectionSample_triageStatus_done = #555555
>> **+SectionBackground = rgbcccccc
>> +SectionLabel = rgb000000
>> +SectionCount = rgb888888
>> +SectionSample_triageStatus_now = rgb00cc00
>> +SectionSample_triageStatus_later = rgbffcc00
>> +SectionSample_triageStatus_done = rgb555555
>> **
>>  [colororder]
>>  # listed colors must all be on one line
>> *
>>
>> * *
>>
>>
>>         *Modified: branches/0.7alpha4/chandler/application/styles.py
>>         (12206 => 12207)*
>>
>> *--- branches/0.7alpha4/chandler/application/styles.py	2006-11-02  
>> 02:32:00 UTC (rev 12206)
>> +++ branches/0.7alpha4/chandler/application/styles.py	2006-11-02  
>> 17:34:07 UTC (rev 12207)
>> **@@ -22,20 +22,97 @@
>> ** can be changed by users in the course of using chandler.
>>  """
>>
>> **-import ConfigParser, os
>> **+import os
>> +from configobj import ConfigObj
>> +from ConfigParser import DuplicateSectionError, NoSectionError
>> **
>>  cfg = None
>>
>> **-class AcceptEmptyConfig(ConfigParser.SafeConfigParser):
>> -    def get(self, *args, **kwargs):
>> **+class AcceptEmptyConfig(ConfigObj):
>> +    # legacy interface to mimic ConfigParser
>> +    # (not a 100% complete)
>> +    def sections(self):
>> +        return self.keys()
>> +
>> +    def add_section(self, section):
>> +        if self.hasKey(unicode(section)):
>> +            raise DuplicateSectionError
>> +        self[unicode(section)] = {}
>> +
>> +    def has_section(self, section):
>> +        return self.hasKey(unicode(section))
>> +
>> +    def options(self, section):
>> +        if self.hasKey(unicode(section)):
>> +            return self[unicode(section)].items()
>> +        return []
>> +
>> +    def has_option(self, section, option):
>> +        return self.hasKey(unicode(section)) and self[unicode 
>> (section)].hasKey(unicode(option))
>> +
>> +    def get(self, section, option):
>> **         try:
>> **-            return ConfigParser.SafeConfigParser.get(self,  
>> *args, **kwargs)
>> -        except (ConfigParser.NoSectionError,  
>> ConfigParser.NoOptionError):
>> **+             entry = self[unicode(section)][unicode(option)]
>> +             if isinstance(entry, list):
>> +                 entry = u", ".join(entry)
>> +             elif not (isinstance(entry, str) or isinstance 
>> (entry, unicode)):
>> +                 entry = unicode(entry)
>> +             # hack for color entries
>> +             if entry.startswith(u"rgb"):
>> +                 entry = u"#%s" % entry[3:9]
>> +             return entry
>> +        except:
>> **             return None
>>
>> **+    def getint(self, section, option):
>> +        try:
>> +            return self[unicode(section)].as_int(unicode(option))
>> +        except:
>> +            return None
>> +
>> +    def getfloat(self, section, option):
>> +        try:
>> +            return self[unicode(section)].as_float(unicode(option))
>> +        except:
>> +            return None
>> +
>> +    def getboolean(self, section, option):
>> +        try:
>> +            return self[unicode(section)].as_bool(unicode(option))
>> +        except:
>> +            return None
>> +
>> +    def items(self, section):
>> +        try:
>> +            return self[unicode(section)].items()
>> +        except:
>> +            return []
>> +
>> +    def set(self, section, option, value):
>> +        if self.hasKey(unicode(section)):
>> +            self[unicode(section)][unicode(option)] = value
>> +        else:
>> +            raise NoSectionError
>> +
>> +    def remove_option(self, section, option):
>> +        if self.hasKey(unicode(section)):
>> +            if self[unicode(section)].hasKey(unicode(option)):
>> +                del self[unicode(section)][unicode(option)]
>> +                return True
>> +            else:
>> +                return False
>> +        else:
>> +            raise NoSectionError
>> +
>> +    def remove_section(self, section):
>> +        if self.hasKey(unicode(section)):
>> +            del self[unicode(section)]
>> +            return True
>> +        else:
>> +            return False
>> +
>> ** def loadConfig():
>>      global cfg
>> **-    cfg = AcceptEmptyConfig()
>> -    cfg.read(os.path.join(os.path.dirname(__file__), 'styles.conf'))
>> **+    cfg = AcceptEmptyConfig(os.path.join(os.path.dirname 
>> (__file__), 'styles.conf'), encoding="UTF8")
>> **
>>  loadConfig()
>> *
>>
>> * *
>>
>>
>>         *Modified:
>>         branches/0.7alpha4/chandler/parcels/osaf/framework/ 
>> attributeEditors/AttributeEditors.py
>>         (12206 => 12207)*
>>
>> *--- branches/0.7alpha4/chandler/parcels/osaf/framework/ 
>> attributeEditors/AttributeEditors.py	2006-11-02 02:32:00 UTC (rev  
>> 12206)
>> +++ branches/0.7alpha4/chandler/parcels/osaf/framework/ 
>> attributeEditors/AttributeEditors.py	2006-11-02 17:34:07 UTC (rev  
>> 12207)
>> **@@ -1793,15 +1793,18 @@
>> **             if ((cls.textMatches[matchKey]).lower()).startswith 
>> (target):
>>                  cal = parsedatetime.Calendar()
>>                  (dateVar, invalidFlag) = cal.parse(matchKey)
>> **-                #invalidFlag is True if the string cannot be  
>> parsed successfully
>> -                if dateVar is not None and invalidFlag is False:
>> **+                #invalidFlag = 0 implies no date/time
>> +                #invalidFlag = 2 implies only time, no date
>> +                if invalidFlag != 0 and invalidFlag != 2:
>> **                     dateStr = pim.shortDateFormat.format 
>> (datetime(*dateVar[:3]))
>>                      matchKey = cls.textMatches[matchKey]+ " : %s"  
>> % dateStr
>>                      yield matchKey
>>              else:
>>                  cal = parsedatetime.Calendar(ptc.Constants(str 
>> (getLocaleSet()[0])))
>>                  (dateVar, invalidFlag) = cal.parse(target)
>> **-                if dateVar is not None and invalidFlag is False:
>> **+                #invalidFlag = 0 implies no date/time
>> +                #invalidFlag = 2 implies only time, no date
>> +                if invalidFlag != 0 and invalidFlag != 2:
>> **                     # temporary fix: parsedatetime sometimes  
>> returns day == 0
>>                      if not filter(lambda x: not x, dateVar[:3]):
>>                          match = pim.shortDateFormat.format 
>> (datetime(*dateVar[:3]))
>> **@@ -1881,15 +1884,18 @@
>> **             if ((cls.textMatches[matchKey]).lower()).startswith 
>> (target):
>>                  cal = parsedatetime.Calendar()
>>                  (timeVar, invalidFlag) = cal.parse(matchKey)
>> **-                #invalidFlag is True if the string cannot be  
>> parsed successfully
>> -                if timeVar is not None and invalidFlag is False:
>> **+                #invalidFlag = 0 implies no date/time
>> +                #invalidFlag = 1 implies only date, no time
>> +                if invalidFlag != 0 and invalidFlag != 1:
>> **                     timeVar = pim.shortTimeFormat.format 
>> (datetime(*timeVar[:5]))
>>                      matchKey = cls.textMatches[matchKey]+ " - %s"  
>> %timeVar
>>                      yield matchKey
>>              else:
>>                  cal = parsedatetime.Calendar()
>>                  (timeVar, invalidFlag) = cal.parse(target)
>> **-                if timeVar != None and invalidFlag is False:
>> **+                #invalidFlag = 0 implies no date/time
>> +                #invalidFlag = 1 implies only date, no time
>> +                if invalidFlag != 0 and invalidFlag != 1:
>> **                     match = pim.shortTimeFormat.format(datetime 
>> (*timeVar[:5]))
>>                      if unicode(match).lower() !=target:
>>                          yield match
>> **@@ -2402,14 +2408,17 @@
>> **             TimeZoneList.buildTZChoiceList(self.item.itsView,  
>> control, value)
>>
>>  class TriageAttributeEditor(BaseAttributeEditor):
>> **+    # Set this to '' to show/edit the "real" triageStatus  
>> everywhere.
>> +    editingAttribute = 'unpurgedTriageStatus'
>> +
>> **     def Draw (self, dc, rect, (item, attributeName),  
>> isInSelection=False):
>>          # Get the value we'll draw, and its label
>>          item = RecurrenceDialog.getProxy(u'ui', item,  
>> createNew=False)
>> **-        value = getattr(item, attributeName, '')
>> **+        value = getattr(item, self.editingAttribute or  
>> attributeName, '')
>> **         label = value and pim.getTriageStatusName(value) or u''
>>
>>          # Paint our box in the right color
>> **-        backgroundColor = styles.cfg.get('summary',  
>> 'SectionSample_%s_%s'
>> **+        backgroundColor = styles.cfg.get('summary',  
>> 'SectionSample_%s_%s'
>> **                                          % (attributeName,  
>> value)) or '#000000'
>>          dc.SetPen(wx.WHITE_PEN)
>>          brush = wx.Brush(backgroundColor, wx.SOLID)
>> **@@ -2428,6 +2437,7 @@
>> **         """
>>          Handle live changes of mouse state related to our cell.
>>          """
>> **+        attributeName = self.editingAttribute or attributeName
>> **         # Note down-ness changes; eat the event if the downness  
>> changed, and
>>          # trigger an advance if appropriate.
>>          if isDown != getattr(self, 'wasDown', False):
>> *
>>
>> * *
>>
>>
>>         *Modified:
>>         branches/0.7alpha4/chandler/parcels/osaf/framework/blocks/ 
>> calendar/CalendarCanvas.py
>>         (12206 => 12207)*
>>
>> *--- branches/0.7alpha4/chandler/parcels/osaf/framework/blocks/ 
>> calendar/CalendarCanvas.py	2006-11-02 02:32:00 UTC (rev 12206)
>> +++ branches/0.7alpha4/chandler/parcels/osaf/framework/blocks/ 
>> calendar/CalendarCanvas.py	2006-11-02 17:34:07 UTC (rev 12207)
>> **@@ -700,7 +700,7 @@
>> **         sidebarCollections = app_ns.sidebarCollection
>>          allCollection = schema.ns('osaf.pim',  
>> self.event.itsItem.itsView).allCollection
>>          if self.isActive:
>> **-            fillColorLozengeType = 'UnselectedGradientRight'
>> **+            fillColorLozengeType = 'UnSelectedGradientRight'
>> **             outlinePre1 = 'Selected'
>>          else:
>>              fillColorLozengeType = 'OverlayGradientRight'
>> *
>>
>> * *
>>
>>
>>         *Modified:
>>         branches/0.7alpha4/chandler/parcels/osaf/mail/constants.py
>>         (12206 => 12207)*
>>
>> *--- branches/0.7alpha4/chandler/parcels/osaf/mail/constants.py	 
>> 2006-11-02 02:32:00 UTC (rev 12206)
>> +++ branches/0.7alpha4/chandler/parcels/osaf/mail/constants.py	 
>> 2006-11-02 17:34:07 UTC (rev 12207)
>> **@@ -63,3 +63,4 @@
>> **    i.e. __debug__ == True
>>  """
>>  VERBOSE = False
>> **+IGNORE_ATTACHMENTS = True
>> *
>>
>> * *
>>
>>
>>         *Modified: branches/0.7alpha4/chandler/parcels/osaf/mail/ 
>> imap.py
>>         (12206 => 12207)*
>>
>> *--- branches/0.7alpha4/chandler/parcels/osaf/mail/imap.py	 
>> 2006-11-02 02:32:00 UTC (rev 12206)
>> +++ branches/0.7alpha4/chandler/parcels/osaf/mail/imap.py	 
>> 2006-11-02 17:34:07 UTC (rev 12207)
>> **@@ -340,6 +340,11 @@
>> **         if curMessage[0] > self.lastUID:
>>              self.lastUID = curMessage[0]
>>
>> **+        if  "\\Seen" in curMessage[1]:
>> +            callback = defer.succeed(True)
>> +        else:
>> +            callback = self.proto.removeFlags(curMessage[0],  
>> ["\Seen"], uid=True)
>> +
>> **         messageText = msgs[msg]['RFC822']
>>
>>          #XXX: Need a more perforrmant way to do this
>> **@@ -365,15 +370,16 @@
>> **         if self.numDownloaded == self.numToDownload:
>>              self._setNextUID(self.lastUID + 1)
>>              self.totalDownloaded += self.numDownloaded
>> **-            self._commitDownloadedMail()
>> **
>> **+            return callback.addBoth(lambda x:  
>> self._commitDownloadedMail())
>> +
>> **         else:
>>              m = self.pending.pop(0)
>>
>> **-            return self.proto.fetchMessage(str(m[0]), uid=True
>> -                         ).addCallback(self._fetchMessage, m
>> -                         ).addErrback(self.catchErrors)
>> -
>> **+            return callback.addBoth(lambda x:  
>> self.proto.fetchMessage(str(m[0]), uid=True
>> +                                        ).addCallback 
>> (self._fetchMessage, m
>> +                                        ).addErrback 
>> (self.catchErrors)
>> +                                    )
>> **     def _expunge(self, result):
>>          if __debug__:
>>              trace("_expunge")
>> *
>>
>> * *
>>
>>
>>         *Modified:
>>         branches/0.7alpha4/chandler/parcels/osaf/mail/message.py  
>> (12206
>>         => 12207)*
>>
>> *--- branches/0.7alpha4/chandler/parcels/osaf/mail/message.py	 
>> 2006-11-02 02:32:00 UTC (rev 12206)
>> +++ branches/0.7alpha4/chandler/parcels/osaf/mail/message.py	 
>> 2006-11-02 17:34:07 UTC (rev 12207)
>> **@@ -30,11 +30,11 @@
>> ** #Chandler imports
>>  import osaf.pim.mail as Mail
>>  from osaf.pim import has_stamp, EventStamp, Remindable
>> **-from PyICU import UnicodeString
>> ** from i18n import ChandlerMessageFactory as _
>>
>>  #Chandler Mail Service imports
>>  import constants
>> **+from constants import IGNORE_ATTACHMENTS
>> ** from utils import *
>>  from utils import Counter
>>  from osaf.pim import TriageEnum
>> **@@ -73,16 +73,16 @@
>> **     except(UnicodeError, UnicodeDecodeError, LookupError):
>>          return unicode("".join(header.splitlines()), charset,  
>> 'ignore')
>>
>> **-def getUnicodeValue(val, charset=constants.DEFAULT_CHARSET):
>> **+def getUnicodeValue(val, charset=constants.DEFAULT_CHARSET,  
>> ignore=False):
>> **     assert isinstance(val, str), "The value to convert must be  
>> a string"
>>      assert charset is not None, "A charset must be specified"
>>
>>      try:
>> **-        # The PyICU UnicodeString is used because
>> -        # ICU has support for more character set
>> -        # encodings than Python.
>> -        return unicode(UnicodeString(val, charset))
>> **+        if ignore:
>> +            return unicode(val, charset, 'ignore')
>> **
>> **+        return unicode(val, charset)
>> +
>> **     except Exception:
>>          if  charset != constants.DEFAULT_CHARSET:
>>              return getUnicodeValue(val)
>> **@@ -258,14 +258,15 @@
>> **         # Didn't find a parsable ICS attachment: just treat it  
>> as a mail msg.
>>          m = Mail.MailMessage(itsView=view)
>>
>> **-    """
>> -    Save the original message text in a text blob
>> -    """
>> -    if messageText is None:
>> -        messageText = messageObject.as_string()
>> **+    if not IGNORE_ATTACHMENTS:
>> +        """
>> +        Save the original message text in a text blob
>> +        """
>> +        if messageText is None:
>> +            messageText = messageObject.as_string()
>> **
>> **-    m.rfc2822Message = dataToBinary(m, "rfc2822Message",  
>> messageText,
>> -                                    'message/rfc822',  
>> compression, False)
>> **+        m.rfc2822Message = dataToBinary(m, "rfc2822Message",  
>> messageText,
>> +                                        'message/rfc822',  
>> compression, False)
>> **
>>      counter = Counter()
>>      bodyBuffer = {'plain': [], 'html': []}
>> **@@ -282,12 +283,6 @@
>> **     __parsePart(view, messageObject, m, bodyBuffer, counter, buf,
>>                  compression=compression)
>>
>> **-    """
>> -    If the message has attachments set hasMimeParts to True
>> -    """
>> -    if len(m.mimeParts) > 0:
>> -        m.hasMimeParts = True
>> -
>> **     if len(bodyBuffer.get('plain')):
>>          body = constants.LF.join(bodyBuffer.get('plain')).replace 
>> (constants.CR, constants.EMPTY)
>>
>> **@@ -438,7 +433,7 @@
>> **
>>          for attachment in attachments:
>>              if has_stamp(attachment, Mail.MailStamp):
>> **-            # The attachment is another MailMessage
>> **+                # The attachment is another MailMessage
>> **                 try:
>>                      rfc2822 = binaryToData(Mail.MailStamp 
>> (attachment).rfc2822Message)
>>                  except AttributeError:
>> **@@ -463,7 +458,7 @@
>> **     return messageObject
>>
>>
>> **-def kindToMessageText(mailMessage, saveMessage=True):
>> **+def kindToMessageText(mailMessage, saveMessage=False):
>> **     """
>>      This method converts a email message string to
>>      a Chandler C{Mail.MailMessage} object
>> **@@ -620,6 +615,7 @@
>> **
>>  def __parsePart(view, mimePart, parentMIMEContainer, bodyBuffer,  
>> counter, buf,
>>                  level=0, compression='bz2'):
>> **+
>> **     __checkForDefects(mimePart)
>>
>>      if isinstance(mimePart, str):
>> **@@ -802,6 +798,10 @@
>> **
>>  def __handleBinary(view, mimePart, parentMIMEContainer,
>>                     counter, buf, level, compression):
>> **+
>> +    if IGNORE_ATTACHMENTS:
>> +        return
>> +
>> **     contype = mimePart.get_content_type()
>>
>>      if verbose():
>> **@@ -855,30 +855,31 @@
>> **     size = len(body)
>>
>>      charset = mimePart.get_content_charset 
>> (constants.DEFAULT_CHARSET)
>> **-    lang    = mimePart.get("Content-language")
>> **
>> **-    if subtype == "plain" or subtype == "rfc822-headers":
>> -        #XXX: Will want to leverage the language to aid the GUI  
>> layer
>> -        size > 0 and bodyBuffer.get('plain').append 
>> (getUnicodeValue(body, charset))
>> **+    if size and (subtype == "plain" or subtype == "rfc822- 
>> headers"):
>> +        bodyBuffer.get('plain').append(getUnicodeValue(body,  
>> charset,ignore=True))
>> **
>>      else:
>> **-        if subtype == "html":
>> -            size > 0 and bodyBuffer.get('html').append 
>> (getUnicodeValue(body, charset))
>> **+        if size and subtype == "html" and len(bodyBuffer.get 
>> ('plain')) == 0:
>> +            bodyBuffer.get('html').append(getUnicodeValue(body,  
>> charset, ignore=True))
>> **
>> **+        if IGNORE_ATTACHMENTS:
>> +            return
>> +
>> **         mimeText = Mail.MIMEText(itsView=view)
>> **-
>> **         mimeText.mimeType = mimePart.get_content_type()
>>          mimeText.charset  = charset
>>          mimeText.filesize = len(body)
>>          mimeText.filename = __getFileName(mimePart, counter)
>>
>> **+        lang = mimePart.get("Content-language")
>> +
>> **         if lang:
>>              mimeText.lang = lang
>>
>>          mimeText.itsItem.body = getUnicodeValue(body, charset)
>>
>>          parentMIMEContainer.mimeParts.append(mimeText.itsItem)
>> **-        parentMIMEContainer.hasMimeParts = True
>> **
>>  def __getFileName(mimePart, counter):
>>      #This can return none, a str, or unicode :(
>> *
>>
>> * *
>>
>>
>>         *Modified:
>>         branches/0.7alpha4/chandler/parcels/osaf/mail/tests/ 
>> TestMessage.py
>>         (12206 => 12207)*
>>
>> *--- branches/0.7alpha4/chandler/parcels/osaf/mail/tests/ 
>> TestMessage.py	2006-11-02 02:32:00 UTC (rev 12206)
>> +++ branches/0.7alpha4/chandler/parcels/osaf/mail/tests/ 
>> TestMessage.py	2006-11-02 17:34:07 UTC (rev 12207)
>> **@@ -27,6 +27,7 @@
>> ** from osaf.pim.stamping import has_stamp
>>  from osaf.pim.mail import MailStamp
>>  from osaf.pim.calendar import EventStamp
>> **+from osaf.mail.constants import IGNORE_ATTACHMENTS
>> **
>>  from PyICU import ICUtzinfo
>>  from datetime import datetime
>> **@@ -168,8 +169,10 @@
>> **         m.dateSentString = dateString
>>
>>          m.itsItem.body = u"This is the body"
>> **-        m.rfc2822Message = utils.dataToBinary(m,  
>> "rfc2822Message", self.__mail)
>> **
>> **+        if not IGNORE_ATTACHMENTS:
>> +            m.rfc2822Message = utils.dataToBinary(m,  
>> "rfc2822Message", self.__mail)
>> +
>> **         self.__mailMessage = m
>>
>>          return self.__mailMessage
>> **@@ -221,9 +224,12 @@
>> **         self.assertEquals(mOne.headers['Content-Transfer- 
>> Encoding'], mTwo.headers['Content-Transfer-Encoding'])
>>          self.assertEquals(mOne.headers['Mime-Version'],  
>> mTwo.headers['Mime-Version'])
>>          self.assertEquals(mOne.itsItem.body, mTwo.itsItem.body)
>> **-        self.assertEquals(utils.binaryToData 
>> (mOne.rfc2822Message), utils.binaryToData(mTwo.rfc2822Message))
>> **
>> **+        if not IGNORE_ATTACHMENTS:
>> +            self.assertEquals(utils.binaryToData 
>> (mOne.rfc2822Message), \
>> +                          utils.binaryToData(mTwo.rfc2822Message))
>> **
>> **+
>> **     def __compareMessageObjects(self, mOne, mTwo):
>>          self.assertNotEqual(mOne, None)
>>          self.assertNotEqual(mTwo, None)
>> *
>>
>> * *
>>
>>
>>         *Modified:
>>         branches/0.7alpha4/chandler/parcels/osaf/pim/calendar/ 
>> Calendar.py
>>         (12206 => 12207)*
>>
>> *--- branches/0.7alpha4/chandler/parcels/osaf/pim/calendar/ 
>> Calendar.py	2006-11-02 02:32:00 UTC (rev 12206)
>> +++ branches/0.7alpha4/chandler/parcels/osaf/pim/calendar/ 
>> Calendar.py	2006-11-02 17:34:07 UTC (rev 12207)
>> **@@ -1931,4 +1931,88 @@
>> **
>>  class RecurrencePattern(ContentItem):
>>      """Unused, should be removed."""
>> **+
>> +def parseText(text):
>> +    """
>> +    Parses the given text and returns the start date/time and the  
>> end date/time and
>> +    a countFlag  and a typeFlag.
>> +
>> +    countFlag indicates the number of date/times present in the  
>> text. It is an enum.
>> +    0 indicates no date/time, 1 indicates only one date/time, 2  
>> indicates more than one date/time.
>> +
>> +    typeFlag indicates the type of date/time information present.  
>> It is an ennum too.
>> +    0 indicates no date/time, 1 indicates only date, 2 indicates  
>> only time
>> +    and 3 indicates both date and time
>> +    """
>> +
>> +    import parsedatetime.parsedatetime as parsedatetime
>> +    import parsedatetime.parsedatetime_consts as ptc
>> +    from i18n import getLocaleSet
>> +    import time
>> +    import string
>> +
>> +    cal = parsedatetime.Calendar(ptc.Constants(str(getLocaleSet() 
>> [0])))
>> +    countFlag = 0   #counts the number of date/times in the text
>> +    for line in (text.split('.')):
>> +        line = string.strip(line)
>> +        if  countFlag > 1:
>> +            #More than one date time exists.
>> +            break
>> +        else:
>> +            if line is not '' and line is not None:
>> +                (dt1, dt2, typeFlag) = cal.evalRanges(line)
>> +                if typeFlag != 0:
>> +                    countFlag += 1
>> +                    # Date/time range exists
>> +                    (yr1, mth1, dy1, hr1, mn1, sec1, wd1, yd1,  
>> isdst1) = dt1
>> +                    (yr2, mth2, dy2, hr2, mn2, sec2, wd2, yd2,  
>> isdst2) = dt2
>> +
>> +                    if typeFlag == 1:
>> +                        #only date exists
>> +                        startTime = datetime(yr1, mth1, dy1,  
>> tzinfo=ICUtzinfo.default)
>> +                        endTime = datetime(yr2, mth2, dy2,  
>> tzinfo=ICUtzinfo.default)
>> +                    else:
>> +                        #time exists
>> +                        startTime = datetime(yr1, mth1, dy1, hr1,  
>> mn1, tzinfo=ICUtzinfo.default)
>> +                        endTime = datetime(yr2, mth2, dy2, hr2,  
>> mn2, tzinfo=ICUtzinfo.default)
>> +                else:
>> +                    # Check whether there is a single date/time
>> +                    (dt, typeFlag) = cal.parse(line)
>> +                    if typeFlag != 0:
>> +                        # Date/time exists
>> +                        countFlag += 1
>> +                        (yr, mth, dy, hr, mn, sec, wd, yd, isdst)  
>> = dt
>> +
>> +                        if typeFlag == 1:
>> +                            #only date exists
>> +                            startTime = endTime = datetime(yr,  
>> mth, dy, tzinfo=ICUtzinfo.default)
>> +                        else:
>> +                            #time exists
>> +                            startTime = endTime = datetime(yr,  
>> mth, dy, hr, mn, tzinfo=ICUtzinfo.default)
>> +
>> +    #If no date/time exists or more than one date/time exists,
>> +    #set the date as today's date and time as Anytime
>> +    if (countFlag == 2) or (countFlag == 0):
>> +        (yr, mth, dy, hr, mn, sec, wd, yd, isdst) = time.localtime()
>> +        startTime = endTime = datetime(yr, mth, dy,  
>> tzinfo=ICUtzinfo.default)
>> +        typeFlag = 0
>> +
>> +    return startTime, endTime, countFlag, typeFlag
>> **
>> **+
>> +def setEventDateTime(item, startTime, endTime, typeFlag):
>> +    """
>> +    Sets the startTime and the endTime of the item  
>> (CalendarEvent) depending on the typeFlag.
>> +    typeFlag = 0 indicates no date/time, 1 indicates only date, 2  
>> indicates only time
>> +    and 3 indicates both date and time
>> +    """
>> +    from osaf import pim
>> +
>> +    if (typeFlag == 1) or (typeFlag == 0):
>> +        # No time is present
>> +        pim.EventStamp(item).anyTime = True
>> +    else:
>> +        pim.EventStamp(item).anyTime = False
>> +
>> +    pim.EventStamp(item).startTime = startTime
>> +    pim.EventStamp(item).endTime = endTime
>> **\ No newline at end of file
>> *
>>
>> * *
>>
>>
>>         *Modified:
>>         branches/0.7alpha4/chandler/parcels/osaf/pim/calendar/ 
>> DateTimeUtil.py
>>         (12206 => 12207)*
>>
>> *--- branches/0.7alpha4/chandler/parcels/osaf/pim/calendar/ 
>> DateTimeUtil.py	2006-11-02 02:32:00 UTC (rev 12206)
>> +++ branches/0.7alpha4/chandler/parcels/osaf/pim/calendar/ 
>> DateTimeUtil.py	2006-11-02 17:34:07 UTC (rev 12207)
>> **@@ -96,10 +96,18 @@
>> **         self.dateFormat.setTimeZone(tzinfo.timezone)
>>          return unicode(self.dateFormat.format(datetime))
>>
>> **-shortDateFormat = DatetimeFormatter(
>> -    PyICU.DateFormat.createDateInstance(PyICU.DateFormat.kShort))
>> -mediumDateFormat = DatetimeFormatter(
>> -    PyICU.DateFormat.createDateInstance(PyICU.DateFormat.kMedium))
>> **+def forceFourDigitDates(formatter):
>> +    #""" If this formatter isn't using a 4-digit year, force it  
>> to. """
>> +    pattern = formatter.dateFormat.toPattern()
>> +    if pattern.find('yyyy') == -1:
>> +        formatter.dateFormat.applyPattern(pattern.replace 
>> ('yy','yyyy'))
>> +    return formatter
>> +
>> +
>> +shortDateFormat = forceFourDigitDates(DatetimeFormatter(
>> +    PyICU.DateFormat.createDateInstance(PyICU.DateFormat.kShort)))
>> +mediumDateFormat = forceFourDigitDates(DatetimeFormatter(
>> +    PyICU.DateFormat.createDateInstance(PyICU.DateFormat.kMedium)))
>> ** shortTimeFormat = DatetimeFormatter(
>>      PyICU.DateFormat.createTimeInstance(PyICU.DateFormat.kShort))
>>  durationFormat = PyICU.SimpleDateFormat(_(u"H:mm"))
>> *
>>
>> * *
>>
>>
>>         *Modified:
>>         branches/0.7alpha4/chandler/parcels/osaf/pim/calendar/ 
>> tests/TestFormatters.py
>>         (12206 => 12207)*
>>
>> *--- branches/0.7alpha4/chandler/parcels/osaf/pim/calendar/tests/ 
>> TestFormatters.py	2006-11-02 02:32:00 UTC (rev 12206)
>> +++ branches/0.7alpha4/chandler/parcels/osaf/pim/calendar/tests/ 
>> TestFormatters.py	2006-11-02 17:34:07 UTC (rev 12207)
>> **@@ -52,7 +52,7 @@
>> ** class ShortDateParse(AbstractTestCase):
>>
>>      def testSimple(self):
>> **-        parsed = DateTimeUtil.shortDateFormat.parse("12/11/04")
>> **+        parsed = DateTimeUtil.shortDateFormat.parse("12/11/2004")
>> **
>>          self.failUnlessEqual(parsed, datetime(2004,12,11))
>>
>> **@@ -72,7 +72,7 @@
>> **     def testSimpleWithReference(self):
>>          tzinfo = ICUtzinfo.getInstance("US/Eastern")
>>          parsed = DateTimeUtil.shortDateFormat.parse(
>> **-                    "12/11/04",
>> **+                    "12/11/2004",
>> **                     datetime(2006, 1, 1,tzinfo=tzinfo))
>>
>>          self.failUnlessEqual(parsed, datetime(2004,12,11,  
>> tzinfo=tzinfo))
>> *
>>
>> * *
>>
>>
>>         *Modified:
>>         branches/0.7alpha4/chandler/parcels/osaf/pim/collections.py
>>         (12206 => 12207)*
>>
>> *--- branches/0.7alpha4/chandler/parcels/osaf/pim/collections.py	 
>> 2006-11-02 02:32:00 UTC (rev 12206)
>> +++ branches/0.7alpha4/chandler/parcels/osaf/pim/collections.py	 
>> 2006-11-02 17:34:07 UTC (rev 12207)
>> **@@ -124,10 +124,10 @@
>> **     # other side of 'sources'
>>      sourceFor = schema.Sequence(otherName='sources')
>>
>> **-    # other side of AppCollection.exclusions
>> **+    # other side of AppCollection.collectionExclusions
>> **     exclusionsFor = schema.Sequence()
>>
>> **-    # other side of AppCollection.trash
>> **+    # other side of AppCollection.collectionTrash
>> **     trashFor = schema.Sequence()
>>
>>      schema.addClouds(
>> **@@ -475,12 +475,7 @@
>> **         if source is None:
>>              s = EmptySet()
>>          else:
>> **-            attrTuples = set()
>> -            for name in self.filterAttributes:
>> -                attrTuples.add((name, "set"))
>> -                attrTuples.add((name, "remove"))
>> -            attrs = tuple(attrTuples)
>> -
>> **+            attrs = tuple(set(self.filterAttributes))
>> **             if hasattr(self, 'filterExpression'):
>>                  s = ExpressionFilteredSet(source,  
>> self.filterExpression, attrs)
>>              else:
>> **@@ -504,16 +499,43 @@
>> **     # must be named 'inclusions' to match ListCollection
>>      inclusions = schema.Sequence(otherName='collections',  
>> initialValue=[])
>>
>> **-    exclusions = schema.One 
>> (inverse=ContentCollection.exclusionsFor)
>> -    trash = schema.One(inverse=ContentCollection.trashFor,  
>> initialValue=None)
>> **+    # the exclusions used when no exclusions collection is given
>> +    collectionExclusions = schema.Sequence(otherName='excludedBy')
>> **
>> **+    exclusionsCollection = schema.One 
>> (inverse=ContentCollection.exclusionsFor,
>> +                                      initialValue=None)
>> +    trashCollection = schema.One(inverse=ContentCollection.trashFor,
>> +                                 initialValue=None)
>> +
>> +    # an AppCollection may have another collection for exclusions  
>> and that
>> +    # other collection may be the global trash collection. If no  
>> collection
>> +    # is specified for exclusions, a local ref collection is used  
>> instead.
>> +
>> +    def _getExclusions(self):
>> +        exclusions = self.exclusionsCollection
>> +        if exclusions is None:
>> +            exclusions = self.collectionExclusions
>> +        return exclusions
>> +    exclusions = property(_getExclusions)
>> +
>> +    # an AppCollection may have another collection for trash. If no
>> +    # collection is given for trash, the collection's exclusions  
>> is used
>> +    # instead following the logic above.
>> +
>> +    def _getTrash(self):
>> +        trash = self.trashCollection
>> +        if trash is None:
>> +            trash = self.exclusions
>> +        return trash
>> +    trash = property(_getTrash)
>> +
>> **     # __collection__ denotes a bi-ref set,
>>      # therefore it must be added to the copying cloud def for it  
>> to be copied.
>>
>>      schema.addClouds(
>>          copying = schema.Cloud(
>> **-            byCloud=[inclusions, exclusions],
>> -            byRef=[trash, __collection__]
>> **+            byCloud=[inclusions, collectionExclusions,  
>> exclusionsCollection],
>> +            byRef=[trashCollection, __collection__]
>> **         ),
>>      )
>>
>> **@@ -523,15 +545,17 @@
>> **         """
>>          self.inclusions.add(item)
>>
>> **-        if item in self.exclusions:
>> -            self.exclusions.remove(item)
>> **+        exclusions = self.exclusions
>> +        if item in exclusions:
>> +            exclusions.remove(item)
>> **
>>          # If a trash is associated with this collection, remove  
>> the item
>>          # from the trash.  This has the additional benefit of  
>> having the item
>>          # reappear in any collection which has the item in its  
>> inclusions
>>
>> **-        if self.trash is not None and item in self.trash:
>> -            self.trash.remove(item)
>> **+        trash = self.trash
>> +        if trash is not None and item in trash:
>> +            trash.remove(item)
>> **
>>      def remove(self, item):
>>          """
>> **@@ -552,15 +576,17 @@
>> **         if item in self.inclusions:
>>              self.inclusions.remove(item)
>>
>> **-        if not (isDeleting or self.trash is None):
>> -            for collection in self.trash.trashFor:
>> -                if collection is not self and item in collection:
>> -                    # it exists somewhere else, definitely don't add
>> -                    # to trash
>> -                    break
>> -            else:
>> -                # we couldn't find it anywhere else, so it goes  
>> in the trash
>> -                self.trash.add(item)
>> **+        trash = self.trash
>> +        if not (isDeleting or trash is None):
>> +            if isinstance(trash, ContentCollection):
>> +                for collection in trash.trashFor:
>> +                    if collection is not self and item in  
>> collection:
>> +                        # it exists somewhere else, definitely  
>> don't add
>> +                        # to trash
>> +                        break
>> +                else:
>> +                    # we couldn't find it anywhere else, so it  
>> goes in the trash
>> +                    trash.add(item)
>> **
>>      def __init__(self, itsName=None, itsParent=None,
>>                   itsKind=None, itsView=None,
>> **@@ -602,14 +628,16 @@
>> **         if source is not None:
>>              innerSource = Union(source, innerSource)
>>
>> **-        # Typically we will create an exclusions  
>> ListCollection; however,
>> -        # a collection like 'All' will instead want to use the  
>> Trash collection
>> -        # for exclusions
>> **+        # Typically we will create a collectionExclusions ref  
>> collection;
>> +        # however, a collection like 'All' will instead want to  
>> use the
>> +        # Trash collection for exclusions
>> **
>>          if exclusions is None:
>> **-            exclusions = ListCollection(itsParent=self,
>> -                                        displayName=u"(Exclusions)")
>> -        self.exclusions = exclusions
>> **+            self.collectionExclusions = []
>> +            set = Difference(innerSource, (self,  
>> 'collectionExclusions'))
>> +        else:
>> +            self.exclusionsCollection = exclusions
>> +            set = Difference(innerSource, exclusions)
>> **
>>          # You can designate a certain ListCollection to be used  
>> for this
>>          # collection's trash; in this case, an additional  
>> DifferenceCollection
>> **@@ -621,12 +649,9 @@
>> **         #   be moved to the trash if it doesn't appear in any  
>> collection which
>>          #   shares that trash
>>
>> **-        set = Difference(innerSource, exclusions)
>> **         if trash is not None:
>>              set = Difference(set, trash)
>> **-            self.trash = trash
>> -        else:
>> -            self.trash = exclusions
>> **+            self.trashCollection = trash
>> **
>>          setattr(self, self.__collection__, set)
>>
>> **@@ -640,7 +665,7 @@
>> **         # their Difference set. This means that when they are  
>> hooked
>>          # into a larger collection tree, they need to only give out
>>          # the _left side, which has no trash.
>> **-
>> **+
>> **         if self.trash is schema.ns('osaf.pim',  
>> self.itsView).trashCollection:
>>              return self.set._left.copy(self.itsUUID)
>>
>> *
>>
>> * *
>>
>>
>>         *Modified: branches/0.7alpha4/chandler/parcels/osaf/pim/ 
>> items.py
>>         (12206 => 12207)*
>>
>> *--- branches/0.7alpha4/chandler/parcels/osaf/pim/items.py	 
>> 2006-11-02 02:32:00 UTC (rev 12206)
>> +++ branches/0.7alpha4/chandler/parcels/osaf/pim/items.py	 
>> 2006-11-02 17:34:07 UTC (rev 12207)
>> **@@ -178,7 +178,26 @@
>> **
>>      triageStatus = schema.One(TriageEnum, indexed=True,
>>                                defaultValue=TriageEnum.now)
>> **-
>> **+
>> +    _unpurgedTriageStatus = schema.One(TriageEnum)
>> +
>> +    def getUnpurgedTriageStatus(self):
>> +        result = self.getAttributeValue('_unpurgedTriageStatus',  
>> default=None)
>> +        if result is None:
>> +            result = self.triageStatus
>> +        return result
>> +
>> +    def setUnpurgedTriageStatus(self, value):
>> +        self._unpurgedTriageStatus = value
>> +
>> +    unpurgedTriageStatus = schema.Calculated(
>> +                            TriageEnum,
>> +                            fset=setUnpurgedTriageStatus,
>> +                            fget=getUnpurgedTriageStatus,
>> +                            basedOn=(_unpurgedTriageStatus,  
>> triageStatus),
>> +                            doc="Calculated for edited  
>> triageStatus, before"
>> +                                "user has committed changes")
>> +
>> **     # For sorting by how recently triageStatus changed, we keep  
>> this attribute,
>>      # which is the time (in seconds) of the last change, negated  
>> for proper
>>      # order. It's updated automatically when triageStatus is  
>> changed by
>> **@@ -199,6 +218,9 @@
>> **     # ContentItem instances can be put into ListCollections and  
>> AppCollections
>>      collections = schema.Sequence(otherName='inclusions',  
>> notify=True)
>>
>> **+    # ContentItem instances can be excluded by AppCollections
>> +    excludedBy = schema.Sequence(otherName='collectionExclusions')
>> +
>> **     # ContentItem instances can be put into SmartCollections  
>> (which define
>>      # the other end of this biref)
>>      appearsIn = schema.Sequence()
>> **@@ -458,6 +480,9 @@
>> **         when = when or datetime.now(tz=ICUtzinfo.default)
>>          self.triageStatusChanged = time.mktime(when.utctimetuple())
>>          logger.debug("%s.triageStatus = %s @ %s", self, getattr 
>> (self, 'triageStatus', None), when)
>> **+
>> +        if getattr(self, '_unpurgedTriageStatus', None) ==  
>> self.triageStatus:
>> +            del self._unpurgedTriageStatus
>> **
>>      def getBasedAttributes(self, attribute):
>>          """ Determine the schema attributes that affect this  
>> attribute
>> *
>>
>> * *
>>
>>
>>         *Modified: branches/0.7alpha4/chandler/parcels/osaf/pim/ 
>> mail.py
>>         (12206 => 12207)*
>>
>> *--- branches/0.7alpha4/chandler/parcels/osaf/pim/mail.py	 
>> 2006-11-02 02:32:00 UTC (rev 12206)
>> +++ branches/0.7alpha4/chandler/parcels/osaf/pim/mail.py	 
>> 2006-11-02 17:34:07 UTC (rev 12207)
>> **@@ -283,7 +283,6 @@
>> **     mailStamp.referencesMID = []
>>      mailStamp.spamScore = 0.0
>>      mailStamp.mimeContainer = None
>> **-    mailStamp.hasMimeParts = False
>> **     mailStamp.mimeParts = []
>>      mailStamp.messageId = u""
>>
>> **@@ -732,13 +731,12 @@
>> ** class MIMEContainer(MIMEBase):
>>      schema.kindInfo(annotates=items.ContentItem)
>>
>> **-    hasMimeParts = schema.One(schema.Boolean, initialValue =  
>> False)
>> **     mimeParts = schema.Sequence(
>>          MIMEBase,
>>          initialValue = [],
>>          inverse = MIMEBase.mimeContainer,
>>      )
>> **-    schema.addClouds(sharing = schema.Cloud(hasMimeParts,  
>> mimeParts))
>> **+    schema.addClouds(sharing = schema.Cloud(mimeParts))
>> **
>>
>>  class MailStamp(stamping.Stamp, MIMEContainer):
>> **@@ -819,7 +817,7 @@
>> **     # on with schema.observer here.
>>      @schema.observer(toAddress, stamping.Stamp.stamp_types)
>>      def updateWho(self, op, name):
>> **-        if op == 'set' and stamping.has_stamp(self, MailStamp):
>> **+        if op in ('init', 'set') and stamping.has_stamp(self,  
>> MailStamp):
>> **             self.itsItem.who = u", ".join(unicode(x) for x in  
>> self.toAddress)
>>          else:
>>              self.itsItem.who = u""
>> **@@ -918,12 +916,6 @@
>> **         """
>>          return len(self.mimeParts)
>>
>> **-    def hasAttachments(self):
>> -        """
>> -        First pass at API will be expanded upon later.
>> -        """
>> -        return self.hasMimeParts
>> -
>> **     def getSendability(self, ignoreAttr=None):
>>          """
>>          Return whether this item is ready to send: 'sendable',  
>> 'sent',
>> *
>>
>> * *
>>
>>
>>         *Modified:
>>         branches/0.7alpha4/chandler/parcels/osaf/pim/tests/ 
>> TestStamping.py
>>         (12206 => 12207)*
>>
>> *--- branches/0.7alpha4/chandler/parcels/osaf/pim/tests/ 
>> TestStamping.py	2006-11-02 02:32:00 UTC (rev 12206)
>> +++ branches/0.7alpha4/chandler/parcels/osaf/pim/tests/ 
>> TestStamping.py	2006-11-02 17:34:07 UTC (rev 12207)
>> **@@ -313,7 +313,6 @@
>> **         stampedWelcome.add()
>>
>>          self.failUnlessEqual(list(stampedWelcome.mimeParts), [])
>> **-        self.failUnlessEqual(stampedWelcome.hasMimeParts, False)
>> **         self.failUnlessEqual(stampedWelcome.mimeType, '')
>>          self.failUnlessEqual(stampedWelcome.mimeContainer, None)
>>
>> *
>>
>> * *
>>
>>
>>         *Modified:
>>         branches/0.7alpha4/chandler/parcels/osaf/servlets/xmlrpc.py
>>         (12206 => 12207)*
>>
>> *--- branches/0.7alpha4/chandler/parcels/osaf/servlets/xmlrpc.py	 
>> 2006-11-02 02:32:00 UTC (rev 12206)
>> +++ branches/0.7alpha4/chandler/parcels/osaf/servlets/xmlrpc.py	 
>> 2006-11-02 17:34:07 UTC (rev 12207)
>> **@@ -83,8 +83,8 @@
>> **         view = getServletView(self.repositoryView.repository,  
>> viewName)
>>          view.refresh()
>>          note = pim.Note(itsView=view, displayName=title, body=body)
>> **-        pim.EventStamp(note).add()
>> **         event = pim.EventStamp(note)
>> **+        event.add()
>> **         event.startTime = datetime.datetime.now 
>> (tz=ICUtzinfo.floating)
>>          event.duration = datetime.timedelta(minutes=60)
>>          event.anyTime = False
>> *
>>
>> * *
>>
>>
>>         *Modified: branches/0.7alpha4/chandler/parcels/osaf/ 
>> settings.py
>>         (12206 => 12207)*
>>
>> *--- branches/0.7alpha4/chandler/parcels/osaf/settings.py	 
>> 2006-11-02 02:32:00 UTC (rev 12206)
>> +++ branches/0.7alpha4/chandler/parcels/osaf/settings.py	 
>> 2006-11-02 17:34:07 UTC (rev 12207)
>> **@@ -15,10 +15,10 @@
>> **
>>  """Save and Restore Application Settings"""
>>
>> **-import ConfigParser, logging
>> **+import logging
>> +from configobj import ConfigObj
>> ** from application import schema
>>  from osaf import pim, sharing, usercollections
>> **-from osaf.framework.blocks import Block
>> ** from osaf.pim.structs import ColorType
>>  from application.dialogs import SubscribeCollection
>>  from chandlerdb.util.c import UUID
>> **@@ -29,179 +29,167 @@
>> ** def save(rv, filename):
>>      """Save selected settings information, including all sharing  
>> accounts
>>      and shares (whether published or subscribed), to an INI file"""
>> **-
>> -    cfg = ConfigParser.ConfigParser()
>> -
>> **+
>> +    cfg = ConfigObj()
>> +    cfg.encoding = "UTF8"
>> +    cfg.filename = filename
>> +
>> **     # Sharing accounts
>>      currentAccount = schema.ns("osaf.sharing",  
>> rv).currentWebDAVAccount.item
>> **-    section_prefix = "sharing_account"
>> **     counter = 1
>> **-
>> **     for account in sharing.WebDAVAccount.iterItems(rv):
>>          if account.username: # skip account if not configured
>> **-            section_name = "%s_%d" % (section_prefix, counter)
>> -            cfg.add_section(section_name)
>> -            cfg.set(section_name, "type", "webdav account")
>> -            cfg.set(section_name, "uuid", account.itsUUID)
>> -            cfg.set(section_name, "title", account.displayName)
>> -            cfg.set(section_name, "host", account.host)
>> -            cfg.set(section_name, "path", account.path)
>> -            cfg.set(section_name, "username", account.username)
>> -            cfg.set(section_name, "password", account.password)
>> -            cfg.set(section_name, "port", account.port)
>> -            cfg.set(section_name, "usessl", account.useSSL)
>> **+            section_name = u"sharing_account_%d" % counter
>> +            cfg[section_name] = {}
>> +            cfg[section_name][u"type"] = u"webdav account"
>> +            cfg[section_name][u"uuid"] = account.itsUUID
>> +            cfg[section_name][u"title"] = account.displayName
>> +            cfg[section_name][u"host"] = account.host
>> +            cfg[section_name][u"path"] = account.path
>> +            cfg[section_name][u"username"] = account.username
>> +            cfg[section_name][u"password"] = account.password
>> +            cfg[section_name][u"port"] = account.port
>> +            cfg[section_name][u"usessl"] = account.useSSL
>> **             if account is currentAccount:
>> **-                cfg.set(section_name, "default", "True")
>> **+                cfg[section_name][u"default"] = u"True"
>> **             counter += 1
>> **-
>> **+
>> **     # Subscriptions
>>      mine = schema.ns("osaf.pim", rv).mine
>> **-    section_prefix = "share"
>> **     counter = 1
>>      for col in pim.ContentCollection.iterItems(rv):
>>          share = sharing.getShare(col)
>>          if share:
>> **-            section_name = "%s_%d" % (section_prefix, counter)
>> -            cfg.add_section(section_name)
>> -            cfg.set(section_name, "type", "share")
>> -            cfg.set(section_name, "title",  
>> share.contents.displayName)
>> -            cfg.set(section_name, "mine", col in mine.sources)
>> **+            section_name = u"share_%d" % counter
>> +            cfg[section_name] = {}
>> +            cfg[section_name][u"type"] = u"share"
>> +            cfg[section_name][u"title"] = share.contents.displayName
>> +            cfg[section_name][u"mine"] = col in mine.sources
>> **             uc = usercollections.UserCollection(col)
>>              if getattr(uc, "color", False):
>>                  color = uc.color
>> **-                cfg.set(section_name, "red", color.red)
>> -                cfg.set(section_name, "green", color.green)
>> -                cfg.set(section_name, "blue", color.blue)
>> -                cfg.set(section_name, "alpha", color.alpha)
>> **+                cfg[section_name][u"red"] = color.red
>> +                cfg[section_name][u"green"] = color.green
>> +                cfg[section_name][u"blue"] = color.blue
>> +                cfg[section_name][u"alpha"] = color.alpha
>> **             urls = sharing.getUrls(share)
>>              if sharing.isSharedByMe(share):
>> **-                cfg.set(section_name, "publisher", "True")
>> -                cfg.set(section_name, "url", share.getLocation())
>> **+                cfg[section_name][u"publisher"] = u"True"
>> +                cfg[section_name][u"url"] = share.getLocation()
>> **             else:
>> **-                cfg.set(section_name, "publisher", "False")
>> **+                cfg[section_name][u"publisher"] = u"False"
>> **                 url = share.getLocation()
>> **-                cfg.set(section_name, "url", url)
>> **+                cfg[section_name][u"url"] = url
>> **                 if url != urls[0]:
>> **-                    cfg.set(section_name, "ticket", urls[0])
>> **+                    cfg[section_name][u"ticket"] = urls[0]
>> **                 ticketFreeBusy = getattr(share.conduit,  
>> "ticketFreeBusy", None)
>>                  if ticketFreeBusy:
>> **-                    cfg.set(section_name, "freebusy", "True")
>> **+                    cfg[section_name][u"freebusy"] = u"True"
>> **             counter += 1
>> **-
>> **+
>> **     # SMTP accounts
>> **-    section_prefix = "smtp_account"
>> **     counter = 1
>> **-
>> **     for account in pim.mail.SMTPAccount.iterItems(rv):
>>          if account.isActive and account.host:
>> **-            section_name = "%s_%d" % (section_prefix, counter)
>> -            cfg.add_section(section_name)
>> -            cfg.set(section_name, "type", "smtp account")
>> -            cfg.set(section_name, "uuid", account.itsUUID)
>> -            cfg.set(section_name, "title", account.displayName)
>> -            cfg.set(section_name, "host", account.host)
>> -            cfg.set(section_name, "auth", account.useAuth)
>> -            cfg.set(section_name, "username", account.username)
>> -            cfg.set(section_name, "password", account.password)
>> -            cfg.set(section_name, "name",  
>> account.fromAddress.fullName)
>> -            cfg.set(section_name, "address",
>> -                account.fromAddress.emailAddress)
>> -            cfg.set(section_name, "port", account.port)
>> -            cfg.set(section_name, "security",  
>> account.connectionSecurity)
>> **+            section_name = u"smtp_account_%d" % counter
>> +            cfg[section_name] = {}
>> +            cfg[section_name][u"type"] = u"smtp account"
>> +            cfg[section_name][u"uuid"] = account.itsUUID
>> +            cfg[section_name][u"title"] = account.displayName
>> +            cfg[section_name][u"host"] = account.host
>> +            cfg[section_name][u"auth"] = account.useAuth
>> +            cfg[section_name][u"username"] = account.username
>> +            cfg[section_name][u"password"] = account.password
>> +            cfg[section_name][u"name"] =  
>> account.fromAddress.fullName
>> +            cfg[section_name][u"address"] =  
>> account.fromAddress.emailAddress
>> +            cfg[section_name][u"port"] = account.port
>> +            cfg[section_name][u"security"] =  
>> account.connectionSecurity
>> **             counter += 1
>> **-
>> **+
>> **     # IMAP accounts
>>      currentAccount = schema.ns("osaf.pim",  
>> rv).currentMailAccount.item
>> **-    section_prefix = "imap_account"
>> **     counter = 1
>> **-
>> **     for account in pim.mail.IMAPAccount.iterItems(rv):
>>          if account.isActive and account.host:
>> **-            section_name = "%s_%d" % (section_prefix, counter)
>> -            cfg.add_section(section_name)
>> -            cfg.set(section_name, "type", "imap account")
>> -            cfg.set(section_name, "uuid", account.itsUUID)
>> -            cfg.set(section_name, "title", account.displayName)
>> -            cfg.set(section_name, "host", account.host)
>> -            cfg.set(section_name, "username", account.username)
>> -            cfg.set(section_name, "password", account.password)
>> -            cfg.set(section_name, "name",  
>> account.replyToAddress.fullName)
>> -            cfg.set(section_name, "address",
>> -                account.replyToAddress.emailAddress)
>> -            cfg.set(section_name, "port", account.port)
>> -            cfg.set(section_name, "security",  
>> account.connectionSecurity)
>> **+            section_name = u"imap_account_%d" % counter
>> +            cfg[section_name] = {}
>> +            cfg[section_name][u"type"] = u"imap account"
>> +            cfg[section_name][u"uuid"] = account.itsUUID
>> +            cfg[section_name][u"title"] = account.displayName
>> +            cfg[section_name][u"host"] = account.host
>> +            cfg[section_name][u"username"] = account.username
>> +            cfg[section_name][u"password"] = account.password
>> +            cfg[section_name][u"name"] =  
>> account.replyToAddress.fullName
>> +            cfg[section_name][u"address"] =  
>> account.replyToAddress.emailAddress
>> +            cfg[section_name][u"port"] = account.port
>> +            cfg[section_name][u"security"] =  
>> account.connectionSecurity
>> **             if account.defaultSMTPAccount:
>> **-                cfg.set(section_name, "smtp",
>> -                    account.defaultSMTPAccount.itsUUID)
>> **+                cfg[section_name][u"smtp"] =  
>> account.defaultSMTPAccount.itsUUID
>> **             if account is currentAccount:
>> **-                cfg.set(section_name, "default", "True")
>> **+                cfg[section_name][u"default"] = u"True"
>> **             counter += 1
>> **-
>> **+
>> **     # POP accounts
>>      currentAccount = schema.ns("osaf.pim",  
>> rv).currentMailAccount.item
>> **-    section_prefix = "pop_account"
>> **     counter = 1
>> **-
>> **     for account in pim.mail.POPAccount.iterItems(rv):
>>          if account.isActive and account.host:
>> **-            section_name = "%s_%d" % (section_prefix, counter)
>> -            cfg.add_section(section_name)
>> -            cfg.set(section_name, "type", "pop account")
>> -            cfg.set(section_name, "uuid", account.itsUUID)
>> -            cfg.set(section_name, "title", account.displayName)
>> -            cfg.set(section_name, "host", account.host)
>> -            cfg.set(section_name, "username", account.username)
>> -            cfg.set(section_name, "password", account.password)
>> -            cfg.set(section_name, "name",  
>> account.replyToAddress.fullName)
>> -            cfg.set(section_name, "address",
>> -                account.replyToAddress.emailAddress)
>> -            cfg.set(section_name, "port", account.port)
>> -            cfg.set(section_name, "security",  
>> account.connectionSecurity)
>> -            cfg.set(section_name, "leave", account.leaveOnServer)
>> **+            section_name = u"pop_account_%d" % counter
>> +            cfg[section_name] = {}
>> +            cfg[section_name][u"type"] = u"pop account"
>> +            cfg[section_name][u"uuid"] = account.itsUUID
>> +            cfg[section_name][u"title"] = account.displayName
>> +            cfg[section_name][u"host"] = account.host
>> +            cfg[section_name][u"username"] = account.username
>> +            cfg[section_name][u"password"] = account.password
>> +            cfg[section_name][u"name"] =  
>> account.replyToAddress.fullName
>> +            cfg[section_name][u"address"] =  
>> account.replyToAddress.emailAddress
>> +            cfg[section_name][u"port"] = account.port
>> +            cfg[section_name][u"security"] =  
>> account.connectionSecurity
>> +            cfg[section_name][u"leave"] = account.leaveOnServer
>> **             if account.defaultSMTPAccount:
>> **-                cfg.set(section_name, "smtp",
>> -                    account.defaultSMTPAccount.itsUUID)
>> **+                cfg[section_name][u"smtp"] =  
>> account.defaultSMTPAccount.itsUUID
>> **             if account is currentAccount:
>> **-                cfg.set(section_name, "default", "True")
>> **+                cfg[section_name][u"default"] = u"True"
>> **             counter += 1
>> **-
>> **+
>> **     # Show timezones
>> **-    cfg.add_section("timezones")
>> **+    cfg[u"timezones"] = {}
>> **     showTZ = schema.ns("osaf.app", rv).TimezonePrefs.showUI
>> **-    cfg.set("timezones", "type", "show timezones")
>> -    cfg.set("timezones", "show_timezones", showTZ)
>> -
>> **+    cfg[u"timezones"][u"type"] = u"show timezones"
>> +    cfg[u"timezones"][u"show_timezones"] = showTZ
>> +
>> **     # Visible hours
>> **-    cfg.add_section("visible_hours")
>> -    cfg.set("visible_hours", "type", "visible hours")
>> **+    cfg[u"visible_hours"] = {}
>> +    cfg[u"visible_hours"][u"type"] = u"visible hours"
>> **     calPrefs = schema.ns("osaf.framework.blocks.calendar",  
>> rv).calendarPrefs
>> **-    cfg.set("visible_hours", "height_mode",  
>> calPrefs.hourHeightMode)
>> -    cfg.set("visible_hours", "num_hours", calPrefs.visibleHours)
>> -
>> **+    cfg[u"visible_hours"][u"height_mode"] =  
>> calPrefs.hourHeightMode
>> +    cfg[u"visible_hours"][u"num_hours"] = calPrefs.visibleHours
>> +
>> **     # Event Logger
>> **-    cfg.add_section("event_logger")
>> **+    cfg[u"event_logger"] = {}
>> **     eventHook = schema.ns("eventLogger", rv).EventLoggingHook
>> **-    cfg.set("event_logger", "type", "event logger")
>> **+    cfg[u"event_logger"][u"type"] = u"event logger"
>> **     active = eventHook.logging
>> **-    cfg.set("event_logger", "active", active)
>> **+    cfg[u"event_logger"][u"active"] = active
>> +
>> +    cfg.write()
>> **
>> **-    output = file(filename, "w")
>> -    cfg.write(output)
>> -    output.close()
>> **
>> **-
>> ** def restore(rv, filename, testmode=False):
>>      """Restore accounts and shares from an INI file"""
>> **-
>> -    cfg = ConfigParser.ConfigParser()
>> -    cfg.read(filename)
>> -
>> -    # sharing accounts
>> -    for section in cfg.sections():
>> -        section_type = cfg.get(section, "type")
>> -        if section_type == "webdav account":
>> -            if cfg.has_option(section, "uuid"):
>> -                uuid = cfg.get(section, "uuid")
>> **+
>> +    cfg = ConfigObj(filename, encoding="UTF8")
>> +
>> +    for sectionname, section in cfg.iteritems():
>> +        if section.has_key(u"type"):
>> +            sectiontype = section[u"type"]
>> +        else:
>> +            sectiontype = ""
>> +        # sharing accounts
>> +        if sectiontype == u"webdav account":
>> +            if section.has_key(u"uuid"):
>> +                uuid = section[u"uuid"]
>> **                 uuid = UUID(uuid)
>>                  account = rv.findUUID(uuid)
>>                  if account is None:
>> **@@ -212,34 +200,36 @@
>> **             else:
>>                  account = sharing.WebDAVAccount(itsView=rv)
>>
>> **-            account.displayName = cfg.get(section, "title")
>> -            account.host = cfg.get(section, "host")
>> -            account.path = cfg.get(section, "path")
>> -            account.username = cfg.get(section, "username")
>> -            account.password = cfg.get(section, "password")
>> -            account.port = cfg.getint(section, "port")
>> -            account.useSSL = cfg.getboolean(section, "usessl")
>> **+            account.displayName = section[u"title"]
>> +            account.host = section[u"host"]
>> +            account.path = section[u"path"]
>> +            account.username = section[u"username"]
>> +            account.password = section[u"password"]
>> +            account.port = section.as_int(u"port")
>> +            account.useSSL = section.as_bool(u"usessl")
>> **
>> **-            if (cfg.has_option(section, "default") and
>> -                cfg.getboolean(section, "default")):
>> **+            if section.has_key(u"default") and section.as_bool 
>> (u"default"):
>> **                 accountRef = schema.ns("osaf.sharing",  
>> rv).currentWebDAVAccount
>>                  accountRef.item = account
>> **+
>> +    for sectionname, section in cfg.iteritems():
>> +        if section.has_key(u"type"):
>> +            sectiontype = section[u"type"]
>> +        else:
>> +            sectiontype = ""
>> +        # shares
>> +        if sectiontype == u"share":
>> +            url = section[u"url"]
>> **
>> **-    # shares
>> -    for section in cfg.sections():
>> -        section_type = cfg.get(section, "type")
>> -        if section_type == "share":
>> -            url = cfg.get(section, "url")
>> -
>> **             mine = False
>> **-            if cfg.has_option(section, "mine"):
>> **+            if section.has_key(u"mine"):
>> **                 # Add to my items
>> **-                mine = cfg.getboolean(section, "mine")
>> **+                mine = section.as_bool(u"mine")
>> **
>>              publisher = False
>> **-            if cfg.has_option(section, "publisher"):
>> **+            if section.has_key(u"publisher"):
>> **                 # make me the publisher
>> **-                publisher = cfg.getboolean(section, "publisher")
>> **+                publisher = section.as_bool(u"publisher")
>> **
>>              subscribed = False
>>              for share in sharing.Share.iterItems(rv):
>> **@@ -247,21 +237,22 @@
>> **                     subscribed = True
>>
>>              if not subscribed:
>> **-                if cfg.has_option(section, "ticket"):
>> -                    url = cfg.get(section, "ticket")
>> **+                url = ""
>> +                if section.has_key(u"ticket"):
>> +                    url = section[u"ticket"]
>> **                 freebusy = False
>> **-                if cfg.has_option(section, "freebusy"):
>> -                    freebusy = cfg.getboolean(section, "freebusy")
>> -                title = cfg.get(section, "title")
>> **+                if section.has_key(u"freebusy"):
>> +                    freebusy = section.as_bool(u"freebusy")
>> +                title = section[u"title"]
>> **
>> **-                if cfg.has_option(section, "red"):
>> **+                if section.has_key(u"red"):
>> **                     # Backwards-compatibility fix for bug 6899...
>>                      # Due to an earlier bug, some people's ini files
>>                      # still have floats in them, so let's cast  
>> just in case:
>> **-                    red = int(float(cfg.get(section, "red")))
>> -                    blue = int(float(cfg.get(section, "blue")))
>> -                    green = int(float(cfg.get(section, "green")))
>> -                    alpha = int(float(cfg.get(section, "alpha")))
>> **+                    red = int(float(section.as_float(u"red")))
>> +                    blue = int(float(section.as_float(u"blue")))
>> +                    green = int(float(section.as_float(u"green")))
>> +                    alpha = int(float(section.as_float(u"alpha")))
>> **                     color = ColorType(red, green, blue, alpha)
>>                  else:
>>                      color = None
>> **@@ -280,13 +271,16 @@
>> **                                              immediate=True,  
>> mine=mine,
>>                                               publisher=publisher,
>>                                               freebusy=freebusy,  
>> color=color)
>> **-
>> -    # smtp accounts
>> -    for section in cfg.sections():
>> -        section_type = cfg.get(section, "type")
>> -        if section_type == "smtp account":
>> -            if cfg.has_option(section, "uuid"):
>> -                uuid = cfg.get(section, "uuid")
>> **+
>> +    for sectionname, section in cfg.iteritems():
>> +        if section.has_key(u"type"):
>> +            sectiontype = section[u"type"]
>> +        else:
>> +            sectiontype = ""
>> +        # smtp accounts
>> +        if sectiontype == u"smtp account":
>> +            if section.has_key(u"uuid"):
>> +                uuid = section[u"uuid"]
>> **                 uuid = UUID(uuid)
>>                  account = rv.findUUID(uuid)
>>                  if account is None:
>> **@@ -297,24 +291,26 @@
>> **             else:
>>                  account = pim.mail.SMTPAccount(itsView=rv)
>>
>> **-            account.displayName = cfg.get(section, "title")
>> -            account.host = cfg.get(section, "host")
>> -            account.useAuth = cfg.getboolean(section, "auth")
>> -            account.username = cfg.get(section, "username")
>> -            account.password = cfg.get(section, "password")
>> -            account.port = cfg.getint(section, "port")
>> -            account.connectionSecurity = cfg.get(section,  
>> "security")
>> **+            account.displayName = section[u"title"]
>> +            account.host = section[u"host"]
>> +            account.useAuth = section.as_bool(u"auth")
>> +            account.username = section[u"username"]
>> +            account.password = section[u"password"]
>> +            account.port = section.as_int(u"port")
>> +            account.connectionSecurity = section[u"security"]
>> **             emailAddress = pim.mail.EmailAddress.getEmailAddress 
>> (rv,
>> **-                cfg.get(section, "address"), cfg.get(section,  
>> "name"))
>> **+                section[u"address"], section[u"name"])
>> **             account.fromAddress = emailAddress
>> **-
>> -
>> -    # imap accounts
>> -    for section in cfg.sections():
>> -        section_type = cfg.get(section, "type")
>> -        if section_type == "imap account":
>> -            if cfg.has_option(section, "uuid"):
>> -                uuid = cfg.get(section, "uuid")
>> **+
>> +    for sectionname, section in cfg.iteritems():
>> +        if section.has_key(u"type"):
>> +            sectiontype = section[u"type"]
>> +        else:
>> +            sectiontype = ""
>> +        # imap accounts
>> +        if sectiontype == u"imap account":
>> +            if section.has_key(u"uuid"):
>> +                uuid = section[u"uuid"]
>> **                 uuid = UUID(uuid)
>>                  account = rv.findUUID(uuid)
>>                  if account is None:
>> **@@ -325,33 +321,35 @@
>> **             else:
>>                  account = pim.mail.IMAPAccount(itsView=rv)
>>
>> **-            account.displayName = cfg.get(section, "title")
>> -            account.host = cfg.get(section, "host")
>> -            account.username = cfg.get(section, "username")
>> -            account.password = cfg.get(section, "password")
>> -            account.port = cfg.getint(section, "port")
>> -            account.connectionSecurity = cfg.get(section,  
>> "security")
>> **+            account.displayName = section[u"title"]
>> +            account.host = section[u"host"]
>> +            account.username = section[u"username"]
>> +            account.password = section[u"password"]
>> +            account.port = section.as_int(u"port")
>> +            account.connectionSecurity = section[u"security"]
>> **             emailAddress = pim.mail.EmailAddress.getEmailAddress 
>> (rv,
>> **-                cfg.get(section, "address"), cfg.get(section,  
>> "name"))
>> **+                section[u"address"], section[u"name"])
>> **             account.replyToAddress = emailAddress
>>
>> **-            if (cfg.has_option(section, "default") and
>> -                cfg.getboolean(section, "default")):
>> **+            if section.has_key(u"default") and section 
>> [u"default"]:
>> **                 accountRef = schema.ns("osaf.pim",  
>> rv).currentMailAccount
>>                  accountRef.item = account
>>
>> **-            if cfg.has_option(section, "smtp"):
>> -                uuid = cfg.get(section, "smtp")
>> **+            if section.has_key(u"smtp"):
>> +                uuid = section[u"smtp"]
>> **                 uuid = UUID(uuid)
>>                  smtp = rv.findUUID(uuid)
>>                  account.defaultSMTPAccount = smtp
>> **-
>> -    # pop accounts
>> -    for section in cfg.sections():
>> -        section_type = cfg.get(section, "type")
>> -        if section_type == "pop account":
>> -            if cfg.has_option(section, "uuid"):
>> -                uuid = cfg.get(section, "uuid")
>> **+
>> +    for sectionname, section in cfg.iteritems():
>> +        if section.has_key(u"type"):
>> +            sectiontype = section[u"type"]
>> +        else:
>> +            sectiontype = ""
>> +        # pop accounts
>> +        if sectiontype == u"pop account":
>> +            if section.has_key(u"uuid"):
>> +                uuid = section[u"uuid"]
>> **                 uuid = UUID(uuid)
>>                  account = rv.findUUID(uuid)
>>                  if account is None:
>> **@@ -362,46 +360,51 @@
>> **             else:
>>                  account = pim.mail.POPAccount(itsView=rv)
>>
>> **-            account.displayName = cfg.get(section, "title")
>> -            account.host = cfg.get(section, "host")
>> -            account.username = cfg.get(section, "username")
>> -            account.password = cfg.get(section, "password")
>> -            account.port = cfg.getint(section, "port")
>> -            account.connectionSecurity = cfg.get(section,  
>> "security")
>> -            account.leaveOnServer = cfg.getboolean(section, "leave")
>> **+            account.displayName = section[u"title"]
>> +            account.host = section[u"host"]
>> +            account.username = section[u"username"]
>> +            account.password = section[u"password"]
>> +            account.port = section.as_int(u"port")
>> +            account.connectionSecurity = section[u"security"]
>> +            account.leaveOnServer = section.as_bool(u"leave")
>> **             emailAddress = pim.mail.EmailAddress.getEmailAddress 
>> (rv,
>> **-                cfg.get(section, "address"), cfg.get(section,  
>> "name"))
>> **+                section[u"address"], section[u"name"])
>> **             account.replyToAddress = emailAddress
>>
>> **-            if (cfg.has_option(section, "default") and
>> -                cfg.getboolean(section, "default")):
>> **+            if section.has_key(u"default") and section 
>> [u"default"]:
>> **                 accountRef = schema.ns("osaf.pim",  
>> rv).currentMailAccount
>>                  accountRef.item = account
>>
>> **-            if cfg.has_option(section, "smtp"):
>> -                uuid = cfg.get(section, "smtp")
>> **+            if section.has_key(u"smtp"):
>> +                uuid = section[u"smtp"]
>> **                 uuid = UUID(uuid)
>>                  smtp = rv.findUUID(uuid)
>>                  account.defaultSMTPAccount = smtp
>> **+
>> +    for sectionname, section in cfg.iteritems():
>> +        if section.has_key(u"type"):
>> +            sectiontype = section[u"type"]
>> +        else:
>> +            sectiontype = ""
>> +        # timezones
>> +        if sectionname == u"timezones":
>> +            if section.has_key(u"show_timezones"):
>> +                show = section.as_bool(u"show_timezones")
>> +                schema.ns("osaf.app", rv).TimezonePrefs.showUI =  
>> show
>> +
>> +        # Visible hours
>> +        elif sectionname == u"visible_hours":
>> +            calPrefs = schema.ns 
>> ("osaf.framework.blocks.calendar", rv).calendarPrefs
>> +            if section.has_key(u"height_mode"):
>> +                calPrefs.hourHeightMode = section[u"height_mode"]
>> +            if section.has_key(u"num_hours"):
>> +                calPrefs.visibleHours = section.as_int(u"num_hours")
>> +
>> +        # Event Logger
>> +        elif sectionname == u"event_logger":
>> +            if section.has_key(u"active"):
>> +                active = section.as_bool(u"active")
>> +                if active:
>> +                    eventHook = schema.ns("eventLogger",  
>> rv).EventLoggingHook
>> +                    eventHook.onToggleLoggingEvent(None)
>> **
>> **-
>> -    # timezones
>> -    if cfg.has_section("timezones"):
>> -        if cfg.has_option("timezones", "show_timezones"):
>> -            show = cfg.getboolean("timezones", "show_timezones")
>> -            schema.ns("osaf.app", rv).TimezonePrefs.showUI = show
>> -
>> -    # Visible hours
>> -    if cfg.has_section("visible_hours"):
>> -        calPrefs = schema.ns("osaf.framework.blocks.calendar",  
>> rv).calendarPrefs
>> -        if cfg.has_option("visible_hours", "height_mode"):
>> -            calPrefs.hourHeightMode = cfg.get("visible_hours",  
>> "height_mode")
>> -        if cfg.has_option("visible_hours", "num_hours"):
>> -            calPrefs.visibleHours = cfg.getint("visible_hours",  
>> "num_hours")
>> -
>> -    # Event Logger
>> -    if cfg.has_section("event_logger"):
>> -        active = cfg.getboolean("event_logger", "active")
>> -        if active:
>> -            eventHook = schema.ns("eventLogger",  
>> rv).EventLoggingHook
>> -            eventHook.onToggleLoggingEvent(None)
>> *
>>
>> * *
>>
>>
>>         *Added: branches/0.7alpha4/chandler/parcels/osaf/sharing/ 
>> EIM.txt
>>         (12206 => 12207)*
>>
>> *--- branches/0.7alpha4/chandler/parcels/osaf/sharing/EIM.txt	 
>> 2006-11-02 02:32:00 UTC (rev 12206)
>> +++ branches/0.7alpha4/chandler/parcels/osaf/sharing/EIM.txt	 
>> 2006-11-02 17:34:07 UTC (rev 12207)
>> **@@ -0,0 +1,353 @@
>> **+----------------------
>> +The Sharing Record API
>> +----------------------
>> +
>> +
>> +>>> import osaf.sharing.eim as sharing   # API kludge during  
>> initial dev & testing
>> +
>> +
>> +Record Types and Fields
>> +=======================
>> +
>> +TODO: Record type URIs, primary keys, foreign key refs
>> +
>> +TODO: record diffing, NoChange
>> +
>> +TODO: importers, exporters, and Schemas
>> +
>> +
>> +
>> +
>> +Defining and Using Field Types
>> +==============================
>> +
>> +Custom Types
>> +------------
>> +
>> +The most basic kinds of field types can be created using the  
>> ``BytesType``,
>> +``TextType``, ``IntType``, ``DateType``, and ``LobType``  
>> constructors::
>> +
>> +    >>> my_date = sharing.DateType()
>> +    >>> my_date
>> +    sharing.DateType(None)
>> +
>> +Types can be given a unique URI, and they can be looked up by it::
>> +
>> +    >>> my_text = sharing.TextType("cid:some_text_type at osaf.us",  
>> size=99)
>> +    >>> my_text
>> +    sharing.TextType('cid:some_text_type at osaf.us', 99)
>> +
>> +    >>> sharing.typeinfo_for("cid:some_text_type at osaf.us")
>> +    sharing.TextType('cid:some_text_type at osaf.us', 99)
>> +
>> +    >>> my_text.uri
>> +    'cid:some_text_type at osaf.us'
>> +
>> +    >>> my_text.size
>> +    99
>> +
>> +But only one type can exist for a given URI at a given point in  
>> time::
>> +
>> +    >>> another_text = sharing.TextType 
>> ("cid:some_text_type at osaf.us", 99)
>> +    Traceback (most recent call last):
>> +      ...
>> +    TypeError: A type already exists for  
>> 'cid:some_text_type at osaf.us'
>> +
>> +    >>> del my_text     # no conflicting definition now
>> +    >>> another_text = sharing.TextType 
>> ("cid:some_text_type at osaf.us", 99)
>> +
>> +
>> +Type Aliasing
>> +-------------
>> +
>> +The ``sharing.typedef()`` API lets you register type information  
>> for arbitrary
>> +Python objects, so that you can use existing types, kinds, etc.  
>> as field types.
>> +For example::
>> +
>> +    >>> class my_int(int):
>> +    ...     """This is just a demonstration type"""
>> +
>> +    >>> my_int_type = sharing.IntType('cid:my_int_ex at osaf.us')
>> +    >>> sharing.typedef(my_int, my_int_type)
>> +
>> +Now, ``my_int`` can be used directly as a field type in a  
>> ``sharing.Record``
>> +class, instead of using the ``IntType`` object::
>> +
>> +    >>> class DemoRecord(sharing.Record):
>> +    ...     an_int = sharing.field(my_int)
>> +
>> +    >>> DemoRecord.an_int.type
>> +    <class 'my_int'>
>> +
>> +    >>> DemoRecord.an_int.typeinfo
>> +    sharing.IntType('cid:my_int_ex at osaf.us')
>> +
>> +You can alias more than one object to the same type, or alias an  
>> object to
>> +an already-registered alias::
>> +
>> +    >>> class my_int2(int):
>> +    ...     """Another demonstration type"""
>> +
>> +    >>> sharing.typedef(my_int2, my_int)
>> +    >>> sharing.typeinfo_for(my_int2) is sharing.typeinfo_for 
>> (my_int)
>> +    True
>> +
>> +There are also built-in aliases for anonymous versions of the  
>> sizeless
>> +primitive types (``IntType``, ``LobType``, and ``DateType``), so  
>> you can
>> +use them directly in fields::
>> +
>> +    >>> sharing.typeinfo_for(sharing.IntType)
>> +    sharing.IntType(None)
>> +
>> +    >>> sharing.typeinfo_for(sharing.LobType)
>> +    sharing.LobType(None)
>> +
>> +    >>> sharing.typeinfo_for(sharing.DateType)
>> +    sharing.DateType(None)
>> +
>> +
>> +Type Conversion
>> +---------------
>> +
>> +Because there are only five primitive EIM types (bytes, text,  
>> integer,
>> +date/time, and "lob"), it is usually necessary to convert some  
>> application-
>> +level data types to the corresponding primitive type.
>> +
>> +For example, let's say that an application has a value that is  
>> normally
>> +represented as a hexidecimal string, but which for some reason it  
>> wants to
>> +transmit as an integer in its sharing records.  The application  
>> would need
>> +to define a string converter to turn the hex string into an integer.
>> +
>> +So let's define a ``hexint`` type that we can use in field  
>> definitions where
>> +we want to be able to supply either integers or hex strings as  
>> input when
>> +creating a record.
>> +
>> +    >>> hexint = sharing.IntType('cid:hexint_example at osaf.us')
>> +
>> +    >>> class HexRecord(sharing.Record):
>> +    ...     aField = sharing.field(hexint)
>> +
>> +By default, there is no converter registered to convert strings  
>> to integers,
>> +although there is one for converting integers to integers::
>> +
>> +    >>> HexRecord(23)
>> +    HexRecord(23)
>> +
>> +    >>> HexRecord("23")
>> +    Traceback (most recent call last):
>> +      ...
>> +    TypeError: No converter registered for values of type <type  
>> 'str'>
>> +
>> +The ``sharing.add_converter()`` API allows you to register a  
>> conversion
>> +function to be used for a particular field or field type::
>> +
>> +    >>> sharing.add_converter(hexint, str, lambda v: int(v,16))
>> +    >>> HexRecord("23")
>> +    HexRecord(35)
>> +
>> +You can also override the conversion function(s) on a field-by- 
>> field basis::
>> +
>> +    >>> sharing.add_converter(HexRecord.aField, str, lambda v: int 
>> (v,8))
>> +    >>> HexRecord("23")
>> +    HexRecord(19)
>> +
>> +XXX Need more default encoders for primitive types; only int- 
>> >IntType currently
>> +    works
>> +
>> +
>> +Creating Subtypes
>> +-----------------
>> +
>> +Sometimes, it's useful to create a field type by copying an  
>> existing type.  The
>> +``sharing.subtype()`` function creates a new type from an  
>> existing one.  The
>> +new type will be of the same primitive type, and it will  
>> "inherit" any
>> +conversion functions defined for the base type::
>> +
>> +    >>> hexint2 = sharing.subtype(hexint)
>> +    >>> hexint2
>> +    sharing.IntType(None)
>> +
>> +    >>> sharing.get_converter(hexint2)("23")
>> +    35
>> +
>> +New subtypes default to having the same size as their base type, if
>> +applicable, and any extra arguments to ``subtype()`` are passed  
>> through to
>> +the appropriate constructor::
>> +
>> +    >>> bytes1 = sharing.BytesType(size=55)
>> +    >>> bytes2 = sharing.subtype(bytes1, 'bytes2 uri')
>> +    >>> bytes2
>> +    sharing.BytesType('bytes2 uri', 55)
>> +
>> +Note that you can also subtype type aliases::
>> +
>> +    >>> sharing.subtype(my_int, 'dummy uri')
>> +    sharing.IntType('dummy uri')
>> +
>> +
>> +XXX test generation-skipping in converter registration
>> +
>> +
>> +---------
>> +Internals
>> +---------
>> +
>> +TypeInfo instances are immutable once created::
>> +
>> +    >>> t = sharing.IntType()
>> +    >>> t.uri = "fhdsfblah"
>> +    Traceback (most recent call last):
>> +      ...
>> +    TypeError: sharing.IntType instances are immutable
>> +
>> +Misc. constructor data validation tests::
>> +
>> +    >>> sharing.TypeInfo()
>> +    Traceback (most recent call last):
>> +      ...
>> +    TypeError: sharing.TypeInfo is an abstract type; use a subtype
>> +
>> +    >>> sharing.SizedType()
>> +    Traceback (most recent call last):
>> +      ...
>> +    TypeError: size must be specified when creating a  
>> sharing.SizedType
>> +
>> +    >>> sharing.SizedType(size=53)
>> +    Traceback (most recent call last):
>> +      ...
>> +    TypeError: sharing.SizedType is an abstract type; use a subtype
>> +
>> +    >>> sharing.BytesType()
>> +    Traceback (most recent call last):
>> +      ...
>> +    TypeError: size must be specified when creating a  
>> sharing.BytesType
>> +
>> +    >>> sharing.TextType()
>> +    Traceback (most recent call last):
>> +      ...
>> +    TypeError: size must be specified when creating a  
>> sharing.TextType
>> +
>> +No such type::
>> +
>> +    >>> sharing.typeinfo_for('xyz:abc')
>> +    Traceback (most recent call last):
>> +      ...
>> +    UnknownType: 'xyz:abc'
>> +
>> +Recordtype/field creation and sequence numbers::
>> +
>> +    >>> class MyRecord(sharing.Record):
>> +    ...     f1, f2 = sharing.field(hexint), sharing.field(hexint)
>> +
>> +    >>> f1, f2 = MyRecord.f1, MyRecord.f2
>> +
>> +    >>> f1.name
>> +    'f1'
>> +    >>> f1.offset
>> +    1
>> +    >>> f2.offset
>> +    2
>> +    >>> f1.owner is MyRecord
>> +    True
>> +
>> +    >>> MyRecord.__fields__ == (f1, f2)
>> +    True
>> +
>> +    >>> f1.type is hexint
>> +    True
>> +    >>> f1 < f2
>> +    True
>> +    >>> f2 > f1
>> +    True
>> +    >>> f1 != f2
>> +    True
>> +    >>> f1 >= f2
>> +    False
>> +
>> +    >>> f2 == f2.seq    # must not be directly comparable to integer
>> +    False
>> +
>> +    >>> class MR2(sharing.Record):
>> +    ...     f3 = sharing.field(my_int)
>> +
>> +    >>> r = MyRecord("23", f2=3)
>> +    >>> r
>> +    MyRecord(35, 3)
>> +
>> +    >>> r.f1, r.f2
>> +    (35, 3)
>> +
>> +    >>> MR2(27)
>> +    MR2(27)
>> +
>> +    >>> sharing.field(27)   # must be a registered type or alias
>> +    Traceback (most recent call last):
>> +      ...
>> +    UnknownType: 27
>> +
>> +Verify that the generated constructor code shows up in tracebacks::
>> +
>> +    >>> try:
>> +    ...     MR2(42.0)
>> +    ... except:
>> +    ...     import traceback
>> +    ...     tb = traceback.format_exc()
>> +
>> +    >>> print tb
>> +    Traceback (most recent call last):
>> +      File ...
>> +        MR2(42.0)
>> +      File "EIM-Generated Constructor for __builtin__.MR2", line  
>> 2, in __new__
>> +        f3 = get_converter(cls.f3)(f3)
>> +      ...
>> +    TypeError: No converter registered for values of type <type  
>> 'float'>
>> +    <BLANKLINE>
>> +
>> +Immutable field attrs::
>> +
>> +    >>> sharing.field(my_int).foo = "bar"
>> +    Traceback (most recent call last):
>> +      ...
>> +    AttributeError: 'field' object has no attribute 'foo'
>> +
>> +    >>> MyRecord.f1.offset = 16
>> +    Traceback (most recent call last):
>> +      ...
>> +    TypeError: field objects are immutable
>> +
>> +Record is dict-less, immutable::
>> +
>> +    >>> r.__dict__
>> +    Traceback (most recent call last):
>> +      ...
>> +    AttributeError: 'MyRecord' object has no attribute '__dict__'
>> +
>> +    >>> r.f1 = 42
>> +    Traceback (most recent call last):
>> +      ...
>> +    AttributeError: 'MyRecord' object attribute 'f1' is read-only
>> +
>> +    >>> r.xxx = 99
>> +    Traceback (most recent call last):
>> +      ...
>> +    AttributeError: 'MyRecord' object has no attribute 'xxx'
>> +
>> +
>> +Can't subclass an existing record type, or reuse fields in other  
>> record types::
>> +
>> +    >>> class CantDoThis(MyRecord):
>> +    ...     pass
>> +    Traceback (most recent call last):
>> +      ...
>> +    TypeError: Record classes cannot be subclassed
>> +
>> +    >>> class CantDoThis(sharing.Record):
>> +    ...     f3 = MyRecord.f1
>> +    Traceback (most recent call last):
>> +      ...
>> +    TypeError: Can't reuse field 'MyRecord.f1' as 'CantDoThis.f3'
>> +
>> +
>> +XXX typeinfo_for(obj) -> TypeInfo
>> +   descr -> typeinfo_for(descr.type)
>> +
>> **Property changes on: branches/0.7alpha4/chandler/parcels/osaf/ 
>> sharing/EIM.txt
>> ___________________________________________________________________
>> Name: svn:executable
>>    + *
>> Name: svn:mime-type
>>    + text/plain
>> Name: svn:eol-style
>>    + native
>> *
>>
>> * *
>>
>>
>>         *Modified:
>>         branches/0.7alpha4/chandler/parcels/osaf/sharing/Sharing.py
>>         (12206 => 12207)*
>>
>> *--- branches/0.7alpha4/chandler/parcels/osaf/sharing/Sharing.py	 
>> 2006-11-02 02:32:00 UTC (rev 12206)
>> +++ branches/0.7alpha4/chandler/parcels/osaf/sharing/Sharing.py	 
>> 2006-11-02 17:34:07 UTC (rev 12207)
>> **@@ -2902,11 +2902,11 @@
>> **                             'list'):
>>                              itemValue = list(itemValue)
>>
>> **-                        # ... with the exception of  
>> hasMimeParts and
>> **+                        # ... with the exception of
>> **                         # mimeParts, which always seem to have  
>> been written
>>                          # in the "old" world.
>>                          if ( (not (hasMailStamp and  
>> splitComponents[-1] in
>> **-                                ('hasMimeParts', 'mimeParts')))  
>> and
>> **+                                ('mimeParts'))) and
>> **                                 itemValue == initial ):
>>                              continue
>>
>> *
>>
>> * *
>>
>>
>>         *Added: branches/0.7alpha4/chandler/parcels/osaf/sharing/ 
>> eim.py
>>         (12206 => 12207)*
>>
>> *--- branches/0.7alpha4/chandler/parcels/osaf/sharing/eim.py	 
>> 2006-11-02 02:32:00 UTC (rev 12206)
>> +++ branches/0.7alpha4/chandler/parcels/osaf/sharing/eim.py	 
>> 2006-11-02 17:34:07 UTC (rev 12207)
>> **@@ -0,0 +1,369 @@
>> **+__all__ = [
>> +    'UnknownType', 'typeinfo_for', 'BytesType', 'TextType',  
>> 'DateType',
>> +    'IntType', 'LobType', 'get_converter', 'add_converter',  
>> 'subtype',
>> +    'typedef',
>> +]
>> +
>> +from simplegeneric import generic
>> +from weakref import WeakValueDictionary
>> +import linecache, os
>> +
>> + at generic
>> +def get_converter(context):
>> +    """Return a conversion function for encoding in the `context`  
>> type context
>> +    """
>> +    ctx = typeinfo_for(context)
>> +
>> +    if isinstance(context,type) and issubclass(context, TypeInfo):
>> +        # prevent infinite recursion for unregistered primitive  
>> types
>> +        # if this error occurs, somebody added a new primitive  
>> type without
>> +        # creating a base conversion function for it
>> +        raise AssertionError("Unregistered metatype", ctx)
>> +
>> +    return get_converter(ctx)
>> +
>> + at generic
>> +def default_converter(value):
>> +    raise TypeError(
>> +        "No converter registered for values of type %r" % type 
>> (value)
>> +    )
>> +
>> +def add_converter(context, from_type, converter):
>> +    """Register `converter` for converting `from_type` in  
>> `context`"""
>> +    # XXX if converters cached by record types, add hooks here  
>> for updating
>> +    gf = get_converter(context)
>> +    if not get_converter.has_object(context):
>> +        gf = generic(gf)    # extend base function
>> +        get_converter.when_object(context)(lambda context: gf)
>> +    gf.when_type(from_type)(converter)
>> +
>> +
>> +
>> +class UnknownType(KeyError):
>> +    """An object was not recognized as a type, alias, context, or  
>> URI"""
>> +
>> +
>> + at generic
>> +def typeinfo_for(context):
>> +    """Return the relevant ``sharing.TypeInfo`` for `context`
>> +
>> +    `context` may be a URI string, a ``sharing.TypeInfo``,  
>> ``sharing.Field``,
>> +    or ``schema.Descriptor`` (e.g. ``schema.One``, etc.).   
>> object.  It can also
>> +    be any object registered as a type alias using  
>> ``sharing.typedef()``.
>> +
>> +    The return value is a ``sharing.TypeInfo``.  If no type  
>> information is
>> +    available for `context`, raise ``sharing.UnknownType``
>> +    """
>> +    raise UnknownType(context)
>> +
>> +
>> +types_by_uri = WeakValueDictionary()
>> +
>> + at typeinfo_for.when_type(str)
>> +def lookup_by_uri(context):
>> +    try:
>> +        return types_by_uri[context]
>> +    except KeyError:
>> +        return typeinfo_for.default(context)
>> +
>> +
>> +def typedef(alias, typeinfo):
>> +    """Register `alias` as an alias for `typeinfo`
>> +
>> +    `alias` may be any object.  `typeinfo` must be a type  
>> context, i.e.,
>> +    ``typeinfo_for()`` should return a ``TypeInfo`` for it.   
>> (Which means it
>> +    can be a ``TypeInfo``, a URI, or a registered alias, field,  
>> etc.)
>> +    An error occurs if `alias` is already registered."""
>> +    typeinfo = typeinfo_for(typeinfo)   # unaliases and validates  
>> typeinfo
>> +    typeinfo_for.when_object(alias)(lambda context: typeinfo)
>> +
>> +
>> +
>> +
>> +class TypeInfo(object):
>> +    size = None
>> +    abstract = True
>> +    __slots__ = 'uri', '__weakref__'
>> +
>> +    def __init__(self, uri=None):
>> +        if self.__class__.__dict__.get('abstract'):
>> +            raise TypeError(
>> +                "sharing.%s is an abstract type; use a subtype"
>> +                % self.__class__.__name__
>> +            )
>> +        if uri is not None and uri in types_by_uri:
>> +            raise TypeError("A type already exists for "+repr(uri))
>> +        self.uri = uri
>> +        types_by_uri[uri] = self
>> +
>> +    def __setattr__(self, attr, value):
>> +        if hasattr(self, 'uri'):    # have we been initialized?
>> +            raise TypeError(
>> +                "sharing.%s instances are immutable" %  
>> self.__class__.__name__
>> +            )
>> +        object.__setattr__(self, attr, value)
>> +
>> +    def __repr__(self):
>> +        return 'sharing.%s(%r)' % (
>> +            self.__class__.__name__, self.uri
>> +        )
>> +
>> +    def clone(self, uri=None, *args, **kw):
>> +        return self.__class__(uri, *args, **kw)
>> +
>> + at get_converter.when_type(TypeInfo)
>> +def get_default_converter_for_primitive_type(context):
>> +    return get_converter(type(context))
>> +
>> + at typeinfo_for.when_type(TypeInfo)
>> +def return_typeinfo(context):
>> +    return context  # TypeInfo can be used as-is
>> +
>> +
>> +
>> +class SizedType(TypeInfo):
>> +    abstract = True
>> +    __slots__ = 'size'
>> +
>> +    def __init__(self, uri=None, size=None):
>> +        if size is None:
>> +            raise TypeError(
>> +                "size must be specified when creating a sharing."
>> +                + self.__class__.__name__
>> +            )
>> +        self.size = size
>> +        TypeInfo.__init__(self, uri)
>> +
>> +    def __repr__(self):
>> +        return 'sharing.%s(%r, %d)' % (
>> +            self.__class__.__name__, self.uri, self.size
>> +        )
>> +
>> +    def clone(self, uri=None, size=None, *args, **kw):
>> +        if size is None:
>> +            size = self.size
>> +        return self.__class__(uri, size, *args, **kw)
>> +
>> +class BytesType(SizedType): __slots__ = ()
>> +class TextType(SizedType):  __slots__ = ()
>> +class IntType(TypeInfo):    __slots__ = ()
>> +class DateType(TypeInfo):   __slots__ = ()
>> +class LobType(TypeInfo):    __slots__ = ()
>> +
>> +# define aliases so () is optional for anonymous unsized field types
>> +typedef(IntType,  IntType())
>> +typedef(LobType,  LobType())
>> +typedef(DateType, DateType())
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +# Monkeypatch linecache to not throw out lines that don't come  
>> from files
>> +# This patch is only needed for Python 2.4, as identical code is  
>> part of
>> +# the linecache module in Python 2.5.  As soon as we go to 2.5,  
>> we can remove
>> +# all of this code down to the '### END' marker below.
>> +#
>> +def checkcache(filename=None):
>> +    """Discard cache entries that are out of date.
>> +    (This is not checked upon each call!)"""
>> +
>> +    if filename is None:
>> +        filenames = linecache.cache.keys()
>> +    else:
>> +        if filename in linecache.cache:
>> +            filenames = [filename]
>> +        else:
>> +            return
>> +
>> +    for filename in filenames:
>> +        size, mtime, lines, fullname = linecache.cache[filename]
>> +        if mtime is None:
>> +            continue   # no-op for files loaded via a __loader__
>> +        try:
>> +            stat = os.stat(fullname)
>> +        except os.error:
>> +            del linecache.cache[filename]
>> +            continue
>> +        if size != stat.st_size or mtime != stat.st_mtime:
>> +            del linecache.cache[filename]
>> +
>> +linecache.checkcache = checkcache
>> +
>> +### END
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +def _constructor_for(name, cdict, fields):
>> +    fname = "EIM-Generated Constructor for %s.%s" % (cdict 
>> ['__module__'],name)
>> +    args =', '.join(f.name for f in fields)
>> +    conversions = ''.join(
>> +        "\n    %s = get_converter(cls.%s)(%s)" %  
>> (f.name,f.name,f.name)
>> +        for f in fields
>> +    )
>> +    source = (
>> +        "def __new__(cls, %(args)s):%(conversions)s\n"
>> +        "    return tuple.__new__(cls, (cls, %(args)s))""" %  
>> locals()
>> +    )
>> +    # Push the source into the linecache
>> +    lines = [line+'\n' for line in source.splitlines()]
>> +    linecache.cache[fname] = 0, None, lines, fname
>> +    return compile(source, fname, "exec")
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +class RecordClass(type):
>> +    def __new__(meta, name, bases, cdict):
>> +        try:
>> +            Record
>> +        except NameError:
>> +            pass
>> +        else:
>> +            if bases != (Record,):
>> +                raise TypeError("Record classes cannot be  
>> subclassed")
>> +        fields = []
>> +        for attr, val in cdict.items():
>> +            if isinstance(val, field):
>> +                if val.owner is not None:
>> +                    raise TypeError(
>> +                        "Can't reuse field '%s.%s' as '%s.%s'" %
>> +                        (val.owner.__name__, val.name, name, attr)
>> +                    )
>> +                val.name = attr
>> +                fields.append(val)
>> +
>> +        fields.sort()
>> +        cdict['__slots__'] = ()
>> +        cdict['__fields__'] = tuple(fields)
>> +        exec _constructor_for(name, cdict, fields) in globals(),  
>> cdict
>> +        cls = type.__new__(meta, name, bases, cdict)
>> +        for n,f in enumerate(fields):
>> +            f.owner = cls
>> +            f.offset = n+1
>> +        return cls
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +_field_num = 1
>> +
>> +class field(object):
>> +    __slots__ = "owner", "name", "type", "typeinfo", "seq", "offset"
>> +    def __init__(self, type):
>> +        global _field_num
>> +        self.owner = self.name = None
>> +        self.type = type
>> +        self.typeinfo = typeinfo_for(type)
>> +        self.seq = _field_num = _field_num + 1
>> +
>> +    def __setattr__(self, attr, val):
>> +        if hasattr(self,'offset'):
>> +            raise TypeError("field objects are immutable")
>> +        super(field, self).__setattr__(attr, val)
>> +
>> +    def __cmp__(self, other):
>> +        if isinstance(other, field):
>> +            return cmp(self.seq, other.seq)
>> +        return cmp(id(self), id(other))
>> +
>> +    def __get__(self, ob, typ=None):
>> +        if ob is None:
>> +            return self
>> +        return ob[self.offset]
>> +
>> + at typeinfo_for.when_type(field)
>> +def return_typeinfo(context):
>> +    return context.typeinfo
>> +
>> +class Record(tuple):
>> +    __slots__ = ()
>> +    __metaclass__ = RecordClass
>> +    def __repr__(self):
>> +        r = "%s%r" % (self.__class__.__name__, self[1:])
>> +        if r.endswith(',)'):
>> +            return r[:-2]+')'
>> +        return r
>> +
>> +
>> +
>> +def create_default_converter(t):
>> +    converter = generic(default_converter)
>> +    get_converter.when_object(t)(lambda ctx: converter)
>> +
>> +map(create_default_converter,
>> +    [BytesType, TextType, IntType, DateType, LobType]
>> +)
>> +
>> +add_converter(IntType, int, int)
>> +
>> +
>> +def subtype(typeinfo, *args, **kw):
>> +    """XXX"""
>> +    newti = typeinfo_for(typeinfo).clone(*args, **kw)
>> +    gf = generic(get_converter(typeinfo))
>> +    get_converter.when_object(newti)(lambda ctx:gf)
>> +    return newti
>> +
>> +def test_suite():
>> +    import doctest
>> +    return doctest.DocFileSuite(
>> +        'EIM.txt',
>> +        optionflags=doctest.ELLIPSIS| 
>> doctest.REPORT_ONLY_FIRST_FAILURE,
>> +    )
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> **Property changes on: branches/0.7alpha4/chandler/parcels/osaf/ 
>> sharing/eim.py
>> ___________________________________________________________________
>> Name: svn:executable
>>    + *
>> Name: svn:mime-type
>>    + text/plain
>> Name: svn:eol-style
>>    + native
>> *
>>
>> * *
>>
>>
>>         *Added:
>>         branches/0.7alpha4/chandler/parcels/osaf/sharing/ 
>> simplegeneric.py
>>         (12206 => 12207)*
>>
>> *--- branches/0.7alpha4/chandler/parcels/osaf/sharing/ 
>> simplegeneric.py	2006-11-02 02:32:00 UTC (rev 12206)
>> +++ branches/0.7alpha4/chandler/parcels/osaf/sharing/ 
>> simplegeneric.py	2006-11-02 17:34:07 UTC (rev 12207)
>> **@@ -0,0 +1,126 @@
>> **+# This is a copy of PJE's 'simplegeneric 0.6' package; it  
>> should be replaced
>> +# with an egg dependency as soon as practical.  (i.e., DON'T EDIT  
>> THIS CODE.)
>> +
>> +__all__ = ["generic"]
>> +
>> +from types import ClassType, InstanceType
>> +classtypes = type, ClassType
>> +
>> +def generic(func):
>> +    """Create a simple generic function"""
>> +
>> +    _sentinel = object()
>> +
>> +    def _by_class(*args, **kw):
>> +        cls = args[0].__class__
>> +        for t in type(cls.__name__, (cls,object), {}).__mro__:
>> +            f = _gbt(t, _sentinel)
>> +            if f is not _sentinel:
>> +                return f(*args, **kw)
>> +        else:
>> +            return func(*args, **kw)
>> +
>> +    _by_type = {object: func, InstanceType: _by_class}
>> +    _gbt = _by_type.get
>> +
>> +    def when_type(t):
>> +        """Decorator to add a method that will be called for type  
>> `t`"""
>> +        if not isinstance(t, classtypes):
>> +            raise TypeError(
>> +                "%r is not a type or class" % (t,)
>> +            )
>> +        def decorate(f):
>> +            if _by_type.setdefault(t,f) is not f:
>> +                raise TypeError(
>> +                    "%r already has method for type %r" % (func, t)
>> +                )
>> +            return f
>> +        return decorate
>> +
>> +
>> +
>> +
>> +
>> +
>> +    _by_object = {}
>> +    _gbo = _by_object.get
>> +
>> +    def when_object(o):
>> +        """Decorator to add a method that will be called for  
>> object `o`"""
>> +        def decorate(f):
>> +            if _by_object.setdefault(id(o), (o,f))[1] is not f:
>> +                raise TypeError(
>> +                    "%r already has method for object %r" %  
>> (func, o)
>> +                )
>> +            return f
>> +        return decorate
>> +
>> +
>> +    def dispatch(*args, **kw):
>> +        f = _gbo(id(args[0]), _sentinel)
>> +        if f is _sentinel:
>> +            for t in type(args[0]).__mro__:
>> +                f = _gbt(t, _sentinel)
>> +                if f is not _sentinel:
>> +                    return f(*args, **kw)
>> +            else:
>> +                return func(*args, **kw)
>> +        else:
>> +            return f[1](*args, **kw)
>> +
>> +    dispatch.__name__       = func.__name__
>> +    dispatch.__dict__       = func.__dict__.copy()
>> +    dispatch.__doc__        = func.__doc__
>> +    dispatch.__module__     = func.__module__
>> +
>> +    dispatch.when_type = when_type
>> +    dispatch.when_object = when_object
>> +    dispatch.default = func
>> +    dispatch.has_object = lambda o: id(o) in _by_object
>> +    dispatch.has_type   = lambda t: t in _by_type
>> +    return dispatch
>> +
>> +
>> +
>> +
>> +def test_suite():
>> +    import doctest
>> +    return doctest.DocFileSuite(
>> +        'README.txt',
>> +        optionflags=doctest.ELLIPSIS| 
>> doctest.REPORT_ONLY_FIRST_FAILURE,
>> +    )
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> +
>> **Property changes on: branches/0.7alpha4/chandler/parcels/osaf/ 
>> sharing/simplegeneric.py
>> ___________________________________________________________________
>> Name: svn:executable
>>    + *
>> Name: svn:mime-type
>>    + text/plain
>> Name: svn:eol-style
>>    + native
>> *
>>
>> * *
>>
>>
>>         *Added:
>>         branches/0.7alpha4/chandler/parcels/osaf/sharing/tests/ 
>> TestEIM.py
>>         (12206 => 12207)*
>>
>> *--- branches/0.7alpha4/chandler/parcels/osaf/sharing/tests/ 
>> TestEIM.py	2006-11-02 02:32:00 UTC (rev 12206)
>> +++ branches/0.7alpha4/chandler/parcels/osaf/sharing/tests/ 
>> TestEIM.py	2006-11-02 17:34:07 UTC (rev 12207)
>> **@@ -0,0 +1,8 @@
>> **+import unittest
>> +from util.test_finder import ScanningLoader
>> +unittest.main(
>> +        module=None, testLoader = ScanningLoader(),
>> +        argv=["unittest", "osaf.sharing.eim.test_suite"]
>> +)
>> +
>> +
>> **Property changes on: branches/0.7alpha4/chandler/parcels/osaf/ 
>> sharing/tests/TestEIM.py
>> ___________________________________________________________________
>> Name: svn:mime-type
>>    + text/plain
>> Name: svn:eol-style
>>    + native
>> *
>>
>> * *
>>
>>
>>         *Modified:
>>         branches/0.7alpha4/chandler/parcels/osaf/sharing/tests/ 
>> bad.xml
>>         (12206 => 12207)*
>>
>> *--- branches/0.7alpha4/chandler/parcels/osaf/sharing/tests/ 
>> bad.xml	2006-11-02 02:32:00 UTC (rev 12206)
>> +++ branches/0.7alpha4/chandler/parcels/osaf/sharing/tests/bad.xml	 
>> 2006-11-02 17:34:07 UTC (rev 12207)
>> **@@ -35,7 +35,6 @@
>> **     <bccAddress>
>>      </bccAddress>
>>      <subject>Somebody working from New York</subject>
>> **-    <hasMimeParts>True</hasMimeParts>
>> **     <mimeParts>
>>         <MIMEText class='osaf.pim.mail.MIMEText'  
>> uuid='a5992270-23e2-11db-9020-ae744e613304'>
>>            <filename>event.ics</filename>
>> *
>>
>> * *
>>
>>
>>         *Modified:
>>         branches/0.7alpha4/chandler/parcels/osaf/sharing/tests/ 
>> compatibility/ComplexMail.xml
>>         (12206 => 12207)*
>>
>> *--- branches/0.7alpha4/chandler/parcels/osaf/sharing/tests/ 
>> compatibility/ComplexMail.xml	2006-11-02 02:32:00 UTC (rev 12206)
>> +++ branches/0.7alpha4/chandler/parcels/osaf/sharing/tests/ 
>> compatibility/ComplexMail.xml	2006-11-02 17:34:07 UTC (rev 12207)
>> **@@ -24,7 +24,6 @@
>> **       <EmailAddress uuid='09dd5f96-442a-11db-bd6e-0016cbca6aed' />
>>     </replyToAddress>
>>     <subject>ALTERNATIVE MIMETYPE TEST</subject>
>> **-   <hasMimeParts>True</hasMimeParts>
>> **    <mimeParts>
>>        <MIMEBinary class='osaf.pim.mail.MIMEBinary'  
>> uuid='09dbbb82-442a-11db-bd6e-0016cbca6aed'>
>>           <filename>Attachment-1.obj</filename>
>> *
>>
>> * *
>>
>>
>>         *Modified:
>>         branches/0.7alpha4/chandler/parcels/osaf/sharing/tests/ 
>> compatibility/Mail.xml
>>         (12206 => 12207)*
>>
>> *--- branches/0.7alpha4/chandler/parcels/osaf/sharing/tests/ 
>> compatibility/Mail.xml	2006-11-02 02:32:00 UTC (rev 12206)
>> +++ branches/0.7alpha4/chandler/parcels/osaf/sharing/tests/ 
>> compatibility/Mail.xml	2006-11-02 17:34:07 UTC (rev 12207)
>> **@@ -37,7 +37,6 @@
>> **    </tags>
>>     <triageStatus>later</triageStatus>
>>     <triageStatusChanged>1159945337.0</triageStatusChanged>
>> **-   <hasMimeParts>False</hasMimeParts>
>> **    <mimeParts>
>>     </mimeParts>
>>  </MailMessage>
>> *
>>
>> * *
>>
>>
>>         *Modified:
>>         branches/0.7alpha4/chandler/parcels/osaf/sharing/tests/ 
>> compatibility/MailedEventTask.xml
>>         (12206 => 12207)*
>>
>> *--- branches/0.7alpha4/chandler/parcels/osaf/sharing/tests/ 
>> compatibility/MailedEventTask.xml	2006-11-02 02:32:00 UTC (rev 12206)
>> +++ branches/0.7alpha4/chandler/parcels/osaf/sharing/tests/ 
>> compatibility/MailedEventTask.xml	2006-11-02 17:34:07 UTC (rev 12207)
>> **@@ -13,7 +13,6 @@
>> **    <bccAddress>
>>     </bccAddress>
>>     <subject>Here we go.....</subject>
>> **-   <hasMimeParts>False</hasMimeParts>
>> **    <mimeParts>
>>     </mimeParts>
>>     <mimeType>message/rfc822</mimeType>
>> *
>>
>> * *
>>
>>
>>         *Modified:
>>         branches/0.7alpha4/chandler/parcels/osaf/sharing/tests/ 
>> compatibility/TestXMLCompatibility.py
>>         (12206 => 12207)*
>>
>> *--- branches/0.7alpha4/chandler/parcels/osaf/sharing/tests/ 
>> compatibility/TestXMLCompatibility.py	2006-11-02 02:32:00 UTC (rev  
>> 12206)
>> +++ branches/0.7alpha4/chandler/parcels/osaf/sharing/tests/ 
>> compatibility/TestXMLCompatibility.py	2006-11-02 17:34:07 UTC (rev  
>> 12207)
>> **@@ -304,7 +304,6 @@
>> **         # Make sure importing an Event didn't delete attributes
>>          # on MailStamp.
>>          mailMsg = pim.mail.MailStamp(eventItem)
>> **-        self.failUnlessEqual(mailMsg.hasMimeParts, False)
>> **         self.failUnlessEqual(mailMsg.mimeContainer, None)
>>          self.failUnlessEqual(list(mailMsg.mimeParts), [])
>>          self.failUnlessEqual(list(mailMsg.toAddress), [])
>> **@@ -486,7 +485,6 @@
>> **         self.attributes.update(toAddress=[address],
>>                                 fromAddress=address,
>>                                 replyToAddress=address,
>> **-                               hasMimeParts=True,
>> **                                mimeParts=[mimeBinary, mimeText])
>>
>>      def testExport(self):
>> *
>>
>> * *
>>
>>
>>         *Modified:
>>         branches/0.7alpha4/chandler/parcels/osaf/views/detail/ 
>> detail.py
>>         (12206 => 12207)*
>>
>> *--- branches/0.7alpha4/chandler/parcels/osaf/views/detail/ 
>> detail.py	2006-11-02 02:32:00 UTC (rev 12206)
>> +++ branches/0.7alpha4/chandler/parcels/osaf/views/detail/ 
>> detail.py	2006-11-02 17:34:07 UTC (rev 12207)
>> **@@ -56,7 +56,9 @@
>> ** from i18n import ChandlerMessageFactory as _
>>  from osaf import messages
>>
>> **-import parsedatetime.parsedatetime as parsedatetime
>> **+import parsedatetime.parsedatetime as parsedatetime
>> +import parsedatetime.parsedatetime_consts as ptc
>> +from i18n import getLocaleSet
>> **
>>
>>  logger = logging.getLogger(__name__)
>> **@@ -451,9 +453,29 @@
>> **         if pim.has_stamp(item, self.stampClass):
>>              stampClass(item).remove()
>>          else:
>> **+            startTimeExists = hasattr(item,  
>> pim.EventStamp.startTime.name)
>> **             stampClass(item).add()
>> **-
>> -
>> **+
>> +            if stampClass == Calendar.EventStamp and not  
>> startTimeExists:
>> +                # If the item is being stamped as CalendarEvent,  
>> parse the body
>> +                # of the item for date/time information, if the  
>> item does not
>> +                # already have a startTime.
>> +                startTime, endTime, countFlag, typeFlag = \
>> +                         pim.calendar.Calendar.parseText(item.body)
>> +
>> +                statusMsg = { 0:_(u"No date/time found"),
>> +                              1:_(u"Event set to the date/time  
>> found"),
>> +                              2:_(u"Multiple date/times found")}
>> +
>> +                # Set the appropriate status message in the  
>> status bar
>> +                wx.GetApp().CallItemMethodAsync("MainView",  
>> 'setStatusMessage',
>> +                                                statusMsg 
>> [countFlag])
>> +
>> +                # Set the event's start and end date/time
>> +                pim.calendar.Calendar.setEventDateTime(item,  
>> startTime, endTime,
>> +                                                       typeFlag)
>> +
>> +
>> **         #logger.debug("%s: stamping: %s %s to %s", debugName 
>> (self), operation, mixinKind, debugName(item))
>>          #logger.debug("%s: done stamping: %s %s to %s", debugName 
>> (self), operation, mixinKind, debugName(item))
>>
>> **@@ -1185,8 +1207,16 @@
>> **             # claims to parse bogus  values like  
>> "06/05/0506/05/05"
>>              #successfully, which causes fromtimestamp() to throw.)
>>              try:
>> **-                dateTimeValue = pim.shortDateFormat.parse 
>> (newValueString,
>> -                                                           
>> referenceDate=oldValue)
>> **+                # use parsedatetime to calculate the date
>> +                cal = parsedatetime.Calendar(ptc.Constants(str 
>> (getLocaleSet()[0])))
>> +                (dateVar, invalidFlag) = cal.parse(newValueString)
>> +                #invalidFlag = 0 implies no date/time
>> +                #invalidFlag = 2 implies only time, no date
>> +                if invalidFlag != 0 and invalidFlag != 2:
>> +                    dateTimeValue = datetime(*dateVar[:3])
>> +                else:
>> +                    self._changeTextQuietly(self.control, "%s ?"  
>> % newValueString)
>> +                    return
>> **             except (ICUError, ValueError):
>>                  self._changeTextQuietly(self.control, "%s ?" %  
>> newValueString)
>>                  return
>> **@@ -1323,8 +1353,9 @@
>> **                     # use parsedatetime to calculate time
>>                      cal = parsedatetime.Calendar()
>>                      (timeVar, invalidFlag) = cal.parse(valueString)
>> **-
>> -                    if timeVar != None and invalidFlag is False:
>> **+                    #invalidFlag = 0 implies no date/time
>> +                    #invalidFlag = 1 implies only date, no time
>> +                    if invalidFlag != 0 and invalidFlag != 1:
>> **                         newValueString =  
>> pim.shortTimeFormat.format(datetime(*timeVar[:5]))
>>                          gotTime = pim.shortTimeFormat.parse 
>> (newValueString,
>>                                                            
>> referenceDate=oldValue)
>> *
>>
>> * *
>>
>>
>>         *Modified:
>>         branches/0.7alpha4/chandler/parcels/osaf/views/main/ 
>> Dashboard.py
>>         (12206 => 12207)*
>>
>> *--- branches/0.7alpha4/chandler/parcels/osaf/views/main/ 
>> Dashboard.py	2006-11-02 02:32:00 UTC (rev 12206)
>> +++ branches/0.7alpha4/chandler/parcels/osaf/views/main/ 
>> Dashboard.py	2006-11-02 17:34:07 UTC (rev 12207)
>> **@@ -195,3 +195,13 @@
>> **     def onEnableSectionsPref(self, op, item, names):
>>          if 'showSections' in names:
>>              self.synchronizeWidget()
>> **+
>> +    def onTriageEvent(self, event):
>> +        for key in self.contents.iterkeys():
>> +            triageStatus = self.itsView.findValue(key,
>> +                                                  
>> '_unpurgedTriageStatus',
>> +                                                  default=None)
>> +            if triageStatus is not None:
>> +                item = self.itsView[key]
>> +                item.triageStatus = triageStatus
>> +
>> *
>>
>> * *
>>
>>
>>         *Modified:
>>         branches/0.7alpha4/chandler/parcels/osaf/views/main/events.py
>>         (12206 => 12207)*
>>
>> *--- branches/0.7alpha4/chandler/parcels/osaf/views/main/events.py	 
>> 2006-11-02 02:32:00 UTC (rev 12206)
>> +++ branches/0.7alpha4/chandler/parcels/osaf/views/main/events.py	 
>> 2006-11-02 17:34:07 UTC (rev 12207)
>> **@@ -227,6 +227,12 @@
>> **         dispatchEnum = 'SendToBlockByName',
>>          dispatchToBlockName = 'MainView').install(parcel)
>>
>> **+    BlockEvent.template(
>> +        'Triage',
>> +        commitAfterDispatch = True,
>> +        dispatchEnum = 'SendToBlockByName',
>> +        dispatchToBlockName = 'TableSummaryView').install(parcel)
>> +
>> **     ClassParameterizedEvent.template(
>>          'ApplicationBarAll',
>>          methodName = 'onClassParameterizedEvent',
>> *
>>
>> * *
>>
>>
>>         *Modified:
>>         branches/0.7alpha4/chandler/parcels/osaf/views/main/ 
>> mainblocks.py
>>         (12206 => 12207)*
>>
>> *--- branches/0.7alpha4/chandler/parcels/osaf/views/main/ 
>> mainblocks.py	2006-11-02 02:32:00 UTC (rev 12206)
>> +++ branches/0.7alpha4/chandler/parcels/osaf/views/main/ 
>> mainblocks.py	2006-11-02 17:34:07 UTC (rev 12207)
>> **@@ -163,6 +163,13 @@
>> **                 helpString = _(u'Send the selected Item')),
>>              ToolbarItem.template('ApplicationSeparator2',
>>                  toolbarItemKind = 'Separator'),
>> **+            ToolbarItem.template('TriageButton',
>> +                event = main.Triage,
>> +                title = _(u"Triage"),
>> +                bitmap = 'ApplicationBarTriage.png',
>> +                toolbarItemKind = 'Button'),
>> +            ToolbarItem.template('ApplicationSeparator3',
>> +                toolbarItemKind = 'Separator'),
>> **             ToolbarItem.template('ApplicationBarSearchField',
>>                  event = main.Search,
>>                  title = u'',
>> *
>>
>> * *
>>
>>
>>         *Modified: branches/0.7alpha4/chandler/repository/item/ 
>> Item.py
>>         (12206 => 12207)*
>>
>> *--- branches/0.7alpha4/chandler/repository/item/Item.py	 
>> 2006-11-02 02:32:00 UTC (rev 12206)
>> +++ branches/0.7alpha4/chandler/repository/item/Item.py	2006-11-02  
>> 17:34:07 UTC (rev 12207)
>> **@@ -115,9 +115,9 @@
>> **             try:
>>                  self._status |= Item.SYSMONONLY
>>                  for name in self._values.keys():
>> **-                    self._fireChanges('set', name, name in values)
>> **+                    self._fireChanges('init', name, name in  
>> values)
>> **                 for name in self._references.keys():
>> **-                    self._fireChanges('set', name, name in values)
>> **+                    self._fireChanges('init', name, name in  
>> values)
>> **             finally:
>>                  self._status &= ~Item.SYSMONONLY
>>
>> *
>>
>> * *
>>
>>
>>         *Modified:
>>         branches/0.7alpha4/chandler/repository/item/Monitors.py  
>> (12206
>>         => 12207)*
>>
>> *--- branches/0.7alpha4/chandler/repository/item/Monitors.py	 
>> 2006-11-02 02:32:00 UTC (rev 12206)
>> +++ branches/0.7alpha4/chandler/repository/item/Monitors.py	 
>> 2006-11-02 17:34:07 UTC (rev 12207)
>> **@@ -57,7 +57,7 @@
>> **     def cacheMonitors(self):
>>
>>          view = self.itsView
>> **-        view._monitors = { 'set': {}, 'remove': {} }
>> **+        view._monitors = { 'init': {}, 'set': {}, 'remove': {} }
>> **         self.itsView.MONITORING = True
>>
>>          for monitor in getattr(self, 'monitors', []):
>> *
>>
>> * *
>>
>>
>>         *Modified: branches/0.7alpha4/chandler/repository/item/ 
>> Sets.py
>>         (12206 => 12207)*
>>
>> *--- branches/0.7alpha4/chandler/repository/item/Sets.py	 
>> 2006-11-02 02:32:00 UTC (rev 12206)
>> +++ branches/0.7alpha4/chandler/repository/item/Sets.py	2006-11-02  
>> 17:34:07 UTC (rev 12207)
>> **@@ -1336,15 +1336,23 @@
>> **                 attrs = self.attributes
>>                  if oldItem is not None:
>>                      if attrs:
>> **-                        for name, op in attrs:
>> **+                        def detach(op, name):
>> **                             Monitors.detach(oldItem,  
>> '_filteredItemChanged',
>>                                              op, name, oldAttribute)
>> **+                        for name in attrs:
>> +                            detach('init', name)
>> +                            detach('set', name)
>> +                            detach('remove', name)
>> **                 if item is not None:
>>                      if attrs:
>> **-                        for name, op in attrs:
>> **+                        def attach(op, name):
>> **                             mon = Monitors.attach(item,  
>> '_filteredItemChanged',
>>                                                    op, name,  
>> attribute)
>>                              mon._status |= CItem.SYSMONITOR
>> **+                        for name in attrs:
>> +                            attach('init', name)
>> +                            attach('set', name)
>> +                            attach('remove', name)
>> **
>>          return oldItem, oldAttribute
>>
>> *
>>
>> * *
>>
>>
>>         *Modified: branches/0.7alpha4/chandler/repository/item/ 
>> Values.py
>>         (12206 => 12207)*
>>
>> *--- branches/0.7alpha4/chandler/repository/item/Values.py	 
>> 2006-11-02 02:32:00 UTC (rev 12206)
>> +++ branches/0.7alpha4/chandler/repository/item/Values.py	 
>> 2006-11-02 17:34:07 UTC (rev 12207)
>> **@@ -1145,18 +1145,18 @@
>> **                             if card == 'dict':
>>                                  for key, vc in  
>> valueChanges.iteritems():
>>                                      refList = value._refList(key)
>> **-                                    refList._applyChanges(vc, ())
>> **+                                    refList._applyChanges(vc,  
>> (), ask)
>> **                             else:
>> **-                                value._applyChanges 
>> (valueChanges, ())
>> **+                                value._applyChanges 
>> (valueChanges, (), ask)
>> **                         else:
>>                              if card == 'dict':
>>                                  for key, vc in  
>> valueChanges.iteritems():
>>                                      c = changes[flag][name].get 
>> (key, ())
>>                                      refList = value._refList(key)
>> **-                                    refList._applyChanges(vc, c)
>> **+                                    refList._applyChanges(vc,  
>> c, ask)
>> **                             else:
>>                                  value._applyChanges(valueChanges,
>> **-                                                    changes 
>> [flag][name])
>> **+                                                    changes 
>> [flag][name], ask)
>> **                         self._setDirty(name)
>>
>>                  elif card == 'dict':
>> **@@ -1166,12 +1166,12 @@
>> **                         self[name] = value = RefDict(item,  
>> name, otherName)
>>                      for key, vc in valueChanges.iteritems():
>>                          refList = value._refList(key)
>> **-                        refList._applyChanges(vc, ())
>> **+                        refList._applyChanges(vc, (), ask)
>> **                     self._setDirty(name)
>>                  else:
>>                      if value is Nil:
>>                          self[name] = value = item._refList(name)
>> **-                    value._applyChanges(valueChanges, ())
>> **+                    value._applyChanges(valueChanges, (), ask)
>> **                     self._setDirty(name)
>>
>>          elif flag == CItem.VDIRTY:
>> *
>>
>> * *
>>
>>
>>         *Modified:
>>         branches/0.7alpha4/chandler/repository/persistence/ 
>> DBContainer.py
>>         (12206 => 12207)*
>>
>> *--- branches/0.7alpha4/chandler/repository/persistence/ 
>> DBContainer.py	2006-11-02 02:32:00 UTC (rev 12206)
>> +++ branches/0.7alpha4/chandler/repository/persistence/ 
>> DBContainer.py	2006-11-02 17:34:07 UTC (rev 12207)
>> **@@ -423,6 +423,7 @@
>> **
>>              def __init__(_self):
>>
>> **+                _self.cursor = None
>> **                 _self.txnStatus = store.startTransaction(view)
>>                  _self.cursor = self.openCursor()
>>
>> **@@ -956,6 +957,7 @@
>> **
>>              def __init__(_self):
>>
>> **+                _self.cursor = None
>> **                 _self.txnStatus = store.startTransaction(view)
>>                  _self.cursor = self.openCursor()
>>
>> *
>>
>> * *
>>
>>
>>         *Modified:
>>         branches/0.7alpha4/chandler/repository/persistence/DBRefs.py
>>         (12206 => 12207)*
>>
>> *--- branches/0.7alpha4/chandler/repository/persistence/DBRefs.py	 
>> 2006-11-02 02:32:00 UTC (rev 12206)
>> +++ branches/0.7alpha4/chandler/repository/persistence/DBRefs.py	 
>> 2006-11-02 17:34:07 UTC (rev 12207)
>> **@@ -243,7 +243,7 @@
>> **
>>          self._changedRefs = Nil
>>
>> **-    def _applyChanges(self, changes, history):
>> **+    def _applyChanges(self, changes, history, ask):
>> **
>>          moves = {}
>>          done = set()
>> **@@ -275,8 +275,18 @@
>> **                 else:
>>                      if alias is not None:
>>                          resolvedKey = self.resolveAlias(alias)
>> **-                        if resolvedKey not in (None, key):
>> -                            self.view._e_2_name(self,  
>> resolvedKey, key, alias)
>> **+                        while resolvedKey not in (None, key):
>> +                            if ask is not None:
>> +                                newAlias = ask(MergeError.ALIAS,  
>> self._name,
>> +                                               (key, resolvedKey,  
>> alias))
>> +                            else:
>> +                                newAlias = alias
>> +                            if newAlias == alias:
>> +                                self.view._e_2_name(self,  
>> resolvedKey,
>> +                                                    key, alias)
>> +                            else:
>> +                                alias = newAlias
>> +                                resolvedKey = self.resolveAlias 
>> (alias)
>> **
>>                      if key in self:
>>                          link = self._get(key)
>> *
>>
>> * *
>>
>>
>>         *Modified:
>>         branches/0.7alpha4/chandler/repository/persistence/ 
>> DBRepositoryView.py
>>         (12206 => 12207)*
>>
>> *--- branches/0.7alpha4/chandler/repository/persistence/ 
>> DBRepositoryView.py	2006-11-02 02:32:00 UTC (rev 12206)
>> +++ branches/0.7alpha4/chandler/repository/persistence/ 
>> DBRepositoryView.py	2006-11-02 17:34:07 UTC (rev 12207)
>> **@@ -882,10 +882,10 @@
>> **             if changes is None:
>>                  if item._children is None:
>>                      item._children = self._createChildren(item,  
>> True)
>> **-                item._children._applyChanges(newChanges 
>> [CDIRTY], ())
>> **+                item._children._applyChanges(newChanges 
>> [CDIRTY], (), None)
>> **             else:
>>                  item._children._applyChanges(newChanges[CDIRTY],
>> **-                                             changes[CDIRTY])
>> **+                                             changes[CDIRTY],  
>> None)
>> **             dirty &= ~CDIRTY
>>              newDirty &= ~CDIRTY
>>              item._status |= (CItem.CMERGED | CDIRTY)
>> *
>>
>> * *
>>
>>
>>         *Modified:
>>         branches/0.7alpha4/chandler/repository/persistence/ 
>> RepositoryError.py
>>         (12206 => 12207)*
>>
>> *--- branches/0.7alpha4/chandler/repository/persistence/ 
>> RepositoryError.py	2006-11-02 02:32:00 UTC (rev 12206)
>> +++ branches/0.7alpha4/chandler/repository/persistence/ 
>> RepositoryError.py	2006-11-02 17:34:07 UTC (rev 12207)
>> **@@ -104,6 +104,7 @@
>> **     KIND   = 6
>>      CHANGE = 7
>>      DELETE = 8
>> **+    ALIAS  = 9
>> **
>>      codeNames = { BUG: 'BUG',
>>                    RENAME: 'RENAME',
>> **@@ -113,7 +114,8 @@
>> **                   REF: 'REF',
>>                    KIND: 'KIND',
>>                    CHANGE: 'CHANGE',
>> **-                  DELETE: 'DELETE' }
>> **+                  DELETE: 'DELETE',
>> +                  ALIAS: 'ALIAS' }
>> **
>>
>>  class LoadError(RepositoryError):
>> *
>>
>> * *
>>
>>
>>         *Modified:
>>         branches/0.7alpha4/chandler/repository/persistence/ 
>> RepositoryView.py
>>         (12206 => 12207)*
>>
>> *--- branches/0.7alpha4/chandler/repository/persistence/ 
>> RepositoryView.py	2006-11-02 02:32:00 UTC (rev 12206)
>> +++ branches/0.7alpha4/chandler/repository/persistence/ 
>> RepositoryView.py	2006-11-02 17:34:07 UTC (rev 12207)
>> **@@ -65,8 +65,9 @@
>> **     # 0.6.11: removed Kind inheritedSuperKinds transient cache
>>      # 0.6.12: removed 'persisted' aspect
>>      # 0.6.13: added IndexMonitor class
>> **+    # 0.6.14: added support for 'init' monitor op
>> **
>> **-    CORE_SCHEMA_VERSION = 0x00060d00
>> **+    CORE_SCHEMA_VERSION = 0x00060e00
>> **
>>      def __init__(self, repository, name, version,  
>> deferDelete=Default):
>>          """
>> *
>>
>> * *
>>
>>
>>         *Modified: branches/0.7alpha4/chandler/repository/schema/ 
>> Kind.py
>>         (12206 => 12207)*
>>
>> *--- branches/0.7alpha4/chandler/repository/schema/Kind.py	 
>> 2006-11-02 02:32:00 UTC (rev 12206)
>> +++ branches/0.7alpha4/chandler/repository/schema/Kind.py	 
>> 2006-11-02 17:34:07 UTC (rev 12207)
>> **@@ -500,7 +500,12 @@
>> **                     if name not in allAttributes:
>>                          allAttributes[name] = (attribute.itsUUID,  
>> kind.itsUUID,
>>                                                 False, False)
>> **-                        allNames[_hash(name)] = name
>> **+                        h = _hash(name)
>> +
>> +                        if h in allNames:
>> +                            if allNames[h] != name:
>> +                                raise AssertionError, ('clash',  
>> allNames[h], name)
>> +                        allNames[h] = name
>> **                         if attribute.getAspect('notify', False):
>>                              notifyAttributes.add(name)
>>
>> *
>>
>> * *
>>
>>
>>         *Modified:
>>         branches/0.7alpha4/chandler/repository/schema/Types.py  
>> (12206 =>
>>         12207)*
>>
>> *--- branches/0.7alpha4/chandler/repository/schema/Types.py	 
>> 2006-11-02 02:32:00 UTC (rev 12206)
>> +++ branches/0.7alpha4/chandler/repository/schema/Types.py	 
>> 2006-11-02 17:34:07 UTC (rev 12207)
>> **@@ -960,7 +960,7 @@
>> **     def _fillItem(self, *args):
>>          super(ConstantEnumeration, self)._fillItem(*args)
>>          if 'values' in self._values:
>> **-            self._afterValuesChange('set', 'values')
>> **+            self._afterValuesChange('init', 'values')
>> **
>>      def getImplementationType(self):
>>          return EnumValue
>> **@@ -1000,7 +1000,7 @@
>> **
>>      def _afterValuesChange(self, op, name):
>>
>> **-        if op == 'set':
>> **+        if op in ('init', 'set'):
>> **             constants = [SchemaEnumValue(self, name, value)
>>                           for name, value in self._values['values']]
>>              constants.sort(None, lambda x: x.name)
>> *
>>
>> * *
>>
>>
>>         *Modified: branches/0.7alpha4/chandler/tools/ 
>> QAUITestAppLib.py
>>         (12206 => 12207)*
>>
>> *--- branches/0.7alpha4/chandler/tools/QAUITestAppLib.py	 
>> 2006-11-02 02:32:00 UTC (rev 12206)
>> +++ branches/0.7alpha4/chandler/tools/QAUITestAppLib.py	2006-11-02  
>> 17:34:07 UTC (rev 12207)
>> **@@ -61,17 +61,17 @@
>> **     ap.Open() # first, open the accounts dialog window
>>      ap.CreateAccount("WebDAV")
>>      ap.TypeValue("displayName", uw("Publish Test WebDAV"))
>> **-    ap.TypeValue("host", "qacosmo.osafoundation.org")
>> **+    ap.TypeValue("host", "osaf.us")
>> **     ap.TypeValue("path", "cosmo/home/demo1")
>>      ap.TypeValue("username", "demo1")
>>      ap.TypeValue("password", "ad3leib5")
>> **-    ap.TypeValue("port", "8080")
>> -    ap.ToggleValue("ssl", False)
>> **+    ap.TypeValue("port", "443")
>> +    ap.ToggleValue("ssl", True)
>> **     ap.ToggleValue("default", True)
>>      ap.Ok()
>>
>>      # verification
>> **-    ap.VerifyValues("WebDAV", uw("Publish Test WebDAV"),  
>> displayName = uw("Publish Test WebDAV"), host =  
>> "qacosmo.osafoundation.org", username = "demo1",  
>> password="ad3leib5", port=8080)
>> **+    ap.VerifyValues("WebDAV", uw("Publish Test WebDAV"),  
>> displayName = uw("Publish Test WebDAV"), host = "osaf.us",  
>> username = "demo1", password="ad3leib5", port=443)
>> **
>>      # import events so test will have something to share even  
>> when run by itself
>>      path = os.path.join(os.getenv('CHANDLERHOME'),"tools/ 
>> QATestScripts/DataFiles")
>> *
>>
>> * *
>>
>>
>>         *Modified:
>>         branches/0.7alpha4/chandler/tools/cats/Functional/ 
>> TestCreateAccounts.py
>>         (12206 => 12207)*
>>
>> *--- branches/0.7alpha4/chandler/tools/cats/Functional/ 
>> TestCreateAccounts.py	2006-11-02 02:32:00 UTC (rev 12206)
>> +++ branches/0.7alpha4/chandler/tools/cats/Functional/ 
>> TestCreateAccounts.py	2006-11-02 17:34:07 UTC (rev 12207)
>> **@@ -68,12 +68,12 @@
>> **
>>          ap.CreateAccount("WebDAV")
>>          ap.TypeValue("displayName", pWEBDAV)
>> **-        ap.TypeValue("host", "qacosmo.osafoundation.org")
>> -        ap.TypeValue("path", "home/demo1")
>> **+        ap.TypeValue("host", "osaf.us")
>> +        ap.TypeValue("path", "cosmo/home/demo1")
>> **         ap.TypeValue("username", "demo1")
>>          ap.TypeValue("password", "ad3leib5")
>> **-        ap.TypeValue("port", "8080")
>> -        ap.ToggleValue("ssl", False)
>> **+        ap.TypeValue("port", "443")
>> +        ap.ToggleValue("ssl", True)
>> **         ap.ToggleValue("default", True)
>>
>>          ap.Ok()
>> **@@ -83,6 +83,6 @@
>> **         ap.VerifyValues("SMTP", pSMTP, host=  
>> "smtp.osafoundation.org", connectionSecurity = "TLS", useAuth =  
>> True, port = 587, username = 'demo1', password = 'ad3leib5' )
>>          ap.VerifyValues("IMAP", pIMAP, host =  
>> "imap.osafoundation.org", connectionSecurity = "SSL", username =  
>> "demo1", password = "ad3leib5")
>>          ap.VerifyValues("POP", pPOP, host =  
>> "pop.osafoundation.org", connectionSecurity = "SSL", username =  
>> "demo1", password = "ad3leib5")
>> **-        ap.VerifyValues("WebDAV", pWEBDAV, host =  
>> "qacosmo.osafoundation.org", username = "demo1",  
>> password="ad3leib5", port=8080)
>> **+        ap.VerifyValues("WebDAV", pWEBDAV, host = "osaf.us",  
>> username = "demo1", password="ad3leib5", port=443)
>> **         self.logger.endAction(True, "Verifying Account Values")
>>
>> *
>>
>> * *
>>
>>
>>         *Modified:
>>         branches/0.7alpha4/chandler/tools/cats/Functional/ 
>> TestEventStacking.py
>>         (12206 => 12207)*
>>
>> *--- branches/0.7alpha4/chandler/tools/cats/Functional/ 
>> TestEventStacking.py	2006-11-02 02:32:00 UTC (rev 12206)
>> +++ branches/0.7alpha4/chandler/tools/cats/Functional/ 
>> TestEventStacking.py	2006-11-02 17:34:07 UTC (rev 12207)
>> **@@ -25,7 +25,7 @@
>> **
>>      def startTest(self):
>>
>> **-        today = strftime('%m/%d/%y',localtime())
>> **+        today = strftime('%m/%d/%Y',localtime())
>> **
>>
>>          view = QAUITestAppLib.UITestView(self.logger)
>> *
>>
>> * *
>>
>>
>>         *Modified:
>>         branches/0.7alpha4/chandler/tools/cats/Functional/ 
>> TestMoveToTrash.py
>>         (12206 => 12207)*
>>
>> *--- branches/0.7alpha4/chandler/tools/cats/Functional/ 
>> TestMoveToTrash.py	2006-11-02 02:32:00 UTC (rev 12206)
>> +++ branches/0.7alpha4/chandler/tools/cats/Functional/ 
>> TestMoveToTrash.py	2006-11-02 17:34:07 UTC (rev 12207)
>> **@@ -32,7 +32,7 @@
>> **         note.Check_ItemInCollection("Trash")
>>          note.Check_ItemInCollection("Dashboard",  
>> expectedResult=False)
>>
>> **-        today = strftime('%m/%d/%y',localtime())
>> **+        today = strftime('%m/%d/%Y',localtime())
>> **
>>          view = QAUITestAppLib.UITestView(self.logger)
>>          view.SwitchToCalView()
>> *
>>
>> * *
>>
>>
>>         *Modified:
>>         branches/0.7alpha4/chandler/tools/cats/Functional/ 
>> TestNewEvent.py
>>         (12206 => 12207)*
>>
>> *--- branches/0.7alpha4/chandler/tools/cats/Functional/ 
>> TestNewEvent.py	2006-11-02 02:32:00 UTC (rev 12206)
>> +++ branches/0.7alpha4/chandler/tools/cats/Functional/ 
>> TestNewEvent.py	2006-11-02 17:34:07 UTC (rev 12207)
>> **@@ -34,7 +34,7 @@
>> **             monday = today - datetime.timedelta 
>> (days=daysUntilMonday)
>>              incDay =  monday + datetime.timedelta(days=inc)
>>              y, m, d = incDay.timetuple()[:3]
>> **-            return '%s/%s/%s' % (m, d, str(y)[2:].zfill(2))
>> **+            return '%s/%s/%s' % (m, d, y)
>> **
>>          # make user collection, since only user
>>          # collections can be displayed as a calendar
>> *
>>
>> * *
>>
>>
>>         *Modified:
>>         branches/0.7alpha4/chandler/tools/cats/Functional/ 
>> TestRecurringEvent.py
>>         (12206 => 12207)*
>>
>> *--- branches/0.7alpha4/chandler/tools/cats/Functional/ 
>> TestRecurringEvent.py	2006-11-02 02:32:00 UTC (rev 12206)
>> +++ branches/0.7alpha4/chandler/tools/cats/Functional/ 
>> TestRecurringEvent.py	2006-11-02 17:34:07 UTC (rev 12207)
>> **@@ -39,8 +39,8 @@
>> **
>>          # verification
>>          dailyEvent.Check_DetailView({"displayName":uw("Daily  
>> Exercise"),
>> **-                                     "startDate":"1/1/06",
>> -                                     "endDate":"1/1/06",
>> **+                                     "startDate":"1/1/2006",
>> +                                     "endDate":"1/1/2006",
>> **                                      "startTime":"6:00 AM",
>>                                       "endTime":"7:00 AM",
>>                                       "location":uw("Gym"),
>> **@@ -48,7 +48,7 @@
>> **                                      "body":uw("Resolution:  
>> exercise daily for optimal health"),
>>                                       "timeZone":"US/Central",
>>                                       "recurrence":"Daily",
>> **-                                     "recurrenceEnd":"3/1/06"})
>> **+                                     "recurrenceEnd":"3/1/2006"})
>> **
>>          dailyEvent.Check_Object({"displayName":uw("Daily Exercise"),
>>                                   "startDate":"1/1/2006",
>> **@@ -79,8 +79,8 @@
>> **         # verification
>>
>>          weeklyEvent.Check_DetailView({"displayName":uw("Weekly  
>> call home"),
>> **-                                      "startDate":"1/7/06",
>> -                                      "endDate":"1/7/06",
>> **+                                      "startDate":"1/7/2006",
>> +                                      "endDate":"1/7/2006",
>> **                                       "startTime":"5:00 PM",
>>                                        "endTime":"6:00 PM",
>>                                        "location":uw("Phone"),
>> **@@ -88,7 +88,7 @@
>> **                                       "body":uw("Resolution:  
>> call home weekly for good family relations"),
>>                                        "timeZone":"US/Central",
>>                                        "recurrence":"Weekly",
>> **-                                      "recurrenceEnd":"3/25/06"})
>> **+                                       
>> "recurrenceEnd":"3/25/2006"})
>> **
>>          weeklyEvent.Check_Object({"displayName":uw("Weekly call  
>> home"),
>>                                    "startDate":"1/7/2006",
>> **@@ -120,8 +120,8 @@
>> **         # verification
>>
>>          monthlyEvent.Check_DetailView({"displayName":uw("Monthly  
>> book club"),
>> **-                                     "startDate":"1/1/06",
>> -                                      "endDate":"1/1/06",
>> **+                                     "startDate":"1/1/2006",
>> +                                      "endDate":"1/1/2006",
>> **                                       "startTime":"7:00 PM",
>>                                        "endTime":"9:00 PM",
>>                                        "location":uw("My house"),
>> **@@ -129,7 +129,7 @@
>> **                                       "body":uw("Resolution:  
>> host book club once a month"),
>>                                        "timeZone":"US/Central",
>>                                        "recurrence":"Monthly",
>> **-                                      "recurrenceEnd":"12/31/06"})
>> **+                                       
>> "recurrenceEnd":"12/31/2006"})
>> **
>>          monthlyEvent.Check_Object({"displayName":uw("Monthly book  
>> club"),
>>                                    "startDate":"1/1/2006",
>> **@@ -160,8 +160,8 @@
>> **         # verification
>>
>>          yearlyEvent.Check_DetailView({"displayName":uw("Yearly  
>> dentist appointment"),
>> **-                                      "startDate":"2/6/06",
>> -                                      "endDate":"2/6/06",
>> **+                                      "startDate":"2/6/2006",
>> +                                      "endDate":"2/6/2006",
>> **                                       "startTime":"10:00 AM",
>>                                        "endTime":"11:00 AM",
>>                                        "location":uw("Downtown"),
>> **@@ -169,7 +169,7 @@
>> **                                       "body":uw("Resolution:  
>> get teeth cleaned once a year"),
>>                                        "timeZone":"US/Pacific",
>>                                        "recurrence":"Yearly",
>> **-                                      "recurrenceEnd":"2/7/10"})
>> **+                                      "recurrenceEnd":"2/7/2010"})
>> **
>>          yearlyEvent.Check_Object({"displayName":uw("Yearly  
>> dentist appointment"),
>>                                    "startDate":"2/6/2006",
>> *
>>
>> * *
>>
>>
>>         *Modified:
>>         branches/0.7alpha4/chandler/tools/cats/Functional/ 
>> TestReminderProcessing.py
>>         (12206 => 12207)*
>>
>> *--- branches/0.7alpha4/chandler/tools/cats/Functional/ 
>> TestReminderProcessing.py	2006-11-02 02:32:00 UTC (rev 12206)
>> +++ branches/0.7alpha4/chandler/tools/cats/Functional/ 
>> TestReminderProcessing.py	2006-11-02 17:34:07 UTC (rev 12207)
>> **@@ -29,10 +29,14 @@
>> **     stack = traceback.extract_stack(limit=5)[:-2]
>>      return "".join(traceback.format_list(stack))
>>
>> **-# Under normal circumstances, we'll create events to fire very
>> -# shortly, so the tests aren't slowed much by waiting. (at least 2!)
>> **+# Under normal circumstances, we'll create events to fire
>> +# shortly, so the tests aren't slowed much by waiting.
>> +# (Note: this used to be 3 seconds, which failed on slow machines  
>> or when
>> +# indexing or other background processing happened to fire after  
>> we started
>> +# but before we got to the 'waiting' phase of the test)
>> +nearFutureSeconds=15
>> +
>> ** # If I'm debugging, set up events farther in the future
>> **-nearFutureSeconds=3
>> ** #nearFutureSeconds=120
>>
>>  # While we're debugging this test, I set reallyFail to False so  
>> failures will
>> *
>>
>> * *
>>
>>
>>         *Modified:
>>         branches/0.7alpha4/chandler/tools/cats/Functional/ 
>> TestRemoveFromTrashOnImport.py
>>         (12206 => 12207)*
>>
>> *--- branches/0.7alpha4/chandler/tools/cats/Functional/ 
>> TestRemoveFromTrashOnImport.py	2006-11-02 02:32:00 UTC (rev 12206)
>> +++ branches/0.7alpha4/chandler/tools/cats/Functional/ 
>> TestRemoveFromTrashOnImport.py	2006-11-02 17:34:07 UTC (rev 12207)
>> **@@ -30,20 +30,14 @@
>> **     def startTest(self):
>>
>>          appView = self.app_ns.itsView
>> **-        today = strftime('%m/%d/%y',localtime())
>> **+        today = strftime('%m/%d/%Y',localtime())
>> **
>>          colName = "deleteThenImport"
>>          eventName = "eventToTest"
>>
>>          #create a collection
>>          collection = QAUITestAppLib.UITestItem("Collection",  
>> self.logger)
>> **-        # SetDisplayName fails after TestEventStacking occluded  
>> its collection
>> -        # by adding events that appeared in the PreviewArea (bug  
>> 6727).  To work
>> -        # around this, just set collection's displayName directly  
>> for now.
>> -        # This is a brittle hack, the failure is order- 
>> dependent.  We need a
>> -        # more robust solution to the sidebar SetDisplayName  
>> failures.
>> -        #collection.SetDisplayName(colName)
>> -        collection.item.displayName = colName
>> **+        collection.SetDisplayName(colName)
>> **         sb=self.app_ns.sidebar
>>          scripting.User.emulate_sidebarClick(sb,colName)
>>
>> *
>>
>> * *
>>
>>
>>         *Modified:
>>         branches/0.7alpha4/chandler/tools/cats/framework/ 
>> ChandlerTestLib.py
>>         (12206 => 12207)*
>>
>> *--- branches/0.7alpha4/chandler/tools/cats/framework/ 
>> ChandlerTestLib.py	2006-11-02 02:32:00 UTC (rev 12206)
>> +++ branches/0.7alpha4/chandler/tools/cats/framework/ 
>> ChandlerTestLib.py	2006-11-02 17:34:07 UTC (rev 12207)
>> **@@ -68,17 +68,17 @@
>> **     ap.Open() # first, open the accounts dialog window
>>      ap.CreateAccount("WebDAV")
>>      ap.TypeValue("displayName", uw("Publish Test WebDAV"))
>> **-    ap.TypeValue("host", "qacosmo.osafoundation.org")
>> **+    ap.TypeValue("host", "osaf.us")
>> **     ap.TypeValue("path", "cosmo/home/demo1")
>>      ap.TypeValue("username", "demo1")
>>      ap.TypeValue("password", "ad3leib5")
>> **-    ap.TypeValue("port", "8080")
>> -    ap.ToggleValue("ssl", False)
>> **+    ap.TypeValue("port", "443")
>> +    ap.ToggleValue("ssl", True)
>> **     ap.ToggleValue("default", True)
>>      ap.Ok()
>>
>>      # verification
>> **-    ap.VerifyValues("WebDAV", uw("Publish Test WebDAV"), host =  
>> "qacosmo.osafoundation.org", username = "demo1",  
>> password="ad3leib5", port=8080)
>> **+    ap.VerifyValues("WebDAV", uw("Publish Test WebDAV"), host =  
>> "osaf.us", username = "demo1", password="ad3leib5", port=443)
>> **
>>      # import events so test will have something to share even  
>> when run by itself
>>      path = os.path.join(os.getenv('CHANDLERHOME'),"tools/ 
>> QATestScripts/DataFiles")
>> **@@ -1021,14 +1021,10 @@
>> **             self.logger.report(True, name="CheckMenuBlock",  
>> comment="(On %s Checking)" % description)
>>
>>      def formatDate(self, dateStr):
>> **-        """if year has 4 digits removes first 2
>> -             also removes leading zeros from month/ day
>> -             to resolve bug 5031"""
>> **+        """Removes leading zeros from month/ day to resolve bug  
>> 5031"""
>> **         month, day, year = dateStr.split('/')
>>          month = str(int(month)) # get rid of leading zeros
>>          day = str(int(day))
>> **-        if len(year) == 4:
>> -            year = year[2:]
>> **         return  '%s/%s/%s' % (month, day, year)
>>
>>
>> *
>>
>> * *
>>
>>
>>         *Modified:
>>         branches/0.7alpha4/chandler/tools/cats/framework/ 
>> TestOutput.py
>>         (12206 => 12207)*
>>
>> *--- branches/0.7alpha4/chandler/tools/cats/framework/ 
>> TestOutput.py	2006-11-02 02:32:00 UTC (rev 12206)
>> +++ branches/0.7alpha4/chandler/tools/cats/framework/TestOutput.py	 
>> 2006-11-02 17:34:07 UTC (rev 12207)
>> **@@ -31,7 +31,7 @@
>> **     """Class for overriding datetime's normal string method"""
>>      def __str__(self):
>>          """Method to return more parsable datetime string"""
>> **-        return '%s:%s:%s:%s' % (self.hour, self.minute,  
>> self.second, self.microsecond)
>> **+        return '%s:%s:%0.2f' % (self.hour, self.minute,  
>> self.second +( 0.000001 * self.microsecond))
>> **
>>  class TestOutput:
>>      """
>> **@@ -69,6 +69,8 @@
>> **         self.inSuite = False
>>          self.hadStderrOutput = False
>>          self.stderrOutput = ''
>> **+        self.testHasFailed = False
>> +        self.testsSkipped = None
>> **         #print 'logName = %s:: debug level = %d :: mask level =  
>> %d ::  stdout = %s' % (logName, debug, mask, stdout)
>>
>>          if stdout is True:
>> **@@ -123,7 +125,7 @@
>> **
>>          self.currentSuite['endtime'] = datetime.now()
>>          self.currentSuite['totaltime'] = self.currentSuite 
>> ['endtime'] - self.currentSuite['starttime']
>> **-        self.printOut(u'Ending Suite ""%s"" :: EndTime %s ::  
>> Total Time %s' % (self.currentSuite['name'], self.currentSuite 
>> ['endtime'], self.currentSuite['totaltime']), level=3)
>> **+        self.printOut(u'Ending Suite ""%s"" :: EndTime %s ::  
>> Total Time %0.2f seconds' % (self.currentSuite['name'],  
>> self.currentSuite['endtime'], self._inSeconds(self.currentSuite 
>> ['totaltime'])), level=3)
>> **         self.currentSuite['testlist'] = copy.copy(self.testList)
>>          self.suiteList.append(copy.copy(self.currentSuite))
>>          self.inSuite = False
>> **@@ -151,7 +153,7 @@
>> **         self.currentTest['endtime'] = datetime.now()
>>          self.currentTest['totaltime'] = self.currentTest 
>> ['endtime'] - self.currentTest['starttime']
>>          self.currentTest['comment'] = '%s\n%s' % (self.currentTest 
>> ['comment'], comment)
>> **-        self.printOut(u'Ending Test ""%s"" :: EndTime %s ::  
>> Total Time %s' % (self.currentTest['name'], self.currentTest 
>> ['endtime'], self.currentTest['totaltime']), level=2)
>> **+        self.printOut(u'Ending Test ""%s"" :: EndTime %s ::  
>> Total Time %0.2f seconds' % (self.currentTest['name'],  
>> self.currentTest['endtime'], self._inSeconds(self.currentTest 
>> ['totaltime'])), level=2)
>> **         self.currentTest['actionlist'] = copy.copy 
>> (self.actionList)
>>          self.testList.append(copy.copy(self.currentTest))
>>          self.inTest = False
>> **@@ -253,6 +255,7 @@
>> **             self.printOut(u'Success in action.%s.report:: %s' %  
>> (self.currentAction['name'], comment), level=0, result=True)
>>          else:
>>              self.printOut(u'Failure in action.%s.report :: %s' %  
>> (self.currentAction['name'], comment), level=0, result=False)
>> **+            self.testHasFailed = True
>> **
>>      def write(self, string):
>>          """Method to allow TestOutput to be used like a file object.
>> **@@ -414,8 +417,8 @@
>> **                     for report in action['reportlist']:
>>                          reports_ran = reports_ran + 1
>>
>> **-        self._write('$Suites run=%s, pass=%s, fail=%s :: Tests  
>> run=%s, pass=%s, fail=%s :: Actions run=%s, pass=%s, fail=%s ::  
>> Reports run=%s, pass=%s, fail=%s \n' %
>> -                    (suites_ran, suites_ran - suites_failed,  
>> suites_failed, tests_ran, tests_ran - tests_failed, tests_failed,  
>> actions_ran,
>> **+        self._write('$Suites run=%s, pass=%s, fail=%s :: Tests  
>> run=%s, pass=%s, fail=%s :: Tests skipped=%s :: Actions run=%s,  
>> pass=%s, fail=%s :: Reports run=%s, pass=%s, fail=%s \n' %
>> +                    (suites_ran, suites_ran - suites_failed,  
>> suites_failed, tests_ran, tests_ran - tests_failed, tests_failed,  
>> self.testsSkipped, actions_ran,
>> **                      actions_ran - actions_failed,  
>> actions_failed, reports_ran, reports_ran - reports_failed,  
>> reports_failed))
>>
>>      def simpleSummary(self):
>> **@@ -427,13 +430,19 @@
>> **                         self._write('%s*FAILED*\n' % test_dict 
>> ['name'].ljust(30,'_'))
>>                      else:
>>                          self._write('%s passed \n' % test_dict 
>> ['name'].ljust(30,'_'))
>> **+        if self.testsSkipped:
>> +            self._write('** %d tests skipped after failure **\n'  
>> % self.testsSkipped)
>> **         self._write("*************************************\n")
>>
>> **+    def _inSeconds(self, tDelta):
>> +        """return a timedelta object as a float of seconds"""
>> +        return (tDelta.days * 86400) + tDelta.seconds +  
>> (tDelta.microseconds * .000001)
>> +
>> **     def tinderOutput(self):
>>          #write out stuff for tinderbox
>>          for suite_dict in self.suiteList:
>>              self._write('#TINDERBOX# Testname = %s\n' % suite_dict 
>> ['name'])
>> **-            self._write('#TINDERBOX# Time elapsed = %s (seconds) 
>> \n' % suite_dict['totaltime'])
>> **+            self._write('#TINDERBOX# Time elapsed = %0.2f  
>> (seconds)\n' % self._inSeconds(suite_dict['totaltime']))
>> **             if suite_dict['result'] is None:
>>                  self._write('#TINDERBOX# Status = PASSED\n')
>>              else:
>> *
>>
>> * *
>>
>>
>>         *Modified:
>>         branches/0.7alpha4/chandler/tools/cats/framework/runTests.py
>>         (12206 => 12207)*
>>
>> *--- branches/0.7alpha4/chandler/tools/cats/framework/runTests.py	 
>> 2006-11-02 02:32:00 UTC (rev 12206)
>> +++ branches/0.7alpha4/chandler/tools/cats/framework/runTests.py	 
>> 2006-11-02 17:34:07 UTC (rev 12207)
>> **@@ -24,12 +24,14 @@
>> ** from tools.cats.framework.TestOutput import TestOutput
>>  import os, sys
>>  from application import Globals
>> **+import osaf.framework.scripting as scripting
>> **
>> **-functional_dir = os.path.join(os.getenv('CHANDLERHOME'),"tools/ 
>> cats/Functional")
>> **+functional_dir = os.path.join(Globals.chandlerDirectory,"tools/ 
>> cats/Functional")
>> ** testDebug = Globals.options.chandlerTestDebug
>>  testMask = Globals.options.chandlerTestMask
>>  logFileName = Globals.options.chandlerTestLogfile
>>  filePath = Globals.options.profileDir
>> **+haltOnFailure = not Globals.options.continueTestsOnFailure
>> ** if filePath and logFileName:
>>      logFileName = os.path.join(filePath, logFileName)
>>
>> **@@ -71,6 +73,10 @@
>> **     runner = Globals.options.catch != 'never' and  
>> run_test_wrapped or run_test
>>      for paramSet in tests.split(','):
>>          runner(logger, paramSet)
>> **+        if haltOnFailure and logger.testHasFailed:
>> +            logger.report(False, 'Suite halted on test failure')
>> +            logger.testsSkipped = len(tests.split(',')) -  
>> (tests.split(',').index(paramSet) + 1)
>> +            break
>> **
>>      if logger.debug < 2: checkRepo(logger)
>>      logger.endSuite()
>> **@@ -80,7 +86,6 @@
>> **         logger.summary()
>>      logger.simpleSummary()
>>      logger.tinderOutput()
>> **-    import osaf.framework.scripting as scripting
>> **     scripting.app_ns().root.Quit()
>>
>>  def run_perf_tests(tests, debug=testDebug, mask=testMask,  
>> logName=logFileName):
>> *
>>
>> * *
>>
>>
>>         *Modified: branches/0.7alpha4/chandler/tools/do_tests.sh  
>> (12206
>>         => 12207)*
>>
>> *--- branches/0.7alpha4/chandler/tools/do_tests.sh	2006-11-02  
>> 02:32:00 UTC (rev 12206)
>> +++ branches/0.7alpha4/chandler/tools/do_tests.sh	2006-11-02  
>> 17:34:07 UTC (rev 12207)
>> **@@ -14,7 +14,7 @@
>> ** NO_ARGS=0
>>  E_OPTERROR=65
>>
>> **-USAGE="Usage: `basename $0` -fpuN [-m debug|release] [-t  
>> test_name] [chandler-base-path]"
>> **+USAGE="Usage: `basename $0` -fpuF [-m debug|release] [-t  
>> test_name] [chandler-base-path]"
>> **
>>  # Signals to the Chandler code that it is being run from a unit test
>>  export UNIT_TESTING=True
>> **@@ -36,11 +36,13 @@
>> ** fi
>>
>>  hadError=0
>> **+FORCE_CONT=" "
>> **
>> **-while getopts "fput:m:" Option
>> **+while getopts "fput:Fm:" Option
>> ** do
>>    case $Option in
>>      f ) RUN_FUNCTIONAL=yes;;
>> **+    F ) FORCE_CONT="-F";;
>> **     p ) RUN_PERFORMANCE=yes;;
>>      u ) RUN_UNIT=yes;;
>>      t ) TEST_TO_RUN=$OPTARG;;
>> **@@ -53,6 +55,7 @@
>> ** if [ $hadError = 1 ]; then
>>      echo $USAGE
>>      echo "   if CHANDLER_FUNCTIONAL_TEST=yes or -f then CATS  
>> Functional Tests are run"
>> **+    echo "   if -F then forces all tests to run (does not stop  
>> after first failure)"
>> **     echo "   if CHANDLER_PERFORMANCE_TEST=yes or -p then CATS  
>> Performance Tests are run"
>>      echo "   if CHANDLER_UNIT_TEST=yes or -u then Chandler Unit  
>> Tests are run"
>>      echo "if a specific test name or (pattern) is given using -t  
>> then only that test name will be run"
>> **@@ -234,15 +237,14 @@
>> **                     echo Skipping $TESTNAME in $F_TEST_IGNORE
>>                  else
>>                      if echo "$TESTNAME" | grep -q "$F_TEST_DIR" ;  
>> then
>> **-                        $CHANDLERBIN/$mode/$RUN_CHANDLER -- 
>> create --catch=tests --profileDir="$PC_DIR" --parcelPath="$PP_DIR"  
>> --scriptTimeout=600 --chandlerTests="$TEST_WITHOUT_PATH" &> $TESTLOG
>> **+                        $CHANDLERBIN/$mode/$RUN_CHANDLER -D2 - 
>> M0 --create --catch=tests --profileDir="$PC_DIR" -- 
>> parcelPath="$PP_DIR" --scriptTimeout=600 -- 
>> chandlerTests="$TEST_WITHOUT_PATH" 2>&1 | tee $TESTLOG
>> **                         SUCCESS="#TINDERBOX# Status = PASSED"
>>                      else
>> **-                        $CHANDLERBIN/$mode/$RUN_PYTHON  
>> $TESTNAME &> $TESTLOG
>> **+                        $CHANDLERBIN/$mode/$RUN_PYTHON  
>> $TESTNAME 2>&1 | tee $TESTLOG
>> **                         SUCCESS="^OK"
>>                      fi
>>
>>                      echo - - - - - - - - - - - - - - - - - - - -  
>> - - - - - - | tee -a $DOTESTSLOG
>> **-                    cat $TESTLOG | tee -a $DOTESTSLOG
>> **
>>                      RESULT=`grep "$SUCCESS" $TESTLOG`
>>                      if [ "$RESULT" = "" ]; then
>> **@@ -280,6 +282,7 @@
>> **
>>            # walk thru all of the test dirs and find the test files
>>
>> **+        CONTINUE="true"
>> **         for mode in $MODES ; do
>>              echo Running $mode unit tests | tee -a $DOTESTSLOG
>>
>> **@@ -287,26 +290,33 @@
>> **                 TESTS=`find $testdir -name 'Test*.py' -print`
>>
>>                  for test in $TESTS ; do
>> **-                    if [ "$OSTYPE" = "cygwin" ]; then
>> -                        TESTNAME=`cygpath -w $test`
>> -                    else
>> -                        TESTNAME=$test
>> -                    fi
>> **+                	if [ "$CONTINUE" == "true" ]; then
>> +                        if [ "$OSTYPE" = "cygwin" ]; then
>> +                            TESTNAME=`cygpath -w $test`
>> +                        else
>> +                            TESTNAME=$test
>> +                        fi
>> **
>> **-                    echo Running $TESTNAME | tee -a $DOTESTSLOG
>> **+                        echo Running $TESTNAME | tee -a  
>> $DOTESTSLOG
>> **
>> **-                    cd $C_DIR
>> -                    $CHANDLERBIN/$mode/$RUN_PYTHON $TESTNAME &>  
>> $TESTLOG
>> **+                        cd $C_DIR
>> +                        $CHANDLERBIN/$mode/$RUN_PYTHON $TESTNAME  
>> 2>&1 | tee $TESTLOG
>> **
>> **-                      # scan the test output for the success  
>> messge "OK"
>> -                    RESULT=`grep '^OK' $TESTLOG`
>> **+                          # scan the test output for the  
>> success messge "OK"
>> +                        RESULT=`grep '^OK' $TESTLOG`
>> **
>> **-                    echo - - - - - - - - - - - - - - - - - - -  
>> - - - - - - - | tee -a $DOTESTSLOG
>> -                    echo $TESTNAME [$RESULT] | tee -a $DOTESTSLOG
>> -                    cat $TESTLOG      | tee -a $DOTESTSLOG
>> **+                        echo - - - - - - - - - - - - - - - - -  
>> - - - - - - - - - | tee -a $DOTESTSLOG
>> +                        echo $TESTNAME [$RESULT] | tee -a  
>> $DOTESTSLOG
>> **
>> **-                    if [ "$RESULT" = "" ]; then
>> -                        FAILED_TESTS="$FAILED_TESTS ($mode) 
>> $TESTNAME"
>> **+                        if [ "$RESULT" = "" ]; then
>> +                            FAILED_TESTS="$FAILED_TESTS ($mode) 
>> $TESTNAME"
>> +                            if [ "$FORCE_CONT" != "-F" ]; then
>> +                            	RUN_FUNCTIONAL="no"
>> +                                RUN_PERFORMANCE="no"
>> +                                CONTINUE="false"
>> +                                echo Skipping further tests due  
>> to failure | tee -a $DOTESTSLOG
>> +                            fi
>> +                        fi
>> **                     fi
>>                  done
>>              done
>> **@@ -329,17 +339,19 @@
>> **             echo Running $TESTNAME | tee -a $DOTESTSLOG
>>
>>              cd $C_DIR
>> **-            $CHANDLERBIN/$mode/$RUN_CHANDLER --create -- 
>> catch=tests --profileDir="$PC_DIR" --parcelPath="$PP_DIR" -- 
>> scriptTimeout=600 --scriptFile="$TESTNAME" -D1 -M2 &> $TESTLOG
>> **+            $CHANDLERBIN/$mode/$RUN_CHANDLER --create -- 
>> catch=tests $FORCE_CONT --profileDir="$PC_DIR" -- 
>> parcelPath="$PP_DIR" --scriptTimeout=600 --scriptFile="$TESTNAME" - 
>> D1 -M2 2>&1 | tee $TESTLOG
>> **
>>                # scan the test output for the success messge "OK"
>>              RESULT=`grep '#TINDERBOX# Status = PASSED' $TESTLOG`
>>
>>              echo - - - - - - - - - - - - - - - - - - - - - - - -  
>> - - | tee -a $DOTESTSLOG
>>              echo $TESTNAME [$RESULT] | tee -a $DOTESTSLOG
>> **-            cat $TESTLOG      | tee -a $DOTESTSLOG
>> **
>>              if [ "$RESULT" = "" ]; then
>>                  FAILED_TESTS="$FAILED_TESTS ($mode)$TESTNAME"
>> **+                if [ "$FORCE_CONT" != "-F" ]; then
>> +                    RUN_PERFORMANCE="no"
>> +                fi
>> **             fi
>>          done
>>      fi
>> **@@ -484,6 +496,8 @@
>> **                     echo gtime not found, skipping startup tests
>>                      RUN_STARTUP_TESTS=no
>>                  fi
>> **+            else
>> +                TIME='/usr/bin/time --format=%e'
>> **             fi
>>          fi
>>
>> *
>>
>> * *
>>
>>
>>         *Modified: branches/0.7alpha4/chandler/util/task.py (12206 =>
>>         12207)*
>>
>> *--- branches/0.7alpha4/chandler/util/task.py	2006-11-02 02:32:00  
>> UTC (rev 12206)
>> +++ branches/0.7alpha4/chandler/util/task.py	2006-11-02 17:34:07  
>> UTC (rev 12207)
>> **@@ -17,6 +17,7 @@
>> ** from twisted.internet import reactor, defer
>>  import logging
>>  from i18n import ChandlerMessageFactory as _
>> **+from repository.persistence.RepositoryError import MergeError
>> **
>>  logger = logging.getLogger(__name__)
>>
>> **@@ -90,5 +91,13 @@
>> **         self.callInMainThread(self.error, failure, done=True)
>>
>>      def _success(self, result):
>> **-        self.view.commit()
>> **+
>> +        def mergeFunction(code, item, attribute, value):
>> +            if code == MergeError.ALIAS:
>> +                key, currentKey, alias = value
>> +                logger.warning("While merging attribute '%s' on % 
>> s, an alias conflict for key %s was detected: %s is set to the  
>> same alias: '%s'", attribute, item._repr_(), key, currentKey, alias)
>> +                return alias + '_duplicate'
>> +            raise NotImplementedError, (code, attribute, value)
>> +
>> +        self.view.commit(mergeFunction)
>> **         self.callInMainThread(self.success, result, done=True)
>> *
>>
>> * *
>>
>>
>>         *Modified: branches/0.7alpha4/chandler/version.py (12206  
>> => 12207)*
>>
>> *--- branches/0.7alpha4/chandler/version.py	2006-11-02 02:32:00  
>> UTC (rev 12206)
>> +++ branches/0.7alpha4/chandler/version.py	2006-11-02 17:34:07 UTC  
>> (rev 12207)
>> **@@ -7,7 +7,7 @@
>> ** #   version    - "%s%s-r%s%s" % (release, build, revision,  
>> checkpoint)
>>  #
>>
>> **-release = "0.7alpha4"
>> **+release = "0.7alpha5"
>> ** build = ".dev"
>>  checkpoint = ""
>>  revision = ""
>> *
>>
>> *
>> *
>> --------------------------------------------------------------------- 
>> ---
>> *
>> _______________________________________________
>> Commits mailing list
>> Commits at osafoundation.org
>> http://lists.osafoundation.org/mailman/listinfo/commits
>> *



More information about the chandler-dev mailing list