[CalendarServer-changes] [3003] CalendarServer/branches/users/sagen/principal-property-search-2995

source_changes at macosforge.org source_changes at macosforge.org
Tue Sep 16 15:45:30 PDT 2008


Revision: 3003
          http://trac.macosforge.org/projects/calendarserver/changeset/3003
Author:   sagen at apple.com
Date:     2008-09-16 15:45:29 -0700 (Tue, 16 Sep 2008)
Log Message:
-----------
Move DAV-property-to-directory-record-field map to directory/principal.py; added default brute-force directory search implementation

Modified Paths:
--------------
    CalendarServer/branches/users/sagen/principal-property-search-2995/lib-patches/Twisted/twisted.web2.dav.method.report_principal_property_search.patch
    CalendarServer/branches/users/sagen/principal-property-search-2995/twistedcaldav/directory/aggregate.py
    CalendarServer/branches/users/sagen/principal-property-search-2995/twistedcaldav/directory/appleopendirectory.py
    CalendarServer/branches/users/sagen/principal-property-search-2995/twistedcaldav/directory/directory.py
    CalendarServer/branches/users/sagen/principal-property-search-2995/twistedcaldav/directory/principal.py

Modified: CalendarServer/branches/users/sagen/principal-property-search-2995/lib-patches/Twisted/twisted.web2.dav.method.report_principal_property_search.patch
===================================================================
--- CalendarServer/branches/users/sagen/principal-property-search-2995/lib-patches/Twisted/twisted.web2.dav.method.report_principal_property_search.patch	2008-09-16 19:38:26 UTC (rev 3002)
+++ CalendarServer/branches/users/sagen/principal-property-search-2995/lib-patches/Twisted/twisted.web2.dav.method.report_principal_property_search.patch	2008-09-16 22:45:29 UTC (rev 3003)
@@ -2,13 +2,7 @@
 ===================================================================
 --- twisted/web2/dav/method/report_principal_property_search.py	(revision 19773)
 +++ twisted/web2/dav/method/report_principal_property_search.py	(working copy)
