Improved handling of notifications and participation change updates. Added comments to the code.
Monotone-Parent: 17e3e8707a2ae061fd0c4184a32cd23a97af96ba Monotone-Revision: 6fac49c5eccc3f49ff214ee3fa7e0df6f166f18d Monotone-Author: ludovic@Sophos.ca Monotone-Date: 2008-11-10T15:38:05 Monotone-Branch: ca.inverse.sogomaint-2.0.2
parent
1b5c0ef81c
commit
312656117f
|
@ -1882,18 +1882,18 @@ static Class sogoAppointmentFolderKlass = Nil;
|
|||
NSArray *elements;
|
||||
NSString *method, *filename;
|
||||
SOGoAppointmentObject *apt;
|
||||
|
||||
|
||||
filename = [NSString stringWithFormat: @"%@.ics", [event uid]];
|
||||
apt = [SOGoAppointmentObject objectWithName: filename
|
||||
andContent: iCalString
|
||||
inContainer: self];
|
||||
method = [[event parent] method];
|
||||
if ([method isEqualToString: @"REQUEST"])
|
||||
elements = [apt postCalDAVEventRequestTo: recipients];
|
||||
elements = [apt postCalDAVEventRequestTo: recipients from: originator];
|
||||
else if ([method isEqualToString: @"REPLY"])
|
||||
elements = [apt postCalDAVEventReplyTo: recipients];
|
||||
elements = [apt postCalDAVEventReplyTo: recipients from: originator];
|
||||
else if ([method isEqualToString: @"CANCEL"])
|
||||
elements = [apt postCalDAVEventCancelTo: recipients];
|
||||
elements = [apt postCalDAVEventCancelTo: recipients from: originator];
|
||||
else
|
||||
elements = nil;
|
||||
|
||||
|
@ -1964,6 +1964,10 @@ static Class sogoAppointmentFolderKlass = Nil;
|
|||
if ([cType hasPrefix: @"text/calendar"])
|
||||
{
|
||||
originator = [request headerForKey: @"originator"];
|
||||
|
||||
if ([[originator lowercaseString] hasPrefix: @"mailto:"])
|
||||
originator = [originator substringFromIndex: 7];
|
||||
|
||||
recipients = [[request headerForKey: @"recipient"]
|
||||
componentsSeparatedByString: @", "];
|
||||
obj = [self caldavScheduleRequest: [request contentAsString]
|
||||
|
|
|
@ -48,11 +48,11 @@
|
|||
|
||||
- (NSException *) changeParticipationStatus: (NSString *) _status;
|
||||
|
||||
- (void) takeAttendeeStatus: (iCalPerson *) attendee;
|
||||
- (void) takeAttendeeStatus: (iCalPerson *) attendee from: (NSString *) originator;
|
||||
|
||||
- (NSArray *) postCalDAVEventRequestTo: (NSArray *) recipients;
|
||||
- (NSArray *) postCalDAVEventReplyTo: (NSArray *) recipients;
|
||||
- (NSArray *) postCalDAVEventCancelTo: (NSArray *) recipients;
|
||||
- (NSArray *) postCalDAVEventRequestTo: (NSArray *) recipients from: (NSString *) originator;
|
||||
- (NSArray *) postCalDAVEventReplyTo: (NSArray *) recipients from: (NSString *) originator;
|
||||
- (NSArray *) postCalDAVEventCancelTo: (NSArray *) recipients from: (NSString *) originator;
|
||||
|
||||
/* "iCal multifolder saves" */
|
||||
|
||||
|
|
|
@ -362,6 +362,17 @@
|
|||
[super saveComponent: newEvent];
|
||||
}
|
||||
|
||||
//
|
||||
// This method is used to update the status of an attendee.
|
||||
//
|
||||
// - theOwnerUser is owner of the calendar where the attendee
|
||||
// participation state has changed.
|
||||
// - uid is the actual UID of the user for whom we must
|
||||
// update the calendar event (with the participation change)
|
||||
//
|
||||
// This method is called multiple times, in order to update the
|
||||
// status of the attendee in calendars for the particular event UID.
|
||||
//
|
||||
- (NSException *) _updateAttendee: (iCalPerson *) attendee
|
||||
ownerUser: (SOGoUser *) theOwnerUser
|
||||
forEventUID: (NSString *) eventUID
|
||||
|
@ -409,14 +420,21 @@
|
|||
return error;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// This method is invoked only from the SOGo Web interface.
|
||||
//
|
||||
// - theOwnerUser is owner of the calendar where the attendee
|
||||
// participation state has changed.
|
||||
//
|
||||
- (NSException *) _handleAttendee: (iCalPerson *) attendee
|
||||
ownerUser: (SOGoUser *) theOwnerUser
|
||||
statusChange: (NSString *) newStatus
|
||||
inEvent: (iCalEvent *) event
|
||||
{
|
||||
NSString *newContent, *currentStatus, *currentUser, *organizerUID;
|
||||
NSException *ex;
|
||||
SOGoUser *ownerUser;
|
||||
NSException *ex;
|
||||
|
||||
ex = nil;
|
||||
|
||||
|
@ -442,14 +460,17 @@
|
|||
newContent = [[event parent] versitString];
|
||||
ex = [self saveContentString: newContent];
|
||||
|
||||
|
||||
// If the current user isn't the organizer of the event
|
||||
// that has just been updated, we update the event and
|
||||
// send a notification
|
||||
ownerUser = [SOGoUser userWithLogin: owner roles: nil];
|
||||
if (!(ex || [event userIsOrganizer: ownerUser]))
|
||||
{
|
||||
if ([[attendee rsvp] isEqualToString: @"true"]
|
||||
&& [event isStillRelevant])
|
||||
[self sendResponseToOrganizer: event];
|
||||
|
||||
[self sendResponseToOrganizer: event
|
||||
from: ownerUser];
|
||||
|
||||
organizerUID = [[event organizer] uid];
|
||||
if (organizerUID)
|
||||
ex = [self _updateAttendee: attendee
|
||||
|
@ -514,6 +535,7 @@
|
|||
}
|
||||
|
||||
- (NSArray *) postCalDAVEventRequestTo: (NSArray *) recipients
|
||||
from: (NSString *) originator
|
||||
{
|
||||
NSMutableArray *elements;
|
||||
NSEnumerator *recipientsEnum;
|
||||
|
@ -546,6 +568,7 @@
|
|||
}
|
||||
|
||||
- (NSArray *) postCalDAVEventCancelTo: (NSArray *) recipients
|
||||
from: (NSString *) originator
|
||||
{
|
||||
NSMutableArray *elements;
|
||||
NSEnumerator *recipientsEnum;
|
||||
|
@ -577,7 +600,19 @@
|
|||
return elements;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// This method is invoked by CalDAV clients such as
|
||||
// Mozilla Lightning. We assume the SENT-BY has
|
||||
// already been added, if required.
|
||||
//
|
||||
// It is used to updated the status of an attendee.
|
||||
// The originator is the actualy owner of the calendar
|
||||
// where the update took place. The status must then
|
||||
// be propagated to the organizer and the other attendees.
|
||||
//
|
||||
- (void) takeAttendeeStatus: (iCalPerson *) attendee
|
||||
from: (NSString *) originator
|
||||
{
|
||||
iCalPerson *localAttendee;
|
||||
iCalEvent *event;
|
||||
|
@ -595,17 +630,23 @@
|
|||
iCalPerson *att;
|
||||
NSString *uid;
|
||||
int i;
|
||||
|
||||
ownerUser = [SOGoUser userWithLogin:[[LDAPUserManager sharedUserManager]
|
||||
getUIDForEmail: originator]
|
||||
roles: nil];
|
||||
|
||||
// We update for the organizer
|
||||
ownerUser = [context activeUser];
|
||||
|
||||
[self _updateAttendee: attendee
|
||||
ownerUser: ownerUser
|
||||
forEventUID: [event uid]
|
||||
withSequence: [event sequence]
|
||||
forUID: [[SOGoUser userWithLogin: owner roles: nil] login]
|
||||
shouldAddSentBy: NO];
|
||||
|
||||
// We update the copy of the organizer, only
|
||||
// if it's a local user.
|
||||
#warning add a check for only local users
|
||||
uid = [[event organizer] uid];
|
||||
if (uid)
|
||||
[self _updateAttendee: attendee
|
||||
ownerUser: ownerUser
|
||||
forEventUID: [event uid]
|
||||
withSequence: [event sequence]
|
||||
forUID: uid
|
||||
shouldAddSentBy: NO];
|
||||
|
||||
attendees = [event attendees];
|
||||
|
||||
for (i = 0; i < [attendees count]; i++)
|
||||
|
@ -619,6 +660,12 @@
|
|||
|
||||
if (uid)
|
||||
{
|
||||
// We skip the update that correspond to the originator
|
||||
// since the CalDAV client will already have updated
|
||||
// the actual event.
|
||||
if ([ownerUser hasEmail: [att rfc822Email]])
|
||||
continue;
|
||||
|
||||
[self _updateAttendee: attendee
|
||||
ownerUser: ownerUser
|
||||
forEventUID: [event uid]
|
||||
|
@ -635,6 +682,7 @@
|
|||
}
|
||||
|
||||
- (NSArray *) postCalDAVEventReplyTo: (NSArray *) recipients
|
||||
from: (NSString *) originator
|
||||
{
|
||||
NSMutableArray *elements;
|
||||
NSEnumerator *recipientsEnum;
|
||||
|
@ -643,10 +691,15 @@
|
|||
iCalPerson *attendee, *person;
|
||||
SOGoAppointmentObject *recipientEvent;
|
||||
SOGoUser *ownerUser;
|
||||
NSString *email;
|
||||
|
||||
elements = [NSMutableArray array];
|
||||
event = [self component: NO secure: NO];
|
||||
ownerUser = [SOGoUser userWithLogin: owner roles: nil];
|
||||
//ownerUser = [SOGoUser userWithLogin: owner roles: nil];
|
||||
|
||||
ownerUser = [SOGoUser userWithLogin: [[LDAPUserManager sharedUserManager]
|
||||
getUIDForEmail: originator]
|
||||
roles: nil];
|
||||
attendee = [event findParticipant: ownerUser];
|
||||
eventUID = [event uid];
|
||||
|
||||
|
@ -663,9 +716,12 @@
|
|||
if ([recipientEvent isNew])
|
||||
[recipientEvent saveComponent: event];
|
||||
else
|
||||
[recipientEvent takeAttendeeStatus: attendee];
|
||||
[recipientEvent takeAttendeeStatus: attendee
|
||||
from: originator];
|
||||
}
|
||||
[self sendIMIPReplyForEvent: event to: person];
|
||||
[self sendIMIPReplyForEvent: event
|
||||
from: ownerUser
|
||||
to: person];
|
||||
[person release];
|
||||
[elements
|
||||
addObject: [self _caldavSuccessCodeWithRecipient: recipient]];
|
||||
|
@ -674,6 +730,9 @@
|
|||
return elements;
|
||||
}
|
||||
|
||||
//
|
||||
// This method is invoked only from the SOGo Web interface.
|
||||
//
|
||||
- (NSException *) changeParticipationStatus: (NSString *) _status
|
||||
{
|
||||
iCalEvent *event;
|
||||
|
@ -686,7 +745,13 @@
|
|||
event = [self component: NO secure: NO];
|
||||
if (event)
|
||||
{
|
||||
// owerUser will actually be the owner of the calendar
|
||||
// where the participation change on the event has
|
||||
// actually occured. The particpation change will of
|
||||
// course be on the attendee that is the owner of the
|
||||
// calendar where the participation change has occured.
|
||||
ownerUser = [SOGoUser userWithLogin: owner roles: nil];
|
||||
|
||||
attendee = [event findParticipant: ownerUser];
|
||||
if (attendee)
|
||||
ex = [self _handleAttendee: attendee
|
||||
|
|
|
@ -63,8 +63,10 @@
|
|||
forObject: (iCalRepeatableEntityObject *) object
|
||||
toAttendees: (NSArray *) attendees;
|
||||
- (void) sendIMIPReplyForEvent: (iCalRepeatableEntityObject *) event
|
||||
from: (SOGoUser *) from
|
||||
to: (iCalPerson *) recipient;
|
||||
- (void) sendResponseToOrganizer: (iCalRepeatableEntityObject *) newComponent;
|
||||
- (void) sendResponseToOrganizer: (iCalRepeatableEntityObject *) newComponent
|
||||
from: (SOGoUser *) owner;
|
||||
|
||||
// - (BOOL) isOrganizerOrOwner: (SOGoUser *) user;
|
||||
|
||||
|
|
|
@ -583,6 +583,7 @@ _occurenceHasID (iCalRepeatableEntityObject *occurence, NSString *recID)
|
|||
|
||||
#warning fix this when sendEmailUsing blabla has been cleaned up
|
||||
- (void) sendIMIPReplyForEvent: (iCalRepeatableEntityObject *) event
|
||||
from: (SOGoUser *) from
|
||||
to: (iCalPerson *) recipient
|
||||
{
|
||||
NSString *pageName, *language, *mailDate, *email;
|
||||
|
@ -602,7 +603,8 @@ _occurenceHasID (iCalRepeatableEntityObject *occurence, NSString *recID)
|
|||
/* get WOApplication instance */
|
||||
app = [WOApplication application];
|
||||
|
||||
ownerUser = [SOGoUser userWithLogin: owner roles: nil];
|
||||
//ownerUser = [SOGoUser userWithLogin: owner roles: nil];
|
||||
ownerUser = from;
|
||||
language = [ownerUser language];
|
||||
/* create page name */
|
||||
pageName
|
||||
|
@ -672,6 +674,7 @@ _occurenceHasID (iCalRepeatableEntityObject *occurence, NSString *recID)
|
|||
}
|
||||
|
||||
- (void) sendResponseToOrganizer: (iCalRepeatableEntityObject *) newComponent
|
||||
from: (SOGoUser *) from
|
||||
{
|
||||
iCalPerson *organizer, *attendee;
|
||||
iCalEvent *event;
|
||||
|
@ -684,7 +687,7 @@ _occurenceHasID (iCalRepeatableEntityObject *occurence, NSString *recID)
|
|||
organizer = [event organizer];
|
||||
attendee = [event findParticipant: ownerUser];
|
||||
[event setAttendees: [NSArray arrayWithObject: attendee]];
|
||||
[self sendIMIPReplyForEvent: event to: organizer];
|
||||
[self sendIMIPReplyForEvent: event from: from to: organizer];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* UIxMailPartICalActions.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2007 Inverse inc.
|
||||
* Copyright (C) 2007-2008 Inverse inc.
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
@ -36,6 +36,7 @@
|
|||
|
||||
#import <NGImap4/NGImap4EnvelopeAddress.h>
|
||||
|
||||
#import <SoObjects/Appointments/iCalEvent+SOGo.h>
|
||||
#import <SoObjects/Appointments/iCalPerson+SOGo.h>
|
||||
#import <SoObjects/Appointments/SOGoAppointmentObject.h>
|
||||
#import <SoObjects/Appointments/SOGoAppointmentFolder.h>
|
||||
|
@ -168,16 +169,18 @@
|
|||
|
||||
#warning this is code copied from SOGoAppointmentObject...
|
||||
- (void) _updateAttendee: (iCalPerson *) attendee
|
||||
withSequence: (NSNumber *) sequence
|
||||
andCalUID: (NSString *) calUID
|
||||
forUID: (NSString *) uid
|
||||
ownerUser: (SOGoUser *) theOwnerUser
|
||||
forEventUID: (NSString *) eventUID
|
||||
withSequence: (NSNumber *) sequence
|
||||
forUID: (NSString *) uid
|
||||
shouldAddSentBy: (BOOL) b
|
||||
{
|
||||
SOGoAppointmentObject *eventObject;
|
||||
iCalEvent *event;
|
||||
iCalPerson *otherAttendee;
|
||||
NSString *iCalString;
|
||||
|
||||
eventObject = [self _eventObjectWithUID: calUID
|
||||
eventObject = [self _eventObjectWithUID: eventUID
|
||||
forUser: [SOGoUser userWithLogin: uid roles: nil]];
|
||||
if (![eventObject isNew])
|
||||
{
|
||||
|
@ -185,9 +188,22 @@
|
|||
if ([[event sequence] compare: sequence]
|
||||
== NSOrderedSame)
|
||||
{
|
||||
otherAttendee
|
||||
= [event findParticipantWithEmail: [attendee rfc822Email]];
|
||||
SOGoUser *currentUser;
|
||||
|
||||
otherAttendee = [event findParticipant: theOwnerUser];
|
||||
[otherAttendee setPartStat: [attendee partStat]];
|
||||
|
||||
// If one has accepted / declined an invitation on behalf of
|
||||
// the attendee, we add the user to the SENT-BY attribute.
|
||||
currentUser = [context activeUser];
|
||||
if (b && ![[currentUser login] isEqualToString: [theOwnerUser login]])
|
||||
{
|
||||
NSString *currentEmail;
|
||||
currentEmail = [[currentUser allEmails] objectAtIndex: 0];
|
||||
[otherAttendee addAttribute: @"SENT-BY"
|
||||
value: [NSString stringWithFormat: @"\"MAILTO:%@\"", currentEmail]];
|
||||
}
|
||||
|
||||
iCalString = [[event parent] versitString];
|
||||
[eventObject saveContentString: iCalString];
|
||||
}
|
||||
|
@ -219,12 +235,50 @@
|
|||
else
|
||||
rsvp = nil;
|
||||
[eventObject saveContentString: [calendar versitString]];
|
||||
if ([rsvp isEqualToString: @"true"])
|
||||
[eventObject sendResponseToOrganizer: chosenEvent];
|
||||
if ([rsvp isEqualToString: @"true"] &&
|
||||
[chosenEvent isStillRelevant])
|
||||
[eventObject sendResponseToOrganizer: chosenEvent
|
||||
from: [context activeUser]];
|
||||
organizerUID = [[chosenEvent organizer] uid];
|
||||
if (organizerUID)
|
||||
[self _updateAttendee: user withSequence: [chosenEvent sequence]
|
||||
andCalUID: [chosenEvent uid] forUID: organizerUID];
|
||||
[self _updateAttendee: user
|
||||
ownerUser: [context activeUser]
|
||||
forEventUID: [chosenEvent uid]
|
||||
withSequence: [chosenEvent sequence]
|
||||
forUID: organizerUID
|
||||
shouldAddSentBy: YES];
|
||||
|
||||
// We update the calendar of all participants that are
|
||||
// local to the system. This is useful in case user A accepts
|
||||
// invitation from organizer B and users C, D, E who are also
|
||||
// attendees need to verify if A has accepted.
|
||||
NSArray *attendees;
|
||||
iCalPerson *att;
|
||||
NSString *uid;
|
||||
int i;
|
||||
|
||||
attendees = [chosenEvent attendees];
|
||||
|
||||
for (i = 0; i < [attendees count]; i++)
|
||||
{
|
||||
att = [attendees objectAtIndex: i];
|
||||
|
||||
if (att == user) continue;
|
||||
|
||||
uid = [[LDAPUserManager sharedUserManager]
|
||||
getUIDForEmail: [att rfc822Email]];
|
||||
|
||||
if (uid)
|
||||
{
|
||||
[self _updateAttendee: user
|
||||
ownerUser: [context activeUser]
|
||||
forEventUID: [chosenEvent uid]
|
||||
withSequence: [chosenEvent sequence]
|
||||
forUID: uid
|
||||
shouldAddSentBy: YES];
|
||||
}
|
||||
}
|
||||
|
||||
response = [self responseWith204];
|
||||
}
|
||||
else
|
||||
|
|
Loading…
Reference in New Issue