[CalendarServer-changes] [1090] CalendarServer/trunk

source_changes at macosforge.org source_changes at macosforge.org
Tue Jan 23 13:19:47 PST 2007


Revision: 1090
          http://trac.macosforge.org/projects/calendarserver/changeset/1090
Author:   cdaboo at apple.com
Date:     2007-01-23 13:19:46 -0800 (Tue, 23 Jan 2007)

Log Message:
-----------
Merge of /branches/users/cdaboo/availability-1018.

Modified Paths:
--------------
    CalendarServer/trunk/run
    CalendarServer/trunk/twistedcaldav/caldavxml.py
    CalendarServer/trunk/twistedcaldav/directory/appleopendirectory.py
    CalendarServer/trunk/twistedcaldav/instance.py
    CalendarServer/trunk/twistedcaldav/method/report_common.py
    CalendarServer/trunk/twistedcaldav/resource.py
    CalendarServer/trunk/twistedcaldav/test/test_options.py

Added Paths:
-----------
    CalendarServer/trunk/doc/RFC/draft-daboo-calendar-availability.txt

Removed Paths:
-------------
    CalendarServer/trunk/lib-patches/vobject/README.patch
    CalendarServer/trunk/lib-patches/vobject/src.vobject.base.patch
    CalendarServer/trunk/lib-patches/vobject/tests.tests.patch