-@@ -46,17 +46,24 @@
-     Generate a principal-property-search REPORT. (RFC 3744, section 9.4)
-     """
- 
-+
-     # Verify root element
-     if not isinstance(principal_property_search, davxml.PrincipalPropertySearch):
+@@ -51,12 +51,18 @@
          raise ValueError("%s expected as root element, not %s."
                           % (davxml.PrincipalPropertySearch.sname(), principal_property_search.sname()))
  
@@ -28,7 +22,7 @@
      # Get a single DAV:prop element from the REPORT request body
      propertiesForResource = None
      propElement = None
-@@ -93,73 +100,157 @@
+@@ -93,73 +99,147 @@
          else:
              return False
          
@@ -101,25 +95,15 @@
      try:
 -        resources = []
 -        responses = []
-+        # propertySearches is a list of tuple(tuple(props), match)
 +
-+        # TODO: should this mapping live elsewhere?
-+        # See if there are any that are recognized by record fields
-+        cs_ns = "http://calendarserver.org/ns/"
-+        fieldMap = {
-+            "<{%s}%s>" % (cs_ns, "first-name") : "firstName",
-+            "<{%s}%s>" % (cs_ns, "last-name") : "lastName",
-+            "<{%s}%s>" % (cs_ns, "email-address") : "emailAddress",
-+        }
-+
++        # See if we can take advantage of the directory
 +        fields = []
 +        nonDirectorySearches = []
 +        for props, match in propertySearches:
 +            nonDirectoryProps = []
 +            for prop in props:
-+                uri = repr(prop)
-+                if fieldMap.has_key(uri):
-+                    fieldName = fieldMap[uri]
++                fieldName = self.propertyToField(prop)
++                if fieldName:
 +                    fields.append((fieldName, match))
 +                else:
 +                    nonDirectoryProps.append(prop)
@@ -232,7 +216,7 @@
                      yield d
                      d = d.getResult()
                      if d:
-@@ -167,18 +258,26 @@
+@@ -167,18 +247,26 @@
                          matchcount += 1
                          if matchcount > max_number_of_matches:
                              raise NumberOfMatchesWithinLimits

Modified: CalendarServer/branches/users/sagen/principal-property-search-2995/twistedcaldav/directory/aggregate.py
===================================================================
--- CalendarServer/branches/users/sagen/principal-property-search-2995/twistedcaldav/directory/aggregate.py	2008-09-16 19:38:26 UTC (rev 3002)
+++ CalendarServer/branches/users/sagen/principal-property-search-2995/twistedcaldav/directory/aggregate.py	2008-09-16 22:45:29 UTC (rev 3003)
@@ -103,9 +103,13 @@
     def recordWithCalendarUserAddress(self, address):
         return self._queryAll("recordWithCalendarUserAddress", address)
 
-    def recordsMatchingFields(self, fields, caseInsensitive=True, operand="or"):
-        return self._queryAll("recordsMatchingFields", fields,
-            caseInsensitive=caseInsensitive, operand=operand)
+    def recordsMatchingFields(self, fields, caseInsensitive=True, operand="or",
+        recordType=DirectoryService.recordType_users):
+        for service in self._recordTypes.values():
+            for record in service.recordsMatchingFields(fields,
+                caseInsensitive=caseInsensitive, operand=operand,
+                recordType=recordType):
+                    yield record
 
     def serviceForRecordType(self, recordType):
         try:
@@ -124,9 +128,9 @@
             *[a[len(service.recordTypePrefix):] for a in args]
         )
 
-    def _queryAll(self, query, *args, **kwds):
+    def _queryAll(self, query, *args):
         for service in self._recordTypes.values():
-            record = getattr(service, query)(*args, **kwds)
+            record = getattr(service, query)(*args)
             if record is not None:
                 return record
         else:

Modified: CalendarServer/branches/users/sagen/principal-property-search-2995/twistedcaldav/directory/appleopendirectory.py
===================================================================
--- CalendarServer/branches/users/sagen/principal-property-search-2995/twistedcaldav/directory/appleopendirectory.py	2008-09-16 19:38:26 UTC (rev 3002)
+++ CalendarServer/branches/users/sagen/principal-property-search-2995/twistedcaldav/directory/appleopendirectory.py	2008-09-16 22:45:29 UTC (rev 3003)
@@ -467,7 +467,8 @@
         'emailAddress' : dsattributes.kDSNAttrEMailAddress,
     }
 
-    def recordsMatchingFields(self, fields, caseInsensitive=True, operand="or"):
+    def recordsMatchingFields(self, fields, caseInsensitive=True, operand="or",
+        recordType=DirectoryService.recordType_users):
 
         comparison = dsattributes.eDSStartsWith
         operand = (dsquery.expression.OR if operand == "or"
@@ -494,7 +495,6 @@
                 dsattributes.kDSNAttrMetaNodeLocation,
             ]
         )
-        returning = []
         for key, val in results.iteritems():
             try:
                 calendarUserAddresses = set()
@@ -519,14 +519,12 @@
                     proxyGUIDs = (),
                     readOnlyProxyGUIDs = (),
                 )
-                returning.append(rec)
+                yield rec
             except Exception, e:
                 print e
                 import pdb; pdb.set_trace()
 
-        return returning
 
-
     def reloadCache(self, recordType, shortName=None, guid=None):
         if shortName:
             self.log_info("Faulting record %s into %s record cache" % (shortName, recordType))

Modified: CalendarServer/branches/users/sagen/principal-property-search-2995/twistedcaldav/directory/directory.py
===================================================================
--- CalendarServer/branches/users/sagen/principal-property-search-2995/twistedcaldav/directory/directory.py	2008-09-16 19:38:26 UTC (rev 3002)
+++ CalendarServer/branches/users/sagen/principal-property-search-2995/twistedcaldav/directory/directory.py	2008-09-16 22:45:29 UTC (rev 3003)
@@ -138,9 +138,50 @@
             for record in self.listRecords(recordType):
                 yield record
 
-    def recordsMatchingFields(self, fields, caseInsensitive=True, operand="or"):
-        return None
+    def recordsMatchingFields(self, fields, caseInsensitive=True, operand="or",
+        recordType=recordType_users):
+        # Default, bruteforce method; override with one optimized for each
+        # service
 
+        def fieldMatches(fieldValue, value):
+            if caseInsensitive:
+                return fieldValue.lower().startswith(value.lower())
+            else:
+                return fieldValue.startswith(value)
+
+        def recordMatches(record):
+            if operand == "and":
+                for fieldName, value in fields:
+                    try:
+                        fieldValue = getattr(record, fieldName)
+                        if not fieldMatches(fieldValue, value):
+                            return False
+                    except AttributeError:
+                        # No property => no match
+                        return False
+                # we hit on every property
+                return True
+            else: # "or"
+                for fieldName, value in fields:
+                    try:
+                        fieldValue = getattr(record, fieldName)
+                        if fieldMatches(fieldValue, value):
+                            return True
+                    except AttributeError:
+                        # No value
+                        pass
+                # we didn't hit any
+                return False
+
+        try:
+            for record in self.listRecords(recordType):
+                if recordMatches(record):
+                    yield record
+        except UnknownRecordTypeError:
+            # Skip this service since it doesn't understand this record type
+            pass
+
+
 class DirectoryRecord(LoggingMixIn):
     implements(IDirectoryRecord)
 

Modified: CalendarServer/branches/users/sagen/principal-property-search-2995/twistedcaldav/directory/principal.py
===================================================================
--- CalendarServer/branches/users/sagen/principal-property-search-2995/twistedcaldav/directory/principal.py	2008-09-16 19:38:26 UTC (rev 3002)
+++ CalendarServer/branches/users/sagen/principal-property-search-2995/twistedcaldav/directory/principal.py	2008-09-16 22:45:29 UTC (rev 3003)
@@ -212,6 +212,7 @@
 
         return None
 
+
     ##
     # Static
     ##
@@ -289,6 +290,21 @@
     def principalCollections(self):
         return self.parent.principalCollections()
 
+    ##
+    # DAV-property-to-record-field mapping
+    ##
+
+    _cs_ns = "http://calendarserver.org/ns/"
+    _fieldMap = {
+        "<{%s}%s>" % (_cs_ns, "first-name") : "firstName",
+        "<{%s}%s>" % (_cs_ns, "last-name") : "lastName",
+        "<{%s}%s>" % (_cs_ns, "email-address") : "emailAddress",
+    }
+
+    def propertyToField(self, property):
+        return self._fieldMap.get(repr(property), None)
+
+
 class DirectoryPrincipalUIDProvisioningResource (DirectoryProvisioningResource):
     """
     Collection resource which provisions directory principals indexed
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20080916/66d304c4/attachment-0001.html 


More information about the calendarserver-changes mailing list