[CalendarServer-changes] [5006] CalendarServer/branches/users/glyph/contacts-server-merge

source_changes at macosforge.org source_changes at macosforge.org
Mon Feb 1 17:25:33 PST 2010


Revision: 5006
          http://trac.macosforge.org/projects/calendarserver/changeset/5006
Author:   glyph at apple.com
Date:     2010-02-01 17:25:32 -0800 (Mon, 01 Feb 2010)
Log Message:
-----------
Merge in changes from trunk

Modified Paths:
--------------
    CalendarServer/branches/users/glyph/contacts-server-merge/calendarserver/provision/root.py
    CalendarServer/branches/users/glyph/contacts-server-merge/calendarserver/provision/test/test_root.py
    CalendarServer/branches/users/glyph/contacts-server-merge/calendarserver/sidecar/task.py
    CalendarServer/branches/users/glyph/contacts-server-merge/calendarserver/tap/caldav.py
    CalendarServer/branches/users/glyph/contacts-server-merge/calendarserver/tools/loadaugmentdb.py
    CalendarServer/branches/users/glyph/contacts-server-merge/calendarserver/tools/manageaugments.py
    CalendarServer/branches/users/glyph/contacts-server-merge/calendarserver/tools/principals.py
    CalendarServer/branches/users/glyph/contacts-server-merge/memcacheclient.py
    CalendarServer/branches/users/glyph/contacts-server-merge/test
    CalendarServer/branches/users/glyph/contacts-server-merge/twext/internet/tcp.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twext/web2/dav/davxml.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/accesslog.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/accounting.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/authkerb.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/cache.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/caldavxml.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/client/pool.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/client/reverseproxy.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/database.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/directory/augment.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/directory/cachingdirectory.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/directory/calendar.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/directory/calendaruserproxy.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/directory/calendaruserproxyloader.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/directory/digest.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/directory/directory.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/directory/principal.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/directory/resourceinfo.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/directory/test/test_guidchange.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/directory/wiki.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/directory/xmlaccountsparser.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/directory/xmlaugmentsparser.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/dropbox.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/extensions.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/ical.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/index.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/localization.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/mail.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/memcachepool.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/memcacheprops.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/memcacher.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/method/copymove.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/method/delete.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/method/delete_common.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/method/mkcalendar.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/method/propfind.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/method/put.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/method/put_common.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/method/report.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/method/report_calquery.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/method/report_common.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/method/report_freebusy.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/method/report_multiget.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/method/report_sync_collection.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/notify.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/partitions.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/pdmonster.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/resource.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/scheduling/addressmapping.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/scheduling/caldav.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/scheduling/cuaddress.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/scheduling/delivery.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/scheduling/icaldiff.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/scheduling/imip.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/scheduling/implicit.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/scheduling/ischedule.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/scheduling/ischeduleservers.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/scheduling/itip.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/scheduling/processing.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/scheduling/scheduler.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/sql.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/static.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/stdconfig.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/test/test_config.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/test/test_log.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/test/test_upgrade.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/timezones.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/upgrade.py
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/util.py
    CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/icalendarstore.py

Added Paths:
-----------
    CalendarServer/branches/users/glyph/contacts-server-merge/lib-patches/Twisted/twisted.mail.imap4.patch
    CalendarServer/branches/users/glyph/contacts-server-merge/lib-patches/Twisted/twisted.test.test_paths.patch
    CalendarServer/branches/users/glyph/contacts-server-merge/lib-patches/Twisted/twisted.web2.dav.resource.patch
    CalendarServer/branches/users/glyph/contacts-server-merge/twext/log.py
    CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/
    CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/__init__.py
    CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/file.py
    CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/
    CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/__init__.py
    CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/
    CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/
    CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_1/
    CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_1/1.ics
    CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_1/2.ics
    CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_1/3.ics
    CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_2/
    CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_2/24204e8682b99527cbda64d7423acda7.ics
    CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_2/61038c41bd02ae5daf9f7fe9d54199fd.ics
    CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_2/84be58ced1f1bb34057e1bd7e602c9c8.ics
    CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_2/acc1015b7dc300c1b5665f6833960994.ics
    CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_2/b0d5785f275c064117ffd1fc20f4ed40.ics
    CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_2/b495c5dd5aa53392078eb43b1f906a80.ics
    CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_2/b88dd50941e4a31520ee396fd7894c96.ics
    CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_empty/
    CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/test_file.py

Removed Paths:
-------------
    CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/log.py
    CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/__init__.py
    CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/file.py
    CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/
    CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/__init__.py
    CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/
    CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/
    CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_1/
    CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_1/1.ics
    CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_1/2.ics
    CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_1/3.ics
    CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_2/
    CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_2/24204e8682b99527cbda64d7423acda7.ics
    CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_2/61038c41bd02ae5daf9f7fe9d54199fd.ics
    CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_2/84be58ced1f1bb34057e1bd7e602c9c8.ics
    CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_2/acc1015b7dc300c1b5665f6833960994.ics
    CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_2/b0d5785f275c064117ffd1fc20f4ed40.ics
    CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_2/b495c5dd5aa53392078eb43b1f906a80.ics
    CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_2/b88dd50941e4a31520ee396fd7894c96.ics
    CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_empty/
    CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/test_file.py

Property Changed:
----------------
    CalendarServer/branches/users/glyph/contacts-server-merge/


Property changes on: CalendarServer/branches/users/glyph/contacts-server-merge
___________________________________________________________________
Modified: svn:mergeinfo
   - /CalendarServer/branches/config-separation:4379-4443
/CalendarServer/branches/egg-info-351:4589-4625
/CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627:3628-3644
/CalendarServer/branches/users/cdaboo/partition-4464:4465-4957
/CalendarServer/branches/users/sagen/resource-delegates-4038:4040-4067
/CalendarServer/branches/users/sagen/resource-delegates-4066:4068-4075
   + /CalendarServer/branches/config-separation:4379-4443
/CalendarServer/branches/egg-info-351:4589-4625
/CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627:3628-3644
/CalendarServer/branches/users/cdaboo/partition-4464:4465-4957
/CalendarServer/branches/users/sagen/resource-delegates-4038:4040-4067
/CalendarServer/branches/users/sagen/resource-delegates-4066:4068-4075
/CalendarServer/trunk:4971-5005

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/calendarserver/provision/root.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/calendarserver/provision/root.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/calendarserver/provision/root.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -20,18 +20,18 @@
 
 from twisted.internet.defer import inlineCallbacks, returnValue
 from twisted.cred.error import LoginFailed, UnauthorizedLogin
-
 from twisted.web2 import responsecode
 from twisted.web2.dav import davxml
 from twisted.web2.http import HTTPError, StatusResponse
 from twisted.web2.auth.wrapper import UnauthorizedResponse
 from twisted.web.xmlrpc import Proxy
 
+from twext.log import Logger
+
 from twistedcaldav.extensions import DAVFile, CachingPropertyStore
 from twistedcaldav.extensions import DirectoryPrincipalPropertySearchMixIn
 from twistedcaldav.extensions import ReadOnlyResourceMixIn
 from twistedcaldav.config import config
-from twistedcaldav.log import Logger
 from twistedcaldav.cache import _CachedResponseResource
 from twistedcaldav.cache import MemcacheResponseCache, MemcacheChangeNotifier
 from twistedcaldav.cache import DisabledCache

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/calendarserver/provision/test/test_root.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/calendarserver/provision/test/test_root.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/calendarserver/provision/test/test_root.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -31,9 +31,10 @@
 from twistedcaldav.test.util import TestCase
 from twistedcaldav.directory.principal import DirectoryPrincipalProvisioningResource
 from twistedcaldav.directory.xmlfile import XMLDirectoryService
-from twistedcaldav.directory.test.test_xmlfile import xmlFile
+from twistedcaldav.directory.test.test_xmlfile import xmlFile, augmentsFile
 
 from calendarserver.provision.root import RootResource
+from twistedcaldav.directory import augment
 
 class FakeCheckSACL(object):
     def __init__(self, sacls=None):
@@ -60,6 +61,7 @@
                 'calendar': ['dreid']})
 
         directory = XMLDirectoryService({'xmlFile' : xmlFile})
+        augment.AugmentService = augment.AugmentXMLDB(xmlFiles=(augmentsFile.path,))
 
         principals = DirectoryPrincipalProvisioningResource('/principals/', directory)
 

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/calendarserver/sidecar/task.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/calendarserver/sidecar/task.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/calendarserver/sidecar/task.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -22,30 +22,34 @@
     "Task",
 ]
 
-from calendarserver.provision.root import RootResource
 from time import sleep
+import os
+
+from zope.interface import implements
+
 from twisted.application.service import Service, IServiceMaker
-from twisted.internet.address import IPv4Address
 from twisted.internet.defer import DeferredList, inlineCallbacks, returnValue
 from twisted.internet.reactor import callLater
 from twisted.plugin import IPlugin
 from twisted.python.reflect import namedClass
 from twisted.python.usage import Options, UsageError
 from twisted.web2.http_headers import Headers
+
+from twext.log import Logger, LoggingMixIn
+from twext.log import logLevelForNamespace, setLogLevelForNamespace
+
 from twistedcaldav import memcachepool
 from twistedcaldav.config import config
 from twistedcaldav.stdconfig import DEFAULT_CONFIG, DEFAULT_CONFIG_FILE
 from twistedcaldav.directory.principal import DirectoryPrincipalProvisioningResource
 from twistedcaldav.ical import Component
-from twistedcaldav.log import Logger, LoggingMixIn
-from twistedcaldav.log import logLevelForNamespace, setLogLevelForNamespace
 from twistedcaldav.notify import installNotificationClient
 from twistedcaldav.scheduling.cuaddress import LocalCalendarUser
 from twistedcaldav.scheduling.scheduler import DirectScheduler
 from twistedcaldav.static import CalendarHomeProvisioningFile
-from zope.interface import implements
-import os
 
+from calendarserver.provision.root import RootResource
+
 log = Logger()
 
 class FakeRequest(object):

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/calendarserver/tap/caldav.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/calendarserver/tap/caldav.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/calendarserver/tap/caldav.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -43,7 +43,6 @@
 from twisted.internet.reactor import callLater, spawnProcess
 from twisted.internet.process import ProcessExitedAlready
 from twisted.internet.protocol import Protocol, Factory
-from twisted.internet.address import IPv4Address
 from twisted.application.internet import TCPServer, UNIXServer
 from twisted.application.service import Service, MultiService, IServiceMaker
 from twisted.scripts.mktap import getid
@@ -54,17 +53,19 @@
 from twisted.web2.server import Site
 from twisted.web2.static import File as FileResource
 
+from twext.log import Logger, LoggingMixIn
+from twext.log import logLevelForNamespace, setLogLevelForNamespace
 from twext.internet.ssl import ChainingOpenSSLContextFactory
 from twext.internet.tcp import MaxAcceptTCPServer, MaxAcceptSSLServer
 from twext.web2.channel.http import LimitingHTTPFactory, SSLRedirectRequest
 
 try:
     from twistedcaldav.version import version
-    version                     # pacify pyflakes
 except ImportError:
     sys.path.insert(0, os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))), "support"))
     from version import version as getVersion
     version = "%s (%s)" % getVersion()
+
 from twistedcaldav import memcachepool
 from twistedcaldav.accesslog import AMPCommonAccessLoggingObserver
 from twistedcaldav.accesslog import AMPLoggingFactory
@@ -81,11 +82,8 @@
 from twistedcaldav.directory.util import NotFilePath
 from twistedcaldav.directory.wiki import WikiDirectoryService
 from twistedcaldav.localization import processLocalizationFiles
-from twistedcaldav.log import Logger, LoggingMixIn
-from twistedcaldav.log import logLevelForNamespace, setLogLevelForNamespace
 from twistedcaldav.mail import IMIPReplyInboxResource
 from twistedcaldav.notify import installNotificationClient
-from twistedcaldav.pdmonster import PDClientAddressWrapper
 from twistedcaldav.resource import CalDAVResource, AuthenticationWrapper
 from twistedcaldav.static import CalendarHomeProvisioningFile
 from twistedcaldav.static import IScheduleInboxFile

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/calendarserver/tools/loadaugmentdb.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/calendarserver/tools/loadaugmentdb.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/calendarserver/tools/loadaugmentdb.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -15,12 +15,16 @@
 # limitations under the License.
 ##
 
-from calendarserver.tools.util import loadConfig, getDirectory,\
-    autoDisableMemcached
+import os
+import sys
+
 from getopt import getopt, GetoptError
 from grp import getgrnam
 from pwd import getpwnam
 from sys import stdout, stderr
+
+from twext.log import setLogLevelForNamespace
+
 from twisted.internet import reactor
 from twisted.internet.defer import inlineCallbacks
 from twisted.python.log import addObserver, removeObserver
@@ -28,10 +32,10 @@
 from twistedcaldav.config import config, ConfigurationError
 from twistedcaldav.directory import augment
 from twistedcaldav.directory.augment import AugmentXMLDB
-from twistedcaldav.log import setLogLevelForNamespace
-import os
-import sys
 
+from calendarserver.tools.util import loadConfig, getDirectory,\
+    autoDisableMemcached
+
 class UsageError (StandardError):
     pass
 

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/calendarserver/tools/manageaugments.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/calendarserver/tools/manageaugments.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/calendarserver/tools/manageaugments.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -20,6 +20,7 @@
 from xml.etree.ElementTree import ElementTree, tostring, SubElement
 from xml.parsers.expat import ExpatError
 import sys
+import os
 
 def error(s):
     print s
@@ -78,7 +79,8 @@
                 error("Cannot add guid '%s' because it already exists in augment file: '%s'" % (guid, xmlfile,))
     
     # Create new record
-    augments_node.getchildren()[-1].tail = "\n  "
+    if len(augments_node.getchildren()):
+        augments_node.getchildren()[-1].tail = "\n  "
     record = addSubElement(augments_node, xmlaugmentsparser.ELEMENT_RECORD, "\n    ")
     addSubElement(record, xmlaugmentsparser.ELEMENT_GUID, guid, 4)
     addSubElement(record, xmlaugmentsparser.ELEMENT_ENABLE, "true", 4)
@@ -173,6 +175,8 @@
                       help="XML augment file to manipulate", metavar="FILE")
     parser.add_option("-g", "--guid", dest="guid",
                       help="OD GUID to manipulate", metavar="GUID")
+    parser.add_option("-i", "--guidfile", dest="guidfile",
+                      help="File containing a list of GUIDs to manipulate", metavar="GUIDFILE")
     parser.add_option("-n", "--node", dest="node",
                       help="Partition node to assign to GUID", metavar="NODE")
     parser.add_option("-c", "--enable-calendar", action="store_true", dest="enable_calendar",
@@ -185,14 +189,27 @@
     if len(args) != 1:
         parser.error("incorrect number of arguments")
 
+    guids = []
+    if options.guid:
+        guids.append(options.guid)
+    elif options.guidfile:
+        if not os.path.exists(options.guidfile):
+            parser.error("File containing list of GUIDs does not exist")
+        with open(options.guidfile) as f:
+            for line in f:
+                guids.append(line[:-1])
+        
     if args[0] == "add":
         if not options.node:
-            parser.error("Partition node must be specified when adding")   
-        doAdd(options.xmlfilename, options.guid, options.node, options.enable_calendar, options.auto_schedule)
+            parser.error("Partition node must be specified when adding")
+        for guid in guids:
+            doAdd(options.xmlfilename, guid, options.node, options.enable_calendar, options.auto_schedule)
     elif args[0] == "modify":
-        doModify(options.xmlfilename, options.guid, options.node, options.enable_calendar, options.auto_schedule)
+        for guid in guids:
+            doModify(options.xmlfilename, guid, options.node, options.enable_calendar, options.auto_schedule)
     elif args[0] == "remove":
-        doRemove(options.xmlfilename, options.guid)
+        for guid in guids:
+            doRemove(options.xmlfilename, guid)
     elif args[0] == "print":
         doPrint(options.xmlfilename)
 

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/calendarserver/tools/principals.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/calendarserver/tools/principals.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/calendarserver/tools/principals.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -26,16 +26,15 @@
 
 from twisted.python.util import switchUID
 from twisted.internet import reactor
-from twisted.internet.address import IPv4Address
 from twisted.internet.defer import inlineCallbacks
 from twisted.web2.dav import davxml
 
+from twext.log import setLogLevelForNamespace
 from twext.python.log import StandardIOObserver
 from twext.web2.dav.davxml import sname2qname, qname2sname
 
 from twistedcaldav import memcachepool
 from twistedcaldav.config import config, ConfigurationError
-from twistedcaldav.log import setLogLevelForNamespace
 from twistedcaldav.notify import installNotificationClient
 from twistedcaldav.static import CalendarHomeProvisioningFile
 from twistedcaldav.directory.directory import UnknownRecordTypeError, DirectoryError

Copied: CalendarServer/branches/users/glyph/contacts-server-merge/lib-patches/Twisted/twisted.mail.imap4.patch (from rev 5005, CalendarServer/trunk/lib-patches/Twisted/twisted.mail.imap4.patch)
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/lib-patches/Twisted/twisted.mail.imap4.patch	                        (rev 0)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/lib-patches/Twisted/twisted.mail.imap4.patch	2010-02-02 01:25:32 UTC (rev 5006)
@@ -0,0 +1,18 @@
+Index: twisted/mail/imap4.py
+===================================================================
+--- twisted/mail/imap4.py	(revision 27622)
++++ twisted/mail/imap4.py	(working copy)
+@@ -391,10 +391,10 @@
+         return ''
+ 
+     def setResponse(self, response):
+-        parts = response[:-1].split('\0', 1)
+-        if len(parts) != 2:
++        parts = response.split('\0', 2)
++        if len(parts) != 3:
+             raise IllegalClientResponse("Malformed Response - wrong number of parts")
+-        self.username, self.password = parts
++        _ignore, self.username, self.password = parts
+ 
+     def moreChallenges(self):
+         return False

Copied: CalendarServer/branches/users/glyph/contacts-server-merge/lib-patches/Twisted/twisted.test.test_paths.patch (from rev 5005, CalendarServer/trunk/lib-patches/Twisted/twisted.test.test_paths.patch)
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/lib-patches/Twisted/twisted.test.test_paths.patch	                        (rev 0)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/lib-patches/Twisted/twisted.test.test_paths.patch	2010-02-02 01:25:32 UTC (rev 5006)
@@ -0,0 +1,12 @@
+Index: twisted/test/test_paths.py
+===================================================================
+--- twisted/test/test_paths.py	(revision 27622)
++++ twisted/test/test_paths.py	(working copy)
+@@ -793,6 +793,7 @@
+         self.assertEquals(fp.exists(), False)
+ 
+         fp.makedirs()
++        fp.changed()
+         self.assertEquals(fp.exists(), True)
+ 
+ 

Copied: CalendarServer/branches/users/glyph/contacts-server-merge/lib-patches/Twisted/twisted.web2.dav.resource.patch (from rev 5005, CalendarServer/trunk/lib-patches/Twisted/twisted.web2.dav.resource.patch)
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/lib-patches/Twisted/twisted.web2.dav.resource.patch	                        (rev 0)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/lib-patches/Twisted/twisted.web2.dav.resource.patch	2010-02-02 01:25:32 UTC (rev 5006)
@@ -0,0 +1,22 @@
+Index: twisted/web2/dav/resource.py
+===================================================================
+--- twisted/web2/dav/resource.py	(revision 27622)
++++ twisted/web2/dav/resource.py	(working copy)
+@@ -706,7 +706,7 @@
+                 hasattr(request, 'loginInterfaces')):
+             request.authnUser = davxml.Principal(davxml.Unauthenticated())
+             request.authzUser = davxml.Principal(davxml.Unauthenticated())
+-            return (request.authnUser, request.authzUser)
++            return succeed((request.authnUser, request.authzUser))
+ 
+         authHeader = request.headers.getHeader('authorization')
+ 
+@@ -754,7 +754,7 @@
+         else:
+             request.authnUser = davxml.Principal(davxml.Unauthenticated())
+             request.authzUser = davxml.Principal(davxml.Unauthenticated())
+-            return (request.authnUser, request.authzUser)
++            return succeed((request.authnUser, request.authzUser))
+ 
+     ##
+     # ACL

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/memcacheclient.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/memcacheclient.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/memcacheclient.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -49,8 +49,10 @@
 import os
 import re
 import types
+
+from twext.log import Logger
+
 from twistedcaldav.config import config
-from twistedcaldav.log import Logger
 
 log = Logger()
 

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/test
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/test	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/test	2010-02-02 01:25:32 UTC (rev 5006)
@@ -67,7 +67,7 @@
 if [ $# -gt 0 ]; then
     test_modules="$@";
 else
-    test_modules="calendarserver twistedcaldav twext twisted";
+    test_modules="calendarserver twistedcaldav twext txdav txcaldav txcarddav twisted";
 fi;
 
 cd "${wd}" && "${python}" "${twisted}/bin/trial" --rterrors ${random} ${until_fail} ${no_colour} ${coverage} ${test_modules};

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twext/internet/tcp.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twext/internet/tcp.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twext/internet/tcp.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -23,12 +23,14 @@
     "MaxAcceptSSLServer",
 ]
 
+import socket
 from OpenSSL import SSL
+
 from twisted.application import internet
 from twisted.internet import tcp, ssl
-from twistedcaldav.log import Logger
-import socket
 
+from twext.log import Logger
+
 log = Logger()
 
 