Copied: CalendarServer/trunk/doc/RFC/draft-daboo-calendar-availability.txt (from rev 1088, CalendarServer/branches/users/cdaboo/availability-1018/doc/RFC/draft-daboo-calendar-availability.txt)
===================================================================
--- CalendarServer/trunk/doc/RFC/draft-daboo-calendar-availability.txt	                        (rev 0)
+++ CalendarServer/trunk/doc/RFC/draft-daboo-calendar-availability.txt	2007-01-23 21:19:46 UTC (rev 1090)
@@ -0,0 +1,952 @@
+
+
+
+Network Working Group                                           C. Daboo
+Internet-Draft                                            Apple Computer
+Intended status: Standards Track                         B. Desruisseaux
+Expires: May 18, 2007                                             Oracle
+                                                       November 14, 2006
+
+
+                         Calendar Availability
+                  draft-daboo-calendar-availability-00
+
+Status of this Memo
+
+   By submitting this Internet-Draft, each author represents that any
+   applicable patent or other IPR claims of which he or she is aware
+   have been or will be disclosed, and any of which he or she becomes
+   aware will be disclosed, in accordance with Section 6 of BCP 79.
+
+   Internet-Drafts are working documents of the Internet Engineering
+   Task Force (IETF), its areas, and its working groups.  Note that
+   other groups may also distribute working documents as Internet-
+   Drafts.
+
+   Internet-Drafts are draft documents valid for a maximum of six months
+   and may be updated, replaced, or obsoleted by other documents at any
+   time.  It is inappropriate to use Internet-Drafts as reference
+   material or to cite them other than as "work in progress."
+
+   The list of current Internet-Drafts can be accessed at
+   http://www.ietf.org/ietf/1id-abstracts.txt.
+
+   The list of Internet-Draft Shadow Directories can be accessed at
+   http://www.ietf.org/shadow.html.
+
+   This Internet-Draft will expire on May 18, 2007.
+
+Copyright Notice
+
+   Copyright (C) The Internet Society (2006).
+
+Abstract
+
+   This document specifies a new iCalendar calendar component that
+   allows the publication of available and unavailable time periods
+   associated with a calendar user.  This component can be used in
+   standard iCalendar free-busy lookups, including iTIP free-busy
+   requests, to generate repeating blocks of available or busy time with
+   exceptions as needed.
+
+
+
+
+Daboo & Desruisseaux      Expires May 18, 2007                  [Page 1]
+
+Internet-Draft            Calendar Availability            November 2006
+
+
+   This document also defines extensions to CalDAV calendar-access and
+   calendar-schedule which specify how this new calendar component
+   should be used when doing free busy time evaluation in CalDAV.
+
+Editorial Note (To be removed by RFC Editor before publication)
+
+   Discussion of this specification is taking place on the mailing list
+   http://lists.osafoundation.org/mailman/listinfo/ietf-caldav.
+
+
+Table of Contents
+
+   1.  Introduction . . . . . . . . . . . . . . . . . . . . . . . . .  3
+   2.  Conventions Used in This Document  . . . . . . . . . . . . . .  3
+   3.  iCalendar Extensions . . . . . . . . . . . . . . . . . . . . .  4
+     3.1.  Availability Component . . . . . . . . . . . . . . . . . .  4
+     3.2.  Busy Time Type . . . . . . . . . . . . . . . . . . . . . .  8
+   4.  Calculating Free-Busy Time . . . . . . . . . . . . . . . . . .  9
+     4.1.  Examples . . . . . . . . . . . . . . . . . . . . . . . . . 10
+   5.  CalDAV Extensions  . . . . . . . . . . . . . . . . . . . . . . 11
+     5.1.  CalDAV Requirements Overview . . . . . . . . . . . . . . . 11
+     5.2.  New features in CalDAV . . . . . . . . . . . . . . . . . . 12
+   6.  Security Considerations  . . . . . . . . . . . . . . . . . . . 13
+   7.  IANA Considerations  . . . . . . . . . . . . . . . . . . . . . 13
+   8.  Acknowledgments  . . . . . . . . . . . . . . . . . . . . . . . 13
+   9.  Normative References . . . . . . . . . . . . . . . . . . . . . 13
+   Appendix A.  Example Calendar #1 . . . . . . . . . . . . . . . . . 14
+   Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . . 16
+   Intellectual Property and Copyright Statements . . . . . . . . . . 17
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Daboo & Desruisseaux      Expires May 18, 2007                  [Page 2]
+
+Internet-Draft            Calendar Availability            November 2006
+
+
+1.  Introduction
+
+   Often calendar users have regular periods of time when they are
+   either available to be scheduled or always unavailable.  For example,
+   an office worker will often wish to only appear free to her work
+   colleagues during normal 'office hours' (e.g., Monday through Friday,
+   9 am through 5 pm).  Or, a university professor may only be available
+   to students during a set period of time (e.g., Thursday afternoons, 2
+   pm through 5 pm during term time only).  Ideally users should be able
+   to specify such periods directly via their calendar user agent, and
+   have them automatically considered as part of the normal free-busy
+   lookup for that user.  In addition it should be possible for
+   different periods of available time to appear for different users.
+
+   However, iCalendar [RFC2445] does not provide a way to specify a
+   repeating period of available or unavailable time as "VFREEBUSY"
+   components cannot include any form of recurrence information, as
+   opposed to "VEVENT" components which can.  Since repeating patterns
+   are often the case, "VFREEBUSY" components are not sufficient to
+   solve this problem.
+
+   This specification defines a new type of iCalendar calendar component
+   that can be used to publish user availability.
+
+   CalDAV provides a way for calendar users to access and manage
+   calendar data and exchange this data via scheduling operations.  As
+   part of this the CalDAV calendar-access [I-D.dusseault-caldav]
+   feature provides a CALDAV:free-busy-query REPORT that returns free-
+   busy information for a calendar collection or hierarchy of calendar
+   collections.  Also, the CalDAV calendar-schedule
+   [I-D.desruisseaux-caldav-sched] feature allows free-busy information
+   for a calendar user to be determined.  Both of these operations
+   involve examining user calendars for events that 'block time', with
+   the blocked out periods being returned in a "VFREEBUSY" component.
+
+   This specification extends the CalDAV calendar-access and CalDAV
+   calendar-schedule features to allow the new iCalendar availability
+   components to be stored and manipulated, and to allow free-busy
+   lookups to use the information from any such components, if present.
+
+
+2.  Conventions Used in This Document
+
+   The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
+   "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and
+   "OPTIONAL" in this document are to be interpreted as described in
+   [RFC2119].
+
+
+
+
+Daboo & Desruisseaux      Expires May 18, 2007                  [Page 3]
+
+Internet-Draft            Calendar Availability            November 2006
+
+
+   When XML element types in the namespaces "DAV:" and
+   "urn:ietf:params:xml:ns:caldav" are referenced in this document
+   outside of the context of an XML fragment, the string "DAV:" and
+   "CALDAV:" will be prefixed to the element type names respectively.
+
+
+3.  iCalendar Extensions
+
+   This specification adds a new "VAVAILABILITY" calendar component to
+   iCalendar.  The "VAVAILABILITY" component is itself a container for
+   new "AVAILABLE" sub-components.
+
+   The purpose of the "VAVAILABILITY" calendar component is to provide a
+   grouping of available time information over a specific range of time.
+   Within that there are specific time ranges that are marked as
+   available via a set of "AVAILABLE" calendar sub-components.  Together
+   these can be used to specify available time that can repeat over set
+   periods of time, and which can vary over time.
+
+3.1.  Availability Component
+
+   Component Name:  VAVAILABILITY
+
+   Purpose:  Provide a grouping of component properties that describe
+      the availability associated with a calendar user.
+
+   Format Definition:  A "VAVAILABILITY" calendar component is defined
+      by the following notation:
+
+          availabilityc  = "BEGIN" ":" "VAVAILABILITY" CRLF
+                           availabilityprop *availablec
+                           "END" ":" "VAVAILABILITY" CRLF
+
+          availabilityprop  = *(
+
+                            ; the following are REQUIRED,
+                            ; but MUST NOT occur more than once
+
+                            dtstamp / uid
+
+                            ; the following are OPTIONAL,
+                            ; but MUST NOT occur more than once
+
+                            busytype / created / dtstart / last-mod /
+                            organizer / seq / summary / url /
+
+                            ; either 'dtend' or 'duration' may appear
+                            ; in a 'availabilityprop', but 'dtend' and
+
+
+
+Daboo & Desruisseaux      Expires May 18, 2007                  [Page 4]
+
+Internet-Draft            Calendar Availability            November 2006
+
+
+                            ; 'duration' MUST NOT occur in the same
+                            ; 'availabilityprop'
+
+                            dtend / duration /
+
+                            ; the following are OPTIONAL,
+                            ; and MAY occur more than once
+
+                            categories / comment / contact / x-prop
+
+                            )
+
+          availablec  = "BEGIN" ":" "AVAILABLE" CRLF
+                        availableprop
+                        "END" ":" "AVAILABLE" CRLF
+
+          availableprop  = *(
+
+                         ; the following are REQUIRED,
+                         ; but MUST NOT occur more than once
+
+                         dtstamp / dtstart / uid /
+
+                         ; either a 'dtend' or a 'duration' is required
+                         ; in a 'availableprop', but 'dtend' and
+                         ; 'duration' MUST NOT occur in the same
+                         ; 'availableprop', and each MUST NOT occur more
+                         ; than once
+
+                         dtend / duration /
+
+                         ; the following are OPTIONAL,
+                         ; but MUST NOT occur more than once
+
+                         created / last-mod / recurid / rrule /
+                         summary /
+
+                         ; the following are OPTIONAL,
+                         ; and MAY occur more than once
+
+                         categories / comment / contact / exdate /
+                         rdate / x-prop
+
+                         )
+
+
+
+
+
+
+
+Daboo & Desruisseaux      Expires May 18, 2007                  [Page 5]
+
+Internet-Draft            Calendar Availability            November 2006
+
+
+   Description:  A "VAVAILABILITY" component indicates a period of time
+      within which availability information is provided.  A
+      "VAVAILABILITY" component MUST specify a start time and optionally
+      an end time or duration.  Within that time period, availability
+      defaults to a free-busy type of "BUSY", except for any time
+      periods corresponding to "AVAILABLE" sub-components.
+
+      "AVAILABLE" sub-components are used to indicate periods of free
+      time within the time range of the enclosing "VAVAILABILITY"
+      component.  "AVAILABLE" sub-components MAY include recurrence
+      properties to specify recurring periods of time, which may be
+      overridden using normal recurrence behavior (i.e., use of the
+      "RECURRENCE-ID" property).
+
+      If specified, the "DTSTART" and "DTEND" properties in
+      "VAVAILABILITY" components and "AVAILABLE" sub-components MUST be
+      "DATE-TIME" values specified as either date with UTC time or date
+      with local time and a time zone reference.
+
+      If any property with a "DATE-TIME" value is present in a
+      "VAVAILABILITY" component or any of its "AVAILABLE" sub-
+      components, and that property includes a "TZID" parameter, then
+      the iCalendar object containing the "VAVAILABILITY" component MUST
+      contain "VTIMEZONE" components corresponding to each "TZID"
+      parameter value.
+
+      When used to publish available time, the "ORGANIZER" property
+      specifies the calendar user associated with the published
+      available time.
+
+   Example:  The following is an example of a "VAVAILABILITY" calendar
+      component used to represent the availability of a user available
+      Monday through Friday, 9:00 AM to 5:00 PM in the America/Montreal
+      time zone:
+
+        BEGIN:VAVAILABILITY
+        ORGANIZER:mailto:bernard at example.com
+        UID:20061005T133225Z-00001 at example.com
+        DTSTAMP:20061005T133225Z
+        DTSTART;TZID=America/Montreal:20061002T000000
+        BEGIN:AVAILABLE
+        UID:20061005T133225Z-00001-A at example.com
+        SUMMARY:Monday to Friday from 9:00 to 17:00
+        DTSTART;TZID=America/Montreal:20061002T090000
+        DTEND;TZID=America/Montreal:20061002T170000
+        RRULE:FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR
+        END:AVAILABLE
+        END:VAVAILABILITY
+
+
+
+Daboo & Desruisseaux      Expires May 18, 2007                  [Page 6]
+
+Internet-Draft            Calendar Availability            November 2006
+
+
+      The following is an example of a "VAVAILABILITY" calendar
+      component used to represent the availability of a user available
+      Monday through Thursday, 9:00 AM to 5:00 PM, and Friday 9:00 AM to
+      12:00 PM in the America/Montreal time zone:
+
+        BEGIN:VAVAILABILITY
+        ORGANIZER:mailto:bernard at example.com
+        UID:20061005T133225Z-00001 at example.com
+        DTSTAMP:20061005T133225Z
+        DTSTART;TZID=America/Montreal:20061002T000000
+        DTEND;TZID=America/Montreal:20061202T000000
+        BEGIN:AVAILABLE
+        UID:20061005T133225Z-00001-A at example.com
+        SUMMARY:Monday to Thursday from 9:00 to 17:00
+        DTSTART;TZID=America/Montreal:20061002T090000
+        DTEND;TZID=America/Montreal:20061002T170000
+        RRULE:FREQ=WEEKLY;BYDAY=MO,TU,WE,TH
+        END:AVAILABLE
+        BEGIN:AVAILABLE
+        UID:20061005T133225Z-00001-B at example.com
+        SUMMARY:Friday from 9:00 to 12:00
+        DTSTART;TZID=America/Montreal:20061006T090000
+        DTEND;TZID=America/Montreal:20061006T120000
+        RRULE:FREQ=WEEKLY;BYDAY=FR
+        END:AVAILABLE
+        END:VAVAILABILITY
+
+      The following is an example of three "VAVAILABILITY" calendar
+      components used to represent the availability of an itinerant
+      worker: Monday through Friday, 9:00 AM to 5:00 PM each day.
+      However, for three weeks the calendar user is working in Montreal,
+      then one week in Los Angeles, then back to Montreal.  Note that
+      each overall period is covered by separate "VAVAILABILITY"
+      components.  The last of these has no DTEND so continues on "for
+      ever".  This example shows how "exceptions" to available time can
+      be handled.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Daboo & Desruisseaux      Expires May 18, 2007                  [Page 7]
+
+Internet-Draft            Calendar Availability            November 2006
+
+
+        BEGIN:VAVAILABILITY
+        ORGANIZER:mailto:bernard at example.com
+        UID:20061005T133225Z-00001 at example.com
+        DTSTAMP:20061005T133225Z
+        DTSTART;TZID=America/Montreal:20061002T000000
+        DTEND;TZID=America/Montreal:20061023T030000
+        BEGIN:AVAILABLE
+        UID:20061005T133225Z-00001-A at example.com
+        SUMMARY:Monday to Friday from 9:00 to 17:00
+        DTSTART;TZID=America/Montreal:20061002T090000
+        DTEND;TZID=America/Montreal:20061002T170000
+        RRULE:FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR
+        END:AVAILABLE
+        END:VAVAILABILITY
+        BEGIN:VAVAILABILITY
+        ORGANIZER:mailto:bernard at example.com
+        UID:20061005T133225Z-00001 at example.com
+        DTSTAMP:20061005T133225Z
+        DTSTART;TZID=America/Los_Angeles:20061023T000000
+        DTEND;TZID=America/Los_Angeles:20061030T000000
+        BEGIN:AVAILABLE
+        UID:20061005T133225Z-00001-A at example.com
+        SUMMARY:Monday to Friday from 9:00 to 17:00
+        DTSTART;TZID=America/Los_Angeles:20061023T090000
+        DTEND;TZID=America/Los_Angeles:20061023T170000
+        RRULE:FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR
+        END:AVAILABLE
+        END:VAVAILABILITY
+        BEGIN:VAVAILABILITY
+        ORGANIZER:mailto:bernard at example.com
+        UID:20061005T133225Z-00001 at example.com
+        DTSTAMP:20061005T133225Z
+        DTSTART;TZID=America/Montreal:20061030T030000
+        BEGIN:AVAILABLE
+        UID:20061005T133225Z-00001-A at example.com
+        SUMMARY:Monday to Friday from 9:00 to 17:00
+        DTSTART;TZID=America/Montreal:20061030T090000
+        DTEND;TZID=America/Montreal:20061030T170000
+        RRULE:FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR
+        END:AVAILABLE
+        END:VAVAILABILITY
+
+3.2.  Busy Time Type
+
+
+
+
+
+
+
+
+Daboo & Desruisseaux      Expires May 18, 2007                  [Page 8]
+
+Internet-Draft            Calendar Availability            November 2006
+
+
+   Property Name:  BUSYTYPE
+
+   Purpose:  This property specifies the default busy time type.
+
+   Value Type:  TEXT
+
+   Property Parameters:  Non-standard property parameters can be
+      specified on this property.
+
+   Conformance:  This property can be specified within "VAVAILABILITY"
+      calendar components.
+
+   Format Definition:  This property is defined by the following
+      notation:
+
+        busytype      = "BUSYTYPE" busytypeparam ":" busytypevalue CRLF
+
+        busytypeparam = *(";" xparam)
+
+        busytypevalue = "BUSY" / "BUSY-UNAVAILABLE" /
+                        "BUSY-TENTATIVE" / iana-token / x-name
+                        ; Default is "BUSY-UNAVAILABLE"
+
+   Description:  This property is used to specify the default busy time
+      type.  The values correspond to those used by the "FBTYPE"
+      parameter used on a "FREEBUSY" property, with the exception that
+      the "FREE" value is not used.  If not specified on a component
+      that allows this property, the default is "BUSY-UNAVAILABLE".
+
+   Example:  The following is an example of this property:
+
+        BUSYTYPE:BUSY
+
+
+4.  Calculating Free-Busy Time
+
+   This section describes how free-busy time information for a calendar
+   user is calculated in the presence of "VAVAILABILITY" calendar
+   components.
+
+   An iCalendar "VFREEBUSY" component is used to convey "rolled-up"
+   free-busy time information for a calendar user.  This can be
+   generated as the result of an iTIP "VFREEBUSY" [RFC2446] request or
+   through some other mechanism (e.g., a CalDAV calendar-access CALDAV:
+   free-busy-query REPORT).
+
+   When a "VAVAILABILITY" component is present and intersects the time-
+   range for the free-busy request, the time covered by the
+
+
+
+Daboo & Desruisseaux      Expires May 18, 2007                  [Page 9]
+
+Internet-Draft            Calendar Availability            November 2006
+
+
+   "VAVAILABILITY" component is set to busy and then portions of it
+   "carved out" to be free based on the "AVAILABLE" components in the
+   "VAVAILABILITY" component.  Once that is done, regular "VEVENT" and
+   "VFREEBUSY" components can be "overlaid" in the usual way to block
+   out additional time.
+
+   An example procedure for this is as follows:
+
+   1.  Initially mark the entire period of the free-busy request as
+       free.
+
+   2.  For each "VAVAILABILITY" component:
+
+       1.  Determine if the "VAVAILABILITY" intersects the time-range of
+           the free-busy request.  If not ignore it.
+
+       2.  For the time period covered by the "VAVAILABILITY" component,
+           mark time in the free-busy request result set as busy, using
+           the busy time type derived from the "BUSYTYPE" property in
+           the "VAVAILABILITY" component.
+
+   3.  For each remaining "VAVAILABILITY" component:
+
+       1.  For each "AVAILABLE" component in the "VAVAILABILITY"
+           component:
+
+           1.  Expand all recurring instances, taking into account
+               overridden instances, ignoring those not within the free-
+               busy request time-range.
+
+           2.  For each instance, mark the corresponding time in the
+               free-busy request result set as free.
+
+   4.  For each "VEVENT" or "VFREEBUSY" component apply normal free-busy
+       processing within the free-busy request time-range.
+
+4.1.  Examples
+
+   In the examples below a table is used to represent time slots for the
+   period of a free-busy request.  Each time slot is two hours long.
+   The column header represents the hours from midnight local time.
+   Each row below the column headers represents a step in the free-busy
+   result set determination, following the procedure outlined above.
+
+   Each cell in the rows below the column header contains a single
+   character that represents the free-busy type for the corresponding
+   time period at the end of the process step represented by the row.
+   The characters in the row are:
+
+
+
+Daboo & Desruisseaux      Expires May 18, 2007                 [Page 10]
+
+Internet-Draft            Calendar Availability            November 2006
+
+
+     +-----------+--------------------------------------------------+
+     | Character | Meaning                                          |
+     +-----------+--------------------------------------------------+
+     | F         | Represents "FREE" time in that slot.             |
+     | B         | Represents "BUSY" time in that slot.             |
+     | U         | Represents "BUSY-UNAVAILABLE" time in that slot. |
+     | T         | Represents "BUSY-TENTATIVE" time in that slot.   |
+     +-----------+--------------------------------------------------+
+
+4.1.1.  Simple Example
+
+   A free-busy request for Monday, 6th November 2006, midnight to
+   midnight in the America/Montreal timezone.
+
+   The user's calendar is as shown in Appendix A.  This includes one
+   "VAVAILABILITY" component giving available time within the requested
+   time-range of 8:00 AM to 6:00 PM, together with one "VEVENT"
+   component representing a two hour meeting starting at 12:00 PM.
+
+   +------+----+----+----+----+----+----+----+----+----+----+----+----+
+   | Step |  0 |  2 |  4 |  6 |  8 | 10 | 12 | 14 | 16 | 18 | 20 | 22 |
+   +------+----+----+----+----+----+----+----+----+----+----+----+----+
+   | 1.   | F  | F  | F  | F  | F  | F  | F  | F  | F  | F  | F  | F  |
+   | 2.   | U  | U  | U  | U  | U  | U  | U  | U  | U  | U  | U  | U  |
+   | 3.   | U  | U  | U  | U  | F  | F  | F  | F  | F  | U  | U  | U  |
+   | 4.   | U  | U  | U  | U  | F  | F  | B  | F  | F  | U  | U  | U  |
+   +------+----+----+----+----+----+----+----+----+----+----+----+----+
+
+4.1.2.  TBD
+
+   More examples here../not sure what though.
+
+
+5.  CalDAV Extensions
+
+5.1.  CalDAV Requirements Overview
+
+   This section lists what functionality is required of a CalDAV server
+   which supports this extension.  A server:
+
+   o  MUST support CalDAV calendar-access;
+
+   o  MAY support CalDAV calendar-schedule;
+
+   o  MUST support "VAVAILABILITY" components in a calendar collection
+      resource;
+
+
+
+
+
+Daboo & Desruisseaux      Expires May 18, 2007                 [Page 11]
+
+Internet-Draft            Calendar Availability            November 2006
+
+
+   o  MUST support CALDAV:free-busy-query REPORTs that aggregate the
+      information in any "VAVAILABILITY" components;
+
+   o  MUST support CalDAV calendar-schedule iTIP [RFC2446] free busy
+      requests that aggregate the information in any "VAVAILABILITY"
+      components, if the CalDAV calendar-schedule feature is available.
+
+5.2.  New features in CalDAV
+
+5.2.1.  Calendar Availability Support
+
+   A server supporting the features described in this document MUST
+   include "calendar-availability" as a field in the DAV response header
+   from an OPTIONS request on any resource that supports any calendar
+   properties, reports, method, or privilege.  A value of "calendar-
+   availability" in the DAV response header MUST indicate that the
+   server supports all MUST level requirements specified in this
+   document.
+
+5.2.1.1.  Example: Using OPTIONS for the Discovery of Calendar
+          Availability Support
+
+   >> Request <<
+
+      OPTIONS /home/bernard/calendars/ HTTP/1.1
+      Host: cal.example.com
+
+   >> Response <<
+
+      HTTP/1.1 200 OK
+      Allow: OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, COPY, MOVE
+      Allow: PROPFIND, PROPPATCH, LOCK, UNLOCK, REPORT, ACL
+      DAV: 1, 2, 3, access-control, calendar-access,
+       calendar-availability
+      Date: Fri, 11 Nov 2005 09:32:12 GMT
+      Content-Length: 0
+
+   In this example, the OPTIONS method returns the value "calendar-
+   availability" in the DAV response header to indicate that the
+   collection "/home/bernard/calendars/" supports the new features
+   defined in this specification.
+
+5.2.2.  CALDAV:free-busy-query REPORT
+
+   A CALDAV:free-busy-query REPORT can be executed on a calendar
+   collection that contains iCalendar "VAVAILABILITY" components.  When
+   that is done, the server MUST aggregate the information in any
+   "VAVAILABILITY" components when generating the free-busy response, as
+
+
+
+Daboo & Desruisseaux      Expires May 18, 2007                 [Page 12]
+
+Internet-Draft            Calendar Availability            November 2006
+
+
+   described in Section 4.
+
+5.2.3.  iTIP VFREEBUSY requests
+
+   The [I-D.desruisseaux-caldav-sched] processing of a "VFREEBUSY"
+   request targeted at the owner of the CALDAV:schedule-inbox will
+   include free-busy information derived from "VAVAILABILITY" components
+   in any calendar collection targeted during the request, as described
+   in Section 4.
+
+
+6.  Security Considerations
+
+   Free-busy information generated from "VAVAILABILITY" components MUST
+   NOT include information other than busy or free time periods.  In
+   particular, user specified property values such as "SUMMARY" and
+   "DESCRIPTION" MUST NOT be copied into the free-busy result data.
+
+   Beyond this, this specification does not add any additional security
+   issues that are not already present in [RFC2445] and [RFC2446].
+
+
+7.  IANA Considerations
+
+   TBD - register new components using 2445bis templates.
+
+
+8.  Acknowledgments
+
+   This specification came about via discussions at the Calendaring and
+   Scheduling Consortium.
+
+
+9.  Normative References
+
+   [I-D.desruisseaux-caldav-sched]
+              Daboo, C., Desruisseaux, B., and L. Dusseault, "Scheduling
+              Extensions to CalDAV", draft-desruisseaux-caldav-sched-02
+              (work in progress), June 2006.
+
+   [I-D.dusseault-caldav]
+              Daboo, C., Desruisseaux, B., and L. Dusseault,
+              "Calendaring Extensions to WebDAV (CalDAV)",
+              draft-dusseault-caldav-15 (work in progress),
+              September 2006.
+
+   [RFC2119]  Bradner, S., "Key words for use in RFCs to Indicate
+              Requirement Levels", BCP 14, RFC 2119, March 1997.
+
+
+
+Daboo & Desruisseaux      Expires May 18, 2007                 [Page 13]
+
+Internet-Draft            Calendar Availability            November 2006
+
+
+   [RFC2445]  Dawson, F. and D. Stenerson, "Internet Calendaring and
+              Scheduling Core Object Specification (iCalendar)",
+              RFC 2445, November 1998.
+
+   [RFC2446]  Silverberg, S., Mansour, S., Dawson, F., and R. Hopson,
+              "iCalendar Transport-Independent Interoperability Protocol
+              (iTIP) Scheduling Events, BusyTime, To-dos and Journal
+              Entries", RFC 2446, November 1998.
+
+
+Appendix A.  Example Calendar #1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Daboo & Desruisseaux      Expires May 18, 2007                 [Page 14]
+
+Internet-Draft            Calendar Availability            November 2006
+
+
+   iCalendar object
+
+       BEGIN:VCALENDAR
+       CALSCALE:GREGORIAN
+       PRODID:-//example.com//iCalendar 2.0//EN
+       VERSION:2.0
+       BEGIN:VTIMEZONE
+       LAST-MODIFIED:20040110T032845Z
+       TZID:America/Montreal
+       BEGIN:DAYLIGHT
+       DTSTART:20000404T020000
+       RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
+       TZNAME:EDT
+       TZOFFSETFROM:-0500
+       TZOFFSETTO:-0400
+       END:DAYLIGHT
+       BEGIN:STANDARD
+       DTSTART:20001026T020000
+       RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+       TZNAME:EST
+       TZOFFSETFROM:-0400
+       TZOFFSETTO:-0500
+       END:STANDARD
+       END:VTIMEZONE
+       BEGIN:VEVENT
+       DTSTAMP:20061113T044111Z
+       DTSTART;TZID=America/Montreal:20061106T120000
+       DURATION:PT1H
+       SUMMARY:Meeting
+       UID:60A48841ECB90F3F215FE3D2 at example.com
+       END:VEVENT
+       BEGIN:VAVAILABILITY
+       UID:20061005T133225Z-00001 at example.com
+       DTSTAMP:20061005T133225Z
+       DTSTART;TZID=America/Montreal:20061002T000000
+       BEGIN:AVAILABLE
+       UID:20061005T133225Z-00001-A at example.com
+       SUMMARY:Monday to Friday from 9:00 to 18:00
+       DTSTART;TZID=America/Montreal:20061002T090000
+       DTEND;TZID=America/Montreal:20061002T180000
+       RRULE:FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR
+       END:AVAILABLE
+       END:VAVAILABILITY
+       END:VCALENDAR
+
+
+
+
+
+
+
+Daboo & Desruisseaux      Expires May 18, 2007                 [Page 15]
+
+Internet-Draft            Calendar Availability            November 2006
+
+
+Authors' Addresses
+
+   Cyrus Daboo
+   Apple Computer, Inc.
+   1 Infinite Loop
+   Cupertino, CA  95014
+   USA
+
+   Email: cyrus at daboo.name
+   URI:   http://www.apple.com/
+
+
+   Bernard Desruisseaux
+   Oracle Corporation
+   600 blvd. de Maisonneuve West
+   Suite 1900
+   Montreal, QC  H3A 3J2
+   CA
+
+   Email: bernard.desruisseaux at oracle.com
+   URI:   http://www.oracle.com/
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Daboo & Desruisseaux      Expires May 18, 2007                 [Page 16]
+
+Internet-Draft            Calendar Availability            November 2006
+
+
+Full Copyright Statement
+
+   Copyright (C) The Internet Society (2006).
+
+   This document is subject to the rights, licenses and restrictions
+   contained in BCP 78, and except as set forth therein, the authors
+   retain all their rights.
+
+   This document and the information contained herein are provided on an
+   "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS
+   OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET
+   ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED,
+   INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE
+   INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
+   WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+
+Intellectual Property
+
+   The IETF takes no position regarding the validity or scope of any
+   Intellectual Property Rights or other rights that might be claimed to
+   pertain to the implementation or use of the technology described in
+   this document or the extent to which any license under such rights
+   might or might not be available; nor does it represent that it has
+   made any independent effort to identify any such rights.  Information
+   on the procedures with respect to rights in RFC documents can be
+   found in BCP 78 and BCP 79.
+
+   Copies of IPR disclosures made to the IETF Secretariat and any
+   assurances of licenses to be made available, or the result of an
+   attempt made to obtain a general license or permission for the use of
+   such proprietary rights by implementers or users of this
+   specification can be obtained from the IETF on-line IPR repository at
+   http://www.ietf.org/ipr.
+
+   The IETF invites any interested party to bring to its attention any
+   copyrights, patents or patent applications, or other proprietary
+   rights that may cover technology that may be required to implement
+   this standard.  Please address the information to the IETF at
+   ietf-ipr at ietf.org.
+
+
+Acknowledgment
+
+   Funding for the RFC Editor function is provided by the IETF
+   Administrative Support Activity (IASA).
+
+
+
+
+
+Daboo & Desruisseaux      Expires May 18, 2007                 [Page 17]
+

