merge of '2f632eb28149d9eef08c30d3057eb9d93b8d34c5'

and 'b2196339f77de9ebd51fbed1e0cbf45850b06d7e'

Monotone-Parent: 2f632eb28149d9eef08c30d3057eb9d93b8d34c5
Monotone-Parent: b2196339f77de9ebd51fbed1e0cbf45850b06d7e
Monotone-Revision: 6b2ab08cb3954daacb8c9007f41296b61035de29

Monotone-Author: ludovic@Sophos.ca
Monotone-Date: 2010-11-24T19:15:17
Monotone-Branch: ca.inverse.sogo
This commit is contained in:
Ludovic Marcotte
2010-11-24 19:15:17 +00:00
13 changed files with 432 additions and 26 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

@@ -6,8 +6,8 @@ include $(GNUSTEP_MAKEFILES)/common.make
SUBPROJECTS = \
SOPE/NGCards \
SOPE/GDLContentStore \
SoObjects \
OGoContentStore \
SoObjects \
Main \
UI \
Tools

View File

@@ -6,8 +6,7 @@ libOGoContentStore_LIBRARIES_DEPEND_UPON += \
-lNGCards \
-lNGExtensions \
-lEOControl \
-lSaxObjC \
-lSOGo
-lSaxObjC
ADDITIONAL_INCLUDE_DIRS += -I. -I.. -I../SOPE -I../SoObjects

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

@@ -122,7 +122,6 @@ NSObjectFromSPropValue (const struct SPropValue *value)
// #define PT_SVREID 0xFB
// #define PT_SRESTRICT 0xFD
// #define PT_ACTIONS 0xFE
// #define PT_BINARY 0x102
result = [NSNull null];
NSLog (@"object type not handled: %d (0x.4x)", valueType, valueType);
}
@@ -143,6 +142,11 @@ MAPIStoreDumpMessageProperties (NSDictionary *properties)
max = [allKeys count];
NSLog (@"message properties (%d):", max);
value = [properties objectForKey: @"recipients"];
if (value)
NSLog (@" recipients: %@", value);
for (count = 0; count < max; count++)
{
key = [allKeys objectAtIndex: count];

View File

@@ -31,5 +31,4 @@
@end
#endif /* SOGOCONTENTOBJECT_MAPISTORE_H */

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