Copied: CalendarServer/branches/users/glyph/contacts-server-merge/twext/log.py (from rev 5005, CalendarServer/trunk/twext/log.py)
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twext/log.py	                        (rev 0)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twext/log.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -0,0 +1,317 @@
+##
+# Copyright (c) 2006-2010 Apple Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##
+
+"""
+Classes and functions to do granular logging.
+
+Example usage in a module:
+
+    from twext.log import Logger
+    log = Logger()
+
+    log.info("Blah blah")
+
+Or in a class:
+
+    from twext.log import LoggingMixIn
+
+    class Foo (LoggingMixIn):
+        def oops(self):
+            self.log_error("Oops!")
+
+C{Logger}s have namespaces, for which logging can be configured
+independently.  Namespaces may be specified by passing in a
+C{namespace} argument to L{Logger} when instantiating it, but if none
+is given, the logger will derive its own namespace by using the module
+name of the callable that instantiating it, or, in the case of a
+L{LoggingMixIn}, by using the fully qualified name of the class.
+
+In the first example above, the namespace would be C{some.module}, and
+in the second example, it would be C{some.module.Foo}.
+"""
+
+__all__ = [
+    "logLevels",
+    "cmpLogLevels",
+    "pythonLogLevelForLevel",
+    "logLevelForNamespace",
+    "setLogLevelForNamespace",
+    "clearLogLevels",
+    "logLevelsByNamespace",
+    "Logger",
+    "LoggingMixIn",
+    "InvalidLogLevelError",
+]
+
+import inspect
+import logging
+
+from twisted.python import log
+
+logLevels = (
+    "debug",
+    "info",
+    "warn",
+    "error",
+)
+
+logLevelIndexes = dict(zip(logLevels, xrange(0, len(logLevels))))
+
+def cmpLogLevels(a, b):
+    """
+    Compare two log levels.
+    @param a: a log level
+    @param b: a log level
+    @return: a negative integer if C{a < b}, C{0} if C{a == b}, or a
+        positive integer if C{a > b}.
+    """
+    return cmp(logLevelIndexes[a], logLevelIndexes[b])
+
+##
+# Mappings to Python's logging module
+##
+
+pythonLogLevelMapping = {
+    "debug"   : logging.DEBUG,
+    "info"    : logging.INFO,
+    "warn"    : logging.WARNING,
+    "error"   : logging.ERROR,
+   #"critical": logging.CRITICAL,
+}
+
+def pythonLogLevelForLevel(level):
+    """
+    @param: a log level
+    @return: a L{logging} module log level
+    """
+    if level in pythonLogLevelMapping:
+        return pythonLogLevelMapping[level]
+
+    raise InvalidLogLevelError(level)
+
+#    #
+#    # In case we add log levels that don't map to pythong logging levels:
+#    #
+#    for l in logLevels:
+#        print "Trying %s: %s, %s" % (l, l in pythonLogLevelMapping, cmpLogLevels(level, l) <= 0)
+#        if l in pythonLogLevelMapping and cmpLogLevels(level, l) <= 0:
+#            return pythonLogLevelMapping[l]
+#
+#    return logging.CRITICAL
+
+##
+# Tools for managing log levels
+##
+
+def logLevelForNamespace(namespace):
+    """
+    @param namespace: a logging namespace, or C{None} to set the
+        default log level.
+    @return: the log level for the given namespace.
+    """
+    if not namespace:
+        return logLevelsByNamespace[None]
+
+    if namespace in logLevelsByNamespace:
+        return logLevelsByNamespace[namespace]
+
+    segments = namespace.split(".")
+    index = len(segments) - 1
+
+    while index > 0:
+        namespace = ".".join(segments[:index])
+        if namespace in logLevelsByNamespace:
+            return logLevelsByNamespace[namespace]
+        index -= 1
+
+    return logLevelsByNamespace[None]
+
+def setLogLevelForNamespace(namespace, level):
+    """
+    Sets the log level for a logging namespace.
+    @param namespace: a logging namespace
+    @param level: the log level for the given namespace.
+    """
+    if level not in logLevels:
+        raise InvalidLogLevelError(level)
+
+    if namespace:
+        logLevelsByNamespace[namespace] = level
+    else:
+        logLevelsByNamespace[None] = level
+
+def clearLogLevels():
+    """
+    Clears all log levels to the default.
+    """
+    logLevelsByNamespace.clear()
+    logLevelsByNamespace[None] = "warn"  # Default log level
+
+logLevelsByNamespace = {}
+clearLogLevels()
+
+##
+# Loggers
+##
+
+class Logger (object):
+    """
+    Logging object.
+    """
+    def __init__(self, namespace=None):
+        """
+        @param namespace: The namespace for this logger.  Uses a
+            dotted notation, as used by python modules.  If not
+            C{None}, then the name of the module of the caller
+            is used.
+        """
+        if namespace is None:
+            currentFrame = inspect.currentframe()
+            callerFrame  = currentFrame.f_back
+            callerModule = callerFrame.f_globals["__name__"]
+
+            namespace = callerModule
+
+        self.namespace = namespace
+
+    def __repr__(self):
+        return "<%s %r>" % (self.__class__.__name__, self.namespace)
+
+    def emit(self, level, message, **kwargs):
+        """
+        Called internally to emit log messages at a given log level.
+        """
+        assert level in logLevels, "Unknown log level: %r" % (level,)
+
+        logLevel = pythonLogLevelForLevel(level)
+
+        # FIXME: Filtering should be done by the log observer(s)
+        if not self.willLogAtLevel(level):
+            return
+
+        kwargs["level"] = level
+        kwargs["logLevel"] = logLevel
+        kwargs["namespace"] = self.namespace
+
+        log.msg(
+            # FIXME: This formatting should be done by the log observer(s)
+            "[%s#%s] %s" % (self.namespace, level, message),
+            **kwargs
+        )
+
+    def level(self):
+        """
+        @return: the logging level for this logger's namespace.
+        """
+        return logLevelForNamespace(self.namespace)
+
+    def setLevel(self, level):
+        """
+        Set the logging level for this logger's namespace.
+        @param level: a logging level
+        """
+        setLogLevelForNamespace(self.namespace, level)
+
+    def willLogAtLevel(self, level):
+        """
+        @param level: a logging level
+        @return: C{True} if this logger will log at the given logging
+            level.
+        """
+        return cmpLogLevels(self.level(), level) <= 0
+
+
+class LoggingMixIn (object):
+    """
+    Mix-in class for logging methods.
+    """
+    def _getLogger(self):
+        try:
+            return self._logger
+        except AttributeError:
+            self._logger = Logger(
+                "%s.%s" % (
+                    self.__class__.__module__,
+                    self.__class__.__name__,
+                )
+            )
+
+        return self._logger
+
+    def _setLogger(self, value):
+        self._logger = value
+
+    logger = property(_getLogger, _setLogger)
+
+for level in logLevels:
+    doc = """
+    Emit a log message at log level C{%s}.
+    @param message: The message to emit.
+    """ % (level,)
+
+    #
+    # Attach methods to Logger
+    #
+    def log_emit(self, message, __level__=level, raiseException=None, **kwargs):
+        self.emit(__level__, message, **kwargs)
+        if raiseException:
+            raise raiseException(message)
+
+    def will_emit(self, __level__=level):
+        return self.willLogAtLevel(__level__)
+
+    log_emit.__doc__ = doc
+
+    setattr(Logger, level, log_emit)
+    setattr(Logger, level + "_enabled", property(will_emit))
+
+    del log_emit
+    del will_emit
+
+    #
+    # Attach methods to LoggingMixIn
+    #
+    def log_emit(self, message, __level__=level, raiseException=None, **kwargs):
+        self.logger.emit(__level__, message, **kwargs)
+        if raiseException:
+            raise raiseException(message)
+
+    def will_emit(self=log_emit, __level__=level):
+        return self.logger.willLogAtLevel(__level__)
+
+    log_emit.__doc__ = doc
+    log_emit.enabled = will_emit
+
+    setattr(LoggingMixIn, "log_" + level, log_emit)
+    setattr(LoggingMixIn, "log_" + level + "_enabled", property(will_emit))
+
+    del log_emit
+    del will_emit
+
+del level
+
+# Add some compatibility with twisted's log module
+Logger.msg = Logger.info
+Logger.err = Logger.error
+
+##
+# Errors
+##
+
+class InvalidLogLevelError (RuntimeError):
+    def __init__(self, level):
+        super(InvalidLogLevelError, self).__init__(str(level))
+        self.level = level

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twext/web2/dav/davxml.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twext/web2/dav/davxml.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twext/web2/dav/davxml.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -155,7 +155,7 @@
             elif qname in (
                 (dav_namespace, "prop"    ),
             ):
-                if property is not None:
+                if self.property is not None:
                     raise ValueError("Only one of DAV:prop allowed")
                 self.property = child
 

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/accesslog.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/accesslog.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/accesslog.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -31,15 +31,15 @@
 
 from twisted.internet import protocol
 from twisted.protocols import amp
-
 from twisted.web2 import iweb
 from twisted.web2.dav import davxml
 from twisted.web2.log import BaseCommonAccessLoggingObserver
 from twisted.web2.log import LogWrapperResource
 
+from twext.log import Logger
+
 from twistedcaldav.config import config
 from twistedcaldav.directory.directory import DirectoryService
-from twistedcaldav.log import Logger
 
 log = Logger()
 

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/accounting.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/accounting.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/accounting.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -27,8 +27,9 @@
 import datetime
 import os
 
+from twext.log import Logger
+
 from twistedcaldav.config import config
-from twistedcaldav.log import Logger
 
 log = Logger()
 

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/authkerb.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/authkerb.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/authkerb.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -46,7 +46,7 @@
 from twisted.web2.auth.interfaces import ICredentialFactory
 from twisted.web2.dav.auth import IPrincipalCredentials
 
-from twistedcaldav.log import LoggingMixIn
+from twext.log import LoggingMixIn
 
 class KerberosCredentialFactoryBase(LoggingMixIn):
     """

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/cache.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/cache.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/cache.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -21,13 +21,13 @@
 from zope.interface import implements
 
 from twisted.internet.defer import succeed, maybeDeferred
-
 from twisted.web2.dav.util import allDataFromStream
 from twisted.web2.http import Response
 from twisted.web2.iweb import IResource
 from twisted.web2.stream import MemoryStream
 
-from twistedcaldav.log import LoggingMixIn
+from twext.log import LoggingMixIn
+
 from twistedcaldav.memcachepool import CachePoolUserMixIn, defaultCachePool
 from twistedcaldav.config import config
 

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/caldavxml.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/caldavxml.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/caldavxml.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -31,11 +31,12 @@
 
 from twisted.web2.dav import davxml
 
+from twext.log import Logger
+
 from twistedcaldav.dateops import clipPeriod, timeRangesOverlap
 from twistedcaldav.ical import Component as iComponent
 from twistedcaldav.ical import Property as iProperty
 from twistedcaldav.ical import parse_date_or_datetime
-from twistedcaldav.log import Logger
 
 log = Logger()
 

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/client/pool.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/client/pool.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/client/pool.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -20,7 +20,12 @@
     "getHTTPClientPool",
 ]
 
+import OpenSSL
+import urlparse
+
+from twext.log import LoggingMixIn
 from twext.internet.ssl import ChainingOpenSSLContextFactory
+
 from twisted.internet.address import IPv4Address
 from twisted.internet.defer import Deferred, inlineCallbacks, returnValue
 from twisted.internet.error import ConnectionLost, ConnectionDone, ConnectError
@@ -29,9 +34,6 @@
 from twisted.web2.client.http import HTTPClientProtocol
 from twisted.web2.http import StatusResponse, HTTPError
 from twistedcaldav.config import config
-from twistedcaldav.log import LoggingMixIn
-import OpenSSL
-import urlparse
 
 class PooledHTTPClientFactory(ClientFactory, LoggingMixIn):
     """

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/client/reverseproxy.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/client/reverseproxy.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/client/reverseproxy.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -18,17 +18,19 @@
     "ReverseProxyResource",
 ]
 
+import urllib
+
+from zope.interface.declarations import implements
+
 from twisted.web2 import iweb
 from twisted.web2.client.http import ClientRequest
 from twisted.web2.resource import LeafResource
 
+from twext.log import LoggingMixIn
+
 from twistedcaldav.client.pool import getHTTPClientPool
 from twistedcaldav.config import config
-from twistedcaldav.log import LoggingMixIn
 
-import urllib
-from zope.interface.declarations import implements
-
 class ReverseProxyResource(LeafResource, LoggingMixIn):
     """
     A L{LeafResource} which always performs a reverse proxy operation.

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/database.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/database.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/database.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -14,13 +14,6 @@
 # limitations under the License.
 ##
 
-from twisted.enterprise.adbapi import ConnectionPool
-from twisted.internet.defer import inlineCallbacks, returnValue
-from twisted.python.threadpool import ThreadPool
-
-from twistedcaldav.config import ConfigurationError
-from twistedcaldav.log import Logger
-
 import thread
 
 try:
@@ -29,6 +22,14 @@
     pgdb = None
 #pgdb = None
 
+from twisted.enterprise.adbapi import ConnectionPool
+from twisted.internet.defer import inlineCallbacks, returnValue
+from twisted.python.threadpool import ThreadPool
+
+from twext.log import Logger
+
+from twistedcaldav.config import ConfigurationError
+
 """
 Generic ADAPI database access object.
 """

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/directory/augment.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/directory/augment.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/directory/augment.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -14,15 +14,17 @@
 # limitations under the License.
 ##
 
+import copy
+import time
 
 from twisted.internet.defer import inlineCallbacks, returnValue, succeed
+
+from twext.log import Logger
+
 from twistedcaldav.database import AbstractADBAPIDatabase, ADBAPISqliteMixin,\
     ADBAPIPostgreSQLMixin
 from twistedcaldav.directory.xmlaugmentsparser import XMLAugmentsParser
-import copy
-import time
 
-from twistedcaldav.log import Logger
 
 log = Logger()
 

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/directory/cachingdirectory.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/directory/cachingdirectory.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/directory/cachingdirectory.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -31,9 +31,10 @@
 import memcacheclient
 import base64
 
+from twext.log import LoggingMixIn
+
 from twistedcaldav.config import config
 from twistedcaldav.directory.directory import DirectoryService, DirectoryRecord, DirectoryError, UnknownRecordTypeError
-from twistedcaldav.log import LoggingMixIn
 from twistedcaldav.scheduling.cuaddress import normalizeCUAddr
 
 

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/directory/calendar.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/directory/calendar.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/directory/calendar.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -34,6 +34,8 @@
 from twisted.web2.dav.util import joinURL
 from twisted.web2.dav.resource import TwistedACLInheritable
 
+from twext.log import Logger
+
 from twistedcaldav import caldavxml
 from twistedcaldav.config import config
 from twistedcaldav.dropbox import DropBoxHomeResource
@@ -45,7 +47,6 @@
 from twistedcaldav.directory.wiki import getWikiACL
 from twistedcaldav.directory.resource import AutoProvisioningResourceMixIn
 
-from twistedcaldav.log import Logger
 log = Logger()
 
 # Use __underbars__ convention to avoid conflicts with directory resource types.

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/directory/calendaruserproxy.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/directory/calendaruserproxy.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/directory/calendaruserproxy.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -26,6 +26,9 @@
     "ProxyPostgreSQLDB",
 ]
 
+import itertools
+import time
+
 from twisted.internet.defer import succeed, inlineCallbacks, returnValue
 from twisted.web2 import responsecode
 from twisted.web2.http import HTTPError, StatusResponse
@@ -34,6 +37,8 @@
 from twisted.web2.dav.util import joinURL
 from twisted.web2.dav.noneprops import NonePropertyStore
 
+from twext.log import LoggingMixIn
+
 from twistedcaldav.config import config
 from twistedcaldav.database import AbstractADBAPIDatabase, ADBAPISqliteMixin,\
     ADBAPIPostgreSQLMixin
@@ -42,11 +47,7 @@
 from twistedcaldav.memcacher import Memcacher
 from twistedcaldav.resource import CalDAVComplianceMixIn
 from twistedcaldav.directory.util import NotFilePath
-from twistedcaldav.log import LoggingMixIn
 
-import itertools
-import time
-
 class PermissionsMixIn (ReadOnlyWritePropertiesResourceMixIn):
     def defaultAccessControlList(self):
         aces = (

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/directory/calendaruserproxyloader.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/directory/calendaruserproxyloader.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/directory/calendaruserproxyloader.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -14,12 +14,6 @@
 # limitations under the License.
 ##
 
-from xml.etree.ElementTree import ElementTree
-from xml.parsers.expat import ExpatError
-from twistedcaldav.directory import calendaruserproxy
-from twisted.internet.defer import inlineCallbacks
-import types
-
 """
 XML based calendar user proxy loader.
 """
@@ -28,8 +22,16 @@
     "XMLCalendarUserProxyLoader",
 ]
 
-from twistedcaldav.log import Logger
+import types
+from xml.etree.ElementTree import ElementTree
+from xml.parsers.expat import ExpatError
 
+from twisted.internet.defer import inlineCallbacks
+
+from twext.log import Logger
+
+from twistedcaldav.directory import calendaruserproxy
+
 log = Logger()
 
 ELEMENT_PROXIES           = "proxies"

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/directory/digest.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/directory/digest.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/directory/digest.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -23,7 +23,8 @@
 from twisted.web2.http_headers import split
 from twisted.web2.http_headers import tokenize
 
-from twistedcaldav.log import Logger
+from twext.log import Logger
+
 from twistedcaldav.memcacher import Memcacher
 
 from zope.interface import implements, Interface

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/directory/directory.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/directory/directory.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/directory/directory.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -38,8 +38,9 @@
 from twisted.web2.dav.auth import IPrincipalCredentials
 from twisted.internet.defer import succeed
 
+from twext.log import LoggingMixIn
+
 from twistedcaldav.config import config
-from twistedcaldav.log import LoggingMixIn
 from twistedcaldav.directory.idirectory import IDirectoryService, IDirectoryRecord
 from twistedcaldav.directory.util import uuidFromName
 from twistedcaldav.partitions import partitions

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/directory/principal.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/directory/principal.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/directory/principal.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -50,10 +50,11 @@
 
 from twistedcaldav import carddavxml
 
+from twext.log import Logger
+
 from twistedcaldav.authkerb import NegotiateCredentials
 from twistedcaldav.config import config
 from twistedcaldav.cache import DisabledCacheNotifier, PropfindCacheMixin
-
 from twistedcaldav.directory import calendaruserproxy
 from twistedcaldav.directory.calendaruserproxy import CalendarUserProxyPrincipalResource
 from twistedcaldav.directory.directory import DirectoryService, DirectoryRecord
@@ -61,7 +62,6 @@
 from twistedcaldav.extensions import ReadOnlyResourceMixIn, DAVFile, DAVPrincipalResource
 from twistedcaldav.resource import CalendarPrincipalCollectionResource, CalendarPrincipalResource
 from twistedcaldav.directory.idirectory import IDirectoryService
-from twistedcaldav.log import Logger
 from twistedcaldav import caldavxml, customxml
 from twistedcaldav.customxml import calendarserver_namespace
 from twistedcaldav.directory.wiki import getWikiACL

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/directory/resourceinfo.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/directory/resourceinfo.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/directory/resourceinfo.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -22,11 +22,14 @@
     "ResourceInfoDatabase",
 ]
 
+import os
+
 from twisted.internet.defer import inlineCallbacks, returnValue
-from twistedcaldav.log import LoggingMixIn
+
+from twext.log import LoggingMixIn
+
 from twistedcaldav.memcacher import Memcacher
 from twistedcaldav.sql import AbstractSQLDatabase, db_prefix
-import os
 
 class ResourceInfoDatabase(AbstractSQLDatabase, LoggingMixIn):
     """

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/directory/test/test_guidchange.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/directory/test/test_guidchange.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/directory/test/test_guidchange.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -24,9 +24,10 @@
 from twisted.web2.test.test_server import SimpleRequest
 
 from twistedcaldav.directory.xmlfile import XMLDirectoryService
-from twistedcaldav.directory.test.test_xmlfile import xmlFile
+from twistedcaldav.directory.test.test_xmlfile import xmlFile, augmentsFile
 
 import twistedcaldav.test.util
+from twistedcaldav.directory import augment
 
 
 class ProvisionedPrincipals (twistedcaldav.test.util.TestCase):
@@ -42,6 +43,7 @@
         fd.write(open(xmlFile.path, "r").read())
         fd.close()
         self.directoryService = XMLDirectoryService({'xmlFile' : self.xmlFile})
+        augment.AugmentService = augment.AugmentXMLDB(xmlFiles=(augmentsFile.path,))
         
         # Set up a principals hierarchy for each service we're testing with
         name = "principals"

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/directory/wiki.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/directory/wiki.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/directory/wiki.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -23,20 +23,19 @@
     "WikiDirectoryService",
 ]
 
+from twisted.internet.defer import inlineCallbacks, returnValue
 from twisted.web2.dav import davxml
 from twisted.web.xmlrpc import Proxy, Fault
 from twisted.web2.http import HTTPError, StatusResponse
 from twisted.web2.auth.wrapper import UnauthorizedResponse
 
-from twisted.internet.defer import inlineCallbacks, returnValue
+from twext.log import Logger
 
-
 from twisted.web2.dav.resource import TwistedACLInheritable
 from twistedcaldav.config import config
 from twistedcaldav.directory.directory import (DirectoryService,
                                                DirectoryRecord,
                                                UnknownRecordTypeError)
-from twistedcaldav.log import Logger
 
 log = Logger()
 

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/directory/xmlaccountsparser.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/directory/xmlaccountsparser.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/directory/xmlaccountsparser.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -27,8 +27,9 @@
 
 from twisted.python.filepath import FilePath
 
+from twext.log import Logger
+
 from twistedcaldav.directory.directory import DirectoryService
-from twistedcaldav.log import Logger
 
 log = Logger()
 

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/directory/xmlaugmentsparser.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/directory/xmlaugmentsparser.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/directory/xmlaugmentsparser.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -14,10 +14,6 @@
 # limitations under the License.
 ##
 
-from xml.etree.ElementTree import ElementTree
-from xml.parsers.expat import ExpatError
-import types
-
 """
 XML based augment configuration file handling.
 """
@@ -26,8 +22,12 @@
     "XMLAugmentsParser",
 ]
 
-from twistedcaldav.log import Logger
+from xml.etree.ElementTree import ElementTree
+from xml.parsers.expat import ExpatError
+import types
 
+from twext.log import Logger
+
 log = Logger()
 
 ELEMENT_AUGMENTS          = "augments"

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/dropbox.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/dropbox.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/dropbox.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -28,8 +28,9 @@
 from twisted.web2.dav import davxml
 from twisted.web2.dav.resource import DAVResource, TwistedACLInheritable
 
+from twext.log import Logger
+
 from twistedcaldav.customxml import calendarserver_namespace
-from twistedcaldav.log import Logger
 
 log = Logger()
 

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/extensions.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/extensions.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/extensions.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -56,9 +56,10 @@
 from twisted.web2.dav.method import prop_common
 from twisted.web2.dav.method.report import max_number_of_matches
 
+from twext.log import Logger, LoggingMixIn
+
 from twistedcaldav import customxml
 from twistedcaldav.customxml import calendarserver_namespace