Deleted: CalendarServer/trunk/lib-patches/vobject/README.patch
===================================================================
--- CalendarServer/trunk/lib-patches/vobject/README.patch	2007-01-23 21:12:18 UTC (rev 1089)
+++ CalendarServer/trunk/lib-patches/vobject/README.patch	2007-01-23 21:19:46 UTC (rev 1090)
@@ -1,13 +0,0 @@
-Index: README.txt
-===================================================================
---- README.txt	(revision 164)
-+++ README.txt	(working copy)
-@@ -193,7 +193,7 @@
- serializing will add any required computable attributes (like 'VERSION')
- 
- >>> j.serialize()
--u'BEGIN:VCARD\r\nVERSION:3.0\r\nEMAIL;TYPE=INTERNET:jeffrey at osafoundation.org\r\nFN:Jeffrey Harris\r\nN:Harris;Jeffrey;;;\r\nEND:VCARD\r\n'
-+'BEGIN:VCARD\r\nVERSION:3.0\r\nEMAIL;TYPE=INTERNET:jeffrey at osafoundation.org\r\nFN:Jeffrey Harris\r\nN:Harris;Jeffrey;;;\r\nEND:VCARD\r\n'
- >>> j.prettyPrint()
-  VCARD
-     VERSION: 3.0

