Monotone-Parent: 0cec38c2db19c72bdff0ec74c3b4141bdc6cfeb4

Monotone-Revision: 383366b73218cb743a0be1ecef654d1c6aabd0a5

Monotone-Author: flachapelle@inverse.ca
Monotone-Date: 2008-12-09T15:29:39
Monotone-Branch: ca.inverse.sogo
maint-2.0.2
Francis Lachapelle 2008-12-09 15:29:39 +00:00
parent cfb24466be
commit 0ce1d4ed63
4 changed files with 164 additions and 94 deletions

View File

@ -1,3 +1,21 @@
2008-12-09 Francis Lachapelle <flachapelle@inverse.ca>
* SoObjects/Appointments/SOGoAppointmentObject.m
([SOGoAppointmentObject -_handleUpdatedEvent:fromOldEvent:]): if
the sequence doesn't change, attendees will no longer receive a
notification by email.
([SOGoAppointmentObject
-_updateAttendee:ownerUser:forEventUID:withRecurrenceId:withSequence:forUID:shouldAddSentBy:]):
if an attendee accepts all events, on the master event of a
repeating event will be updated; occurrences will no longer be affected.
([SOGoAppointmentObject -postCalDAVEventRequestTo:from:]): when
dealing with an occurrence of a repeating event, the function now
proprly update each attendee's calendar.
([SOGoAppointmentObject
-takeAttendeeStatus:from:withRecurrenceId:]): fixed handling of an
occurrence of a repeating event.
([SOGoAppointmentObject -postCalDAVEventReplyTo:from:]): idem.
2008-12-08 Ludovic Marcotte <lmarcotte@inverse.ca>
* SoObjects/Appointments/SOGoAppointmentFolder.m
@ -14,17 +32,17 @@
* SoObjects/Appointments/SOGoAppointmentObject.m
([SOGoAppointmentObject
_removeEventFromUID:owner:withRecurrenceId:]): for a repeating
-_removeEventFromUID:owner:withRecurrenceId:]): for a repeating
event, the occurrence was not properly removed.
* SoObjects/Appointments/SOGoComponentOccurence.m
([SOGoComponentOccurence prepareDelete]): for a repeating event,
([SOGoComponentOccurence -prepareDelete]): for a repeating event,
the exception date was not added and the occurence was not
properly deleted.
* UI/MailPartViewers/UIxMailPartICalViewer.m
([UIxMailPartICalViewer isEventStoredInCalendar]): when dealing
with an occurence of a repeating event, the function now properly
([UIxMailPartICalViewer -isEventStoredInCalendar]): when dealing
with an occurrence of a repeating event, the function now properly
verify the presence of the occurence and not only the event.
2008-12-05 Ludovic Marcotte <lmarcotte@inverse.ca>

View File