-from twistedcaldav.log import Logger, LoggingMixIn
 from twistedcaldav.util import submodule, Alternator, printTracebacks
 from twistedcaldav.directory.sudo import SudoDirectoryService
 from twistedcaldav.directory.directory import DirectoryService

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/ical.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/ical.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/ical.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -19,6 +19,7 @@
 """
 
 __all__ = [
+    "InvalidICalendarDataError",
     "iCalendarProductID",
     "allowedComponents",
     "Property",
@@ -32,24 +33,26 @@
     "tzexpand",
 ]
 
+import cStringIO as StringIO
+import datetime
+import heapq
+import itertools
+
+from vobject import newFromBehavior, readComponents
+from vobject.base import Component as vComponent, ContentLine as vContentLine, ParseError as vParseError
+from vobject.icalendar import TimezoneComponent, dateTimeToString, deltaToOffset, getTransition, stringToDate, stringToDateTime, stringToDurations, utc
+
 from twisted.web2.dav.util import allDataFromStream
 from twisted.web2.stream import IStream
 
+from twext.log import Logger
+
 from twistedcaldav.dateops import compareDateTime, normalizeToUTC, timeRangesOverlap,\
     normalizeStartEndDuration, toString, normalizeForIndex, differenceDateTime
 from twistedcaldav.instance import InstanceList
-from twistedcaldav.log import Logger
 from twistedcaldav.scheduling.cuaddress import normalizeCUAddr
 
-from vobject import newFromBehavior, readComponents
-from vobject.base import Component as vComponent, ContentLine as vContentLine, ParseError as vParseError
-from vobject.icalendar import TimezoneComponent, dateTimeToString, deltaToOffset, getTransition, stringToDate, stringToDateTime, stringToDurations, utc
 
-import cStringIO as StringIO
-import datetime
-import heapq
-import itertools
-
 log = Logger()
 
 iCalendarProductID = "-//CALENDARSERVER.ORG//NONSGML Version 1//EN"
@@ -129,6 +132,9 @@
     "ORGANIZER":    normalizeCUAddr,
 }
 
+class InvalidICalendarDataError(ValueError):
+    pass
+
 class Property (object):
     """
     iCalendar Property
@@ -197,12 +203,12 @@
     def paramValue(self, name):
         """
         Returns a single value for the given parameter.  Raises
-        ValueError if the parameter has more than one value.
+        InvalidICalendarDataError if the parameter has more than one value.
         """
         values = self._vobject.params.get(name, [None,])
         assert type(values) is list, "vobject returned non-list value for parameter %r in property %r" % (name, self)
         if len(values) != 1:
-            raise ValueError("Not exactly one %s value in property %r" % (name, self))
+            raise InvalidICalendarDataError("Not exactly one %s value in property %r" % (name, self))
         return values[0]
 
     def containsTimeRange(self, start, end, tzinfo=None):
@@ -299,11 +305,11 @@
             return clazz(None, vobject=readComponents(stream, findBegin=False).next())
         except UnicodeDecodeError, e:
             stream.seek(0)
-            raise ValueError("%s: %s" % (e, stream.read()))
+            raise InvalidICalendarDataError("%s: %s" % (e, stream.read()))
         except vParseError, e:
-            raise ValueError(e)
+            raise InvalidICalendarDataError(e)
         except StopIteration, e:
-            raise ValueError(e)
+            raise InvalidICalendarDataError(e)
 
     @classmethod
     def fromIStream(clazz, stream):
@@ -412,7 +418,7 @@
         """
         Determine the primary type of iCal component in this calendar.
         @return: the name of the primary type.
-        @raise: L{ValueError} if there is more than one primary type.
+        @raise: L{InvalidICalendarDataError} if there is more than one primary type.
         """
         assert self.name() == "VCALENDAR", "Must be a VCALENDAR: %r" % (self,)
         
@@ -421,7 +427,7 @@
             if component.name() == "VTIMEZONE":
                 continue
             elif mtype and (mtype != component.name()):
-                raise ValueError("Component contains more than one type of primary type: %r" % (self,))
+                raise InvalidICalendarDataError("Component contains more than one type of primary type: %r" % (self,))
             else:
                 mtype = component.name()
         
@@ -431,7 +437,7 @@
         """
         Return the primary iCal component in this calendar.
         @return: the L{Component} of the primary type.
-        @raise: L{ValueError} if there is more than one primary type.
+        @raise: L{InvalidICalendarDataError} if there is more than one primary type.
         """
         assert self.name() == "VCALENDAR", "Must be a VCALENDAR: %r" % (self,)
         
@@ -440,7 +446,7 @@
             if component.name() == "VTIMEZONE":
                 continue
             elif not allow_multiple and (result is not None):
-                raise ValueError("Calendar contains more than one primary component: %r" % (self,))
+                raise InvalidICalendarDataError("Calendar contains more than one primary component: %r" % (self,))
             else:
                 result = component
                 if allow_multiple:
@@ -547,11 +553,11 @@
         Get one property from the property list.
         @param name: the name of the property to get.
         @return: the L{Property} found or None.
-        @raise: L{ValueError} if there is more than one property of the given name.
+        @raise: L{InvalidICalendarDataError} if there is more than one property of the given name.
         """
         properties = tuple(self.properties(name))
         if len(properties) == 1: return properties[0]
-        if len(properties) > 1: raise ValueError("More than one %s property in component %r" % (name, self))
+        if len(properties) > 1: raise InvalidICalendarDataError("More than one %s property in component %r" % (name, self))
         return None
         
     def properties(self, name=None):
@@ -580,7 +586,7 @@
         if len(properties) == 1:
             return properties[0].value()
         if len(properties) > 1:
-            raise ValueError("More than one %s property in component %r" % (name, self))
+            raise InvalidICalendarDataError("More than one %s property in component %r" % (name, self))
         return None
 
 
@@ -604,7 +610,7 @@
             return result
 
         elif len(properties) > 1:
-            raise ValueError("More than one %s property in component %r" % (name, self))
+            raise InvalidICalendarDataError("More than one %s property in component %r" % (name, self))
         else:
             return None
 
@@ -702,7 +708,7 @@
         # The trigger value
         trigger = self.propertyNativeValue("TRIGGER")
         if trigger is None:
-            raise ValueError("VALARM has no TRIGGER property: %r" % (self,))
+            raise InvalidICalendarDataError("VALARM has no TRIGGER property: %r" % (self,))
         
         # The related parameter
         related = self.getProperty("TRIGGER").paramValue("RELATED")
@@ -720,7 +726,7 @@
         duration = self.propertyNativeValue("DURATION")
 
         if repeat > 0 and duration is None:
-            raise ValueError("VALARM has invalid REPEAT/DURATIOn properties: %r" % (self,))
+            raise InvalidICalendarDataError("VALARM has invalid REPEAT/DURATIOn properties: %r" % (self,))
 
         return (trigger, related, repeat, duration)
  
@@ -1190,30 +1196,30 @@
                 if has_timezone:
                     self._resource_type = "VTIMEZONE"
                 else:
-                    raise ValueError("No component type found for calendar component: %r" % (self,))
+                    raise InvalidICalendarDataError("No component type found for calendar component: %r" % (self,))
 
         return self._resource_type
 
     def validCalendarForCalDAV(self):
         """
-        @raise ValueError: if the given calendar data is not valid.
+        @raise InvalidICalendarDataError: if the given calendar data is not valid.
         """
         if self.name() != "VCALENDAR":
             log.debug("Not a calendar: %s" % (self,))
-            raise ValueError("Not a calendar")
+            raise InvalidICalendarDataError("Not a calendar")
         if not self.resourceType():
             log.debug("Unknown resource type: %s" % (self,))
-            raise ValueError("Unknown resource type")
+            raise InvalidICalendarDataError("Unknown resource type")
 
         version = self.propertyValue("VERSION")
         if version != "2.0":
             msg = "Not a version 2.0 iCalendar (version=%s)" % (version,)
             log.debug(msg)
-            raise ValueError(msg)
+            raise InvalidICalendarDataError(msg)
 
     def validateForCalDAV(self):
         """
-        @raise ValueError: if the given calendar component is not valid for
+        @raise InvalidICalendarDataError: if the given calendar component is not valid for
             use as a X{CalDAV} resource.
         """
         self.validCalendarForCalDAV()
@@ -1222,14 +1228,14 @@
         if self.hasProperty("METHOD"):
             msg = "METHOD property is not allowed in CalDAV iCalendar data"
             log.debug(msg)
-            raise ValueError(msg)
+            raise InvalidICalendarDataError(msg)
 
         self.validateComponentsForCalDAV(False)
 
     def validateComponentsForCalDAV(self, method):
         """
         @param method:     True if METHOD property is allowed, False otherwise.
-        @raise ValueError: if the given calendar component is not valid for
+        @raise InvalidICalendarDataError: if the given calendar component is not valid for
             use as a X{CalDAV} resource.
         """
         #
@@ -1250,7 +1256,7 @@
             if not method and subcomponent.hasProperty("METHOD"):
                 msg = "METHOD property is not allowed in CalDAV iCalendar data"
                 log.debug(msg)
-                raise ValueError(msg)
+                raise InvalidICalendarDataError(msg)
         
             if subcomponent.name() == "VTIMEZONE":
                 timezones.add(subcomponent.propertyValue("TZID"))
@@ -1261,18 +1267,18 @@
                     if ctype != subcomponent.name():
                         msg = "Calendar resources may not contain more than one type of calendar component (%s and %s found)" % (ctype, subcomponent.name())
                         log.debug(msg)
-                        raise ValueError(msg)
+                        raise InvalidICalendarDataError(msg)
         
                 if ctype not in allowedComponents:
                     msg = "Component type: %s not allowed" % (ctype,)
                     log.debug(msg)
-                    raise ValueError(msg)
+                    raise InvalidICalendarDataError(msg)
                     
                 uid = subcomponent.propertyValue("UID")
                 if uid is None:
                     msg = "All components must have UIDs"
                     log.debug(msg)
-                    raise ValueError(msg)
+                    raise InvalidICalendarDataError(msg)
                 rid = subcomponent.getRecurrenceIDUTC()
                 
                 # Verify that UIDs are the same
@@ -1281,14 +1287,14 @@
                 elif component_id != uid:
                     msg = "Calendar resources may not contain components with different UIDs (%s and %s found)" % (component_id, subcomponent.propertyValue("UID"))
                     log.debug(msg)
-                    raise ValueError(msg)
+                    raise InvalidICalendarDataError(msg)
 
                 # Verify that there is only one master component
                 if rid is None:
                     if got_master:
                         msg = "Calendar resources may not contain components with the same UIDs and no Recurrence-IDs (%s and %s found)" % (component_id, subcomponent.propertyValue("UID"))
                         log.debug(msg)
-                        raise ValueError(msg)
+                        raise InvalidICalendarDataError(msg)
                     else:
                         got_master = True
                         # master_recurring = subcomponent.hasProperty("RRULE") or subcomponent.hasProperty("RDATE")
@@ -1305,13 +1311,13 @@
 #                if got_override and got_master and not master_recurring:
 #                    msg = "Calendar resources must have a recurring master component if there is an overridden one (%s)" % (subcomponent.propertyValue("UID"),)
 #                    log.debug(msg)
-#                    raise ValueError(msg)
+#                    raise InvalidICalendarDataError(msg)
                 
                 # Check for duplicate RECURRENCE-IDs        
                 if rid in component_rids:
                     msg = "Calendar resources may not contain components with the same Recurrence-IDs (%s)" % (rid,)
                     log.debug(msg)
-                    raise ValueError(msg)
+                    raise InvalidICalendarDataError(msg)
                 else:
                     component_rids.add(rid)
 
@@ -1324,7 +1330,7 @@
             if timezone_ref not in timezones:
                 msg = "Timezone ID %s is referenced but not defined: %s" % (timezone_ref, self,)
                 log.debug(msg)
-                raise ValueError(msg)
+                raise InvalidICalendarDataError(msg)
         
         #
         # FIXME:
@@ -1353,7 +1359,7 @@
                         # We have different ORGANIZERs in the same iCalendar object - this is an error
                         msg = "Only one ORGANIZER is allowed in an iCalendar object:\n%s" % (self,)
                         log.debug(msg)
-                        raise ValueError(msg)
+                        raise InvalidICalendarDataError(msg)
                 else:
                     foundOrganizer = organizer
                     foundRid = rid
@@ -1409,7 +1415,7 @@
             method = self.propertyValue("METHOD")
             if method not in ("PUBLISH", "REQUEST", "REPLY", "ADD", "CANCEL", "REFRESH", "COUNTER", "DECLINECOUNTER"):
                 return False
-        except ValueError:
+        except InvalidICalendarDataError:
             return False
         
         return True
@@ -1440,7 +1446,7 @@
                 if len([c for c in self.subcomponents()]) != 1:
                     return False
 
-        except ValueError:
+        except InvalidICalendarDataError:
             return False
         
         return True
@@ -1461,7 +1467,7 @@
             try:
                 # Find the primary subcomponent
                 return self.propertyValue("ORGANIZER")
-            except ValueError:
+            except InvalidICalendarDataError:
                 pass
 
         return None
@@ -1486,7 +1492,7 @@
                 org = self.propertyValue("ORGANIZER")
                 rid = self.getRecurrenceIDUTC()
                 return ((org, rid),)
-            except ValueError:
+            except InvalidICalendarDataError:
                 pass
 
         return ()
@@ -1507,7 +1513,7 @@
             try:
                 # Find the primary subcomponent
                 return self.getProperty("ORGANIZER")
-            except ValueError:
+            except InvalidICalendarDataError:
                 pass
 
         return None
@@ -1663,7 +1669,7 @@
             try:
                 # Find the primary subcomponent
                 return self.propertyValue("X-CALENDARSERVER-MASK-UID")
-            except ValueError:
+            except InvalidICalendarDataError:
                 pass
 
         return None
@@ -1949,7 +1955,7 @@
                             del prop.params()[param]
                     except KeyError:
                         pass
-                    except ValueError:
+                    except InvalidICalendarDataError:
                         pass
 
     def normalizeAll(self):
@@ -2206,8 +2212,8 @@
     """
     try:
         return stringToDate(date_string)
-    except (vParseError, ValueError):
-        raise ValueError("Invalid iCalendar DATE: %r" % (date_string,))
+    except (vParseError, InvalidICalendarDataError):
+        raise InvalidICalendarDataError("Invalid iCalendar DATE: %r" % (date_string,))
 
 def parse_time(time_string):
     """
@@ -2219,8 +2225,8 @@
         # Parse this as a fake date-time string by prepending date
         with_date = "20000101T" + time_string
         return stringToDateTime(with_date).time()
-    except (vParseError, ValueError):
-        raise ValueError("Invalid iCalendar TIME: %r" % (time_string,))
+    except (vParseError, InvalidICalendarDataError):
+        raise InvalidICalendarDataError("Invalid iCalendar TIME: %r" % (time_string,))
 
 def parse_datetime(datetime_string):
     """
@@ -2230,8 +2236,8 @@
     """
     try:
         return stringToDateTime(datetime_string)
-    except (vParseError, ValueError):
-        raise ValueError("Invalid iCalendar DATE-TIME: %r" % (datetime_string,))
+    except (vParseError, InvalidICalendarDataError):
+        raise InvalidICalendarDataError("Invalid iCalendar DATE-TIME: %r" % (datetime_string,))
 
 def parse_date_or_datetime(date_string):
     """
@@ -2246,8 +2252,8 @@
             return parse_date(date_string)
         else:
             return parse_datetime(date_string)
-    except ValueError:
-        raise ValueError("Invalid iCalendar DATE or DATE-TIME: %r" % (date_string,))
+    except InvalidICalendarDataError:
+        raise InvalidICalendarDataError("Invalid iCalendar DATE or DATE-TIME: %r" % (date_string,))
 
 def parse_duration(duration_string):
     """
@@ -2257,8 +2263,8 @@
     """
     try:
         return stringToDurations(duration_string)[0]
-    except (vParseError, ValueError):
-        raise ValueError("Invalid iCalendar DURATION: %r" % (duration_string,))
+    except (vParseError, InvalidICalendarDataError):
+        raise InvalidICalendarDataError("Invalid iCalendar DURATION: %r" % (duration_string,))
 
 _regex_duration = None
 
@@ -2290,7 +2296,7 @@
             tzcomp = comp
             break
     else:
-        raise ValueError("No VTIMEZONE component in %s" % (tzdata,))
+        raise InvalidICalendarDataError("No VTIMEZONE component in %s" % (tzdata,))
 
     tzinfo = tzcomp.gettzinfo()
     

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/index.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/index.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/index.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -44,13 +44,14 @@
 
 from twisted.internet.defer import maybeDeferred, succeed
 
+from twext.log import Logger, LoggingMixIn
+
 from twistedcaldav.ical import Component
 from twistedcaldav.query import calendarquery
 from twistedcaldav.sql import AbstractSQLDatabase
 from twistedcaldav.sql import db_prefix
 from twistedcaldav import caldavxml
 from twistedcaldav.instance import InvalidOverriddenInstanceError
-from twistedcaldav.log import Logger, LoggingMixIn
 from twistedcaldav.config import config
 from twistedcaldav.memcachepool import CachePoolUserMixIn
 

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/localization.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/localization.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/localization.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -23,8 +23,10 @@
 import array
 import codecs
 from locale import normalize
+
+from twext.log import Logger
+
 from twistedcaldav.config import config
-from twistedcaldav.log import Logger
 
 log = Logger()
 

