Monotone-Parent: 88dbd2a21bc32921ce7ccfe80336f902eb022b0e

Monotone-Revision: 17b50baf79da6da49bc8ce0e951e73f58eaa2cab

Monotone-Author: wsourdeau@inverse.ca
Monotone-Date: 2010-11-24T19:28:45
Monotone-Branch: ca.inverse.sogo
maint-2.0.2
Wolfgang Sourdeau 2010-11-24 19:28:45 +00:00
parent 425825658c
commit 8caad635f5
9 changed files with 425 additions and 21 deletions

View File

@ -1,3 +1,22 @@
2010-11-24 Wolfgang Sourdeau <root@inverse.ca>
* OpenChange/SOGoDraftObject+MAPIStore.m: new category module.
(-setMAPIProperties,-MAPISubmit,-MAPISave): implemented the MAPI
methods for sending messages.
* OpenChange/MAPIStoreSOGo.m: (sogo_op_modifyrecipients): new
backend operation.
* OpenChange/MAPIStoreContext.m:
(-modifyRecipientsWithMID:inRows:withCount:): new method
implementing the new "modifyrecipients" operation.
* OpenChange/MAPIStoreOutboxContext.m: new class module
implementing the "outbox" folder type, as a subclass of
MAPIStoreMailContext.
(-createMessageInFolder:): new method that returns an instance of
SOGoDraftObject.
2010-11-23 Francis Lachapelle <flachapelle@inverse.ca>
* UI/WebServerResources/SchedulerUI.js (deletePersonalCalendar):

View File

@ -35,12 +35,14 @@ $(SOGOBACKEND)_OBJC_FILES += \
MAPIStoreContactsContext.m \
MAPIStoreFreebusyContext.m \
MAPIStoreMailContext.m \
MAPIStoreOutboxContext.m \
MAPIStoreTasksContext.m \
\
SOGoAppointmentObject+MAPIStore.m \
SOGoGCSFolder+MAPIStore.m \
SOGoContentObject+MAPIStore.m \
SOGoContactGCSEntry+MAPIStore.m \
SOGoDraftObject+MAPIStore.m \
SOGoGCSFolder+MAPIStore.m \
SOGoTaskObject+MAPIStore.m \
\
NSArray+MAPIStore.m \

View File

@ -62,7 +62,7 @@
WOContext *woContext;
NSMutableDictionary *messageCache;
NSMutableDictionary *subfolderCache;
SOGoFolder *moduleFolder;
id moduleFolder;
}
+ (id) contextFromURI: (const char *) newUri
@ -123,6 +123,9 @@
- (int) setPropertiesWithFMID: (uint64_t) fmid
ofTableType: (uint8_t) tableType
inRow: (struct SRow *) aRow;
- (int) modifyRecipientsWithMID: (uint64_t) mid
inRows: (struct ModifyRecipientRow *) rows
withCount: (NSUInteger) max;
- (int) deleteMessageWithMID: (uint64_t) mid
withFlags: (uint8_t) flags;

View File

