Monotone-Parent: cb5283601b9539bb382aa64a739bf758b9e2ac7f

Monotone-Revision: e064a5558d641325b03001de47cede6db61eed32

Monotone-Author: wsourdeau@inverse.ca
Monotone-Date: 2011-10-03T20:55:02
Monotone-Branch: ca.inverse.sogo
maint-2.0.2
Wolfgang Sourdeau 2011-10-03 20:55:02 +00:00
parent 88a5fec753
commit 132987d8bc
8 changed files with 793 additions and 56 deletions

View File

@ -25,11 +25,15 @@
#import <Foundation/NSObject.h>
#import <Appointments/iCalEntityObject+SOGo.h>
@class NSTimeZone;
@class iCalCalendar;
@class iCalEvent;
@class SOGoUser;
extern NSTimeZone *utcTZ;
@interface MAPIStoreAppointmentWrapper : NSObject
@ -39,17 +43,38 @@ extern NSTimeZone *utcTZ;
NSTimeZone *timeZone;
NSData *globalObjectId;
NSData *cleanGlobalObjectId;
SOGoUser *user;
}
+ (id) wrapperWithICalEvent: (iCalEvent *) newEvent
andUser: (SOGoUser *) newUser
inTimeZone: (NSTimeZone *) newTimeZone;
- (id) initWithICalEvent: (iCalEvent *) newEvent
andUser: (SOGoUser *) newUser
inTimeZone: (NSTimeZone *) newTimeZone;
/* getters */
- (void) fillMessageData: (struct mapistore_message *) dataPtr
inMemCtx: (TALLOC_CTX *) memCtx;
- (int) getPrSenderEmailAddress: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx;
- (int) getPrSenderAddrtype: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx;
- (int) getPrSenderName: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx;
- (int) getPrSenderEntryid: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx;
- (int) getPrReceivedByAddrtype: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx;
- (int) getPrReceivedByEmailAddress: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx;
- (int) getPrReceivedByName: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx;
- (int) getPrReceivedByEntryid: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx;
- (int) getPrIconIndex: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx;
- (int) getPrOwnerApptId: (void **) data
@ -64,6 +89,9 @@ extern NSTimeZone *utcTZ;
inMemCtx: (TALLOC_CTX *) memCtx;
- (int) getPidLidAppointmentStateFlags: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx;
- (int) getPidLidResponseStatus: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx;
- (int) getPidLidAppointmentStartWhole: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx;
- (int) getPidLidCommonStart: (void **) data
@ -104,6 +132,10 @@ extern NSTimeZone *utcTZ;
inMemCtx: (TALLOC_CTX *) memCtx;
- (int) getPidLidServerProcessed: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx;
- (int) getPidLidServerProcessingActions: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx;
- (int) getPidLidAppointmentReplyTime: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx;
@end

View File

