[CalendarServer-changes] [3279] CalendarServer/trunk/calendarserver/tools/export.py
source_changes at macosforge.org
source_changes at macosforge.org
Thu Oct 30 12:06:29 PDT 2008
Revision: 3279
http://trac.macosforge.org/projects/calendarserver/changeset/3279
Author: wsanchez at apple.com
Date: 2008-10-30 12:06:29 -0700 (Thu, 30 Oct 2008)
Log Message:
-----------
This tool can't be dependant on OD. If we want to add directory-type
stuff, it needs to read the caldavd.plist and use the IDirectory API.
Modified Paths:
--------------
CalendarServer/trunk/calendarserver/tools/export.py
Modified: CalendarServer/trunk/calendarserver/tools/export.py
===================================================================
--- CalendarServer/trunk/calendarserver/tools/export.py 2008-10-30 18:44:52 UTC (rev 3278)
+++ CalendarServer/trunk/calendarserver/tools/export.py 2008-10-30 19:06:29 UTC (rev 3279)
@@ -1,5 +1,4 @@
#!/usr/bin/env python
-import dsquery
##
# Copyright (c) 2006-2007 Apple Inc. All rights reserved.
@@ -25,173 +24,22 @@
from twistedcaldav.resource import isCalendarCollectionResource
from twistedcaldav.static import CalDAVFile
-try:
- import opendirectory
- import dsattributes
-except ImportError:
- sys.path.append("/usr/share/caldavd/lib/python")
- import opendirectory
- import dsattributes
+class UsageError (StandardError):
+ pass
-try:
- from plistlib import readPlist
-except ImportError:
- from twistedcaldav.py.plistlib import readPlist
-
-class CalendarExporter(object):
-
- def __init__(self, plistpath, users, output_dir):
-
- self.plistpath = plistpath
- self.users = users
- self.output_dir = output_dir
-
- self.dsnode = None
- self.docroot = None
-
- def run(self):
- self._extractPlistPieces()
- self.od = opendirectory.odInit(self.dsnode)
-
- for user in self.users:
- print ""
- print "Dumping user: %s" % (user,)
- self._dumpUser(user)
-
- def _extractPlistPieces(self):
-
- plist = readPlist(self.plistpath)
-
- try:
- self.dsnode = plist["DirectoryService"]["params"]["node"]
- except KeyError:
- raise ValueError("Unable to read DirectoryService/params/node key from plist: %s" % (self.plistpath,))
-
- try:
- self.docroot = plist["DocumentRoot"]
- except KeyError:
- raise ValueError("Unable to read DocumentRoot key from plist: %s" % (self.plistpath,))
-
- print ""
- print "Parsed: %s" % (self.plistpath,)
- print "Found DS Node: %s" % (self.dsnode,)
- print "Found Server docroot: %s" % (self.docroot)
- print "Output directory: %s" % (self.output_dir)
-
- def _getCalendarHome(self, user):
-
- guid = self._getUserGUID(user)
- return os.path.join(self.docroot, "calendars/__uids__", guid[0:2], guid[2:4], guid)
-
- def _getUserGUID(self, user):
-
- query = dsquery.match(dsattributes.kDSNAttrRecordName, user, dsattributes.eDSExact)
-
- results = opendirectory.queryRecordsWithAttribute_list(
- self.od,
- query.attribute,
- query.value,
- query.matchType,
- False,
- dsattributes.kDSStdRecordTypeUsers,
- [dsattributes.kDS1AttrGeneratedUID,]
- )
-
- for (_ignore, record) in results:
- guid = record.get(dsattributes.kDS1AttrGeneratedUID, None)
- if guid:
- return guid
- else:
- raise ValueError("No directory record for user: %s" % (user,))
-
- def _findCalendars(self, basepath):
-
- paths = []
-
- def _addDirectories(path):
-
- for child in os.listdir(path):
- childpath = os.path.join(path, child)
- resource = CalDAVFile(childpath)
- if resource.exists() and isCalendarCollectionResource(resource):
- paths.append(childpath)
- continue
- elif os.path.isdir(childpath):
- _addDirectories(childpath)
-
- _addDirectories(basepath)
- return paths
-
- def _dumpUser(self, user):
-
- # Find the user's calendar home
- calendar_home = self._getCalendarHome(user)
- if not os.path.exists(calendar_home):
- print "Error: No calendar home for user: %s" % (user,)
- return
-
- # Create an output directory for the user
- user_dir = os.path.join(self.output_dir, user)
- if not os.path.exists(user_dir):
- os.makedirs(user_dir)
-
- # List all possible calendars
- calendar_paths = self._findCalendars(calendar_home)
-
- for calendar_path in calendar_paths:
- resource = CalDAVFile(calendar_path)
-
- if not resource.exists() or not isCalendarCollectionResource(resource):
- continue
-
- calendar = iComponent("VCALENDAR")
- calendar.addProperty(iProperty("VERSION", "2.0"))
-
- tzids = set()
-
- for name, _ignore_uid, type in resource.index().search(None):
- child = resource.getChild(name)
- child_data = child.iCalendarText()
-
- try:
- child_calendar = iComponent.fromString(child_data)
- except ValueError:
- continue
- assert child_calendar.name() == "VCALENDAR"
-
- for component in child_calendar.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)
-
- f = file(os.path.join(user_dir, os.path.basename(calendar_path)), "w")
- f.write(str(calendar))
- f.close()
- print "Dumped calendar for user '%s': %s" % (user, calendar_path,)
-
def usage(e=None):
if e:
print e
print ""
name = os.path.basename(sys.argv[0])
- print "usage: %s [-f plistfile] [-o outputdir] [-u user]" % (name,)
+ print "usage: %s [-c collection]" % (name,)
print ""
print "Generate an iCalendar file containing the merged content of each calendar"
print "collection specified."
print ""
print "options:"
print " -h: print this help"
- print " -f: plist file for server configuration (/etc/caldavd/caldavd.plist)"
- print " -o: directory in which to write results (./exported)"
- print " -u: user record name to lookup (can appear multiple times)"
- print " -h: print this help"
if e:
sys.exit(64)
@@ -200,39 +48,64 @@
def main():
try:
- (optargs, args) = getopt.getopt(sys.argv[1:], "hf:o:u:", ["help",])
+ (optargs, args) = getopt.getopt(sys.argv[1:], "hc:", ["help", "collection="])
except getopt.GetoptError, e:
usage(e)
- plistpath = "/etc/caldavd/caldavd.plist"
- users = set()
- output_dir = os.path.join(os.getcwd(), "exported")
+ collections = set()
for opt, arg in optargs:
if opt in ("-h", "--help"):
usage()
- elif opt in ("-o",):
- output_dir = arg
- elif opt in ("-u",):
- users.add(arg)
- elif opt == "-f":
- plistpath = arg
+ if opt in ("-c", "--collection"):
+ collections.add(arg)
if args:
usage("Too many arguments: %s" % (" ".join(args),))
try:
- print "CalendarServer calendar user export tool"
- print "====================================="
-
- if not os.path.exists(plistpath):
- raise ValueError("caldavd.plist file does not exist: %s" % (plistpath,))
-
- CalendarExporter(plistpath, users, output_dir).run()
+ calendar = iComponent("VCALENDAR")
+ calendar.addProperty(iProperty("VERSION", "2.0"))
- except ValueError, e:
- print ""
- print "Failed: %s" % (str(e),)
+ uids = set()
+ tzids = set()
+ for collection in collections:
+ resource = CalDAVFile(collection)
+
+ if not resource.exists() or not isCalendarCollectionResource(resource):
+ sys.stderr.write("Not a calendar collection: %s\n" % (collection,))
+ sys.exit(1)
+
+ for name, uid, type in resource.index().search(None):
+ child = resource.getChild(name)
+ child_data = child.iCalendarText()
+
+ try:
+ child_calendar = iComponent.fromString(child_data)
+ except ValueError:
+ continue
+ assert child_calendar.name() == "VCALENDAR"
+
+ if uid in uids:
+ sys.stderr.write("Skipping duplicate event UID: %s" % (uid,))
+ continue
+ else:
+ uids.add(uid)
+
+ for component in child_calendar.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)
+
+ except UsageError, e:
+ usage(e)
+
if __name__ == "__main__":
main()
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20081030/3c75fba5/attachment.html>
More information about the calendarserver-changes
mailing list