[CalendarServer-changes] [3183] CalendarServer/trunk/twistedcaldav

source_changes at macosforge.org source_changes at macosforge.org
Fri Oct 17 13:33:49 PDT 2008


Revision: 3183
          http://trac.macosforge.org/projects/calendarserver/changeset/3183
Author:   cdaboo at apple.com
Date:     2008-10-17 13:33:49 -0700 (Fri, 17 Oct 2008)
Log Message:
-----------
Fix bug where calendar-query expands did not take calendar-timezone element into account for
all-day and floating events.

Modified Paths:
--------------
    CalendarServer/trunk/twistedcaldav/caldavxml.py
    CalendarServer/trunk/twistedcaldav/ical.py
    CalendarServer/trunk/twistedcaldav/method/report_calquery.py
    CalendarServer/trunk/twistedcaldav/method/report_common.py
    CalendarServer/trunk/twistedcaldav/method/report_multiget.py

Modified: CalendarServer/trunk/twistedcaldav/caldavxml.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/caldavxml.py	2008-10-17 18:53:02 UTC (rev 3182)
+++ CalendarServer/trunk/twistedcaldav/caldavxml.py	2008-10-17 20:33:49 UTC (rev 3183)
@@ -478,30 +478,32 @@
         
         return False
 
-    def elementFromResource(self, resource):
+    def elementFromResource(self, resource, timezone=None):
         """
         Return a new CalendarData element comprised of the possibly filtered
         calendar data from the specified resource. If no filter is being applied
         read the data directly from the resource without parsing it. If a filter
         is required, parse the iCal data and filter using this CalendarData.
         @param resource: the resource whose calendar data is to be returned.
+        @param timezone: the L{Component} the VTIMEZONE to use for floating/all-day.
         @return: an L{CalendarData} with the (filtered) calendar data.
         """
-        return self.elementFromCalendar(resource.iCalendar())
+        return self.elementFromCalendar(resource.iCalendar(), timezone)
 
-    def elementFromCalendar(self, calendar):
+    def elementFromCalendar(self, calendar, timezone=None):
         """
         Return a new CalendarData element comprised of the possibly filtered
         calendar.
         @param calendar: the calendar that is to be filtered and returned.
+        @param timezone: the L{Component} the VTIMEZONE to use for floating/all-day.
         @return: an L{CalendarData} with the (filtered) calendar data.
         """
         
         # Check for filtering or not
-        filtered = self.getFromICalendar(calendar)
+        filtered = self.getFromICalendar(calendar, timezone)
         return CalendarData.fromCalendar(filtered)
 
-    def elementFromResourceWithAccessRestrictions(self, resource, access):
+    def elementFromResourceWithAccessRestrictions(self, resource, access, timezone=None):
         """
         Return a new CalendarData element comprised of the possibly filtered
         calendar data from the specified resource. If no filter is being applied
@@ -512,11 +514,12 @@
 
         @param resource: the resource whose calendar data is to be returned.
         @param access: private event access restriction level.
+        @param timezone: the L{Component} the VTIMEZONE to use for floating/all-day.
         @return: an L{CalendarData} with the (filtered) calendar data.
         """
-        return self.elementFromCalendarWithAccessRestrictions(resource.iCalendar(), access)
+        return self.elementFromCalendarWithAccessRestrictions(resource.iCalendar(), access, timezone)
 
-    def elementFromCalendarWithAccessRestrictions(self, calendar, access):
+    def elementFromCalendarWithAccessRestrictions(self, calendar, access, timezone=None):
         """
         Return a new CalendarData element comprised of the possibly filtered
         calendar.
@@ -525,11 +528,12 @@
 
         @param calendar: the calendar that is to be filtered and returned.
         @param access: private event access restriction level.
+        @param timezone: the L{Component} the VTIMEZONE to use for floating/all-day.
         @return: an L{CalendarData} with the (filtered) calendar data.
         """
         
         # Do normal filtering first
-        filtered_calendar = self.getFromICalendar(calendar)
+        filtered_calendar = self.getFromICalendar(calendar, timezone)
         
         if access in (iComponent.ACCESS_CONFIDENTIAL, iComponent.ACCESS_RESTRICTED):
             # Create a CALDAV:calendar-data element with the appropriate iCalendar Component/Property
@@ -629,12 +633,14 @@
             )
 
             # Now "filter" the resource calendar data through the CALDAV:calendar-data element
-            return filter.elementFromCalendar(filtered_calendar)
+            return filter.elementFromCalendar(filtered_calendar, timezone)
         else:
             return CalendarData.fromCalendar(filtered_calendar)
 