@ -1198,28 +1198,14 @@ _prepareContextClass (struct mapistore_context *newMemCtx,
return MAPISTORE_ERROR;
}
- (int) setPropertiesOfMessage: (NSMutableDictionary *) message
fromRow: (struct SRow *) aRow
{
int counter;
struct SPropValue *cValue;
for (counter = 0; counter < aRow->cValues; counter++)
{
cValue = &(aRow->lpProps[counter]);
[message setObject: NSObjectFromSPropValue (cValue)
forKey: MAPIPropertyNumber (cValue->ulPropTag)];
}
return MAPISTORE_SUCCESS;
}
- (int) setPropertiesWithFMID: (uint64_t) fmid
ofTableType: (uint8_t) tableType
inRow: (struct SRow *) aRow
{
NSMutableDictionary *message;
NSNumber *midNbr;
struct SPropValue *cValue;
NSUInteger counter;
int rc;
switch (tableType)
@ -1228,8 +1214,15 @@ _prepareContextClass (struct mapistore_context *newMemCtx,
midNbr = [NSNumber numberWithUnsignedLongLong: fmid];
message = [messages objectForKey: midNbr];
if (message)
rc = [self setPropertiesOfMessage: message
fromRow: aRow];
{
for (counter = 0; counter < aRow->cValues; counter++)
{
cValue = &(aRow->lpProps[counter]);
[message setObject: NSObjectFromSPropValue (cValue)
forKey: MAPIPropertyNumber (cValue->ulPropTag)];
}
rc = MAPISTORE_SUCCESS;
}
else
rc = MAPISTORE_ERR_NOT_FOUND;
break;
@ -1243,6 +1236,97 @@ _prepareContextClass (struct mapistore_context *newMemCtx,
return rc;
}
- (NSDictionary *) _convertRecipientFromRow: (struct RecipientRow *) row
{
NSMutableDictionary *recipient;
NSString *value;
recipient = [NSMutableDictionary dictionaryWithCapacity: 5];
if ((row->RecipientFlags & 0x07) == 1)
{
value = [NSString stringWithUTF8String: row->X500DN.recipient_x500name];
[recipient setObject: value forKey: @"x500dn"];
}
switch ((row->RecipientFlags & 0x208))
{
case 0x08:
// TODO: we cheat
value = [NSString stringWithUTF8String: row->EmailAddress.lpszA];
break;
case 0x208:
value = [NSString stringWithUTF8String: row->EmailAddress.lpszW];
break;
default:
value = nil;
}
if (value)
[recipient setObject: value forKey: @"email"];
switch ((row->RecipientFlags & 0x210))
{
case 0x10:
// TODO: we cheat
value = [NSString stringWithUTF8String: row->DisplayName.lpszA];
break;
case 0x210:
value = [NSString stringWithUTF8String: row->DisplayName.lpszW];
break;
default:
value = nil;
}
if (value)
[recipient setObject: value forKey: @"fullName"];
return recipient;
}
- (int) modifyRecipientsWithMID: (uint64_t) mid
inRows: (struct ModifyRecipientRow *) rows
withCount: (NSUInteger) max
{
static NSString *recTypes[] = { @"orig", @"to", @"cc", @"bcc" };
NSMutableDictionary *message, *recipients;
NSMutableArray *list;
NSString *recType;
struct ModifyRecipientRow *currentRow;
NSUInteger count;
int rc;
message = [messages
objectForKey: [NSNumber numberWithUnsignedLongLong: mid]];
if (message)
{
recipients = [NSMutableDictionary new];
[message setObject: recipients forKey: @"recipients"];
[recipients release];
for (count = 0; count < max; count++)
{
currentRow = rows + count;
if (currentRow->RecipClass >= 0
&& currentRow->RecipClass < 3)
{
recType = recTypes[currentRow->RecipClass];
list = [recipients objectForKey: recType];
if (!list)
{
list = [NSMutableArray new];
[recipients setObject: list forKey: recType];
[list release];
}
[list addObject: [self _convertRecipientFromRow:
&(currentRow->RecipientRow)]];
}
}
rc = MAPISTORE_SUCCESS;
}
else
rc = MAPISTORE_ERR_NOT_FOUND;
return rc;
}
- (int) deleteMessageWithMID: (uint64_t) mid
withFlags: (uint8_t) flags
{

View File

@ -0,0 +1,32 @@
/* MAPIStoreOutboxContext.h - this file is part of SOGo
*
* Copyright (C) 2010 Wolfgang Sourdeau
*
* Author: Wolfgang Sourdeau <root@inverse.ca>
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef MAPISTOREOUTBOXCONTEXT_H
#define MAPISTOREOUTBOXCONTEXT_H
#import "MAPIStoreMailContext.h"
@interface MAPIStoreOutboxContext : MAPIStoreMailContext
@end
#endif /* MAPISTOREOUTBOXCONTEXT_H */

View File

@ -0,0 +1,84 @@
/* MAPIStoreOutboxContext.m - this file is part of SOGo
*
* Copyright (C) 2010 Wolfgang Sourdeau
*
* Author: Wolfgang Sourdeau <root@inverse.ca>
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#import <Foundation/NSString.h>
#import <NGObjWeb/WOContext+SoObjects.h>
#import <SOGo/SOGoUserFolder.h>
#import <Mailer/SOGoDraftsFolder.h>
#import <Mailer/SOGoMailAccount.h>
#import <Mailer/SOGoMailAccounts.h>
#import "MAPIApplication.h"
#import "MAPIStoreAuthenticator.h"
#import "MAPIStoreMapping.h"
#import "MAPIStoreTypes.h"
#import "MAPIStoreOutboxContext.h"
@implementation MAPIStoreOutboxContext
+ (NSString *) MAPIModuleName
{
return @"outbox";
}
+ (void) registerFixedMappings: (MAPIStoreMapping *) mapping
{
[mapping registerURL: @"sogo://openchange:openchange@outbox/"
withID: 0x150001];
}
- (void) setupModuleFolder
{
SOGoUserFolder *userFolder;
SOGoMailAccounts *accountsFolder;
SOGoMailAccount *accountFolder;
userFolder = [SOGoUserFolder objectWithName: [authenticator username]
inContainer: MAPIApp];
[woContext setClientObject: userFolder];
[userFolder retain]; // LEAK
accountsFolder = [userFolder lookupName: @"Mail"
inContext: woContext
acquire: NO];
[woContext setClientObject: accountsFolder];
[accountsFolder retain]; // LEAK
accountFolder = [accountsFolder lookupName: @"0"
inContext: woContext
acquire: NO];
[accountFolder retain]; // LEAK
moduleFolder = [accountFolder draftsFolderInContext: nil];
[moduleFolder retain];
}
- (id) createMessageInFolder: (id) parentFolder
{
return [moduleFolder newDraft];
}
@end

View File

@ -551,7 +551,9 @@ static int sogo_op_getprops(void *private_data,
context = cContext->objcContext;
[context setupRequest];
rc = [context getProperties: SPropTagArray ofTableType: type inRow: aRow withMID: fmid];
rc = [context getProperties: SPropTagArray
ofTableType: type
inRow: aRow withMID: fmid];
[context tearDownRequest];
[pool release];
@ -586,6 +588,34 @@ static int sogo_op_setprops(void *private_data,
return rc;
}
static int sogo_op_modifyrecipients(void *private_data,
uint64_t mid,
struct ModifyRecipientRow *rows,
uint16_t count)
{
NSAutoreleasePool *pool;
sogo_context *cContext;
MAPIStoreContext *context;
int rc;
DEBUG (5, ("[SOGo: %s:%d]\n", __FUNCTION__, __LINE__));
pool = [NSAutoreleasePool new];
cContext = private_data;
context = cContext->objcContext;
[context setupRequest];
rc = [context modifyRecipientsWithMID: mid
inRows: rows
withCount: count];
[context tearDownRequest];
[pool release];
return rc;
}
static int sogo_op_deletemessage(void *private_data,
uint64_t mid,
uint8_t flags)
@ -680,6 +710,7 @@ int mapistore_init_backend(void)
backend.op_getprops = sogo_op_getprops;
backend.op_get_fid_by_name = sogo_op_get_fid_by_name;
backend.op_setprops = sogo_op_setprops;
backend.op_modifyrecipients = sogo_op_modifyrecipients;
backend.op_deletemessage = sogo_op_deletemessage;
backend.op_get_folders_list = sogo_op_get_folders_list;

View File

@ -0,0 +1,36 @@
/* SOGoDraftObject+MAPIStore.h - this file is part of SOGo
*
* Copyright (C) 2010 Wolfgang Sourdeau
*
* Author: Wolfgang Sourdeau <root@inverse.ca>
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef SOGODRAFTOBJECT_MAPISTORE_H
#define SOGODRAFTOBJECT_MAPISTORE_H
#import <Mailer/SOGoDraftObject.h>
@interface SOGoDraftObject (MAPIStoreMessage)
- (void) setMAPIProperties: (NSDictionary *) properties;
- (void) MAPISubmit;
@end
#endif /* SOGODRAFTOBJECT_MAPISTORE_H */

View File

@ -0,0 +1,113 @@
/* SOGoDraftObject+MAPIStore.m - this file is part of SOGo
*
* Copyright (C) 2010 Wolfgang Sourdeau
*
* Author: Wolfgang Sourdeau <root@inverse.ca>
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#import <Foundation/NSArray.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSString.h>
#import <NGObjWeb/WOContext+SoObjects.h>
#import <SOGo/NSArray+Utilities.h>
#import <SOGo/NSDictionary+Utilities.h>
#import <SOGo/SOGoUser.h>
#import "MAPIStoreTypes.h"
#import "SOGoDraftObject+MAPIStore.h"
@implementation SOGoDraftObject (MAPIStoreMessage)
- (void) setMAPIProperties: (NSDictionary *) properties
{
static NSString *recIds[] = { @"to", @"cc", @"bcc" };
NSArray *list;
NSDictionary *recipients, *identity;
NSMutableDictionary *newHeaders;
NSString *recId, *body;
NSUInteger count;
id value;
// MAPIStoreDumpMessageProperties (properties);
newHeaders = [NSMutableDictionary dictionaryWithCapacity: 6];
recipients = [properties objectForKey: @"recipients"];
for (count = 0; count < 3; count++)
{
recId = recIds[count];
list = [recipients objectForKey: recId];
if ([list count] > 0)
[newHeaders setObject: [list objectsForKey: @"email"
notFoundMarker: nil]
forKey: recId];
}
/*
message properties (20):
recipients: {to = ({email = "wsourdeau@inverse.ca"; fullName = "wsourdeau@inverse.ca"; }); }
0x1000001f (PR_BODY_UNICODE): text body (GSCBufferString)
0x0037001f (PR_SUBJECT_UNICODE): Test without (GSCBufferString)
0x30070040 (PR_CREATION_TIME): 2010-11-24 13:45:38 -0500 (NSCalendarDate)
e)
2010-11-24 13:45:38.715 samba[25685] 0x0e62000b (PR_URL_COMP_NAME_SET):
0 (NSIntNumber) */
value = [properties objectForKey: MAPIPropertyNumber (PR_SUBJECT_UNICODE)];
if (value)
[newHeaders setObject: value forKey: @"subject"];
identity = [[context activeUser] primaryIdentity];
[newHeaders setObject: [identity keysWithFormat: @"%{fullName} <%{email}>"]
forKey: @"from"];
[self setHeaders: newHeaders];
value = [properties objectForKey: MAPIPropertyNumber (PR_HTML)];
if (value)
{
[self setIsHTML: YES];
// TODO: encoding
body = [[NSString alloc] initWithData: value
encoding: NSUTF8StringEncoding];
[self setText: body];
[body release];
}
else
{
value = [properties objectForKey: MAPIPropertyNumber (PR_BODY_UNICODE)];
if (value)
{
[self setIsHTML: NO];
[self setText: value];
}
}
}
- (void) MAPISubmit
{
[self sendMail];
}
- (void) MAPISave
{
[self save];
}
@end