@ -118,11 +118,11 @@
[dateTime release];
}
- (void) setExceptionDates: (NSArray *) _rdates
{
[children removeObjectsInArray: [self childrenWithTag: @"exdate"]];
[self addChildren: _rdates];
}
//- (void) setExceptionDates: (NSArray *) _rdates
//{
// [children removeObjectsInArray: [self childrenWithTag: @"exdate"]];
// [self addChildren: _rdates];
//}
- (BOOL) hasExceptionDates
{

View File

@ -50,7 +50,9 @@
- (NSException *) changeParticipationStatus: (NSString *) _status
forRecurrenceId: (NSCalendarDate *) _recurrenceId;
- (void) takeAttendeeStatus: (iCalPerson *) attendee from: (NSString *) originator;
- (void) takeAttendeeStatus: (iCalPerson *) attendee
from: (NSString *) originator
withRecurrenceId: (NSCalendarDate*) recurrenceId;
- (NSArray *) postCalDAVEventRequestTo: (NSArray *) recipients from: (NSString *) originator;
- (NSArray *) postCalDAVEventReplyTo: (NSArray *) recipients from: (NSString *) originator;

View File

@ -162,8 +162,8 @@
SOGoAppointmentObject *object;
NSString *possibleName;
folder = [container lookupCalendarFolderForUID: uid];
#warning Should call lookupCalendarFoldersForUIDs to search among all folders
folder = [container lookupCalendarFolderForUID: uid];
object = [folder lookupName: nameInContainer
inContext: context acquire: NO];
if ([object isKindOfClass: [NSException class]])
@ -221,6 +221,7 @@
NSString *calendarContent;
int max, count;
#warning Should call lookupCalendarFoldersForUIDs to search among all folders
folder = [container lookupCalendarFolderForUID: theUID];
object = [folder lookupName: nameInContainer
inContext: context acquire: NO];
@ -364,16 +365,16 @@
if ([changes sequenceShouldBeIncreased])
{
[newEvent increaseSequence];
// Set new attendees status to "needs action"
[self _requireResponseFromAttendees: [newEvent attendees]];
// Update attendees calendars and send them an update
// notification by email
[self _handleSequenceUpdateInEvent: newEvent
ignoringAttendees: attendees
fromOldEvent: oldEvent];
}
else
{
// Set new attendees status to "needs action"
[self _requireResponseFromAttendees: attendees];
// If other attributes have changed, update the event
// in each attendee's calendar
if ([[changes updatedProperties] count])
@ -487,7 +488,6 @@
iCalCalendar *calendar;
iCalEntityObject *event;
iCalPerson *otherAttendee;
NSArray *events;
NSString *iCalString, *recurrenceTime;
NSException *error;
@ -501,7 +501,7 @@
// We must update main event and all its occurences (if any).
calendar = [eventObject calendar: NO secure: NO];
event = (iCalEntityObject*)[calendar firstChildWithTag: [self componentTag]];
events = [calendar allObjects];
//events = [calendar allObjects];
}
else
{
@ -513,48 +513,41 @@
if (event == nil)
// If no occurence found, create one
event = [eventObject newOccurenceWithID: recurrenceTime];
events = [NSArray arrayWithObject: event];
}
if ([[event sequence] compare: sequence]
== NSOrderedSame)
{
SOGoUser *currentUser;
int i;
currentUser = [context activeUser];
otherAttendee = [event findParticipant: theOwnerUser];
[otherAttendee setPartStat: [attendee partStat]];
for (i = 0; i < [events count]; i++)
// If one has accepted / declined an invitation on behalf of
// the attendee, we add the user to the SENT-BY attribute.
if (b && ![[currentUser login] isEqualToString: [theOwnerUser login]])
{
event = [events objectAtIndex: i];
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.
if (b && ![[currentUser login] isEqualToString: [theOwnerUser login]])
{
NSString *currentEmail;
currentEmail = [[currentUser allEmails] objectAtIndex: 0];
[otherAttendee addAttribute: @"SENT-BY"
value: [NSString stringWithFormat: @"\"MAILTO:%@\"", currentEmail]];
}
else
{
// We must REMOVE any SENT-BY here. This is important since if A accepted
// the event for B and then, B changes by himself his participation status,
// we don't want to keep the previous SENT-BY attribute there.
[(NSMutableDictionary *)[otherAttendee attributes] removeObjectForKey: @"SENT-BY"];
}
NSString *currentEmail;
currentEmail = [[currentUser allEmails] objectAtIndex: 0];
[otherAttendee addAttribute: @"SENT-BY"
value: [NSString stringWithFormat: @"\"MAILTO:%@\"", currentEmail]];
}
else
{
// We must REMOVE any SENT-BY here. This is important since if A accepted
// the event for B and then, B changes by himself his participation status,
// we don't want to keep the previous SENT-BY attribute there.
[(NSMutableDictionary *)[otherAttendee attributes] removeObjectForKey: @"SENT-BY"];
}
iCalString = [[event parent] versitString];
error = [eventObject saveContentString: iCalString];
}
// We generate the updated iCalendar file and we save it
// in the database.
iCalString = [[event parent] versitString];
error = [eventObject saveContentString: iCalString];
}
return error;
}
@ -623,6 +616,7 @@
organizerUID = [[(iCalEntityObject*)[[event parent] firstChildWithTag: [self componentTag]] organizer] uid];
if (organizerUID)
// Update the attendee in organizer's calendar.
ex = [self _updateAttendee: attendee
ownerUser: theOwnerUser
forEventUID: [event uid]
@ -699,13 +693,15 @@
{
NSMutableArray *elements;
NSEnumerator *recipientsEnum;
NSString *recipient, *uid;
NSString *recipient, *uid, *ownerUID;
iCalEvent *event, *oldEvent;
iCalPerson *person;
BOOL isUpdate, hasChanged;
elements = [NSMutableArray array];
ownerUID = [[LDAPUserManager sharedUserManager]
getUIDForEmail: originator];
event = [self component: NO secure: NO];
recipientsEnum = [recipients objectEnumerator];
while ((recipient = [recipientsEnum nextObject]))
@ -722,24 +718,65 @@
{
// We check if we must send an invitation update
// rather than just a normal invitation
NSString *iCalString;
SOGoAppointmentObject *oldEventObject;
iCalEventChanges *changes;
oldEventObject = [self _lookupEvent: [event uid] forUID: uid];
oldEvent = [oldEventObject component: NO secure: NO];
changes = [event getChangesRelativeToEvent: oldEvent];
if ([[oldEvent sequence] compare: [event sequence]] != NSOrderedSame)
if (![oldEventObject isNew])
{
if ([changes sequenceShouldBeIncreased])
isUpdate = YES;
// We are updating an existing event.
// If the event containts a recurrence-id, replace the proper
// occurrence of the recurrent event.
iCalCalendar *calendar;
iCalEvent *currentOccurence;
iCalEventChanges *changes;
NSArray *occurences;
NSCalendarDate *recurrenceId, *currentId;
NSString *recurrenceTime;
unsigned int i;
calendar = [oldEventObject calendar: NO secure: NO];
recurrenceId = [event recurrenceId];
if (recurrenceId == nil)
oldEvent = [oldEventObject component: NO secure: NO];
else
hasChanged = NO;
{
// If recurrenceId is defined, find the specified occurence
// within the repeating vEvent and replace it.
occurences = [calendar events];
for (i = 1; i< [occurences count]; i++)
{
currentOccurence = [occurences objectAtIndex: i];
currentId = [currentOccurence recurrenceId];
if ([currentId compare: recurrenceId] == NSOrderedSame)
{
[[calendar children] removeObject: currentOccurence];
oldEvent = currentOccurence;
break;
}
}
// Add the event as a new occurrence, without the organizer.
[event setOrganizer: nil];
[calendar addChild: event];
}
// Identify changes in order to send a notification to the attendee
// if necessary and with the proper template.
changes = [event getChangesRelativeToEvent: oldEvent];
if ([[oldEvent sequence] compare: [event sequence]] != NSOrderedSame)
{
if ([changes sequenceShouldBeIncreased])
isUpdate = YES;
else
hasChanged = NO;
}
}
[self _addOrUpdateEvent: event
forUID: uid
owner: [[LDAPUserManager sharedUserManager]
getUIDForEmail: originator]];
// We generate the updated iCalendar file and we save it
// in the database.
iCalString = [[event parent] versitString];
[oldEventObject saveContentString: iCalString];
}
#warning fix this when sendEmailUsing blabla has been cleaned up
if (hasChanged)
@ -764,12 +801,14 @@
{
NSMutableArray *elements;
NSEnumerator *recipientsEnum;
NSString *recipient, *uid;
NSString *recipient, *ownerUID, *uid;
iCalEvent *event;
iCalPerson *person;
elements = [NSMutableArray array];
ownerUID = [[LDAPUserManager sharedUserManager]
getUIDForEmail: originator];
event = [self component: NO secure: NO];
recipientsEnum = [recipients objectEnumerator];
while ((recipient = [recipientsEnum nextObject]))
@ -780,8 +819,7 @@
uid = [person uid];
if (uid)
[self _removeEventFromUID: uid
owner: [[LDAPUserManager sharedUserManager]
getUIDForEmail: originator]
owner: ownerUID
withRecurrenceId: [event recurrenceId]];
#warning fix this when sendEmailUsing blabla has been cleaned up
[self sendEMailUsingTemplateNamed: @"Deletion"
@ -808,42 +846,54 @@
// be propagated to the organizer and the other attendees.
//
- (void) takeAttendeeStatus: (iCalPerson *) attendee
from: (NSString *) originator
from: (NSString *) ownerUser
withRecurrenceId: (NSCalendarDate*) recurrenceId
{
iCalPerson *localAttendee;
iCalEvent *event;
SOGoUser *ownerUser;
NSString *recurrenceTime;
event = [self component: NO secure: NO];
if (recurrenceId == nil)
// We must update the master event only.
event = [self component: NO secure: NO];
else
{
// If recurrenceId is defined, find the specified occurence
// within the repeating vEvent.
recurrenceTime = [NSString stringWithFormat: @"%f", [recurrenceId timeIntervalSince1970]];
event = [self lookupOccurence: recurrenceTime];
if (event == nil)
// If no occurence found, create one
event = [self newOccurenceWithID: recurrenceTime];
}
// Find attendee within event
localAttendee = [event findParticipantWithEmail: [attendee rfc822Email]];
if (localAttendee)
{
// Update the attendee's status
[localAttendee setPartStat: [attendee partStat]];
[self saveComponent: event];
/// TEST ///
NSArray *attendees;
iCalPerson *att;
NSString *uid;
int i;
ownerUser = [SOGoUser userWithLogin:[[LDAPUserManager sharedUserManager]
getUIDForEmail: originator]
roles: nil];
// We update the copy of the organizer, only
// if it's a local user.
NSArray *attendees;
iCalPerson *att;
NSString *uid;
int i;
// 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]
withRecurrenceId: [event recurrenceId]
withSequence: [event sequence]
forUID: uid
shouldAddSentBy: NO];
uid = [[event organizer] uid];
if (uid)
[self _updateAttendee: attendee
ownerUser: ownerUser
forEventUID: [event uid]
withRecurrenceId: [event recurrenceId]
withSequence: [event sequence]
forUID: uid
shouldAddSentBy: NO];
attendees = [event attendees];
for (i = 0; i < [attendees count]; i++)
@ -854,15 +904,15 @@
uid = [[LDAPUserManager sharedUserManager]
getUIDForEmail: [att rfc822Email]];
if (uid)
{
// We skip the update that correspond to the originator
// We skip the update that correspond to the owner
// 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]
@ -872,8 +922,6 @@
shouldAddSentBy: NO];
}
}
/// TEST ///
}
else
[self errorWithFormat: @"attendee not found: '%@'", attendee];
@ -892,7 +940,6 @@
elements = [NSMutableArray array];
event = [self component: NO secure: NO];
//ownerUser = [SOGoUser userWithLogin: owner roles: nil];
ownerUser = [SOGoUser userWithLogin: [[LDAPUserManager sharedUserManager]
getUIDForEmail: originator]
@ -914,8 +961,11 @@
[recipientEvent saveComponent: event];
else
[recipientEvent takeAttendeeStatus: attendee
from: originator];
from: ownerUser
withRecurrenceId: [event recurrenceId]];
}
// Send reply to recipient/organizer
[self sendIMIPReplyForEvent: event
from: ownerUser
to: person];