[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