[CalendarServer-changes] [5233] CalendarServer/trunk
source_changes at macosforge.org
source_changes at macosforge.org
Wed Mar 3 13:08:47 PST 2010
Revision: 5233
http://trac.macosforge.org/projects/calendarserver/changeset/5233
Author: sagen at apple.com
Date: 2010-03-03 13:08:46 -0800 (Wed, 03 Mar 2010)
Log Message:
-----------
Adds sidecar task for purging events older than a given number of days
Modified Paths:
--------------
CalendarServer/trunk/calendarserver/sidecar/task.py
CalendarServer/trunk/calendarserver/util.py
CalendarServer/trunk/twext/web2/resource.py
CalendarServer/trunk/twistedcaldav/method/delete_common.py
Added Paths:
-----------
CalendarServer/trunk/calendarserver/tools/purge.py
CalendarServer/trunk/calendarserver/tools/test/purge/
CalendarServer/trunk/calendarserver/tools/test/purge/accounts.xml
CalendarServer/trunk/calendarserver/tools/test/test_purge.py
Modified: CalendarServer/trunk/calendarserver/sidecar/task.py
===================================================================
--- CalendarServer/trunk/calendarserver/sidecar/task.py 2010-03-03 17:39:59 UTC (rev 5232)
+++ CalendarServer/trunk/calendarserver/sidecar/task.py 2010-03-03 21:08:46 UTC (rev 5233)
@@ -23,6 +23,7 @@
]
import os
+from datetime import date, timedelta
from zope.interface import implements
@@ -31,7 +32,6 @@
from twisted.internet.reactor import callLater
from twisted.plugin import IPlugin
from twisted.python.usage import Options, UsageError
-from twext.web2.http_headers import Headers
from twext.python.log import Logger, LoggingMixIn
from twext.python.log import logLevelForNamespace, setLogLevelForNamespace
@@ -42,52 +42,11 @@
from twistedcaldav.scheduling.cuaddress import LocalCalendarUser
from twistedcaldav.scheduling.scheduler import DirectScheduler
-from calendarserver.util import getRootResource
+from calendarserver.util import getRootResource, FakeRequest
+from calendarserver.tools.purge import purgeOldEvents
log = Logger()
-class FakeRequest(object):
-
- def __init__(self, rootResource, method):
- self.rootResource = rootResource
- self.method = method
- self._resourcesByURL = {}
- self._urlsByResource = {}
- self.headers = Headers()
-
- @inlineCallbacks
- def _getChild(self, resource, segments):
- if not segments:
- returnValue(resource)
-
- child, remaining = (yield resource.locateChild(self, segments))
- returnValue((yield self._getChild(child, remaining)))
-
- @inlineCallbacks
- def locateResource(self, url):
- url = url.strip("/")
- segments = url.split("/")
- resource = (yield self._getChild(self.rootResource, segments))
- if resource:
- self._rememberResource(resource, url)
- returnValue(resource)
-
- def _rememberResource(self, resource, url):
- self._resourcesByURL[url] = resource
- self._urlsByResource[resource] = url
- return resource
-
- def urlForResource(self, resource):
- url = self._urlsByResource.get(resource, None)
- if url is None:
- class NoURLForResourceError(RuntimeError):
- pass
- raise NoURLForResourceError(resource)
- return url
-
- def addResponseFilter(*args, **kwds):
- pass
-
@inlineCallbacks
def processInboxItem(rootResource, directory, inboxFile, inboxItemFile, uuid):
log.debug("Processing inbox item %s" % (inboxItemFile,))
@@ -192,13 +151,31 @@
os.remove(self.taskFile)
+ @inlineCallbacks
+ def task_purgeoldevents(self):
+ with open(self.taskFile) as input:
+ try:
+ value = input.read().strip()
+ days = int(value)
+ except ValueError:
+ log.error("Illegal value for purge days: %s" % (value,))
+ else:
+ cutoff = (date.today() -
+ timedelta(days=days)).strftime("%Y%m%dT000000Z")
+ count = (yield purgeOldEvents(self.service.directory,
+ self.service.root, cutoff))
+ log.info("Purged %d events" % (count,))
+
+ os.remove(self.taskFile)
+
+
class CalDAVTaskService(Service):
def __init__(self, root):
self.root = root
self.directory = root.directory
- self.seconds = 30 # How often to check for new tasks in incomingDir
+ self.seconds = 5 # How often to check for new tasks in incomingDir
self.taskDir = os.path.join(config.DataRoot, "tasks")
# New task files are placed into "incoming"
self.incomingDir = os.path.join(self.taskDir, "incoming")
Added: CalendarServer/trunk/calendarserver/tools/purge.py
===================================================================
--- CalendarServer/trunk/calendarserver/tools/purge.py (rev 0)
+++ CalendarServer/trunk/calendarserver/tools/purge.py 2010-03-03 21:08:46 UTC (rev 5233)
@@ -0,0 +1,109 @@
+#!/usr/bin/env python
+
+##
+# Copyright (c) 2006-2010 Apple Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##
+
+from twext.python.log import Logger
+from twistedcaldav import caldavxml
+from twistedcaldav.caldavxml import TimeRange
+from twistedcaldav.ical import Component as iComponent
+from twistedcaldav.method.delete_common import DeleteResource
+from twisted.internet.defer import inlineCallbacks, returnValue
+from calendarserver.util import FakeRequest
+
+log = Logger()
+
+ at inlineCallbacks
+def purgeOldEvents(directory, root, date):
+
+ calendars = root.getChild("calendars")
+ uidsFPath = calendars.fp.child("__uids__")
+
+ records = []
+ if uidsFPath.exists():
+ for firstFPath in uidsFPath.children():
+ if len(firstFPath.basename()) == 2:
+ for secondFPath in firstFPath.children():
+ if len(secondFPath.basename()) == 2:
+ for homeFPath in secondFPath.children():
+ uid = homeFPath.basename()
+ record = directory.recordWithUID(uid)
+ if record is not None:
+ records.append(record)
+
+ log.info("Purging events from %d calendar homes" % (len(records),))
+
+ filter = caldavxml.Filter(
+ caldavxml.ComponentFilter(
+ caldavxml.ComponentFilter(
+ TimeRange(end=date,),
+ name=("VEVENT", "VFREEBUSY", "VAVAILABILITY"),
+ ),
+ name="VCALENDAR",
+ )
+ )
+
+ eventCount = 0
+ for record in records:
+ # Get the calendar home
+ principalCollection = directory.principalCollection
+ principal = principalCollection.principalForRecord(record)
+ calendarHome = principal.calendarHome()
+
+ # For each collection in calendar home...
+ for collName in calendarHome.listChildren():
+ collection = calendarHome.getChild(collName)
+ if collection.isCalendarCollection():
+ # ...use their indexes to figure out which events to purge
+ for name, uid, type in collection.index().indexedSearch(filter):
+ resource = collection.getChild(name)
+
+ # indexedSearch also returns endless repeating events, but
+ # we don't want to purge those
+ data = resource.iCalendarText()
+ try:
+ calendar = iComponent.fromString(data)
+ except ValueError, e:
+ log.error("Error parsing %s: %s" % (name, e))
+ continue
+ if calendar.isRecurringUnbounded():
+ continue
+
+ uri = "/calendars/__uids__/%s/%s/%s" % (
+ record.uid,
+ collName,
+ name
+ )
+ try:
+ response = (yield deleteResource(root, collection,
+ resource, uri))
+ eventCount += 1
+ except Exception, e:
+ log.error("Failed to purge old event: %s (%s)" %
+ (uri, e))
+
+ returnValue(eventCount)
+
+
+def deleteResource(root, collection, resource, uri):
+ request = FakeRequest(root, "DELETE", uri)
+
+ # TODO: this seems hacky, even for a stub request:
+ request._rememberResource(resource, uri)
+
+ deleter = DeleteResource(request, resource, uri,
+ collection, "infinity", allowImplicitSchedule=False)
+ return deleter.run()
Property changes on: CalendarServer/trunk/calendarserver/tools/purge.py
___________________________________________________________________
Added: svn:executable
+ *
Added: CalendarServer/trunk/calendarserver/tools/test/purge/accounts.xml
===================================================================
--- CalendarServer/trunk/calendarserver/tools/test/purge/accounts.xml (rev 0)
+++ CalendarServer/trunk/calendarserver/tools/test/purge/accounts.xml 2010-03-03 21:08:46 UTC (rev 5233)
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+Copyright (c) 2006-2010 Apple Inc. All rights reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+ -->
+
+<!DOCTYPE accounts SYSTEM "../../../conf/auth/accounts.dtd">
+
+<accounts realm="/Search">
+ <user>
+ <uid>example</uid>
+ <guid>6423F94A-6B76-4A3A-815B-D52CFD77935D</guid>
+ <password>example</password>
+ <name>Example User</name>
+ <email-address>example at example.com</email-address>
+ </user>
+</accounts>
Added: CalendarServer/trunk/calendarserver/tools/test/test_purge.py
===================================================================
--- CalendarServer/trunk/calendarserver/tools/test/test_purge.py (rev 0)
+++ CalendarServer/trunk/calendarserver/tools/test/test_purge.py 2010-03-03 21:08:46 UTC (rev 5233)
@@ -0,0 +1,293 @@
+##
+# 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.
+##
+
+import os
+import zlib
+
+from twext.python.filepath import CachingFilePath as FilePath
+from twisted.internet import reactor
+from twisted.internet.defer import inlineCallbacks, Deferred, returnValue
+
+from twistedcaldav.config import config
+from twistedcaldav.test.util import TestCase
+from calendarserver.util import getRootResource
+from calendarserver.tools.purge import purgeOldEvents
+
+resourceAttr = "WebDAV:{DAV:}resourcetype"
+collectionType = zlib.compress("""<?xml version='1.0' encoding='UTF-8'?>
+<resourcetype xmlns='DAV:'>
+ <collection/>
+ <calendar xmlns='urn:ietf:params:xml:ns:caldav'/>
+</resourcetype>
+""")
+
+
+class PurgeOldEventsTestCase(TestCase):
+
+ def setUp(self):
+ super(PurgeOldEventsTestCase, self).setUp()
+
+ config.DirectoryService.params['xmlFile'] = os.path.join(os.path.dirname(__file__), "purge", "accounts.xml")
+ self.rootResource = getRootResource(config)
+ self.directory = self.rootResource.getDirectory()
+
+ @inlineCallbacks
+ def test_purge(self):
+ before = {
+ "calendars" : {
+ "__uids__" : {
+ "64" : {
+ "23" : {
+ "6423F94A-6B76-4A3A-815B-D52CFD77935D" : {
+ "calendar": {
+ "@xattrs" :
+ {
+ resourceAttr : collectionType,
+ },
+ "oneshot.ics": {
+ "@contents" : OLD_ICS,
+ },
+ "repeating.ics": {
+ "@contents" : REPEATING_ICS,
+ },
+ "awhile.ics": {
+ "@contents" : REPEATING_AWHILE_ICS,
+ },
+ "recent.ics": {
+ "@contents" : RECENT_ICS,
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ }
+ self.createHierarchy(before, config.DocumentRoot)
+
+ count = (yield purgeOldEvents(self.directory, self.rootResource,
+ "20100303T000000Z"))
+
+ self.assertEquals(count, 2)
+
+ after = {
+ "calendars" : {
+ "__uids__" : {
+ "64" : {
+ "23" : {
+ "6423F94A-6B76-4A3A-815B-D52CFD77935D" : {
+ "calendar": {
+ ".db.sqlite": {
+ "@contents" : None, # ignore contents
+ },
+ "repeating.ics": {
+ "@contents" : REPEATING_ICS,
+ },
+ "recent.ics": {
+ "@contents" : RECENT_ICS,
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ }
+ self.assertTrue(self.verifyHierarchy(config.DocumentRoot, after))
+
+
+
+
+OLD_ICS = """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//Apple Inc.//iCal 4.0.1//EN
+CALSCALE:GREGORIAN
+BEGIN:VTIMEZONE
+TZID:US/Pacific
+BEGIN:STANDARD
+TZOFFSETFROM:-0700
+RRULE:FREQ=YEARLY;UNTIL=20061029T090000Z;BYMONTH=10;BYDAY=-1SU
+DTSTART:19621028T020000
+TZNAME:PST
+TZOFFSETTO:-0800
+END:STANDARD
+BEGIN:DAYLIGHT
+TZOFFSETFROM:-0800
+RRULE:FREQ=YEARLY;UNTIL=20060402T100000Z;BYMONTH=4;BYDAY=1SU
+DTSTART:19870405T020000
+TZNAME:PDT
+TZOFFSETTO:-0700
+END:DAYLIGHT
+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:20100303T181216Z
+UID:685BC3A1-195A-49B3-926D-388DDACA78A6
+DTEND;TZID=US/Pacific:20000307T151500
+TRANSP:OPAQUE
+SUMMARY:Ancient event
+DTSTART;TZID=US/Pacific:20000307T111500
+DTSTAMP:20100303T181220Z
+SEQUENCE:2
+END:VEVENT
+END:VCALENDAR
+""".replace("\n", "\r\n")
+
+REPEATING_ICS = """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//Apple Inc.//iCal 4.0.1//EN
+CALSCALE:GREGORIAN
+BEGIN:VTIMEZONE
+TZID:US/Pacific
+BEGIN:STANDARD
+TZOFFSETFROM:-0700
+RRULE:FREQ=YEARLY;UNTIL=20061029T090000Z;BYMONTH=10;BYDAY=-1SU
+DTSTART:19621028T020000
+TZNAME:PST
+TZOFFSETTO:-0800
+END:STANDARD
+BEGIN:DAYLIGHT
+TZOFFSETFROM:-0800
+RRULE:FREQ=YEARLY;UNTIL=20060402T100000Z;BYMONTH=4;BYDAY=1SU
+DTSTART:19870405T020000
+TZNAME:PDT
+TZOFFSETTO:-0700
+END:DAYLIGHT
+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:20100303T194654Z
+UID:9FDE0E4C-1495-4CAF-863B-F7F0FB15FE8C
+DTEND;TZID=US/Pacific:20000308T151500
+RRULE:FREQ=YEARLY;INTERVAL=1
+TRANSP:OPAQUE
+SUMMARY:Ancient Repeating Endless
+DTSTART;TZID=US/Pacific:20000308T111500
+DTSTAMP:20100303T194710Z
+SEQUENCE:4
+END:VEVENT
+END:VCALENDAR
+""".replace("\n", "\r\n")
+
+REPEATING_AWHILE_ICS = """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//Apple Inc.//iCal 4.0.1//EN
+CALSCALE:GREGORIAN
+BEGIN:VTIMEZONE
+TZID:US/Pacific
+BEGIN:STANDARD
+TZOFFSETFROM:-0700
+RRULE:FREQ=YEARLY;UNTIL=20061029T090000Z;BYMONTH=10;BYDAY=-1SU
+DTSTART:19621028T020000
+TZNAME:PST
+TZOFFSETTO:-0800
+END:STANDARD
+BEGIN:DAYLIGHT
+TZOFFSETFROM:-0800
+RRULE:FREQ=YEARLY;UNTIL=20060402T100000Z;BYMONTH=4;BYDAY=1SU
+DTSTART:19870405T020000
+TZNAME:PDT
+TZOFFSETTO:-0700
+END:DAYLIGHT
+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:20100303T194716Z
+UID:76236B32-2BC4-4D78-956B-8D42D4086200
+DTEND;TZID=US/Pacific:20000309T151500
+RRULE:FREQ=YEARLY;INTERVAL=1;COUNT=3
+TRANSP:OPAQUE
+SUMMARY:Ancient Repeat Awhile
+DTSTART;TZID=US/Pacific:20000309T111500
+DTSTAMP:20100303T194747Z
+SEQUENCE:6
+END:VEVENT
+END:VCALENDAR
+""".replace("\n", "\r\n")
+
+RECENT_ICS = """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//Apple Inc.//iCal 4.0.1//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:20100303T195159Z
+UID:F2F14D94-B944-43D9-8F6F-97F95B2764CA
+DTEND;TZID=US/Pacific:20100304T141500
+TRANSP:OPAQUE
+SUMMARY:Recent
+DTSTART;TZID=US/Pacific:20100304T120000
+DTSTAMP:20100303T195203Z
+SEQUENCE:2
+END:VEVENT
+END:VCALENDAR
+""".replace("\n", "\r\n")
+
Modified: CalendarServer/trunk/calendarserver/util.py
===================================================================
--- CalendarServer/trunk/calendarserver/util.py 2010-03-03 17:39:59 UTC (rev 5232)
+++ CalendarServer/trunk/calendarserver/util.py 2010-03-03 21:08:46 UTC (rev 5233)
@@ -17,6 +17,7 @@
__all__ = [
"getRootResource",
+ "FakeRequest",
]
import errno
@@ -26,6 +27,7 @@
from twisted.python.reflect import namedClass
from twisted.internet import reactor
from twisted.cred.portal import Portal
+from twext.web2.http_headers import Headers
from twext.web2.dav import auth
from twext.web2.auth.basic import BasicCredentialFactory
from twext.web2.static import File as FileResource
@@ -50,6 +52,7 @@
from twistedcaldav.static import TimezoneServiceFile
from twistedcaldav.static import AddressBookHomeProvisioningFile, DirectoryBackedAddressBookFile
from twistedcaldav.timezones import TimezoneCache
+from twisted.internet.defer import inlineCallbacks, returnValue
try:
from twistedcaldav.authkerb import NegotiateCredentialFactory
@@ -429,3 +432,49 @@
return logWrapper
+
+
+
+class FakeRequest(object):
+
+ def __init__(self, rootResource, method, path):
+ self.rootResource = rootResource
+ self.method = method
+ self.path = path
+ self._resourcesByURL = {}
+ self._urlsByResource = {}
+ self.headers = Headers()
+
+ @inlineCallbacks
+ def _getChild(self, resource, segments):
+ if not segments:
+ returnValue(resource)
+
+ child, remaining = (yield resource.locateChild(self, segments))
+ returnValue((yield self._getChild(child, remaining)))
+
+ @inlineCallbacks
+ def locateResource(self, url):
+ url = url.strip("/")
+ segments = url.split("/")
+ resource = (yield self._getChild(self.rootResource, segments))
+ if resource:
+ self._rememberResource(resource, url)
+ returnValue(resource)
+
+ def _rememberResource(self, resource, url):
+ self._resourcesByURL[url] = resource
+ self._urlsByResource[resource] = url
+ return resource
+
+ def urlForResource(self, resource):
+ url = self._urlsByResource.get(resource, None)
+ if url is None:
+ class NoURLForResourceError(RuntimeError):
+ pass
+ raise NoURLForResourceError(resource)
+ return url
+
+ def addResponseFilter(*args, **kwds):
+ pass
+
Modified: CalendarServer/trunk/twext/web2/resource.py
===================================================================
--- CalendarServer/trunk/twext/web2/resource.py 2010-03-03 17:39:59 UTC (rev 5232)
+++ CalendarServer/trunk/twext/web2/resource.py 2010-03-03 21:08:46 UTC (rev 5233)
@@ -312,5 +312,8 @@
return x.addCallback(lambda data: self.resource)
return self.resource
+ def getChild(self, name):
+ return self.resource.getChild(name)
+
__all__ = ['RenderMixin', 'Resource', 'PostableResource', 'LeafResource', 'WrapperResource']
Modified: CalendarServer/trunk/twistedcaldav/method/delete_common.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/method/delete_common.py 2010-03-03 17:39:59 UTC (rev 5232)
+++ CalendarServer/trunk/twistedcaldav/method/delete_common.py 2010-03-03 21:08:46 UTC (rev 5233)
@@ -43,7 +43,8 @@
class DeleteResource(object):
- def __init__(self, request, resource, resource_uri, parent, depth, internal_request=False):
+ def __init__(self, request, resource, resource_uri, parent, depth,
+ internal_request=False, allowImplicitSchedule=True):
self.request = request
self.resource = resource
@@ -51,6 +52,7 @@
self.parent = parent
self.depth = depth
self.internal_request = internal_request
+ self.allowImplicitSchedule = allowImplicitSchedule
def validIfScheduleMatch(self):
"""
@@ -139,7 +141,7 @@
scheduler = None
lock = None
- if not self.internal_request:
+ if not self.internal_request and self.allowImplicitSchedule:
# Get data we need for implicit scheduling
calendar = delresource.iCalendar()
scheduler = ImplicitScheduler()
@@ -164,7 +166,7 @@
index.deleteResource(delresource.fp.basename(), newrevision)
# Do scheduling
- if scheduler and not self.internal_request:
+ if scheduler and not self.internal_request and self.allowImplicitSchedule:
yield scheduler.doImplicitScheduling()
except MemcacheLockTimeoutError:
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20100303/05558a19/attachment-0001.html>
More information about the calendarserver-changes
mailing list