[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