-    def getFromICalendar(self, calendar):
+    def getFromICalendar(self, calendar, timezone=None):
         """
+        @param timezone: the L{Component} the VTIMEZONE to use for floating/all-day.
+
         Returns a calendar object containing the data in the given calendar
         which is specified by this CalendarData.
         """
@@ -659,7 +665,7 @@
             if isinstance(self.recurrence_set, LimitRecurrenceSet):
                 calendar = self.limitRecurrence(calendar)
             elif isinstance(self.recurrence_set, Expand):
-                calendar = self.expandRecurrence(calendar)
+                calendar = self.expandRecurrence(calendar, timezone)
         
         return calendar
 
@@ -686,13 +692,14 @@
 
         return str(data)
 
-    def expandRecurrence(self, calendar):
+    def expandRecurrence(self, calendar, timezone=None):
         """
         Expand the recurrence set into individual items.
         @param calendar: the L{Component} for the calendar to operate on.
+        @param timezone: the L{Component} the VTIMEZONE to use for floating/all-day.
         @return: the L{Component} for the result.
         """
-        return calendar.expand(self.recurrence_set.start, self.recurrence_set.end)
+        return calendar.expand(self.recurrence_set.start, self.recurrence_set.end, timezone)
     
     def limitRecurrence(self, calendar):
         """

Modified: CalendarServer/trunk/twistedcaldav/ical.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/ical.py	2008-10-17 18:53:02 UTC (rev 3182)
+++ CalendarServer/trunk/twistedcaldav/ical.py	2008-10-17 20:33:49 UTC (rev 3183)
@@ -721,16 +721,19 @@
         
         return results
     
-    def expand(self, start, end):
+    def expand(self, start, end, timezone=None):
         """
         Expand the components into a set of new components, one for each
         instance in the specified range. Date-times are converted to UTC. A
         new calendar object is returned.
         @param start: the L{datetime.datetime} for the start of the range.
         @param end: the L{datetime.datetime} for the end of the range.
+        @param timezone: the L{Component} the VTIMEZONE to use for floating/all-day.
         @return: the L{Component} for the new calendar with expanded instances.
         """
         
+        tzinfo = timezone.gettzinfo() if timezone else None
+
         # Create new calendar object with same properties as the original, but
         # none of the originals sub-components
         calendar = Component("VCALENDAR")
@@ -744,7 +747,7 @@
         first = True
         for key in instances:
             instance = instances[key]
-            if timeRangesOverlap(instance.start, instance.end, start, end):
+            if timeRangesOverlap(instance.start, instance.end, start, end, tzinfo):
                 calendar.addComponent(self.expandComponent(instance, first))
             first = False
         

Modified: CalendarServer/trunk/twistedcaldav/method/report_calquery.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/method/report_calquery.py	2008-10-17 18:53:02 UTC (rev 3182)
+++ CalendarServer/trunk/twistedcaldav/method/report_calquery.py	2008-10-17 20:33:49 UTC (rev 3183)
@@ -65,12 +65,14 @@
     assert query is not None
     
     # Get the original timezone provided in the query, if any, and validate it now
+    query_timezone = None
     query_tz = calendar_query.timezone
     if query_tz is not None and not query_tz.valid():
         log.err("CalDAV:timezone must contain one VTIMEZONE component only: %s" % (query_tz,))
         raise HTTPError(ErrorResponse(responsecode.FORBIDDEN, (caldav_namespace, "valid-calendar-data")))
     if query_tz:
         filter.settimezone(query_tz)
+        query_timezone = tuple(calendar_query.timezone.calendar().subcomponents())[0]
 
     if query.qname() == ("DAV:", "allprop"):
         propertiesForResource = report_common.allPropertiesForResource
@@ -108,7 +110,7 @@
         @param uri: the uri for the calendar collecton resource.
         """
         