@ -73,11 +73,13 @@ static NSCharacterSet *hexCharacterSet = nil;
}
+ (id) wrapperWithICalEvent: (iCalEvent *) newEvent
andUser: (SOGoUser *) newUser
inTimeZone: (NSTimeZone *) newTimeZone
{
MAPIStoreAppointmentWrapper *wrapper;
wrapper = [[self alloc] initWithICalEvent: newEvent
andUser: newUser
inTimeZone: newTimeZone];
[wrapper autorelease];
@ -93,12 +95,14 @@ static NSCharacterSet *hexCharacterSet = nil;
timeZone = nil;
globalObjectId = nil;
cleanGlobalObjectId = nil;
user = nil;
}
return self;
}
- (id) initWithICalEvent: (iCalEvent *) newEvent
andUser: (SOGoUser *) newUser
inTimeZone: (NSTimeZone *) newTimeZone
{
if ((self = [self init]))
@ -106,6 +110,7 @@ static NSCharacterSet *hexCharacterSet = nil;
ASSIGN (event, newEvent);
ASSIGN (calendar, [event parent]);
ASSIGN (timeZone, newTimeZone);
ASSIGN (user, newUser);
}
return self;
@ -118,6 +123,7 @@ static NSCharacterSet *hexCharacterSet = nil;
[timeZone release];
[globalObjectId release];
[cleanGlobalObjectId release];
[user release];
[super dealloc];
}
@ -448,11 +454,23 @@ static NSCharacterSet *hexCharacterSet = nil;
- (int) getPrMessageClass: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{
*data = talloc_strdup(memCtx, "IPM.Appointment");
const char *className;
if ([[event attendees] count] > 0)
className = "IPM.Schedule.Meeting.Request";
else
className = "IPM.Appointment";
*data = talloc_strdup(memCtx, className);
return MAPISTORE_SUCCESS;
}
- (int) getPidLidFInvited: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{
return [self getYes: data inMemCtx: memCtx];
}
- (int) getPrBody: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{
@ -488,13 +506,56 @@ static NSCharacterSet *hexCharacterSet = nil;
uint32_t flags = 0x00;
if ([[event attendees] count] > 0)
flags |= 0x01; /* asfMeeting */
{
flags |= 0x01; /* asfMeeting */
if ([event userAsAttendee: user])
flags |= 0x02; /* asfReceived */
/* TODO: asfCancelled */
}
*data = MAPILongValue (memCtx, flags);
return MAPISTORE_SUCCESS;
}
- (int) getPidLidResponseStatus: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{
uint32_t status = 0x00;
iCalPerson *person;
if ([[event attendees] count] > 0)
{
if ([event userIsOrganizer: user])
status = 1;
else
{
person = [event userAsAttendee: user];
if (person)
{
switch ([person participationStatus])
{
case iCalPersonPartStatTentative:
status = 2;
break;
case iCalPersonPartStatAccepted:
status = 3;
break;
case iCalPersonPartStatDeclined:
status = 4;
break;
default:
status = 5;
}
}
}
}
*data = MAPILongValue (memCtx, status);
return MAPISTORE_SUCCESS;
}
- (int) getPidLidAppointmentStartWhole: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{
@ -507,6 +568,167 @@ static NSCharacterSet *hexCharacterSet = nil;
return [self getPidLidAppointmentStartWhole: data inMemCtx: memCtx];
}
- (int) _getEntryIdFromCN: (NSString *) cn
andEmail: (NSString *) email
inData: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{
NSString *username;
SOGoUserManager *mgr;
NSDictionary *contactInfos;
NSData *entryId;
mgr = [SOGoUserManager sharedUserManager];
contactInfos = [mgr contactInfosForUserWithUIDorEmail: email];
if (contactInfos)
{
username = [contactInfos objectForKey: @"c_uid"];
entryId = MAPIStoreInternalEntryId (username);
}
else
entryId = MAPIStoreExternalEntryId (cn, email);
*data = [entryId asBinaryInMemCtx: memCtx];
return MAPISTORE_SUCCESS;
}
- (int) _getEmailAddress: (void **) data
forICalPerson: (iCalPerson *) person
inMemCtx: (TALLOC_CTX *) memCtx
{
int rc;
NSString *email;
email = [person rfc822Email];
if ([email length] > 0)
{
*data = [email asUnicodeInMemCtx: memCtx];
rc = MAPISTORE_SUCCESS;
}
else
rc = MAPISTORE_ERR_NOT_FOUND;
return rc;
}
- (int) _getAddrType: (void **) data
forICalPerson: (iCalPerson *) person
inMemCtx: (TALLOC_CTX *) memCtx
{
*data = [@"SMTP" asUnicodeInMemCtx: memCtx];
return MAPISTORE_SUCCESS;
}
- (int) _getName: (void **) data
forICalPerson: (iCalPerson *) person
inMemCtx: (TALLOC_CTX *) memCtx
{
int rc;
NSString *cn;
cn = [person cn];
if ([cn length] > 0)
{
*data = [cn asUnicodeInMemCtx: memCtx];
rc = MAPISTORE_SUCCESS;
}
else
rc = MAPISTORE_ERR_NOT_FOUND;
return rc;
}
- (int) _getEntryid: (void **) data
forICalPerson: (iCalPerson *) person
inMemCtx: (TALLOC_CTX *) memCtx
{
int rc = MAPISTORE_ERR_NOT_FOUND;
NSString *email, *cn;
if (person)
{
email = [person rfc822Email];
if ([email length] > 0)
{
cn = [person cn];
rc = [self _getEntryIdFromCN: cn andEmail: email
inData: data
inMemCtx: memCtx];
}
}
return rc;
}
/* sender (organizer) */
- (int) getPrSenderEmailAddress: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{
return [self _getEmailAddress: data
forICalPerson: [event organizer]
inMemCtx: memCtx];
}
- (int) getPrSenderAddrtype: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{
return [self _getAddrType: data
forICalPerson: [event organizer]
inMemCtx: memCtx];
}
- (int) getPrSenderName: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{
return [self _getName: data
forICalPerson: [event organizer]
inMemCtx: memCtx];
}
- (int) getPrSenderEntryid: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{
return [self _getEntryid: data
forICalPerson: [event organizer]
inMemCtx: memCtx];
}
/* attendee */
- (int) getPrReceivedByEmailAddress: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{
return [self _getEmailAddress: data
forICalPerson: [event userAsAttendee: user]
inMemCtx: memCtx];
}
- (int) getPrReceivedByAddrtype: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{
return [self _getAddrType: data
forICalPerson: [event userAsAttendee: user]
inMemCtx: memCtx];
}
- (int) getPrReceivedByName: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{
return [self _getName: data
forICalPerson: [event userAsAttendee: user]
inMemCtx: memCtx];
}
- (int) getPrReceivedByEntryid: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{
return [self _getEntryid: data
forICalPerson: [event userAsAttendee: user]
inMemCtx: memCtx];
}
/* /attendee */
- (int) getPrEndDate: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{
@ -601,8 +823,7 @@ static NSCharacterSet *hexCharacterSet = nil;
return [self getPidLidLocation: data inMemCtx: memCtx];
}
- (int) getPidLidServerProcessed: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
- (int) getPidLidServerProcessed: (void **) data inMemCtx: (TALLOC_CTX *) memCtx
{
/* TODO: we need to check whether the event has been processed internally by
SOGo or if it was received only by mail. We only assume the SOGo case
@ -610,6 +831,16 @@ static NSCharacterSet *hexCharacterSet = nil;
return [self getYes: data inMemCtx: memCtx];
}
- (int) getPidLidServerProcessingActions: (void **) data inMemCtx: (TALLOC_CTX *) memCtx
{
*data = MAPILongValue (memCtx,
0x00000010 /* cpsCreatedOnPrincipal */
| 0x00000080 /* cpsUpdatedCalItem */
| 0x00000100 /* cpsCopiedOldProperties */);
return MAPISTORE_SUCCESS;
}
- (int) getPidLidPrivate: (void **) data // private (bool), should depend on CLASS and permissions
inMemCtx: (TALLOC_CTX *) memCtx
{
@ -923,4 +1154,26 @@ _fillAppointmentRecurrencePattern (struct AppointmentRecurrencePattern *arp,
return rc;
}
- (int) getPidLidAppointmentReplyTime: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{
/* We always return LAST-MODIFIED, which is a hack, but one that works
because: the user is either (NOT recipient OR (is recipient AND its
status is N/A), where this value should not be taken into account by the
client OR the user is recipient and its status is defined, where this
value is thus correct because the recipient status is the only property
that can be changed. */
int rc = MAPISTORE_ERR_NOT_FOUND;
NSCalendarDate *lastModified;
lastModified = [event lastModified];
if (lastModified)
{
*data = [lastModified asFileTimeInMemCtx: memCtx];
rc = MAPISTORE_SUCCESS;
}
return rc;
}
@end

View File

@ -40,6 +40,7 @@
#import <NGCards/iCalPerson.h>
#import <NGCards/iCalTimeZone.h>
#import <SOGo/SOGoUser.h>
#import <Appointments/SOGoAppointmentFolder.h>
#import <Appointments/SOGoAppointmentObject.h>
#import <Appointments/iCalEntityObject+SOGo.h>
@ -47,6 +48,7 @@
#import "MAPIStoreCalendarAttachment.h"
#import "MAPIStoreCalendarFolder.h"
#import "MAPIStoreContext.h"
#import "MAPIStoreMapping.h"
#import "MAPIStoreRecurrenceUtils.h"
#import "MAPIStoreTypes.h"
#import "NSDate+MAPIStore.h"
@ -104,7 +106,8 @@
event = [sogoObject component: NO secure: NO];
ASSIGN (appointmentWrapper,
[MAPIStoreAppointmentWrapper wrapperWithICalEvent: event
inTimeZone: [self ownerTimeZone]]);
andUser: [[self context] activeUser]
inTimeZone: [self ownerTimeZone]]);
}
return appointmentWrapper;
@ -117,10 +120,18 @@
return [[self appointmentWrapper] getPrIconIndex: data inMemCtx: memCtx];
}
- (int) getPidLidFInvited: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{
return [self getYes: data inMemCtx: memCtx];
}
- (int) getPrMessageClass: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{
return [[self appointmentWrapper] getPrMessageClass: data inMemCtx: memCtx];
*data = talloc_strdup (memCtx, "IPM.Appointment");
return MAPISTORE_SUCCESS;
}
- (int) getPrOwnerApptId: (void **) data
@ -141,6 +152,13 @@
return [[self appointmentWrapper] getPidLidAppointmentStateFlags: data inMemCtx: memCtx];
}
- (int) getPidLidResponseStatus: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{
return [[self appointmentWrapper] getPidLidResponseStatus: data
inMemCtx: memCtx];
}
- (int) getPidLidAppointmentStartWhole: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{
@ -252,6 +270,29 @@
inMemCtx: memCtx];
}
- (int) getPrProcessed: (void **) data inMemCtx: (TALLOC_CTX *) memCtx
{
return [self getYes: data inMemCtx: memCtx];
}
- (int) getPidLidServerProcessed: (void **) data inMemCtx: (TALLOC_CTX *) memCtx
{
return [[self appointmentWrapper] getPidLidServerProcessed: data
inMemCtx: memCtx];
}
- (int) getPidLidServerProcessingActions: (void **) data inMemCtx: (TALLOC_CTX *) memCtx
{
return [[self appointmentWrapper] getPidLidServerProcessingActions: data
inMemCtx: memCtx];
}
- (int) getPidLidAppointmentReplyTime: (void **) data inMemCtx: (TALLOC_CTX *) memCtx
{
return [[self appointmentWrapper] getPidLidAppointmentReplyTime: data
inMemCtx: memCtx];
}
- (void) getMessageData: (struct mapistore_message **) dataPtr
inMemCtx: (TALLOC_CTX *) memCtx
{
@ -263,6 +304,120 @@
*dataPtr = msgData;
}
/* sender */
- (int) getPrSenderEmailAddress: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{
return [[self appointmentWrapper] getPrSenderEmailAddress: data
inMemCtx: memCtx];
}
- (int) getPrSenderAddrtype: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{
return [[self appointmentWrapper] getPrSenderAddrtype: data
inMemCtx: memCtx];
}
- (int) getPrSenderName: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{
return [[self appointmentWrapper] getPrSenderName: data
inMemCtx: memCtx];
}
- (int) getPrSenderEntryid: (void **) data inMemCtx: (TALLOC_CTX *) memCtx
{
return [[self appointmentWrapper] getPrSenderEntryid: data
inMemCtx: memCtx];
}
/* sender representing */
- (int) getPrSentRepresentingEmailAddress: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{
return [self getPrSenderEmailAddress: data inMemCtx: memCtx];
}
- (int) getPrSentRepresentingAddrtype: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{
return [self getSMTPAddrType: data inMemCtx: memCtx];
}
- (int) getPrSentRepresentingName: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{
return [self getPrSenderName: data inMemCtx: memCtx];
}
- (int) getPrSentRepresentingEntryid: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{
return [self getPrSenderEntryid: data inMemCtx: memCtx];
}
/* attendee */
// - (int) getPrReceivedByAddrtype: (void **) data
// inMemCtx: (TALLOC_CTX *) memCtx
// {
// return [[self appointmentWrapper] getPrReceivedByAddrtype: data
// inMemCtx: memCtx];
// }
// - (int) getPrReceivedByEmailAddress: (void **) data
// inMemCtx: (TALLOC_CTX *) memCtx
// {
// return [[self appointmentWrapper] getPrReceivedByEmailAddress: data
// inMemCtx: memCtx];
// }
// - (int) getPrReceivedByName: (void **) data
// inMemCtx: (TALLOC_CTX *) memCtx
// {
// return [[self appointmentWrapper] getPrReceivedByName: data
// inMemCtx: memCtx];
// }
// - (int) getPrReceivedByEntryid: (void **) data
// inMemCtx: (TALLOC_CTX *) memCtx
// {
// return [[self appointmentWrapper] getPrReceivedByEntryid: data
// inMemCtx: memCtx];
// }
// /* attendee representing */
// - (int) getPrRcvdRepresentingEmailAddress: (void **) data
// inMemCtx: (TALLOC_CTX *) memCtx
// {
// return [self getPrReceivedByEmailAddress: data inMemCtx: memCtx];
// }
// - (int) getPrRcvdRepresentingAddrtype: (void **) data
// inMemCtx: (TALLOC_CTX *) memCtx
// {
// return [self getSMTPAddrType: data inMemCtx: memCtx];
// }
// - (int) getPrRcvdRepresentingName: (void **) data
// inMemCtx: (TALLOC_CTX *) memCtx
// {
// return [self getPrReceivedByName: data inMemCtx: memCtx];
// }
// - (int) getPrRcvdRepresentingEntryid: (void **) data
// inMemCtx: (TALLOC_CTX *) memCtx
// {
// return [self getPrReceivedByEntryid: data inMemCtx: memCtx];
// }
- (int) getPrResponseRequested: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{
return [self getYes: data inMemCtx: memCtx];
}
/* attendee */
- (void) _setupRecurrenceInCalendar: (iCalCalendar *) calendar
withEvent: (iCalEvent *) event
fromData: (NSData *) mapiRecurrenceData
@ -284,6 +439,73 @@
talloc_free (blob);
}
- (NSString *) _uidFromGlobalObjectId
{
NSData *objectId;
NSString *uid = nil;
char *bytesDup, *uidStart;
NSUInteger length;
/* NOTE: we only handle the generic case at the moment, see
MAPIStoreAppointmentWrapper */
objectId = [newProperties objectForKey: MAPIPropertyKey (PidLidGlobalObjectId)];
if (objectId)
{
length = [objectId length];
bytesDup = talloc_array (NULL, char, length + 1);
memcpy (bytesDup, [objectId bytes], length);
bytesDup[length] = 0;
uidStart = bytesDup + length - 1;
while (uidStart != bytesDup && *(uidStart - 1))
uidStart--;
if (uidStart > bytesDup && *uidStart)
uid = [NSString stringWithUTF8String: uidStart];
talloc_free (bytesDup);
}
return uid;
}
- (void) _fixupEventWithExistingUID
{
NSString *uid, *existingCName, *existingURL;
MAPIStoreMapping *mapping;
uint64_t objectId;
SOGoAppointmentObject *existingObject;
WOContext *woContext;
uid = [self _uidFromGlobalObjectId];
existingCName = [[container sogoObject] resourceNameForEventUID: uid];
if (existingCName)
{
/* Steps:
unregister self'url mapping
unregister old object's url mapping to discard further delete operation
set new object nameInContainer
register new url mapping */
mapping = [[self context] mapping];
existingURL = [NSString stringWithFormat: @"%@%@",
[container url], existingCName];
objectId = [mapping idFromURL: existingURL];
[mapping unregisterURLWithID: objectId];
objectId = [self objectId];
[mapping unregisterURLWithID: objectId];
[mapping registerURL: existingURL withID: objectId];
woContext = [[self context] woContext];
existingObject = [[container sogoObject] lookupName: existingCName
inContext: woContext
acquire: NO];
[existingObject setContext: woContext];
ASSIGN (sogoObject, existingObject);
isNew = NO;
}
}
- (void) save
{
iCalCalendar *vCalendar;
@ -297,6 +519,17 @@
SOGoUser *activeUser;
id value;
if (isNew)
{
/* big response hack:
- if isNew:
- deduce UID from GlobalObjectId
- if UID already exist in db:
- invoke setNameInContainer on sogoObject with proper cname */
[self _fixupEventWithExistingUID];
}
[self logWithFormat: @"-save, event props:"];
// MAPIStoreDumpMessageProperties (newProperties);
@ -329,6 +562,8 @@
if (value)
responseStatus = [value unsignedLongValue];
/* FIXME: we should provide a data converter between OL partstats and
SOGo */
switch (responseStatus)
{
case 0x02: /* respTentative */
@ -452,15 +687,23 @@
withEvent: newEvent
fromData: value];
[newEvent setOrganizer: nil];
[newEvent removeAllAttendees];
// Organizer
value = [newProperties objectForKey: @"recipients"];
if (value)
{
NSArray *recipients;
NSDictionary *dict;
NSDictionary *dict, *properties;
iCalPerson *person;
iCalPersonPartStat newPartStat;
NSNumber *flags, *trackStatus;
int i;
/* 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 = [activeUser primaryIdentity];
person = [iCalPerson new];
[person setCn: [dict objectForKey: @"fullName"]];
@ -473,18 +716,50 @@
for (i = 0; i < [recipients count]; i++)
{
dict = [recipients objectAtIndex: i];
properties = [dict objectForKey: @"properties"];
flags = [properties
objectForKey: MAPIPropertyKey (PR_RECIPIENT_FLAGS)];
if (!flags)
{
[self logWithFormat: @"no recipient flags specified"];
break;
}
person = [iCalPerson new];
[person setCn: [dict objectForKey: @"fullName"]];
[person setEmail: [dict objectForKey: @"email"]];
[person setParticipationStatus: iCalPersonPartStatNeedsAction];
[person setRsvp: @"TRUE"];
[person setRole: @"REQ-PARTICIPANT"];
// FIXME: We must NOT always rely on this
if (![newEvent isAttendee: [person rfc822Email]])
[newEvent addToAttendees: person];
if (([flags unsignedIntValue] & 0x0002)) /* recipOrganizer */
[newEvent setOrganizer: person];
else
{
trackStatus
= [properties
objectForKey: MAPIPropertyKey (PR_RECIPIENT_TRACKSTATUS)];
/* FIXME: we should provide a data converter between OL
partstats and SOGo */
switch ([trackStatus unsignedIntValue])
{
case 0x02: /* respTentative */
newPartStat = iCalPersonPartStatTentative;
break;
case 0x03: /* respAccepted */
newPartStat = iCalPersonPartStatAccepted;
break;
case 0x04: /* respDeclined */
newPartStat = iCalPersonPartStatDeclined;
break;
default:
newPartStat = iCalPersonPartStatNeedsAction;
}
[person setParticipationStatus: newPartStat];
[person setRsvp: @"TRUE"];
[person setRole: @"REQ-PARTICIPANT"];
[newEvent addToAttendees: person];
}
[person release];
}
}