Deleted: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/log.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/log.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/log.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -1,404 +0,0 @@
-##
-# Copyright (c) 2006-2010 Apple Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-##
-
-"""
-Classes and functions to do better logging.
-
-Example usage in a module:
-
-    from twistedcaldav.log import Logger
-    log = Logger()
-
-    log.info("Blah blah")
-
-Or in a class:
-
-    from twistedcaldav.log import LoggingMixIn
-
-    class Foo (LoggingMixIn):
-        def oops(self):
-            self.log_error("Oops!")
-
-C{Logger}s have namespaces, for which logging can be configured
-independently.  Namespaces may be specified by passing in a
-C{namespace} argument to L{Logger} when instantiating it, but if none
-is given, the logger will derive its own namespace by using the module
-name of the callable that instantiating it, or, in the case of a
-L{LoggingMixIn}, by using the fully qualified name of the class.
-
-In the first example above, the namespace would be C{some.module}, and
-in the second example, it would be C{some.module.Foo}.
-"""
-
-__all__ = [
-    "logLevels",
-    "cmpLogLevels",
-    "pythonLogLevelForLevel",
-    "logLevelForNamespace",
-    "setLogLevelForNamespace",
-    "clearLogLevels",
-    "logLevelsByNamespace",
-    "Logger",
-    "LoggingMixIn",
-    "InvalidLogLevelError",
-]
-
-import inspect
-import logging
-
-from twisted.python import log
-
-from StringIO import StringIO
-
-from twisted.internet.defer import succeed
-
-from twisted.web2 import responsecode
-from twisted.web2.dav.util import allDataFromStream
-from twisted.web2.stream import MemoryStream
-
-logLevels = (
-    "debug",
-    "info",
-    "warn",
-    "error",
-)
-
-logLevelIndexes = dict(zip(logLevels, xrange(0, len(logLevels))))
-
-def cmpLogLevels(a, b):
-    """
-    Compare two log levels.
-    @param a: a log level
-    @param b: a log level
-    @return: a negative integer if C{a < b}, C{0} if C{a == b}, or a
-        positive integer if C{a > b}.
-    """
-    return cmp(logLevelIndexes[a], logLevelIndexes[b])
-
-##
-# Mappings to Python's logging module
-##
-
-pythonLogLevelMapping = {
-    "debug"   : logging.DEBUG,
-    "info"    : logging.INFO,
-    "warn"    : logging.WARNING,
-    "error"   : logging.ERROR,
-   #"critical": logging.CRITICAL,
-}
-
-def pythonLogLevelForLevel(level):
-    """
-    @param: a log level
-    @return: a L{logging} module log level
-    """
-    if level in pythonLogLevelMapping:
-        return pythonLogLevelMapping[level]
-
-    raise InvalidLogLevelError(level)
-
-#    #
-#    # In case we add log levels that don't map to pythong logging levels:
-#    #
-#    for l in logLevels:
-#        print "Trying %s: %s, %s" % (l, l in pythonLogLevelMapping, cmpLogLevels(level, l) <= 0)
-#        if l in pythonLogLevelMapping and cmpLogLevels(level, l) <= 0:
-#            return pythonLogLevelMapping[l]
-#
-#    return logging.CRITICAL
-
-##
-# Tools for managing log levels
-##
-
-def logLevelForNamespace(namespace):
-    """
-    @param namespace: a logging namespace, or C{None} to set the
-        default log level.
-    @return: the log level for the given namespace.
-    """
-    if not namespace:
-        return logLevelsByNamespace[None]
-
-    if namespace in logLevelsByNamespace:
-        return logLevelsByNamespace[namespace]
-
-    segments = namespace.split(".")
-    index = len(segments) - 1
-
-    while index > 0:
-        namespace = ".".join(segments[:index])
-        if namespace in logLevelsByNamespace:
-            return logLevelsByNamespace[namespace]
-        index -= 1
-
-    return logLevelsByNamespace[None]
-
-def setLogLevelForNamespace(namespace, level):
-    """
-    Sets the log level for a logging namespace.
-    @param namespace: a logging namespace
-    @param level: the log level for the given namespace.
-    """
-    if level not in logLevels:
-        raise InvalidLogLevelError(level)
-
-    if namespace:
-        logLevelsByNamespace[namespace] = level
-    else:
-        logLevelsByNamespace[None] = level
-
-def clearLogLevels():
-    """
-    Clears all log levels to the default.
-    """
-    logLevelsByNamespace.clear()
-    logLevelsByNamespace[None] = "warn"  # Default log level
-
-logLevelsByNamespace = {}
-clearLogLevels()
-
-##
-# Loggers
-##
-
-class Logger (object):
-    """
-    Logging object.
-    """
-    def __init__(self, namespace=None):
-        """
-        @param namespace: The namespace for this logger.  Uses a
-            dotted notation, as used by python modules.  If not
-            C{None}, then the name of the module of the caller
-            is used.
-        """
-        if namespace is None:
-            currentFrame = inspect.currentframe()
-            callerFrame  = currentFrame.f_back
-            callerModule = callerFrame.f_globals["__name__"]
-
-            namespace = callerModule
-
-        self.namespace = namespace
-
-    def __repr__(self):
-        return "<%s %r>" % (self.__class__.__name__, self.namespace)
-
-    def emit(self, level, message, **kwargs):
-        """
-        Called internally to emit log messages at a given log level.
-        """
-        assert level in logLevels, "Unknown log level: %r" % (level,)
-
-        logLevel = pythonLogLevelForLevel(level)
-
-        # FIXME: Filtering should be done by the log observer(s)
-        if not self.willLogAtLevel(level):
-            return
-
-        kwargs["level"] = level
-        kwargs["logLevel"] = logLevel
-        kwargs["namespace"] = self.namespace
-
-        log.msg(
-            # FIXME: This formatting should be done by the log observer(s)
-            "[%s#%s] %s" % (self.namespace, level, message),
-            **kwargs
-        )
-
-    def level(self):
-        """
-        @return: the logging level for this logger's namespace.
-        """
-        return logLevelForNamespace(self.namespace)
-
-    def setLevel(self, level):
-        """
-        Set the logging level for this logger's namespace.
-        @param level: a logging level
-        """
-        setLogLevelForNamespace(self.namespace, level)
-
-    def willLogAtLevel(self, level):
-        """
-        @param level: a logging level
-        @return: C{True} if this logger will log at the given logging
-            level.
-        """
-        return cmpLogLevels(self.level(), level) <= 0
-
-    # FIXME: This doesn't belong here
-    def logRequest(self, level, message, request, **kwargs):
-        """
-        Log an HTTP request.
-        """
-
-        assert level in logLevels
-
-        if self.willLogAtLevel(level):
-            iostr = StringIO()
-            iostr.write("%s\n" % (message,))
-            if hasattr(request, "clientproto"):
-                protocol = "HTTP/%d.%d" % (request.clientproto[0], request.clientproto[1],)
-            else:
-                protocol = "HTTP/1.1"
-            iostr.write("%s %s %s\n" % (request.method, request.uri, protocol,))
-            for name, valuelist in request.headers.getAllRawHeaders():
-                for value in valuelist:
-                    # Do not log authorization details
-                    if name not in ("Authorization",):
-                        iostr.write("%s: %s\n" % (name, value))
-                    else:
-                        iostr.write("%s: xxxxxxxxx\n" % (name,))
-            iostr.write("\n")
-            
-            # We need to play a trick with the request stream as we can only read it once. So we
-            # read it, store the value in a MemoryStream, and replace the request's stream with that,
-            # so the data can be read again.
-            def _gotData(data):
-                iostr.write(data)
-                
-                request.stream = MemoryStream(data if data is not None else "")
-                request.stream.doStartReading = None
-            
-                self.emit(level, iostr.getvalue(), **kwargs)
-
-            d = allDataFromStream(request.stream)
-            d.addCallback(_gotData)
-            return d
-        
-        else:
-            return succeed(None)
-    
-    # FIXME: This doesn't belong here
-    def logResponse(self, level, message, response, **kwargs):
-        """
-        Log an HTTP request.
-        """
-
-        assert level in logLevels
-
-        if self.willLogAtLevel(level):
-            iostr = StringIO()
-            iostr.write("%s\n" % (message,))
-            code_message = responsecode.RESPONSES.get(response.code, "Unknown Status")
-            iostr.write("HTTP/1.1 %s %s\n" % (response.code, code_message,))
-            for name, valuelist in response.headers.getAllRawHeaders():
-                for value in valuelist:
-                    # Do not log authorization details
-                    if name not in ("WWW-Authenticate",):
-                        iostr.write("%s: %s\n" % (name, value))
-                    else:
-                        iostr.write("%s: xxxxxxxxx\n" % (name,))
-            iostr.write("\n")
-            
-            # We need to play a trick with the response stream to ensure we don't mess it up. So we
-            # read it, store the value in a MemoryStream, and replace the response's stream with that,
-            # so the data can be read again.
-            def _gotData(data):
-                iostr.write(data)
-                
-                response.stream = MemoryStream(data if data is not None else "")
-                response.stream.doStartReading = None
-            
-                self.emit(level, iostr.getvalue(), **kwargs)
-                
-            d = allDataFromStream(response.stream)
-            d.addCallback(_gotData)
-            return d
-
-class LoggingMixIn (object):
-    """
-    Mix-in class for logging methods.
-    """
-    def _getLogger(self):
-        try:
-            return self._logger
-        except AttributeError:
-            self._logger = Logger(
-                "%s.%s" % (
-                    self.__class__.__module__,
-                    self.__class__.__name__,
-                )
-            )
-
-        return self._logger
-
-    def _setLogger(self, value):
-        self._logger = value
-
-    logger = property(_getLogger, _setLogger)
-
-for level in logLevels:
-    doc = """
-    Emit a log message at log level C{%s}.
-    @param message: The message to emit.
-    """ % (level,)
-
-    #
-    # Attach methods to Logger
-    #
-    def log_emit(self, message, __level__=level, raiseException=None, **kwargs):
-        self.emit(__level__, message, **kwargs)
-        if raiseException:
-            raise raiseException(message)
-
-    def will_emit(self, __level__=level):
-        return self.willLogAtLevel(__level__)
-
-    log_emit.__doc__ = doc
-
-    setattr(Logger, level, log_emit)
-    setattr(Logger, level + "_enabled", property(will_emit))
-
-    del log_emit
-    del will_emit
-
-    #
-    # Attach methods to LoggingMixIn
-    #
-    def log_emit(self, message, __level__=level, raiseException=None, **kwargs):
-        self.logger.emit(__level__, message, **kwargs)
-        if raiseException:
-            raise raiseException(message)
-
-    def will_emit(self=log_emit, __level__=level):
-        return self.logger.willLogAtLevel(__level__)
-
-    log_emit.__doc__ = doc
-    log_emit.enabled = will_emit
-
-    setattr(LoggingMixIn, "log_" + level, log_emit)
-    setattr(LoggingMixIn, "log_" + level + "_enabled", property(will_emit))
-
-    del log_emit
-    del will_emit
-
-del level
-
-# Add some compatibility with twisted's log module
-Logger.msg = Logger.info
-Logger.err = Logger.error
-
-##
-# Errors
-##
-
-class InvalidLogLevelError (RuntimeError):
-    def __init__(self, level):
-        super(InvalidLogLevelError, self).__init__(str(level))
-        self.level = level

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/mail.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/mail.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/mail.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -20,16 +20,25 @@
 """
 from __future__ import with_statement
 
-from calendarserver.provision.root import RootResource
+import datetime
+import email.utils
+import os
+import uuid
 
+try:
+    from cStringIO import StringIO
+except ImportError:
+    from StringIO import StringIO
+
 from email.mime.image import MIMEImage
 from email.mime.multipart import MIMEMultipart
 from email.mime.text import MIMEText
 
+from zope.interface import implements
+
 from twisted.application import internet, service
 from twisted.cred.portal import Portal
 from twisted.internet import protocol, defer, ssl, reactor
-from twisted.internet.address import IPv4Address
 from twisted.internet.defer import inlineCallbacks, returnValue, succeed
 from twisted.mail import pop3client, imap4
 from twisted.mail.smtp import messageid, rfc822date, ESMTPSenderFactory
@@ -45,6 +54,8 @@
 from twisted.web2.http import Response, HTTPError
 from twisted.web2.http_headers import MimeType
 
+from twext.log import Logger, LoggingMixIn
+
 from twistedcaldav import ical, caldavxml
 from twistedcaldav import memcachepool
 from twistedcaldav.config import config
@@ -53,7 +64,6 @@
 from twistedcaldav.directory.util import NotFilePath
 from twistedcaldav.ical import Property
 from twistedcaldav.localization import translationTo
-from twistedcaldav.log import Logger, LoggingMixIn
 from twistedcaldav.scheduling.cuaddress import normalizeCUAddr
 from twistedcaldav.scheduling.scheduler import IMIPScheduler
 from twistedcaldav.sql import AbstractSQLDatabase
@@ -63,20 +73,9 @@
 from twistedcaldav.sql import AbstractSQLDatabase
 from twistedcaldav.localization import translationTo
 
-from zope.interface import implements
+from calendarserver.provision.root import RootResource
 
-import datetime
-import email.utils
-import os
-import uuid
 
-try:
-    from cStringIO import StringIO
-except ImportError:
-    from StringIO import StringIO
-
-
-
 __all__ = [
     "IMIPInboxResource",
     "MailGatewayServiceMaker",

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/memcachepool.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/memcachepool.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/memcachepool.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -19,11 +19,9 @@
 from twisted.internet.defer import Deferred, fail
 from twisted.internet.protocol import ReconnectingClientFactory
 
+from twext.log import LoggingMixIn
 from twext.protocols.memcache import MemCacheProtocol, NoSuchCommand
 
-from twistedcaldav.log import LoggingMixIn
-
-
 class PooledMemCacheProtocol(MemCacheProtocol):
     """
     A MemCacheProtocol that will notify a connectionPool that it is ready

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/memcacheprops.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/memcacheprops.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/memcacheprops.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -34,12 +34,13 @@
 
 from memcacheclient import ClientFactory as MemcacheClientFactory, MemcacheError, TokenMismatchError
 
+from twext.log import LoggingMixIn, Logger
+
 from twisted.python.filepath import FilePath
 from twisted.web2 import responsecode
 from twisted.web2.http import HTTPError, StatusResponse
 
 from twistedcaldav.config import config
-from twistedcaldav.log import LoggingMixIn, Logger
 
 log = Logger()
 

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/memcacher.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/memcacher.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/memcacher.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -14,14 +14,16 @@
 # limitations under the License.
 ##
 
+import hashlib
+import cPickle
+import string
+
 from twisted.internet.defer import succeed
 
-from twistedcaldav.log import LoggingMixIn
+from twext.log import LoggingMixIn
+
 from twistedcaldav.memcachepool import CachePoolUserMixIn
 from twistedcaldav.config import config
-import hashlib
-import cPickle
-import string
 
 class Memcacher(LoggingMixIn, CachePoolUserMixIn):
 

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/method/copymove.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/method/copymove.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/method/copymove.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -30,6 +30,8 @@
 from twisted.web2.dav.util import parentForURL
 from twisted.web2.http import StatusResponse, HTTPError
 
