[CalendarServer-changes] [5203] CalendarServer/branches/users/cdaboo/shared-calendars-5187/ twistedcaldav

source_changes at macosforge.org source_changes at macosforge.org
Wed Feb 24 19:32:19 PST 2010


Revision: 5203
          http://trac.macosforge.org/projects/calendarserver/changeset/5203
Author:   cdaboo at apple.com
Date:     2010-02-24 19:32:17 -0800 (Wed, 24 Feb 2010)
Log Message:
-----------
Notification collection in calendar home.

Modified Paths:
--------------
    CalendarServer/branches/users/cdaboo/shared-calendars-5187/twistedcaldav/customxml.py
    CalendarServer/branches/users/cdaboo/shared-calendars-5187/twistedcaldav/directory/calendar.py
    CalendarServer/branches/users/cdaboo/shared-calendars-5187/twistedcaldav/directory/principal.py
    CalendarServer/branches/users/cdaboo/shared-calendars-5187/twistedcaldav/resource.py
    CalendarServer/branches/users/cdaboo/shared-calendars-5187/twistedcaldav/static.py

Added Paths:
-----------
    CalendarServer/branches/users/cdaboo/shared-calendars-5187/twistedcaldav/notifications.py

Modified: CalendarServer/branches/users/cdaboo/shared-calendars-5187/twistedcaldav/customxml.py
===================================================================
--- CalendarServer/branches/users/cdaboo/shared-calendars-5187/twistedcaldav/customxml.py	2010-02-25 03:19:49 UTC (rev 5202)
+++ CalendarServer/branches/users/cdaboo/shared-calendars-5187/twistedcaldav/customxml.py	2010-02-25 03:32:17 UTC (rev 5203)
@@ -571,7 +571,141 @@
     namespace = calendarserver_namespace
     name = "auto-schedule"
 
+class UID (davxml.WebDAVTextElement):
+    namespace = calendarserver_namespace
+    name = "uid"
+
 ##