Deleted: CalendarServer/trunk/lib-patches/vobject/src.vobject.base.patch
===================================================================
--- CalendarServer/trunk/lib-patches/vobject/src.vobject.base.patch	2007-01-23 21:12:18 UTC (rev 1089)
+++ CalendarServer/trunk/lib-patches/vobject/src.vobject.base.patch	2007-01-23 21:19:46 UTC (rev 1090)
@@ -1,96 +0,0 @@
-Index: src/vobject/base.py
-===================================================================
---- src/vobject/base.py	(revision 164)
-+++ src/vobject/base.py	(working copy)
-@@ -842,14 +842,36 @@
-     return param
- 
- def foldOneLine(outbuf, input, lineLength = 75):
--    if isinstance(input, basestring): input = StringIO.StringIO(input)
--    input.seek(0)
--    outbuf.write(input.read(lineLength) + CRLF)
--    brokenline = input.read(lineLength - 1)
--    while brokenline:
--        outbuf.write(' ' + brokenline + CRLF)
--        brokenline = input.read(lineLength - 1)
-+    # Folding line procedure that ensures multi-byte utf-8 sequences are not broken
-+    # across lines
- 
-+    if len(input) < lineLength:
-+        # Optimize for unfolded line case
-+        outbuf.write(input)
-+    else:
-+        # Look for valid utf8 range and write that out
-+        start = 0
-+        written = 0
-+        while written < len(input):
-+            # Start max length -1 chars on from where we are
-+            offset = start + lineLength - 1
-+            if offset >= len(input):
-+                line = input[start:]
-+                outbuf.write(line)
-+                written = len(input)
-+            else:
-+                # Check whether next char is valid utf8 lead byte
-+                while (input[offset] > 0x7F) and ((ord(input[offset]) & 0xC0) == 0x80):
-+                    # Step back until we have a valid char
-+                    offset -= 1
-+                
-+                line = input[start:offset]
-+                outbuf.write(line)
-+                outbuf.write("\r\n ")
-+                written += offset - start
-+                start = offset
-+    outbuf.write("\r\n")
-+
- def defaultSerialize(obj, buf, lineLength):
-     """Encode and fold obj and its children, write to buf or return a string."""
- 
-@@ -861,12 +883,12 @@
-         else:
-             groupString = obj.group + '.'
-         if obj.useBegin:
--            foldOneLine(outbuf, groupString + u"BEGIN:" + obj.name, lineLength)
-+            foldOneLine(outbuf, str(groupString + u"BEGIN:" + obj.name), lineLength)
-         for child in obj.getSortedChildren():
-             #validate is recursive, we only need to validate once
-             child.serialize(outbuf, lineLength, validate=False)
-         if obj.useBegin:
--            foldOneLine(outbuf, groupString + u"END:" + obj.name, lineLength)
-+            foldOneLine(outbuf, str(groupString + u"END:" + obj.name), lineLength)
-         if DEBUG: logger.debug("Finished %s" % obj.name.upper())
-         
-     elif isinstance(obj, ContentLine):
-@@ -875,14 +897,18 @@
-         if obj.behavior and not startedEncoded: obj.behavior.encode(obj)
-         s=StringIO.StringIO() #unfolded buffer
-         if obj.group is not None:
--            s.write(obj.group + '.')
-+            s.write(str(obj.group + '.'))
-         if DEBUG: logger.debug("Serializing line" + str(obj))
--        s.write(obj.name.upper())
-+        s.write(str(obj.name.upper()))
-         for key, paramvals in obj.params.iteritems():
--            s.write(';' + key + '=' + ','.join(map(dquoteEscape, paramvals)))
--        s.write(':' + obj.value)
-+            s.write(';' + str(key) + '=' + ','.join(map(dquoteEscape, paramvals)).encode("utf-8"))
-+        if isinstance(obj.value, unicode):
-+            strout = obj.value.encode("utf-8")
-+        else:
-+            strout = obj.value
-+        s.write(':' + strout)
-         if obj.behavior and not startedEncoded: obj.behavior.decode(obj)
--        foldOneLine(outbuf, s, lineLength)
-+        foldOneLine(outbuf, s.getvalue(), lineLength)
-         if DEBUG: logger.debug("Finished %s line" % obj.name.upper())
-     
-     return buf or outbuf.getvalue()
-@@ -1023,7 +1049,7 @@
-     else:
-         obj = ContentLine(name, [], '')
-     obj.behavior = behavior
--    obj.isNative = True
-+    obj.isNative = False
-     return obj
- 
- 

