[CalendarServer-changes] [1379] CalendarServer/trunk

source_changes at macosforge.org source_changes at macosforge.org
Wed Mar 14 09:52:28 PDT 2007


Revision: 1379
          http://trac.macosforge.org/projects/calendarserver/changeset/1379
Author:   cdaboo at apple.com
Date:     2007-03-14 09:52:27 -0700 (Wed, 14 Mar 2007)

Log Message:
-----------
Merge of branches/users/cdaboo/performance-1354.

Modified Paths:
--------------
    CalendarServer/trunk/lib-patches/Twisted/twisted.web2.dav.element.base.patch
    CalendarServer/trunk/lib-patches/Twisted/twisted.web2.dav.element.parser.patch
    CalendarServer/trunk/twistedcaldav/caldavxml.py
    CalendarServer/trunk/twistedcaldav/ical.py
    CalendarServer/trunk/twistedcaldav/method/report_common.py
    CalendarServer/trunk/twistedcaldav/query/calendarquery.py
    CalendarServer/trunk/twistedcaldav/query/expression.py
    CalendarServer/trunk/twistedcaldav/query/sqlgenerator.py

Added Paths:
-----------
    CalendarServer/trunk/lib-patches/Twisted/twisted.web2.dav.element.rfc2518.patch
    CalendarServer/trunk/lib-patches/Twisted/twisted.web2.dav.element.rfc3744.patch
    CalendarServer/trunk/lib-patches/Twisted/twisted.web2.dav.util.patch

Modified: CalendarServer/trunk/lib-patches/Twisted/twisted.web2.dav.element.base.patch
===================================================================
--- CalendarServer/trunk/lib-patches/Twisted/twisted.web2.dav.element.base.patch	2007-03-14 16:18:25 UTC (rev 1378)
+++ CalendarServer/trunk/lib-patches/Twisted/twisted.web2.dav.element.base.patch	2007-03-14 16:52:27 UTC (rev 1379)
@@ -2,8 +2,69 @@
 ===================================================================
 --- twisted/web2/dav/element/base.py	(revision 19773)
 +++ twisted/web2/dav/element/base.py	(working copy)
-@@ -145,21 +145,20 @@
+@@ -45,7 +45,7 @@
+ ]
  
+ import string
+-import StringIO
++import cStringIO as StringIO
+ import xml.dom.minidom
+ 
+ import datetime
+@@ -90,6 +90,35 @@
+             raise NotImplementedError("WebDAVElement subclass %s is not implemented."
+                                       % (self.__class__.__name__,))
+ 
++        my_children = []
++
++        allowPCDATA = self.allowed_children.has_key(PCDATAElement)
++
++        for child in children:
++            if child is None:
++                continue
++
++            if isinstance(child, (str, unicode)):
++                child = PCDATAElement(child)
++
++            if isinstance(child, PCDATAElement) and not allowPCDATA:
++                continue
++
++            my_children.append(child)
++
++        self.children = tuple(my_children)
++
++        self.attributes = attributes
++
++    def validate(self):
++
++        children = self.children
++        attributes = self.attributes
++
++        if self.allowed_children is None:
++            raise NotImplementedError("WebDAVElement subclass %s is not implemented."
++                                      % (self.__class__.__name__,))
++
+         #
+         # Validate that children are of acceptable types
+         #
+@@ -102,13 +131,10 @@
+         my_children = []
+ 
+         for child in children:
+-            if child is None:
+-                continue
+ 
+-            if isinstance(child, (str, unicode)):
+-                child = PCDATAElement(child)
+-
+             assert isinstance(child, (WebDAVElement, PCDATAElement)), "Not an element: %r" % (child,)
++            
++            child.validate()
+ 
+             for allowed, (min, max) in allowed_children.items():
+                 if type(allowed) == type and isinstance(child, allowed):
+@@ -145,21 +171,20 @@
+ 
          if self.allowed_attributes:
              for name in attributes:
 -                if name in self.allowed_attributes:
@@ -31,7 +92,7 @@
  
          self.attributes = my_attributes
  
-@@ -190,14 +189,93 @@
+@@ -190,14 +215,93 @@
          return child in self.children
  
      def writeXML(self, output):