+from twext.log import Logger
+
 from twistedcaldav.caldavxml import caldav_namespace
 from twistedcaldav.method.put_common import StoreCalendarObjectResource
 from twistedcaldav.method.copymove_contact import (
@@ -38,7 +40,6 @@
 
 from twistedcaldav.resource import isCalendarCollectionResource,\
     isPseudoCalendarCollectionResource
-from twistedcaldav.log import Logger
 
 CalDAVFile = None               # Pacify PyFlakes; this *should* be fixed, but
                                 # it's not actually an undefined name, as the

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/method/delete.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/method/delete.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/method/delete.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -20,6 +20,8 @@
 
 __all__ = ["http_DELETE"]
 
+from twext.log import Logger
+
 from twisted.internet.defer import inlineCallbacks, returnValue
 from twisted.web2 import responsecode
 from twisted.web2.dav import davxml
@@ -27,7 +29,6 @@
 from twisted.web2.http import HTTPError
 
 from twistedcaldav.method.delete_common import DeleteResource
-from twistedcaldav.log import Logger
 
 log = Logger()
 

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/method/delete_common.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/method/delete_common.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/method/delete_common.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -23,8 +23,6 @@
 
 __all__ = ["DeleteResource"]
 
-from twext.web2.dav.davxml import ErrorResponse
-
 from twisted.internet.defer import inlineCallbacks, returnValue
 from twisted.web2 import responsecode
 from twisted.web2.dav.fileop import delete
@@ -32,9 +30,11 @@
 from twisted.web2.dav.util import joinURL
 from twisted.web2.http import HTTPError, StatusResponse
 
+from twext.log import Logger
+from twext.web2.dav.davxml import ErrorResponse
+
 from twistedcaldav.caldavxml import caldav_namespace, ScheduleTag
 from twistedcaldav.config import config
-from twistedcaldav.log import Logger
 from twistedcaldav.memcachelock import MemcacheLock, MemcacheLockTimeoutError
 from twistedcaldav.method.report_common import applyToCalendarCollections
 from twistedcaldav.resource import isCalendarCollectionResource,\

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/method/mkcalendar.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/method/mkcalendar.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/method/mkcalendar.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -20,8 +20,6 @@
 
 __all__ = ["http_MKCALENDAR"]
 
-from twext.web2.dav.davxml import ErrorResponse
-
 from twisted.internet.defer import inlineCallbacks, returnValue
 from twisted.python.failure import Failure
 from twisted.web2 import responsecode
@@ -31,8 +29,10 @@
 from twisted.web2.dav.util import parentForURL
 from twisted.web2.http import HTTPError, StatusResponse
 
+from twext.log import Logger
+from twext.web2.dav.davxml import ErrorResponse
+
 from twistedcaldav import caldavxml
-from twistedcaldav.log import Logger
 
 log = Logger()
 

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/method/propfind.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/method/propfind.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/method/propfind.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -36,7 +36,7 @@
 from twisted.web2.dav.http import MultiStatusResponse, statusForFailure
 from twisted.web2.dav.util import normalizeURL, davXMLFromStream
 
-from twistedcaldav.log import Logger
+from twext.log import Logger
 
 log = Logger()
 

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/method/put.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/method/put.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/method/put.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -22,12 +22,14 @@
 
 from twisted.internet.defer import inlineCallbacks, returnValue
 from twisted.web2 import responsecode
-from twext.web2.dav.davxml import ErrorResponse
 from twisted.web2.dav.util import allDataFromStream, parentForURL
 from twisted.web2.http import HTTPError, StatusResponse
 
+from twext.log import Logger
+from twext.web2.dav.davxml import ErrorResponse
+
 from twistedcaldav.caldavxml import caldav_namespace
-from twistedcaldav.log import Logger
+
 from twistedcaldav.method.put_common import StoreCalendarObjectResource
 from twistedcaldav.resource import isPseudoCalendarCollectionResource
 from twistedcaldav.static import CalDAVFile

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/method/put_common.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/method/put_common.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/method/put_common.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -25,8 +25,6 @@
 import types
 import uuid
 
-from twext.web2.dav.davxml import ErrorResponse
-
 from twisted.internet import reactor
 from twisted.internet.defer import Deferred, inlineCallbacks, succeed
 from twisted.internet.defer import returnValue
@@ -46,6 +44,9 @@
 from twisted.web2.iweb import IResponse
 from twisted.web2.stream import MemoryStream
 
+from twext.log import Logger
+from twext.web2.dav.davxml import ErrorResponse
+
 from twistedcaldav.config import config
 from twistedcaldav.caldavxml import NoUIDConflict, ScheduleTag
 from twistedcaldav.caldavxml import NumberOfRecurrencesWithinLimits
@@ -61,7 +62,6 @@
 from twistedcaldav.index import ReservationError
 from twistedcaldav.instance import TooManyInstancesError,\
     InvalidOverriddenInstanceError
-from twistedcaldav.log import Logger
 from twistedcaldav.memcachelock import MemcacheLock, MemcacheLockTimeoutError
 from twistedcaldav.method.delete_common import DeleteResource
 from twistedcaldav.scheduling.implicit import ImplicitScheduler

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/method/report.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/method/report.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/method/report.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -28,8 +28,6 @@
 
 import string
 
-from twext.web2.dav.davxml import ErrorResponse
-
 from twisted.internet.defer import inlineCallbacks, returnValue
 from twisted.web2 import responsecode
 from twisted.web2.http import HTTPError, StatusResponse
@@ -37,8 +35,10 @@
 from twisted.web2.dav.element.parser import lookupElement
 from twisted.web2.dav.util import davXMLFromStream
 
+from twext.log import Logger
+from twext.web2.dav.davxml import ErrorResponse
+
 from twistedcaldav import caldavxml
-from twistedcaldav.log import Logger
 
 log = Logger()
 

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/method/report_calquery.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/method/report_calquery.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/method/report_calquery.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -22,6 +22,7 @@
 
 import urllib
 
+from twext.log import Logger
 from twext.web2.dav.davxml import ErrorResponse
 
 from twisted.internet.defer import succeed, inlineCallbacks, returnValue
@@ -38,7 +39,6 @@
 from twistedcaldav.customxml import TwistedCalendarAccessProperty
 from twistedcaldav.index import IndexedSearchException
 from twistedcaldav.instance import TooManyInstancesError
-from twistedcaldav.log import Logger
 from twistedcaldav.method import report_common
 
 log = Logger()

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/method/report_common.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/method/report_common.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/method/report_common.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -51,6 +51,8 @@
 from twisted.web2.dav.resource import AccessDeniedError
 from twisted.web2.http import HTTPError
 
+from twext.log import Logger
+
 from twistedcaldav import caldavxml
 from twistedcaldav import carddavxml
 from twistedcaldav.caldavxml import caldav_namespace
@@ -59,7 +61,6 @@
 from twistedcaldav.ical import Component, Property, iCalendarProductID
 from twistedcaldav.instance import InstanceList
 from twistedcaldav.index import IndexedSearchException
-from twistedcaldav.log import Logger
 
 log = Logger()
 

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/method/report_freebusy.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/method/report_freebusy.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/method/report_freebusy.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -20,6 +20,7 @@
 
 __all__ = ["report_urn_ietf_params_xml_ns_caldav_free_busy_query"]
 
+from twext.log import Logger
 from twext.web2.dav.davxml import ErrorResponse
 
 from twisted.internet.defer import inlineCallbacks, returnValue
@@ -32,7 +33,6 @@
 
 from twistedcaldav import caldavxml
 from twistedcaldav.method import report_common
-from twistedcaldav.log import Logger
 
 log = Logger()
 

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/method/report_multiget.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/method/report_multiget.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/method/report_multiget.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -22,6 +22,7 @@
 
 from urllib import unquote
 
+from twext.log import Logger
 from twext.web2.dav.davxml import ErrorResponse
 
 from twisted.internet.defer import inlineCallbacks, returnValue
@@ -34,7 +35,6 @@
 
 from twistedcaldav.caldavxml import caldav_namespace
 from twistedcaldav.method import report_common
-from twistedcaldav.log import Logger
 
 log = Logger()
 

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/method/report_sync_collection.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/method/report_sync_collection.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/method/report_sync_collection.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -20,6 +20,7 @@
 
 __all__ = ["report_DAV__sync_collection"]
 
+from twext.log import Logger
 from twext.web2.dav.davxml import ErrorResponse, SyncToken
 
 from twisted.internet.defer import inlineCallbacks, returnValue
@@ -34,7 +35,6 @@
 from twisted.web2.http import HTTPError
 
 from twistedcaldav.config import config
-from twistedcaldav.log import Logger
 
 import functools
 
@@ -51,7 +51,7 @@
    
     responses = []
 
-    propertyreq = sync_collection.property
+    propertyreq = sync_collection.property.children if sync_collection.property else None 
     
     @inlineCallbacks
     def _namedPropertiesForResource(request, props, resource, forbidden=False):
@@ -91,7 +91,7 @@
                 else:
                     properties_by_status[responsecode.NOT_FOUND].append(propertyName(qname))
         
-        yield properties_by_status
+        returnValue(properties_by_status)
     
     # Do some optimization of access control calculation by determining any inherited ACLs outside of
     # the child resource loop and supply those to the checkPrivileges on each child.

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/notify.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/notify.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/notify.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -34,8 +34,14 @@
 
 # TODO: add CalDAVTester test for examining new xmpp-uri property
 
+import uuid
+from fnmatch import fnmatch
+
+from zope.interface import Interface, implements
+
+from twext.log import LoggingMixIn
+
 from twisted.internet.protocol import ReconnectingClientFactory, ServerFactory
-from twisted.internet.address import IPv4Address
 from twisted.internet.ssl import ClientContextFactory
 from twisted.internet.defer import inlineCallbacks, Deferred
 from twisted.protocols.basic import LineReceiver
@@ -48,14 +54,10 @@
 from twisted.words.protocols.jabber.client import XMPPAuthenticator, IQAuthInitializer
 from twisted.words.protocols.jabber.xmlstream import IQ
 from twisted.words.xish import domish
-from twistedcaldav.log import LoggingMixIn
 from twistedcaldav.config import config
 from twistedcaldav.memcacher import Memcacher
 from twistedcaldav.stdconfig import DEFAULT_CONFIG, DEFAULT_CONFIG_FILE
 from twistedcaldav import memcachepool
-from zope.interface import Interface, implements
-from fnmatch import fnmatch
-import uuid
 
 __all__ = [
     "ClientNotifier",

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/partitions.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/partitions.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/partitions.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -14,9 +14,10 @@
 # limitations under the License.
 ##
 
+from twext.log import Logger
 from twext.python.plistlib import readPlist
+
 from twistedcaldav.client.pool import installPool
-from twistedcaldav.log import Logger
 
 """
 Collection of classes for managing partition information for a group of servers.

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/pdmonster.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/pdmonster.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/pdmonster.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -4,7 +4,7 @@
 
 from twisted.web2.resource import WrapperResource
 
-from twistedcaldav.log import LoggingMixIn
+from twext.log import LoggingMixIn
 
 class PDClientAddressWrapper(WrapperResource, LoggingMixIn):
     def __init__(self, resource, socket, directory):

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/resource.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/resource.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/resource.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -31,9 +31,11 @@
 ]
 
 import urllib
+from urlparse import urlsplit
 
 from zope.interface import implements
 
+from twext.log import LoggingMixIn
 from twext.web2.dav.davxml import ErrorResponse, SyncCollection
 
 from twisted.internet import reactor
@@ -66,14 +68,8 @@
 from twistedcaldav.ical import Component as iComponent
 from twistedcaldav.ical import allowedComponents
 from twistedcaldav.icaldav import ICalDAVResource, ICalendarPrincipalResource
-from twistedcaldav.caldavxml import caldav_namespace
-from twistedcaldav.customxml import calendarserver_namespace
-from twistedcaldav.ical import allowedComponents
-from twistedcaldav.ical import Component as iComponent
 from twistedcaldav.vcard import Component as vComponent
-from twistedcaldav.log import LoggingMixIn
 
-from urlparse import urlsplit
 
 if twistedcaldav.__version__:
     serverVersion = twisted.web2.server.VERSION + " TwistedCardDAV/" + twistedcaldav.__version__

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/scheduling/addressmapping.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/scheduling/addressmapping.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/scheduling/addressmapping.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -14,8 +14,11 @@
 # limitations under the License.
 ##
 
+from twisted.internet.defer import inlineCallbacks, returnValue
+
+from twext.log import Logger
+
 from twistedcaldav.config import config
-from twistedcaldav.log import Logger
 from twistedcaldav.memcacher import Memcacher
 from twistedcaldav.scheduling.caldav import ScheduleViaCalDAV
 from twistedcaldav.scheduling.delivery import DeliveryService
@@ -24,7 +27,6 @@
 from twistedcaldav.scheduling.cuaddress import LocalCalendarUser,\
     RemoteCalendarUser, EmailCalendarUser, InvalidCalendarUser,\
     PartitionedCalendarUser
-from twisted.internet.defer import inlineCallbacks, returnValue
 
 __all__ = [
     "ScheduleAddressMapper",

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/scheduling/caldav.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/scheduling/caldav.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/scheduling/caldav.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -21,6 +21,7 @@
 except ImportError:
     from md5 import new as md5
 
+from twext.log import Logger
 from twext.web2.dav.davxml import ErrorResponse
 
 from twisted.internet.defer import inlineCallbacks, returnValue
@@ -35,7 +36,6 @@
 from twistedcaldav.caldavxml import caldav_namespace
 from twistedcaldav.config import config
 from twistedcaldav.customxml import calendarserver_namespace
-from twistedcaldav.log import Logger
 from twistedcaldav.method import report_common
 from twistedcaldav.resource import isCalendarCollectionResource
 from twistedcaldav.scheduling.cuaddress import LocalCalendarUser, RemoteCalendarUser,\

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/scheduling/cuaddress.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/scheduling/cuaddress.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/scheduling/cuaddress.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -14,7 +14,8 @@
 # limitations under the License.
 ##
 
-from twistedcaldav.log import Logger
+from twext.log import Logger
+
 from twistedcaldav.scheduling.delivery import DeliveryService
 
 __all__ = [

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/scheduling/delivery.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/scheduling/delivery.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/scheduling/delivery.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -14,11 +14,12 @@
 # limitations under the License.
 ##
 
+import re
+
+from twext.log import Logger
+
 from twistedcaldav.config import config
-from twistedcaldav.log import Logger
 
-import re
-
 __all__ = [
     "DeliveryService",
 ]

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/scheduling/icaldiff.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/scheduling/icaldiff.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/scheduling/icaldiff.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -14,11 +14,12 @@
 # limitations under the License.
 ##
 
+from twext.log import Logger
+
 from twistedcaldav.config import config
 from twistedcaldav.dateops import normalizeToUTC, toString,\
     normalizeStartEndDuration
 from twistedcaldav.ical import Component, Property
-from twistedcaldav.log import Logger
 from twistedcaldav.scheduling.cuaddress import normalizeCUAddr
 from twistedcaldav.scheduling.itip import iTipGenerator
 from twistedcaldav import accounting

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/scheduling/imip.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/scheduling/imip.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/scheduling/imip.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -14,10 +14,10 @@
 # limitations under the License.
 ##
 
+from twisted.python.failure import Failure
 from twisted.internet.defer import inlineCallbacks, returnValue
 
-from twisted.python.failure import Failure
-
+from twext.log import Logger
 from twext.web2.dav.davxml import ErrorResponse
 
 from twisted.web2 import responsecode
@@ -26,7 +26,6 @@
 
 from twistedcaldav.caldavxml import caldav_namespace
 from twistedcaldav.config import config
-from twistedcaldav.log import Logger
 from twistedcaldav.util import AuthorizedHTTPGetter
 from twistedcaldav.scheduling.delivery import DeliveryService
 from twistedcaldav.scheduling.itip import iTIPRequestStatus

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/scheduling/implicit.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/scheduling/implicit.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/scheduling/implicit.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -14,6 +14,7 @@
 # limitations under the License.
 ##
 
+from twext.log import Logger
 from twext.web2.dav.davxml import ErrorResponse
 
 from twisted.internet.defer import inlineCallbacks, returnValue
@@ -28,7 +29,6 @@
 from twistedcaldav.customxml import TwistedSchedulingObjectResource
 from twistedcaldav.directory.principal import DirectoryCalendarPrincipalResource
 from twistedcaldav.ical import Property
-from twistedcaldav.log import Logger
 from twistedcaldav.method import report_common
 from twistedcaldav.scheduling import addressmapping
 from twistedcaldav.scheduling.cuaddress import InvalidCalendarUser,\

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/scheduling/ischedule.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/scheduling/ischedule.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/scheduling/ischedule.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -14,9 +14,9 @@
 # limitations under the License.
 ##
 
-from twext.web2.dav.davxml import ErrorResponse
+from StringIO import StringIO
 
-from twisted.internet.defer import inlineCallbacks, DeferredList
+from twisted.internet.defer import inlineCallbacks, DeferredList, succeed
 from twisted.internet.protocol import ClientCreator
 
 from twisted.python.failure import Failure
@@ -24,24 +24,26 @@
 from twisted.web2 import responsecode
 from twisted.web2.client.http import ClientRequest
 from twisted.web2.client.http import HTTPClientProtocol
-from twisted.web2.dav.util import davXMLFromStream, joinURL
+from twisted.web2.dav.util import davXMLFromStream, joinURL, allDataFromStream
 from twisted.web2.http import HTTPError
 from twisted.web2.http_headers import Headers
 from twisted.web2.http_headers import MimeType
+from twisted.web2.stream import MemoryStream
 
+from twext.log import Logger, logLevels
 from twext.internet.ssl import ChainingOpenSSLContextFactory
+from twext.web2.dav.davxml import ErrorResponse
 
 from twistedcaldav import caldavxml
 from twistedcaldav.caldavxml import caldav_namespace
 from twistedcaldav.config import config
-from twistedcaldav.log import Logger
 from twistedcaldav.scheduling.delivery import DeliveryService
-from twistedcaldav.scheduling.ischeduleservers import IScheduleServers,\
-    IScheduleServerRecord
+from twistedcaldav.scheduling.ischeduleservers import IScheduleServers
+from twistedcaldav.scheduling.ischeduleservers import IScheduleServerRecord
 from twistedcaldav.scheduling.itip import iTIPRequestStatus
 from twistedcaldav.util import utf8String
-from twistedcaldav.scheduling.cuaddress import RemoteCalendarUser,\
-    PartitionedCalendarUser
+from twistedcaldav.scheduling.cuaddress import RemoteCalendarUser
+from twistedcaldav.scheduling.cuaddress import PartitionedCalendarUser
 
 import OpenSSL
 
@@ -170,6 +172,83 @@
                 err = HTTPError(ErrorResponse(responsecode.FORBIDDEN, (caldav_namespace, "recipient-failed")))
                 self.responses.add(recipient.cuaddr, Failure(exc_value=err), reqstatus=iTIPRequestStatus.SERVICE_UNAVAILABLE)
 
+    def logRequest(self, level, message, request, **kwargs):
+        """
+        Log an HTTP request.
+        """
+
+        assert level in logLevels
+
+        if self.willLogAtLevel(level):
+            iostr = StringIO()
+            iostr.write("%s\n" % (message,))
+            if hasattr(request, "clientproto"):
+                protocol = "HTTP/%d.%d" % (request.clientproto[0], request.clientproto[1],)
+            else:
+                protocol = "HTTP/1.1"
+            iostr.write("%s %s %s\n" % (request.method, request.uri, protocol,))
+            for name, valuelist in request.headers.getAllRawHeaders():
+                for value in valuelist:
+                    # Do not log authorization details
+                    if name not in ("Authorization",):
+                        iostr.write("%s: %s\n" % (name, value))
+                    else:
+                        iostr.write("%s: xxxxxxxxx\n" % (name,))
+            iostr.write("\n")
+            
+            # We need to play a trick with the request stream as we can only read it once. So we
+            # read it, store the value in a MemoryStream, and replace the request's stream with that,
+            # so the data can be read again.
+            def _gotData(data):
+                iostr.write(data)
+                
+                request.stream = MemoryStream(data if data is not None else "")
+                request.stream.doStartReading = None
+            
+                self.emit(level, iostr.getvalue(), **kwargs)
+
+            d = allDataFromStream(request.stream)
+            d.addCallback(_gotData)
+            return d
+        
+        else:
+            return succeed(None)
+    
+    def logResponse(self, level, message, response, **kwargs):
+        """
+        Log an HTTP request.
+        """
+        assert level in logLevels
+
+        if self.willLogAtLevel(level):
+            iostr = StringIO()
+            iostr.write("%s\n" % (message,))
+            code_message = responsecode.RESPONSES.get(response.code, "Unknown Status")
+            iostr.write("HTTP/1.1 %s %s\n" % (response.code, code_message,))
+            for name, valuelist in response.headers.getAllRawHeaders():
+                for value in valuelist:
+                    # Do not log authorization details
+                    if name not in ("WWW-Authenticate",):
+                        iostr.write("%s: %s\n" % (name, value))
+                    else:
+                        iostr.write("%s: xxxxxxxxx\n" % (name,))
+            iostr.write("\n")
+            
+            # We need to play a trick with the response stream to ensure we don't mess it up. So we
+            # read it, store the value in a MemoryStream, and replace the response's stream with that,
+            # so the data can be read again.
+            def _gotData(data):
+                iostr.write(data)
+                
+                response.stream = MemoryStream(data if data is not None else "")
+                response.stream.doStartReading = None
+            
+                self.emit(level, iostr.getvalue(), **kwargs)
+                
+            d = allDataFromStream(response.stream)
+            d.addCallback(_gotData)
+            return d
+
     def _generateHeaders(self):
         self.headers = Headers()
         self.headers.setHeader('Host', utf8String(self.server.host + ":%s" % (self.server.port,)))

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/scheduling/ischeduleservers.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/scheduling/ischeduleservers.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/scheduling/ischeduleservers.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -16,8 +16,9 @@
 
 from twisted.python.filepath import FilePath
 
+from twext.log import Logger
+
 from twistedcaldav.config import config
-from twistedcaldav.log import Logger
 from twistedcaldav.scheduling.delivery import DeliveryService
 
 import xml.dom.minidom

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/scheduling/itip.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/scheduling/itip.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/scheduling/itip.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -32,14 +32,15 @@
 
 import datetime
 
+from vobject.icalendar import utc
+from vobject.icalendar import dateTimeToString
+
+from twext.log import Logger
+
 from twistedcaldav.config import config
 from twistedcaldav.dateops import normalizeToUTC, toString
-from twistedcaldav.log import Logger
 from twistedcaldav.ical import Property, iCalendarProductID, Component
 
-from vobject.icalendar import utc
-from vobject.icalendar import dateTimeToString
-
 log = Logger()
 
 __version__ = "0.0"

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/scheduling/processing.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/scheduling/processing.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/scheduling/processing.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -14,7 +14,14 @@
 # limitations under the License.
 ##
 
+import datetime
+import time
 from hashlib import md5
+
+from vobject.icalendar import utc
+
+from twext.log import Logger
+
 from twisted.internet import reactor
 from twisted.internet.defer import inlineCallbacks, returnValue
 from twisted.web2.dav.method.report import NumberOfMatchesWithinLimits
@@ -24,15 +31,11 @@
 from twistedcaldav.caldavxml import caldav_namespace
 from twistedcaldav.ical import Property
 from twistedcaldav.instance import InvalidOverriddenInstanceError
-from twistedcaldav.log import Logger
 from twistedcaldav.method import report_common
 from twistedcaldav.scheduling.cuaddress import normalizeCUAddr
 from twistedcaldav.scheduling.itip import iTipProcessing, iTIPRequestStatus
 from twistedcaldav.scheduling.utils import getCalendarObjectForPrincipals
-from vobject.icalendar import utc
 from twistedcaldav.memcachelock import MemcacheLock, MemcacheLockTimeoutError
-import datetime
-import time
 
 __all__ = [
     "ImplicitProcessor",

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/scheduling/scheduler.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/scheduling/scheduler.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/scheduling/scheduler.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -14,12 +14,11 @@
 # limitations under the License.
 ##
 
+from twext.log import Logger, LoggingMixIn
 from twext.web2.dav.davxml import ErrorResponse
 
 from twisted.internet.defer import inlineCallbacks, returnValue
-
 from twisted.python.failure import Failure
-
 from twisted.web2 import responsecode
 from twisted.web2.dav import davxml
 from twisted.web2.dav.http import errorForFailure, messageForFailure, statusForFailure
@@ -32,7 +31,6 @@
 from twistedcaldav.config import config
 from twistedcaldav.customxml import calendarserver_namespace
 from twistedcaldav.ical import Component
-from twistedcaldav.log import Logger, LoggingMixIn
 from twistedcaldav.scheduling import addressmapping
 from twistedcaldav.scheduling.caldav import ScheduleViaCalDAV
 from twistedcaldav.scheduling.cuaddress import InvalidCalendarUser,\

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/sql.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/sql.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/sql.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -31,7 +31,7 @@
 except ImportError:
     from pysqlite2 import dbapi2 as sqlite
 
-from twistedcaldav.log import Logger
+from twext.log import Logger
 
 log = Logger()
 

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/static.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/static.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/static.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -44,6 +44,7 @@
 from urlparse import urlsplit
 from uuid import uuid4
 
+from twext.log import Logger
 from twext.web2.dav.davxml import ErrorResponse
 
 from twisted.internet.defer import fail, succeed, inlineCallbacks, returnValue, maybeDeferred
@@ -90,7 +91,6 @@
 from twistedcaldav.directory.calendar import DirectoryCalendarHomeUIDProvisioningResource
 from twistedcaldav.directory.calendar import DirectoryCalendarHomeResource
 from twistedcaldav.directory.resource import AutoProvisioningResourceMixIn
-from twistedcaldav.log import Logger
 from twistedcaldav.timezoneservice import TimezoneServiceResource
 from twistedcaldav.vcardindex import AddressBookIndex
 from twistedcaldav.cache import DisabledCacheNotifier, PropfindCacheMixin

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/stdconfig.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/stdconfig.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/stdconfig.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -23,14 +23,14 @@
 from twisted.web2.dav.resource import TwistedACLInheritable
 
 from twext.python.plistlib import PlistParser
+from twext.log import Logger, InvalidLogLevelError
+from twext.log import clearLogLevels, setLogLevelForNamespace
 
-from twistedcaldav.config import (
-    ConfigProvider, ConfigurationError, config, _mergeData, )
-from twistedcaldav.log import (
-    Logger, clearLogLevels, setLogLevelForNamespace, InvalidLogLevelError, )
+from twistedcaldav.config import ConfigProvider, ConfigurationError
+from twistedcaldav.config import config, _mergeData
 from twistedcaldav.partitions import partitions
-from twistedcaldav.util import (
-    KeychainAccessError, KeychainPasswordNotFound, getPasswordFromKeychain, )
+from twistedcaldav.util import getPasswordFromKeychain
+from twistedcaldav.util import KeychainAccessError, KeychainPasswordNotFound
 
 log = Logger()
 

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/test/test_config.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/test/test_config.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/test/test_config.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -15,8 +15,8 @@
 ##
 
 from twext.python.plistlib import writePlist
+from twext.log import logLevelForNamespace
 
-from twistedcaldav.log import logLevelForNamespace
 from twistedcaldav.config import config, ConfigDict
 from twistedcaldav.static import CalDAVFile
 from twistedcaldav.stdconfig import DEFAULT_CONFIG, PListConfigProvider

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/test/test_log.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/test/test_log.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/test/test_log.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -18,7 +18,8 @@
 
 from twisted.python import log as twistedLogging
 
-from twistedcaldav.log import *
+from twext.log import *
+
 from twistedcaldav.test.util import TestCase
 
 defaultLogLevel = logLevelsByNamespace[None]

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/test/test_upgrade.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/test/test_upgrade.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/test/test_upgrade.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -35,6 +35,7 @@
 
 
 class ProxyDBUpgradeTests(TestCase):
+    todo = "upgrade.py needs to be fixed"
     
     def setUpXMLDirectory(self):
         xmlFile = os.path.join(os.path.dirname(os.path.dirname(__file__)),
@@ -1190,9 +1191,9 @@
         upgradeData(config)
         self.assertTrue(self.verifyHierarchy(root, after))
 
-        calendarUserProxyDatabase = CalendarUserProxyDatabase(root)
-        resourceInfoDatabase = ResourceInfoDatabase(root)
-
+#        calendarUserProxyDatabase = CalendarUserProxyDatabase(root)
+#        resourceInfoDatabase = ResourceInfoDatabase(root)
+#
 #        for guid, info in assignments.iteritems():
 #
 #            proxyGroup = "%s#calendar-proxy-write" % (guid,)

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/timezones.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/timezones.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/timezones.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -20,8 +20,9 @@
 from vobject.icalendar import getTzid
 from vobject.icalendar import registerTzid
 
+from twext.log import Logger
+
 from twistedcaldav.ical import Component
-from twistedcaldav.log import Logger
 
 log = Logger()
 

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/upgrade.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/upgrade.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/upgrade.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -17,20 +17,23 @@
 
 from __future__ import with_statement
 
+import xattr, os, zlib, hashlib, datetime, pwd, grp, shutil
+from zlib import compress
+from cPickle import loads as unpickle, UnpicklingError
+
 from twisted.web2.dav.fileop import rmdir
 from twisted.web2.dav import davxml
+
+from twext.log import Logger
+
 from twistedcaldav.directory.directory import DirectoryService
-from twistedcaldav.directory.resourceinfo import ResourceInfoDatabase
+#from twistedcaldav.directory.resourceinfo import ResourceInfoDatabase
 from twistedcaldav.mail import MailGatewayTokensDatabase
-from twistedcaldav.log import Logger
 from twistedcaldav.ical import Component
 from twistedcaldav import caldavxml
+
 from calendarserver.tools.util import getDirectory
-import xattr, os, zlib, hashlib, datetime, pwd, grp, shutil
-from zlib import compress
-from cPickle import loads as unpickle, UnpicklingError
 
-
 log = Logger()
 
 def getCalendarServerIDs(config):

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/util.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/util.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/twistedcaldav/util.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -17,14 +17,15 @@
 import os
 import re
 import sys
+import base64
+
 from subprocess import Popen, PIPE, STDOUT
+from hashlib import md5, sha1
 
 from twisted.internet import ssl, reactor
 from twisted.web import client
-from twistedcaldav.log import LoggingMixIn
 from twisted.python import failure
-from hashlib import md5, sha1
-import base64
+from twext.log import LoggingMixIn
 
 ##
 # getNCPU

Deleted: CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/__init__.py
===================================================================
--- CalendarServer/trunk/txcaldav/calendarstore/__init__.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/__init__.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -1,19 +0,0 @@
-##
-# Copyright (c) 2010 Apple Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-##
-
-"""
-Calendar stores.
-"""

Copied: CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/__init__.py (from rev 5005, CalendarServer/trunk/txcaldav/calendarstore/__init__.py)
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/__init__.py	                        (rev 0)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/__init__.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -0,0 +1,19 @@
+##
+# Copyright (c) 2010 Apple Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##
+
+"""
+Calendar stores.
+"""

Deleted: CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/file.py
===================================================================
--- CalendarServer/trunk/txcaldav/calendarstore/file.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/file.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -1,245 +0,0 @@
-##
-# Copyright (c) 2010 Apple Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-##
-
-"""
-File calendar store.
-"""
-
-__all__ = [
-    "CalendarStore",
-    "CalendarHome",
-    "Calendar",
-    "CalendarObject",
-]
-
-import errno
-
-from zope.interface import implements
-
-from twisted.python.filepath import FilePath
-
-from twext.log import LoggingMixIn
-from twext.python.icalendar import Component as iComponent, InvalidICalendarDataError
-
-from txcaldav.icalendarstore import ICalendarHome, ICalendar, ICalendarObject
-#from txcaldav.icalendarstore import CalendarStoreError
-#from txcaldav.icalendarstore import AlreadyExistsError
-#from txcaldav.icalendarstore import CalendarAlreadyExistsError
-#from txcaldav.icalendarstore import CalendarObjectNameAlreadyExistsError
-#from txcaldav.icalendarstore import CalendarObjectUIDAlreadyExistsError
-from txcaldav.icalendarstore import NotFoundError
-#from txcaldav.icalendarstore import NoSuchCalendarError
-from txcaldav.icalendarstore import NoSuchCalendarObjectError
-#from txcaldav.icalendarstore import InvalidCalendarComponentError
-from txcaldav.icalendarstore import InternalDataStoreError
-
-
-class CalendarStore(LoggingMixIn):
-    # FIXME: Do we need an interface?
-
-    calendarHomeClass = property(lambda _: CalendarHome)
-
-    def __init__(self, path):
-        """
-        @param path: a L{FilePath}
-        """
-        assert isinstance(path, FilePath)
-
-        self.path = path
-
-        if not path.isdir():
-            # FIXME: If we add a CalendarStore interface, this should
-            # be CalendarStoreNotFoundError.
-            raise NotFoundError("No such calendar store")
-
-    def __str__(self):
-        return "<%s: %s>" % (self.__class__, self.path)
-
-    def calendarHomeWithUID(self, uid):
-        return CalendarHome(self.path.child(uid), self)
-
-
-class CalendarHome(LoggingMixIn):
-    implements(ICalendarHome)
-
-    calendarClass = property(lambda _: Calendar)
-
-    def __init__(self, path, calendarStore):
-        self.path = path
-        self.calendarStore = calendarStore
-
-    def __str__(self):
-        return "<%s: %s>" % (self.__class__, self.path)
-
-    def uid(self):
-        return self.path.basename()
-
-    def calendars(self):
-        return (
-            self.calendarWithName(name)
-            for name in self.path.listdir()
-            if not name.startswith(".")
-        )
-
-    def calendarWithName(self, name):
-        return Calendar(self.path.child(name), self)
-
-    def createCalendarWithName(self, name):
-        raise NotImplementedError()
-
-    def removeCalendarWithName(self, name):
-        raise NotImplementedError()
-
-    def properties(self):
-        raise NotImplementedError()
-
-
-class Calendar(LoggingMixIn):
-    implements(ICalendar)
-
-    calendarObjectClass = property(lambda _: CalendarObject)
-
-    def __init__(self, path, calendarHome):
-        self.path = path
-        self.calendarHome = calendarHome
-
-    def __str__(self):
-        return "<%s: %s>" % (self.__class__, self.path)
-
-    def name(self):
-        return self.path.basename()
-
-    def ownerCalendarHome(self):
-        return self.calendarHome
-
-    def calendarObjects(self):
-        return (
-            self.calendarObjectWithName(name)
-            for name in self.path.listdir()
-            if not name.startswith(".")
-        )
-
-    def calendarObjectWithName(self, name):
-        return CalendarObject(self.path.child(name), self)
-
-    def calendarObjectWithUID(self, uid):
-        raise NotImplementedError()
-
-    def createCalendarObjectWithName(self, name, component):
-        raise NotImplementedError()
-
-    def removeCalendarObjectWithName(self, name):
-        raise NotImplementedError()
-
-    def removeCalendarObjectWithUID(self, uid):
-        raise NotImplementedError()
-
-    def syncToken(self):
-        raise NotImplementedError()
-
-    def calendarObjectsInTimeRange(self, start, end, timeZone):
-        raise NotImplementedError()
-
-    def calendarObjectsSinceToken(self, token):
-        raise NotImplementedError()
-
-    def properties(self):
-        raise NotImplementedError()
-
-
-class CalendarObject(LoggingMixIn):
-    implements(ICalendarObject)
-
-    def __init__(self, path, calendar):
-        self.path = path
-        self.calendar = calendar
-
-    def __str__(self):
-        return "<%s: %s>" % (self.__class__, self.path)
-
-    def name(self):
-        return self.path.basename()
-
-    def setComponent(self, component):
-        raise NotImplementedError()
-
-    def component(self):
-        if not hasattr(self, "_component"):
-            text = self.iCalendarText()
-
-            try:
-                component = iComponent.fromString(text)
-            except InvalidICalendarDataError, e:
-                raise InternalDataStoreError(
-                    "File corruption detected (%s) in file: %s"
-                    % (e, self.path.path)
-                )
-
-            del self._text
-            self._component = component
-
-        return self._component
-
-    def iCalendarText(self):
-        #
-        # Note I'm making an assumption here that caching both is
-        # redundant, so we're caching the text if it's asked for and
-        # we don't have the component cached, then tossing it and
-        # relying on the component if we have that cached. -wsv
-        #
-        if not hasattr(self, "_text"):
-            if hasattr(self, "_component"):
-                return str(self._component)
-
-            try:
-                fh = self.path.open()
-            except IOError, e:
-                if e[0] == errno.ENOENT:
-                    raise NoSuchCalendarObjectError(self)
-
-            try:
-                text = fh.read()
-            finally:
-                fh.close()
-
-            if not (
-                text.startswith("BEGIN:VCALENDAR\r\n") or
-                text.endswith("\r\nEND:VCALENDAR\r\n")
-            ):
-                raise InternalDataStoreError(
-                    "File corruption detected (improper start) in file: %s"
-                    % (self.path.path,)
-                )
-
-            self._text = text
-
-        return self._text
-
-    def uid(self):
-        if not hasattr(self, "_uid"):
-            self._uid = self.component().resourceUID()
-        return self._uid
-
-    def componentType(self):
-        if not hasattr(self, "_componentType"):
-            self._componentType = self.component().mainType()
-        return self._componentType
-
-    def organizer(self):
-        return self.component().getOrganizer()
-
-    def properties(self):
-        raise NotImplementedError()

Copied: CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/file.py (from rev 5005, CalendarServer/trunk/txcaldav/calendarstore/file.py)
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/file.py	                        (rev 0)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/file.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -0,0 +1,245 @@
+##
+# Copyright (c) 2010 Apple Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##
+
+"""
+File calendar store.
+"""
+
+__all__ = [
+    "CalendarStore",
+    "CalendarHome",
+    "Calendar",
+    "CalendarObject",
+]
+
+import errno
+
+from zope.interface import implements
+
+from twisted.python.filepath import FilePath
+
+from twext.log import LoggingMixIn
+from twext.python.icalendar import Component as iComponent, InvalidICalendarDataError
+
+from txcaldav.icalendarstore import ICalendarHome, ICalendar, ICalendarObject
+#from txcaldav.icalendarstore import CalendarStoreError
+#from txcaldav.icalendarstore import AlreadyExistsError
+#from txcaldav.icalendarstore import CalendarAlreadyExistsError
+#from txcaldav.icalendarstore import CalendarObjectNameAlreadyExistsError
+#from txcaldav.icalendarstore import CalendarObjectUIDAlreadyExistsError
+from txcaldav.icalendarstore import NotFoundError
+#from txcaldav.icalendarstore import NoSuchCalendarError
+from txcaldav.icalendarstore import NoSuchCalendarObjectError
+#from txcaldav.icalendarstore import InvalidCalendarComponentError
+from txcaldav.icalendarstore import InternalDataStoreError
+
+
+class CalendarStore(LoggingMixIn):
+    # FIXME: Do we need an interface?
+
+    calendarHomeClass = property(lambda _: CalendarHome)
+
+    def __init__(self, path):
+        """
+        @param path: a L{FilePath}
+        """
+        assert isinstance(path, FilePath)
+
+        self.path = path
+
+        if not path.isdir():
+            # FIXME: If we add a CalendarStore interface, this should
+            # be CalendarStoreNotFoundError.
+            raise NotFoundError("No such calendar store")
+
+    def __str__(self):
+        return "<%s: %s>" % (self.__class__, self.path)
+
+    def calendarHomeWithUID(self, uid):
+        return CalendarHome(self.path.child(uid), self)
+
+
+class CalendarHome(LoggingMixIn):
+    implements(ICalendarHome)
+
+    calendarClass = property(lambda _: Calendar)
+
+    def __init__(self, path, calendarStore):
+        self.path = path
+        self.calendarStore = calendarStore
+
+    def __str__(self):
+        return "<%s: %s>" % (self.__class__, self.path)
+
+    def uid(self):
+        return self.path.basename()
+
+    def calendars(self):
+        return (
+            self.calendarWithName(name)
+            for name in self.path.listdir()
+            if not name.startswith(".")
+        )
+
+    def calendarWithName(self, name):
+        return Calendar(self.path.child(name), self)
+
+    def createCalendarWithName(self, name):
+        raise NotImplementedError()
+
+    def removeCalendarWithName(self, name):
+        raise NotImplementedError()
+
+    def properties(self):
+        raise NotImplementedError()
+
+
+class Calendar(LoggingMixIn):
+    implements(ICalendar)
+
+    calendarObjectClass = property(lambda _: CalendarObject)
+
+    def __init__(self, path, calendarHome):
+        self.path = path
+        self.calendarHome = calendarHome
+
+    def __str__(self):
+        return "<%s: %s>" % (self.__class__, self.path)
+
+    def name(self):
+        return self.path.basename()
+
+    def ownerCalendarHome(self):
+        return self.calendarHome
+
+    def calendarObjects(self):
+        return (
+            self.calendarObjectWithName(name)
+            for name in self.path.listdir()
+            if not name.startswith(".")
+        )
+
+    def calendarObjectWithName(self, name):
+        return CalendarObject(self.path.child(name), self)
+
+    def calendarObjectWithUID(self, uid):
+        raise NotImplementedError()
+
+    def createCalendarObjectWithName(self, name, component):
+        raise NotImplementedError()
+
+    def removeCalendarObjectWithName(self, name):
+        raise NotImplementedError()
+
+    def removeCalendarObjectWithUID(self, uid):
+        raise NotImplementedError()
+
+    def syncToken(self):
+        raise NotImplementedError()
+
+    def calendarObjectsInTimeRange(self, start, end, timeZone):
+        raise NotImplementedError()
+
+    def calendarObjectsSinceToken(self, token):
+        raise NotImplementedError()
+
+    def properties(self):
+        raise NotImplementedError()
+
+
+class CalendarObject(LoggingMixIn):
+    implements(ICalendarObject)
+
+    def __init__(self, path, calendar):
+        self.path = path
+        self.calendar = calendar
+
+    def __str__(self):
+        return "<%s: %s>" % (self.__class__, self.path)
+
+    def name(self):
+        return self.path.basename()
+
+    def setComponent(self, component):
+        raise NotImplementedError()
+
+    def component(self):
+        if not hasattr(self, "_component"):
+            text = self.iCalendarText()
+
+            try:
+                component = iComponent.fromString(text)
+            except InvalidICalendarDataError, e:
+                raise InternalDataStoreError(
+                    "File corruption detected (%s) in file: %s"
+                    % (e, self.path.path)
+                )
+
+            del self._text
+            self._component = component
+
+        return self._component
+
+    def iCalendarText(self):
+        #
+        # Note I'm making an assumption here that caching both is
+        # redundant, so we're caching the text if it's asked for and
+        # we don't have the component cached, then tossing it and
+        # relying on the component if we have that cached. -wsv
+        #
+        if not hasattr(self, "_text"):
+            if hasattr(self, "_component"):
+                return str(self._component)
+
+            try:
+                fh = self.path.open()
+            except IOError, e:
+                if e[0] == errno.ENOENT:
+                    raise NoSuchCalendarObjectError(self)
+
+            try:
+                text = fh.read()
+            finally:
+                fh.close()
+
+            if not (
+                text.startswith("BEGIN:VCALENDAR\r\n") or
+                text.endswith("\r\nEND:VCALENDAR\r\n")
+            ):
+                raise InternalDataStoreError(
+                    "File corruption detected (improper start) in file: %s"
+                    % (self.path.path,)
+                )
+
+            self._text = text
+
+        return self._text
+
+    def uid(self):
+        if not hasattr(self, "_uid"):
+            self._uid = self.component().resourceUID()
+        return self._uid
+
+    def componentType(self):
+        if not hasattr(self, "_componentType"):
+            self._componentType = self.component().mainType()
+        return self._componentType
+
+    def organizer(self):
+        return self.component().getOrganizer()
+
+    def properties(self):
+        raise NotImplementedError()

Deleted: CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/__init__.py
===================================================================
--- CalendarServer/trunk/txcaldav/calendarstore/test/__init__.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/__init__.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -1,19 +0,0 @@
-##
-# Copyright (c) 2010 Apple Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-##
-
-"""
-Calendar store tests.
-"""

Copied: CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/__init__.py (from rev 5005, CalendarServer/trunk/txcaldav/calendarstore/test/__init__.py)
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/__init__.py	                        (rev 0)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/__init__.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -0,0 +1,19 @@
+##
+# Copyright (c) 2010 Apple Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##
+
+"""
+Calendar store tests.
+"""

Deleted: CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_1/1.ics
===================================================================
--- CalendarServer/trunk/txcaldav/calendarstore/test/calendar_store/home1/calendar_1/1.ics	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_1/1.ics	2010-02-02 01:25:32 UTC (rev 5006)
@@ -1,28 +0,0 @@
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//Apple Inc.//iCal 4.0.1//EN
-CALSCALE:GREGORIAN
-BEGIN:VEVENT
-ATTENDEE;CN="Wilfredo Sanchez";CUTYPE=INDIVIDUAL;PARTSTAT=ACCEPTED:mailt
- o:wsanchez at apple.com
-ATTENDEE;CN="Cyrus Daboo";CUTYPE=INDIVIDUAL;PARTSTAT=ACCEPTED:mailto:cda
- boo at apple.com
-DTEND;TZID=US/Pacific:20090324T124500
-TRANSP:OPAQUE
-ORGANIZER;CN="Wilfredo Sanchez":mailto:wsanchez at apple.com
-UID:uid1
-DTSTAMP:20090326T145447Z
-LOCATION:Wilfredo's Office
-SEQUENCE:2
-X-APPLE-EWS-BUSYSTATUS:BUSY
-SUMMARY:CalDAV protocol updates
-DTSTART;TZID=US/Pacific:20090324T121500
-CREATED:20090326T145440Z
-BEGIN:VALARM
-X-WR-ALARMUID:DB39AB67-449C-441C-89D2-D740B5F41A73
-TRIGGER;VALUE=DATE-TIME:20090324T180009Z
-ATTACH;VALUE=URI:Basso
-ACTION:AUDIO
-END:VALARM
-END:VEVENT
-END:VCALENDAR

Copied: CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_1/1.ics (from rev 5005, CalendarServer/trunk/txcaldav/calendarstore/test/calendar_store/home1/calendar_1/1.ics)
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_1/1.ics	                        (rev 0)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_1/1.ics	2010-02-02 01:25:32 UTC (rev 5006)
@@ -0,0 +1,28 @@
+BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//Apple Inc.//iCal 4.0.1//EN
+CALSCALE:GREGORIAN
+BEGIN:VEVENT
+ATTENDEE;CN="Wilfredo Sanchez";CUTYPE=INDIVIDUAL;PARTSTAT=ACCEPTED:mailt
+ o:wsanchez at apple.com
+ATTENDEE;CN="Cyrus Daboo";CUTYPE=INDIVIDUAL;PARTSTAT=ACCEPTED:mailto:cda
+ boo at apple.com
+DTEND;TZID=US/Pacific:20090324T124500
+TRANSP:OPAQUE
+ORGANIZER;CN="Wilfredo Sanchez":mailto:wsanchez at apple.com
+UID:uid1
+DTSTAMP:20090326T145447Z
+LOCATION:Wilfredo's Office
+SEQUENCE:2
+X-APPLE-EWS-BUSYSTATUS:BUSY
+SUMMARY:CalDAV protocol updates
+DTSTART;TZID=US/Pacific:20090324T121500
+CREATED:20090326T145440Z
+BEGIN:VALARM
+X-WR-ALARMUID:DB39AB67-449C-441C-89D2-D740B5F41A73
+TRIGGER;VALUE=DATE-TIME:20090324T180009Z
+ATTACH;VALUE=URI:Basso
+ACTION:AUDIO
+END:VALARM
+END:VEVENT
+END:VCALENDAR

Deleted: CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_1/2.ics
===================================================================
--- CalendarServer/trunk/txcaldav/calendarstore/test/calendar_store/home1/calendar_1/2.ics	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_1/2.ics	2010-02-02 01:25:32 UTC (rev 5006)
@@ -1,48 +0,0 @@
-BEGIN:VCALENDAR
-VERSION:2.0
-CALSCALE:GREGORIAN
-PRODID:-//Cyrusoft International\, Inc.//Mulberry v4.0//EN
-BEGIN:VTIMEZONE
-TZID:US/Eastern
-LAST-MODIFIED:20040110T032845Z
-BEGIN:STANDARD
-DTSTART:20001026T020000
-RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
-TZNAME:EST
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-DTSTART:20000404T020000
-RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
-TZNAME:EDT
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-END:VTIMEZONE
-BEGIN:VEVENT
-UID:uid2
-DTSTART;TZID=US/Eastern:20060102T140000
-DURATION:PT1H
-CREATED:20060102T190000Z
-DTSTAMP:20051222T210507Z
-RRULE:FREQ=DAILY;COUNT=5
-SUMMARY:event 6-%ctr
-END:VEVENT
-BEGIN:VEVENT
-UID:uid2
-RECURRENCE-ID;TZID=US/Eastern:20060104T140000
-DTSTART;TZID=US/Eastern:20060104T160000
-DURATION:PT1H
-CREATED:20060102T190000Z
-DESCRIPTION:Some notes
-DTSTAMP:20051222T210507Z
-SUMMARY:event 6-%ctr changed
-BEGIN:VALARM
-ACTION:AUDIO
-TRIGGER;RELATED=START:-PT10M
-X-MULBERRY-ALARM-STATUS:PENDING
-X-MULBERRY-SPEAK-TEXT:
-END:VALARM
-END:VEVENT
-END:VCALENDAR

Copied: CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_1/2.ics (from rev 5005, CalendarServer/trunk/txcaldav/calendarstore/test/calendar_store/home1/calendar_1/2.ics)
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_1/2.ics	                        (rev 0)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_1/2.ics	2010-02-02 01:25:32 UTC (rev 5006)
@@ -0,0 +1,48 @@
+BEGIN:VCALENDAR
+VERSION:2.0
+CALSCALE:GREGORIAN
+PRODID:-//Cyrusoft International\, Inc.//Mulberry v4.0//EN
+BEGIN:VTIMEZONE
+TZID:US/Eastern
+LAST-MODIFIED:20040110T032845Z
+BEGIN:STANDARD
+DTSTART:20001026T020000
+RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+TZNAME:EST
+TZOFFSETFROM:-0400
+TZOFFSETTO:-0500
+END:STANDARD
+BEGIN:DAYLIGHT
+DTSTART:20000404T020000
+RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
+TZNAME:EDT
+TZOFFSETFROM:-0500
+TZOFFSETTO:-0400
+END:DAYLIGHT
+END:VTIMEZONE
+BEGIN:VEVENT
+UID:uid2
+DTSTART;TZID=US/Eastern:20060102T140000
+DURATION:PT1H
+CREATED:20060102T190000Z
+DTSTAMP:20051222T210507Z
+RRULE:FREQ=DAILY;COUNT=5
+SUMMARY:event 6-%ctr
+END:VEVENT
+BEGIN:VEVENT
+UID:uid2
+RECURRENCE-ID;TZID=US/Eastern:20060104T140000
+DTSTART;TZID=US/Eastern:20060104T160000
+DURATION:PT1H
+CREATED:20060102T190000Z
+DESCRIPTION:Some notes
+DTSTAMP:20051222T210507Z
+SUMMARY:event 6-%ctr changed
+BEGIN:VALARM
+ACTION:AUDIO
+TRIGGER;RELATED=START:-PT10M
+X-MULBERRY-ALARM-STATUS:PENDING
+X-MULBERRY-SPEAK-TEXT:
+END:VALARM
+END:VEVENT
+END:VCALENDAR

Deleted: CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_1/3.ics
===================================================================
--- CalendarServer/trunk/txcaldav/calendarstore/test/calendar_store/home1/calendar_1/3.ics	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_1/3.ics	2010-02-02 01:25:32 UTC (rev 5006)
@@ -1,33 +0,0 @@
-BEGIN:VCALENDAR
-VERSION:2.0
-CALSCALE:GREGORIAN
-PRODID:-//Cyrusoft International\, Inc.//Mulberry v4.0//EN
-BEGIN:VTIMEZONE
-TZID:US/Pacific
-LAST-MODIFIED:20040110T032845Z
-BEGIN:STANDARD
-DTSTART:20001026T020000
-RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
-TZNAME:PST
-TZOFFSETFROM:-0700
-TZOFFSETTO:-0800
-END:STANDARD
-BEGIN:DAYLIGHT
-DTSTART:20000404T020000
-RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
-TZNAME:PDT
-TZOFFSETFROM:-0800
-TZOFFSETTO:-0700
-END:DAYLIGHT
-END:VTIMEZONE
-BEGIN:VEVENT
-UID:uid3
-DTSTART;TZID=US/Pacific:20060101T130000
-DURATION:PT1H
-CREATED:20060101T210000Z
-DTSTAMP:20051222T210146Z
-LAST-MODIFIED:20051222T210203Z
-SEQUENCE:1
-SUMMARY:event 3-%ctr
-END:VEVENT
-END:VCALENDAR

Copied: CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_1/3.ics (from rev 5005, CalendarServer/trunk/txcaldav/calendarstore/test/calendar_store/home1/calendar_1/3.ics)
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_1/3.ics	                        (rev 0)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_1/3.ics	2010-02-02 01:25:32 UTC (rev 5006)
@@ -0,0 +1,33 @@
+BEGIN:VCALENDAR
+VERSION:2.0
+CALSCALE:GREGORIAN
+PRODID:-//Cyrusoft International\, Inc.//Mulberry v4.0//EN
+BEGIN:VTIMEZONE
+TZID:US/Pacific
+LAST-MODIFIED:20040110T032845Z
+BEGIN:STANDARD
+DTSTART:20001026T020000
+RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+TZNAME:PST
+TZOFFSETFROM:-0700
+TZOFFSETTO:-0800
+END:STANDARD
+BEGIN:DAYLIGHT
+DTSTART:20000404T020000
+RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
+TZNAME:PDT
+TZOFFSETFROM:-0800
+TZOFFSETTO:-0700
+END:DAYLIGHT
+END:VTIMEZONE
+BEGIN:VEVENT
+UID:uid3
+DTSTART;TZID=US/Pacific:20060101T130000
+DURATION:PT1H
+CREATED:20060101T210000Z
+DTSTAMP:20051222T210146Z
+LAST-MODIFIED:20051222T210203Z
+SEQUENCE:1
+SUMMARY:event 3-%ctr
+END:VEVENT
+END:VCALENDAR

Deleted: CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_2/24204e8682b99527cbda64d7423acda7.ics
===================================================================
--- CalendarServer/trunk/txcaldav/calendarstore/test/calendar_store/home1/calendar_2/24204e8682b99527cbda64d7423acda7.ics	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_2/24204e8682b99527cbda64d7423acda7.ics	2010-02-02 01:25:32 UTC (rev 5006)
@@ -1,32 +0,0 @@
-BEGIN:VCALENDAR
-VERSION:2.0
-CALSCALE:GREGORIAN
-PRODID:-//Cyrusoft International\, Inc.//Mulberry v4.0//EN
-BEGIN:VTIMEZONE
-TZID:US/Mountain
-LAST-MODIFIED:20040110T032845Z
-BEGIN:STANDARD
-DTSTART:20001026T020000
-RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
-TZNAME:MST
-TZOFFSETFROM:-0600
-TZOFFSETTO:-0700
-END:STANDARD
-BEGIN:DAYLIGHT
-DTSTART:20000404T020000
-RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
-TZNAME:MDT
-TZOFFSETFROM:-0700
-TZOFFSETTO:-0600
-END:DAYLIGHT
-END:VTIMEZONE
-BEGIN:VEVENT
-UID:9A6519F71822CD45840C3440-%ctr at ninevah.local
-DTSTART;TZID=US/Mountain:20060101T110000
-DURATION:PT1H
-CREATED:20060101T160000Z
-DESCRIPTION:Some notes
-DTSTAMP:20051222T210052Z
-SUMMARY:event 2-%ctr
-END:VEVENT
-END:VCALENDAR

Copied: CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_2/24204e8682b99527cbda64d7423acda7.ics (from rev 5005, CalendarServer/trunk/txcaldav/calendarstore/test/calendar_store/home1/calendar_2/24204e8682b99527cbda64d7423acda7.ics)
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_2/24204e8682b99527cbda64d7423acda7.ics	                        (rev 0)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_2/24204e8682b99527cbda64d7423acda7.ics	2010-02-02 01:25:32 UTC (rev 5006)
@@ -0,0 +1,32 @@
+BEGIN:VCALENDAR
+VERSION:2.0
+CALSCALE:GREGORIAN
+PRODID:-//Cyrusoft International\, Inc.//Mulberry v4.0//EN
+BEGIN:VTIMEZONE
+TZID:US/Mountain
+LAST-MODIFIED:20040110T032845Z
+BEGIN:STANDARD
+DTSTART:20001026T020000
+RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+TZNAME:MST
+TZOFFSETFROM:-0600
+TZOFFSETTO:-0700
+END:STANDARD
+BEGIN:DAYLIGHT
+DTSTART:20000404T020000
+RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
+TZNAME:MDT
+TZOFFSETFROM:-0700
+TZOFFSETTO:-0600
+END:DAYLIGHT
+END:VTIMEZONE
+BEGIN:VEVENT
+UID:9A6519F71822CD45840C3440-%ctr at ninevah.local
+DTSTART;TZID=US/Mountain:20060101T110000
+DURATION:PT1H
+CREATED:20060101T160000Z
+DESCRIPTION:Some notes
+DTSTAMP:20051222T210052Z
+SUMMARY:event 2-%ctr
+END:VEVENT
+END:VCALENDAR

Deleted: CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_2/61038c41bd02ae5daf9f7fe9d54199fd.ics
===================================================================
--- CalendarServer/trunk/txcaldav/calendarstore/test/calendar_store/home1/calendar_2/61038c41bd02ae5daf9f7fe9d54199fd.ics	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_2/61038c41bd02ae5daf9f7fe9d54199fd.ics	2010-02-02 01:25:32 UTC (rev 5006)
@@ -1,31 +0,0 @@
-BEGIN:VCALENDAR
-VERSION:2.0
-CALSCALE:GREGORIAN
-PRODID:-//Cyrusoft International\, Inc.//Mulberry v4.0//EN
-BEGIN:VTIMEZONE
-TZID:US/Eastern
-LAST-MODIFIED:20040110T032845Z
-BEGIN:STANDARD
-DTSTART:20001026T020000
-RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
-TZNAME:EST
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-DTSTART:20000404T020000
-RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
-TZNAME:EDT
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-END:VTIMEZONE
-BEGIN:VEVENT
-UID:54E181BC7CCC373042B28842-%ctr at ninevah.local
-DTSTART;TZID=US/Eastern:20060101T100000
-DURATION:PT1H
-CREATED:20060101T150000Z
-DTSTAMP:20051222T205953Z
-SUMMARY:event 1-%ctr
-END:VEVENT
-END:VCALENDAR

Copied: CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_2/61038c41bd02ae5daf9f7fe9d54199fd.ics (from rev 5005, CalendarServer/trunk/txcaldav/calendarstore/test/calendar_store/home1/calendar_2/61038c41bd02ae5daf9f7fe9d54199fd.ics)
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_2/61038c41bd02ae5daf9f7fe9d54199fd.ics	                        (rev 0)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_2/61038c41bd02ae5daf9f7fe9d54199fd.ics	2010-02-02 01:25:32 UTC (rev 5006)
@@ -0,0 +1,31 @@
+BEGIN:VCALENDAR
+VERSION:2.0
+CALSCALE:GREGORIAN
+PRODID:-//Cyrusoft International\, Inc.//Mulberry v4.0//EN
+BEGIN:VTIMEZONE
+TZID:US/Eastern
+LAST-MODIFIED:20040110T032845Z
+BEGIN:STANDARD
+DTSTART:20001026T020000
+RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+TZNAME:EST
+TZOFFSETFROM:-0400
+TZOFFSETTO:-0500
+END:STANDARD
+BEGIN:DAYLIGHT
+DTSTART:20000404T020000
+RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
+TZNAME:EDT
+TZOFFSETFROM:-0500
+TZOFFSETTO:-0400
+END:DAYLIGHT
+END:VTIMEZONE
+BEGIN:VEVENT
+UID:54E181BC7CCC373042B28842-%ctr at ninevah.local
+DTSTART;TZID=US/Eastern:20060101T100000
+DURATION:PT1H
+CREATED:20060101T150000Z
+DTSTAMP:20051222T205953Z
+SUMMARY:event 1-%ctr
+END:VEVENT
+END:VCALENDAR

Deleted: CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_2/84be58ced1f1bb34057e1bd7e602c9c8.ics
===================================================================
--- CalendarServer/trunk/txcaldav/calendarstore/test/calendar_store/home1/calendar_2/84be58ced1f1bb34057e1bd7e602c9c8.ics	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_2/84be58ced1f1bb34057e1bd7e602c9c8.ics	2010-02-02 01:25:32 UTC (rev 5006)
@@ -1,31 +0,0 @@
-BEGIN:VCALENDAR
-VERSION:2.0
-CALSCALE:GREGORIAN
-PRODID:-//Cyrusoft International\, Inc.//Mulberry v4.0//EN
-BEGIN:VTIMEZONE
-TZID:US/Eastern
-LAST-MODIFIED:20040110T032845Z
-BEGIN:STANDARD
-DTSTART:20001026T020000
-RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
-TZNAME:EST
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-DTSTART:20000404T020000
-RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
-TZNAME:EDT
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-END:VTIMEZONE
-BEGIN:VEVENT
-UID:54E181BC7CCC373042B28842-8-%ctr at ninevah.local
-DTSTART;TZID=US/Eastern:20060107T100000
-DURATION:PT1H
-CREATED:20060101T150000Z
-DTSTAMP:20051222T205953Z
-SUMMARY:event 8-%ctr
-END:VEVENT
-END:VCALENDAR

Copied: CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_2/84be58ced1f1bb34057e1bd7e602c9c8.ics (from rev 5005, CalendarServer/trunk/txcaldav/calendarstore/test/calendar_store/home1/calendar_2/84be58ced1f1bb34057e1bd7e602c9c8.ics)
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_2/84be58ced1f1bb34057e1bd7e602c9c8.ics	                        (rev 0)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_2/84be58ced1f1bb34057e1bd7e602c9c8.ics	2010-02-02 01:25:32 UTC (rev 5006)
@@ -0,0 +1,31 @@
+BEGIN:VCALENDAR
+VERSION:2.0
+CALSCALE:GREGORIAN
+PRODID:-//Cyrusoft International\, Inc.//Mulberry v4.0//EN
+BEGIN:VTIMEZONE
+TZID:US/Eastern
+LAST-MODIFIED:20040110T032845Z
+BEGIN:STANDARD
+DTSTART:20001026T020000
+RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+TZNAME:EST
+TZOFFSETFROM:-0400
+TZOFFSETTO:-0500
+END:STANDARD
+BEGIN:DAYLIGHT
+DTSTART:20000404T020000
+RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
+TZNAME:EDT
+TZOFFSETFROM:-0500
+TZOFFSETTO:-0400
+END:DAYLIGHT
+END:VTIMEZONE
+BEGIN:VEVENT
+UID:54E181BC7CCC373042B28842-8-%ctr at ninevah.local
+DTSTART;TZID=US/Eastern:20060107T100000
+DURATION:PT1H
+CREATED:20060101T150000Z
+DTSTAMP:20051222T205953Z
+SUMMARY:event 8-%ctr
+END:VEVENT
+END:VCALENDAR

Deleted: CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_2/acc1015b7dc300c1b5665f6833960994.ics
===================================================================
--- CalendarServer/trunk/txcaldav/calendarstore/test/calendar_store/home1/calendar_2/acc1015b7dc300c1b5665f6833960994.ics	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_2/acc1015b7dc300c1b5665f6833960994.ics	2010-02-02 01:25:32 UTC (rev 5006)
@@ -1,31 +0,0 @@
-BEGIN:VCALENDAR
-VERSION:2.0
-CALSCALE:GREGORIAN
-PRODID:-//Cyrusoft International\, Inc.//Mulberry v4.0//EN
-BEGIN:VTIMEZONE
-TZID:US/Eastern
-LAST-MODIFIED:20040110T032845Z
-BEGIN:STANDARD
-DTSTART:20001026T020000
-RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
-TZNAME:EST
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-DTSTART:20000404T020000
-RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
-TZNAME:EDT
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-END:VTIMEZONE
-BEGIN:VEVENT
-UID:54E181BC7CCC373042B28842-9-%ctr at ninevah.local
-DTSTART;TZID=US/Eastern:20060107T103000
-DURATION:PT1H
-CREATED:20060101T150000Z
-DTSTAMP:20051222T205953Z
-SUMMARY:event 9-%ctr
-END:VEVENT
-END:VCALENDAR

Copied: CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_2/acc1015b7dc300c1b5665f6833960994.ics (from rev 5005, CalendarServer/trunk/txcaldav/calendarstore/test/calendar_store/home1/calendar_2/acc1015b7dc300c1b5665f6833960994.ics)
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_2/acc1015b7dc300c1b5665f6833960994.ics	                        (rev 0)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_2/acc1015b7dc300c1b5665f6833960994.ics	2010-02-02 01:25:32 UTC (rev 5006)
@@ -0,0 +1,31 @@
+BEGIN:VCALENDAR
+VERSION:2.0
+CALSCALE:GREGORIAN
+PRODID:-//Cyrusoft International\, Inc.//Mulberry v4.0//EN
+BEGIN:VTIMEZONE
+TZID:US/Eastern
+LAST-MODIFIED:20040110T032845Z
+BEGIN:STANDARD
+DTSTART:20001026T020000
+RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+TZNAME:EST
+TZOFFSETFROM:-0400
+TZOFFSETTO:-0500
+END:STANDARD
+BEGIN:DAYLIGHT
+DTSTART:20000404T020000
+RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
+TZNAME:EDT
+TZOFFSETFROM:-0500
+TZOFFSETTO:-0400
+END:DAYLIGHT
+END:VTIMEZONE
+BEGIN:VEVENT
+UID:54E181BC7CCC373042B28842-9-%ctr at ninevah.local
+DTSTART;TZID=US/Eastern:20060107T103000
+DURATION:PT1H
+CREATED:20060101T150000Z
+DTSTAMP:20051222T205953Z
+SUMMARY:event 9-%ctr
+END:VEVENT
+END:VCALENDAR

Deleted: CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_2/b0d5785f275c064117ffd1fc20f4ed40.ics
===================================================================
--- CalendarServer/trunk/txcaldav/calendarstore/test/calendar_store/home1/calendar_2/b0d5785f275c064117ffd1fc20f4ed40.ics	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_2/b0d5785f275c064117ffd1fc20f4ed40.ics	2010-02-02 01:25:32 UTC (rev 5006)
@@ -1,39 +0,0 @@
-BEGIN:VCALENDAR
-VERSION:2.0
-CALSCALE:GREGORIAN
-PRODID:-//Cyrusoft International\, Inc.//Mulberry v4.0//EN
-BEGIN:VTIMEZONE
-TZID:US/Eastern
-LAST-MODIFIED:20040110T032845Z
-BEGIN:STANDARD
-DTSTART:20001026T020000
-RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
-TZNAME:EST
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-DTSTART:20000404T020000
-RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
-TZNAME:EDT
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-END:VTIMEZONE
-BEGIN:VEVENT
-UID:A3217B429B4D2FF2DC2EEE66-%ctr at ninevah.local
-DTSTART;TZID=US/Eastern:20060101T180000
-DURATION:PT1H
-CREATED:20060101T230000Z
-DTSTAMP:20051222T210310Z
-SUMMARY:event 4-%ctr
-BEGIN:VALARM
-ACTION:AUDIO
-DURATION:PT10M
-REPEAT:5
-TRIGGER;RELATED=START:-PT1H
-X-MULBERRY-ALARM-STATUS:PENDING
-X-MULBERRY-SPEAK-TEXT:
-END:VALARM
-END:VEVENT
-END:VCALENDAR

Copied: CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_2/b0d5785f275c064117ffd1fc20f4ed40.ics (from rev 5005, CalendarServer/trunk/txcaldav/calendarstore/test/calendar_store/home1/calendar_2/b0d5785f275c064117ffd1fc20f4ed40.ics)
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_2/b0d5785f275c064117ffd1fc20f4ed40.ics	                        (rev 0)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_2/b0d5785f275c064117ffd1fc20f4ed40.ics	2010-02-02 01:25:32 UTC (rev 5006)
@@ -0,0 +1,39 @@
+BEGIN:VCALENDAR
+VERSION:2.0
+CALSCALE:GREGORIAN
+PRODID:-//Cyrusoft International\, Inc.//Mulberry v4.0//EN
+BEGIN:VTIMEZONE
+TZID:US/Eastern
+LAST-MODIFIED:20040110T032845Z
+BEGIN:STANDARD
+DTSTART:20001026T020000
+RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+TZNAME:EST
+TZOFFSETFROM:-0400
+TZOFFSETTO:-0500
+END:STANDARD
+BEGIN:DAYLIGHT
+DTSTART:20000404T020000
+RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
+TZNAME:EDT
+TZOFFSETFROM:-0500
+TZOFFSETTO:-0400
+END:DAYLIGHT
+END:VTIMEZONE
+BEGIN:VEVENT
+UID:A3217B429B4D2FF2DC2EEE66-%ctr at ninevah.local
+DTSTART;TZID=US/Eastern:20060101T180000
+DURATION:PT1H
+CREATED:20060101T230000Z
+DTSTAMP:20051222T210310Z
+SUMMARY:event 4-%ctr
+BEGIN:VALARM
+ACTION:AUDIO
+DURATION:PT10M
+REPEAT:5
+TRIGGER;RELATED=START:-PT1H
+X-MULBERRY-ALARM-STATUS:PENDING
+X-MULBERRY-SPEAK-TEXT:
+END:VALARM
+END:VEVENT
+END:VCALENDAR

Deleted: CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_2/b495c5dd5aa53392078eb43b1f906a80.ics
===================================================================
--- CalendarServer/trunk/txcaldav/calendarstore/test/calendar_store/home1/calendar_2/b495c5dd5aa53392078eb43b1f906a80.ics	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_2/b495c5dd5aa53392078eb43b1f906a80.ics	2010-02-02 01:25:32 UTC (rev 5006)
@@ -1,38 +0,0 @@
-BEGIN:VCALENDAR
-VERSION:2.0
-CALSCALE:GREGORIAN
-PRODID:-//Cyrusoft International\, Inc.//Mulberry v4.0//EN
-BEGIN:VTIMEZONE
-TZID:US/Eastern
-LAST-MODIFIED:20040110T032845Z
-BEGIN:STANDARD
-DTSTART:20001026T020000
-RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
-TZNAME:EST
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-DTSTART:20000404T020000
-RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
-TZNAME:EDT
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-END:VTIMEZONE
-BEGIN:VEVENT
-UID:945113826375CBB89184DC36-%ctr at ninevah.local
-DTSTART;TZID=US/Eastern:20060102T100000
-DURATION:PT1H
-CREATED:20060102T150000Z
-DTSTAMP:20051222T210412Z
-RRULE:FREQ=DAILY;COUNT=5
-SUMMARY:event 5-%ctr
-BEGIN:VALARM
-ACTION:AUDIO
-TRIGGER;RELATED=START:-PT10M
-X-MULBERRY-ALARM-STATUS:PENDING
-X-MULBERRY-SPEAK-TEXT:
-END:VALARM
-END:VEVENT
-END:VCALENDAR

Copied: CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_2/b495c5dd5aa53392078eb43b1f906a80.ics (from rev 5005, CalendarServer/trunk/txcaldav/calendarstore/test/calendar_store/home1/calendar_2/b495c5dd5aa53392078eb43b1f906a80.ics)
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_2/b495c5dd5aa53392078eb43b1f906a80.ics	                        (rev 0)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_2/b495c5dd5aa53392078eb43b1f906a80.ics	2010-02-02 01:25:32 UTC (rev 5006)
@@ -0,0 +1,38 @@
+BEGIN:VCALENDAR
+VERSION:2.0
+CALSCALE:GREGORIAN
+PRODID:-//Cyrusoft International\, Inc.//Mulberry v4.0//EN
+BEGIN:VTIMEZONE
+TZID:US/Eastern
+LAST-MODIFIED:20040110T032845Z
+BEGIN:STANDARD
+DTSTART:20001026T020000
+RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+TZNAME:EST
+TZOFFSETFROM:-0400
+TZOFFSETTO:-0500
+END:STANDARD
+BEGIN:DAYLIGHT
+DTSTART:20000404T020000
+RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
+TZNAME:EDT
+TZOFFSETFROM:-0500
+TZOFFSETTO:-0400
+END:DAYLIGHT
+END:VTIMEZONE
+BEGIN:VEVENT
+UID:945113826375CBB89184DC36-%ctr at ninevah.local
+DTSTART;TZID=US/Eastern:20060102T100000
+DURATION:PT1H
+CREATED:20060102T150000Z
+DTSTAMP:20051222T210412Z
+RRULE:FREQ=DAILY;COUNT=5
+SUMMARY:event 5-%ctr
+BEGIN:VALARM
+ACTION:AUDIO
+TRIGGER;RELATED=START:-PT10M
+X-MULBERRY-ALARM-STATUS:PENDING
+X-MULBERRY-SPEAK-TEXT:
+END:VALARM
+END:VEVENT
+END:VCALENDAR

Deleted: CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_2/b88dd50941e4a31520ee396fd7894c96.ics
===================================================================
--- CalendarServer/trunk/txcaldav/calendarstore/test/calendar_store/home1/calendar_2/b88dd50941e4a31520ee396fd7894c96.ics	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_2/b88dd50941e4a31520ee396fd7894c96.ics	2010-02-02 01:25:32 UTC (rev 5006)
@@ -1,31 +0,0 @@
-BEGIN:VCALENDAR
-VERSION:2.0
-CALSCALE:GREGORIAN
-PRODID:-//Cyrusoft International\, Inc.//Mulberry v4.0//EN
-BEGIN:VTIMEZONE
-TZID:US/Eastern
-LAST-MODIFIED:20040110T032845Z
-BEGIN:STANDARD
-DTSTART:20001026T020000
-RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
-TZNAME:EST
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-DTSTART:20000404T020000
-RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
-TZNAME:EDT
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-END:VTIMEZONE
-BEGIN:VEVENT
-UID:54E181BC7CCC373042B28842-10-%ctr at ninevah.local
-DTSTART;TZID=US/Eastern:20060108T100000
-DURATION:PT1H
-CREATED:20060101T150000Z
-DTSTAMP:20051222T205953Z
-SUMMARY:event 10-%ctr
-END:VEVENT
-END:VCALENDAR

Copied: CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_2/b88dd50941e4a31520ee396fd7894c96.ics (from rev 5005, CalendarServer/trunk/txcaldav/calendarstore/test/calendar_store/home1/calendar_2/b88dd50941e4a31520ee396fd7894c96.ics)
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_2/b88dd50941e4a31520ee396fd7894c96.ics	                        (rev 0)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/calendar_store/home1/calendar_2/b88dd50941e4a31520ee396fd7894c96.ics	2010-02-02 01:25:32 UTC (rev 5006)
@@ -0,0 +1,31 @@
+BEGIN:VCALENDAR
+VERSION:2.0
+CALSCALE:GREGORIAN
+PRODID:-//Cyrusoft International\, Inc.//Mulberry v4.0//EN
+BEGIN:VTIMEZONE
+TZID:US/Eastern
+LAST-MODIFIED:20040110T032845Z
+BEGIN:STANDARD
+DTSTART:20001026T020000
+RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+TZNAME:EST
+TZOFFSETFROM:-0400
+TZOFFSETTO:-0500
+END:STANDARD
+BEGIN:DAYLIGHT
+DTSTART:20000404T020000
+RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
+TZNAME:EDT
+TZOFFSETFROM:-0500
+TZOFFSETTO:-0400
+END:DAYLIGHT
+END:VTIMEZONE
+BEGIN:VEVENT
+UID:54E181BC7CCC373042B28842-10-%ctr at ninevah.local
+DTSTART;TZID=US/Eastern:20060108T100000
+DURATION:PT1H
+CREATED:20060101T150000Z
+DTSTAMP:20051222T205953Z
+SUMMARY:event 10-%ctr
+END:VEVENT
+END:VCALENDAR

Deleted: CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/test_file.py
===================================================================
--- CalendarServer/trunk/txcaldav/calendarstore/test/test_file.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/test_file.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -1,272 +0,0 @@
-##
-# Copyright (c) 2010 Apple Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-##
-
-"""
-File calendar store tests.
-"""
-
-from zope.interface.verify import verifyObject, BrokenMethodImplementation
-
-from twisted.python.filepath import FilePath
-from twisted.trial import unittest
-
-from twext.python.icalendar import Component as iComponent
-
-from txdav.idav import IPropertyStore
-
-from txcaldav.icalendarstore import ICalendarHome
-from txcaldav.icalendarstore import ICalendar
-from txcaldav.icalendarstore import ICalendarObject
-
-from txcaldav.calendarstore.file import CalendarStore
-from txcaldav.calendarstore.file import CalendarHome
-from txcaldav.calendarstore.file import Calendar
-from txcaldav.calendarstore.file import CalendarObject
-
-storePath = FilePath(__file__).parent().child("calendar_store")
-
-home1_calendarNames = (
-    "calendar_1",
-    "calendar_2",
-    "calendar_empty",
-)
-
-calendar1_objectNames = (
-    "1.ics",
-    "2.ics",
-    "3.ics",
-)
-
-class CalendarStoreTest(unittest.TestCase):
-    def setUp(self):
-        self.calendarStore = CalendarStore(storePath)
-
-    # FIXME: If we define an interface
-    #def test_interface(self):
-    #    try:
-    #        verifyObject(ICalendarStore, self.calendarstore)
-    #    except BrokenMethodImplementation, e:
-    #        self.fail(e)
-
-    def test_init(self):
-        assert isinstance(self.calendarStore.path, FilePath), self.calendarStore.path
-
-    def test_calendarHomeWithUID(self):
-        calendarHome = self.calendarStore.calendarHomeWithUID("home1")
-
-        assert isinstance(calendarHome, CalendarHome)
-
-
-class CalendarHomeTest(unittest.TestCase):
-    def setUp(self):
-        self.calendarStore = CalendarStore(storePath)
-        self.home1 = self.calendarStore.calendarHomeWithUID("home1")
-
-    def test_interface(self):
-        try:
-            verifyObject(ICalendarHome, self.home1)
-        except BrokenMethodImplementation, e:
-            self.fail(e)
-
-    def test_init(self):
-        self.failUnless(
-            isinstance(self.home1.path, FilePath),
-            self.home1.path
-        )
-        self.assertEquals(
-            self.home1.calendarStore,
-            self.calendarStore
-        )
-
-    def test_uid(self):
-        self.assertEquals(self.home1.uid(), "home1")
-
-    def test_calendars(self):
-        calendars = tuple(self.home1.calendars())
-
-        for calendar in calendars:
-            self.failUnless(isinstance(calendar, Calendar))
-
-        self.assertEquals(
-            tuple(c.name() for c in calendars),
-            home1_calendarNames
-        )
-
-    def test_calendarWithName(self):
-        for name in home1_calendarNames:
-            calendar = self.home1.calendarWithName(name)
-            self.failUnless(isinstance(calendar, Calendar))
-            self.assertEquals(calendar.name(), name)
-
-    def test_createCalendarWithName(self):
-        raise NotImplementedError()
-    test_createCalendarWithName.todo = "Unimplemented"
-
-    def test_removeCalendarWithName(self):
-        raise NotImplementedError()
-    test_removeCalendarWithName.todo = "Unimplemented"
-
-    def test_properties(self):
-        properties = self.home1.properties()
-
-        # FIXME: check specific class later?
-        self.failUnless(IPropertyStore.providedBy(properties))
-    test_properties.todo = "Unimplemented"
-
-
-class CalendarTest(unittest.TestCase):
-    def setUp(self):
-        self.calendarStore = CalendarStore(storePath)
-        self.home1 = self.calendarStore.calendarHomeWithUID("home1")
-        self.calendar1 = self.home1.calendarWithName("calendar_1")
-
-    def test_interface(self):
-        try:
-            verifyObject(ICalendar, self.calendar1)
-        except BrokenMethodImplementation, e:
-            self.fail(e)
-
-    def test_init(self):
-        self.failUnless(
-            isinstance(self.calendar1.path, FilePath),
-            self.calendar1
-        )
-        self.failUnless(
-            isinstance(self.calendar1.calendarHome, CalendarHome),
-            self.calendar1.calendarHome
-        )
-
-    def test_name(self):
-        self.assertEquals(self.calendar1.name(), "calendar_1")
-
-    def test_ownerCalendarHome(self):
-        # Note that here we know that home1 owns calendar1
-        self.assertEquals(
-            self.calendar1.ownerCalendarHome().uid(),
-            self.home1.uid()
-        )
-
-    def test_calendarObjects(self):
-        calendarObjects = tuple(self.calendar1.calendarObjects())
-
-        for calendarObject in calendarObjects:
-            self.failUnless(isinstance(calendarObject, CalendarObject))
-
-        self.assertEquals(
-            tuple(o.name() for o in calendarObjects),
-            calendar1_objectNames
-        )
-
-    def test_calendarObjectWithName(self):
-        for name in calendar1_objectNames:
-            calendarObject = self.calendar1.calendarObjectWithName(name)
-            self.failUnless(isinstance(calendarObject, CalendarObject))
-            self.assertEquals(calendarObject.name(), name)
-
-    def test_calendarObjectWithUID(self):
-        raise NotImplementedError()
-    test_calendarObjectWithUID.todo = "Unimplemented"
-
-    def test_createCalendarObjectWithName(self):
-        raise NotImplementedError()
-    test_createCalendarObjectWithName.todo = "Unimplemented"
-
-    def test_removeCalendarComponentWithName(self):
-        raise NotImplementedError()
-    test_removeCalendarComponentWithName.todo = "Unimplemented"
-
-    def test_removeCalendarComponentWithUID(self):
-        raise NotImplementedError()
-    test_removeCalendarComponentWithUID.todo = "Unimplemented"
-
-    def test_syncToken(self):
-        raise NotImplementedError()
-    test_syncToken.todo = "Unimplemented"
-
-    def test_calendarObjectsInTimeRange(self):
-        raise NotImplementedError()
-    test_calendarObjectsInTimeRange.todo = "Unimplemented"
-
-    def test_calendarObjectsSinceToken(self):
-        raise NotImplementedError()
-    test_calendarObjectsSinceToken.todo = "Unimplemented"
-
-    def test_properties(self):
-        raise NotImplementedError()
-    test_properties.todo = "Unimplemented"
-
-
-class CalendarObjectTest(unittest.TestCase):
-    def setUp(self):
-        self.calendarStore = CalendarStore(storePath)
-        self.home1 = self.calendarStore.calendarHomeWithUID("home1")
-        self.calendar1 = self.home1.calendarWithName("calendar_1")
-        self.object1 = self.calendar1.calendarObjectWithName("1.ics")
-
-    def test_interface(self):
-        try:
-            verifyObject(ICalendarObject, self.object1)
-        except BrokenMethodImplementation, e:
-            self.fail(e)
-
-    def test_init(self):
-        self.failUnless(
-            isinstance(self.object1.path, FilePath),
-            self.object1.path
-        )
-        self.failUnless(
-            isinstance(self.object1.calendar, Calendar),
-            self.object1.calendar
-        )
-
-    def test_name(self):
-        self.assertEquals(self.object1.name(), "1.ics")
-
-    def test_setComponent(self):
-        raise NotImplementedError()
-    test_setComponent.todo = "Unimplemented"
-
-    def test_component(self):
-        component = self.object1.component()
-
-        self.failUnless(
-            isinstance(component, iComponent),
-            component
-        )
-
-        self.assertEquals(component.name(), "VCALENDAR")
-        self.assertEquals(component.mainType(), "VEVENT")
-        self.assertEquals(component.resourceUID(), "uid1")
-
-    def text_iCalendarText(self):
-        text = self.object1.iCalendarText()
-
-        self.failUnless(text.startswith("BEGIN:VCALENDAR\r\n"))
-        self.failUnless("\r\nUID:uid-1\r\n" in text)
-        self.failUnless(text.endswith("\r\nEND:VCALENDAR\r\n"))
-
-    def test_uid(self):
-        self.assertEquals(self.object1.uid(), "uid1")
-
-    def test_componentType(self):
-        self.assertEquals(self.object1.componentType(), "VEVENT")
-
-    def test_organizer(self):
-        self.assertEquals(self.object1.organizer(), "mailto:wsanchez at apple.com")
-
-    def test_properties(self):
-        raise NotImplementedError()
-    test_properties.todo = "Unimplemented"

Copied: CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/test_file.py (from rev 5005, CalendarServer/trunk/txcaldav/calendarstore/test/test_file.py)
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/test_file.py	                        (rev 0)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/calendarstore/test/test_file.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -0,0 +1,272 @@
+##
+# Copyright (c) 2010 Apple Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##
+
+"""
+File calendar store tests.
+"""
+
+from zope.interface.verify import verifyObject, BrokenMethodImplementation
+
+from twisted.python.filepath import FilePath
+from twisted.trial import unittest
+
+from twext.python.icalendar import Component as iComponent
+
+from txdav.idav import IPropertyStore
+
+from txcaldav.icalendarstore import ICalendarHome
+from txcaldav.icalendarstore import ICalendar
+from txcaldav.icalendarstore import ICalendarObject
+
+from txcaldav.calendarstore.file import CalendarStore
+from txcaldav.calendarstore.file import CalendarHome
+from txcaldav.calendarstore.file import Calendar
+from txcaldav.calendarstore.file import CalendarObject
+
+storePath = FilePath(__file__).parent().child("calendar_store")
+
+home1_calendarNames = (
+    "calendar_1",
+    "calendar_2",
+    "calendar_empty",
+)
+
+calendar1_objectNames = (
+    "1.ics",
+    "2.ics",
+    "3.ics",
+)
+
+class CalendarStoreTest(unittest.TestCase):
+    def setUp(self):
+        self.calendarStore = CalendarStore(storePath)
+
+    # FIXME: If we define an interface
+    #def test_interface(self):
+    #    try:
+    #        verifyObject(ICalendarStore, self.calendarstore)
+    #    except BrokenMethodImplementation, e:
+    #        self.fail(e)
+
+    def test_init(self):
+        assert isinstance(self.calendarStore.path, FilePath), self.calendarStore.path
+
+    def test_calendarHomeWithUID(self):
+        calendarHome = self.calendarStore.calendarHomeWithUID("home1")
+
+        assert isinstance(calendarHome, CalendarHome)
+
+
+class CalendarHomeTest(unittest.TestCase):
+    def setUp(self):
+        self.calendarStore = CalendarStore(storePath)
+        self.home1 = self.calendarStore.calendarHomeWithUID("home1")
+
+    def test_interface(self):
+        try:
+            verifyObject(ICalendarHome, self.home1)
+        except BrokenMethodImplementation, e:
+            self.fail(e)
+
+    def test_init(self):
+        self.failUnless(
+            isinstance(self.home1.path, FilePath),
+            self.home1.path
+        )
+        self.assertEquals(
+            self.home1.calendarStore,
+            self.calendarStore
+        )
+
+    def test_uid(self):
+        self.assertEquals(self.home1.uid(), "home1")
+
+    def test_calendars(self):
+        calendars = tuple(self.home1.calendars())
+
+        for calendar in calendars:
+            self.failUnless(isinstance(calendar, Calendar))
+
+        self.assertEquals(
+            tuple(c.name() for c in calendars),
+            home1_calendarNames
+        )
+
+    def test_calendarWithName(self):
+        for name in home1_calendarNames:
+            calendar = self.home1.calendarWithName(name)
+            self.failUnless(isinstance(calendar, Calendar))
+            self.assertEquals(calendar.name(), name)
+
+    def test_createCalendarWithName(self):
+        raise NotImplementedError()
+    test_createCalendarWithName.todo = "Unimplemented"
+
+    def test_removeCalendarWithName(self):
+        raise NotImplementedError()
+    test_removeCalendarWithName.todo = "Unimplemented"
+
+    def test_properties(self):
+        properties = self.home1.properties()
+
+        # FIXME: check specific class later?
+        self.failUnless(IPropertyStore.providedBy(properties))
+    test_properties.todo = "Unimplemented"
+
+
+class CalendarTest(unittest.TestCase):
+    def setUp(self):
+        self.calendarStore = CalendarStore(storePath)
+        self.home1 = self.calendarStore.calendarHomeWithUID("home1")
+        self.calendar1 = self.home1.calendarWithName("calendar_1")
+
+    def test_interface(self):
+        try:
+            verifyObject(ICalendar, self.calendar1)
+        except BrokenMethodImplementation, e:
+            self.fail(e)
+
+    def test_init(self):
+        self.failUnless(
+            isinstance(self.calendar1.path, FilePath),
+            self.calendar1
+        )
+        self.failUnless(
+            isinstance(self.calendar1.calendarHome, CalendarHome),
+            self.calendar1.calendarHome
+        )
+
+    def test_name(self):
+        self.assertEquals(self.calendar1.name(), "calendar_1")
+
+    def test_ownerCalendarHome(self):
+        # Note that here we know that home1 owns calendar1
+        self.assertEquals(
+            self.calendar1.ownerCalendarHome().uid(),
+            self.home1.uid()
+        )
+
+    def test_calendarObjects(self):
+        calendarObjects = tuple(self.calendar1.calendarObjects())
+
+        for calendarObject in calendarObjects:
+            self.failUnless(isinstance(calendarObject, CalendarObject))
+
+        self.assertEquals(
+            tuple(o.name() for o in calendarObjects),
+            calendar1_objectNames
+        )
+
+    def test_calendarObjectWithName(self):
+        for name in calendar1_objectNames:
+            calendarObject = self.calendar1.calendarObjectWithName(name)
+            self.failUnless(isinstance(calendarObject, CalendarObject))
+            self.assertEquals(calendarObject.name(), name)
+
+    def test_calendarObjectWithUID(self):
+        raise NotImplementedError()
+    test_calendarObjectWithUID.todo = "Unimplemented"
+
+    def test_createCalendarObjectWithName(self):
+        raise NotImplementedError()
+    test_createCalendarObjectWithName.todo = "Unimplemented"
+
+    def test_removeCalendarComponentWithName(self):
+        raise NotImplementedError()
+    test_removeCalendarComponentWithName.todo = "Unimplemented"
+
+    def test_removeCalendarComponentWithUID(self):
+        raise NotImplementedError()
+    test_removeCalendarComponentWithUID.todo = "Unimplemented"
+
+    def test_syncToken(self):
+        raise NotImplementedError()
+    test_syncToken.todo = "Unimplemented"
+
+    def test_calendarObjectsInTimeRange(self):
+        raise NotImplementedError()
+    test_calendarObjectsInTimeRange.todo = "Unimplemented"
+
+    def test_calendarObjectsSinceToken(self):
+        raise NotImplementedError()
+    test_calendarObjectsSinceToken.todo = "Unimplemented"
+
+    def test_properties(self):
+        raise NotImplementedError()
+    test_properties.todo = "Unimplemented"
+
+
+class CalendarObjectTest(unittest.TestCase):
+    def setUp(self):
+        self.calendarStore = CalendarStore(storePath)
+        self.home1 = self.calendarStore.calendarHomeWithUID("home1")
+        self.calendar1 = self.home1.calendarWithName("calendar_1")
+        self.object1 = self.calendar1.calendarObjectWithName("1.ics")
+
+    def test_interface(self):
+        try:
+            verifyObject(ICalendarObject, self.object1)
+        except BrokenMethodImplementation, e:
+            self.fail(e)
+
+    def test_init(self):
+        self.failUnless(
+            isinstance(self.object1.path, FilePath),
+            self.object1.path
+        )
+        self.failUnless(
+            isinstance(self.object1.calendar, Calendar),
+            self.object1.calendar
+        )
+
+    def test_name(self):
+        self.assertEquals(self.object1.name(), "1.ics")
+
+    def test_setComponent(self):
+        raise NotImplementedError()
+    test_setComponent.todo = "Unimplemented"
+
+    def test_component(self):
+        component = self.object1.component()
+
+        self.failUnless(
+            isinstance(component, iComponent),
+            component
+        )
+
+        self.assertEquals(component.name(), "VCALENDAR")
+        self.assertEquals(component.mainType(), "VEVENT")
+        self.assertEquals(component.resourceUID(), "uid1")
+
+    def text_iCalendarText(self):
+        text = self.object1.iCalendarText()
+
+        self.failUnless(text.startswith("BEGIN:VCALENDAR\r\n"))
+        self.failUnless("\r\nUID:uid-1\r\n" in text)
+        self.failUnless(text.endswith("\r\nEND:VCALENDAR\r\n"))
+
+    def test_uid(self):
+        self.assertEquals(self.object1.uid(), "uid1")
+
+    def test_componentType(self):
+        self.assertEquals(self.object1.componentType(), "VEVENT")
+
+    def test_organizer(self):
+        self.assertEquals(self.object1.organizer(), "mailto:wsanchez at apple.com")
+
+    def test_properties(self):
+        raise NotImplementedError()
+    test_properties.todo = "Unimplemented"

Modified: CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/icalendarstore.py
===================================================================
--- CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/icalendarstore.py	2010-02-02 00:59:14 UTC (rev 5005)
+++ CalendarServer/branches/users/glyph/contacts-server-merge/txcaldav/icalendarstore.py	2010-02-02 01:25:32 UTC (rev 5006)
@@ -19,6 +19,22 @@
 """
 
 __all__ = [
+    # Exceptions
+    "CalendarStoreError",
+    "NameNotAllowedError",
+    "CalendarNameNotAllowedError",
+    "CalendarObjectNameNotAllowedError",
+    "AlreadyExistsError",
+    "CalendarAlreadyExistsError",
+    "CalendarObjectNameAlreadyExistsError",
+    "CalendarObjectUIDAlreadyExistsError",
+    "NotFoundError",
+    "NoSuchCalendarError",
+    "NoSuchCalendarObjectError",
+    "InvalidCalendarComponentError",
+    "InternalDataStoreError",
+
+    # Classes
     "ICalendarHome",
     "ICalendar",
     "ICalendarObject",
@@ -27,7 +43,7 @@
 from zope.interface import Interface #, Attribute
 
 from datetime import datetime, date, tzinfo
-from twext.icalendar import Component
+from twext.python.icalendar import Component
 from txdav.idav import IPropertyStore
 
 #
@@ -39,6 +55,21 @@
     Calendar store generic error.
     """
 
+class NameNotAllowedError(CalendarStoreError):
+    """
+    Attempt to create an object with a name that is not allowed.
+    """
+
+class CalendarNameNotAllowedError(NameNotAllowedError):
+    """
+    Calendar name not allowed.
+    """
+
+class CalendarObjectNameNotAllowedError(NameNotAllowedError):
+    """
+    Calendar object name not allowed.
+    """
+
 class AlreadyExistsError(CalendarStoreError):
     """
     Attempt to create an object that already exists.
@@ -79,6 +110,11 @@
     Invalid calendar component.
     """
 
+class InternalDataStoreError(CalendarStoreError):
+    """
+    Uh, oh.
+    """
+
 #
 # Interfaces
 #
@@ -87,14 +123,21 @@
     """
     Calendar home
     """
-    def calendars(self):
+    def uid():
         """
+        Retrieve the unique identifier for this calendar home.
+
+        @return: a string.
+        """
+
+    def calendars():
+        """
         Retrieve calendars contained in this calendar home.
 
         @return: an iterable of L{ICalendar}s.
         """
 
-    def calendarWithName(self, name):
+    def calendarWithName(name):
         """
         Retrieve the calendar with the given C{name} contained in this
         calendar home.
@@ -104,7 +147,7 @@
             exists.
         """
 
-    def createCalendarWithName(self, name):
+    def createCalendarWithName(name):
         """
         Create a calendar with the given C{name} in this calendar
         home.
@@ -114,7 +157,7 @@
             given C{name} already exists.
         """
 
-    def removeCalendarWithName(self, name):
+    def removeCalendarWithName(name):
         """
         Remove the calendar with the given C{name} from this calendar
         home.  If this calendar home owns the calendar, also remove
@@ -124,7 +167,7 @@
         @raise NoSuchCalendarObjectError: if no such calendar exists.
         """
 
-    def properties(self):
+    def properties():
         """
         Retrieve the property store for this calendar home.
 
@@ -135,7 +178,7 @@
     """
     Calendar
     """
-    def ownerCalendarHome(self):
+    def ownerCalendarHome():
         """
         Retrieve the calendar home for the owner of this calendar.
         Calendars may be shared from one (the owner's) calendar home
@@ -144,14 +187,14 @@
         @return: an L{ICalendarHome}.
         """
 
-    def calendarObjects(self):
+    def calendarObjects():
         """
         Retrieve the calendar objects contained in this calendar.
 
         @return: an iterable of L{ICalendarObject}s.
         """
 
-    def calendarObjectWithName(self, name):
+    def calendarObjectWithName(name):
         """
         Retrieve the calendar object with the given C{name} contained
         in this calendar.
@@ -161,7 +204,7 @@
             object exists.
         """
 
-    def calendarObjectWithUID(self, uid):
+    def calendarObjectWithUID(uid):
         """
         Retrieve the calendar object with the given C{uid} contained
         in this calendar.
@@ -171,7 +214,7 @@
             object exists.
         """
 
-    def createCalendarObjectWithName(self, name, component):
+    def createCalendarObjectWithName(name, component):
         """
         Create a calendar component with the given C{name} in this
         calendar from the given C{component}.
@@ -188,9 +231,9 @@
             a calendar object.
         """
 
-    def removeCalendarComponentWithName(self, name):
+    def removeCalendarObjectWithName(name):
         """
-        Remove the calendar component with the given C{name} from this
+        Remove the calendar object with the given C{name} from this
         calendar.
 
         @param name: a string.
@@ -198,9 +241,9 @@
             exists.
         """
 
-    def removeCalendarComponentWithUID(self, uid):
+    def removeCalendarObjectWithUID(uid):
         """
-        Remove the calendar component with the given C{uid} from this
+        Remove the calendar object with the given C{uid} from this
         calendar.
 
         @param uid: a string.
@@ -208,14 +251,14 @@
             not exist.
         """
 
-    def syncToken(self):
+    def syncToken():
         """
         Retrieve the current sync token for this calendar.
 
         @return: a string containing a sync token.
         """
 
-    def calendarObjectsInTimeRange(self, start, end, timeZone):
+    def calendarObjectsInTimeRange(start, end, timeZone):
         """
         Retrieve all calendar objects in this calendar which have
         instances that occur within the time range that begins at
@@ -227,7 +270,7 @@
         @return: an iterable of L{ICalendarObject}s.
         """
 
-    def calendarObjectsSinceToken(self, token):
+    def calendarObjectsSinceToken(token):
         """
         Retrieve all calendar objects in this calendar that have
         changed since the given C{token} was last valid.
@@ -238,7 +281,7 @@
             that have been removed, and the current sync token.
         """
 
-    def properties(self):
+    def properties():
         """
         Retrieve the property store for this calendar.
 
@@ -249,7 +292,7 @@
     """
     Calendar object (event, to-do, etc.).
     """
-    def setComponent(self, component):
+    def setComponent(component):
         """
         Rewrite this calendar object to match the given C{component}.
         C{component} must have the same UID and be of the same
@@ -261,14 +304,14 @@
             a calendar object.
         """
 
-    def component(self):
+    def component():
         """
         Retrieve the calendar component for this calendar object.
 
         @return: a C{VCALENDAR} L{Component}.
         """
 
-    def iCalendarText(self):
+    def iCalendarText():
         """
         Retrieve the iCalendar text data for this calendar object.
 
@@ -276,14 +319,14 @@
             calendar object.
         """
 
-    def uid(self):
+    def uid():
         """
         Retrieve the UID for this calendar object.
 
         @return: a string containing a UID.
         """
 
-    def componentType(self):
+    def componentType():
         """
         Retrieve the iCalendar component type for the main component
         in this calendar object.
@@ -291,7 +334,7 @@
         @return: a string containing the component type.
         """
 
-    def organizer(self):
+    def organizer():
         # FIXME: Ideally should return a URI object
         """
         Retrieve the organizer's calendar user address for this
@@ -300,7 +343,7 @@
         @return: a URI string.
         """
 
-    def properties(self):
+    def properties():
         """
         Retrieve the property store for this calendar object.
 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20100201/3a626f99/attachment-0001.html>


More information about the calendarserver-changes mailing list