[CalendarServer-changes] [4027] CalendarServer/trunk/bin/caldav_utility.py
source_changes at macosforge.org
source_changes at macosforge.org
Thu Apr 16 11:06:36 PDT 2009
Revision: 4027
http://trac.macosforge.org/projects/calendarserver/changeset/4027
Author: sagen at apple.com
Date: 2009-04-16 11:06:35 -0700 (Thu, 16 Apr 2009)
Log Message:
-----------
Work in progress on a tool for manipulating data in a running environment
Added Paths:
-----------
CalendarServer/trunk/bin/caldav_utility.py
Added: CalendarServer/trunk/bin/caldav_utility.py
===================================================================
--- CalendarServer/trunk/bin/caldav_utility.py (rev 0)
+++ CalendarServer/trunk/bin/caldav_utility.py 2009-04-16 18:06:35 UTC (rev 4027)
@@ -0,0 +1,303 @@
+#!/usr/bin/env python
+
+##
+# Copyright (c) 2006-2009 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 __future__ import with_statement
+
+import sys
+
+if "PYTHONPATH" in globals():
+ sys.path.insert(0, PYTHONPATH)
+else:
+ from os.path import dirname, abspath, join
+ from subprocess import Popen, PIPE
+
+ home = dirname(dirname(abspath(__file__)))
+ run = join(home, "run")
+
+ child = Popen((run, "-p"), stdout=PIPE)
+ path, stderr = child.communicate()
+
+ if child.wait() == 0:
+ sys.path[0:0] = path.split(":")
+
+# sys.path.insert(0, "/usr/share/caldavd/lib/python")
+
+import os
+import itertools
+from code import interact
+
+from getopt import getopt, GetoptError
+from os.path import dirname, abspath
+
+from twisted.internet import reactor
+from twisted.internet.defer import inlineCallbacks, returnValue, succeed
+from twisted.python import log
+from twisted.python.reflect import namedClass
+from twisted.web2.dav import davxml
+# from twisted.web2.http import Request
+
+from twistedcaldav import ical
+from twistedcaldav import caldavxml
+from twistedcaldav.resource import isPseudoCalendarCollectionResource
+from twistedcaldav.static import CalDAVFile, CalendarHomeFile, CalendarHomeProvisioningFile
+from twistedcaldav.config import config, defaultConfigFile
+from twistedcaldav.directory.directory import DirectoryService, DirectoryRecord
+from twistedcaldav.directory.principal import DirectoryPrincipalProvisioningResource
+
+from calendarserver.provision.root import RootResource
+
+
+from twistedcaldav import memcachepool
+from twistedcaldav.notify import installNotificationClient
+from twisted.internet.address import IPv4Address
+
+# This dictionary is a mapping of symbols that other modules might want
+# to use; it's populated by the @exportmethod decorator below.
+exportedSymbols = { }
+
+def exportmethod(method):
+ """ Add the method to exportedSymbols """
+ global exportedSymbols
+ exportedSymbols[method.func_name] = method
+ return method
+
+def getExports(**kw):
+ """ Return a copy of exportedSymbols, with kw included """
+ exports = exportedSymbols.copy()
+ exports.update(**kw)
+ return exports
+
+
+
+def loadConfig(configFileName):
+ if configFileName is None:
+ configFileName = defaultConfigFile
+
+ if not os.path.isfile(configFileName):
+ sys.stderr.write("No config file: %s\n" % (configFileName,))
+ sys.exit(1)
+
+ config.loadConfig(configFileName)
+
+ return config
+
+
+def getDirectory():
+ BaseDirectoryService = namedClass(config.DirectoryService["type"])
+
+ class MyDirectoryService (BaseDirectoryService):
+ def getPrincipalCollection(self):
+ if not hasattr(self, "_principalCollection"):
+ from twistedcaldav.directory.principal import DirectoryPrincipalProvisioningResource
+ self._principalCollection = DirectoryPrincipalProvisioningResource("/principals/", self)
+
+ return self._principalCollection
+
+ def setPrincipalCollection(self, coll):
+ # See principal.py line 237: self.directory.principalCollection = self
+ pass
+
+ principalCollection = property(getPrincipalCollection, setPrincipalCollection)
+
+ def calendarHomeForRecord(self, record):
+ principal = self.principalCollection.principalForRecord(record)
+ if principal:
+ try:
+ return principal._calendarHome()
+ except AttributeError:
+ pass
+ return None
+
+ def calendarHomeForShortName(self, recordType, shortName):
+ principal = self.principalCollection.principalForShortName(recordType, shortName)
+ if principal:
+ try:
+ return principal._calendarHome()
+ except AttributeError:
+ pass
+ return None
+
+ def principalForCalendarUserAddress(self, cua):
+ return self.principalCollection.principalForCalendarUserAddress(cua)
+
+
+ return MyDirectoryService(**config.DirectoryService["params"])
+
+class DummyDirectoryService (DirectoryService):
+ realmName = ""
+ baseGUID = "51856FD4-5023-4890-94FE-4356C4AAC3E4"
+ def recordTypes(self): return ()
+ def listRecords(self): return ()
+ def recordWithShortName(self): return None
+
+dummyDirectoryRecord = DirectoryRecord(
+ service = DummyDirectoryService(),
+ recordType = "dummy",
+ guid = "8EF0892F-7CB6-4B8E-B294-7C5A5321136A",
+ shortNames = ("dummy",),
+ fullName = "Dummy McDummerson",
+ calendarUserAddresses = set(),
+ autoSchedule = False,
+)
+
+def setup():
+
+ directory = getDirectory()
+ if config.Memcached["ClientEnabled"]:
+ memcachepool.installPool(
+ IPv4Address(
+ 'TCP',
+ config.Memcached["BindAddress"],
+ config.Memcached["Port"]
+ ),
+ config.Memcached["MaxClients"]
+ )
+ if config.Notifications["Enabled"]:
+ installNotificationClient(
+ config.Notifications["InternalNotificationHost"],
+ config.Notifications["InternalNotificationPort"],
+ )
+ principalCollection = directory.getPrincipalCollection()
+ root = RootResource(
+ config.DocumentRoot,
+ principalCollections=(principalCollection,),
+ )
+ root.putChild("principals", principalCollection)
+ calendarCollection = CalendarHomeProvisioningFile(
+ os.path.join(config.DocumentRoot, "calendars"),
+ directory, "/calendars/",
+ )
+ root.putChild("calendars", calendarCollection)
+
+ return (directory, root)
+
+
+
+class UsageError (StandardError):
+ pass
+
+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 "Change calendar user addresses"
+ print __doc__
+ print "options:"
+ print " -h --help: print this help and exit"
+ print " -f --config: Specify caldavd.plist configuration path"
+ print ""
+ print "input specifiers:"
+ print " -c --changes: add all calendar homes"
+ print " --dry-run: Don't actually change the data"
+
+ if e:
+ sys.exit(64)
+ else:
+ sys.exit(0)
+
+def loadChanges(fileName):
+ addresses = {}
+ with open(fileName) as input:
+ count = 1
+ for line in input:
+ line = line.strip()
+ if line and not line.startswith("#"):
+ try:
+ oldAddr, newAddr = line.split()
+ addresses[oldAddr] = newAddr
+ except Exception, e:
+ print "Could not parse line %d: %s" % (count, line)
+ sys.exit(2)
+ count += 1
+ return addresses
+
+
+
+
+class ResourceWrapper(object):
+
+ def __init__(self, resource):
+ self.resource = resource
+
+ at exportmethod
+def byPath(root, path):
+ resource = root
+ segments = path.strip("/").split("/")
+ for segment in segments:
+ resource = resource.getChild(segment)
+ return ResourceWrapper(resource)
+
+def main():
+ try:
+ (optargs, args) = getopt(
+ sys.argv[1:], "hf:", [
+ "config=",
+ "help",
+ "dry-run",
+ ],
+ )
+ except GetoptError, e:
+ usage(e)
+
+ configFileName = None
+ logFileName = "/dev/stdout"
+ modifyData = True
+ changesFile = None
+
+ directory = None
+ calendarHomePaths = set()
+ calendarHomes = set()
+
+ def checkExists(resource):
+ if not resource.exists():
+ sys.stderr.write("No such file: %s\n" % (resource.fp.path,))
+ sys.exit(1)
+
+ for opt, arg in optargs:
+ if opt in ("-h", "--help"):
+ usage()
+
+ elif opt in ("-f", "--config"):
+ configFileName = arg
+
+ elif opt in ("--dry-run",):
+ modifyData = False
+
+ if args:
+ usage("Too many arguments: %s" % (" ".join(args),))
+
+ observer = log.FileLogObserver(open(logFileName, "a"))
+ log.addObserver(observer.emit)
+
+ loadConfig(configFileName)
+
+ directory, root = setup()
+ exportedSymbols['root'] = root
+ exportedSymbols['directory'] = directory
+
+ banner = "\nWelcome to calendar server\n"
+ interact(banner, None, getExports(__name__="__console__", __doc__=None))
+
+
+if __name__ == "__main__":
+
+ main()
Property changes on: CalendarServer/trunk/bin/caldav_utility.py
___________________________________________________________________
Added: svn:executable
+ *
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20090416/ddd640fd/attachment-0001.html>
More information about the calendarserver-changes
mailing list