Monotone-Parent: 88dbd2a21bc32921ce7ccfe80336f902eb022b0e
Monotone-Revision: 17b50baf79da6da49bc8ce0e951e73f58eaa2cab Monotone-Author: wsourdeau@inverse.ca Monotone-Date: 2010-11-24T19:28:45 Monotone-Branch: ca.inverse.sogomaint-2.0.2
parent
425825658c
commit
8caad635f5
19
ChangeLog
19
ChangeLog
|
@ -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):
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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 */
|
|
@ -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
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 */
|
|
@ -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
|
Loading…
Reference in New Issue