@@ -129,7 +190,17 @@
  
      def element(self, document):
          element = document.createElementNS(self.namespace, self.name)
-@@ -324,6 +402,22 @@
+@@ -285,6 +389,9 @@
+ 
+         self.data = data
+ 
++    def validate(self):
++        pass
++
+     def __str__(self):
+         return str(self.data)
+ 
+@@ -324,6 +431,22 @@
              log.err("Invalid PCDATA: %r" % (self.data,))
              raise
  

Modified: CalendarServer/trunk/lib-patches/Twisted/twisted.web2.dav.element.parser.patch
===================================================================
--- CalendarServer/trunk/lib-patches/Twisted/twisted.web2.dav.element.parser.patch	2007-03-14 16:18:25 UTC (rev 1378)
+++ CalendarServer/trunk/lib-patches/Twisted/twisted.web2.dav.element.parser.patch	2007-03-14 16:52:27 UTC (rev 1379)
@@ -2,6 +2,15 @@
 ===================================================================
 --- twisted/web2/dav/element/parser.py	(revision 19773)
 +++ twisted/web2/dav/element/parser.py	(working copy)
+@@ -37,7 +37,7 @@
+     "WebDAVDocument",
+ ]
+ 
+-import StringIO
++import cStringIO as StringIO
+ import xml.dom.minidom
+ import xml.sax
+ 
 @@ -106,6 +106,26 @@
              "children"   : [],
          }]