Deleted: CalendarServer/trunk/lib-patches/vobject/tests.tests.patch
===================================================================
--- CalendarServer/trunk/lib-patches/vobject/tests.tests.patch	2007-01-23 21:12:18 UTC (rev 1089)
+++ CalendarServer/trunk/lib-patches/vobject/tests.tests.patch	2007-01-23 21:19:46 UTC (rev 1090)
@@ -1,51 +0,0 @@
-Index: tests/tests.py
-===================================================================
---- tests/tests.py	(revision 164)
-+++ tests/tests.py	(working copy)
-@@ -280,7 +280,7 @@
-     >>> silly.stuff
-     <STUFF{}foldedline>
-     >>> original = silly.serialize()
--    >>> f3 = StringIO.StringIO(original)
-+    >>> f3 = StringIO.StringIO(original.decode("utf-8"))
-     >>> silly2 = base.readOne(f3)
-     >>> silly2.serialize()==original
-     True
-@@ -289,7 +289,7 @@
-     >>> ex1
-     <*unnamed*| [<CN{}Babs Jensen>, <CN{}Barbara J Jensen>, <EMAIL{}babs at umich.edu>, <PHONE{}+1 313 747-4454>, <SN{}Jensen>, <X-ID{}1234567890>]>
-     >>> ex1.serialize()
--    u'CN:Babs Jensen\r\nCN:Barbara J Jensen\r\nEMAIL:babs at umich.edu\r\nPHONE:+1 313 747-4454\r\nSN:Jensen\r\nX-ID:1234567890\r\n'
-+    'CN:Babs Jensen\r\nCN:Barbara J Jensen\r\nEMAIL:babs at umich.edu\r\nPHONE:+1 313 747-4454\r\nSN:Jensen\r\nX-ID:1234567890\r\n'
-     """,
-     
-     "Import icaltest" :
-@@ -306,7 +306,7 @@
-     >>> c.vevent.valarm.description.value
-     u'Event reminder, with comma\nand line feed'
-     >>> c.vevent.valarm.description.serialize()
--    u'DESCRIPTION:Event reminder\\, with comma\\nand line feed\r\n'
-+    'DESCRIPTION:Event reminder\\, with comma\\nand line feed\r\n'
-     >>> vevent = c.vevent.transformFromNative()
-     >>> vevent.rrule
-     <RRULE{}FREQ=Weekly;COUNT=10>
-@@ -352,6 +352,7 @@
-     >>> vevent.summary.value
-     u'The title \u3053\u3093\u306b\u3061\u306f\u30ad\u30c6\u30a3'
-     >>> summary = vevent.summary.value
-+    >>> test = str(vevent.serialize()),
-     """,
-     
-     # make sure date valued UNTILs in rrules are in a reasonable timezone,
-@@ -690,9 +691,9 @@
-     u'home'
-     >>> card.group = card.tel.group = 'new'
-     >>> card.tel.serialize().strip()
--    u'new.TEL;TYPE=fax,voice,msg:+49 3581 123456'
-+    'new.TEL;TYPE=fax,voice,msg:+49 3581 123456'
-     >>> card.serialize().splitlines()[0]
--    u'new.BEGIN:VCARD'
-+    'new.BEGIN:VCARD'
-     >>> dtstart = base.newFromBehavior('dtstart')
-     >>> dtstart.group = "badgroup"
-     >>> dtstart.serialize()