View File

@ -33,6 +33,7 @@
#import <NGObjWeb/WOContext+SoObjects.h>
#import "MAPIStoreContext.h"
#import "MAPIStoreMapping.h"
#import "MAPIStoreTypes.h"
#import "NSData+MAPIStore.h"
#import "NSObject+MAPIStore.h"
@ -572,6 +573,7 @@ e)
{
NSString *msgClass;
NSException *error;
MAPIStoreMapping *mapping;
msgClass = [newProperties
objectForKey: MAPIPropertyKey (PR_MESSAGE_CLASS_UNICODE)];
@ -584,6 +586,9 @@ e)
}
else
[self logWithFormat: @"ignored scheduling message"];
mapping = [[self context] mapping];
[mapping unregisterURLWithID: [self objectId]];
}
- (int) submitWithFlags: (enum SubmitFlags) flags

View File

@ -711,6 +711,8 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe
MAPIStoreMapping *mapping;
struct mapistore_object_notification_parameters *notif_parameters;
struct mapistore_connection_info *connInfo;
connInfo = [[self context] connectionInfo];
// For the "source folder, we ensure the table caches are loaded so
// that old and new state can be compared
@ -733,7 +735,6 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe
notif_parameters->tags[4] = PR_RECIPIENT_ON_NORMAL_MSG_COUNT;
notif_parameters->new_message_count = true;
notif_parameters->message_count = [[sourceFolder messageKeys] count] - midCount;
connInfo = [[self context] connectionInfo];
mapistore_push_notification (connInfo->mstore_ctx,
MAPISTORE_FOLDER,
MAPISTORE_OBJECT_MODIFIED,

View File

@ -28,6 +28,8 @@
#import <NGImap4/NGImap4Client.h>
#import <NGImap4/NGImap4Connection.h>
#import <NGImap4/NGImap4EnvelopeAddress.h>
#import <NGMail/NGMailAddress.h>
#import <NGMail/NGMailAddressParser.h>
#import <NGCards/iCalCalendar.h>
#import <SOGo/NSArray+Utilities.h>
#import <SOGo/NSString+Utilities.h>
@ -272,6 +274,7 @@ _compareBodyKeysByPriority (id entry1, id entry2, void *data)
event = [events objectAtIndex: 0];
appointmentWrapper = [MAPIStoreAppointmentWrapper
wrapperWithICalEvent: event
andUser: [[self context] activeUser]
inTimeZone: [self ownerTimeZone]];
[appointmentWrapper retain];
}
@ -414,6 +417,14 @@ _compareBodyKeysByPriority (id entry1, id entry2, void *data)
return MAPISTORE_SUCCESS;
}
- (int) getPidLidResponseStatus: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{
*data = MAPILongValue (memCtx, 0);
return MAPISTORE_SUCCESS;
}
- (int) getPidLidImapDeleted: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{
@ -481,6 +492,12 @@ _compareBodyKeysByPriority (id entry1, id entry2, void *data)
return MAPISTORE_SUCCESS;
}
- (int) getPidLidFInvited: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{
return [self getYes: data inMemCtx: memCtx];
}
- (int) getPrMessageClass: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{
@ -504,6 +521,7 @@ _compareBodyKeysByPriority (id entry1, id entry2, void *data)
return MAPISTORE_SUCCESS;
}
/* Note: this applies to regular mails... */
// - (int) getPrReplyRequested: (void **) data // TODO
// inMemCtx: (TALLOC_CTX *) memCtx
// {
@ -515,6 +533,7 @@ _compareBodyKeysByPriority (id entry1, id entry2, void *data)
// : [self getNo: data inMemCtx: memCtx]);
// }
/* ... while this applies to invitations. */
- (int) getPrResponseRequested: (void **) data // TODO
inMemCtx: (TALLOC_CTX *) memCtx
{
@ -650,24 +669,117 @@ _compareBodyKeysByPriority (id entry1, id entry2, void *data)
return [self getSMTPAddrType: data inMemCtx: memCtx];
}
- (int) _getEmailAddressFromEmail: (NSString *) fullMail
inData: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{
NGMailAddress *ngAddress;
NSString *email;
if (!fullMail)
fullMail = @"";
ngAddress = [[NGMailAddressParser mailAddressParserWithString: fullMail]
parse];
if ([ngAddress isKindOfClass: [NGMailAddress class]])
email = [ngAddress address];
else
email = @"";
*data = [email asUnicodeInMemCtx: memCtx];
return MAPISTORE_SUCCESS;
}
- (int) _getCNFromEmail: (NSString *) fullMail
inData: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{
NGMailAddress *ngAddress;
NSString *cn;
if (!fullMail)
fullMail = @"";
ngAddress = [[NGMailAddressParser mailAddressParserWithString: fullMail]
parse];
if ([ngAddress isKindOfClass: [NGMailAddress class]])
cn = [ngAddress address];
else
cn = @"";
*data = [cn asUnicodeInMemCtx: memCtx];
return MAPISTORE_SUCCESS;
}
- (int) _getEntryIdFromEmail: (NSString *) fullMail
inData: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{
NSString *username, *cn, *email;
SOGoUserManager *mgr;
NSDictionary *contactInfos;
NGMailAddress *ngAddress;
NSData *entryId;
int rc;
if (fullMail)
{
ngAddress = [[NGMailAddressParser mailAddressParserWithString: fullMail]
parse];
if ([ngAddress isKindOfClass: [NGMailAddress class]])
{
email = [ngAddress address];
cn = [ngAddress displayName];
}
else
{
email = fullMail;
cn = @"";
}
mgr = [SOGoUserManager sharedUserManager];
contactInfos = [mgr contactInfosForUserWithUIDorEmail: email];
if (contactInfos)
{
username = [contactInfos objectForKey: @"c_uid"];
entryId = MAPIStoreInternalEntryId (username);
}
else
entryId = MAPIStoreExternalEntryId (cn, email);
*data = [entryId asBinaryInMemCtx: memCtx];
rc = MAPISTORE_SUCCESS;
}
else
rc = MAPISTORE_ERR_NOT_FOUND;
return rc;
}
- (int) getPrSenderEmailAddress: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{
NSString *stringValue;
stringValue = [sogoObject from];
if (!stringValue)
stringValue = @"";
*data = [stringValue asUnicodeInMemCtx: memCtx];
return MAPISTORE_SUCCESS;
return [self _getEmailAddressFromEmail: [sogoObject from]
inData: data
inMemCtx: memCtx];
}
- (int) getPrSenderName: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{
return [self getPrSenderEmailAddress: data inMemCtx: memCtx];
return [self _getCNFromEmail: [sogoObject from]
inData: data
inMemCtx: memCtx];
}
- (int) getPrSenderEntryid: (void **) data inMemCtx: (TALLOC_CTX *) memCtx
{
return [self _getEntryIdFromEmail: [sogoObject from]
inData: data
inMemCtx: memCtx];
}
- (int) getPrOriginalAuthorName: (void **) data
@ -685,33 +797,43 @@ _compareBodyKeysByPriority (id entry1, id entry2, void *data)
- (int) getPrSentRepresentingName: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{
return [self getPrSenderEmailAddress: data inMemCtx: memCtx];
return [self getPrSenderName: data inMemCtx: memCtx];
}
- (int) getPrSentRepresentingEntryid: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{
return [self getPrSenderEntryid: data inMemCtx: memCtx];
}
- (int) getPrReceivedByEmailAddress: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{
NSString *stringValue;
stringValue = [sogoObject to];
if (!stringValue)
stringValue = @"";
*data = [stringValue asUnicodeInMemCtx: memCtx];
return MAPISTORE_SUCCESS;
return [self _getEmailAddressFromEmail: [sogoObject to]
inData: data
inMemCtx: memCtx];
}
- (int) getPrReceivedByName: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{
return [self getPrReceivedByEmailAddress: data inMemCtx: memCtx];
return [self _getCNFromEmail: [sogoObject to]
inData: data
inMemCtx: memCtx];
}
- (int) getPrReceivedByEntryid: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{
return [self _getEntryIdFromEmail: [sogoObject to]
inData: data
inMemCtx: memCtx];
}
- (int) getPrRcvdRepresentingName: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{
return [self getPrReceivedByEmailAddress: data inMemCtx: memCtx];
return [self getPrReceivedByName: data inMemCtx: memCtx];
}
- (int) getPrRcvdRepresentingEmailAddress: (void **) data
@ -720,10 +842,18 @@ _compareBodyKeysByPriority (id entry1, id entry2, void *data)
return [self getPrReceivedByEmailAddress: data inMemCtx: memCtx];
}
- (int) getPrRcvdRepresentingEntryid: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{
return [self getPrReceivedByEntryid: data inMemCtx: memCtx];
}
- (int) getPrDisplayTo: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{
return [self getPrReceivedByEmailAddress: data inMemCtx: memCtx];
*data = [[sogoObject to] asUnicodeInMemCtx: memCtx];
return MAPISTORE_SUCCESS;
}
- (int) getPrOriginalDisplayTo: (void **) data
@ -910,8 +1040,7 @@ _compareBodyKeysByPriority (id entry1, id entry2, void *data)
: MAPISTORE_ERR_NOT_FOUND);
}
- (int) getPidLidServerProcessed: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
- (int) getPidLidServerProcessed: (void **) data inMemCtx: (TALLOC_CTX *) memCtx
{
if (!headerSetup)
[self _fetchHeaderData];
@ -922,6 +1051,44 @@ _compareBodyKeysByPriority (id entry1, id entry2, void *data)
: MAPISTORE_ERR_NOT_FOUND);
}
- (int) getPidLidServerProcessingActions: (void **) data inMemCtx: (TALLOC_CTX *) memCtx
{
if (!headerSetup)
[self _fetchHeaderData];
return (mailIsEvent
? [[self _appointmentWrapper] getPidLidServerProcessingActions: data
inMemCtx: memCtx]
: MAPISTORE_ERR_NOT_FOUND);
}
- (int) getPrProcessed: (void **) data inMemCtx: (TALLOC_CTX *) memCtx
{
int rc;
if (!headerSetup)
[self _fetchHeaderData];
if (mailIsEvent)
rc = [self getYes: data inMemCtx: memCtx];
else
rc = MAPISTORE_ERR_NOT_FOUND;
return rc;
}
// - (int) getPidLidServerProcessed: (void **) data
// inMemCtx: (TALLOC_CTX *) memCtx
// {
// if (!headerSetup)
// [self _fetchHeaderData];
// return (mailIsEvent
// ? [[self _appointmentWrapper] getPidLidServerProcessed: data
// inMemCtx: memCtx]
// : MAPISTORE_ERR_NOT_FOUND);
// }
- (int) getPidLidPrivate: (void **) data
inMemCtx: (TALLOC_CTX *) memCtx
{
@ -1232,9 +1399,8 @@ _compareBodyKeysByPriority (id entry1, id entry2, void *data)
if (contactInfos)
{
username = [contactInfos objectForKey: @"c_uid"];
// recipient->username = [username asUnicodeInMemCtx: msgData];
// entryId = MAPIStoreInternalEntryId (username);
entryId = MAPIStoreExternalEntryId (cn, email);
recipient->username = [username asUnicodeInMemCtx: msgData];
entryId = MAPIStoreInternalEntryId (username);
}
else
entryId = MAPIStoreExternalEntryId (cn, email);

View File

@ -220,8 +220,8 @@ MAPIStoreMappingTDBTraverse (TDB_CONTEXT *ctx, TDB_DATA data1, TDB_DATA data2,
[mapping setObject: urlString forKey: idKey];
[reverseMapping setObject: idKey forKey: urlString];
rc = YES;
// [self logWithFormat: @"registered url '%@' with id %lld (0x%.16"PRIx64")",
// urlString, idNbr, idNbr];
[self logWithFormat: @"registered url '%@' with id %lld (0x%.16"PRIx64")",
urlString, idNbr, idNbr];
/* Add the record given its fid and mapistore_uri */
key.dptr = (unsigned char *) talloc_asprintf(NULL, "0x%.16"PRIx64, idNbr);
@ -245,18 +245,20 @@ MAPIStoreMappingTDBTraverse (TDB_CONTEXT *ctx, TDB_DATA data1, TDB_DATA data2,
idKey = [NSNumber numberWithUnsignedLongLong: idNbr];
urlString = [mapping objectForKey: idKey];
[reverseMapping removeObjectForKey: urlString];
[mapping removeObjectForKey: idKey];
if (urlString)
{
[self logWithFormat: @"unregistering url '%@' with id %lld (0x%.16"PRIx64")",
urlString, idNbr, idNbr];
[reverseMapping removeObjectForKey: urlString];
[mapping removeObjectForKey: idKey];
/* We hard-delete the entry from the indexing database */
key.dptr = (unsigned char *) talloc_asprintf(NULL, "0x%.16"PRIx64, idNbr);
key.dsize = strlen((const char *) key.dptr);
/* We hard-delete the entry from the indexing database */
key.dptr = (unsigned char *) talloc_asprintf(NULL, "0x%.16"PRIx64, idNbr);
key.dsize = strlen((const char *) key.dptr);
tdb_delete(indexing->tdb, key);
talloc_free(key.dptr);
// [self logWithFormat: @"unregistered url '%@' with id %lld (0x%.16"PRIx64")",
// urlString, idNbr, idNbr];
tdb_delete(indexing->tdb, key);
talloc_free(key.dptr);
}
}
@end

View File

@ -129,12 +129,15 @@
[container ensureDirectory];
[self logWithFormat: @"%d props in whole dict", [properties count]];
content = [NSPropertyListSerialization dataFromPropertyList: properties
format: NSPropertyListBinaryFormat_v1_0
errorDescription: NULL];
if (![content writeToFile: [self completeFilename] atomically: NO])
[NSException raise: @"MAPIStoreIOException"
format: @"could not save message"];
[self logWithFormat: @"fs message written to '%@'", [self completeFilename]];
}
- (NSString *) davEntityTag