@@ -59,3 +68,12 @@
  
          self.stack.append({
              "name"       : name,
+@@ -194,6 +219,8 @@
+             except xml.sax.SAXParseException, e:
+                 raise ValueError(e)
+ 
++            #handler.dom.root_element.validate()
++
+             return handler.dom
+ 
+         return parse

Copied: CalendarServer/trunk/lib-patches/Twisted/twisted.web2.dav.element.rfc2518.patch (from rev 1378, CalendarServer/branches/users/cdaboo/performance-1354/lib-patches/Twisted/twisted.web2.dav.element.rfc2518.patch)
===================================================================
--- CalendarServer/trunk/lib-patches/Twisted/twisted.web2.dav.element.rfc2518.patch	                        (rev 0)
+++ CalendarServer/trunk/lib-patches/Twisted/twisted.web2.dav.element.rfc2518.patch	2007-03-14 16:52:27 UTC (rev 1379)
@@ -0,0 +1,37 @@
+Index: twisted/web2/dav/element/rfc2518.py
+===================================================================
+--- twisted/web2/dav/element/rfc2518.py	(revision 19773)
++++ twisted/web2/dav/element/rfc2518.py	(working copy)
+@@ -59,8 +59,8 @@
+     """
+     name = "depth"
+ 
+-    def __init__(self, *children, **attributes):
+-        super(Depth, self).__init__(*children, **attributes)
++    def validate(self):
++        super(Depth, self).validate()
+ 
+         depth = str(self)
+         if depth not in ("0", "1", "infinity"):
+@@ -382,8 +382,8 @@
+         PCDATAElement: (0, 1),
+     }
+ 
+-    def __init__(self, *children, **attributes):
+-        super(KeepAlive, self).__init__(*children, **attributes)
++    def validate(self):
++        super(KeepAlive, self).validate()
+ 
+         type = None
+ 
+@@ -450,8 +450,8 @@
+         (dav_namespace, "prop"    ): (0, 1),
+     }
+ 
+-    def __init__(self, *children, **attributes):
+-        super(PropertyFind, self).__init__(*children, **attributes)
++    def validate(self):
++        super(PropertyFind, self).validate()
+ 
+         if len(self.children) != 1:
+             raise ValueError(

Copied: CalendarServer/trunk/lib-patches/Twisted/twisted.web2.dav.element.rfc3744.patch (from rev 1378, CalendarServer/branches/users/cdaboo/performance-1354/lib-patches/Twisted/twisted.web2.dav.element.rfc3744.patch)
===================================================================
--- CalendarServer/trunk/lib-patches/Twisted/twisted.web2.dav.element.rfc3744.patch	                        (rev 0)
+++ CalendarServer/trunk/lib-patches/Twisted/twisted.web2.dav.element.rfc3744.patch	2007-03-14 16:52:27 UTC (rev 1379)
@@ -0,0 +1,74 @@
+Index: twisted/web2/dav/element/rfc3744.py
+===================================================================
+--- twisted/web2/dav/element/rfc3744.py	(revision 19773)
++++ twisted/web2/dav/element/rfc3744.py	(working copy)
+@@ -131,8 +131,8 @@
+         (dav_namespace, "self"           ): (0, 1),
+     }
+ 
+-    def __init__(self, *children, **attributes):
+-        super(Principal, self).__init__(*children, **attributes)
++    def validate(self):
++        super(Principal, self).validate()
+ 
+         if len(self.children) > 1:
+             raise ValueError(
+@@ -385,9 +385,14 @@
+         self.inherited  = None
+         self.protected  = False
+ 
++        my_children = []
++
+         for child in self.children:
+             namespace, name = child.qname()
+ 
++            if isinstance(child, PCDATAElement):
++                continue
++
+             if (namespace == dav_namespace):
+                 if name in ("principal", "invert"):
+                     if self.principal is not None:
+@@ -417,6 +422,10 @@
+                 elif name == "protected":
+                     self.protected = True
+ 
++            my_children.append(child)
++
++        self.children = tuple(my_children)
++
+         if self.principal is None:
+             raise ValueError(
+                 "One of DAV:principal or DAV:invert is required in %s, got: %s"
+@@ -551,8 +560,8 @@
+         (dav_namespace, "property"       ): (0, None),
+     }
+ 
+-    def __init__(self, *children, **attributes):
+-        super(RequiredPrincipal, self).__init__(*children, **attributes)
++    def validate(self):
++        super(RequiredPrincipal, self).validate()
+ 
+         type = None
+ 
+@@ -628,8 +637,8 @@
+ 
+     allowed_children = { WebDAVElement: (0, None) }
+ 
+-    def __init__(self, *children, **attributes):
+-        super(ACLPrincipalPropSet, self).__init__(*children, **attributes)
++    def validate(self):
++        super(ACLPrincipalPropSet, self).validate()
+ 
+         prop = False
+         
+@@ -656,8 +665,8 @@
+         (dav_namespace, "prop"              ): (0, 1),
+     }
+ 
+-    def __init__(self, *children, **attributes):
+-        super(PrincipalMatch, self).__init__(*children, **attributes)
++    def validate(self):
++        super(PrincipalMatch, self).validate()
+ 
+         # This element can be empty when uses in supported-report-set
+         if not len(self.children):

Copied: CalendarServer/trunk/lib-patches/Twisted/twisted.web2.dav.util.patch (from rev 1378, CalendarServer/branches/users/cdaboo/performance-1354/lib-patches/Twisted/twisted.web2.dav.util.patch)
===================================================================
--- CalendarServer/trunk/lib-patches/Twisted/twisted.web2.dav.util.patch	                        (rev 0)
+++ CalendarServer/trunk/lib-patches/Twisted/twisted.web2.dav.util.patch	2007-03-14 16:52:27 UTC (rev 1379)
@@ -0,0 +1,15 @@
+Index: twisted/web2/dav/util.py
+===================================================================
+--- twisted/web2/dav/util.py	(revision 19773)
++++ twisted/web2/dav/util.py	(working copy)
+@@ -76,7 +76,9 @@
+ 
+     def parse(xml):
+         try:
+-            return davxml.WebDAVDocument.fromString(xml)
++            doc = davxml.WebDAVDocument.fromString(xml)
++            doc.root_element.validate()
++            return doc
+         except ValueError:
+             log.err("Bad XML:\n%s" % (xml,))
+             raise

Modified: CalendarServer/trunk/twistedcaldav/caldavxml.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/caldavxml.py	2007-03-14 16:18:25 UTC (rev 1378)
+++ CalendarServer/trunk/twistedcaldav/caldavxml.py	2007-03-14 16:52:27 UTC (rev 1379)
@@ -182,6 +182,8 @@
         self.qualifier   = qualifier
         self.filters     = filters
         self.filter_name = attributes["name"]
+        if isinstance(self.filter_name, unicode):
+            self.filter_name = self.filter_name.encode("utf-8")
         self.defined     = not self.qualifier or (self.qualifier.qname() != (caldav_namespace, "is-not-defined"))
 
     def match(self, item):
@@ -843,7 +845,10 @@
     def _match(self, component):
         # At least one subcomponent must match (or is-not-defined is set)
         for subcomponent in component.subcomponents():
-            if subcomponent.name() != self.filter_name: continue
+            if isinstance(self.filter_name, str):
+                if subcomponent.name() != self.filter_name: continue
+            else:
+                if subcomponent.name() not in self.filter_name: continue
             if self.match(subcomponent): break
         else:
             return not self.defined

Modified: CalendarServer/trunk/twistedcaldav/ical.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/ical.py	2007-03-14 16:18:25 UTC (rev 1378)
+++ CalendarServer/trunk/twistedcaldav/ical.py	2007-03-14 16:52:27 UTC (rev 1379)
@@ -32,7 +32,7 @@
 ]
 
 import datetime
-import StringIO
+import cStringIO as StringIO
 
 from vobject import newFromBehavior, readComponents
 from vobject.base import Component as vComponent

Modified: CalendarServer/trunk/twistedcaldav/method/report_common.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/method/report_common.py	2007-03-14 16:18:25 UTC (rev 1378)
+++ CalendarServer/trunk/twistedcaldav/method/report_common.py	2007-03-14 16:52:27 UTC (rev 1379)
@@ -294,16 +294,8 @@
                   caldavxml.ComponentFilter(
                       caldavxml.ComponentFilter(
                           timerange,
-                          name="VEVENT",
+                          name=("VEVENT", "VFREEBUSY", "VAVAILABILITY"),
                       ),
-                      caldavxml.ComponentFilter(
-                          timerange,
-                          name="VFREEBUSY",
-                      ),
-                      caldavxml.ComponentFilter(
-                          timerange,
-                          name="VAVAILABILITY",
-                      ),
                       name="VCALENDAR",
                    )
               )

Modified: CalendarServer/trunk/twistedcaldav/query/calendarquery.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/query/calendarquery.py	2007-03-14 16:18:25 UTC (rev 1378)
+++ CalendarServer/trunk/twistedcaldav/query/calendarquery.py	2007-03-14 16:52:27 UTC (rev 1379)
@@ -90,7 +90,10 @@
         return expression.isnotExpression(FIELD_TYPE, compfilter.filter_name, True)
         
     expressions = []
-    expressions.append(expression.isExpression(FIELD_TYPE, compfilter.filter_name, True))
+    if isinstance(compfilter.filter_name, str):
+        expressions.append(expression.isExpression(FIELD_TYPE, compfilter.filter_name, True))
+    else:
+        expressions.append(expression.inExpression(FIELD_TYPE, compfilter.filter_name, True))
     
     # Handle time-range    
     if compfilter.qualifier and isinstance(compfilter.qualifier, caldavxml.TimeRange):
@@ -226,7 +229,7 @@
                  caldavxml.ComponentFilter(
                      *[caldavxml.ComponentFilter(
                            *[caldavxml.TimeRange(**{"start":"20060605T160000Z", "end":"20060605T170000Z"})],
-                           **{"name":"VEVENT"}
+                           **{"name":("VEVENT", "VFREEBUSY", "VAVAILABILITY")}
                        )],
                      **{"name":"VCALENDAR"}
                  )

Modified: CalendarServer/trunk/twistedcaldav/query/expression.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/query/expression.py	2007-03-14 16:18:25 UTC (rev 1378)
+++ CalendarServer/trunk/twistedcaldav/query/expression.py	2007-03-14 16:52:27 UTC (rev 1379)
@@ -30,6 +30,9 @@
     "timerangeExpression",
     "containsExpression",
     "isExpression",
+    "isnotExpression",
+    "inExpression",
+    "notinExpression",
 ]
 
 class baseExpression(object):
@@ -213,12 +216,44 @@
     def operator(self):
         return "is not"
 
+class inExpression(textcompareExpression):
+    """
+    Text IN (exact string match to one of the supplied items) expression.
+    """
+    
+    def __init__(self, field, text_list, caseless):
+        super(inExpression, self).__init__(field, text_list, caseless)
+
+    def operator(self):
+        return "in"
+
+    def __str__(self):
+        return self.operator() + "(" + self.field + ", " + str(self.text) + ", " + str(self.caseless) + ")"
+
+class notinExpression(textcompareExpression):
+    """
+    Text NOT IN (exact string match to none of the supplied items) expression.
+    """
+    
+    def __init__(self, field, text, caseless):
+        super(notinExpression, self).__init__(field, text, caseless)
+
+    def operator(self):
+        return "not in"
+
+    def __str__(self):
+        return self.operator() + "(" + self.field + ", " + str(self.text) + ", " + str(self.caseless) + ")"
+
 if __name__ == "__main__":
     
     e1 = isExpression("type", "vevent", False)
-    e2 = timerangeExpression("20060101T120000Z", "20060101T130000Z")
+    e2 = timerangeExpression("20060101T120000Z", "20060101T130000Z", "20060101T120000Z", "20060101T130000Z")
     e3 = containsExpression("summary", "help", True)
     e4 = notExpression(e3)
     e5 = andExpression([e1, e2, e4])
     print e5
+    e6 = inExpression("type", ("vevent", "vtodo",), False)
+    print e6
+    e7 = notinExpression("type", ("vevent", "vtodo",), False)
+    print e7
 

Modified: CalendarServer/trunk/twistedcaldav/query/sqlgenerator.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/query/sqlgenerator.py	2007-03-14 16:18:25 UTC (rev 1378)
+++ CalendarServer/trunk/twistedcaldav/query/sqlgenerator.py	2007-03-14 16:52:27 UTC (rev 1379)
@@ -28,7 +28,7 @@
 
 from twistedcaldav.query import expression
 
-import StringIO
+import cStringIO as StringIO
 
 class sqlgenerator(object):
     
@@ -43,6 +43,8 @@
     NOTCONTAINSOP = " NOT GLOB "
     ISOP          = " == "
     ISNOTOP       = " != "
+    INOP          = " IN "
+    NOTINOP       = " NOT IN "
 
     TIMESPANTEST  = "((TIMESPAN.FLOAT == 'N' AND TIMESPAN.START < %s AND TIMESPAN.END > %s) OR (TIMESPAN.FLOAT == 'Y' AND TIMESPAN.START < %s AND TIMESPAN.END > %s)) AND TIMESPAN.NAME == RESOURCE.NAME"
 
@@ -149,6 +151,28 @@
             self.sout.write(expr.field)
             self.sout.write(self.ISNOTOP)
             self.addArgument(expr.text)
+        
+        # IN
+        elif isinstance(expr, expression.inExpression):
+            self.sout.write(expr.field)
+            self.sout.write(self.INOP)
+            self.sout.write("(")
+            for count, item in enumerate(expr.text):
+                if count != 0:
+                    self.sout.write(", ")
+                self.addArgument(item)
+            self.sout.write(")")
+        
+        # NOT IN
+        elif isinstance(expr, expression.notinExpression):
+            self.sout.write(expr.field)
+            self.sout.write(self.NOTINOP)
+            self.sout.write("(")
+            for count, item in enumerate(expr.text):
+                if count != 0:
+                    self.sout.write(", ")
+                self.addArgument(item)
+            self.sout.write(")")
 
     def generateSubExpression(self, expression):
         """
@@ -195,3 +219,11 @@
     print e5
     sql = sqlgenerator(e5)
     print sql.generate()
+    e6 = expression.inExpression("TYPE", ("VEVENT", "VTODO",), False)
+    print e6
+    sql = sqlgenerator(e6)
+    print sql.generate()
+    e7 = expression.notinExpression("TYPE", ("VEVENT", "VTODO",), False)
+    print e7
+    sql = sqlgenerator(e7)
+    print sql.generate()

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20070314/519a611d/attachment.html


More information about the calendarserver-changes mailing list