Modified: CalendarServer/trunk/run
===================================================================
--- CalendarServer/trunk/run	2007-01-23 21:12:18 UTC (rev 1089)
+++ CalendarServer/trunk/run	2007-01-23 21:19:46 UTC (rev 1090)
@@ -503,8 +503,8 @@
     base="http://svn.osafoundation.org";
     ;;
 esac;
-svn_uri="${base}/vobject/trunk";
-svn_get "vObject" "${vobject}" "${svn_uri}" 164;
+svn_uri="${base}/vobject/branches/users/cdaboo/vavailability-173";
+svn_get "vObject" "${vobject}" "${svn_uri}" 178;
 
 if ! "${disable_setup}"; then
   # Avoid having to download setuptools to build vobject

Modified: CalendarServer/trunk/twistedcaldav/caldavxml.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/caldavxml.py	2007-01-23 21:12:18 UTC (rev 1089)
+++ CalendarServer/trunk/twistedcaldav/caldavxml.py	2007-01-23 21:19:46 UTC (rev 1090)
@@ -898,28 +898,28 @@
                 log.msg("Top-level comp-filter must be VCALENDAR, instead: %s" % (self.filter_name,))
                 return False
         elif level == 1:
-            # Dissallow VCALENDAR, VALARM, STANDARD, DAYLIGHT at the top, everything else is OK
-            if self.filter_name in ("VCALENDAR", "VALARM", "STANDARD", "DAYLIGHT"):
+            # Dissallow VCALENDAR, VALARM, STANDARD, DAYLIGHT, AVAILABLE at the top, everything else is OK
+            if self.filter_name in ("VCALENDAR", "VALARM", "STANDARD", "DAYLIGHT", "AVAILABLE"):
                 log.msg("comp-filter wrong component type: %s" % (self.filter_name,))
                 return False
             
