[CalendarServer-changes] [7486] CalendarServer/trunk
source_changes at macosforge.org
source_changes at macosforge.org
Mon May 16 08:02:28 PDT 2011
Revision: 7486
http://trac.macosforge.org/projects/calendarserver/changeset/7486
Author: glyph at apple.com
Date: 2011-05-16 08:02:27 -0700 (Mon, 16 May 2011)
Log Message:
-----------
Merge new-export branch, making calendarserver_export work again. Also includes several refactorings, especially in tests, to reduce some duplication.
Modified Paths:
--------------
CalendarServer/trunk/calendarserver/tools/export.py
CalendarServer/trunk/calendarserver/tools/purge.py
CalendarServer/trunk/calendarserver/tools/test/test_purge_old_events.py
CalendarServer/trunk/calendarserver/tools/util.py
CalendarServer/trunk/twistedcaldav/datafilters/test/test_peruserdata.py
CalendarServer/trunk/twistedcaldav/ical.py
CalendarServer/trunk/twistedcaldav/method/get.py
CalendarServer/trunk/twistedcaldav/method/report_calendar_query.py
CalendarServer/trunk/twistedcaldav/method/report_multiget_common.py
CalendarServer/trunk/twistedcaldav/resource.py
CalendarServer/trunk/twistedcaldav/stdconfig.py
CalendarServer/trunk/twistedcaldav/storebridge.py
CalendarServer/trunk/twistedcaldav/test/test_calendarquery.py
CalendarServer/trunk/twistedcaldav/test/test_icalendar.py
CalendarServer/trunk/twistedcaldav/test/test_resource.py
CalendarServer/trunk/twistedcaldav/test/test_sharing.py
CalendarServer/trunk/twistedcaldav/test/test_wrapping.py
CalendarServer/trunk/twistedcaldav/test/util.py
CalendarServer/trunk/txdav/base/datastore/subpostgres.py
CalendarServer/trunk/txdav/base/propertystore/test/test_sql.py
CalendarServer/trunk/txdav/caldav/datastore/file.py
CalendarServer/trunk/txdav/caldav/datastore/sql.py
CalendarServer/trunk/txdav/caldav/datastore/test/common.py
CalendarServer/trunk/txdav/caldav/datastore/test/test_file.py
CalendarServer/trunk/txdav/caldav/datastore/test/test_sql.py
CalendarServer/trunk/txdav/caldav/datastore/util.py
CalendarServer/trunk/txdav/carddav/datastore/test/test_sql.py
CalendarServer/trunk/txdav/common/datastore/sql.py
CalendarServer/trunk/txdav/common/datastore/test/test_util.py
CalendarServer/trunk/txdav/common/datastore/test/util.py
Added Paths:
-----------
CalendarServer/trunk/calendarserver/tools/cmdline.py
CalendarServer/trunk/calendarserver/tools/test/test_export.py
CalendarServer/trunk/twistedcaldav/test/data/AnotherEvent.ics
CalendarServer/trunk/twistedcaldav/test/data/OneEvent.ics
CalendarServer/trunk/twistedcaldav/test/data/ThirdEvent.ics
Property Changed:
----------------
CalendarServer/trunk/
CalendarServer/trunk/support/build.sh
CalendarServer/trunk/txdav/caldav/datastore/index_file.py
CalendarServer/trunk/txdav/caldav/datastore/test/test_index_file.py
CalendarServer/trunk/txdav/carddav/datastore/index_file.py
CalendarServer/trunk/txdav/carddav/datastore/test/test_index_file.py
Property changes on: CalendarServer/trunk
___________________________________________________________________
Modified: svn:mergeinfo
- /CalendarServer/branches/config-separation:4379-4443
/CalendarServer/branches/egg-info-351:4589-4625
/CalendarServer/branches/generic-sqlstore:6167-6191
/CalendarServer/branches/new-store:5594-5934
/CalendarServer/branches/new-store-no-caldavfile:5911-5935
/CalendarServer/branches/new-store-no-caldavfile-2:5936-5981
/CalendarServer/branches/users/cdaboo/batchupload-6699:6700-7198
/CalendarServer/branches/users/cdaboo/cached-subscription-calendars-5692:5693-5702
/CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627:3628-3644
/CalendarServer/branches/users/cdaboo/more-sharing-5591:5592-5601
/CalendarServer/branches/users/cdaboo/partition-4464:4465-4957
/CalendarServer/branches/users/cdaboo/pods:7297-7377
/CalendarServer/branches/users/cdaboo/pycalendar:7085-7206
/CalendarServer/branches/users/cdaboo/pycard:7227-7237
/CalendarServer/branches/users/cdaboo/relative-config-paths-5070:5071-5105
/CalendarServer/branches/users/cdaboo/shared-calendars-5187:5188-5440
/CalendarServer/branches/users/glyph/conn-limit:6574-6577
/CalendarServer/branches/users/glyph/contacts-server-merge:4971-5080
/CalendarServer/branches/users/glyph/dalify:6932-7023
/CalendarServer/branches/users/glyph/db-reconnect:6824-6876
/CalendarServer/branches/users/glyph/dont-start-postgres:6592-6614
/CalendarServer/branches/users/glyph/linux-tests:6893-6900
/CalendarServer/branches/users/glyph/misc-portability-fixes:7365-7374
/CalendarServer/branches/users/glyph/more-deferreds-6:6322-6368
/CalendarServer/branches/users/glyph/more-deferreds-7:6369-6445
/CalendarServer/branches/users/glyph/oracle:7106-7155
/CalendarServer/branches/users/glyph/oracle-nulls:7340-7351
/CalendarServer/branches/users/glyph/sendfdport:5388-5424
/CalendarServer/branches/users/glyph/sharedpool:6490-6550
/CalendarServer/branches/users/glyph/sql-store:5929-6073
/CalendarServer/branches/users/glyph/subtransactions:7248-7258
/CalendarServer/branches/users/glyph/use-system-twisted:5084-5149
/CalendarServer/branches/users/sagen/inboxitems:7380-7381
/CalendarServer/branches/users/sagen/locations-resources:5032-5051
/CalendarServer/branches/users/sagen/locations-resources-2:5052-5061
/CalendarServer/branches/users/sagen/purge_old_events:6735-6746
/CalendarServer/branches/users/sagen/resource-delegates-4038:4040-4067
/CalendarServer/branches/users/sagen/resource-delegates-4066:4068-4075
/CalendarServer/branches/users/sagen/resources-2:5084-5093
/CalendarServer/branches/users/wsanchez/transations:5515-5593
+ /CalendarServer/branches/config-separation:4379-4443
/CalendarServer/branches/egg-info-351:4589-4625
/CalendarServer/branches/generic-sqlstore:6167-6191
/CalendarServer/branches/new-store:5594-5934
/CalendarServer/branches/new-store-no-caldavfile:5911-5935
/CalendarServer/branches/new-store-no-caldavfile-2:5936-5981
/CalendarServer/branches/users/cdaboo/batchupload-6699:6700-7198
/CalendarServer/branches/users/cdaboo/cached-subscription-calendars-5692:5693-5702
/CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627:3628-3644
/CalendarServer/branches/users/cdaboo/more-sharing-5591:5592-5601
/CalendarServer/branches/users/cdaboo/partition-4464:4465-4957
/CalendarServer/branches/users/cdaboo/pods:7297-7377
/CalendarServer/branches/users/cdaboo/pycalendar:7085-7206
/CalendarServer/branches/users/cdaboo/pycard:7227-7237
/CalendarServer/branches/users/cdaboo/relative-config-paths-5070:5071-5105
/CalendarServer/branches/users/cdaboo/shared-calendars-5187:5188-5440
/CalendarServer/branches/users/glyph/conn-limit:6574-6577
/CalendarServer/branches/users/glyph/contacts-server-merge:4971-5080
/CalendarServer/branches/users/glyph/dalify:6932-7023
/CalendarServer/branches/users/glyph/db-reconnect:6824-6876
/CalendarServer/branches/users/glyph/dont-start-postgres:6592-6614
/CalendarServer/branches/users/glyph/linux-tests:6893-6900
/CalendarServer/branches/users/glyph/misc-portability-fixes:7365-7374
/CalendarServer/branches/users/glyph/more-deferreds-6:6322-6368
/CalendarServer/branches/users/glyph/more-deferreds-7:6369-6445
/CalendarServer/branches/users/glyph/new-export:7444-7485
/CalendarServer/branches/users/glyph/oracle:7106-7155
/CalendarServer/branches/users/glyph/oracle-nulls:7340-7351
/CalendarServer/branches/users/glyph/sendfdport:5388-5424
/CalendarServer/branches/users/glyph/sharedpool:6490-6550
/CalendarServer/branches/users/glyph/sql-store:5929-6073
/CalendarServer/branches/users/glyph/subtransactions:7248-7258
/CalendarServer/branches/users/glyph/use-system-twisted:5084-5149
/CalendarServer/branches/users/sagen/inboxitems:7380-7381
/CalendarServer/branches/users/sagen/locations-resources:5032-5051
/CalendarServer/branches/users/sagen/locations-resources-2:5052-5061
/CalendarServer/branches/users/sagen/purge_old_events:6735-6746
/CalendarServer/branches/users/sagen/resource-delegates-4038:4040-4067
/CalendarServer/branches/users/sagen/resource-delegates-4066:4068-4075
/CalendarServer/branches/users/sagen/resources-2:5084-5093
/CalendarServer/branches/users/wsanchez/transations:5515-5593
Copied: CalendarServer/trunk/calendarserver/tools/cmdline.py (from rev 7485, CalendarServer/branches/users/glyph/new-export/calendarserver/tools/cmdline.py)
===================================================================
--- CalendarServer/trunk/calendarserver/tools/cmdline.py (rev 0)
+++ CalendarServer/trunk/calendarserver/tools/cmdline.py 2011-05-16 15:02:27 UTC (rev 7486)
@@ -0,0 +1,77 @@
+##
+# Copyright (c) 2005-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.
+##
+
+"""
+Shared main-point between utilities.
+"""
+
+import sys
+
+from calendarserver.tap.caldav import CalDAVServiceMaker, CalDAVOptions
+from calendarserver.tools.util import loadConfig, autoDisableMemcached
+from twistedcaldav.config import ConfigurationError
+
+# TODO: direct unit tests for this function.
+
+def utilityMain(configFileName, serviceClass, reactor=None):
+ """
+ Shared main-point for utilities.
+
+ This function will:
+
+ - Load the configuration file named by C{configFileName},
+ - launch a L{CalDAVServiceMaker}'s with the C{ProcessType} of
+ C{"Utility"}
+ - run the reactor, with start/stop events hooked up to the service's
+ C{startService}/C{stopService} methods.
+
+ It is C{serviceClass}'s responsibility to stop the reactor when it's
+ complete.
+
+ @param configFileName: the name of the configuration file to load.
+ @type configuration: C{str}
+
+ @param serviceClass: a 1-argument callable which takes an object that
+ provides L{ICalendarStore} and/or L{IAddressbookStore} and returns an
+ L{IService}.
+
+ @param reactor: if specified, the L{IReactorTime} / L{IReactorThreads} /
+ L{IReactorTCP} (etc) provider to use. If C{None}, the default reactor
+ will be imported and used.
+ """
+ if reactor is None:
+ from twisted.internet import reactor
+ try:
+ config = loadConfig(configFileName)
+
+ config.ProcessType = "Utility"
+ config.UtilityServiceClass = serviceClass
+
+ autoDisableMemcached(config)
+
+ maker = CalDAVServiceMaker()
+ options = CalDAVOptions
+ service = maker.makeService(options)
+
+ reactor.addSystemEventTrigger("during", "startup", service.startService)
+ reactor.addSystemEventTrigger("before", "shutdown", service.stopService)
+
+ except ConfigurationError, e:
+ sys.stderr.write("Error: %s\n" % (e,))
+ return
+
+ reactor.run()
+
Modified: CalendarServer/trunk/calendarserver/tools/export.py
===================================================================
--- CalendarServer/trunk/calendarserver/tools/export.py 2011-05-16 14:49:19 UTC (rev 7485)
+++ CalendarServer/trunk/calendarserver/tools/export.py 2011-05-16 15:02:27 UTC (rev 7486)
@@ -1,5 +1,5 @@
#!/usr/bin/env python
-
+# -*- test-case-name: calendarserver.tools.test.test_export -*-
##
# Copyright (c) 2006-2009 Apple Inc. All rights reserved.
#
@@ -17,208 +17,298 @@
##
"""
-This tool reads calendar data from a series of inputs and generates a
-single iCalendar file which can be opened in many calendar
-applications.
+This tool reads calendar data from a series of inputs and generates a single
+iCalendar file which can be opened in many calendar applications.
-This can be used to quickly create an iCalendar file from a user's
-calendars.
+This can be used to quickly create an iCalendar file from a user's calendars.
-This tool requires access to the calendar server's configuration and
-data storage; it does not operate by talking to the server via the
-network. It therefore does not apply any of the access restrictions
-that the server would. As such, one should be midful that data
-exported via this tool may be sensitive.
+This tool requires access to the calendar server's configuration and data
+storage; it does not operate by talking to the server via the network. It
+therefore does not apply any of the access restrictions that the server would.
+As such, one should be midful that data exported via this tool may be sensitive.
+
+Please also note that this is not an appropriate tool for backups, as there is
+data associated with users and calendars beyond the iCalendar as visible to the
+owner of that calendar, including DAV properties, information about sharing, and
+per-user data such as alarms.
+
"""
import os
import sys
-from getopt import getopt, GetoptError
-from os.path import dirname, abspath
+import itertools
-from twistedcaldav.config import ConfigurationError
-from twistedcaldav.ical import Component as iComponent, Property as iProperty
-from twistedcaldav.ical import iCalendarProductID
-from twistedcaldav.resource import isCalendarCollectionResource,\
- CalendarHomeResource
-from twistedcaldav.static import CalDAVFile
-from twistedcaldav.directory.directory import DirectoryService
+from twisted.python.text import wordWrap
+from twisted.python.usage import Options
+from twisted.python import log
+from twisted.internet.defer import inlineCallbacks, returnValue
-from calendarserver.tools.util import UsageError
-from calendarserver.tools.util import loadConfig, getDirectory, dummyDirectoryRecord, autoDisableMemcached
+from twistedcaldav.ical import Component
+from twistedcaldav.stdconfig import DEFAULT_CARDDAV_CONFIG_FILE
+from calendarserver.tools.cmdline import utilityMain
+from twisted.application.service import Service
+from calendarserver.tap.util import directoryFromConfig
+
+
def usage(e=None):
if e:
print e
print ""
-
- name = os.path.basename(sys.argv[0])
- print "usage: %s [options] [input_specifiers]" % (name,)
- print ""
- print "Generate an iCalendar file containing the merged content of each calendar"
- print "collection read."
- print __doc__
- print "options:"
- print " -h --help: print this help and exit"
- print " -f --config: Specify caldavd.plist configuration path"
- print " -o --output: Specify output file path (default: '-', meaning stdout)"
- print ""
- print "input specifiers:"
- print " -c --collection: add a calendar collection"
- print " -H --home: add a calendar home (and all calendars within it)"
- print " -r --record: add a directory record's calendar home (format: 'recordType:shortName')"
- print " -u --user: add a user's calendar home (shorthand for '-r users:shortName')"
-
+ try:
+ ExportOptions().opt_help()
+ except SystemExit:
+ pass
if e:
sys.exit(64)
else:
sys.exit(0)
-def main():
- try:
- (optargs, args) = getopt(
- sys.argv[1:], "hf:o:c:H:r:u:", [
- "help",
- "config=",
- "output=",
- "collection=", "home=", "record=", "user=",
- ],
- )
- except GetoptError, e:
- usage(e)
- configFileName = None
- outputFileName = None
+description = '\n'.join(
+ wordWrap(
+ """
+ Usage: calendarserver_export [options] [input specifiers]\n
+ """ + __doc__,
+ int(os.environ.get('COLUMNS', '80'))
+ )
+)
- collections = set()
- calendarHomes = set()
- records = set()
+class ExportOptions(Options):
+ """
+ Command-line options for 'calendarserver_export'
- def checkExists(resource):
- if not resource.exists():
- sys.stderr.write("No such file: %s\n" % (resource.fp.path,))
- sys.exit(1)
+ @ivar exporters: a list of L{HomeExporter} objects which can identify the
+ calendars to export, given a directory service. This list is built by
+ parsing --record and --collection options.
+ """
- for opt, arg in optargs:
- if opt in ("-h", "--help"):
- usage()
+ synopsis = description
- elif opt in ("-f", "--config"):
- configFileName = arg
+ optParameters = [['config', 'f', DEFAULT_CARDDAV_CONFIG_FILE,
+ "Specify caldavd.plist configuration path."]]
- elif opt in ("-o", "--output"):
- if arg == "-":
- outputFileName = None
- else:
- outputFileName = arg
+ def __init__(self):
+ super(ExportOptions, self).__init__()
+ self.exporters = []
+ self.outputName = '-'
- elif opt in ("-c", "--collection"):
- path = abspath(arg)
- collection = CalDAVFile(path)
- checkExists(collection)
- if not isCalendarCollectionResource(collection):
- sys.stderr.write("Not a calendar collection: %s\n" % (path,))
- sys.exit(1)
- collections.add(collection)
- elif opt in ("-H", "--home"):
- path = abspath(arg)
- parent = CalDAVFile(dirname(abspath(path)))
- calendarHome = CalendarHomeResource(arg, parent, dummyDirectoryRecord)
- checkExists(calendarHome)
- calendarHomes.add(calendarHome)
+ def opt_record(self, recordName):
+ """
+ Add a directory record's calendar home (format: 'recordType:shortName').
+ """
+ recordType, shortName = recordName.split(":", 1)
+ self.exporters.append(HomeExporter(recordType, shortName))
- elif opt in ("-r", "--record"):
- try:
- recordType, shortName = arg.split(":", 1)
- if not recordType or not shortName:
- raise ValueError()
- except ValueError:
- sys.stderr.write("Invalid record identifier: %r\n" % (arg,))
- sys.exit(1)
+ opt_r = opt_record
- records.add((recordType, shortName))
- elif opt in ("-u", "--user"):
- records.add((DirectoryService.recordType_users, arg))
+ def opt_collection(self, collectionName):
+ """
+ Add a calendar collection. This option must be passed after --record
+ (or a synonym, like --user). for example, to export user1's calendars
+ called 'meetings' and 'team', invoke 'calendarserver_export --user=user1
+ --collection=meetings --collection=team'.
+ """
+ self.exporters[-1].collections.append(collectionName)
- if args:
- usage("Too many arguments: %s" % (" ".join(args),))
+ opt_c = opt_collection
- if records:
- try:
- config = loadConfig(configFileName)
- config.directory = getDirectory()
- autoDisableMemcached(config)
- except ConfigurationError, e:
- sys.stdout.write("%s\n" % (e,))
- sys.exit(1)
- for record in records:
- recordType, shortName = record
- calendarHome = config.directory.calendarHomeForShortName(recordType, shortName)
- if not calendarHome:
- sys.stderr.write("No calendar home found for record: (%s)%s\n" % (recordType, shortName))
- sys.exit(1)
- calendarHomes.add(calendarHome)
+ def opt_output(self, filename):
+ """
+ Specify output file path (default: '-', meaning stdout).
+ """
+ self.outputName = filename
- for calendarHome in calendarHomes:
- for childName in calendarHome.listChildren():
- child = calendarHome.getChild(childName)
- if isCalendarCollectionResource(child):
- collections.add(child)
+ opt_o = opt_output
- try:
- calendar = iComponent("VCALENDAR")
- calendar.addProperty(iProperty("VERSION", "2.0"))
- calendar.addProperty(iProperty("PRODID", iCalendarProductID))
- uids = set()
- tzids = set()
+ def opt_user(self, user):
+ """
+ Add a user's calendar home (shorthand for '-r users:shortName').
+ """
+ self.opt_record("users:" + user)
- for collection in collections:
- for name, uid, type in collection.index().indexedSearch(None):
- child = collection.getChild(name)
- childData = child.iCalendarText()
+ opt_u = opt_user
- try:
- childCalendar = iComponent.fromString(childData)
- except ValueError:
- continue
- assert childCalendar.name() == "VCALENDAR"
- if uid in uids:
- sys.stderr.write("Skipping duplicate event UID %r from %s\n" % (uid, collection.fp.path))
- continue
- else:
- uids.add(uid)
+ def openOutput(self):
+ """
+ Open the appropriate output file based on the '--output' option.
+ """
+ if self.outputName == '-':
+ return sys.stdout
+ else:
+ return open(self.outputName, 'wb')
- for component in childCalendar.subcomponents():
- # Only insert VTIMEZONEs once
- if component.name() == "VTIMEZONE":
- tzid = component.propertyValue("TZID")
- if tzid in tzids:
- continue
- else:
- tzids.add(tzid)
- calendar.addComponent(component)
- calendarData = str(calendar)
+class HomeExporter(object):
+ """
+ An exporter that constructs a list of calendars based on the UID or
+ directory services record ID of the home.
- if outputFileName:
- try:
- output = open(outputFileName, "w")
- except IOError, e:
- sys.stderr.write("Unable to open output file for writing %s: %s\n" % (outputFileName, e))
- sys.exit(1)
+ @ivar collections: A list of the names of collections that this exporter
+ should enumerate.
+
+ @type collections: C{list} of C{str}
+
+ @ivar recordType: The directory record type to export. For example:
+ 'users'.
+
+ @type recordType: C{str}
+
+ @ivar shortName: The shortName of the directory record to export, according
+ to C{recordType}.
+ """
+
+ def __init__(self, recordType, shortName):
+ self.collections = []
+ self.recordType = recordType
+ self.shortName = shortName
+
+
+ @inlineCallbacks
+ def listCalendars(self, txn, exportService):
+ """
+ Enumerate all calendars based on the directory record and/or calendars
+ for this calendar home.
+ """
+ directory = exportService.directoryService()
+ record = directory.recordWithShortName(self.recordType, self.shortName)
+ home = yield txn.calendarHomeWithUID(record.guid, True)
+ result = []
+ if self.collections:
+ for collection in self.collections:
+ result.append((yield home.calendarWithName(collection)))
else:
- output = sys.stdout
+ for collection in (yield home.calendars()):
+ if collection.name() != 'inbox':
+ result.append(collection)
+ returnValue(result)
- output.write(calendarData)
- except UsageError, e:
- usage(e)
-if __name__ == "__main__":
- main()
+ at inlineCallbacks
+def exportToFile(calendars, fileobj):
+ """
+ Export some calendars to a file as their owner would see them.
+
+ @param calendars: an iterable of L{ICalendar} providers (or L{Deferred}s of
+ same).
+
+ @param fileobj: an object with a C{write} method that will accept some
+ iCalendar data.
+
+ @return: a L{Deferred} which fires when the export is complete. (Note that
+ the file will not be closed.)
+ @rtype: L{Deferred} that fires with C{None}
+ """
+ comp = Component.newCalendar()
+ for calendar in calendars:
+ calendar = yield calendar
+ for obj in (yield calendar.calendarObjects()):
+ evt = yield obj.filteredComponent(
+ calendar.ownerCalendarHome().uid(), True)
+ for sub in evt.subcomponents():
+ if sub.name() != 'VTIMEZONE':
+ # Omit all VTIMEZONE components, since PyCalendar will
+ # helpfully re-include all necessary VTIMEZONEs when we call
+ # __str__; see pycalendar.calendar.PyCalendar.generate() and
+ # .includeTimezones().
+ comp.addComponent(sub)
+
+ fileobj.write(str(comp))
+
+
+
+class ExporterService(Service, object):
+ """
+ Service which runs, exports the appropriate records, then stops the reactor.
+ """
+
+ def __init__(self, store, options, output, reactor, config):
+ super(ExporterService, self).__init__()
+ self.store = store
+ self.options = options
+ self.output = output
+ self.reactor = reactor
+ self.config = config
+ self._directory = None
+
+
+ def startService(self):
+ """
+ Start the service.
+ """
+ super(ExporterService, self).startService()
+ self.doExport()
+
+
+ @inlineCallbacks
+ def doExport(self):
+ """
+ Do the export, stopping the reactor when done.
+ """
+ txn = self.store.newTransaction()
+ try:
+ allCalendars = itertools.chain(
+ *[(yield exporter.listCalendars(txn, self)) for exporter in
+ self.options.exporters]
+ )
+ yield exportToFile(allCalendars, self.output)
+ yield txn.commit()
+ # TODO: should be read-only, so commit/abort shouldn't make a
+ # difference. commit() for now, in case any transparent cache /
+ # update stuff needed to happen, don't want to undo it.
+ self.output.close()
+ except:
+ log.err()
+
+ self.reactor.stop()
+
+
+ def directoryService(self):
+ """
+ Get an appropriate directory service for this L{ExporterService}'s
+ configuration, creating one first if necessary.
+ """
+ if self._directory is None:
+ self._directory = directoryFromConfig(self.config)
+ return self._directory
+
+
+ def stopService(self):
+ """
+ Stop the service. Nothing to do; everything should be finished by this
+ time.
+ """
+ # TODO: stopping this service mid-export should really stop the export
+ # loop, but this is not implemented because nothing will actually do it
+ # except hitting ^C (which also calls reactor.stop(), so that will exit
+ # anyway).
+
+
+
+def main(argv=sys.argv, stderr=sys.stderr, reactor=None):
+ """
+ Do the export.
+ """
+ if reactor is None:
+ from twisted.internet import reactor
+ options = ExportOptions()
+ options.parseOptions(argv[1:])
+ try:
+ output = options.openOutput()
+ except IOError, e:
+ stderr.write("Unable to open output file for writing: %s\n" %
+ (e))
+ sys.exit(1)
+ def makeService(store):
+ from twistedcaldav.config import config
+ return ExporterService(store, options, output, reactor, config)
+ utilityMain(options['config'], makeService, reactor)
+
+
Modified: CalendarServer/trunk/calendarserver/tools/purge.py
===================================================================
--- CalendarServer/trunk/calendarserver/tools/purge.py 2011-05-16 14:49:19 UTC (rev 7485)
+++ CalendarServer/trunk/calendarserver/tools/purge.py 2011-05-16 15:02:27 UTC (rev 7486)
@@ -1,5 +1,5 @@
#!/usr/bin/env python
-
+# -*- test-case-name: calendarserver.tools.test.test_purge -*-
##
# Copyright (c) 2006-2010 Apple Inc. All rights reserved.
#
@@ -19,12 +19,18 @@
import os
import sys
from errno import ENOENT, EACCES
-
from getopt import getopt, GetoptError
+from pycalendar.datetime import PyCalendarDateTime
+
from twisted.application.service import Service
from twisted.internet import reactor
from twisted.internet.defer import inlineCallbacks, returnValue
+
+from twext.python.log import Logger
+from twext.web2.dav import davxml
+from twext.web2.responsecode import NO_CONTENT
+
from twistedcaldav import caldavxml
from twistedcaldav.caldavxml import TimeRange
from twistedcaldav.config import config, ConfigurationError
@@ -33,16 +39,11 @@
from twistedcaldav.method.put_common import StoreCalendarObjectResource
from twistedcaldav.query import calendarqueryfilter
-from twext.python.log import Logger
-from twext.web2.dav import davxml
-from twext.web2.responsecode import NO_CONTENT
-
-from calendarserver.tap.caldav import CalDAVServiceMaker, CalDAVOptions
from calendarserver.tap.util import FakeRequest
from calendarserver.tap.util import getRootResource
+
+from calendarserver.tools.cmdline import utilityMain
from calendarserver.tools.principals import removeProxy
-from calendarserver.tools.util import loadConfig
-from pycalendar.datetime import PyCalendarDateTime
log = Logger()
@@ -205,27 +206,7 @@
-def shared_main(configFileName, serviceClass):
- try:
- loadConfig(configFileName)
-
- config.ProcessType = "Utility"
- config.UtilityServiceClass = serviceClass
-
- maker = CalDAVServiceMaker()
- options = CalDAVOptions
- service = maker.makeService(options)
-
- reactor.addSystemEventTrigger("during", "startup", service.startService)
- reactor.addSystemEventTrigger("before", "shutdown", service.stopService)
-
- except ConfigurationError, e:
- sys.stderr.write("Error: %s\n" % (e,))
- return
-
- reactor.run()
-
def main_purge_events():
try:
@@ -295,7 +276,7 @@
PurgeOldEventsService.dryrun = dryrun
PurgeOldEventsService.verbose = verbose
- shared_main(
+ utilityMain(
configFileName,
PurgeOldEventsService,
)
@@ -357,7 +338,7 @@
PurgeOrphanedAttachmentsService.dryrun = dryrun
PurgeOrphanedAttachmentsService.verbose = verbose
- shared_main(
+ utilityMain(
configFileName,
PurgeOrphanedAttachmentsService,
)
@@ -406,7 +387,7 @@
PurgePrincipalService.verbose = verbose
- shared_main(
+ utilityMain(
configFileName,
PurgePrincipalService
)
Copied: CalendarServer/trunk/calendarserver/tools/test/test_export.py (from rev 7485, CalendarServer/branches/users/glyph/new-export/calendarserver/tools/test/test_export.py)
===================================================================
--- CalendarServer/trunk/calendarserver/tools/test/test_export.py (rev 0)
+++ CalendarServer/trunk/calendarserver/tools/test/test_export.py 2011-05-16 15:02:27 UTC (rev 7486)
@@ -0,0 +1,484 @@
+##
+# Copyright (c) 2011 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.
+##
+
+"""
+Unit tests for L{calendarsever.tools.export}.
+"""
+
+
+import sys
+from cStringIO import StringIO
+
+from twisted.trial.unittest import TestCase
+
+from twisted.internet.defer import inlineCallbacks
+from twisted.python.modules import getModule
+
+from twext.enterprise.ienterprise import AlreadyFinishedError
+
+from twistedcaldav.ical import Component
+from twistedcaldav.directory import augment
+from twistedcaldav.datafilters.test.test_peruserdata import dataForTwoUsers
+from twistedcaldav.datafilters.test.test_peruserdata import resultForUser2
+
+from calendarserver.tools import export
+from calendarserver.tools.export import ExportOptions, main
+from calendarserver.tools.export import HomeExporter
+
+from twisted.python.filepath import FilePath
+from twistedcaldav.test.util import patchConfig
+from twisted.internet.defer import Deferred
+
+from txdav.common.datastore.test.util import buildStore
+from txdav.common.datastore.test.util import populateCalendarsFrom
+
+from calendarserver.tools.export import usage, exportToFile
+
+def holiday(uid):
+ return (
+ getModule("twistedcaldav.test").filePath
+ .sibling("data").child("Holidays").child(uid + ".ics")
+ .getContent()
+ )
+
+def sample(name):
+ return (
+ getModule("twistedcaldav.test").filePath
+ .sibling("data").child(name + ".ics").getContent()
+ )
+
+valentines = holiday("C31854DA-1ED0-11D9-A5E0-000A958A3252")
+newYears = holiday("C3184A66-1ED0-11D9-A5E0-000A958A3252")
+payday = sample("PayDay")
+
+one = sample("OneEvent")
+another = sample("AnotherEvent")
+third = sample("ThirdEvent")
+
+
+class CommandLine(TestCase):
+ """
+ Simple tests for command-line parsing.
+ """
+
+ def test_usageMessage(self):
+ """
+ The 'usage' message should print something to standard output (and
+ nothing to standard error) and exit.
+ """
+ orig = sys.stdout
+ orige = sys.stderr
+ try:
+ out = sys.stdout = StringIO()
+ err = sys.stderr = StringIO()
+ self.assertRaises(SystemExit, usage)
+ finally:
+ sys.stdout = orig
+ sys.stderr = orige
+ self.assertEquals(len(out.getvalue()) > 0, True, "No output.")
+ self.assertEquals(len(err.getvalue()), 0)
+
+
+ def test_oneHome(self):
+ """
+ One '--record' option will result in a single HomeExporter object with
+ no calendars in its list.
+ """
+ eo = ExportOptions()
+ eo.parseOptions(["--record", "users:bob"])
+ self.assertEquals(len(eo.exporters), 1)
+ exp = eo.exporters[0]
+ self.assertIsInstance(exp, HomeExporter)
+ self.assertEquals(exp.recordType, "users")
+ self.assertEquals(exp.shortName, "bob")
+ self.assertEquals(exp.collections, [])
+
+
+ def test_homeAndCollections(self):
+ """
+ The --collection option adds calendars to the last calendar that was
+ exported.
+ """
+ eo = ExportOptions()
+ eo.parseOptions(["--record", "users:bob",
+ "--collection", "work stuff",
+ "--record", "users:jethro",
+ "--collection=fun stuff"])
+ self.assertEquals(len(eo.exporters), 2)
+ exp = eo.exporters[0]
+ self.assertEquals(exp.recordType, "users")
+ self.assertEquals(exp.shortName, "bob")
+ self.assertEquals(exp.collections, ["work stuff"])
+ exp = eo.exporters[1]
+ self.assertEquals(exp.recordType, "users")
+ self.assertEquals(exp.shortName, "jethro")
+ self.assertEquals(exp.collections, ["fun stuff"])
+
+
+ def test_outputFileSelection(self):
+ """
+ The --output option selects the file to write to, '-' or no parameter
+ meaning stdout; the L{ExportOptions.openOutput} method returns that
+ file.
+ """
+ eo = ExportOptions()
+ eo.parseOptions([])
+ self.assertIdentical(eo.openOutput(), sys.stdout)
+ eo = ExportOptions()
+ eo.parseOptions(["--output", "-"])
+ self.assertIdentical(eo.openOutput(), sys.stdout)
+ eo = ExportOptions()
+ tmpnam = self.mktemp()
+ eo.parseOptions(["--output", tmpnam])
+ self.assertEquals(eo.openOutput().name, tmpnam)
+
+
+ def test_outputFileError(self):
+ """
+ If the output file cannot be opened for writing, an error will be
+ displayed to the user on stderr.
+ """
+ io = StringIO()
+ systemExit = self.assertRaises(
+ SystemExit, main, ['calendarserver_export',
+ '--output', '/not/a/file'], io
+ )
+ self.assertEquals(systemExit.code, 1)
+ self.assertEquals(
+ io.getvalue(),
+ "Unable to open output file for writing: "
+ "[Errno 2] No such file or directory: '/not/a/file'\n")
+
+
+
+class IntegrationTests(TestCase):
+ """
+ Tests for exporting data from a live store.
+ """
+
+ accountsFile = 'no-accounts.xml'
+ augmentsFile = 'no-augments.xml'
+
+ @inlineCallbacks
+ def setUp(self):
+ """
+ Set up a store and fix the imported C{utilityMain} function (normally
+ from L{calendarserver.tools.cmdline.utilityMain}) to point to a
+ temporary method of this class. Also, patch the imported C{reactor},
+ since the SUT needs to call C{reactor.stop()} in order to work with
+ L{utilityMain}.
+ """
+ self.mainCalled = False
+ self.patch(export, "utilityMain", self.fakeUtilityMain)
+
+
+ self.store = yield buildStore(self, None)
+ self.waitToStop = Deferred()
+
+
+ def stop(self):
+ """
+ Emulate reactor.stop(), which the service must call when it is done with
+ work.
+ """
+ self.waitToStop.callback(None)
+
+
+ def fakeUtilityMain(self, configFileName, serviceClass, reactor=None):
+ """
+ Verify a few basic things.
+ """
+ if self.mainCalled:
+ raise RuntimeError(
+ "Main called twice during this test; duplicate reactor run.")
+
+ # In lieu of a configuration file, patch up the augment service and make
+ # it so directoryFromConfig will return something useful. Don't
+ # actually need to patch the augment service to a real fake; just patch
+ # it so that trial will restore the previous one when this test has
+ # completed.
+
+ self.patch(augment, "AugmentService", None)
+
+ patchConfig(
+ self,
+ DirectoryService=dict(
+ type="twistedcaldav.directory.xmlfile.XMLDirectoryService",
+ params=dict(
+ xmlFile=self.accountsFile
+ )
+ ),
+ ResourceService=dict(Enabled=False),
+ AugmentService=dict(
+ type="twistedcaldav.directory.augment.AugmentXMLDB",
+ params=dict(
+ xmlFiles=[self.augmentsFile]
+ )
+ )
+ )
+
+ self.mainCalled = True
+ self.usedConfigFile = configFileName
+ self.usedReactor = reactor
+ self.exportService = serviceClass(self.store)
+ self.exportService.startService()
+ self.addCleanup(self.exportService.stopService)
+
+
+ @inlineCallbacks
+ def test_serviceState(self):
+ """
+ export.main() invokes utilityMain with the configuration file specified
+ on the command line, and creates an L{ExporterService} pointed at the
+ appropriate store.
+ """
+ tempConfig = self.mktemp()
+ main(['calendarserver_export', '--config', tempConfig, '--output',
+ self.mktemp()], reactor=self)
+ self.assertEquals(self.mainCalled, True, "Main not called.")
+ self.assertEquals(self.usedConfigFile, tempConfig)
+ self.assertEquals(self.usedReactor, self)
+ self.assertEquals(self.exportService.store, self.store)
+ yield self.waitToStop
+
+
+ @inlineCallbacks
+ def test_emptyCalendar(self):
+ """
+ Exporting an empty calendar results in an empty calendar.
+ """
+ io = StringIO()
+ value = yield exportToFile([], io)
+ # it doesn't return anything, it writes to the file.
+ self.assertEquals(value, None)
+ # but it should write a valid component to the file.
+ self.assertEquals(Component.fromString(io.getvalue()),
+ Component.newCalendar())
+
+
+ def txn(self):
+ """
+ Create a new transaction and automatically clean it up when the test
+ completes.
+ """
+ aTransaction = self.store.newTransaction()
+ @inlineCallbacks
+ def maybeAbort():
+ try:
+ yield aTransaction.abort()
+ except AlreadyFinishedError:
+ pass
+ self.addCleanup(maybeAbort)
+ return aTransaction
+
+
+ @inlineCallbacks
+ def test_oneEventCalendar(self):
+ """
+ Exporting an calendar with one event in it will result in just that
+ event.
+ """
+ yield populateCalendarsFrom(
+ {
+ "home1": {
+ "calendar1": {
+ "valentines-day.ics": (valentines, {})
+ }
+ }
+ }, self.store
+ )
+
+ expected = Component.newCalendar()
+ [theComponent] = Component.fromString(valentines).subcomponents()
+ expected.addComponent(theComponent)
+
+ io = StringIO()
+ yield exportToFile(
+ [(yield self.txn().calendarHomeWithUID("home1"))
+ .calendarWithName("calendar1")], io
+ )
+ self.assertEquals(Component.fromString(io.getvalue()),
+ expected)
+
+
+ @inlineCallbacks
+ def test_twoSimpleEvents(self):
+ """
+ Exporting a calendar with two events in it will result in a VCALENDAR
+ component with both VEVENTs in it.
+ """
+ yield populateCalendarsFrom(
+ {
+ "home1": {
+ "calendar1": {
+ "valentines-day.ics": (valentines, {}),
+ "new-years-day.ics": (newYears, {})
+ }
+ }
+ }, self.store
+ )
+
+ expected = Component.newCalendar()
+ a = Component.fromString(valentines)
+ b = Component.fromString(newYears)
+ for comp in a, b:
+ for sub in comp.subcomponents():
+ expected.addComponent(sub)
+
+ io = StringIO()
+ yield exportToFile(
+ [(yield self.txn().calendarHomeWithUID("home1"))
+ .calendarWithName("calendar1")], io
+ )
+ self.assertEquals(Component.fromString(io.getvalue()),
+ expected)
+
+
+ @inlineCallbacks
+ def test_onlyOneVTIMEZONE(self):
+ """
+ C{VTIMEZONE} subcomponents with matching TZIDs in multiple event
+ calendar objects should only be rendered in the resulting output once.
+
+ (Note that the code to suppor this is actually in PyCalendar, not the
+ export tool itself.)
+ """
+ yield populateCalendarsFrom(
+ {
+ "home1": {
+ "calendar1": {
+ "1.ics": (one, {}), # EST
+ "2.ics": (another, {}), # EST
+ "3.ics": (third, {}) # PST
+ }
+ }
+ }, self.store
+ )
+
+ io = StringIO()
+ yield exportToFile(
+ [(yield self.txn().calendarHomeWithUID("home1"))
+ .calendarWithName("calendar1")], io
+ )
+ result = Component.fromString(io.getvalue())
+
+ def filtered(name):
+ for c in result.subcomponents():
+ if c.name() == name:
+ yield c
+
+ timezones = list(filtered("VTIMEZONE"))
+ events = list(filtered("VEVENT"))
+
+ # Sanity check to make sure we picked up all three events:
+ self.assertEquals(len(events), 3)
+
+ self.assertEquals(len(timezones), 2)
+ self.assertEquals(set([tz.propertyValue("TZID") for tz in timezones]),
+
+ # Use an intentionally wrong TZID in order to make
+ # sure we don't depend on caching effects elsewhere.
+ set(["America/New_Yrok", "US/Pacific"]))
+
+
+ @inlineCallbacks
+ def test_perUserFiltering(self):
+ """
+ L{exportToFile} performs per-user component filtering based on the owner
+ of that calendar.
+ """
+ yield populateCalendarsFrom(
+ {
+ "user02": {
+ "calendar1": {
+ "peruser.ics": (dataForTwoUsers, {}), # EST
+ }
+ }
+ }, self.store
+ )
+ io = StringIO()
+ yield exportToFile(
+ [(yield self.txn().calendarHomeWithUID("user02"))
+ .calendarWithName("calendar1")], io
+ )
+ self.assertEquals(
+ Component.fromString(resultForUser2),
+ Component.fromString(io.getvalue())
+ )
+
+
+ @inlineCallbacks
+ def test_full(self):
+ """
+ Running C{calendarserver_export} on the command line exports an ics
+ file. (Almost-full integration test, starting from the main point, using
+ as few test fakes as possible.)
+
+ Note: currently the only test for directory interaction.
+ """
+ yield populateCalendarsFrom(
+ {
+ "user02": {
+ # TODO: more direct test for skipping inbox
+ "inbox": {
+ "inbox-item.ics": (valentines, {})
+ },
+ "calendar1": {
+ "peruser.ics": (dataForTwoUsers, {}), # EST
+ }
+ }
+ }, self.store
+ )
+
+ augmentsData = """
+ <augments>
+ <record>
+ <uid>Default</uid>
+ <enable>true</enable>
+ <enable-calendar>true</enable-calendar>
+ <enable-addressbook>true</enable-addressbook>
+ </record>
+ </augments>
+ """
+ augments = FilePath(self.mktemp())
+ augments.setContent(augmentsData)
+
+ accountsData = """
+ <accounts realm="Test Realm">
+ <user>
+ <uid>user-under-test</uid>
+ <guid>user02</guid>
+ <name>Not Interesting</name>
+ <password>very-secret</password>
+ </user>
+ </accounts>
+ """
+ accounts = FilePath(self.mktemp())
+ accounts.setContent(accountsData)
+ output = FilePath(self.mktemp())
+ self.accountsFile = accounts.path
+ self.augmentsFile = augments.path
+ main(['calendarserver_export', '--output',
+ output.path, '--user', 'user-under-test'], reactor=self)
+
+ yield self.waitToStop
+
+ self.assertEquals(
+ Component.fromString(resultForUser2),
+ Component.fromString(output.getContent())
+ )
+
+
Modified: CalendarServer/trunk/calendarserver/tools/test/test_purge_old_events.py
===================================================================
--- CalendarServer/trunk/calendarserver/tools/test/test_purge_old_events.py 2011-05-16 14:49:19 UTC (rev 7485)
+++ CalendarServer/trunk/calendarserver/tools/test/test_purge_old_events.py 2011-05-16 15:02:27 UTC (rev 7486)
@@ -26,7 +26,6 @@
from twisted.trial import unittest
from twistedcaldav.config import config
-from twistedcaldav.memcacher import Memcacher
from twistedcaldav.vcard import Component as VCardComponent
from txdav.common.datastore.test.util import buildStore, populateCalendarsFrom, CommonCommonTests
@@ -348,9 +347,6 @@
@inlineCallbacks
def setUp(self):
- self.patch(config.Memcached.Pools.Default, "ClientEnabled", False)
- self.patch(config.Memcached.Pools.Default, "ServerEnabled", False)
- self.patch(Memcacher, "allowTestCache", True)
yield super(PurgeOldEventsTests, self).setUp()
self._sqlCalendarStore = yield buildStore(self, self.notifierFactory)
yield self.populate()
Modified: CalendarServer/trunk/calendarserver/tools/util.py
===================================================================
--- CalendarServer/trunk/calendarserver/tools/util.py 2011-05-16 14:49:19 UTC (rev 7485)
+++ CalendarServer/trunk/calendarserver/tools/util.py 2011-05-16 15:02:27 UTC (rev 7486)
@@ -1,5 +1,5 @@
##
-# Copyright (c) 2008-2010 Apple Inc. All rights reserved.
+# Copyright (c) 2008-2011 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.
@@ -14,6 +14,10 @@
# limitations under the License.
##
+"""
+Utility functionality shared between calendarserver tools.
+"""
+
__all__ = [
"loadConfig",
"getDirectory",
@@ -34,6 +38,7 @@
from calendarserver.provision.root import RootResource
+
from twistedcaldav import memcachepool
from twistedcaldav.config import config, ConfigurationError
from twistedcaldav.directory import augment, calendaruserproxy
@@ -270,3 +275,5 @@
% (description, dirpath)
)
+
+
Property changes on: CalendarServer/trunk/support/build.sh
___________________________________________________________________
Modified: svn:mergeinfo
- /CalendarServer/branches/config-separation/support/build.sh:4379-4443
/CalendarServer/branches/egg-info-351/support/build.sh:4589-4615
/CalendarServer/branches/generic-sqlstore/support/build.sh:6167-6191
/CalendarServer/branches/new-store/support/build.sh:5594-5934
/CalendarServer/branches/new-store-no-caldavfile/support/build.sh:5911-5935
/CalendarServer/branches/new-store-no-caldavfile-2/support/build.sh:5936-5981
/CalendarServer/branches/users/cdaboo/cached-subscription-calendars-5692/support/build.sh:5693-5702
/CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/support/build.sh:3628-3644
/CalendarServer/branches/users/cdaboo/more-sharing-5591/support/build.sh:5592-5601
/CalendarServer/branches/users/cdaboo/partition-4464/support/build.sh:4465-4957
/CalendarServer/branches/users/cdaboo/pods/support/build.sh:7297-7377
/CalendarServer/branches/users/cdaboo/pycalendar/support/build.sh:7085-7206
/CalendarServer/branches/users/cdaboo/pycard/support/build.sh:7227-7237
/CalendarServer/branches/users/cdaboo/relative-config-paths-5070/support/build.sh:5071-5105
/CalendarServer/branches/users/cdaboo/shared-calendars-5187/support/build.sh:5188-5440
/CalendarServer/branches/users/glyph/conn-limit/support/build.sh:6574-6577
/CalendarServer/branches/users/glyph/contacts-server-merge/support/build.sh:4971-5080
/CalendarServer/branches/users/glyph/dalify/support/build.sh:6932-7023
/CalendarServer/branches/users/glyph/db-reconnect/support/build.sh:6824-6876
/CalendarServer/branches/users/glyph/dont-start-postgres/support/build.sh:6592-6614
/CalendarServer/branches/users/glyph/linux-tests/support/build.sh:6893-6900
/CalendarServer/branches/users/glyph/misc-portability-fixes/support/build.sh:7365-7374
/CalendarServer/branches/users/glyph/more-deferreds-6/support/build.sh:6322-6368
/CalendarServer/branches/users/glyph/more-deferreds-7/support/build.sh:6369-6445
/CalendarServer/branches/users/glyph/oracle-nulls/support/build.sh:7340-7351
/CalendarServer/branches/users/glyph/sendfdport/support/build.sh:5388-5424
/CalendarServer/branches/users/glyph/sharedpool/support/build.sh:6490-6550
/CalendarServer/branches/users/glyph/sql-store/support/build.sh:5929-6073
/CalendarServer/branches/users/glyph/subtransactions/support/build.sh:7248-7258
/CalendarServer/branches/users/glyph/use-system-twisted/support/build.sh:5084-5149
/CalendarServer/branches/users/sagen/inboxitems/support/build.sh:7380-7381
/CalendarServer/branches/users/sagen/locations-resources/support/build.sh:5032-5051
/CalendarServer/branches/users/sagen/locations-resources-2/support/build.sh:5052-5061
/CalendarServer/branches/users/sagen/purge_old_events/support/build.sh:6735-6746
/CalendarServer/branches/users/sagen/resource-delegates-4038/support/build.sh:4040-4067
/CalendarServer/branches/users/sagen/resource-delegates-4066/support/build.sh:4068-4075
/CalendarServer/branches/users/sagen/resources-2/support/build.sh:5084-5093
/CalendarServer/branches/users/wsanchez/transations/support/build.sh:5515-5593
+ /CalendarServer/branches/config-separation/support/build.sh:4379-4443
/CalendarServer/branches/egg-info-351/support/build.sh:4589-4615
/CalendarServer/branches/generic-sqlstore/support/build.sh:6167-6191
/CalendarServer/branches/new-store/support/build.sh:5594-5934
/CalendarServer/branches/new-store-no-caldavfile/support/build.sh:5911-5935
/CalendarServer/branches/new-store-no-caldavfile-2/support/build.sh:5936-5981
/CalendarServer/branches/users/cdaboo/cached-subscription-calendars-5692/support/build.sh:5693-5702
/CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/support/build.sh:3628-3644
/CalendarServer/branches/users/cdaboo/more-sharing-5591/support/build.sh:5592-5601
/CalendarServer/branches/users/cdaboo/partition-4464/support/build.sh:4465-4957
/CalendarServer/branches/users/cdaboo/pods/support/build.sh:7297-7377
/CalendarServer/branches/users/cdaboo/pycalendar/support/build.sh:7085-7206
/CalendarServer/branches/users/cdaboo/pycard/support/build.sh:7227-7237
/CalendarServer/branches/users/cdaboo/relative-config-paths-5070/support/build.sh:5071-5105
/CalendarServer/branches/users/cdaboo/shared-calendars-5187/support/build.sh:5188-5440
/CalendarServer/branches/users/glyph/conn-limit/support/build.sh:6574-6577
/CalendarServer/branches/users/glyph/contacts-server-merge/support/build.sh:4971-5080
/CalendarServer/branches/users/glyph/dalify/support/build.sh:6932-7023
/CalendarServer/branches/users/glyph/db-reconnect/support/build.sh:6824-6876
/CalendarServer/branches/users/glyph/dont-start-postgres/support/build.sh:6592-6614
/CalendarServer/branches/users/glyph/linux-tests/support/build.sh:6893-6900
/CalendarServer/branches/users/glyph/misc-portability-fixes/support/build.sh:7365-7374
/CalendarServer/branches/users/glyph/more-deferreds-6/support/build.sh:6322-6368
/CalendarServer/branches/users/glyph/more-deferreds-7/support/build.sh:6369-6445
/CalendarServer/branches/users/glyph/new-export/support/build.sh:7444-7485
/CalendarServer/branches/users/glyph/oracle-nulls/support/build.sh:7340-7351
/CalendarServer/branches/users/glyph/sendfdport/support/build.sh:5388-5424
/CalendarServer/branches/users/glyph/sharedpool/support/build.sh:6490-6550
/CalendarServer/branches/users/glyph/sql-store/support/build.sh:5929-6073
/CalendarServer/branches/users/glyph/subtransactions/support/build.sh:7248-7258
/CalendarServer/branches/users/glyph/use-system-twisted/support/build.sh:5084-5149
/CalendarServer/branches/users/sagen/inboxitems/support/build.sh:7380-7381
/CalendarServer/branches/users/sagen/locations-resources/support/build.sh:5032-5051
/CalendarServer/branches/users/sagen/locations-resources-2/support/build.sh:5052-5061
/CalendarServer/branches/users/sagen/purge_old_events/support/build.sh:6735-6746
/CalendarServer/branches/users/sagen/resource-delegates-4038/support/build.sh:4040-4067
/CalendarServer/branches/users/sagen/resource-delegates-4066/support/build.sh:4068-4075
/CalendarServer/branches/users/sagen/resources-2/support/build.sh:5084-5093
/CalendarServer/branches/users/wsanchez/transations/support/build.sh:5515-5593
Modified: CalendarServer/trunk/twistedcaldav/datafilters/test/test_peruserdata.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/datafilters/test/test_peruserdata.py 2011-05-16 14:49:19 UTC (rev 7485)
+++ CalendarServer/trunk/twistedcaldav/datafilters/test/test_peruserdata.py 2011-05-16 15:02:27 UTC (rev 7486)
@@ -18,11 +18,7 @@
from twistedcaldav.ical import Component
from twistedcaldav.datafilters.peruserdata import PerUserDataFilter
-class PerUserDataFilterTestNotRecurring (twistedcaldav.test.util.TestCase):
-
- def test_public_noperuser(self):
-
- data = """BEGIN:VCALENDAR
+dataForTwoUsers = """BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
BEGIN:VEVENT
@@ -33,17 +29,35 @@
ATTENDEE:mailto:user2 at example.com
ORGANIZER;CN=User 01:mailto:user1 at example.com
END:VEVENT
+BEGIN:X-CALENDARSERVER-PERUSER
+UID:12345-67890
+X-CALENDARSERVER-PERUSER-UID:user01
+BEGIN:X-CALENDARSERVER-PERINSTANCE
+BEGIN:VALARM
+ACTION:DISPLAY
+DESCRIPTION:Test01
+TRIGGER;RELATED=START:-PT10M
+END:VALARM
+TRANSP:OPAQUE
+END:X-CALENDARSERVER-PERINSTANCE
+END:X-CALENDARSERVER-PERUSER
+BEGIN:X-CALENDARSERVER-PERUSER
+UID:12345-67890
+X-CALENDARSERVER-PERUSER-UID:user02
+BEGIN:X-CALENDARSERVER-PERINSTANCE
+BEGIN:VALARM
+ACTION:DISPLAY
+DESCRIPTION:Test02
+TRIGGER;RELATED=START:-PT10M
+END:VALARM
+TRANSP:TRANSPARENT
+END:X-CALENDARSERVER-PERINSTANCE
+END:X-CALENDARSERVER-PERUSER
END:VCALENDAR
""".replace("\n", "\r\n")
-
- for item in (data, Component.fromString(data),):
- self.assertEqual(str(PerUserDataFilter("user01").filter(item)), data)
- for item in (data, Component.fromString(data),):
- self.assertEqual(str(PerUserDataFilter("").filter(item)), data)
- def test_public_oneuser(self):
-
- data = """BEGIN:VCALENDAR
+
+resultForUser1 = """BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
BEGIN:VEVENT
@@ -53,22 +67,18 @@
ATTENDEE:mailto:user1 at example.com
ATTENDEE:mailto:user2 at example.com
ORGANIZER;CN=User 01:mailto:user1 at example.com
-END:VEVENT
-BEGIN:X-CALENDARSERVER-PERUSER
-UID:12345-67890
-X-CALENDARSERVER-PERUSER-UID:user01
-BEGIN:X-CALENDARSERVER-PERINSTANCE
+TRANSP:OPAQUE
BEGIN:VALARM
ACTION:DISPLAY
-DESCRIPTION:Test
+DESCRIPTION:Test01
TRIGGER;RELATED=START:-PT10M
END:VALARM
-TRANSP:OPAQUE
-END:X-CALENDARSERVER-PERINSTANCE
-END:X-CALENDARSERVER-PERUSER
+END:VEVENT
END:VCALENDAR
""".replace("\n", "\r\n")
- result01 = """BEGIN:VCALENDAR
+
+
+resultForUser2 = """BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
BEGIN:VEVENT
@@ -78,16 +88,18 @@
ATTENDEE:mailto:user1 at example.com
ATTENDEE:mailto:user2 at example.com
ORGANIZER;CN=User 01:mailto:user1 at example.com
-TRANSP:OPAQUE
+TRANSP:TRANSPARENT
BEGIN:VALARM
ACTION:DISPLAY
-DESCRIPTION:Test
+DESCRIPTION:Test02
TRIGGER;RELATED=START:-PT10M
END:VALARM
END:VEVENT
END:VCALENDAR
""".replace("\n", "\r\n")
- result02 = """BEGIN:VCALENDAR
+
+
+resultForOtherUser = """BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
BEGIN:VEVENT
@@ -100,15 +112,33 @@
END:VEVENT
END:VCALENDAR
""".replace("\n", "\r\n")
+
+
+
+class PerUserDataFilterTestNotRecurring (twistedcaldav.test.util.TestCase):
+
+ def test_public_noperuser(self):
+ data = """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890
+DTSTART:20080601T120000Z
+DTEND:20080601T130000Z
+ATTENDEE:mailto:user1 at example.com
+ATTENDEE:mailto:user2 at example.com
+ORGANIZER;CN=User 01:mailto:user1 at example.com
+END:VEVENT
+END:VCALENDAR
+""".replace("\n", "\r\n")
+
for item in (data, Component.fromString(data),):
- self.assertEqual(str(PerUserDataFilter("user01").filter(item)), result01)
+ self.assertEqual(str(PerUserDataFilter("user01").filter(item)), data)
for item in (data, Component.fromString(data),):
- self.assertEqual(str(PerUserDataFilter("user02").filter(item)), result02)
- for item in (data, Component.fromString(data),):
- self.assertEqual(str(PerUserDataFilter("").filter(item)), result02)
+ self.assertEqual(str(PerUserDataFilter("").filter(item)), data)
- def test_public_twousers(self):
+ def test_public_oneuser(self):
data = """BEGIN:VCALENDAR
VERSION:2.0
@@ -127,24 +157,12 @@
BEGIN:X-CALENDARSERVER-PERINSTANCE
BEGIN:VALARM
ACTION:DISPLAY
-DESCRIPTION:Test01
+DESCRIPTION:Test
TRIGGER;RELATED=START:-PT10M
END:VALARM
TRANSP:OPAQUE
END:X-CALENDARSERVER-PERINSTANCE
END:X-CALENDARSERVER-PERUSER
-BEGIN:X-CALENDARSERVER-PERUSER
-UID:12345-67890
-X-CALENDARSERVER-PERUSER-UID:user02
-BEGIN:X-CALENDARSERVER-PERINSTANCE
-BEGIN:VALARM
-ACTION:DISPLAY
-DESCRIPTION:Test02
-TRIGGER;RELATED=START:-PT10M
-END:VALARM
-TRANSP:TRANSPARENT
-END:X-CALENDARSERVER-PERINSTANCE
-END:X-CALENDARSERVER-PERUSER
END:VCALENDAR
""".replace("\n", "\r\n")
result01 = """BEGIN:VCALENDAR
@@ -160,7 +178,7 @@
TRANSP:OPAQUE
BEGIN:VALARM
ACTION:DISPLAY
-DESCRIPTION:Test01
+DESCRIPTION:Test
TRIGGER;RELATED=START:-PT10M
END:VALARM
END:VEVENT
@@ -176,38 +194,39 @@
ATTENDEE:mailto:user1 at example.com
ATTENDEE:mailto:user2 at example.com
ORGANIZER;CN=User 01:mailto:user1 at example.com
-TRANSP:TRANSPARENT
-BEGIN:VALARM
-ACTION:DISPLAY
-DESCRIPTION:Test02
-TRIGGER;RELATED=START:-PT10M
-END:VALARM
END:VEVENT
END:VCALENDAR
""".replace("\n", "\r\n")
- result03 = """BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
-BEGIN:VEVENT
-UID:12345-67890
-DTSTART:20080601T120000Z
-DTEND:20080601T130000Z
-ATTENDEE:mailto:user1 at example.com
-ATTENDEE:mailto:user2 at example.com
-ORGANIZER;CN=User 01:mailto:user1 at example.com
-END:VEVENT
-END:VCALENDAR
-""".replace("\n", "\r\n")
-
+
for item in (data, Component.fromString(data),):
self.assertEqual(str(PerUserDataFilter("user01").filter(item)), result01)
for item in (data, Component.fromString(data),):
self.assertEqual(str(PerUserDataFilter("user02").filter(item)), result02)
for item in (data, Component.fromString(data),):
- self.assertEqual(str(PerUserDataFilter("user03").filter(item)), result03)
- for item in (data, Component.fromString(data),):
- self.assertEqual(str(PerUserDataFilter("").filter(item)), result03)
+ self.assertEqual(str(PerUserDataFilter("").filter(item)), result02)
+
+ def test_public_twousers(self):
+ """
+ A component with data for 2 users can return results for either of the
+ two users, or for a third user who has no per-user data embedded in it.
+ """
+
+ for item in (dataForTwoUsers, Component.fromString(dataForTwoUsers),):
+ self.assertEqual(str(PerUserDataFilter("user01").filter(item)),
+ resultForUser1)
+ for item in (dataForTwoUsers, Component.fromString(dataForTwoUsers),):
+ self.assertEqual(str(PerUserDataFilter("user02").filter(item)),
+ resultForUser2)
+ for item in (dataForTwoUsers, Component.fromString(dataForTwoUsers),):
+ self.assertEqual(str(PerUserDataFilter("user03").filter(item)),
+ resultForOtherUser)
+ for item in (dataForTwoUsers, Component.fromString(dataForTwoUsers),):
+ self.assertEqual(str(PerUserDataFilter("").filter(item)),
+ resultForOtherUser)
+
+
+
class PerUserDataFilterTestRecurring (twistedcaldav.test.util.TestCase):
def test_public_noperuser(self):
Modified: CalendarServer/trunk/twistedcaldav/ical.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/ical.py 2011-05-16 14:49:19 UTC (rev 7485)
+++ CalendarServer/trunk/twistedcaldav/ical.py 2011-05-16 15:02:27 UTC (rev 7486)
@@ -1,3 +1,4 @@
+# -*- test-case-name: twistedcaldav.test.test_icalendar -*-
##
# Copyright (c) 2005-2010 Apple Inc. All rights reserved.
#
@@ -362,6 +363,22 @@
def parse(data): return clazz.fromString(data)
return allDataFromStream(IStream(stream), parse)
+
+ @classmethod
+ def newCalendar(cls):
+ """
+ Create and return an empty C{VCALENDAR} component.
+
+ @return: a new C{VCALENDAR} component with appropriate metadata
+ properties already set (version, product ID).
+ @rtype: an instance of this class
+ """
+ self = cls("VCALENDAR")
+ self.addProperty(Property("VERSION", "2.0"))
+ self.addProperty(Property("PRODID", iCalendarProductID))
+ return self
+
+
def __init__(self, name, **kwargs):
"""
Use this constructor to initialize an empty L{Component}.
Modified: CalendarServer/trunk/twistedcaldav/method/get.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/method/get.py 2011-05-16 14:49:19 UTC (rev 7485)
+++ CalendarServer/trunk/twistedcaldav/method/get.py 2011-05-16 15:02:27 UTC (rev 7486)
@@ -81,7 +81,7 @@
if self.accessMode:
# Non DAV:owner's have limited access to the data
- isowner = (yield self.isOwner(request, adminprincipals=True, readprincipals=True))
+ isowner = (yield self.isOwner(request))
# Now "filter" the resource calendar data
caldata = PrivateEventFilter(self.accessMode, isowner).filter(caldata)
Modified: CalendarServer/trunk/twistedcaldav/method/report_calendar_query.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/method/report_calendar_query.py 2011-05-16 14:49:19 UTC (rev 7485)
+++ CalendarServer/trunk/twistedcaldav/method/report_calendar_query.py 2011-05-16 15:02:27 UTC (rev 7486)
@@ -174,7 +174,7 @@
filteredaces = (yield calresource.inheritedACEsforChildren(request))
# Check private events access status
- isowner = (yield calresource.isOwner(request, adminprincipals=True, readprincipals=True))
+ isowner = (yield calresource.isOwner(request))
# Check for disabled access
if filteredaces is not None:
@@ -229,7 +229,7 @@
timezone = tuple(tz.calendar().subcomponents())[0]
# Check private events access status
- isowner = (yield calresource.isOwner(request, adminprincipals=True, readprincipals=True))
+ isowner = (yield calresource.isOwner(request))
calendar = (yield calresource.iCalendarForUser(request))
yield queryCalendarObjectResource(calresource, uri, None, calendar, timezone)
Modified: CalendarServer/trunk/twistedcaldav/method/report_multiget_common.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/method/report_multiget_common.py 2011-05-16 14:49:19 UTC (rev 7485)
+++ CalendarServer/trunk/twistedcaldav/method/report_multiget_common.py 2011-05-16 15:02:27 UTC (rev 7486)
@@ -139,7 +139,7 @@
disabled = True
# Check private events access status
- isowner = (yield self.isOwner(request, adminprincipals=True, readprincipals=True))
+ isowner = (yield self.isOwner(request))
elif self.isAddressBookCollection():
requestURIis = "addressbook"
@@ -352,7 +352,7 @@
filteredaces = (yield parent.inheritedACEsforChildren(request))
# Check private events access status
- isowner = (yield parent.isOwner(request, adminprincipals=True, readprincipals=True))
+ isowner = (yield parent.isOwner(request))
else:
name = unquote(resource_uri[resource_uri.rfind("/") + 1:])
if (resource_uri != request.uri) or not self.exists():
@@ -376,7 +376,7 @@
filteredaces = (yield parent.inheritedACEsforChildren(request))
# Check private events access status
- isowner = (yield parent.isOwner(request, adminprincipals=True, readprincipals=True))
+ isowner = (yield parent.isOwner(request))
# Check privileges - must have at least DAV:read
try:
Modified: CalendarServer/trunk/twistedcaldav/resource.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/resource.py 2011-05-16 14:49:19 UTC (rev 7485)
+++ CalendarServer/trunk/twistedcaldav/resource.py 2011-05-16 15:02:27 UTC (rev 7486)
@@ -878,7 +878,7 @@
"""
Return the DAV:owner property value (MUST be a DAV:href or None).
"""
-
+
isVirt = self.isVirtualShare()
if isVirt:
parent = (yield self.locateParent(request, self._share.hosturl))
@@ -928,33 +928,21 @@
returnValue(None)
- def isOwner(self, request, adminprincipals=False, readprincipals=False):
+ @inlineCallbacks
+ def isOwner(self, request):
"""
- Determine whether the DAV:owner of this resource matches the currently authorized principal
- in the request. Optionally test for admin or read principals and allow those.
+ Determine whether the DAV:owner of this resource matches the currently
+ authorized principal in the request, or if the user is a read-only or
+ read-write administrator.
"""
+ current = self.currentPrincipal(request)
+ if current in config.AllAdminPrincipalObjects:
+ returnValue(True)
+ if davxml.Principal((yield self.owner(request))) == current:
+ returnValue(True)
+ returnValue(False)
- def _gotOwner(owner):
- current = self.currentPrincipal(request)
- if davxml.Principal(owner) == current:
- return True
-
- if adminprincipals:
- for principal in config.AdminPrincipals:
- if davxml.Principal(davxml.HRef(principal)) == current:
- return True
- if readprincipals:
- for principal in config.AdminPrincipals:
- if davxml.Principal(davxml.HRef(principal)) == current:
- return True
-
- return False
-
- d = self.owner(request)
- d.addCallback(_gotOwner)
- return d
-
##
# DAVResource
##
Modified: CalendarServer/trunk/twistedcaldav/stdconfig.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/stdconfig.py 2011-05-16 14:49:19 UTC (rev 7485)
+++ CalendarServer/trunk/twistedcaldav/stdconfig.py 2011-05-16 15:02:27 UTC (rev 7486)
@@ -1040,6 +1040,19 @@
log.debug("Nav ACL: %s" % (configDict.ProvisioningResourceACL.toxml(),))
+ def principalObjects(urls):
+ for principalURL in urls:
+ yield davxml.Principal(davxml.HRef(principalURL))
+
+ # Should be sets, except WebDAVElement isn't hashable.
+ a = configDict.AdminPrincipalObjects = list(
+ principalObjects(configDict.AdminPrincipals))
+ b = configDict.ReadPrincipalObjects = list(
+ principalObjects(configDict.ReadPrincipals))
+ configDict.AllAdminPrincipalObjects = a + b
+
+
+
def _updateRejectClients(configDict):
#
# Compile RejectClients expressions for speed
Modified: CalendarServer/trunk/twistedcaldav/storebridge.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/storebridge.py 2011-05-16 14:49:19 UTC (rev 7485)
+++ CalendarServer/trunk/twistedcaldav/storebridge.py 2011-05-16 15:02:27 UTC (rev 7486)
@@ -938,7 +938,7 @@
filteredaces = (yield self.inheritedACEsforChildren(request))
tzids = set()
- isowner = (yield self.isOwner(request, adminprincipals=True, readprincipals=True))
+ isowner = (yield self.isOwner(request))
accessPrincipal = (yield self.resourceOwnerPrincipal(request))
for name, uid, type in (yield maybeDeferred(self.index().bruteForceSearch)): #@UnusedVariable
@@ -1709,66 +1709,45 @@
returnValue(NO_CONTENT)
-class _CalendarObjectMetaDataMixin(object):
+
+class _MetadataProperty(object):
"""
- Dynamically create the required meta-data for an object resource
+ A python property which can be set either on a _newStoreObject or on some
+ metadata if no new store object exists yet.
"""
- def _get_accessMode(self):
- return self._newStoreObject.accessMode if self._newStoreObject else self._metadata.get("accessMode", None)
+ def __init__(self, name):
+ self.name = name
- def _set_accessMode(self, value):
- if self._newStoreObject:
- self._newStoreObject.accessMode = value
- else:
- self._metadata["accessMode"] = value
- accessMode = property(_get_accessMode, _set_accessMode)
-
- def _get_isScheduleObject(self):
- return self._newStoreObject.isScheduleObject if self._newStoreObject else self._metadata.get("isScheduleObject", None)
-
- def _set_isScheduleObject(self, value):
- if self._newStoreObject:
- self._newStoreObject.isScheduleObject = value
+ def __get__(self, oself, type=None):
+ if oself._newStoreObject:
+ return getattr(oself._newStoreObject, self.name)
else:
- self._metadata["isScheduleObject"] = value
+ return oself._metadata.get(self.name, None)
- isScheduleObject = property(_get_isScheduleObject, _set_isScheduleObject)
- def _get_scheduleTag(self):
- return self._newStoreObject.scheduleTag if self._newStoreObject else self._metadata.get("scheduleTag", None)
-
- def _set_scheduleTag(self, value):
- if self._newStoreObject:
- self._newStoreObject.scheduleTag = value
+ def __set__(self, oself, value):
+ if oself._newStoreObject:
+ setattr(oself._newStoreObject, self.name, value)
else:
- self._metadata["scheduleTag"] = value
+ oself._metadata[self.name] = value
- scheduleTag = property(_get_scheduleTag, _set_scheduleTag)
- def _get_scheduleEtags(self):
- return self._newStoreObject.scheduleEtags if self._newStoreObject else self._metadata.get("scheduleEtags", None)
- def _set_scheduleEtags(self, value):
- if self._newStoreObject:
- self._newStoreObject.scheduleEtags = value
- else:
- self._metadata["scheduleEtags"] = value
+class _CalendarObjectMetaDataMixin(object):
+ """
+ Dynamically create the required meta-data for an object resource
+ """
- scheduleEtags = property(_get_scheduleEtags, _set_scheduleEtags)
+ accessMode = _MetadataProperty("accessMode")
+ isScheduleObject = _MetadataProperty("isScheduleObject")
+ scheduleTag = _MetadataProperty("scheduleTag")
+ scheduleEtags = _MetadataProperty("scheduleEtags")
+ hasPrivateComment = _MetadataProperty("hasPrivateComment")
- def _get_hasPrivateComment(self):
- return self._newStoreObject.hasPrivateComment if self._newStoreObject else self._metadata.get("hasPrivateComment", None)
- def _set_hasPrivateComment(self, value):
- if self._newStoreObject:
- self._newStoreObject.hasPrivateComment = value
- else:
- self._metadata["hasPrivateComment"] = value
- hasPrivateComment = property(_get_hasPrivateComment, _set_hasPrivateComment)
-
class CalendarObjectResource(_CalendarObjectMetaDataMixin, _CommonObjectResource):
"""
A resource wrapping a calendar object.
Copied: CalendarServer/trunk/twistedcaldav/test/data/AnotherEvent.ics (from rev 7485, CalendarServer/branches/users/glyph/new-export/twistedcaldav/test/data/AnotherEvent.ics)
===================================================================
--- CalendarServer/trunk/twistedcaldav/test/data/AnotherEvent.ics (rev 0)
+++ CalendarServer/trunk/twistedcaldav/test/data/AnotherEvent.ics 2011-05-16 15:02:27 UTC (rev 7486)
@@ -0,0 +1,32 @@
+BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//Apple Inc.//iCal 4.0.4//EN
+CALSCALE:GREGORIAN
+BEGIN:VTIMEZONE
+TZID:America/New_Yrok
+BEGIN:DAYLIGHT
+TZOFFSETFROM:-0500
+RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU
+DTSTART:20070311T020000
+TZNAME:EDT
+TZOFFSETTO:-0400
+END:DAYLIGHT
+BEGIN:STANDARD
+TZOFFSETFROM:-0400
+RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU
+DTSTART:20071104T020000
+TZNAME:EST
+TZOFFSETTO:-0500
+END:STANDARD
+END:VTIMEZONE
+BEGIN:VEVENT
+CREATED:20110516T031511Z
+UID:1C4B4547-9D99-446B-B1D7-135AE04A319E
+DTEND;TZID=America/New_Yrok:20110516T130000
+TRANSP:OPAQUE
+SUMMARY:Another Event
+DTSTART;TZID=America/New_Yrok:20110516T114500
+DTSTAMP:20110516T031514Z
+SEQUENCE:2
+END:VEVENT
+END:VCALENDAR
Copied: CalendarServer/trunk/twistedcaldav/test/data/OneEvent.ics (from rev 7485, CalendarServer/branches/users/glyph/new-export/twistedcaldav/test/data/OneEvent.ics)
===================================================================
--- CalendarServer/trunk/twistedcaldav/test/data/OneEvent.ics (rev 0)
+++ CalendarServer/trunk/twistedcaldav/test/data/OneEvent.ics 2011-05-16 15:02:27 UTC (rev 7486)
@@ -0,0 +1,32 @@
+BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//Apple Inc.//iCal 4.0.4//EN
+CALSCALE:GREGORIAN
+BEGIN:VTIMEZONE
+TZID:America/New_Yrok
+BEGIN:DAYLIGHT
+TZOFFSETFROM:-0500
+RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU
+DTSTART:20070311T020000
+TZNAME:EDT
+TZOFFSETTO:-0400
+END:DAYLIGHT
+BEGIN:STANDARD
+TZOFFSETFROM:-0400
+RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU
+DTSTART:20071104T020000
+TZNAME:EST
+TZOFFSETTO:-0500
+END:STANDARD
+END:VTIMEZONE
+BEGIN:VEVENT
+CREATED:20110516T031505Z
+UID:89E0257D-3522-4423-B94E-60FF10BDAAFA
+DTEND;TZID=America/New_Yrok:20110516T110000
+TRANSP:OPAQUE
+SUMMARY:One Event
+DTSTART;TZID=America/New_Yrok:20110516T094500
+DTSTAMP:20110516T031511Z
+SEQUENCE:2
+END:VEVENT
+END:VCALENDAR
Copied: CalendarServer/trunk/twistedcaldav/test/data/ThirdEvent.ics (from rev 7485, CalendarServer/branches/users/glyph/new-export/twistedcaldav/test/data/ThirdEvent.ics)
===================================================================
--- CalendarServer/trunk/twistedcaldav/test/data/ThirdEvent.ics (rev 0)
+++ CalendarServer/trunk/twistedcaldav/test/data/ThirdEvent.ics 2011-05-16 15:02:27 UTC (rev 7486)
@@ -0,0 +1,32 @@
+BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//Apple Inc.//iCal 4.0.4//EN
+CALSCALE:GREGORIAN
+BEGIN:VTIMEZONE
+TZID:US/Pacific
+BEGIN:DAYLIGHT
+TZOFFSETFROM:-0800
+RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU
+DTSTART:20070311T020000
+TZNAME:PDT
+TZOFFSETTO:-0700
+END:DAYLIGHT
+BEGIN:STANDARD
+TZOFFSETFROM:-0700
+RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU
+DTSTART:20071104T020000
+TZNAME:PST
+TZOFFSETTO:-0800
+END:STANDARD
+END:VTIMEZONE
+BEGIN:VEVENT
+CREATED:20110516T033401Z
+UID:39F43724-3103-4379-9A0A-11FAD4FF542A
+DTEND;TZID=US/Pacific:20110516T114500
+TRANSP:OPAQUE
+SUMMARY:Third Event
+DTSTART;TZID=US/Pacific:20110516T104500
+DTSTAMP:20110516T033404Z
+SEQUENCE:2
+END:VEVENT
+END:VCALENDAR
Modified: CalendarServer/trunk/twistedcaldav/test/test_calendarquery.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/test/test_calendarquery.py 2011-05-16 14:49:19 UTC (rev 7485)
+++ CalendarServer/trunk/twistedcaldav/test/test_calendarquery.py 2011-05-16 15:02:27 UTC (rev 7486)
@@ -34,7 +34,6 @@
from twistedcaldav.config import config
from twistedcaldav.test.util import HomeTestCase
from twisted.internet.defer import inlineCallbacks, returnValue
-from twistedcaldav.memcacher import Memcacher
from txdav.common.datastore.test.util import buildStore, StubNotifierFactory
@@ -355,9 +354,6 @@
@inlineCallbacks
def setUp(self):
- self.patch(config.Memcached.Pools.Default, "ClientEnabled", False)
- self.patch(config.Memcached.Pools.Default, "ServerEnabled", False)
- self.patch(Memcacher, "allowTestCache", True)
self.calendarStore = yield buildStore(self, StubNotifierFactory())
yield super(DatabaseQueryTests, self).setUp()
Modified: CalendarServer/trunk/twistedcaldav/test/test_icalendar.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/test/test_icalendar.py 2011-05-16 14:49:19 UTC (rev 7485)
+++ CalendarServer/trunk/twistedcaldav/test/test_icalendar.py 2011-05-16 15:02:27 UTC (rev 7486)
@@ -26,6 +26,7 @@
from pycalendar.datetime import PyCalendarDateTime
from pycalendar.timezone import PyCalendarTimezone
+from twistedcaldav.ical import iCalendarProductID
from pycalendar.duration import PyCalendarDuration
class iCalendar (twistedcaldav.test.util.TestCase):
@@ -50,6 +51,20 @@
else:
SkipTest("test unimplemented")
+
+ def test_newCalendar(self):
+ """
+ L{Component.newCalendar} creates a new VCALENDAR L{Component} with
+ appropriate version and product identifiers, and no subcomponents.
+ """
+ calendar = Component.newCalendar()
+ version = calendar.getProperty("VERSION")
+ prodid = calendar.getProperty("PRODID")
+ self.assertEqual(version.value(), "2.0")
+ self.assertEqual(prodid.value(), iCalendarProductID)
+ self.assertEqual(list(calendar.subcomponents()), [])
+
+
def test_component_equality(self):
# for filename in (
# os.path.join(self.data_dir, "Holidays", "C318A4BA-1ED0-11D9-A5E0-000A958A3252.ics"),
Modified: CalendarServer/trunk/twistedcaldav/test/test_resource.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/test/test_resource.py 2011-05-16 14:49:19 UTC (rev 7485)
+++ CalendarServer/trunk/twistedcaldav/test/test_resource.py 2011-05-16 15:02:27 UTC (rev 7486)
@@ -14,13 +14,23 @@
# limitations under the License.
##
-from twistedcaldav.resource import CalDAVResource, CommonHomeResource, CalendarHomeResource, AddressBookHomeResource
+from twisted.internet.defer import inlineCallbacks
+from twext.web2.test.test_server import SimpleRequest
+
+from twext.web2.dav.davxml import Principal
+from twext.web2.dav.davxml import Unauthenticated
+from twext.web2.dav.element.rfc2518 import HRef
+
+from twistedcaldav.resource import (
+ CalDAVResource, CommonHomeResource, CalendarHomeResource,
+ AddressBookHomeResource)
+
from twistedcaldav.test.util import InMemoryPropertyStore
from twistedcaldav.test.util import TestCase
from twistedcaldav.config import config
-from twisted.internet.defer import inlineCallbacks
+from twistedcaldav.test.util import patchConfig
class StubProperty(object):
@@ -62,6 +72,7 @@
self.assertTrue(('http://calendarserver.org/ns/', 'push-transports') in resource.liveProperties())
self.assertTrue(('http://calendarserver.org/ns/', 'pushkey') in resource.liveProperties())
+
def test_calendarHomeliveProperties(self):
resource = CalendarHomeResource(None, None, None, StubHome())
self.assertTrue(('http://calendarserver.org/ns/', 'push-transports') in resource.liveProperties())
@@ -70,6 +81,7 @@
self.assertTrue(('http://calendarserver.org/ns/', 'xmpp-heartbeat-uri') in resource.liveProperties())
self.assertTrue(('http://calendarserver.org/ns/', 'xmpp-server') in resource.liveProperties())
+
def test_addressBookHomeliveProperties(self):
resource = AddressBookHomeResource(None, None, None, StubHome())
self.assertTrue(('http://calendarserver.org/ns/', 'push-transports') in resource.liveProperties())
@@ -78,6 +90,7 @@
self.assertTrue(('http://calendarserver.org/ns/', 'xmpp-heartbeat-uri') not in resource.liveProperties())
self.assertTrue(('http://calendarserver.org/ns/', 'xmpp-server') not in resource.liveProperties())
+
@inlineCallbacks
def test_push404(self):
"""
@@ -117,3 +130,88 @@
self.assertEqual((yield resource.readProperty(('http://calendarserver.org/ns/', 'xmpp-uri'), None)), None)
self.assertEqual((yield resource.readProperty(('http://calendarserver.org/ns/', 'xmpp-heartbeat-uri'), None)), None)
self.assertEqual((yield resource.readProperty(('http://calendarserver.org/ns/', 'xmpp-server'), None)), None)
+
+
+
+class OwnershipTests(TestCase):
+ """
+ L{CalDAVResource.isOwner} determines if the authenticated principal of the
+ given request is the owner of that resource.
+ """
+
+ @inlineCallbacks
+ def test_isOwnerUnauthenticated(self):
+ """
+ L{CalDAVResource.isOwner} returns C{False} for unauthenticated requests.
+ """
+ site = None
+ request = SimpleRequest(site, "GET", "/not/a/real/url/")
+ request.authzUser = request.authnUser = Principal(Unauthenticated())
+ rsrc = CalDAVResource()
+ rsrc.owner = lambda igreq: HRef("/somebody/")
+ self.assertEquals((yield rsrc.isOwner(request)), False)
+
+
+ @inlineCallbacks
+ def test_isOwnerNo(self):
+ """
+ L{CalDAVResource.isOwner} returns C{True} for authenticated requests
+ with a principal that matches the resource's owner.
+ """
+ site = None
+ request = SimpleRequest(site, "GET", "/not/a/real/url/")
+ theOwner = Principal(HRef("/yes-i-am-the-owner/"))
+ request.authzUser = request.authnUser = theOwner
+ rsrc = CalDAVResource()
+ rsrc.owner = lambda igreq: HRef("/no-i-am-not-the-owner/")
+ self.assertEquals((yield rsrc.isOwner(request)), False)
+
+
+ @inlineCallbacks
+ def test_isOwnerYes(self):
+ """
+ L{CalDAVResource.isOwner} returns C{True} for authenticated requests
+ with a principal that matches the resource's owner.
+ """
+ site = None
+ request = SimpleRequest(site, "GET", "/not/a/real/url/")
+ theOwner = Principal(HRef("/yes-i-am-the-owner/"))
+ request.authzUser = request.authnUser = theOwner
+ rsrc = CalDAVResource()
+ rsrc.owner = lambda igreq: HRef("/yes-i-am-the-owner/")
+ self.assertEquals((yield rsrc.isOwner(request)), True)
+
+
+ @inlineCallbacks
+ def test_isOwnerAdmin(self):
+ """
+ L{CalDAVResource.isOwner} returns C{True} for authenticated requests
+ with a principal that matches any principal configured in the
+ L{AdminPrincipals} list.
+ """
+ theAdmin = "/read-write-admin/"
+ patchConfig(self, AdminPrincipals=[theAdmin])
+ site = None
+ request = SimpleRequest(site, "GET", "/not/a/real/url/")
+ request.authzUser = request.authnUser = Principal(HRef(theAdmin))
+ rsrc = CalDAVResource()
+ rsrc.owner = lambda igreq: HRef("/some-other-user/")
+ self.assertEquals((yield rsrc.isOwner(request)), True)
+
+
+ @inlineCallbacks
+ def test_isOwnerReadPrincipal(self):
+ """
+ L{CalDAVResource.isOwner} returns C{True} for authenticated requests
+ with a principal that matches any principal configured in the
+ L{AdminPrincipals} list.
+ """
+ theAdmin = "/read-only-admin/"
+ patchConfig(self, ReadPrincipals=[theAdmin])
+ site = None
+ request = SimpleRequest(site, "GET", "/not/a/real/url/")
+ request.authzUser = request.authnUser = Principal(HRef(theAdmin))
+ rsrc = CalDAVResource()
+ rsrc.owner = lambda igreq: HRef("/some-other-user/")
+ self.assertEquals((yield rsrc.isOwner(request)), True)
+
Modified: CalendarServer/trunk/twistedcaldav/test/test_sharing.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/test/test_sharing.py 2011-05-16 14:49:19 UTC (rev 7485)
+++ CalendarServer/trunk/twistedcaldav/test/test_sharing.py 2011-05-16 15:02:27 UTC (rev 7486)
@@ -24,7 +24,7 @@
from twistedcaldav import customxml
from twistedcaldav.config import config
from twistedcaldav.test.util import HomeTestCase, norequest
-from twistedcaldav.memcacher import Memcacher
+
from twistedcaldav.resource import CalDAVResource
from txdav.common.datastore.test.util import buildStore, StubNotifierFactory
@@ -547,9 +547,6 @@
@inlineCallbacks
def setUp(self):
- self.patch(config.Memcached.Pools.Default, "ClientEnabled", False)
- self.patch(config.Memcached.Pools.Default, "ServerEnabled", False)
- self.patch(Memcacher, "allowTestCache", True)
self.calendarStore = yield buildStore(self, StubNotifierFactory())
yield super(DatabaseSharingTests, self).setUp()
Modified: CalendarServer/trunk/twistedcaldav/test/test_wrapping.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/test/test_wrapping.py 2011-05-16 14:49:19 UTC (rev 7485)
+++ CalendarServer/trunk/twistedcaldav/test/test_wrapping.py 2011-05-16 15:02:27 UTC (rev 7486)
@@ -46,7 +46,6 @@
StubNotifierFactory
-from twistedcaldav.memcacher import Memcacher
from txdav.caldav.icalendarstore import ICalendarHome
from txdav.carddav.iaddressbookstore import IAddressBookHome
@@ -470,9 +469,6 @@
@inlineCallbacks
def setUp(self):
- self.patch(config.Memcached.Pools.Default, "ClientEnabled", False)
- self.patch(config.Memcached.Pools.Default, "ServerEnabled", False)
- self.patch(Memcacher, "allowTestCache", True)
self.calendarStore = yield buildStore(self, StubNotifierFactory())
super(DatabaseWrappingTests, self).setUp()
Modified: CalendarServer/trunk/twistedcaldav/test/util.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/test/util.py 2011-05-16 14:49:19 UTC (rev 7485)
+++ CalendarServer/trunk/twistedcaldav/test/util.py 2011-05-16 15:02:27 UTC (rev 7486)
@@ -586,8 +586,21 @@
+def patchConfig(testCase, **kw):
+ """
+ Patch the global configuration (including running the appropriate hooks) for
+ the duration of the given test.
+ """
+ preserved = {}
+ for k in kw:
+ preserved[k] = config.get(k, None)
+ def reUpdate():
+ config.update(preserved)
+ testCase.addCleanup(reUpdate)
+ config.update(kw)
+
class ErrorOutput(Exception):
"""
The process produced some error output and exited with a non-zero exit
Modified: CalendarServer/trunk/txdav/base/datastore/subpostgres.py
===================================================================
--- CalendarServer/trunk/txdav/base/datastore/subpostgres.py 2011-05-16 14:49:19 UTC (rev 7485)
+++ CalendarServer/trunk/txdav/base/datastore/subpostgres.py 2011-05-16 15:02:27 UTC (rev 7486)
@@ -87,8 +87,9 @@
def processEnded(self, reason):
log.msg("postgres process ended %r" % (reason,))
+ result = (reason.value.status == 0)
self.lineReceiver.connectionLost(reason)
- self.completionDeferred.callback(None)
+ self.completionDeferred.callback(result)
@@ -362,6 +363,7 @@
)
self.monitor = monitor
def gotReady(result):
+ self.shouldStopDatabase = result
self.ready()
self.deactivateDelayedShutdown()
def reportit(f):
@@ -370,6 +372,7 @@
self.monitor.completionDeferred.addCallback(
gotReady).addErrback(reportit)
+ shouldStopDatabase = False
def startService(self):
MultiService.startService(self)
@@ -423,14 +426,17 @@
d = MultiService.stopService(self)
def superStopped(result):
- monitor = _PostgresMonitor()
- pg_ctl = which("pg_ctl")[0]
- reactor.spawnProcess(monitor, pg_ctl,
- [pg_ctl, '-l', 'logfile', 'stop'],
- self.env,
- uid=self.uid, gid=self.gid,
- )
- return monitor.completionDeferred
+ # If pg_ctl's startup wasn't successful, don't bother to stop the
+ # database. (This also happens in command-line tools.)
+ if self.shouldStopDatabase:
+ monitor = _PostgresMonitor()
+ pg_ctl = which("pg_ctl")[0]
+ reactor.spawnProcess(monitor, pg_ctl,
+ [pg_ctl, '-l', 'logfile', 'stop'],
+ self.env,
+ uid=self.uid, gid=self.gid,
+ )
+ return monitor.completionDeferred
return d.addCallback(superStopped)
# def maybeStopSubprocess(result):
Modified: CalendarServer/trunk/txdav/base/propertystore/test/test_sql.py
===================================================================
--- CalendarServer/trunk/txdav/base/propertystore/test/test_sql.py 2011-05-16 14:49:19 UTC (rev 7485)
+++ CalendarServer/trunk/txdav/base/propertystore/test/test_sql.py 2011-05-16 15:02:27 UTC (rev 7486)
@@ -26,10 +26,8 @@
from txdav.base.propertystore.test.base import (
PropertyStoreTest, propertyName, propertyValue)
-from twistedcaldav import memcacher
from twisted.internet.defer import gatherResults
from twext.enterprise.ienterprise import AlreadyFinishedError
-from twistedcaldav.config import config
try:
from txdav.base.propertystore.sql import PropertyStore
@@ -45,10 +43,6 @@
@inlineCallbacks
def setUp(self):
- self.patch(config.Memcached.Pools.Default, "ClientEnabled", False)
- self.patch(config.Memcached.Pools.Default, "ServerEnabled", False)
- self.patch(memcacher.Memcacher, "allowTestCache", True)
-
self.notifierFactory = StubNotifierFactory()
self.store = yield buildStore(self, self.notifierFactory)
self.addCleanup(self.maybeCommitLast)
Modified: CalendarServer/trunk/txdav/caldav/datastore/file.py
===================================================================
--- CalendarServer/trunk/txdav/caldav/datastore/file.py 2011-05-16 14:49:19 UTC (rev 7485)
+++ CalendarServer/trunk/txdav/caldav/datastore/file.py 2011-05-16 15:02:27 UTC (rev 7486)
@@ -55,13 +55,12 @@
from txdav.caldav.datastore.index_file import Index as OldIndex,\
IndexSchedule as OldInboxIndex
from txdav.caldav.datastore.util import (
- validateCalendarComponent, dropboxIDFromCalendarObject
+ validateCalendarComponent, dropboxIDFromCalendarObject, CalendarObjectBase
)
from txdav.common.datastore.file import (
CommonDataStore, CommonStoreTransaction, CommonHome, CommonHomeChild,
- CommonObjectResource
-, CommonStubResource)
+ CommonObjectResource, CommonStubResource)
from txdav.common.icommondatastore import (NoSuchObjectResourceError,
InternalDataStoreError)
@@ -262,7 +261,7 @@
-class CalendarObject(CommonObjectResource):
+class CalendarObject(CommonObjectResource, CalendarObjectBase):
"""
@ivar _path: The path of the .ics file on disk
@@ -340,8 +339,6 @@
def component(self):
- if self._component is not None:
- return self._component
text = self.text()
try:
Property changes on: CalendarServer/trunk/txdav/caldav/datastore/index_file.py
___________________________________________________________________
Modified: svn:mergeinfo
- /CalendarServer/branches/config-separation/txdav/caldav/datastore/index_file.py:4379-4443
/CalendarServer/branches/egg-info-351/txdav/caldav/datastore/index_file.py:4589-4625
/CalendarServer/branches/generic-sqlstore/txdav/caldav/datastore/index_file.py:6167-6191
/CalendarServer/branches/new-store/txdav/caldav/datastore/index_file.py:5594-5934
/CalendarServer/branches/new-store-no-caldavfile/txdav/caldav/datastore/index_file.py:5911-5935
/CalendarServer/branches/new-store-no-caldavfile-2/txdav/caldav/datastore/index_file.py:5936-5981
/CalendarServer/branches/users/cdaboo/batchupload-6699/txdav/caldav/datastore/index_file.py:6700-7198
/CalendarServer/branches/users/cdaboo/cached-subscription-calendars-5692/txdav/caldav/datastore/index_file.py:5693-5702
/CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/txdav/caldav/datastore/index_file.py:3628-3644
/CalendarServer/branches/users/cdaboo/more-sharing-5591/txdav/caldav/datastore/index_file.py:5592-5601
/CalendarServer/branches/users/cdaboo/partition-4464/txdav/caldav/datastore/index_file.py:4465-4957
/CalendarServer/branches/users/cdaboo/pods/txdav/caldav/datastore/index_file.py:7297-7377
/CalendarServer/branches/users/cdaboo/pycalendar/txdav/caldav/datastore/index_file.py:7085-7206
/CalendarServer/branches/users/cdaboo/pycard/txdav/caldav/datastore/index_file.py:7227-7237
/CalendarServer/branches/users/cdaboo/relative-config-paths-5070/txdav/caldav/datastore/index_file.py:5071-5105
/CalendarServer/branches/users/cdaboo/shared-calendars-5187/txdav/caldav/datastore/index_file.py:5188-5440
/CalendarServer/branches/users/glyph/conn-limit/txdav/caldav/datastore/index_file.py:6574-6577
/CalendarServer/branches/users/glyph/contacts-server-merge/txdav/caldav/datastore/index_file.py:4971-5080
/CalendarServer/branches/users/glyph/dalify/txdav/caldav/datastore/index_file.py:6932-7023
/CalendarServer/branches/users/glyph/dont-start-postgres/txdav/caldav/datastore/index_file.py:6592-6614
/CalendarServer/branches/users/glyph/linux-tests/txdav/caldav/datastore/index_file.py:6893-6900
/CalendarServer/branches/users/glyph/misc-portability-fixes/txdav/caldav/datastore/index_file.py:7365-7374
/CalendarServer/branches/users/glyph/more-deferreds-6/txdav/caldav/datastore/index_file.py:6322-6334
/CalendarServer/branches/users/glyph/more-deferreds-7/txdav/caldav/datastore/index_file.py:6369
/CalendarServer/branches/users/glyph/oracle/txdav/caldav/datastore/index_file.py:7106-7155
/CalendarServer/branches/users/glyph/oracle-nulls/txdav/caldav/datastore/index_file.py:7340-7351
/CalendarServer/branches/users/glyph/sendfdport/txdav/caldav/datastore/index_file.py:5388-5424
/CalendarServer/branches/users/glyph/sharedpool/txdav/caldav/datastore/index_file.py:6490-6550
/CalendarServer/branches/users/glyph/sql-store/txdav/caldav/datastore/index_file.py:5929-6073
/CalendarServer/branches/users/glyph/subtransactions/txdav/caldav/datastore/index_file.py:7248-7258
/CalendarServer/branches/users/glyph/use-system-twisted/txdav/caldav/datastore/index_file.py:5084-5149
/CalendarServer/branches/users/sagen/inboxitems/txdav/caldav/datastore/index_file.py:7380-7381
/CalendarServer/branches/users/sagen/locations-resources/txdav/caldav/datastore/index_file.py:5032-5051
/CalendarServer/branches/users/sagen/locations-resources-2/txdav/caldav/datastore/index_file.py:5052-5061
/CalendarServer/branches/users/sagen/purge_old_events/txdav/caldav/datastore/index_file.py:6735-6746
/CalendarServer/branches/users/sagen/resource-delegates-4038/txdav/caldav/datastore/index_file.py:4040-4067
/CalendarServer/branches/users/sagen/resource-delegates-4066/txdav/caldav/datastore/index_file.py:4068-4075
/CalendarServer/branches/users/sagen/resources-2/txdav/caldav/datastore/index_file.py:5084-5093
/CalendarServer/branches/users/wsanchez/transations/txdav/caldav/datastore/index_file.py:5515-5593
/CalendarServer/trunk/twistedcaldav/index.py:6322-6394
+ /CalendarServer/branches/config-separation/txdav/caldav/datastore/index_file.py:4379-4443
/CalendarServer/branches/egg-info-351/txdav/caldav/datastore/index_file.py:4589-4625
/CalendarServer/branches/generic-sqlstore/txdav/caldav/datastore/index_file.py:6167-6191
/CalendarServer/branches/new-store/txdav/caldav/datastore/index_file.py:5594-5934
/CalendarServer/branches/new-store-no-caldavfile/txdav/caldav/datastore/index_file.py:5911-5935
/CalendarServer/branches/new-store-no-caldavfile-2/txdav/caldav/datastore/index_file.py:5936-5981
/CalendarServer/branches/users/cdaboo/batchupload-6699/txdav/caldav/datastore/index_file.py:6700-7198
/CalendarServer/branches/users/cdaboo/cached-subscription-calendars-5692/txdav/caldav/datastore/index_file.py:5693-5702
/CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/txdav/caldav/datastore/index_file.py:3628-3644
/CalendarServer/branches/users/cdaboo/more-sharing-5591/txdav/caldav/datastore/index_file.py:5592-5601
/CalendarServer/branches/users/cdaboo/partition-4464/txdav/caldav/datastore/index_file.py:4465-4957
/CalendarServer/branches/users/cdaboo/pods/txdav/caldav/datastore/index_file.py:7297-7377
/CalendarServer/branches/users/cdaboo/pycalendar/txdav/caldav/datastore/index_file.py:7085-7206
/CalendarServer/branches/users/cdaboo/pycard/txdav/caldav/datastore/index_file.py:7227-7237
/CalendarServer/branches/users/cdaboo/relative-config-paths-5070/txdav/caldav/datastore/index_file.py:5071-5105
/CalendarServer/branches/users/cdaboo/shared-calendars-5187/txdav/caldav/datastore/index_file.py:5188-5440
/CalendarServer/branches/users/glyph/conn-limit/txdav/caldav/datastore/index_file.py:6574-6577
/CalendarServer/branches/users/glyph/contacts-server-merge/txdav/caldav/datastore/index_file.py:4971-5080
/CalendarServer/branches/users/glyph/dalify/txdav/caldav/datastore/index_file.py:6932-7023
/CalendarServer/branches/users/glyph/dont-start-postgres/txdav/caldav/datastore/index_file.py:6592-6614
/CalendarServer/branches/users/glyph/linux-tests/txdav/caldav/datastore/index_file.py:6893-6900
/CalendarServer/branches/users/glyph/misc-portability-fixes/txdav/caldav/datastore/index_file.py:7365-7374
/CalendarServer/branches/users/glyph/more-deferreds-6/txdav/caldav/datastore/index_file.py:6322-6334
/CalendarServer/branches/users/glyph/more-deferreds-7/txdav/caldav/datastore/index_file.py:6369
/CalendarServer/branches/users/glyph/new-export/txdav/caldav/datastore/index_file.py:7444-7485
/CalendarServer/branches/users/glyph/oracle/txdav/caldav/datastore/index_file.py:7106-7155
/CalendarServer/branches/users/glyph/oracle-nulls/txdav/caldav/datastore/index_file.py:7340-7351
/CalendarServer/branches/users/glyph/sendfdport/txdav/caldav/datastore/index_file.py:5388-5424
/CalendarServer/branches/users/glyph/sharedpool/txdav/caldav/datastore/index_file.py:6490-6550
/CalendarServer/branches/users/glyph/sql-store/txdav/caldav/datastore/index_file.py:5929-6073
/CalendarServer/branches/users/glyph/subtransactions/txdav/caldav/datastore/index_file.py:7248-7258
/CalendarServer/branches/users/glyph/use-system-twisted/txdav/caldav/datastore/index_file.py:5084-5149
/CalendarServer/branches/users/sagen/inboxitems/txdav/caldav/datastore/index_file.py:7380-7381
/CalendarServer/branches/users/sagen/locations-resources/txdav/caldav/datastore/index_file.py:5032-5051
/CalendarServer/branches/users/sagen/locations-resources-2/txdav/caldav/datastore/index_file.py:5052-5061
/CalendarServer/branches/users/sagen/purge_old_events/txdav/caldav/datastore/index_file.py:6735-6746
/CalendarServer/branches/users/sagen/resource-delegates-4038/txdav/caldav/datastore/index_file.py:4040-4067
/CalendarServer/branches/users/sagen/resource-delegates-4066/txdav/caldav/datastore/index_file.py:4068-4075
/CalendarServer/branches/users/sagen/resources-2/txdav/caldav/datastore/index_file.py:5084-5093
/CalendarServer/branches/users/wsanchez/transations/txdav/caldav/datastore/index_file.py:5515-5593
/CalendarServer/trunk/twistedcaldav/index.py:6322-6394
Modified: CalendarServer/trunk/txdav/caldav/datastore/sql.py
===================================================================
--- CalendarServer/trunk/txdav/caldav/datastore/sql.py 2011-05-16 14:49:19 UTC (rev 7485)
+++ CalendarServer/trunk/txdav/caldav/datastore/sql.py 2011-05-16 15:02:27 UTC (rev 7486)
@@ -67,6 +67,8 @@
from twext.enterprise.dal.syntax import Parameter
from twext.enterprise.dal.syntax import utcNowSQL
from twext.enterprise.dal.syntax import Len
+
+from txdav.caldav.datastore.util import CalendarObjectBase
from txdav.common.icommondatastore import IndexedSearchException
from pycalendar.datetime import PyCalendarDateTime
@@ -113,7 +115,7 @@
@inlineCallbacks
def hasCalendarResourceUIDSomewhereElse(self, uid, ok_object, type):
-
+
objectResources = (yield self.objectResourcesWithUID(uid, ("inbox",)))
for objectResource in objectResources:
if ok_object and objectResource._resourceID == ok_object._resourceID:
@@ -121,18 +123,18 @@
matched_type = "schedule" if objectResource.isScheduleObject else "calendar"
if type == "schedule" or matched_type == "schedule":
returnValue(True)
-
+
returnValue(False)
@inlineCallbacks
def getCalendarResourcesForUID(self, uid, allow_shared=False):
-
+
results = []
objectResources = (yield self.objectResourcesWithUID(uid, ("inbox",)))
for objectResource in objectResources:
if allow_shared or objectResource._parentCollection._owned:
results.append(objectResource)
-
+
returnValue(results)
@@ -305,7 +307,7 @@
-class CalendarObject(CommonObjectResource):
+class CalendarObject(CommonObjectResource, CalendarObjectBase):
implements(ICalendarObject)
_objectTable = CALENDAR_OBJECT_TABLE
@@ -314,7 +316,7 @@
def __init__(self, calendar, name, uid, resourceID=None, metadata=None):
super(CalendarObject, self).__init__(calendar, name, uid, resourceID)
-
+
if metadata is None:
metadata = {}
self.accessMode = metadata.get("accessMode", "")
@@ -406,7 +408,7 @@
expand = PyCalendarDateTime(2100, 1, 1, 0, 0, 0, tzid=PyCalendarTimezone(utc=True))
doInstanceIndexing = True
else:
-
+
# If migrating or re-creating or config option for delayed indexing is off, always index
if reCreate or self._txn._migrating or not config.FreeBusyIndexDelayedExpand:
doInstanceIndexing = True
@@ -453,11 +455,11 @@
else:
raise
- # Now coerce indexing to off if needed
+ # Now coerce indexing to off if needed
if not doInstanceIndexing:
instances = None
recurrenceLimit = PyCalendarDateTime(1900, 1, 1, 0, 0, 0, tzid=PyCalendarTimezone(utc=True))
-
+
co = schema.CALENDAR_OBJECT
tr = schema.TIME_RANGE
tpy = schema.TRANSPARENCY
@@ -470,13 +472,13 @@
organizer = component.getOrganizer()
if not organizer:
organizer = ""
-
+
# CALENDAR_OBJECT table update
self._uid = component.resourceUID()
self._md5 = hashlib.md5(componentText).hexdigest()
self._size = len(componentText)
- # Special - if migrating we need to preserve the original md5
+ # Special - if migrating we need to preserve the original md5
if self._txn._migrating and hasattr(component, "md5"):
self._md5 = component.md5
@@ -494,7 +496,7 @@
# server dropbox collections and only then set the read mode
self._attachment = _ATTACHMENTS_MODE_READ
self._dropboxID = (yield self.dropboxID())
-
+
values = {
co.CALENDAR_RESOURCE_ID : self._calendar._resourceID,
co.RESOURCE_NAME : self._name,
@@ -513,7 +515,7 @@
co.PRIVATE_COMMENTS : self._private_comments,
co.MD5 : self._md5
}
-
+
if inserting:
self._resourceID, self._created, self._modified = (
yield Insert(
@@ -539,12 +541,12 @@
co.RECURRANCE_MAX :
pyCalendarTodatetime(normalizeForIndex(recurrenceLimit)) if recurrenceLimit else None,
}
-
+
yield Update(
values,
Where=co.RESOURCE_ID == self._resourceID
).on(self._txn)
-
+
# Need to wipe the existing time-range for this and rebuild
yield Delete(
From=tr,
@@ -580,7 +582,7 @@
tpy.USER_ID : useruid,
tpy.TRANSPARENT : transp,
}).on(self._txn))
-
+
# Special - for unbounded recurrence we insert a value for "infinity"
# that will allow an open-ended time-range to always match it.
if component.isRecurringUnbounded():
@@ -622,7 +624,7 @@
def getMetadata(self):
metadata = {}
- metadata["accessMode"] = self.accessMode
+ metadata["accessMode"] = self.accessMode
metadata["isScheduleObject"] = self.isScheduleObject
metadata["scheduleTag"] = self.scheduleTag
metadata["scheduleEtags"] = self.scheduleEtags
@@ -671,7 +673,7 @@
@inlineCallbacks
def createAttachmentWithName(self, name):
-
+
# We need to know the resource_ID of the home collection of the owner (not sharee)
# of this event
sharerHomeID = (yield self._parentCollection.sharerHomeID())
Modified: CalendarServer/trunk/txdav/caldav/datastore/test/common.py
===================================================================
--- CalendarServer/trunk/txdav/caldav/datastore/test/common.py 2011-05-16 14:49:19 UTC (rev 7485)
+++ CalendarServer/trunk/txdav/caldav/datastore/test/common.py 2011-05-16 15:02:27 UTC (rev 7486)
@@ -912,7 +912,100 @@
self.assertEquals(component.resourceUID(), "uid1")
+ perUserComponent = lambda self: VComponent.fromString("""BEGIN:VCALENDAR
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+VERSION:2.0
+BEGIN:VEVENT
+DTSTART:20110101T120000Z
+DTEND:20110101T120100Z
+UID:event-with-some-per-user-data
+ATTENDEE:urn:uuid:home1
+ORGANIZER:urn:uuid:home1
+END:VEVENT
+BEGIN:X-CALENDARSERVER-PERUSER
+X-CALENDARSERVER-PERUSER-UID:some-other-user
+BEGIN:X-CALENDARSERVER-PERINSTANCE
+BEGIN:VALARM
+ACTION:DISPLAY
+DESCRIPTION:somebody else
+END:VALARM
+END:X-CALENDARSERVER-PERINSTANCE
+END:X-CALENDARSERVER-PERUSER
+BEGIN:X-CALENDARSERVER-PERUSER
+X-CALENDARSERVER-PERUSER-UID:home1
+BEGIN:X-CALENDARSERVER-PERINSTANCE
+BEGIN:VALARM
+ACTION:DISPLAY
+DESCRIPTION:the owner
+END:VALARM
+END:X-CALENDARSERVER-PERINSTANCE
+END:X-CALENDARSERVER-PERUSER
+END:VCALENDAR
+""".replace("\n", "\r\n"))
+
+
+ asSeenByOwner = lambda self: VComponent.fromString("""BEGIN:VCALENDAR
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+VERSION:2.0
+BEGIN:VEVENT
+DTSTART:20110101T120000Z
+DTEND:20110101T120100Z
+UID:event-with-some-per-user-data
+ATTENDEE:urn:uuid:home1
+ORGANIZER:urn:uuid:home1
+BEGIN:VALARM
+ACTION:DISPLAY
+DESCRIPTION:the owner
+END:VALARM
+END:VEVENT
+END:VCALENDAR
+""".replace("\n", "\r\n"))
+
+
+ asSeenByOther = lambda self: VComponent.fromString("""BEGIN:VCALENDAR
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+VERSION:2.0
+BEGIN:VEVENT
+DTSTART:20110101T120000Z
+DTEND:20110101T120100Z
+UID:event-with-some-per-user-data
+ATTENDEE:urn:uuid:home1
+ORGANIZER:urn:uuid:home1
+BEGIN:VALARM
+ACTION:DISPLAY
+DESCRIPTION:somebody else
+END:VALARM
+END:VEVENT
+END:VCALENDAR
+""".replace("\n", "\r\n"))
+
+
@inlineCallbacks
+ def setUpPerUser(self):
+ """
+ Set up state for testing of per-user components.
+ """
+ cal = yield self.calendarUnderTest()
+ yield cal.createCalendarObjectWithName(
+ "per-user-stuff.ics",
+ self.perUserComponent())
+ returnValue((yield cal.calendarObjectWithName("per-user-stuff.ics")))
+
+
+ @inlineCallbacks
+ def test_filteredComponent(self):
+ """
+ L{ICalendarObject.filteredComponent} returns a L{VComponent} that has
+ filtered per-user data.
+ """
+ obj = yield self.setUpPerUser()
+ otherComp = (yield obj.filteredComponent("some-other-user"))
+ self.assertEquals(otherComp, self.asSeenByOther())
+ ownerComp = (yield obj.filteredComponent("home1"))
+ self.assertEquals(ownerComp, self.asSeenByOwner())
+
+
+ @inlineCallbacks
def test_iCalendarText(self):
"""
L{ICalendarObject.iCalendarText} returns a C{str} describing the same
Modified: CalendarServer/trunk/txdav/caldav/datastore/test/test_file.py
===================================================================
--- CalendarServer/trunk/txdav/caldav/datastore/test/test_file.py 2011-05-16 14:49:19 UTC (rev 7485)
+++ CalendarServer/trunk/txdav/caldav/datastore/test/test_file.py 2011-05-16 15:02:27 UTC (rev 7486)
@@ -375,23 +375,6 @@
)
- @inlineCallbacks
- def test_modifyCalendarObjectCaches(self):
- """
- Modifying a calendar object should cache the modified component in
- memory, to avoid unnecessary parsing round-trips.
- """
- self.addCleanup(self.txn.commit)
- modifiedComponent = VComponent.fromString(event1modified_text)
- (yield self.calendar1.calendarObjectWithName("1.ics")).setComponent(
- modifiedComponent
- )
- self.assertIdentical(
- modifiedComponent,
- (yield self.calendar1.calendarObjectWithName("1.ics")).component()
- )
-
-
@featureUnimplemented
def test_removeCalendarObjectWithUID_absent(self):
"""
Property changes on: CalendarServer/trunk/txdav/caldav/datastore/test/test_index_file.py
___________________________________________________________________
Modified: svn:mergeinfo
- /CalendarServer/branches/config-separation/txdav/caldav/datastore/test/test_index_file.py:4379-4443
/CalendarServer/branches/egg-info-351/txdav/caldav/datastore/test/test_index_file.py:4589-4625
/CalendarServer/branches/generic-sqlstore/txdav/caldav/datastore/test/test_index_file.py:6167-6191
/CalendarServer/branches/new-store/txdav/caldav/datastore/test/test_index_file.py:5594-5934
/CalendarServer/branches/new-store-no-caldavfile/txdav/caldav/datastore/test/test_index_file.py:5911-5935
/CalendarServer/branches/new-store-no-caldavfile-2/txdav/caldav/datastore/test/test_index_file.py:5936-5981
/CalendarServer/branches/users/cdaboo/batchupload-6699/txdav/caldav/datastore/test/test_index_file.py:6700-7198
/CalendarServer/branches/users/cdaboo/cached-subscription-calendars-5692/txdav/caldav/datastore/test/test_index_file.py:5693-5702
/CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/txdav/caldav/datastore/test/test_index_file.py:3628-3644
/CalendarServer/branches/users/cdaboo/more-sharing-5591/txdav/caldav/datastore/test/test_index_file.py:5592-5601
/CalendarServer/branches/users/cdaboo/partition-4464/txdav/caldav/datastore/test/test_index_file.py:4465-4957
/CalendarServer/branches/users/cdaboo/pods/txdav/caldav/datastore/test/test_index_file.py:7297-7377
/CalendarServer/branches/users/cdaboo/pycalendar/txdav/caldav/datastore/test/test_index_file.py:7085-7206
/CalendarServer/branches/users/cdaboo/pycard/txdav/caldav/datastore/test/test_index_file.py:7227-7237
/CalendarServer/branches/users/cdaboo/relative-config-paths-5070/txdav/caldav/datastore/test/test_index_file.py:5071-5105
/CalendarServer/branches/users/cdaboo/shared-calendars-5187/txdav/caldav/datastore/test/test_index_file.py:5188-5440
/CalendarServer/branches/users/glyph/conn-limit/txdav/caldav/datastore/test/test_index_file.py:6574-6577
/CalendarServer/branches/users/glyph/contacts-server-merge/txdav/caldav/datastore/test/test_index_file.py:4971-5080
/CalendarServer/branches/users/glyph/dalify/txdav/caldav/datastore/test/test_index_file.py:6932-7023
/CalendarServer/branches/users/glyph/dont-start-postgres/txdav/caldav/datastore/test/test_index_file.py:6592-6614
/CalendarServer/branches/users/glyph/linux-tests/txdav/caldav/datastore/test/test_index_file.py:6893-6900
/CalendarServer/branches/users/glyph/misc-portability-fixes/txdav/caldav/datastore/test/test_index_file.py:7365-7374
/CalendarServer/branches/users/glyph/more-deferreds-6/txdav/caldav/datastore/test/test_index_file.py:6322-6334
/CalendarServer/branches/users/glyph/more-deferreds-7/txdav/caldav/datastore/test/test_index_file.py:6369
/CalendarServer/branches/users/glyph/oracle/txdav/caldav/datastore/test/test_index_file.py:7106-7155
/CalendarServer/branches/users/glyph/oracle-nulls/txdav/caldav/datastore/test/test_index_file.py:7340-7351
/CalendarServer/branches/users/glyph/sendfdport/txdav/caldav/datastore/test/test_index_file.py:5388-5424
/CalendarServer/branches/users/glyph/sharedpool/txdav/caldav/datastore/test/test_index_file.py:6490-6550
/CalendarServer/branches/users/glyph/sql-store/txdav/caldav/datastore/test/test_index_file.py:5929-6073
/CalendarServer/branches/users/glyph/subtransactions/txdav/caldav/datastore/test/test_index_file.py:7248-7258
/CalendarServer/branches/users/glyph/use-system-twisted/txdav/caldav/datastore/test/test_index_file.py:5084-5149
/CalendarServer/branches/users/sagen/inboxitems/txdav/caldav/datastore/test/test_index_file.py:7380-7381
/CalendarServer/branches/users/sagen/locations-resources/txdav/caldav/datastore/test/test_index_file.py:5032-5051
/CalendarServer/branches/users/sagen/locations-resources-2/txdav/caldav/datastore/test/test_index_file.py:5052-5061
/CalendarServer/branches/users/sagen/purge_old_events/txdav/caldav/datastore/test/test_index_file.py:6735-6746
/CalendarServer/branches/users/sagen/resource-delegates-4038/txdav/caldav/datastore/test/test_index_file.py:4040-4067
/CalendarServer/branches/users/sagen/resource-delegates-4066/txdav/caldav/datastore/test/test_index_file.py:4068-4075
/CalendarServer/branches/users/sagen/resources-2/txdav/caldav/datastore/test/test_index_file.py:5084-5093
/CalendarServer/branches/users/wsanchez/transations/txdav/caldav/datastore/test/test_index_file.py:5515-5593
/CalendarServer/trunk/twistedcaldav/test/test_index.py:6322-6394
+ /CalendarServer/branches/config-separation/txdav/caldav/datastore/test/test_index_file.py:4379-4443
/CalendarServer/branches/egg-info-351/txdav/caldav/datastore/test/test_index_file.py:4589-4625
/CalendarServer/branches/generic-sqlstore/txdav/caldav/datastore/test/test_index_file.py:6167-6191
/CalendarServer/branches/new-store/txdav/caldav/datastore/test/test_index_file.py:5594-5934
/CalendarServer/branches/new-store-no-caldavfile/txdav/caldav/datastore/test/test_index_file.py:5911-5935
/CalendarServer/branches/new-store-no-caldavfile-2/txdav/caldav/datastore/test/test_index_file.py:5936-5981
/CalendarServer/branches/users/cdaboo/batchupload-6699/txdav/caldav/datastore/test/test_index_file.py:6700-7198
/CalendarServer/branches/users/cdaboo/cached-subscription-calendars-5692/txdav/caldav/datastore/test/test_index_file.py:5693-5702
/CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/txdav/caldav/datastore/test/test_index_file.py:3628-3644
/CalendarServer/branches/users/cdaboo/more-sharing-5591/txdav/caldav/datastore/test/test_index_file.py:5592-5601
/CalendarServer/branches/users/cdaboo/partition-4464/txdav/caldav/datastore/test/test_index_file.py:4465-4957
/CalendarServer/branches/users/cdaboo/pods/txdav/caldav/datastore/test/test_index_file.py:7297-7377
/CalendarServer/branches/users/cdaboo/pycalendar/txdav/caldav/datastore/test/test_index_file.py:7085-7206
/CalendarServer/branches/users/cdaboo/pycard/txdav/caldav/datastore/test/test_index_file.py:7227-7237
/CalendarServer/branches/users/cdaboo/relative-config-paths-5070/txdav/caldav/datastore/test/test_index_file.py:5071-5105
/CalendarServer/branches/users/cdaboo/shared-calendars-5187/txdav/caldav/datastore/test/test_index_file.py:5188-5440
/CalendarServer/branches/users/glyph/conn-limit/txdav/caldav/datastore/test/test_index_file.py:6574-6577
/CalendarServer/branches/users/glyph/contacts-server-merge/txdav/caldav/datastore/test/test_index_file.py:4971-5080
/CalendarServer/branches/users/glyph/dalify/txdav/caldav/datastore/test/test_index_file.py:6932-7023
/CalendarServer/branches/users/glyph/dont-start-postgres/txdav/caldav/datastore/test/test_index_file.py:6592-6614
/CalendarServer/branches/users/glyph/linux-tests/txdav/caldav/datastore/test/test_index_file.py:6893-6900
/CalendarServer/branches/users/glyph/misc-portability-fixes/txdav/caldav/datastore/test/test_index_file.py:7365-7374
/CalendarServer/branches/users/glyph/more-deferreds-6/txdav/caldav/datastore/test/test_index_file.py:6322-6334
/CalendarServer/branches/users/glyph/more-deferreds-7/txdav/caldav/datastore/test/test_index_file.py:6369
/CalendarServer/branches/users/glyph/new-export/txdav/caldav/datastore/test/test_index_file.py:7444-7485
/CalendarServer/branches/users/glyph/oracle/txdav/caldav/datastore/test/test_index_file.py:7106-7155
/CalendarServer/branches/users/glyph/oracle-nulls/txdav/caldav/datastore/test/test_index_file.py:7340-7351
/CalendarServer/branches/users/glyph/sendfdport/txdav/caldav/datastore/test/test_index_file.py:5388-5424
/CalendarServer/branches/users/glyph/sharedpool/txdav/caldav/datastore/test/test_index_file.py:6490-6550
/CalendarServer/branches/users/glyph/sql-store/txdav/caldav/datastore/test/test_index_file.py:5929-6073
/CalendarServer/branches/users/glyph/subtransactions/txdav/caldav/datastore/test/test_index_file.py:7248-7258
/CalendarServer/branches/users/glyph/use-system-twisted/txdav/caldav/datastore/test/test_index_file.py:5084-5149
/CalendarServer/branches/users/sagen/inboxitems/txdav/caldav/datastore/test/test_index_file.py:7380-7381
/CalendarServer/branches/users/sagen/locations-resources/txdav/caldav/datastore/test/test_index_file.py:5032-5051
/CalendarServer/branches/users/sagen/locations-resources-2/txdav/caldav/datastore/test/test_index_file.py:5052-5061
/CalendarServer/branches/users/sagen/purge_old_events/txdav/caldav/datastore/test/test_index_file.py:6735-6746
/CalendarServer/branches/users/sagen/resource-delegates-4038/txdav/caldav/datastore/test/test_index_file.py:4040-4067
/CalendarServer/branches/users/sagen/resource-delegates-4066/txdav/caldav/datastore/test/test_index_file.py:4068-4075
/CalendarServer/branches/users/sagen/resources-2/txdav/caldav/datastore/test/test_index_file.py:5084-5093
/CalendarServer/branches/users/wsanchez/transations/txdav/caldav/datastore/test/test_index_file.py:5515-5593
/CalendarServer/trunk/twistedcaldav/test/test_index.py:6322-6394
Modified: CalendarServer/trunk/txdav/caldav/datastore/test/test_sql.py
===================================================================
--- CalendarServer/trunk/txdav/caldav/datastore/test/test_sql.py 2011-05-16 14:49:19 UTC (rev 7485)
+++ CalendarServer/trunk/txdav/caldav/datastore/test/test_sql.py 2011-05-16 15:02:27 UTC (rev 7486)
@@ -38,8 +38,8 @@
from txdav.common.datastore.sql_tables import schema
from txdav.common.datastore.test.util import buildStore, populateCalendarsFrom
-from twistedcaldav import memcacher, caldavxml
-from twistedcaldav.config import config
+from twistedcaldav import caldavxml
+
from twistedcaldav.dateops import datetimeMktime
from twistedcaldav.sharing import SharedCollectionRecord
@@ -52,10 +52,6 @@
@inlineCallbacks
def setUp(self):
- self.patch(config.Memcached.Pools.Default, "ClientEnabled", False)
- self.patch(config.Memcached.Pools.Default, "ServerEnabled", False)
- self.patch(memcacher.Memcacher, "allowTestCache", True)
-
yield super(CalendarSQLStorageTests, self).setUp()
self._sqlCalendarStore = yield buildStore(self, self.notifierFactory)
yield self.populate()
Modified: CalendarServer/trunk/txdav/caldav/datastore/util.py
===================================================================
--- CalendarServer/trunk/txdav/caldav/datastore/util.py 2011-05-16 14:49:19 UTC (rev 7485)
+++ CalendarServer/trunk/txdav/caldav/datastore/util.py 2011-05-16 15:02:27 UTC (rev 7486)
@@ -28,6 +28,8 @@
from txdav.common.icommondatastore import InvalidObjectResourceError, \
NoSuchObjectResourceError, InternalDataStoreError
+from twistedcaldav.datafilters.privateevents import PrivateEventFilter
+from twistedcaldav.datafilters.peruserdata import PerUserDataFilter
from twext.python.log import Logger
log = Logger()
@@ -215,3 +217,46 @@
# No migration for notifications, since they weren't present in earlier
# released versions of CalendarServer.
+
+
+class CalendarObjectBase(object):
+ """
+ Base logic shared between file- and sql-based L{ICalendarObject}
+ implementations.
+ """
+
+ @inlineCallbacks
+ def filteredComponent(self, accessUID, asAdmin=False):
+ """
+ Filter this calendar object's iCalendar component as it would be
+ perceived by a particular user, accounting for per-user iCalendar data
+ and private events, and return a L{Deferred} that fires with that
+ object.
+
+ Unlike the result of C{component()}, which contains storage-specific
+ iCalendar properties, this is a valid iCalendar object which could be
+ serialized and displayed to other iCalendar-processing software.
+
+ @param accessUID: the UID of the principal who is accessing this
+ component.
+ @type accessUID: C{str} (UTF-8 encoded)
+
+ @param asAdmin: should the given UID be treated as an administrator? If
+ this is C{True}, the resulting component will have an unobscured
+ view of private events, even if the given UID is not actually the
+ owner of said events. (However, per-instance overridden values will
+ still be seen as the given C{accessUID}.)
+
+ @return: a L{Deferred} which fires with a
+ L{twistedcaldav.ical.Component}.
+ """
+ component = yield self.component()
+ calendar = self.calendar()
+ isOwner = asAdmin or (calendar._owned and
+ calendar.ownerCalendarHome().uid() == accessUID)
+ for filter in [PrivateEventFilter(self.accessMode, isOwner),
+ PerUserDataFilter(accessUID)]:
+ component = filter.filter(component)
+ returnValue(component)
+
+
Property changes on: CalendarServer/trunk/txdav/carddav/datastore/index_file.py
___________________________________________________________________
Modified: svn:mergeinfo
- /CalendarServer/branches/config-separation/txdav/carddav/datastore/index_file.py:4379-4443
/CalendarServer/branches/egg-info-351/txdav/carddav/datastore/index_file.py:4589-4625
/CalendarServer/branches/generic-sqlstore/txdav/carddav/datastore/index_file.py:6167-6191
/CalendarServer/branches/new-store/txdav/carddav/datastore/index_file.py:5594-5934
/CalendarServer/branches/new-store-no-caldavfile/txdav/carddav/datastore/index_file.py:5911-5935
/CalendarServer/branches/new-store-no-caldavfile-2/txdav/carddav/datastore/index_file.py:5936-5981
/CalendarServer/branches/users/cdaboo/batchupload-6699/txdav/carddav/datastore/index_file.py:6700-7198
/CalendarServer/branches/users/cdaboo/cached-subscription-calendars-5692/txdav/carddav/datastore/index_file.py:5693-5702
/CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/txdav/carddav/datastore/index_file.py:3628-3644
/CalendarServer/branches/users/cdaboo/more-sharing-5591/txdav/carddav/datastore/index_file.py:5592-5601
/CalendarServer/branches/users/cdaboo/partition-4464/txdav/carddav/datastore/index_file.py:4465-4957
/CalendarServer/branches/users/cdaboo/pods/txdav/carddav/datastore/index_file.py:7297-7377
/CalendarServer/branches/users/cdaboo/pycalendar/txdav/carddav/datastore/index_file.py:7085-7206
/CalendarServer/branches/users/cdaboo/pycard/txdav/carddav/datastore/index_file.py:7227-7237
/CalendarServer/branches/users/cdaboo/relative-config-paths-5070/txdav/carddav/datastore/index_file.py:5071-5105
/CalendarServer/branches/users/cdaboo/shared-calendars-5187/txdav/carddav/datastore/index_file.py:5188-5440
/CalendarServer/branches/users/glyph/conn-limit/txdav/carddav/datastore/index_file.py:6574-6577
/CalendarServer/branches/users/glyph/contacts-server-merge/txdav/carddav/datastore/index_file.py:4971-5080
/CalendarServer/branches/users/glyph/dalify/txdav/carddav/datastore/index_file.py:6932-7023
/CalendarServer/branches/users/glyph/dont-start-postgres/txdav/carddav/datastore/index_file.py:6592-6614
/CalendarServer/branches/users/glyph/linux-tests/txdav/carddav/datastore/index_file.py:6893-6900
/CalendarServer/branches/users/glyph/misc-portability-fixes/txdav/carddav/datastore/index_file.py:7365-7374
/CalendarServer/branches/users/glyph/more-deferreds-6/txdav/carddav/datastore/index_file.py:6322-6334
/CalendarServer/branches/users/glyph/more-deferreds-7/txdav/carddav/datastore/index_file.py:6369
/CalendarServer/branches/users/glyph/oracle/txdav/carddav/datastore/index_file.py:7106-7155
/CalendarServer/branches/users/glyph/oracle-nulls/txdav/carddav/datastore/index_file.py:7340-7351
/CalendarServer/branches/users/glyph/sendfdport/txdav/carddav/datastore/index_file.py:5388-5424
/CalendarServer/branches/users/glyph/sharedpool/txdav/carddav/datastore/index_file.py:6490-6550
/CalendarServer/branches/users/glyph/sql-store/txdav/carddav/datastore/index_file.py:5929-6073
/CalendarServer/branches/users/glyph/subtransactions/txdav/carddav/datastore/index_file.py:7248-7258
/CalendarServer/branches/users/glyph/use-system-twisted/txdav/carddav/datastore/index_file.py:5084-5149
/CalendarServer/branches/users/sagen/inboxitems/txdav/carddav/datastore/index_file.py:7380-7381
/CalendarServer/branches/users/sagen/locations-resources/txdav/carddav/datastore/index_file.py:5032-5051
/CalendarServer/branches/users/sagen/locations-resources-2/txdav/carddav/datastore/index_file.py:5052-5061
/CalendarServer/branches/users/sagen/purge_old_events/txdav/carddav/datastore/index_file.py:6735-6746
/CalendarServer/branches/users/sagen/resource-delegates-4038/txdav/carddav/datastore/index_file.py:4040-4067
/CalendarServer/branches/users/sagen/resource-delegates-4066/txdav/carddav/datastore/index_file.py:4068-4075
/CalendarServer/branches/users/sagen/resources-2/txdav/carddav/datastore/index_file.py:5084-5093
/CalendarServer/branches/users/wsanchez/transations/txdav/carddav/datastore/index_file.py:5515-5593
/CalendarServer/trunk/twistedcaldav/vcardindex.py:6322-6394
+ /CalendarServer/branches/config-separation/txdav/carddav/datastore/index_file.py:4379-4443
/CalendarServer/branches/egg-info-351/txdav/carddav/datastore/index_file.py:4589-4625
/CalendarServer/branches/generic-sqlstore/txdav/carddav/datastore/index_file.py:6167-6191
/CalendarServer/branches/new-store/txdav/carddav/datastore/index_file.py:5594-5934
/CalendarServer/branches/new-store-no-caldavfile/txdav/carddav/datastore/index_file.py:5911-5935
/CalendarServer/branches/new-store-no-caldavfile-2/txdav/carddav/datastore/index_file.py:5936-5981
/CalendarServer/branches/users/cdaboo/batchupload-6699/txdav/carddav/datastore/index_file.py:6700-7198
/CalendarServer/branches/users/cdaboo/cached-subscription-calendars-5692/txdav/carddav/datastore/index_file.py:5693-5702
/CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/txdav/carddav/datastore/index_file.py:3628-3644
/CalendarServer/branches/users/cdaboo/more-sharing-5591/txdav/carddav/datastore/index_file.py:5592-5601
/CalendarServer/branches/users/cdaboo/partition-4464/txdav/carddav/datastore/index_file.py:4465-4957
/CalendarServer/branches/users/cdaboo/pods/txdav/carddav/datastore/index_file.py:7297-7377
/CalendarServer/branches/users/cdaboo/pycalendar/txdav/carddav/datastore/index_file.py:7085-7206
/CalendarServer/branches/users/cdaboo/pycard/txdav/carddav/datastore/index_file.py:7227-7237
/CalendarServer/branches/users/cdaboo/relative-config-paths-5070/txdav/carddav/datastore/index_file.py:5071-5105
/CalendarServer/branches/users/cdaboo/shared-calendars-5187/txdav/carddav/datastore/index_file.py:5188-5440
/CalendarServer/branches/users/glyph/conn-limit/txdav/carddav/datastore/index_file.py:6574-6577
/CalendarServer/branches/users/glyph/contacts-server-merge/txdav/carddav/datastore/index_file.py:4971-5080
/CalendarServer/branches/users/glyph/dalify/txdav/carddav/datastore/index_file.py:6932-7023
/CalendarServer/branches/users/glyph/dont-start-postgres/txdav/carddav/datastore/index_file.py:6592-6614
/CalendarServer/branches/users/glyph/linux-tests/txdav/carddav/datastore/index_file.py:6893-6900
/CalendarServer/branches/users/glyph/misc-portability-fixes/txdav/carddav/datastore/index_file.py:7365-7374
/CalendarServer/branches/users/glyph/more-deferreds-6/txdav/carddav/datastore/index_file.py:6322-6334
/CalendarServer/branches/users/glyph/more-deferreds-7/txdav/carddav/datastore/index_file.py:6369
/CalendarServer/branches/users/glyph/new-export/txdav/carddav/datastore/index_file.py:7444-7485
/CalendarServer/branches/users/glyph/oracle/txdav/carddav/datastore/index_file.py:7106-7155
/CalendarServer/branches/users/glyph/oracle-nulls/txdav/carddav/datastore/index_file.py:7340-7351
/CalendarServer/branches/users/glyph/sendfdport/txdav/carddav/datastore/index_file.py:5388-5424
/CalendarServer/branches/users/glyph/sharedpool/txdav/carddav/datastore/index_file.py:6490-6550
/CalendarServer/branches/users/glyph/sql-store/txdav/carddav/datastore/index_file.py:5929-6073
/CalendarServer/branches/users/glyph/subtransactions/txdav/carddav/datastore/index_file.py:7248-7258
/CalendarServer/branches/users/glyph/use-system-twisted/txdav/carddav/datastore/index_file.py:5084-5149
/CalendarServer/branches/users/sagen/inboxitems/txdav/carddav/datastore/index_file.py:7380-7381
/CalendarServer/branches/users/sagen/locations-resources/txdav/carddav/datastore/index_file.py:5032-5051
/CalendarServer/branches/users/sagen/locations-resources-2/txdav/carddav/datastore/index_file.py:5052-5061
/CalendarServer/branches/users/sagen/purge_old_events/txdav/carddav/datastore/index_file.py:6735-6746
/CalendarServer/branches/users/sagen/resource-delegates-4038/txdav/carddav/datastore/index_file.py:4040-4067
/CalendarServer/branches/users/sagen/resource-delegates-4066/txdav/carddav/datastore/index_file.py:4068-4075
/CalendarServer/branches/users/sagen/resources-2/txdav/carddav/datastore/index_file.py:5084-5093
/CalendarServer/branches/users/wsanchez/transations/txdav/carddav/datastore/index_file.py:5515-5593
/CalendarServer/trunk/twistedcaldav/vcardindex.py:6322-6394
Property changes on: CalendarServer/trunk/txdav/carddav/datastore/test/test_index_file.py
___________________________________________________________________
Modified: svn:mergeinfo
- /CalendarServer/branches/config-separation/txdav/carddav/datastore/test/test_index_file.py:4379-4443
/CalendarServer/branches/egg-info-351/txdav/carddav/datastore/test/test_index_file.py:4589-4625
/CalendarServer/branches/generic-sqlstore/txdav/carddav/datastore/test/test_index_file.py:6167-6191
/CalendarServer/branches/new-store/txdav/carddav/datastore/test/test_index_file.py:5594-5934
/CalendarServer/branches/new-store-no-caldavfile/txdav/carddav/datastore/test/test_index_file.py:5911-5935
/CalendarServer/branches/new-store-no-caldavfile-2/txdav/carddav/datastore/test/test_index_file.py:5936-5981
/CalendarServer/branches/users/cdaboo/batchupload-6699/txdav/carddav/datastore/test/test_index_file.py:6700-7198
/CalendarServer/branches/users/cdaboo/cached-subscription-calendars-5692/txdav/carddav/datastore/test/test_index_file.py:5693-5702
/CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/txdav/carddav/datastore/test/test_index_file.py:3628-3644
/CalendarServer/branches/users/cdaboo/more-sharing-5591/txdav/carddav/datastore/test/test_index_file.py:5592-5601
/CalendarServer/branches/users/cdaboo/partition-4464/txdav/carddav/datastore/test/test_index_file.py:4465-4957
/CalendarServer/branches/users/cdaboo/pods/txdav/carddav/datastore/test/test_index_file.py:7297-7377
/CalendarServer/branches/users/cdaboo/pycalendar/txdav/carddav/datastore/test/test_index_file.py:7085-7206
/CalendarServer/branches/users/cdaboo/pycard/txdav/carddav/datastore/test/test_index_file.py:7227-7237
/CalendarServer/branches/users/cdaboo/relative-config-paths-5070/txdav/carddav/datastore/test/test_index_file.py:5071-5105
/CalendarServer/branches/users/cdaboo/shared-calendars-5187/txdav/carddav/datastore/test/test_index_file.py:5188-5440
/CalendarServer/branches/users/glyph/conn-limit/txdav/carddav/datastore/test/test_index_file.py:6574-6577
/CalendarServer/branches/users/glyph/contacts-server-merge/txdav/carddav/datastore/test/test_index_file.py:4971-5080
/CalendarServer/branches/users/glyph/dalify/txdav/carddav/datastore/test/test_index_file.py:6932-7023
/CalendarServer/branches/users/glyph/dont-start-postgres/txdav/carddav/datastore/test/test_index_file.py:6592-6614
/CalendarServer/branches/users/glyph/linux-tests/txdav/carddav/datastore/test/test_index_file.py:6893-6900
/CalendarServer/branches/users/glyph/misc-portability-fixes/txdav/carddav/datastore/test/test_index_file.py:7365-7374
/CalendarServer/branches/users/glyph/more-deferreds-6/txdav/carddav/datastore/test/test_index_file.py:6322-6334
/CalendarServer/branches/users/glyph/more-deferreds-7/txdav/carddav/datastore/test/test_index_file.py:6369
/CalendarServer/branches/users/glyph/oracle/txdav/carddav/datastore/test/test_index_file.py:7106-7155
/CalendarServer/branches/users/glyph/oracle-nulls/txdav/carddav/datastore/test/test_index_file.py:7340-7351
/CalendarServer/branches/users/glyph/sendfdport/txdav/carddav/datastore/test/test_index_file.py:5388-5424
/CalendarServer/branches/users/glyph/sharedpool/txdav/carddav/datastore/test/test_index_file.py:6490-6550
/CalendarServer/branches/users/glyph/sql-store/txdav/carddav/datastore/test/test_index_file.py:5929-6073
/CalendarServer/branches/users/glyph/subtransactions/txdav/carddav/datastore/test/test_index_file.py:7248-7258
/CalendarServer/branches/users/glyph/use-system-twisted/txdav/carddav/datastore/test/test_index_file.py:5084-5149
/CalendarServer/branches/users/sagen/inboxitems/txdav/carddav/datastore/test/test_index_file.py:7380-7381
/CalendarServer/branches/users/sagen/locations-resources/txdav/carddav/datastore/test/test_index_file.py:5032-5051
/CalendarServer/branches/users/sagen/locations-resources-2/txdav/carddav/datastore/test/test_index_file.py:5052-5061
/CalendarServer/branches/users/sagen/purge_old_events/txdav/carddav/datastore/test/test_index_file.py:6735-6746
/CalendarServer/branches/users/sagen/resource-delegates-4038/txdav/carddav/datastore/test/test_index_file.py:4040-4067
/CalendarServer/branches/users/sagen/resource-delegates-4066/txdav/carddav/datastore/test/test_index_file.py:4068-4075
/CalendarServer/branches/users/sagen/resources-2/txdav/carddav/datastore/test/test_index_file.py:5084-5093
/CalendarServer/branches/users/wsanchez/transations/txdav/carddav/datastore/test/test_index_file.py:5515-5593
/CalendarServer/trunk/twistedcaldav/test/test_vcardindex.py:6322-6394
+ /CalendarServer/branches/config-separation/txdav/carddav/datastore/test/test_index_file.py:4379-4443
/CalendarServer/branches/egg-info-351/txdav/carddav/datastore/test/test_index_file.py:4589-4625
/CalendarServer/branches/generic-sqlstore/txdav/carddav/datastore/test/test_index_file.py:6167-6191
/CalendarServer/branches/new-store/txdav/carddav/datastore/test/test_index_file.py:5594-5934
/CalendarServer/branches/new-store-no-caldavfile/txdav/carddav/datastore/test/test_index_file.py:5911-5935
/CalendarServer/branches/new-store-no-caldavfile-2/txdav/carddav/datastore/test/test_index_file.py:5936-5981
/CalendarServer/branches/users/cdaboo/batchupload-6699/txdav/carddav/datastore/test/test_index_file.py:6700-7198
/CalendarServer/branches/users/cdaboo/cached-subscription-calendars-5692/txdav/carddav/datastore/test/test_index_file.py:5693-5702
/CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627/txdav/carddav/datastore/test/test_index_file.py:3628-3644
/CalendarServer/branches/users/cdaboo/more-sharing-5591/txdav/carddav/datastore/test/test_index_file.py:5592-5601
/CalendarServer/branches/users/cdaboo/partition-4464/txdav/carddav/datastore/test/test_index_file.py:4465-4957
/CalendarServer/branches/users/cdaboo/pods/txdav/carddav/datastore/test/test_index_file.py:7297-7377
/CalendarServer/branches/users/cdaboo/pycalendar/txdav/carddav/datastore/test/test_index_file.py:7085-7206
/CalendarServer/branches/users/cdaboo/pycard/txdav/carddav/datastore/test/test_index_file.py:7227-7237
/CalendarServer/branches/users/cdaboo/relative-config-paths-5070/txdav/carddav/datastore/test/test_index_file.py:5071-5105
/CalendarServer/branches/users/cdaboo/shared-calendars-5187/txdav/carddav/datastore/test/test_index_file.py:5188-5440
/CalendarServer/branches/users/glyph/conn-limit/txdav/carddav/datastore/test/test_index_file.py:6574-6577
/CalendarServer/branches/users/glyph/contacts-server-merge/txdav/carddav/datastore/test/test_index_file.py:4971-5080
/CalendarServer/branches/users/glyph/dalify/txdav/carddav/datastore/test/test_index_file.py:6932-7023
/CalendarServer/branches/users/glyph/dont-start-postgres/txdav/carddav/datastore/test/test_index_file.py:6592-6614
/CalendarServer/branches/users/glyph/linux-tests/txdav/carddav/datastore/test/test_index_file.py:6893-6900
/CalendarServer/branches/users/glyph/misc-portability-fixes/txdav/carddav/datastore/test/test_index_file.py:7365-7374
/CalendarServer/branches/users/glyph/more-deferreds-6/txdav/carddav/datastore/test/test_index_file.py:6322-6334
/CalendarServer/branches/users/glyph/more-deferreds-7/txdav/carddav/datastore/test/test_index_file.py:6369
/CalendarServer/branches/users/glyph/new-export/txdav/carddav/datastore/test/test_index_file.py:7444-7485
/CalendarServer/branches/users/glyph/oracle/txdav/carddav/datastore/test/test_index_file.py:7106-7155
/CalendarServer/branches/users/glyph/oracle-nulls/txdav/carddav/datastore/test/test_index_file.py:7340-7351
/CalendarServer/branches/users/glyph/sendfdport/txdav/carddav/datastore/test/test_index_file.py:5388-5424
/CalendarServer/branches/users/glyph/sharedpool/txdav/carddav/datastore/test/test_index_file.py:6490-6550
/CalendarServer/branches/users/glyph/sql-store/txdav/carddav/datastore/test/test_index_file.py:5929-6073
/CalendarServer/branches/users/glyph/subtransactions/txdav/carddav/datastore/test/test_index_file.py:7248-7258
/CalendarServer/branches/users/glyph/use-system-twisted/txdav/carddav/datastore/test/test_index_file.py:5084-5149
/CalendarServer/branches/users/sagen/inboxitems/txdav/carddav/datastore/test/test_index_file.py:7380-7381
/CalendarServer/branches/users/sagen/locations-resources/txdav/carddav/datastore/test/test_index_file.py:5032-5051
/CalendarServer/branches/users/sagen/locations-resources-2/txdav/carddav/datastore/test/test_index_file.py:5052-5061
/CalendarServer/branches/users/sagen/purge_old_events/txdav/carddav/datastore/test/test_index_file.py:6735-6746
/CalendarServer/branches/users/sagen/resource-delegates-4038/txdav/carddav/datastore/test/test_index_file.py:4040-4067
/CalendarServer/branches/users/sagen/resource-delegates-4066/txdav/carddav/datastore/test/test_index_file.py:4068-4075
/CalendarServer/branches/users/sagen/resources-2/txdav/carddav/datastore/test/test_index_file.py:5084-5093
/CalendarServer/branches/users/wsanchez/transations/txdav/carddav/datastore/test/test_index_file.py:5515-5593
/CalendarServer/trunk/twistedcaldav/test/test_vcardindex.py:6322-6394
Modified: CalendarServer/trunk/txdav/carddav/datastore/test/test_sql.py
===================================================================
--- CalendarServer/trunk/txdav/carddav/datastore/test/test_sql.py 2011-05-16 14:49:19 UTC (rev 7485)
+++ CalendarServer/trunk/txdav/carddav/datastore/test/test_sql.py 2011-05-16 15:02:27 UTC (rev 7486)
@@ -25,8 +25,8 @@
from twisted.internet.defer import inlineCallbacks, returnValue
from twisted.trial import unittest
-from twistedcaldav import memcacher, carddavxml
-from twistedcaldav.config import config
+from twistedcaldav import carddavxml
+
from twistedcaldav.vcard import Component as VCard
from twistedcaldav.vcard import Component as VComponent
@@ -47,10 +47,6 @@
@inlineCallbacks
def setUp(self):
- self.patch(config.Memcached.Pools.Default, "ClientEnabled", False)
- self.patch(config.Memcached.Pools.Default, "ServerEnabled", False)
- self.patch(memcacher.Memcacher, "allowTestCache", True)
-
yield super(AddressBookSQLStorageTests, self).setUp()
self._sqlStore = yield buildStore(self, self.notifierFactory)
yield self.populate()
Modified: CalendarServer/trunk/txdav/common/datastore/sql.py
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/sql.py 2011-05-16 14:49:19 UTC (rev 7485)
+++ CalendarServer/trunk/txdav/common/datastore/sql.py 2011-05-16 15:02:27 UTC (rev 7486)
@@ -1304,6 +1304,10 @@
class CommonHomeChild(LoggingMixIn, FancyEqMixin, _SharedSyncLogic):
"""
Common ancestor class of AddressBooks and Calendars.
+
+ @ivar _owned: Is this calendar or addressbook referencing its sharer (owner)
+ home? (i.e. C{True} if L{ownerCalendarHome} will actually return the
+ sharer, C{False} or if it will return a sharee.)
"""
compareAttributes = (
Modified: CalendarServer/trunk/txdav/common/datastore/test/test_util.py
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/test/test_util.py 2011-05-16 14:49:19 UTC (rev 7485)
+++ CalendarServer/trunk/txdav/common/datastore/test/test_util.py 2011-05-16 15:02:27 UTC (rev 7486)
@@ -26,9 +26,6 @@
from twisted.internet.protocol import Protocol
from twisted.trial.unittest import TestCase
-from twistedcaldav.config import config
-from twistedcaldav.memcacher import Memcacher
-
from txdav.caldav.datastore.test.common import CommonTests
from txdav.carddav.datastore.test.common import CommonTests as ABCommonTests
from txdav.common.datastore.file import CommonDataStore
@@ -48,9 +45,7 @@
Set up two stores to migrate between.
"""
# Add some files to the file store.
- self.patch(config.Memcached.Pools.Default, "ClientEnabled", False)
- self.patch(config.Memcached.Pools.Default, "ServerEnabled", False)
- self.patch(Memcacher, "allowTestCache", True)
+
self.filesPath = CachingFilePath(self.mktemp())
self.filesPath.createDirectory()
fileStore = self.fileStore = CommonDataStore(
Modified: CalendarServer/trunk/txdav/common/datastore/test/util.py
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/test/util.py 2011-05-16 14:49:19 UTC (rev 7485)
+++ CalendarServer/trunk/txdav/common/datastore/test/util.py 2011-05-16 15:02:27 UTC (rev 7486)
@@ -76,6 +76,7 @@
@return: a L{Deferred} which fires with an L{IDataStore}.
"""
+ disableMemcacheForTest(testCase)
dbRoot = CachingFilePath(self.SHARED_DB_PATH)
attachmentRoot = dbRoot.child("attachments")
if self.sharedService is None:
@@ -423,3 +424,24 @@
def reset(self):
self.history = []
+
+
+
+def disableMemcacheForTest(aTest):
+ """
+ Disable all memcache logic for the duration of a test; we shouldn't be
+ starting or connecting to any memcache stuff for most tests.
+ """
+
+ # These imports are local so that they don't accidentally leak to anything
+ # else in this module; nothing else in this module should ever touch global
+ # configuration. -glyph
+
+ from twistedcaldav.config import config
+ from twistedcaldav.memcacher import Memcacher
+
+ aTest.patch(config.Memcached.Pools.Default, "ClientEnabled", False)
+ aTest.patch(config.Memcached.Pools.Default, "ServerEnabled", False)
+ aTest.patch(Memcacher, "allowTestCache", True)
+
+
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20110516/a54e04d2/attachment-0001.html>
More information about the calendarserver-changes
mailing list