[CalendarServer-changes] [428] CalendarServer/branches/users/wsanchez/provisioning/twistedcaldav/ directory/appleopendirectory.py

source_changes at macosforge.org source_changes at macosforge.org
Fri Nov 10 14:03:44 PST 2006


Revision: 428
          http://trac.macosforge.org/projects/calendarserver/changeset/428
Author:   wsanchez at apple.com
Date:     2006-11-10 14:03:43 -0800 (Fri, 10 Nov 2006)

Log Message:
-----------
Add a per-type record cache to OpenDirectoryService.
For now, the cache lives for 5 minutes.

Modified Paths:
--------------
    CalendarServer/branches/users/wsanchez/provisioning/twistedcaldav/directory/appleopendirectory.py

Modified: CalendarServer/branches/users/wsanchez/provisioning/twistedcaldav/directory/appleopendirectory.py
===================================================================
--- CalendarServer/branches/users/wsanchez/provisioning/twistedcaldav/directory/appleopendirectory.py	2006-11-10 21:41:43 UTC (rev 427)
+++ CalendarServer/branches/users/wsanchez/provisioning/twistedcaldav/directory/appleopendirectory.py	2006-11-10 22:03:43 UTC (rev 428)
@@ -29,11 +29,15 @@
 import opendirectory
 import dsattributes
 
+from twisted.python import log
+from twisted.internet import reactor
 from twisted.cred.credentials import UsernamePassword
 
 from twistedcaldav.directory.directory import DirectoryService, DirectoryRecord
 from twistedcaldav.directory.directory import DirectoryError, UnknownRecordTypeError
 
+recordListCacheTimeout = 60 * 5 # 5 minutes
+
 class OpenDirectoryService(DirectoryService):
     """
     Open Directory implementation of L{IDirectoryService}.
@@ -48,65 +52,85 @@
 
         self.directory = directory
         self.node = node
+        self.records = {}
 
     def recordTypes(self):
         return ("user", "group", "resource")
 
-    def listRecords(self, recordType):
-        if recordType == "user":
-            listRecords = opendirectory.listUsers
-        elif recordType == "group":
-            listRecords = opendirectory.listGroups
-        elif recordType == "resource":
-            listRecords = opendirectory.listResources
-        else:
-            raise UnknownRecordTypeError("Unknown Open Directory record type: %s" % (recordType,))
+    def _cacheRecords(self, recordType):
+        if recordType not in self.records:
+            log.msg("Reloading %s record cache" % (recordType,))
 
-        for shortName, guid, lastModified, principalURI in listRecords(self.directory):
-            if guid:
-                yield OpenDirectoryRecord(
-                    service = self,
-                    recordType = recordType,
-                    guid = guid,
-                    shortName = shortName,
-                    fullName = None,
-                )
+            if recordType == "user":
+                listRecords = opendirectory.listUsers
+            elif recordType == "group":
+                listRecords = opendirectory.listGroups
+            elif recordType == "resource":
+                listRecords = opendirectory.listResources
+            else:
+                raise UnknownRecordTypeError("Unknown Open Directory record type: %s" % (recordType,))
 
-    def recordWithShortName(self, recordType, shortName):
-        if recordType == "user":
-            listRecords = opendirectory.listUsersWithAttributes
-        elif recordType == "group":
-            listRecords = opendirectory.listGroupsWithAttributes
-        elif recordType == "resource":
-            listRecords = opendirectory.listResourcesWithAttributes
-        else:
-            raise UnknownRecordTypeError("Unknown record type: %s" % (recordType,))
+            records = {}
 
-        result = listRecords(self.directory, [shortName])
-        if result is None or shortName not in result:
-            return None
-        else:
-            result = result[shortName]
+            for shortName, guid, lastModified, principalURI in listRecords(self.directory):
+                if guid:
+                    records[shortName] = OpenDirectoryRecord(
+                        service = self,
+                        recordType = recordType,
+                        guid = guid,
+                        shortName = shortName,
+                        fullName = None,
+                    )
 
-        if dsattributes.attrGUID in result:
-            guid = result[dsattributes.attrGUID]
-        else:
-            raise DirectoryError("Found OpenDirectory record %s of type %s with no GUID attribute"
-                                 % (shortName, recordType))
+            self.records[recordType] = records
 
-        if dsattributes.attrRealName in result:
-            fullName = result[dsattributes.attrRealName]
-        else:
-            fullName = None
+            def flushCache():
+                del(records[recordType])
+            reactor.callLater(recordListCacheTimeout, lambda: flushCache)
 
-        return OpenDirectoryRecord(
-            service = self,
-            recordType = recordType,
-            guid = guid,
-            shortName = shortName,
-            fullName = fullName,
-        )
+        return self.records[recordType]
 
+    def listRecords(self, recordType):
+        return self._cacheRecords(recordType).values()
+
+    def recordWithShortName(self, recordType, shortName):
+        return self._cacheRecords(recordType).get(shortName, None)
+
+#    def recordWithShortName(self, recordType, shortName):
+#        if recordType == "user":
+#            listRecords = opendirectory.listUsersWithAttributes
+#        elif recordType == "group":
+#            listRecords = opendirectory.listGroupsWithAttributes
+#        elif recordType == "resource":
+#            listRecords = opendirectory.listResourcesWithAttributes
+#        else:
+#            raise UnknownRecordTypeError("Unknown record type: %s" % (recordType,))
+#
+#        result = listRecords(self.directory, [shortName])
+#        if result is None or shortName not in result:
+#            return None
+#        else:
+#            result = result[shortName]
+#
+#        if dsattributes.attrGUID in result:
+#            guid = result[dsattributes.attrGUID]
+#        else:
+#            raise DirectoryError("Found OpenDirectory record %s of type %s with no GUID attribute"
+#                                 % (shortName, recordType))
+#
+#        if dsattributes.attrRealName in result:
+#            fullName = result[dsattributes.attrRealName]
+#        else:
+#            fullName = None
+#
+#        return OpenDirectoryRecord(
+#            service = self,
+#            recordType = recordType,
+#            guid = guid,
+#            shortName = shortName,
+#            fullName = fullName,
+#        )
+
 class OpenDirectoryRecord(DirectoryRecord):
     """
     Open Directory implementation of L{IDirectoryRecord}.
@@ -115,9 +139,15 @@
         if self.recordType != "group":
             return ()
 
+        # FIXME:
+        # Need an API here from opendirectory which finds all members of a group
+
         raise NotImplementedError("OpenDirectoryRecord.members() for groups")
 
     def groups(self):
+        # FIXME:
+        # Need an API here from opendirectory which finds all groups containing this member
+
         raise NotImplementedError("OpenDirectoryRecord.groups()")
 
     def verifyCredentials(self, credentials):

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20061110/63f0c44e/attachment.html


More information about the calendarserver-changes mailing list