-        def queryCalendarObjectResource(resource, uri, name, calendar, query_ok=False, isowner=True):
+        def queryCalendarObjectResource(resource, uri, name, calendar, timezone, query_ok=False, isowner=True):
             """
             Run a query on the specified calendar.
             @param resource: the L{CalDAVFile} for the calendar.
@@ -137,7 +139,7 @@
                 else:
                     href = davxml.HRef.fromString(uri)
             
-                return report_common.responseForHref(request, responses, href, resource, calendar, propertiesForResource, query, isowner)
+                return report_common.responseForHref(request, responses, href, resource, calendar, timezone, propertiesForResource, query, isowner)
             else:
                 return succeed(None)
     
@@ -146,9 +148,11 @@
             # Get the timezone property from the collection if one was not set in the query,
             # and store in the query filter for later use
             has_prop = (yield calresource.hasProperty((caldav_namespace, "calendar-timezone"), request))
+            timezone = query_timezone
             if query_tz is None and has_prop:
                 tz = (yield calresource.readProperty((caldav_namespace, "calendar-timezone"), request))
                 filter.settimezone(tz)
+                timezone = tuple(tz.calendar().subcomponents())[0]
 
             # Do some optimisation of access control calculation by determining any inherited ACLs outside of
             # the child resource loop and supply those to the checkPrivileges on each child.
@@ -189,10 +193,11 @@
                     else:
                         calendar = None
                     
-                    yield queryCalendarObjectResource(child, uri, child_uri_name, calendar, query_ok = index_query_ok, isowner=isowner)
+                    yield queryCalendarObjectResource(child, uri, child_uri_name, calendar, timezone, query_ok = index_query_ok, isowner=isowner)
         else:
             # Get the timezone property from the collection if one was not set in the query,
             # and store in the query object for later use
+            timezone = query_timezone
             if query_tz is None:
 
                 parent = (yield calresource.locateParent(request, uri))
@@ -202,12 +207,13 @@
                 if has_prop:
                     tz = (yield parent.readProperty((caldav_namespace, "calendar-timezone"), request))
                     filter.settimezone(tz)
+                    timezone = tuple(tz.calendar().subcomponents())[0]
 
             # Check private events access status
             isowner = (yield calresource.isOwner(request))
 
             calendar = calresource.iCalendar()
-            yield queryCalendarObjectResource(calresource, uri, None, calendar)
+            yield queryCalendarObjectResource(calresource, uri, None, calendar, timezone)
 
         returnValue(True)
 

Modified: CalendarServer/trunk/twistedcaldav/method/report_common.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/method/report_common.py	2008-10-17 18:53:02 UTC (rev 3182)
+++ CalendarServer/trunk/twistedcaldav/method/report_common.py	2008-10-17 20:33:49 UTC (rev 3183)
@@ -93,14 +93,14 @@
         if not result:
             break
 
-def responseForHref(request, responses, href, resource, calendar, propertiesForResource, propertyreq, isowner=True):
+def responseForHref(request, responses, href, resource, calendar, timezone, propertiesForResource, propertyreq, isowner=True):
     """
     Create an appropriate property status response for the given resource.
 
     @param request: the L{IRequest} for the current request.
     @param responses: the list of responses to append the result of this method to.
-    @param href: the L{HRef} element of the resource being targetted.
-    @param resource: the L{CalDAVFile} for the targetted resource.
+    @param href: the L{HRef} element of the resource being targeted.
+    @param resource: the L{CalDAVFile} for the targeted resource.
     @param calendar: the L{Component} for the calendar for the resource. This may be None
         if the calendar has not already been read in, in which case the resource
         will be used to get the calendar if needed.
@@ -124,11 +124,11 @@
                     )
                 )
 
-    d = propertiesForResource(request, propertyreq, resource, calendar, isowner)
+    d = propertiesForResource(request, propertyreq, resource, calendar, timezone, isowner)
     d.addCallback(_defer)
     return d
 
-def allPropertiesForResource(request, prop, resource, calendar=None, isowner=True): #@UnusedVariable
+def allPropertiesForResource(request, prop, resource, calendar=None, timezone=None, isowner=True):
     """
     Return all (non-hidden) properties for the specified resource.
     @param request: the L{IRequest} for the current request.
@@ -137,19 +137,20 @@
     @param calendar: the L{Component} for the calendar for the resource. This may be None
         if the calendar has not already been read in, in which case the resource
         will be used to get the calendar if needed.
+    @param timezone: the L{Component} the VTIMEZONE to use for floating/all-day.
     @param isowner: C{True} if the authorized principal making the request is the DAV:owner,
         C{False} otherwise.
     @return: a map of OK and NOT FOUND property values.
     """
 
     def _defer(props):
-        return _namedPropertiesForResource(request, props, resource, calendar, isowner)
+        return _namedPropertiesForResource(request, props, resource, calendar, timezone, isowner)
 
     d = resource.listAllprop(request)
     d.addCallback(_defer)
     return d
 
