From c7be84d277898e43ba3303514824e8eabda3bb1a Mon Sep 17 00:00:00 2001 From: Wolfgang Sourdeau Date: Mon, 19 Mar 2012 19:26:11 +0000 Subject: [PATCH] Monotone-Parent: 86cef533a03be060bfad13566c4f0b2802481e87 Monotone-Revision: 0ad0dd5ada272b8cb3b3ec56737e667ebeccd725 Monotone-Author: wsourdeau@inverse.ca Monotone-Date: 2012-03-19T19:26:11 Monotone-Branch: ca.inverse.sogo --- ChangeLog | 5 + OpenChange/MAPIStoreCalendarMessage.m | 342 +++++++++++++------------- 2 files changed, 174 insertions(+), 173 deletions(-) diff --git a/ChangeLog b/ChangeLog index d1ef62a77..dfff79101 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,10 @@ 2012-03-19 Wolfgang Sourdeau + * OpenChange/MAPIStoreCalendarMessage.m (-save): check recipients + even if PidLidAppointmentStateFlags is nil or 0, since all that + matters is that the "recipients" dict be present in the properties + dictionary. + * OpenChange/SOGoMAPIFSMessage.m (-init): init 2 new ivars: fileSize and lastModificationTime. (-properties): check the current file size and last modification diff --git a/OpenChange/MAPIStoreCalendarMessage.m b/OpenChange/MAPIStoreCalendarMessage.m index 3c657b47d..150838384 100644 --- a/OpenChange/MAPIStoreCalendarMessage.m +++ b/OpenChange/MAPIStoreCalendarMessage.m @@ -863,200 +863,196 @@ withEvent: newEvent fromData: value]; - [newEvent setOrganizer: nil]; - [newEvent removeAllAttendees]; - /* alarm */ [self _setupAlarmDataInEvent: newEvent]; - if ([[properties objectForKey: MAPIPropertyKey (PidLidAppointmentStateFlags)] intValue] - != 0) + // Organizer + value = [properties objectForKey: @"recipients"]; + if (value) { - // Organizer - value = [properties objectForKey: @"recipients"]; - if (value) + NSArray *recipients; + NSDictionary *dict; + NSString *orgEmail, *sentBy, *attEmail; + iCalPerson *person; + iCalPersonPartStat newPartStat; + NSNumber *flags, *trackStatus; + int i, effective; + BOOL organizerIsSet = NO; + + [newEvent setOrganizer: nil]; + [newEvent removeAllAttendees]; + + recipients = [value objectForKey: @"to"]; + effective = 0; + for (i = 0; i < [recipients count]; i++) { - NSArray *recipients; - NSDictionary *dict; - NSString *orgEmail, *sentBy, *attEmail; - iCalPerson *person; - iCalPersonPartStat newPartStat; - NSNumber *flags, *trackStatus; - int i, effective; - BOOL organizerIsSet = NO; - - recipients = [value objectForKey: @"to"]; - effective = 0; - for (i = 0; i < [recipients count]; i++) - { - dict = [recipients objectAtIndex: i]; - person = [iCalPerson new]; - [person setCn: [dict objectForKey: @"fullName"]]; - attEmail = [dict objectForKey: @"email"]; - [person setEmail: attEmail]; + dict = [recipients objectAtIndex: i]; + person = [iCalPerson new]; + [person setCn: [dict objectForKey: @"fullName"]]; + attEmail = [dict objectForKey: @"email"]; + [person setEmail: attEmail]; - flags = [dict objectForKey: MAPIPropertyKey (PR_RECIPIENT_FLAGS)]; - if (!flags) - { - [self logWithFormat: - @"no recipient flags specified: skipping recipient"]; - continue; - } - - if (([flags unsignedIntValue] & 0x0002)) /* recipOrganizer */ - { - [newEvent setOrganizer: person]; - organizerIsSet = YES; - [self logWithFormat: @"organizer set via recipient flags"]; - } - else - { - BOOL isOrganizer = NO; - - // /* Work-around: it happens that Outlook still passes the - // organizer as a recipient, maybe because of a feature - // documented in a pre-mesozoic PDF still buried in a - // cavern... In that case we remove it, and we keep the - // number of effective recipients in "effective". If the - // total is 0, we remove the "ORGANIZER" too. */ - // if ([attEmail isEqualToString: orgEmail]) - // { - // [self logWithFormat: - // @"avoiding setting organizer as recipient"]; - // continue; - // } - - trackStatus = [dict objectForKey: MAPIPropertyKey (PidTagRecipientTrackStatus)]; - if (trackStatus) - { - /* FIXME: we should provide a data converter between OL - partstats and SOGo */ - switch ([trackStatus unsignedIntValue]) - { - case 0x01: /* respOrganized */ - isOrganizer = YES; - break; - case 0x02: /* respTentative */ - newPartStat = iCalPersonPartStatTentative; - break; - case 0x03: /* respAccepted */ - newPartStat = iCalPersonPartStatAccepted; - break; - case 0x04: /* respDeclined */ - newPartStat = iCalPersonPartStatDeclined; - break; - default: - newPartStat = iCalPersonPartStatNeedsAction; - } - - if (isOrganizer) - { - [newEvent setOrganizer: person]; - organizerIsSet = YES; - [self logWithFormat: @"organizer set via track status"]; - } - else - { - [person setParticipationStatus: newPartStat]; - [person setRsvp: @"TRUE"]; - [person setRole: @"REQ-PARTICIPANT"]; - [newEvent addToAttendees: person]; - effective++; - } - } - else - [self errorWithFormat: @"skipped recipient due" - @" to missing track status"]; - } - - [person release]; + flags = [dict objectForKey: MAPIPropertyKey (PR_RECIPIENT_FLAGS)]; + if (!flags) + { + [self logWithFormat: + @"no recipient flags specified: skipping recipient"]; + continue; } - if (effective == 0) /* See work-around above */ - [newEvent setOrganizer: nil]; + if (([flags unsignedIntValue] & 0x0002)) /* recipOrganizer */ + { + [newEvent setOrganizer: person]; + organizerIsSet = YES; + [self logWithFormat: @"organizer set via recipient flags"]; + } else { - ownerUser = [[self userContext] sogoUser]; - if (organizerIsSet) + BOOL isOrganizer = NO; + + // /* Work-around: it happens that Outlook still passes the + // organizer as a recipient, maybe because of a feature + // documented in a pre-mesozoic PDF still buried in a + // cavern... In that case we remove it, and we keep the + // number of effective recipients in "effective". If the + // total is 0, we remove the "ORGANIZER" too. */ + // if ([attEmail isEqualToString: orgEmail]) + // { + // [self logWithFormat: + // @"avoiding setting organizer as recipient"]; + // continue; + // } + + trackStatus = [dict objectForKey: MAPIPropertyKey (PidTagRecipientTrackStatus)]; + if (trackStatus) { - /* We must reset the participation status to the value - obtained from PidLidResponseStatus as the value in - PidTagRecipientTrackStatus is not correct. Note (hack): - the method used here requires that the user directory - from LDAP and Samba matches perfectly. This can be solved - more appropriately by making use of the sender - properties... */ - person = [newEvent userAsAttendee: ownerUser]; - if (person) + /* FIXME: we should provide a data converter between OL + partstats and SOGo */ + switch ([trackStatus unsignedIntValue]) + { + case 0x01: /* respOrganized */ + isOrganizer = YES; + break; + case 0x02: /* respTentative */ + newPartStat = iCalPersonPartStatTentative; + break; + case 0x03: /* respAccepted */ + newPartStat = iCalPersonPartStatAccepted; + break; + case 0x04: /* respDeclined */ + newPartStat = iCalPersonPartStatDeclined; + break; + default: + newPartStat = iCalPersonPartStatNeedsAction; + } + + if (isOrganizer) + { + [newEvent setOrganizer: person]; + organizerIsSet = YES; + [self logWithFormat: @"organizer set via track status"]; + } + else { - value - = [properties objectForKey: MAPIPropertyKey (PidLidResponseStatus)]; - if (value) - responseStatus = [value unsignedLongValue]; - - /* FIXME: we should provide a data converter between OL partstats and - SOGo */ - switch (responseStatus) - { - case 0x02: /* respTentative */ - newPartStat = iCalPersonPartStatTentative; - break; - case 0x03: /* respAccepted */ - newPartStat = iCalPersonPartStatAccepted; - break; - case 0x04: /* respDeclined */ - newPartStat = iCalPersonPartStatDeclined; - break; - default: - newPartStat = iCalPersonPartStatNeedsAction; - } [person setParticipationStatus: newPartStat]; - newParticipationStatus = [person partStatWithDefault]; - - // if (newPartStat // != iCalPersonPartStatUndefined - // ) - // { - // // iCalPerson *participant; - - // // participant = [newEvent userAsAttendee: ownerUser]; - // // [participant setParticipationStatus: newPartStat]; - // // [sogoObject saveComponent: newEvent]; - - // [sogoObject changeParticipationStatus: newPartStat - // withDelegate: nil]; - // // [[self context] tearDownRequest]; - // } - // // }1005 - - // // else - // // { + [person setRsvp: @"TRUE"]; + [person setRole: @"REQ-PARTICIPANT"]; + [newEvent addToAttendees: person]; + effective++; } } else + [self errorWithFormat: @"skipped recipient due" + @" to missing track status"]; + } + + [person release]; + } + + if (effective == 0) /* See work-around above */ + [newEvent setOrganizer: nil]; + else + { + ownerUser = [[self userContext] sogoUser]; + if (organizerIsSet) + { + /* We must reset the participation status to the value + obtained from PidLidResponseStatus as the value in + PidTagRecipientTrackStatus is not correct. Note (hack): + the method used here requires that the user directory + from LDAP and Samba matches perfectly. This can be solved + more appropriately by making use of the sender + properties... */ + person = [newEvent userAsAttendee: ownerUser]; + if (person) { - [self errorWithFormat: @"organizer was not set although a" - @" recipient list was specified"]; - /* We must set the organizer preliminarily here because, unlike what - the doc states, Outlook does not always pass the real organizer - in the recipients list. */ - dict = [ownerUser primaryIdentity]; - person = [iCalPerson new]; - [person setCn: [dict objectForKey: @"fullName"]]; - orgEmail = [dict objectForKey: @"email"]; - [person setEmail: orgEmail]; - - activeUser = [[self context] activeUser]; - if (![activeUser isEqual: ownerUser]) + value + = [properties objectForKey: MAPIPropertyKey (PidLidResponseStatus)]; + if (value) + responseStatus = [value unsignedLongValue]; + + /* FIXME: we should provide a data converter between OL partstats and + SOGo */ + switch (responseStatus) { - dict = [activeUser primaryIdentity]; - sentBy = [NSString stringWithFormat: @"mailto:%@", - [dict objectForKey: @"email"]]; - [person setSentBy: sentBy]; + case 0x02: /* respTentative */ + newPartStat = iCalPersonPartStatTentative; + break; + case 0x03: /* respAccepted */ + newPartStat = iCalPersonPartStatAccepted; + break; + case 0x04: /* respDeclined */ + newPartStat = iCalPersonPartStatDeclined; + break; + default: + newPartStat = iCalPersonPartStatNeedsAction; } - [newEvent setOrganizer: person]; - [person release]; + [person setParticipationStatus: newPartStat]; + newParticipationStatus = [person partStatWithDefault]; + + // if (newPartStat // != iCalPersonPartStatUndefined + // ) + // { + // // iCalPerson *participant; + + // // participant = [newEvent userAsAttendee: ownerUser]; + // // [participant setParticipationStatus: newPartStat]; + // // [sogoObject saveComponent: newEvent]; + + // [sogoObject changeParticipationStatus: newPartStat + // withDelegate: nil]; + // // [[self context] tearDownRequest]; + // } + // // }1005 + + // // else + // // { } } + else + { + [self errorWithFormat: @"organizer was not set although a" + @" recipient list was specified"]; + /* We must set the organizer preliminarily here because, unlike what + the doc states, Outlook does not always pass the real organizer + in the recipients list. */ + dict = [ownerUser primaryIdentity]; + person = [iCalPerson new]; + [person setCn: [dict objectForKey: @"fullName"]]; + orgEmail = [dict objectForKey: @"email"]; + [person setEmail: orgEmail]; + + activeUser = [[self context] activeUser]; + if (![activeUser isEqual: ownerUser]) + { + dict = [activeUser primaryIdentity]; + sentBy = [NSString stringWithFormat: @"mailto:%@", + [dict objectForKey: @"email"]]; + [person setSentBy: sentBy]; + } + [newEvent setOrganizer: person]; + [person release]; + } } }