+# Notifications
+##
+
+class InviteAccess (davxml.WebDAVElement):
+    namespace = calendarserver_namespace
+    name = "access"
+
+    allowed_children = {
+        (calendarserver_namespace, "read" )      : (0, 1),
+        (calendarserver_namespace, "read-write" ): (0, 1),
+    }
+
+class InviteSummary (davxml.WebDAVTextElement):
+    namespace = calendarserver_namespace
+    name = "summary"
+
+class InviteStatusNoResponse (davxml.WebDAVEmptyElement):
+    namespace = calendarserver_namespace
+    name = "invite-noresponse"
+
+class InviteStatusDeleted (davxml.WebDAVEmptyElement):
+    namespace = calendarserver_namespace
+    name = "invite-deleted"
+
+class InviteStatusAccepted (davxml.WebDAVEmptyElement):
+    namespace = calendarserver_namespace
+    name = "invite-accepted"
+
+class InviteStatusDeclined (davxml.WebDAVEmptyElement):
+    namespace = calendarserver_namespace
+    name = "invite-declined"
+
+class HostURL (davxml.WebDAVElement):
+    """
+    The source for a shared calendar
+    """
+    namespace = calendarserver_namespace
+    name = "hosturl"
+
+    allowed_children = { (dav_namespace, "href"): (0, None) }
+
+class Organizer (davxml.WebDAVElement):
+    """
+    The organizer for a shared calendar
+    """
+    namespace = calendarserver_namespace
+    name = "organizer"
+
+    allowed_children = { (dav_namespace, "href"): (0, None) }
+
+class InviteNotification (davxml.WebDAVElement):
+    namespace = calendarserver_namespace
+    name = "invite-notification"
+
+    allowed_children = {
+        (dav_namespace, "href")          : (0, 1),
+        InviteStatusNoResponse.qname()   : (0, 1),
+        InviteStatusDeleted.qname()      : (0, 1),
+        InviteStatusAccepted.qname()     : (0, 1),
+        InviteStatusDeclined.qname()     : (0, 1),
+        InviteAccess.qname()             : (0, 1),
+        HostURL.qname()                  : (0, 1),
+        Organizer.qname()                : (0, 1),
+        InviteSummary.qname()            : (0, 1),
+        UID.qname()                      : (0, 1),
+    }
+
+class ResourceUpdateAdded(davxml.WebDAVEmptyElement):
+    namespace = calendarserver_namespace
+    name = "resource-added-notification"
+
+class ResourceUpdateUpdated(davxml.WebDAVEmptyElement):
+    namespace = calendarserver_namespace
+    name = "resource-updated-notification"
+
+class ResourceDeletedUpdated(davxml.WebDAVEmptyElement):
+    namespace = calendarserver_namespace
+    name = "resource-deleted-notification"
+
+class ResourceUpdateNotification (davxml.WebDAVElement):
+    namespace = calendarserver_namespace
+    name = "resource-update-notification"
+
+    allowed_children = {
+        (dav_namespace, "href")          : (0, 1),
+        UID.qname()                      : (0, 1),
+        ResourceUpdateAdded.qname()      : (0, 1),
+        ResourceUpdateUpdated.qname()    : (0, 1),
+        ResourceDeletedUpdated.qname()   : (0, 1),
+    }
+
+class SharedCalendarUpdateNotification (davxml.WebDAVElement):
+    namespace = calendarserver_namespace
+    name = "shared-update-notification"
+
+    allowed_children = {
+        HostURL.qname()                  : (0, 1), # The shared calendar url
+        (dav_namespace, "href")          : (0, 1), # Email userid that was invited
+        InviteStatusDeleted.qname()      : (0, 1), # What the user did...
+        InviteStatusAccepted.qname()     : (0, 1),
+        InviteStatusDeclined.qname()     : (0, 1),
+    }
+
+class Notification (davxml.WebDAVElement):
+    """
+    Denotes a notification collection, or a notification message.
+    """
+    namespace = calendarserver_namespace
+    name = "notification"
+
+    allowed_children = {
+        DTStamp.qname()                            : (0, None),
+        InviteNotification.qname()                 : (0, None),
+        ResourceUpdateNotification.qname()         : (0, None),
+        SharedCalendarUpdateNotification.qname()   : (0, None),
+    }
+
+class NotificationURL (davxml.WebDAVElement):
+    """
+    A principal property to indicate the notification collection for the principal.
+    """
+    namespace = calendarserver_namespace
+    name = "notification-URL"
+    hidden = True
+    protected = True
+
+    allowed_children = { (davxml.dav_namespace, "href"): (0, 1) }
+
+
+##
 # Extensions to davxml.ResourceType
 ##
 
@@ -582,3 +716,4 @@
 davxml.ResourceType.timezones = davxml.ResourceType(Timezones())
 davxml.ResourceType.ischeduleinbox = davxml.ResourceType(IScheduleInbox())
 davxml.ResourceType.freebusyurl = davxml.ResourceType(FreeBusyURL())
+davxml.ResourceType.notification = davxml.ResourceType(davxml.Collection(), Notification())

Modified: CalendarServer/branches/users/cdaboo/shared-calendars-5187/twistedcaldav/directory/calendar.py
===================================================================
--- CalendarServer/branches/users/cdaboo/shared-calendars-5187/twistedcaldav/directory/calendar.py	2010-02-25 03:19:49 UTC (rev 5202)
+++ CalendarServer/branches/users/cdaboo/shared-calendars-5187/twistedcaldav/directory/calendar.py	2010-02-25 03:32:17 UTC (rev 5203)
@@ -46,6 +46,7 @@
 from twistedcaldav.directory.idirectory import IDirectoryService
 from twistedcaldav.directory.wiki import getWikiACL
 from twistedcaldav.directory.resource import AutoProvisioningResourceMixIn
+from twistedcaldav.notifications import NotificationCollectionResource
 
 log = Logger()
 
@@ -277,6 +278,10 @@
             childlist += (
                 ("freebusy", FreeBusyURLResource),
             )
+        if config.EnableSharing:
+            childlist += (
+                ("notification", NotificationCollectionResource),
+            )
         for name, cls in childlist:
             child = self.provisionChild(name)
             assert isinstance(child, cls), "Child %r is not a %s: %r" % (name, cls.__name__, child)

Modified: CalendarServer/branches/users/cdaboo/shared-calendars-5187/twistedcaldav/directory/principal.py
===================================================================
--- CalendarServer/branches/users/cdaboo/shared-calendars-5187/twistedcaldav/directory/principal.py	2010-02-25 03:19:49 UTC (rev 5202)
+++ CalendarServer/branches/users/cdaboo/shared-calendars-5187/twistedcaldav/directory/principal.py	2010-02-25 03:32:17 UTC (rev 5203)
@@ -892,6 +892,16 @@
 
         return succeed(inbox)
 
+    def notificationCollection(self, request):
+        
+        notification = None
+        if config.EnableSharing:
+            home = self.calendarHome()
+            if home is not None:    
+                notification = home.getChild("notification")
+    
+        return succeed(notification)
+
     def calendarHomeURLs(self):
         homeURL = self._homeChildURL(None)
         return (homeURL,) if homeURL else ()
@@ -908,6 +918,12 @@
         else:
             return None
 
+    def notificationURL(self):
+        if config.EnableSharing:
+            return self._homeChildURL("notification/")
+        else:
+            return None
+
     def addressBookHomeURLs(self):
         home = self._addressBookHome()
         if home is None:

Added: CalendarServer/branches/users/cdaboo/shared-calendars-5187/twistedcaldav/notifications.py
===================================================================
--- CalendarServer/branches/users/cdaboo/shared-calendars-5187/twistedcaldav/notifications.py	                        (rev 0)
+++ CalendarServer/branches/users/cdaboo/shared-calendars-5187/twistedcaldav/notifications.py	2010-02-25 03:32:17 UTC (rev 5203)
@@ -0,0 +1,65 @@
+##
+# Copyright (c) 2010 Apple Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##
+
+"""
+Implements notification functionality.
+"""
+
+__all__ = [
+    "NotificationResource",
+    "NotificationCollectionResource",
+]
+
+from twext.web2 import responsecode
+from twext.web2.dav import davxml
+from twext.web2.dav.resource import DAVResource
+
+from twext.python.log import Logger
+
+from twisted.internet.defer import succeed
+
+log = Logger()
+
+class NotificationResource(DAVResource):
+    """
+    An xml resource in a Notification collection.
+    """
+    def principalCollections(self):
+        return self._parent.principalCollections()
+
+    def isCollection(self):
+        return False
+
+    def http_PUT(self, request):
+        return responsecode.FORBIDDEN
+
+class NotificationCollectionResource(DAVResource):
+    
+    def isCollection(self):
+        return True
+
+    def resourceType(self):
+        return davxml.ResourceType.notification
+
+    def getNotifictionMessages(self, request, componentType=None, returnLatestVersion=True):
+        return succeed([])
+
+    def getNotifictionMessagesByUID(self, request, uid):
+        return succeed([])
+
+    def deleteSchedulingMessagesByUID(self, request, uid):
+        return succeed(True)
+

Modified: CalendarServer/branches/users/cdaboo/shared-calendars-5187/twistedcaldav/resource.py
===================================================================
--- CalendarServer/branches/users/cdaboo/shared-calendars-5187/twistedcaldav/resource.py	2010-02-25 03:19:49 UTC (rev 5202)
+++ CalendarServer/branches/users/cdaboo/shared-calendars-5187/twistedcaldav/resource.py	2010-02-25 03:32:17 UTC (rev 5203)
@@ -934,6 +934,14 @@
             clz.liveProperties = tuple([p for p in clz.liveProperties if p != qname])
 
     @classmethod
+    def enableSharing(clz, enable):
+        qname = (calendarserver_namespace, "notification-URL" )
+        if enable and qname not in clz.liveProperties:
+            clz.liveProperties += (qname,)
+        elif not enable and qname in clz.liveProperties:
+            clz.liveProperties = tuple([p for p in clz.liveProperties if p != qname])
+
+    @classmethod
     def enableAddressBooks(clz, enable):
         qname = (carddav_namespace, "addressbook-home-set" )
         if enable and qname not in clz.liveProperties:
@@ -989,6 +997,13 @@
                 else:
                     returnValue(customxml.DropBoxHomeURL(davxml.HRef(url)))
 
+            elif name == "notification-URL" and config.EnableSharing:
+                url = yield self.notificationURL()
+                if url is None:
+                    returnValue(None)
+                else:
+                    returnValue(customxml.NotificationURL(davxml.HRef(url)))
+
             elif name == "calendar-proxy-read-for":
                 results = (yield self.proxyFor(False))
                 returnValue(customxml.CalendarProxyReadFor(
@@ -1086,6 +1101,13 @@
         else:
             return None
 
+    def notificationURL(self, request=None):
+        if self.hasDeadProperty((calendarserver_namespace, "notification-URL")):
+            notification = self.readDeadProperty((calendarserver_namespace, "notification-URL"))
+            return succeed(str(notification.children[0]))
+        else:
+            return succeed(None)
+
     def addressBookHomeURLs(self):
         if self.hasDeadProperty((carddav_namespace, "addressbook-home-set")):
             home_set = self.readDeadProperty((carddav_namespace, "addressbook-home-set"))

Modified: CalendarServer/branches/users/cdaboo/shared-calendars-5187/twistedcaldav/static.py
===================================================================
--- CalendarServer/branches/users/cdaboo/shared-calendars-5187/twistedcaldav/static.py	2010-02-25 03:19:49 UTC (rev 5202)
+++ CalendarServer/branches/users/cdaboo/shared-calendars-5187/twistedcaldav/static.py	2010-02-25 03:32:17 UTC (rev 5203)
@@ -32,6 +32,8 @@
     "DropBoxCollectionFile",
     "DropBoxChildFile",
     "TimezoneServiceFile",
+    "NotificationCollectionFile",
+    "NotificationFile",
     "AddressBookHomeProvisioningFile",
     "AddressBookHomeUIDProvisioningFile",
     "AddressBookHomeFile",
@@ -97,6 +99,8 @@
 from twistedcaldav.notify import getPubSubConfiguration, getPubSubXMPPURI
 from twistedcaldav.notify import getPubSubHeartbeatURI, getPubSubPath
 from twistedcaldav.notify import ClientNotifier, getNodeCacher
+from twistedcaldav.notifications import NotificationCollectionResource,\
+    NotificationResource
 
 log = Logger()
 
@@ -945,11 +949,17 @@
         else:
             FreeBusyURLFileClass = None
             
+        if config.EnableSharing:
+            NotificationCollectionFileClass = NotificationCollectionFile
+        else:
+            NotificationCollectionFileClass = None
+
         cls = {
             "inbox"        : ScheduleInboxFile,
             "outbox"       : ScheduleOutboxFile,
             "dropbox"      : DropBoxHomeFileClass,
             "freebusy"     : FreeBusyURLFileClass,
+            "notification" : NotificationCollectionFileClass,
         }.get(name, None)
 
         if cls is not None:
@@ -1287,6 +1297,41 @@
     def checkPrivileges(self, request, privileges, recurse=False, principal=None, inherited_aces=None):
         return succeed(None)
 
+class NotificationCollectionFile(AutoProvisioningFileMixIn, NotificationCollectionResource, CalDAVFile):
+    """
+    Notification collection resource.
+    """
+    def __init__(self, path, parent):
+        NotificationCollectionResource.__init__(self)
+        CalDAVFile.__init__(self, path, principalCollections=parent.principalCollections())
+        self.parent = parent
+
+    def createSimilarFile(self, path):
+        if self.comparePath(path):
+            return self
+        else:
+            return NotificationFile(path, self)
+
+    def __repr__(self):
+        return "<%s (notification collection): %s>" % (self.__class__.__name__, self.fp.path)
+
+class NotificationFile(NotificationResource, CalDAVFile):
+
+    def __init__(self, path, parent):
+        NotificationResource.__init__(self, parent)
+        CalDAVFile.__init__(self, path, principalCollections=parent.principalCollections())
+
+        assert self.fp.isfile() or not self.fp.exists()
+
+    def createSimilarFile(self, path):
+        if self.comparePath(path):
+            return self
+        else:
+            return responsecode.NOT_FOUND
+
+    def __repr__(self):
+        return "<%s (notification file): %s>" % (self.__class__.__name__, self.fp.path)
+
 class AddressBookHomeProvisioningFile (DirectoryAddressBookHomeProvisioningResource, DAVFile):
     """
     Resource which provisions address book home collections as needed.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20100224/c0104bcd/attachment-0001.html>


More information about the calendarserver-changes mailing list