-def propertyNamesForResource(request, prop, resource, calendar=None, isowner=True): #@UnusedVariable
+def propertyNamesForResource(request, prop, resource, calendar=None, timezone=None, isowner=True): #@UnusedVariable
     """
     Return property names for all properties on the specified resource.
     @param request: the L{IRequest} for the current request.
@@ -158,6 +159,7 @@
     @param calendar: the L{Component} for the calendar for the resource. This may be None
         if the calendar has not already been read in, in which case the resource
         will be used to get the calendar if needed.
+    @param timezone: the L{Component} the VTIMEZONE to use for floating/all-day.
     @param isowner: C{True} if the authorized principal making the request is the DAV:owner,
         C{False} otherwise.
     @return: a map of OK and NOT FOUND property values.
@@ -173,7 +175,7 @@
     d.addCallback(_defer)
     return d
 
-def propertyListForResource(request, prop, resource, calendar=None, isowner=True):
+def propertyListForResource(request, prop, resource, calendar=None, timezone=None, isowner=True):
     """
     Return the specified properties on the specified resource.
     @param request: the L{IRequest} for the current request.
@@ -182,12 +184,13 @@
     @param calendar: the L{Component} for the calendar for the resource. This may be None
         if the calendar has not already been read in, in which case the resource
         will be used to get the calendar if needed.
+    @param timezone: the L{Component} the VTIMEZONE to use for floating/all-day.
     @param isowner: C{True} if the authorized principal making the request is the DAV:owner,
         C{False} otherwise.
     @return: a map of OK and NOT FOUND property values.
     """
     
-    return _namedPropertiesForResource(request, prop.children, resource, calendar, isowner)
+    return _namedPropertiesForResource(request, prop.children, resource, calendar, timezone, isowner)
 
 def validPropertyListCalendarDataTypeVersion(prop):
     """
@@ -213,7 +216,7 @@
     return result, message, generate_calendar_data
 
 @inlineCallbacks
-def _namedPropertiesForResource(request, props, resource, calendar=None, isowner=True):
+def _namedPropertiesForResource(request, props, resource, calendar=None, timezone=None, isowner=True):
     """
     Return the specified properties on the specified resource.
     @param request: the L{IRequest} for the current request.
@@ -222,6 +225,7 @@
     @param calendar: the L{Component} for the calendar for the resource. This may be None
         if the calendar has not already been read in, in which case the resource
         will be used to get the calendar if needed.
+    @param timezone: the L{Component} the VTIMEZONE to use for floating/all-day.
     @param isowner: C{True} if the authorized principal making the request is the DAV:owner,
         C{False} otherwise.
     @return: a map of OK and NOT FOUND property values.
@@ -243,9 +247,9 @@
                 access = None
 
             if calendar:
-                propvalue = property.elementFromCalendarWithAccessRestrictions(calendar, access)
+                propvalue = property.elementFromCalendarWithAccessRestrictions(calendar, access, timezone)
             else:
-                propvalue = property.elementFromResourceWithAccessRestrictions(resource, access)
+                propvalue = property.elementFromResourceWithAccessRestrictions(resource, access, timezone)
             if propvalue is None:
                 raise ValueError("Invalid CalDAV:calendar-data for request: %r" % (property,))
             properties_by_status[responsecode.OK].append(propvalue)

Modified: CalendarServer/trunk/twistedcaldav/method/report_multiget.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/method/report_multiget.py	2008-10-17 18:53:02 UTC (rev 3182)
+++ CalendarServer/trunk/twistedcaldav/method/report_multiget.py	2008-10-17 20:33:49 UTC (rev 3183)
@@ -167,7 +167,7 @@
 
             # Get properties for all valid readable resources
             for resource, href in ok_resources:
-                yield report_common.responseForHref(request, responses, davxml.HRef.fromString(href), resource, None, propertiesForResource, propertyreq, isowner=isowner)
+                yield report_common.responseForHref(request, responses, davxml.HRef.fromString(href), resource, None, None, propertiesForResource, propertyreq, isowner=isowner)
     
             # Indicate error for all valid non-readable resources
             for ignore_resource, href in bad_resources:
@@ -247,6 +247,6 @@
                     responses.append(davxml.StatusResponse(href, davxml.Status.fromResponseCode(responsecode.FORBIDDEN)))
                     continue
         
-                yield report_common.responseForHref(request, responses, href, child, None, propertiesForResource, propertyreq, isowner=isowner)
+                yield report_common.responseForHref(request, responses, href, child, None, None, propertiesForResource, propertyreq, isowner=isowner)
 
     returnValue(MultiStatusResponse(responses))
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20081017/3b1010d7/attachment-0001.html 


More information about the calendarserver-changes mailing list