-            # time-range only on VEVENT, VTODO, VJOURNAL, VFREEBUSY
-            if timerange and self.filter_name not in ("VEVENT", "VTODO", "VJOURNAL", "VFREEBUSY"):
+            # time-range only on VEVENT, VTODO, VJOURNAL, VFREEBUSY, VAVAILABILITY
+            if timerange and self.filter_name not in ("VEVENT", "VTODO", "VJOURNAL", "VFREEBUSY", "VAVAILABILITY"):
                 log.msg("time-range cannot be used with component %s" % (self.filter_name,))
                 return False
         elif level == 2:
-            # Dissallow VCALENDAR, VTIMEZONE, VEVENT, VTODO, VJOURNAL, VFREEBUSY at the top, everything else is OK
-            if (self.filter_name in ("VCALENDAR", "VTIMEZONE", "VEVENT", "VTODO", "VJOURNAL", "VFREEBUSY")):
+            # Dissallow VCALENDAR, VTIMEZONE, VEVENT, VTODO, VJOURNAL, VFREEBUSY, VAVAILABILITY at the top, everything else is OK
+            if (self.filter_name in ("VCALENDAR", "VTIMEZONE", "VEVENT", "VTODO", "VJOURNAL", "VFREEBUSY", "VAVAILABILITY")):
                 log.msg("comp-filter wrong sub-component type: %s" % (self.filter_name,))
                 return False
             
-            # time-range only on VALARM
-            if timerange and self.filter_name not in ("VALARM",):
+            # time-range only on VALARM, AVAILABLE
+            if timerange and self.filter_name not in ("VALARM", "AVAILABLE",):
                 log.msg("time-range cannot be used with sub-component %s" % (self.filter_name,))
                 return False
         else:
             # Dissallow all std iCal components anywhere else
-            if (self.filter_name in ("VCALENDAR", "VTIMEZONE", "VEVENT", "VTODO", "VJOURNAL", "VFREEBUSY", "VALARM", "STANDARD", "DAYLIGHT")) or timerange:
+            if (self.filter_name in ("VCALENDAR", "VTIMEZONE", "VEVENT", "VTODO", "VJOURNAL", "VFREEBUSY", "VALARM", "STANDARD", "DAYLIGHT", "AVAILABLE")) or timerange:
                 log.msg("comp-filter wrong standard component type: %s" % (self.filter_name,))
                 return False
         

Modified: CalendarServer/trunk/twistedcaldav/directory/appleopendirectory.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/appleopendirectory.py	2007-01-23 21:12:18 UTC (rev 1089)
+++ CalendarServer/trunk/twistedcaldav/directory/appleopendirectory.py	2007-01-23 21:19:46 UTC (rev 1090)
@@ -133,8 +133,6 @@
                     continue
                 realName = value.get(dsattributes.kDS1AttrDistinguishedName)
 
-                # FIXME: We get email address also
-                # FIXME: In new schema, kDSNAttrCalendarPrincipalURI goes away
                 cuaddrs = value.get(dsattributes.kDSNAttrCalendarPrincipalURI)
                 cuaddrset = set()
                 if cuaddrs is not None:

Modified: CalendarServer/trunk/twistedcaldav/instance.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/instance.py	2007-01-23 21:12:18 UTC (rev 1089)
+++ CalendarServer/trunk/twistedcaldav/instance.py	2007-01-23 21:19:46 UTC (rev 1090)
@@ -21,8 +21,11 @@
 """
 
 import datetime
+
 from twistedcaldav.dateops import normalizeForIndex, compareDateTime, differenceDateTime, periodEnd
 
+from vobject.icalendar import utc
+
 # The maximum number of instances we will ezpand out to.
 # Raise a TooManyInstancesError exception if we exceed this.
 max_allowed_instances = 1000
@@ -113,7 +116,7 @@
         @param limit: datetime.date value representing the end of the expansion.
         """
         
-        # Look at each VEVENT, VTODO, VJOURNAL
+        # Look at each component type
         overrides = []
         for component in componentSet:
             if component.name() == "VEVENT":
@@ -131,6 +134,14 @@
                 raise NotImplementedError("VJOURNAL recurrence expansion not supported yet")
             elif component.name() == "VFREEBUSY":
                 self._addFreeBusyComponent(component, limit)
+            elif component.name() == "VAVAILABILITY":
+                self._addAvailabilityComponent(component, limit)
+            elif component.name() == "AVAILABLE":
+                if component.hasProperty("RECURRENCE-ID"):
+                    overrides.append(component)
+                else:
+                    # AVAILABLE components are just like VEVENT components
+                    self._addMasterEventComponent(component, limit)
             
         for component in overrides:
             if component.name() == "VEVENT":
@@ -140,6 +151,9 @@
             elif component.name() == "VJOURNAL":
                 #TODO: VJOURNAL
                 raise NotImplementedError("VJOURNAL recurrence expansion not supported yet")
