Added support for MailDAV PUT
Monotone-Parent: 90509c89f14ff1a8b0d7884244366bd33783ccc1 Monotone-Revision: 8515028ade639f5e3e38f20b4eba28b16a1250b1 Monotone-Author: crobert@inverse.ca Monotone-Date: 2009-09-29T20:13:36 Monotone-Branch: ca.inverse.sogomaint-2.0.2
parent
0aaaf59814
commit
9493a33729
19
ChangeLog
19
ChangeLog
|
@ -1,3 +1,22 @@
|
||||||
|
2009-09-29 Cyril Robert <crobert@inverse.ca>
|
||||||
|
|
||||||
|
* SoObjects/Mailer/SOGoMailFolder.m (PUTAction:, _appendMessageData:usingId:):
|
||||||
|
Added new methods to enable MailDAV PUT on a collection.
|
||||||
|
* SoObjects/Mailer/SOGoMailBaseObject.m (IMAP4IDFromAppendResult:): Moved
|
||||||
|
here, since SOGoDraftObject and SOGoMailFolder need it.
|
||||||
|
* SoObjects/Mailer/SOGoDraftObject.m (_IMAP4IDFromAppendResult): Removed,
|
||||||
|
replaced by [SOGoMailBaseObject IMAP4IDFromAppendResult:].
|
||||||
|
* SoObjects/SOGo/SOGoObject.m: Changed file extension from "mail" to "eml".
|
||||||
|
* SoObjects/Mailer/SOGoMailAccount.m: Added accountName to fix errors in MailDAV.
|
||||||
|
* SoObjects/Mailer/SOGoMailAccounts.m: Added management for account names
|
||||||
|
to fix errors in MailDAV.
|
||||||
|
* SoObjects/Mailer/SOGoMailFolder.m (appendMessage:): Added this method to
|
||||||
|
facilitate the PUT from a SOGoMailObject.
|
||||||
|
* SoObjects/Mailer/SOGoMailObject.m (PUTAction:): Added to enable MailDAV
|
||||||
|
PUT on a non-existing object.
|
||||||
|
* UI/MailerUI/UIxMailMainFrame.m (mailAccounts): Changed the return value to
|
||||||
|
include both the account name and display name.
|
||||||
|
|
||||||
2009-09-29 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
2009-09-29 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||||
|
|
||||||
* SoObjects/SOGo/SOGoObject.m (SOGoSelectorForPropertyGetter)
|
* SoObjects/SOGo/SOGoObject.m (SOGoSelectorForPropertyGetter)
|
||||||
|
|
|
@ -365,19 +365,6 @@ static BOOL showTextAttachmentsInline = NO;
|
||||||
return IMAP4ID;
|
return IMAP4ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (int) _IMAP4IDFromAppendResult: (NSDictionary *) result
|
|
||||||
{
|
|
||||||
NSDictionary *results;
|
|
||||||
NSString *flag, *newIdString;
|
|
||||||
|
|
||||||
results = [[result objectForKey: @"RawResponse"]
|
|
||||||
objectForKey: @"ResponseResult"];
|
|
||||||
flag = [results objectForKey: @"flag"];
|
|
||||||
newIdString = [[flag componentsSeparatedByString: @" "] objectAtIndex: 2];
|
|
||||||
|
|
||||||
return [newIdString intValue];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSException *) save
|
- (NSException *) save
|
||||||
{
|
{
|
||||||
NGImap4Client *client;
|
NGImap4Client *client;
|
||||||
|
@ -405,7 +392,7 @@ static BOOL showTextAttachmentsInline = NO;
|
||||||
{
|
{
|
||||||
if (IMAP4ID > -1)
|
if (IMAP4ID > -1)
|
||||||
error = [imap4 markURLDeleted: [self imap4URL]];
|
error = [imap4 markURLDeleted: [self imap4URL]];
|
||||||
IMAP4ID = [self _IMAP4IDFromAppendResult: result];
|
IMAP4ID = [self IMAP4IDFromAppendResult: result];
|
||||||
[self storeInfo];
|
[self storeInfo];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -695,7 +682,7 @@ static BOOL showTextAttachmentsInline = NO;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// TODO: use subject for filename?
|
// TODO: use subject for filename?
|
||||||
// error = [newDraft saveAttachment:content withName:@"forward.mail"];
|
// error = [newDraft saveAttachment:content withName:@"forward.eml"];
|
||||||
signature = [currentUser signature];
|
signature = [currentUser signature];
|
||||||
if ([signature length])
|
if ([signature length])
|
||||||
[self setText: [NSString stringWithFormat: @"\n-- \n%@", signature]];
|
[self setText: [NSString stringWithFormat: @"\n-- \n%@", signature]];
|
||||||
|
@ -936,7 +923,7 @@ static BOOL showTextAttachmentsInline = NO;
|
||||||
if ([_ext isEqualToString: @"gif"]) return @"image/gif";
|
if ([_ext isEqualToString: @"gif"]) return @"image/gif";
|
||||||
if ([_ext isEqualToString: @"jpg"]) return @"image/jpeg";
|
if ([_ext isEqualToString: @"jpg"]) return @"image/jpeg";
|
||||||
if ([_ext isEqualToString: @"jpeg"]) return @"image/jpeg";
|
if ([_ext isEqualToString: @"jpeg"]) return @"image/jpeg";
|
||||||
if ([_ext isEqualToString: @"mail"]) return @"message/rfc822";
|
if ([_ext isEqualToString: @"eml"]) return @"message/rfc822";
|
||||||
return @"application/octet-stream";
|
return @"application/octet-stream";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,12 +42,15 @@
|
||||||
|
|
||||||
@interface SOGoMailAccount : SOGoMailBaseObject
|
@interface SOGoMailAccount : SOGoMailBaseObject
|
||||||
{
|
{
|
||||||
|
NSString *accountName;
|
||||||
SOGoMailFolder *inboxFolder;
|
SOGoMailFolder *inboxFolder;
|
||||||
SOGoDraftsFolder *draftsFolder;
|
SOGoDraftsFolder *draftsFolder;
|
||||||
SOGoSentFolder *sentFolder;
|
SOGoSentFolder *sentFolder;
|
||||||
SOGoTrashFolder *trashFolder;
|
SOGoTrashFolder *trashFolder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void) setAccountName: (NSString *) newAccountName;
|
||||||
|
|
||||||
- (BOOL) supportsQuotas;
|
- (BOOL) supportsQuotas;
|
||||||
|
|
||||||
/* folder pathes */
|
/* folder pathes */
|
||||||
|
|
|
@ -121,6 +121,7 @@ static NSString *fallbackIMAP4Server = nil;
|
||||||
draftsFolder = nil;
|
draftsFolder = nil;
|
||||||
sentFolder = nil;
|
sentFolder = nil;
|
||||||
trashFolder = nil;
|
trashFolder = nil;
|
||||||
|
accountName = nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
|
@ -132,9 +133,15 @@ static NSString *fallbackIMAP4Server = nil;
|
||||||
[draftsFolder release];
|
[draftsFolder release];
|
||||||
[sentFolder release];
|
[sentFolder release];
|
||||||
[trashFolder release];
|
[trashFolder release];
|
||||||
|
[accountName release];
|
||||||
[super dealloc];
|
[super dealloc];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void) setAccountName: (NSString *) newAccountName
|
||||||
|
{
|
||||||
|
ASSIGN (accountName, newAccountName);
|
||||||
|
}
|
||||||
|
|
||||||
/* shared accounts */
|
/* shared accounts */
|
||||||
|
|
||||||
- (BOOL) isSharedAccount
|
- (BOOL) isSharedAccount
|
||||||
|
@ -142,7 +149,7 @@ static NSString *fallbackIMAP4Server = nil;
|
||||||
NSString *s;
|
NSString *s;
|
||||||
NSRange r;
|
NSRange r;
|
||||||
|
|
||||||
s = [self nameInContainer];
|
s = accountName;
|
||||||
r = [s rangeOfString:@"@"];
|
r = [s rangeOfString:@"@"];
|
||||||
if (r.length == 0) /* regular HTTP logins are never a shared mailbox */
|
if (r.length == 0) /* regular HTTP logins are never a shared mailbox */
|
||||||
return NO;
|
return NO;
|
||||||
|
@ -275,7 +282,7 @@ static NSString *fallbackIMAP4Server = nil;
|
||||||
NSDictionary *mailAccount;
|
NSDictionary *mailAccount;
|
||||||
NSString *username, *escUsername, *hostString;
|
NSString *username, *escUsername, *hostString;
|
||||||
|
|
||||||
mailAccount = [[context activeUser] accountWithName: nameInContainer];
|
mailAccount = [[context activeUser] accountWithName: accountName];
|
||||||
if (mailAccount)
|
if (mailAccount)
|
||||||
{
|
{
|
||||||
username = [mailAccount objectForKey: @"userName"];
|
username = [mailAccount objectForKey: @"userName"];
|
||||||
|
@ -536,21 +543,19 @@ static NSString *fallbackIMAP4Server = nil;
|
||||||
|
|
||||||
- (NSString *) shortTitle
|
- (NSString *) shortTitle
|
||||||
{
|
{
|
||||||
NSString *s, *login, *host;
|
NSString *login, *host;
|
||||||
NSRange r;
|
NSRange r;
|
||||||
|
|
||||||
s = [self nameInContainer];
|
r = [accountName rangeOfString:@"@"];
|
||||||
|
|
||||||
r = [s rangeOfString:@"@"];
|
|
||||||
if (r.length > 0)
|
if (r.length > 0)
|
||||||
{
|
{
|
||||||
login = [s substringToIndex:r.location];
|
login = [accountName substringToIndex:r.location];
|
||||||
host = [s substringFromIndex:(r.location + r.length)];
|
host = [accountName substringFromIndex:(r.location + r.length)];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
login = nil;
|
login = nil;
|
||||||
host = s;
|
host = accountName;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = [host rangeOfString:@"."];
|
r = [host rangeOfString:@"."];
|
||||||
|
|
|
@ -38,10 +38,15 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@class NSArray;
|
@class NSArray;
|
||||||
|
@class NSMutableDictionary;
|
||||||
|
|
||||||
@interface SOGoMailAccounts : SOGoFolder
|
@interface SOGoMailAccounts : SOGoFolder
|
||||||
|
{
|
||||||
|
NSMutableDictionary *accountKeys;
|
||||||
|
}
|
||||||
|
|
||||||
- (NSArray *) toManyRelationshipKeys;
|
- (NSArray *) toManyRelationshipKeys;
|
||||||
|
- (NSDictionary *) accountKeys;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
02111-1307, USA.
|
02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#import <Foundation/NSDictionary.h>
|
||||||
#import <Foundation/NSString.h>
|
#import <Foundation/NSString.h>
|
||||||
|
|
||||||
#import <NGObjWeb/NSException+HTTP.h>
|
#import <NGObjWeb/NSException+HTTP.h>
|
||||||
|
@ -27,6 +28,7 @@
|
||||||
#import <NGExtensions/NSObject+Logs.h>
|
#import <NGExtensions/NSObject+Logs.h>
|
||||||
|
|
||||||
#import "../SOGo/NSArray+Utilities.h"
|
#import "../SOGo/NSArray+Utilities.h"
|
||||||
|
#import "../SOGo/NSString+Utilities.h"
|
||||||
#import "../SOGo/SOGoUser.h"
|
#import "../SOGo/SOGoUser.h"
|
||||||
#import "SOGoMailAccount.h"
|
#import "SOGoMailAccount.h"
|
||||||
|
|
||||||
|
@ -41,22 +43,59 @@
|
||||||
// return [[container nameInContainer] isEqualToString: userLogin];
|
// return [[container nameInContainer] isEqualToString: userLogin];
|
||||||
// }
|
// }
|
||||||
|
|
||||||
- (NSArray *) toManyRelationshipKeys
|
- (id) init
|
||||||
|
{
|
||||||
|
if ((self = [super init]))
|
||||||
|
{
|
||||||
|
accountKeys = nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) dealloc
|
||||||
|
{
|
||||||
|
[accountKeys release];
|
||||||
|
[super dealloc];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) _initAccountKeys
|
||||||
{
|
{
|
||||||
NSArray *accounts;
|
NSArray *accounts;
|
||||||
|
NSString *currentName;
|
||||||
|
int count, max;
|
||||||
|
|
||||||
accounts = [[context activeUser] mailAccounts];
|
if (!accountKeys)
|
||||||
|
{
|
||||||
|
accountKeys = [NSMutableDictionary new];
|
||||||
|
|
||||||
return [accounts objectsForKey: @"name" notFoundMarker: nil];
|
accounts = [[context activeUser] mailAccounts];
|
||||||
|
max = [accounts count];
|
||||||
|
for (count = 0; count < max; count++)
|
||||||
|
{
|
||||||
|
currentName = [[accounts objectAtIndex: count] objectForKey: @"name"];
|
||||||
|
[accountKeys setObject: currentName
|
||||||
|
forKey: [currentName asCSSIdentifier]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSDictionary *) accountKeys
|
||||||
|
{
|
||||||
|
[self _initAccountKeys];
|
||||||
|
|
||||||
|
return accountKeys;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSArray *) toManyRelationshipKeys
|
||||||
|
{
|
||||||
|
[self _initAccountKeys];
|
||||||
|
|
||||||
|
return [accountKeys allKeys];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* name lookup */
|
/* name lookup */
|
||||||
|
|
||||||
- (BOOL) isValidMailAccountName: (NSString *) _key
|
|
||||||
{
|
|
||||||
return [[self toManyRelationshipKeys] containsObject: _key];
|
|
||||||
}
|
|
||||||
|
|
||||||
// - (id) mailAccountWithName: (NSString *) _key
|
// - (id) mailAccountWithName: (NSString *) _key
|
||||||
// inContext: (id) _ctx
|
// inContext: (id) _ctx
|
||||||
// {
|
// {
|
||||||
|
@ -76,10 +115,11 @@
|
||||||
// }
|
// }
|
||||||
|
|
||||||
- (id) lookupName: (NSString *) _key
|
- (id) lookupName: (NSString *) _key
|
||||||
inContext: (id) _ctx
|
inContext: (id) _ctx
|
||||||
acquire: (BOOL) _flag
|
acquire: (BOOL) _flag
|
||||||
{
|
{
|
||||||
id obj;
|
id obj;
|
||||||
|
NSString *accountName;
|
||||||
// NSString *userLogin;
|
// NSString *userLogin;
|
||||||
|
|
||||||
// userLogin = [[context activeUser] login];
|
// userLogin = [[context activeUser] login];
|
||||||
|
@ -96,10 +136,15 @@
|
||||||
obj = [super lookupName:_key inContext:_ctx acquire:NO];
|
obj = [super lookupName:_key inContext:_ctx acquire:NO];
|
||||||
if (!obj)
|
if (!obj)
|
||||||
{
|
{
|
||||||
if ([self isValidMailAccountName: _key])
|
[self _initAccountKeys];
|
||||||
obj = [SOGoMailAccount objectWithName: _key inContainer: self];
|
accountName = [accountKeys objectForKey: _key];
|
||||||
|
if ([accountName length])
|
||||||
|
{
|
||||||
|
obj = [SOGoMailAccount objectWithName: _key inContainer: self];
|
||||||
|
[obj setAccountName: accountName];
|
||||||
|
}
|
||||||
else
|
else
|
||||||
obj = [NSException exceptionWithHTTPStatus: 404 /* Not Found */];
|
obj = [NSException exceptionWithHTTPStatus: 404 /* Not Found */];
|
||||||
}
|
}
|
||||||
|
|
||||||
return obj;
|
return obj;
|
||||||
|
|
|
@ -78,6 +78,8 @@
|
||||||
|
|
||||||
- (BOOL) isBodyPartKey: (NSString *) key;
|
- (BOOL) isBodyPartKey: (NSString *) key;
|
||||||
|
|
||||||
|
- (int) IMAP4IDFromAppendResult: (NSDictionary *) result;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
#endif /* __Mailer_SOGoMailBaseObject_H__ */
|
#endif /* __Mailer_SOGoMailBaseObject_H__ */
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
|
|
||||||
#import <Foundation/NSCharacterSet.h>
|
#import <Foundation/NSCharacterSet.h>
|
||||||
#import <Foundation/NSString.h>
|
#import <Foundation/NSString.h>
|
||||||
|
#import <Foundation/NSDictionary.h>
|
||||||
|
|
||||||
#import <NGObjWeb/SoObject+SoDAV.h>
|
#import <NGObjWeb/SoObject+SoDAV.h>
|
||||||
#import <NGExtensions/NSNull+misc.h>
|
#import <NGExtensions/NSNull+misc.h>
|
||||||
|
@ -230,4 +231,17 @@ static BOOL debugOn = YES;
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (int) IMAP4IDFromAppendResult: (NSDictionary *) result
|
||||||
|
{
|
||||||
|
NSDictionary *results;
|
||||||
|
NSString *flag, *newIdString;
|
||||||
|
|
||||||
|
results = [[result objectForKey: @"RawResponse"]
|
||||||
|
objectForKey: @"ResponseResult"];
|
||||||
|
flag = [results objectForKey: @"flag"];
|
||||||
|
newIdString = [[flag componentsSeparatedByString: @" "] objectAtIndex: 2];
|
||||||
|
|
||||||
|
return [newIdString intValue];
|
||||||
|
}
|
||||||
|
|
||||||
@end /* SOGoMailBaseObject */
|
@end /* SOGoMailBaseObject */
|
||||||
|
|
|
@ -446,7 +446,7 @@ static BOOL debugOn = NO;
|
||||||
return NSClassFromString(@"SOGoVCardMailBodyPart");
|
return NSClassFromString(@"SOGoVCardMailBodyPart");
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
if ([pe isEqualToString:@"mail"])
|
if ([pe isEqualToString:@"eml"])
|
||||||
return NSClassFromString(@"SOGoMessageMailBodyPart");
|
return NSClassFromString(@"SOGoMessageMailBodyPart");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -94,6 +94,10 @@ typedef enum {
|
||||||
- (NSString *) userSpoolFolderPath;
|
- (NSString *) userSpoolFolderPath;
|
||||||
- (BOOL) ensureSpoolFolderPath;
|
- (BOOL) ensureSpoolFolderPath;
|
||||||
|
|
||||||
|
- (id) appendMessage: (NSData *) message
|
||||||
|
inContext: (WOContext *) _ctx
|
||||||
|
usingId: (int *) imap4id;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface SOGoSpecialMailFolder : SOGoMailFolder
|
@interface SOGoSpecialMailFolder : SOGoMailFolder
|
||||||
|
|
|
@ -259,7 +259,7 @@ static NSString *spoolFolder = nil;
|
||||||
max = [uids count];
|
max = [uids count];
|
||||||
for (count = 0; count < max; count++)
|
for (count = 0; count < max; count++)
|
||||||
{
|
{
|
||||||
filename = [NSString stringWithFormat: @"%@.mail",
|
filename = [NSString stringWithFormat: @"%@.eml",
|
||||||
[uids objectAtIndex: count]];
|
[uids objectAtIndex: count]];
|
||||||
[filenames addObject: filename];
|
[filenames addObject: filename];
|
||||||
}
|
}
|
||||||
|
@ -1102,6 +1102,83 @@ static NSString *spoolFolder = nil;
|
||||||
return [self nameInContainer];
|
return [self nameInContainer];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// For DAV PUT
|
||||||
|
- (NSException *) _appendMessageData: (NSData *) data
|
||||||
|
usingId: (int *) imap4id;
|
||||||
|
{
|
||||||
|
NGImap4Client *client;
|
||||||
|
NSString *folderName;
|
||||||
|
NSException *error;
|
||||||
|
id result;
|
||||||
|
|
||||||
|
error = nil;
|
||||||
|
client = [imap4 client];
|
||||||
|
|
||||||
|
folderName = [imap4 imap4FolderNameForURL: [self imap4URL]];
|
||||||
|
result = [client append: data toFolder: folderName withFlags: nil];
|
||||||
|
|
||||||
|
if ([[result objectForKey: @"result"] boolValue])
|
||||||
|
*imap4id = [self IMAP4IDFromAppendResult: result];
|
||||||
|
else
|
||||||
|
error = [NSException exceptionWithHTTPStatus: 500 /* Server Error */
|
||||||
|
reason: @"Failed to store message"];
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (id) appendMessage: (NSData *) message
|
||||||
|
inContext: (WOContext *) _ctx
|
||||||
|
usingId: (int *) imap4id
|
||||||
|
{
|
||||||
|
NSException *error;
|
||||||
|
WOResponse *response;
|
||||||
|
NSString *location;
|
||||||
|
id msg;
|
||||||
|
|
||||||
|
error = [self _appendMessageData: message
|
||||||
|
usingId: imap4id];
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
response = (WOResponse *) error;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
response = [_ctx response];
|
||||||
|
[response setStatus: 201];
|
||||||
|
msg = [SOGoMailObject objectWithName:
|
||||||
|
[NSString stringWithFormat: @"%d", imap4id]
|
||||||
|
inContainer: self];
|
||||||
|
if (msg)
|
||||||
|
{
|
||||||
|
location = [NSString stringWithFormat: @"%@%d.eml",
|
||||||
|
[self davURL], *imap4id];
|
||||||
|
[response setHeader: location forKey: @"location"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (id) PUTAction: (WOContext *) _ctx
|
||||||
|
{
|
||||||
|
WORequest *rq;
|
||||||
|
NSException *error;
|
||||||
|
WOResponse *response;
|
||||||
|
int imap4id;
|
||||||
|
|
||||||
|
error = [self matchesRequestConditionInContext: _ctx];
|
||||||
|
if (error)
|
||||||
|
response = (WOResponse *) error;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rq = [_ctx request];
|
||||||
|
response = [self appendMessage: [rq content]
|
||||||
|
inContext: _ctx
|
||||||
|
usingId: &imap4id];
|
||||||
|
}
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
@end /* SOGoMailFolder */
|
@end /* SOGoMailFolder */
|
||||||
|
|
||||||
@implementation SOGoSpecialMailFolder
|
@implementation SOGoSpecialMailFolder
|
||||||
|
|
|
@ -1239,4 +1239,34 @@ static BOOL debugSoParts = NO;
|
||||||
return debugOn;
|
return debugOn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// For DAV PUT
|
||||||
|
- (id) PUTAction: (WOContext *) _ctx
|
||||||
|
{
|
||||||
|
WORequest *rq;
|
||||||
|
NSException *error;
|
||||||
|
WOResponse *response;
|
||||||
|
SOGoMailFolder *folder;
|
||||||
|
int imap4id;
|
||||||
|
|
||||||
|
error = [self matchesRequestConditionInContext: _ctx];
|
||||||
|
if (error)
|
||||||
|
response = (WOResponse *) error;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rq = [_ctx request];
|
||||||
|
folder = [self container];
|
||||||
|
|
||||||
|
if ([self doesMailExist])
|
||||||
|
response = [NSException exceptionWithHTTPStatus: 403
|
||||||
|
reason: @"Can't overwrite messages"];
|
||||||
|
else
|
||||||
|
response = [folder appendMessage: [rq content]
|
||||||
|
inContext: _ctx
|
||||||
|
usingId: &imap4id];
|
||||||
|
}
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
@end /* SOGoMailObject */
|
@end /* SOGoMailObject */
|
||||||
|
|
|
@ -44,6 +44,32 @@ class DAVMailTest(unittest.TestCase):
|
||||||
#self.client.execute(delete)
|
#self.client.execute(delete)
|
||||||
|
|
||||||
|
|
||||||
|
message1 = """Return-Path: <cyril@cyril.dev>
|
||||||
|
Received: from cyril.dev (localhost [127.0.0.1])
|
||||||
|
by cyril.dev (Cyrus v2.3.8-Debian-2.3.8-1) with LMTPA;
|
||||||
|
Tue, 29 Sep 2009 07:42:16 -0400
|
||||||
|
X-Virus-Scanned: Debian amavisd-new at inverse.ca
|
||||||
|
Message-ID: <4AC1F296.5060801@cyril.dev>
|
||||||
|
Date: Tue, 29 Sep 2009 07:42:14 -0400
|
||||||
|
From: Cyril <cyril@cyril.dev>
|
||||||
|
Organization: Inverse inc.
|
||||||
|
User-Agent: Thunderbird 2.0.0.22 (Macintosh/20090605)
|
||||||
|
MIME-Version: 1.0
|
||||||
|
To: jacques@cyril.dev
|
||||||
|
CC: support@inverse.ca
|
||||||
|
Subject: Hallo
|
||||||
|
Content-Type: text/plain; charset=UTF-8; format=flowed
|
||||||
|
Content-Transfer-Encoding: 7bit
|
||||||
|
Reply-To: support@inverse.ca,Cyril <cyril@cyril.dev>
|
||||||
|
|
||||||
|
Hello Jacques,
|
||||||
|
|
||||||
|
Can you read me?
|
||||||
|
|
||||||
|
--
|
||||||
|
Cyril <cyril@cyril.dev>
|
||||||
|
"""
|
||||||
|
|
||||||
class DAVMailCollectionTest(DAVMailTest):
|
class DAVMailCollectionTest(DAVMailTest):
|
||||||
resource = '/SOGo/dav/%s/Mail/' % username
|
resource = '/SOGo/dav/%s/Mail/' % username
|
||||||
user_email = None
|
user_email = None
|
||||||
|
@ -56,6 +82,8 @@ class DAVMailCollectionTest(DAVMailTest):
|
||||||
|
|
||||||
self.resource = '/SOGo/dav/%s/Mail/%s/' \
|
self.resource = '/SOGo/dav/%s/Mail/%s/' \
|
||||||
% (username, self.user_email)
|
% (username, self.user_email)
|
||||||
|
self.resource = self.resource.replace ("@", "_A_")
|
||||||
|
self.resource = self.resource.replace (".", "_D_")
|
||||||
|
|
||||||
DAVMailTest.setUp(self)
|
DAVMailTest.setUp(self)
|
||||||
|
|
||||||
|
@ -69,6 +97,7 @@ class DAVMailCollectionTest(DAVMailTest):
|
||||||
self._deleteCollection ("test-dav-mail-%20-ghi")
|
self._deleteCollection ("test-dav-mail-%20-ghi")
|
||||||
self._makeCollection ("test-dav-mail-%25-jkl", 500)
|
self._makeCollection ("test-dav-mail-%25-jkl", 500)
|
||||||
|
|
||||||
|
# Test MOVE
|
||||||
# self._makeCollection ("test-dav-mail-movable")
|
# self._makeCollection ("test-dav-mail-movable")
|
||||||
# url = "%sfolder%s" % (self.resource, "test-dav-mail-movable")
|
# url = "%sfolder%s" % (self.resource, "test-dav-mail-movable")
|
||||||
# move = webdavlib.WebDAVMOVE (url)
|
# move = webdavlib.WebDAVMOVE (url)
|
||||||
|
@ -79,6 +108,38 @@ class DAVMailCollectionTest(DAVMailTest):
|
||||||
# "failure creating collection"
|
# "failure creating collection"
|
||||||
# "(code = %d)" % move.response["status"])
|
# "(code = %d)" % move.response["status"])
|
||||||
|
|
||||||
|
#Test PUT
|
||||||
|
self._makeCollection ("test-dav-mail")
|
||||||
|
url = "%s%s" % (self.resource, "foldertest-dav-mail/")
|
||||||
|
put = webdavlib.WebDAVPUT (url, message1)
|
||||||
|
self.client.execute (put)
|
||||||
|
self.assertEquals(put.response["status"], 201,
|
||||||
|
"failure putting message"
|
||||||
|
"(code = %d)" % put.response["status"])
|
||||||
|
|
||||||
|
itemLocation = put.response["headers"]["location"]
|
||||||
|
get = webdavlib.WebDAVGET (itemLocation)
|
||||||
|
self.client.execute (get)
|
||||||
|
self.assertEquals(get.response["status"], 200,
|
||||||
|
"failure getting item"
|
||||||
|
"(code = %d)" % get.response["status"])
|
||||||
|
|
||||||
|
url = "%s%s" % (self.resource, "foldertest-dav-mail/blabla.eml")
|
||||||
|
put = webdavlib.WebDAVPUT (url, message1)
|
||||||
|
self.client.execute (put)
|
||||||
|
self.assertEquals(put.response["status"], 201,
|
||||||
|
"failure putting message"
|
||||||
|
"(code = %d)" % put.response["status"])
|
||||||
|
|
||||||
|
itemLocation = put.response["headers"]["location"]
|
||||||
|
get = webdavlib.WebDAVGET (itemLocation)
|
||||||
|
self.client.execute (get)
|
||||||
|
self.assertEquals(get.response["status"], 200,
|
||||||
|
"failure getting item"
|
||||||
|
"(code = %d)" % get.response["status"])
|
||||||
|
|
||||||
|
self._deleteCollection ("test-dav-mail")
|
||||||
|
|
||||||
def _makeCollection (self, name, status = 201):
|
def _makeCollection (self, name, status = 201):
|
||||||
url = "%s%s" % (self.resource, name)
|
url = "%s%s" % (self.resource, name)
|
||||||
mkcol = webdavlib.WebDAVMKCOL(url)
|
mkcol = webdavlib.WebDAVMKCOL(url)
|
||||||
|
|
|
@ -155,6 +155,9 @@ class WebDAVDELETE(WebDAVQuery):
|
||||||
class WebDAVREPORT(WebDAVQuery):
|
class WebDAVREPORT(WebDAVQuery):
|
||||||
method = "REPORT"
|
method = "REPORT"
|
||||||
|
|
||||||
|
class WebDAVGET(WebDAVQuery):
|
||||||
|
method = "GET"
|
||||||
|
|
||||||
class WebDAVPROPFIND(WebDAVQuery):
|
class WebDAVPROPFIND(WebDAVQuery):
|
||||||
method = "PROPFIND"
|
method = "PROPFIND"
|
||||||
|
|
||||||
|
@ -181,6 +184,20 @@ class WebDAVMOVE(WebDAVQuery):
|
||||||
headers["Host"] = self.host
|
headers["Host"] = self.host
|
||||||
return headers
|
return headers
|
||||||
|
|
||||||
|
class WebDAVPUT(WebDAVQuery):
|
||||||
|
method = "PUT"
|
||||||
|
|
||||||
|
def __init__(self, url, content):
|
||||||
|
WebDAVQuery.__init__(self, url)
|
||||||
|
self.content_type = "text/plain; charset=utf-8"
|
||||||
|
self.content = content
|
||||||
|
|
||||||
|
def prepare_headers(self):
|
||||||
|
return WebDAVQuery.prepare_headers(self)
|
||||||
|
|
||||||
|
def render(self):
|
||||||
|
return self.content
|
||||||
|
|
||||||
|
|
||||||
class CalDAVPOST(WebDAVQuery):
|
class CalDAVPOST(WebDAVQuery):
|
||||||
method = "POST"
|
method = "POST"
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
#import <SoObjects/Mailer/SOGoMailAccounts.h>
|
#import <SoObjects/Mailer/SOGoMailAccounts.h>
|
||||||
#import <SoObjects/SOGo/NSDictionary+URL.h>
|
#import <SoObjects/SOGo/NSDictionary+URL.h>
|
||||||
#import <SoObjects/SOGo/NSArray+Utilities.h>
|
#import <SoObjects/SOGo/NSArray+Utilities.h>
|
||||||
|
#import <SoObjects/SOGo/NSDictionary+Utilities.h>
|
||||||
#import <SoObjects/SOGo/SOGoUser.h>
|
#import <SoObjects/SOGo/SOGoUser.h>
|
||||||
#import <SoObjects/SOGo/SOGoUserFolder.h>
|
#import <SoObjects/SOGo/SOGoUserFolder.h>
|
||||||
#import <SOGoUI/UIxComponent.h>
|
#import <SOGoUI/UIxComponent.h>
|
||||||
|
@ -84,15 +85,29 @@
|
||||||
|
|
||||||
/* accessors */
|
/* accessors */
|
||||||
|
|
||||||
#warning this method is a duplication of SOGoMailAccounts:toManyRelationShipKeys
|
|
||||||
- (NSString *) mailAccounts
|
- (NSString *) mailAccounts
|
||||||
{
|
{
|
||||||
NSArray *accounts, *accountNames;
|
SOGoMailAccounts *accounts;
|
||||||
|
NSDictionary *accountKeys;
|
||||||
|
NSArray *keys, *entry;
|
||||||
|
NSMutableArray *values;
|
||||||
|
NSString *key;
|
||||||
|
int i, max;
|
||||||
|
|
||||||
accounts = [[context activeUser] mailAccounts];
|
accounts = [self clientObject];
|
||||||
accountNames = [accounts objectsForKey: @"name" notFoundMarker: nil];
|
accountKeys = [accounts accountKeys];
|
||||||
|
keys = [accountKeys allKeys];
|
||||||
|
values = [NSMutableArray array];
|
||||||
|
|
||||||
return [accountNames jsonRepresentation];
|
max = [keys count];
|
||||||
|
for (i = 0; i < max; i++)
|
||||||
|
{
|
||||||
|
key = [keys objectAtIndex: i];
|
||||||
|
entry = [NSArray arrayWithObjects: key, [accountKeys objectForKey: key], nil];
|
||||||
|
[values addObject: entry];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [values jsonRepresentation];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSString *) defaultColumnsOrder
|
- (NSString *) defaultColumnsOrder
|
||||||
|
|
|
@ -1656,7 +1656,7 @@ function initMailboxTree() {
|
||||||
mailboxTree.pendingRequests = mailAccounts.length;
|
mailboxTree.pendingRequests = mailAccounts.length;
|
||||||
activeAjaxRequests += mailAccounts.length;
|
activeAjaxRequests += mailAccounts.length;
|
||||||
for (var i = 0; i < mailAccounts.length; i++) {
|
for (var i = 0; i < mailAccounts.length; i++) {
|
||||||
var url = ApplicationBaseURL + encodeURI(mailAccounts[i]) + "/mailboxes";
|
var url = ApplicationBaseURL + encodeURI(mailAccounts[i][0]) + "/mailboxes";
|
||||||
triggerAjaxRequest(url, onLoadMailboxesCallback, mailAccounts[i]);
|
triggerAjaxRequest(url, onLoadMailboxesCallback, mailAccounts[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1875,9 +1875,9 @@ function onLoadMailboxesCallback(http) {
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildMailboxes(accountName, encoded) {
|
function buildMailboxes(accountKeys, encoded) {
|
||||||
var account = new Mailbox("account", accountName);
|
var account = new Mailbox("account", accountKeys);
|
||||||
var accountIndex = mailAccounts.indexOf(accountName);
|
var accountIndex = mailAccounts.indexOf(accountKeys);
|
||||||
var data = encoded.evalJSON(true);
|
var data = encoded.evalJSON(true);
|
||||||
var mailboxes = data.mailboxes;
|
var mailboxes = data.mailboxes;
|
||||||
var unseen = (data.status? data.status.unseen : 0);
|
var unseen = (data.status? data.status.unseen : 0);
|
||||||
|
@ -2290,7 +2290,14 @@ document.observe("dom:loaded", initMailer);
|
||||||
|
|
||||||
function Mailbox(type, name, unseen) {
|
function Mailbox(type, name, unseen) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.name = name;
|
if (typeof (name) == "object" && name.length == 2) {
|
||||||
|
this.name = name[0];
|
||||||
|
this.displayName = name[1];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.name = name;
|
||||||
|
this.displayName = name;
|
||||||
|
}
|
||||||
this.unseen = unseen;
|
this.unseen = unseen;
|
||||||
this.parentFolder = null;
|
this.parentFolder = null;
|
||||||
this.children = new Array();
|
this.children = new Array();
|
||||||
|
@ -2322,7 +2329,8 @@ Mailbox.prototype = {
|
||||||
|
|
||||||
var i = 0;
|
var i = 0;
|
||||||
while (!mailbox && i < this.children.length)
|
while (!mailbox && i < this.children.length)
|
||||||
if (this.children[i].name == name)
|
if (this.children[i].name == name
|
||||||
|
|| this.children[i].displayName == name)
|
||||||
mailbox = this.children[i];
|
mailbox = this.children[i];
|
||||||
else
|
else
|
||||||
i++;
|
i++;
|
||||||
|
|
|
@ -31,7 +31,7 @@ var MailerUIdTreeExtension = {
|
||||||
},
|
},
|
||||||
_addFolder: function (parent, folder) {
|
_addFolder: function (parent, folder) {
|
||||||
var thisCounter = this.elementCounter;
|
var thisCounter = this.elementCounter;
|
||||||
this._addFolderNode(parent, folder.name, folder.fullName(), folder.type, folder.unseen);
|
this._addFolderNode(parent, folder.displayName, folder.fullName(), folder.type, folder.unseen);
|
||||||
for (var i = 0; i < folder.children.length; i++)
|
for (var i = 0; i < folder.children.length; i++)
|
||||||
this._addFolder(thisCounter, folder.children[i]);
|
this._addFolder(thisCounter, folder.children[i]);
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue