[CalendarServer-changes] [12042] CalendarServer/branches/users/sagen/groupcacher
source_changes at macosforge.org
source_changes at macosforge.org
Wed Mar 12 11:22:11 PDT 2014
Revision: 12042
http://trac.calendarserver.org//changeset/12042
Author: gaya at apple.com
Date: 2013-12-06 21:24:08 -0800 (Fri, 06 Dec 2013)
Log Message:
-----------
checkpoint
Modified Paths:
--------------
CalendarServer/branches/users/sagen/groupcacher/twext/who/groups.py
CalendarServer/branches/users/sagen/groupcacher/twext/who/test/test_groups.py
CalendarServer/branches/users/sagen/groupcacher/twistedcaldav/ical.py
CalendarServer/branches/users/sagen/groupcacher/txdav/caldav/datastore/sql.py
CalendarServer/branches/users/sagen/groupcacher/txdav/caldav/datastore/util.py
Modified: CalendarServer/branches/users/sagen/groupcacher/twext/who/groups.py
===================================================================
--- CalendarServer/branches/users/sagen/groupcacher/twext/who/groups.py 2013-12-06 21:43:35 UTC (rev 12041)
+++ CalendarServer/branches/users/sagen/groupcacher/twext/who/groups.py 2013-12-07 05:24:08 UTC (rev 12042)
@@ -25,7 +25,7 @@
from twext.who.delegates import allGroupDelegates
from twext.who.idirectory import RecordType
from twisted.internet.defer import inlineCallbacks, returnValue
-from twistedcaldav.ical import ignoredComponents
+from txdav.caldav.datastore.util import normalizationLookup
from txdav.common.datastore.sql_tables import schema
import datetime
import hashlib
@@ -133,15 +133,6 @@
)
).on(self.transaction)
- # get group individual UIDs
- groupMemember = schema.GROUP_MEMBERSHIP
- rows = yield Select(
- [groupMemember.MEMBER_GUID, ],
- From=groupMemember,
- Where=groupMemember.GROUP_ID == self.groupID,
- ).on(self.transaction)
- individualGUIDs = [row[0] for row in rows]
-
# get calendar Object
calObject = schema.CALENDAR_OBJECT
rows = yield Select(
@@ -150,7 +141,7 @@
Where=calObject.RESOURCE_ID == self.eventID,
).on(self.transaction)
- calendarID = row[0][0]
+ calendarID = rows[0][0]
calendarHome = (yield self.Calendar._ownerHomeWithResourceID.on(
self.transaction, resourceID=calendarID)
)[0][0]
@@ -159,43 +150,20 @@
calendarObject = yield calendar.objectResourceWithID(self.eventID)
changed = False
- individualUUIDs = set(["urn:uuid:" + individualGUID for individualGUID in individualGUIDs])
- groupUUID = "urn:uuid:" + self.groupGUID()
- vcalendar = yield calendarObject.component()
- for component in vcalendar.subcomponents():
- if component.name() in ignoredComponents:
- continue
+ # get group individual UIDs
+ groupMemember = schema.GROUP_MEMBERSHIP
+ rows = yield Select(
+ [groupMemember.MEMBER_GUID, ],
+ From=groupMemember,
+ Where=groupMemember.GROUP_ID == self.groupID,
+ ).on(self.transaction)
+ individualGUIDs = [row[0] for row in rows]
- oldAttendeeProps = component.getAttendees()
- oldAttendeeUUIDs = set([attendeeProp.value() for attendeeProp in oldAttendeeProps])
+ component = yield calendarObject.component()
+ changed = component.expandGroupAttendee(self.groupGUID, individualGUIDs, normalizationLookup, self.directoryService().recordWithCalendarUserAddress)
- # add new member attendees
- for individualUUID in individualUUIDs - oldAttendeeUUIDs:
- individualGUID = individualUUID[len("urn:uuid:"):]
- directoryRecord = self.transaction.directoryService().recordWithUID(individualGUID)
- newAttendeeProp = directoryRecord.attendee(params={"MEMBER": groupUUID})
- component.addProperty(newAttendeeProp)
- changed = True
-
- # remove attendee or update MEMBER attribute for non-primary attendees in this group,
- for attendeeProp in oldAttendeeProps:
- if attendeeProp.hasParameter("MEMBER"):
- parameterValues = attendeeProp.parameterValues("MEMBER")
- if groupUUID in parameterValues:
- if attendeeProp.value() not in individualUUIDs:
- attendeeProp.removeParameterValue("MEMBER", groupUUID)
- if not attendeeProp.parameterValues("MEMBER"):
- component.removeProperty(attendeeProp)
- changed = True
- else:
- if attendeeProp.value() in individualUUIDs:
- attendeeProp.setParameter("MEMBER", parameterValues + [groupUUID, ])
- changed = True
-
- # replace old with new
if changed:
- # TODO: call calendarObject._setComponentInternal( vcalendar, mode ) instead?
- yield calendarObject.setComponent(vcalendar)
+ yield calendarObject.setComponent(component)
Modified: CalendarServer/branches/users/sagen/groupcacher/twext/who/test/test_groups.py
===================================================================
--- CalendarServer/branches/users/sagen/groupcacher/twext/who/test/test_groups.py 2013-12-06 21:43:35 UTC (rev 12041)
+++ CalendarServer/branches/users/sagen/groupcacher/twext/who/test/test_groups.py 2013-12-07 05:24:08 UTC (rev 12042)
@@ -343,7 +343,7 @@
DURATION:PT1H
ATTENDEE;CN=User 01;EMAIL=user01 at example.com;RSVP=TRUE:urn:uuid:user01
ATTENDEE;CN=User 02;EMAIL=user02 at example.com;RSVP=TRUE;SCHEDULE-STATUS=1.2:urn:uuid:user02
-ATTENDEE;CN=Group 01;EMAIL=group01 at example.com;RSVP=TRUE;SCHEDULE-STATUS=3.7:urn:uuid:group01
+ATTENDEE;CN=Group 01;CUTYPE=GROUP;EMAIL=group01 at example.com;RSVP=TRUE;SCHEDULE-STATUS=3.7:urn:uuid:group01
CREATED:20060101T150000Z
ORGANIZER;CN=User 01;EMAIL=user01 at example.com:urn:uuid:user01
SUMMARY:event 1
Modified: CalendarServer/branches/users/sagen/groupcacher/twistedcaldav/ical.py
===================================================================
--- CalendarServer/branches/users/sagen/groupcacher/twistedcaldav/ical.py 2013-12-06 21:43:35 UTC (rev 12041)
+++ CalendarServer/branches/users/sagen/groupcacher/twistedcaldav/ical.py 2013-12-07 05:24:08 UTC (rev 12042)
@@ -3251,7 +3251,7 @@
# Check that we can lookup this calendar user address - if not
# we cannot do anything with it
cuaddr = normalizeCUAddr(prop.value())
- name, guid, cuaddrs = lookupFunction(cuaddr, principalFunction, config)
+ name, guid, cutype, cuaddrs = lookupFunction(cuaddr, principalFunction, config)
if guid is None:
continue
@@ -3263,8 +3263,6 @@
# Get any CN parameter
oldCN = prop.parameterValue("CN")
- cutype = prop.parameterValue("CUTYPE")
-
if toUUID:
# Always re-write value to urn:uuid
prop.setValue("urn:uuid:%s" % (guid,))
@@ -3343,11 +3341,56 @@
else:
prop.removeParameter("EMAIL")
+ if cutype == "INDIVIDUAL":
+ cutype = None
+
+ if cutype != prop.parameterValue("CUTYPE"):
+ if cutype:
+ prop.setParameter("CUTYPE", cutype)
+ else:
+ prop.removeParameter("CUTYPE")
+
# For VPOLL also do immediate children
if component.name() == "VPOLL":
component.normalizeCalendarUserAddresses(lookupFunction, principalFunction, toUUID)
+ def expandGroupAttendee(self, groupGUID, individualGUIDs, lookupFunction, principalFunction):
+
+ individualUUIDs = set(["urn:uuid:" + individualGUID for individualGUID in individualGUIDs])
+ groupUUID = "urn:uuid:" + groupGUID
+ changed = False
+ for component in self.subcomponents():
+ if component.name() in ignoredComponents:
+ continue
+
+ oldAttendeeProps = component.properties("ATTENDEE")
+ oldAttendeeUUIDs = set([attendeeProp.value() for attendeeProp in oldAttendeeProps])
+
+ # add new member attendees
+ for individualUUID in individualUUIDs - oldAttendeeUUIDs:
+ directoryRecord = lookupFunction(individualUUID, principalFunction, config)
+ newAttendeeProp = directoryRecord.attendee(params={"MEMBER": groupUUID})
+ component.addProperty(newAttendeeProp)
+ changed = True
+
+ # remove attendee or update MEMBER attribute for non-primary attendees in this group,
+ for attendeeProp in oldAttendeeProps:
+ if attendeeProp.hasParameter("MEMBER"):
+ parameterValues = attendeeProp.parameterValues("MEMBER")
+ if groupUUID in parameterValues:
+ if attendeeProp.value() not in individualUUIDs:
+ attendeeProp.removeParameterValue("MEMBER", groupUUID)
+ if not attendeeProp.parameterValues("MEMBER"):
+ component.removeProperty(attendeeProp)
+ changed = True
+ else:
+ if attendeeProp.value() in individualUUIDs:
+ attendeeProp.setParameter("MEMBER", parameterValues + [groupUUID, ])
+ changed = True
+ return changed
+
+
def allPerUserUIDs(self):
results = set()
Modified: CalendarServer/branches/users/sagen/groupcacher/txdav/caldav/datastore/sql.py
===================================================================
--- CalendarServer/branches/users/sagen/groupcacher/txdav/caldav/datastore/sql.py 2013-12-06 21:43:35 UTC (rev 12041)
+++ CalendarServer/branches/users/sagen/groupcacher/txdav/caldav/datastore/sql.py 2013-12-07 05:24:08 UTC (rev 12042)
@@ -1582,13 +1582,16 @@
if not self.calendar().isSupportedComponent(component.mainType()):
raise InvalidComponentTypeError("Invalid component type %s for calendar: %s" % (component.mainType(), self.calendar(),))
- # Valid attendee list size check
- yield self.validAttendeeListSizeCheck(component, inserting)
-
# Normalize the calendar user addresses once we know we have valid
# calendar data
component.normalizeCalendarUserAddresses(normalizationLookup, self.directoryService().recordWithCalendarUserAddress)
+ # Expand groups
+ yield self.expandGroupAttendees(component)
+
+ # Valid attendee list size check
+ yield self.validAttendeeListSizeCheck(component, inserting)
+
# Possible timezone stripping
if config.EnableTimezonesByReference:
component.stripKnownTimezones()
@@ -1601,8 +1604,40 @@
self.validAccess(component, inserting, internal_state)
- def validCalendarDataCheck(self, component, inserting):
+ @inlineCallbacks
+ def expandGroupAttendees(self, component):
"""
+ Expand group attendees
+ """
+
+ if not config.Scheduling.Options.AllowGroupAsAttendee:
+ return
+
+ attendeeProps = component.getAllAttendeeProperties()
+ groupGUIDs = [
+ attendeeProp.value()[len("urn:uuid:"):] for attendeeProp in attendeeProps
+ if attendeeProp.parameterValue("CUTYPE") == "GROUP"
+ ]
+
+ # FIXME: need to add event to Group resource ID here
+ # need get get members here because they may not be cached yet
+
+ for groupGUID in groupGUIDs:
+ groupID, name, membershipHash = yield self._txn.groupByGUID(groupGUID)
+
+ groupMemember = schema.GROUP_MEMBERSHIP
+ rows = yield Select(
+ [groupMemember.MEMBER_GUID, ],
+ From=groupMemember,
+ Where=groupMemember.GROUP_ID == groupID,
+ ).on(self._txn)
+ individualGUIDs = [row[0] for row in rows]
+
+ component.expandGroupAttendee(groupGUID, individualGUIDs, normalizationLookup, self.directoryService().recordWithCalendarUserAddress)
+
+
+ def validCalendarDataCheck(self, component, inserting): #@UnusedVariable
+ """
Check that the calendar data is valid iCalendar.
@return: tuple: (True/False if the calendar data is valid,
log message string).
Modified: CalendarServer/branches/users/sagen/groupcacher/txdav/caldav/datastore/util.py
===================================================================
--- CalendarServer/branches/users/sagen/groupcacher/txdav/caldav/datastore/util.py 2013-12-06 21:43:35 UTC (rev 12041)
+++ CalendarServer/branches/users/sagen/groupcacher/txdav/caldav/datastore/util.py 2013-12-07 05:24:08 UTC (rev 12042)
@@ -103,7 +103,7 @@
def normalizationLookup(cuaddr, recordFunction, config):
"""
Lookup function to be passed to ical.normalizeCalendarUserAddresses.
- Returns a tuple of (Full name, guid, and calendar user address list)
+ Returns a tuple of (Full name, guid, cutype and calendar user address list)
for the given cuaddr. The recordFunction is called to retrieve the
record for the cuaddr.
"""
@@ -114,7 +114,7 @@
record = None
if record is None:
- return (None, None, None)
+ return (None, None, None, None)
else:
# RFC5545 syntax does not allow backslash escaping in
# parameter values. A double-quote is thus not allowed
@@ -124,6 +124,7 @@
return (
record.fullName.replace('"', "'"),
record.uid,
+ record.getCUType(),
record.calendarUserAddresses,
)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20140312/e0f964e8/attachment.html>
More information about the calendarserver-changes
mailing list