+            elif component.name() == "AVAILABLE":
+                # AVAILABLE components are just like VEVENT components
+                self._addOverrideEventComponent(component)
 
     def addInstance(self, instance):
         """
@@ -347,4 +361,29 @@
                 start = normalizeForIndex(period[0])
                 end = normalizeForIndex(periodEnd(period))
                 self.addInstance(Instance(component, start, end))
-       
+
+    def _addAvailabilityComponent(self, component, limit):
+        """
+        Add the specified master VAVAILABILITY Component to the instance list, expanding it
+        within the supplied time range. VAVAILABILITY components are not recurring, they have an
+        optional DTSTART and DTEND/DURATION defining a single time-range which may be bounded
+        depedning on the presence of the properties. If unbounded at one or both ends, we will
+        set the time to 1/1/1900 in the past and 1/1/3000 in the future.
+        @param component: the Component to expand
+        @param limit: the end datetime.datetime for expansion
+        """
+
+        start = component.getStartDateUTC()
+        if start is not None and (compareDateTime(start, limit) >= 0):
+            # If the free busy is beyond the end of the range we want, ignore it
+            return
+        if start is None:
+            start = datetime.datetime(1900, 1, 1, 0, 0, 0, tzinfo=utc)
+        start = normalizeForIndex(start)
+
+        end = component.getEndDateUTC()
+        if end is None:
+            end = datetime.datetime(3000, 1, 1, 0, 0, 0, tzinfo=utc)
+        end = normalizeForIndex(end)
+
+        self.addInstance(Instance(component, start, end))

Modified: CalendarServer/trunk/twistedcaldav/method/report_common.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/method/report_common.py	2007-01-23 21:12:18 UTC (rev 1089)
+++ CalendarServer/trunk/twistedcaldav/method/report_common.py	2007-01-23 21:19:46 UTC (rev 1090)
@@ -43,6 +43,7 @@
 from twistedcaldav.caldavxml import caldav_namespace
 from twistedcaldav.dateops import clipPeriod, normalizePeriodList, timeRangesOverlap
 from twistedcaldav.ical import Component, Property, iCalendarProductID
+from twistedcaldav.instance import InstanceList
 
 from vobject.icalendar import utc
 
@@ -297,6 +298,10 @@
                           timerange,
                           name="VFREEBUSY",
                       ),
+                      caldavxml.ComponentFilter(
+                          timerange,
+                          name="VAVAILABILITY",
+                      ),
                       name="VCALENDAR",
                    )
               )
@@ -320,7 +325,6 @@
     yield filteredaces
     filteredaces = filteredaces.getResult()
 
-    uri = request.urlForResource(calresource)
     for name, uid, type in calresource.index().search(filter): #@UnusedVariable
         
         # Ignore ones of this UID
@@ -352,6 +356,8 @@
                 processEventFreeBusy(calendar, fbinfo, timerange, tzinfo)
             elif calendar.mainType() == "VFREEBUSY":
                 processFreeBusyFreeBusy(calendar, fbinfo, timerange)
+            elif calendar.mainType() == "VAVAILABILITY":
+                processAvailabilityFreeBusy(calendar, fbinfo, timerange)
             else:
                 assert "Free-busy query returned unwanted component: %s in %r", (name, calresource,)
     
@@ -457,6 +463,96 @@
                     mapper = {"BUSY": 0, "BUSY-TENTATIVE": 1, "BUSY-UNAVAILABLE": 2}
                     fbinfo[mapper.get(fbtype, 0)].append(clipped)
 
+def processAvailabilityFreeBusy(calendar, fbinfo, timerange):
+    """
+    Extract free-busy data from a VAVAILABILITY component.
+    @param calendar: the L{Component} that is the VCALENDAR containing the VAVAILABILITY's.
+    @param fbinfo: the tuple used to store the three types of fb data.
+    @param timerange: the time range to restrict free busy data to.
+    """
+    
+    for vav in [x for x in calendar.subcomponents() if x.name() == "VAVAILABILITY"]:
+
+        # Get overall start/end
+        start = vav.getStartDateUTC()
+        if start is None:
+            start = datetime.datetime(1900, 1, 1, 0, 0, 0, tzinfo=utc)
+        end = vav.getEndDateUTC()
+        if end is None:
+            end = datetime.datetime(3000, 1, 1, 0, 0, 0, tzinfo=utc)
+        period = (start, end)
+        overall = clipPeriod(period, (timerange.start, timerange.end))
+        if overall is None:
+            continue
+        
+        # Now get periods for each instance of AVAILABLE sub-components
+        periods = processAvailablePeriods(vav, timerange)
+        
+        # Now invert the periods and store in accumulator
+        busyperiods = []
+        last_end = timerange.start
+        for period in periods:
+            if last_end < period[0]:
+                busyperiods.append((last_end, period[0]))
+            last_end = period[1]
+        if last_end < timerange.end:
+            busyperiods.append((last_end, timerange.end))
+
+        # Add to actual results mapped by busy type
+        fbtype = vav.propertyValue("BUSYTYPE")
+        if fbtype is None:
+            fbtype = "BUSY-UNAVAILABLE"
+
+        mapper = {"BUSY": 0, "BUSY-TENTATIVE": 1, "BUSY-UNAVAILABLE": 2}
+        fbinfo[mapper.get(fbtype, 2)].extend(busyperiods)
+            
+
+def processAvailablePeriods(calendar, timerange):
+    """
+    Extract instance period data from an AVAILABLE component.
+    @param calendar: the L{Component} that is the VAVAILABILITY containing the AVAILABLE's.
+    @param timerange: the time range to restrict free busy data to.
+    """
+    
+    periods = []
+
+    # First we need to group all AVAILABLE sub-components by UID
+    uidmap = {}
+    for component in calendar.subcomponents():
+        if component.name() == "AVAILABLE":
+            uid = component.propertyValue("UID")
+            uidmap.setdefault(uid, []).append(component)
+            
+    # Then we expand each uid set seperately
+    for componentSet in uidmap.itervalues():
+        instances = InstanceList()
+        instances.expandTimeRanges(componentSet, timerange.end)
+        
+        # Now convert instances into period list
+        for key in instances:
+            instance = instances[key]
+            # Ignore any with floating times (which should not happen as the spec requires UTC or local
+            # but we will try and be safe here).
+            start = instance.start
+            if start.tzinfo is None:
+                continue
+            end = instance.end
+            if end.tzinfo is None:
+                continue
+
+            # Clip period for this instance - use duration for period end if that
+            # is what original component used
+            if instance.component.hasProperty("DURATION"):
+                period = (start, end - start)
+            else:
+                period = (start, end)
+            clipped = clipPeriod(period, (timerange.start, timerange.end))
+            if clipped:
+                periods.append(clipped)
+            
+    normalizePeriodList(periods)
+    return periods
+
 def buildFreeBusyResult(fbinfo, timerange, organizer=None, attendee=None, uid=None):
     """
     Generate a VCALENDAR object containing a single VFREEBUSY that is the

Modified: CalendarServer/trunk/twistedcaldav/resource.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/resource.py	2007-01-23 21:12:18 UTC (rev 1089)
+++ CalendarServer/trunk/twistedcaldav/resource.py	2007-01-23 21:19:46 UTC (rev 1090)
@@ -127,7 +127,11 @@
     ##
 
     def davComplianceClasses(self):
-        return tuple(super(CalDAVResource, self).davComplianceClasses()) + ("calendar-access", "calendar-schedule")
+        return tuple(super(CalDAVResource, self).davComplianceClasses()) + (
+            "calendar-access",
+            "calendar-schedule",
+            "calendar-availability",
+        )
 
     liveProperties = DAVResource.liveProperties + (
         (caldav_namespace, "supported-calendar-component-set"),
@@ -140,6 +144,7 @@
         caldavxml.CalendarComponent(name="VTIMEZONE"),
         caldavxml.CalendarComponent(name="VJOURNAL" ),
         caldavxml.CalendarComponent(name="VFREEBUSY"),
+        caldavxml.CalendarComponent(name="VAVAILABILITY"),
     )
 
     def readProperty(self, property, request):
@@ -558,7 +563,11 @@
     implements(ICalendarPrincipalResource)
 
     def davComplianceClasses(self):
-        return tuple(super(CalendarPrincipalResource, self).davComplianceClasses()) + ("calendar-access", "calendar-schedule")
+        return tuple(super(CalendarPrincipalResource, self).davComplianceClasses()) + (
+            "calendar-access",
+            "calendar-schedule",
+            "calendar-availability",
+        )
 
     liveProperties = DAVPrincipalResource.liveProperties + (
         (caldav_namespace, "calendar-home-set"        ),

Modified: CalendarServer/trunk/twistedcaldav/test/test_options.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/test/test_options.py	2007-01-23 21:12:18 UTC (rev 1089)
+++ CalendarServer/trunk/twistedcaldav/test/test_options.py	2007-01-23 21:19:46 UTC (rev 1090)
@@ -35,7 +35,10 @@
             dav = response.headers.getHeader("dav")
             if not dav: self.fail("no DAV header: %s" % (response.headers,))
             self.assertIn("1", dav, "no DAV level 1 header")
+            self.assertIn("access-control", dav, "no DAV access-control header")
             self.assertIn("calendar-access", dav, "no DAV calendar-access header")
+            self.assertIn("calendar-schedule", dav, "no DAV calendar-schedule header")
+            self.assertIn("calendar-availability", dav, "no DAV calendar-availability header")
 
         request = SimpleRequest(self.site, "OPTIONS", "/")
 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20070123/6670dfd3/attachment.html


More information about the calendarserver-changes mailing list