From 5b14c3e9217b6ddfeba62ffd9394a8b4657b8272 Mon Sep 17 00:00:00 2001 From: helge Date: Fri, 25 Mar 2005 22:45:04 +0000 Subject: [PATCH] fixed mail deletion using WebDAV fixed flagging code to select the folder git-svn-id: http://svn.opengroupware.org/SOGo/trunk@643 d1b88da0-ebda-0310-925b-ed51d893ca5b --- SOGo/SoObjects/Mailer/ChangeLog | 10 +++- SOGo/SoObjects/Mailer/SOGoMailFolder.m | 1 + SOGo/SoObjects/Mailer/SOGoMailManager.h | 3 ++ SOGo/SoObjects/Mailer/SOGoMailManager.m | 68 ++++++++++++++++++++++++- SOGo/SoObjects/Mailer/SOGoMailObject.m | 48 ++++++++++++++--- SOGo/SoObjects/Mailer/Version | 2 +- 6 files changed, 122 insertions(+), 10 deletions(-) diff --git a/SOGo/SoObjects/Mailer/ChangeLog b/SOGo/SoObjects/Mailer/ChangeLog index 3505afe1..7ca151f7 100644 --- a/SOGo/SoObjects/Mailer/ChangeLog +++ b/SOGo/SoObjects/Mailer/ChangeLog @@ -1,5 +1,13 @@ 2005-03-25 Helge Hess - + + * v0.9.83 + + * SOGoMailManager.m: properly select folder prior changing flags + + * SOGoMailObject.m: added a special DELETEAction: for mails, it marks + a mail deleted and expunges the folder to ensure the mail is deleted + (this is different to the -delete method!) + * SOGoMailFolder.m: implemented content datasource for efficient WebDAV listings (currently uses hardcoded parts and has inefficient DASL support) (v0.9.82) diff --git a/SOGo/SoObjects/Mailer/SOGoMailFolder.m b/SOGo/SoObjects/Mailer/SOGoMailFolder.m index 57e070b9..0f9a3e7c 100644 --- a/SOGo/SoObjects/Mailer/SOGoMailFolder.m +++ b/SOGo/SoObjects/Mailer/SOGoMailFolder.m @@ -178,6 +178,7 @@ return [[[SOGoMailFolder alloc] initWithName:_key inContainer:self] autorelease]; } + - (id)lookupImap4Message:(NSString *)_key inContext:(id)_ctx { // TODO: we might want to check for existence prior controller creation return [[[SOGoMailObject alloc] initWithName:_key diff --git a/SOGo/SoObjects/Mailer/SOGoMailManager.h b/SOGo/SoObjects/Mailer/SOGoMailManager.h index 51d5eb9f..b7251dcf 100644 --- a/SOGo/SoObjects/Mailer/SOGoMailManager.h +++ b/SOGo/SoObjects/Mailer/SOGoMailManager.h @@ -78,6 +78,9 @@ - (NSException *)postData:(NSData *)_data flags:(id)_flags toFolderURL:(NSURL *)_url password:(NSString *)_p; +- (NSException *)copyMailURL:(NSURL *)_srcurl toFolderURL:(NSURL *)_desturl + password:(NSString *)_pwd; + /* managing folders */ - (BOOL)doesMailboxExistAtURL:(NSURL *)_url password:(NSString *)_pwd; diff --git a/SOGo/SoObjects/Mailer/SOGoMailManager.m b/SOGo/SoObjects/Mailer/SOGoMailManager.m index c430a6aa..3f35e7af 100644 --- a/SOGo/SoObjects/Mailer/SOGoMailManager.m +++ b/SOGo/SoObjects/Mailer/SOGoMailManager.m @@ -659,11 +659,25 @@ static NSString *imap4Separator = nil; if (![_url isNotNull]) return nil; if (![_f isNotNull]) return nil; + if (![_f isKindOfClass:[NSArray class]]) + _f = [NSArray arrayWithObjects:&_f count:1]; + + /* get client */ + if ((client = [self imap4ClientForURL:_url password:_p]) == nil) + // TODO: return 401? return nil; - if (![_f isKindOfClass:[NSArray class]]) - _f = [NSArray arrayWithObjects:&_f count:1]; + /* select folder */ + + if (![self selectFolder:[self imap4FolderNameForURL:_url removeFileName:YES] + inClient:client]) { + return [NSException exceptionWithHTTPStatus:404 /* server error */ + reason:@"could not select IMAP4 folder"]; + return nil; + } + + /* store flags */ result = [client storeUid:[[[_url path] lastPathComponent] intValue] add:[NSNumber numberWithBool:_flag] @@ -711,6 +725,56 @@ static NSString *imap4Separator = nil; reason:@"failed to store message to IMAP4 message"]; } /* result contains 'fetch' key with the current flags */ + + // TODO: need to flush any caches? + return nil; +} + +- (NSException *)copyMailURL:(NSURL *)_srcurl toFolderURL:(NSURL *)_desturl + password:(NSString *)_pwd +{ + SOGoMailConnectionEntry *entry; + NSString *srcname, *destname; + unsigned uid; + id result; + + /* check connection cache */ + + if ((entry = [self entryForURL:_srcurl password:_pwd]) == nil) { + // TODO: better to use an auth exception? + return [NSException exceptionWithHTTPStatus:404 /* Not Found */ + reason:@"did not find IMAP4 folder (no entry)"]; + } + + /* check whether URLs are on different servers */ + + if ([self entryForURL:_desturl password:_pwd] != entry) { + // TODO: find a better error code + return [NSException exceptionWithHTTPStatus:502 /* Bad Gateway */ + reason:@"source and destination on different servers"]; + } + + /* names */ + + srcname = [self imap4FolderNameForURL:_srcurl removeFileName:YES]; + uid = [[[_srcurl path] lastPathComponent] unsignedIntValue]; + destname = [self imap4FolderNameForURL:_desturl]; + + /* select source folder */ + + if (![self selectFolder:srcname inClient:[entry client]]) { + return [NSException exceptionWithHTTPStatus:404 /* Not Found */ + reason:@"did not find source folder"]; + } + + /* copy */ + + result = [[entry client] copyUid:uid toFolder:destname]; + if (![[result valueForKey:@"result"] boolValue]) { + return [NSException exceptionWithHTTPStatus:500 /* Server Error */ + reason:@"copy operation failed"]; + } + return nil; } diff --git a/SOGo/SoObjects/Mailer/SOGoMailObject.m b/SOGo/SoObjects/Mailer/SOGoMailObject.m index 4e55f466..29a4f8d7 100644 --- a/SOGo/SoObjects/Mailer/SOGoMailObject.m +++ b/SOGo/SoObjects/Mailer/SOGoMailObject.m @@ -557,13 +557,27 @@ static BOOL debugBodyStructure = NO; return [NSException exceptionWithHTTPStatus:501 /* Not Implemented */ reason:@"not implemented"]; } + - (NSException *)davCopyToTargetObject:(id)_target newName:(NSString *)_name inContext:(id)_ctx { - [self logWithFormat:@"TODO: should copy mail as '%@' to: %@", - _name, _target]; - return [NSException exceptionWithHTTPStatus:501 /* Not Implemented */ - reason:@"not implemented"]; + /* + Note: this is special because we create SOGoMailObject's even if they do + not exist (for performance reasons). + + Also: we cannot really take a target resource, the ID will be assigned by + the IMAP4 server. + TODO: return a 'location' header instead? + */ + NSURL *destImap4URL; + + destImap4URL = ([_name length] == 0) + ? [[_target container] imap4URL] + : [_target imap4URL]; + + return [[self mailManager] copyMailURL:[self imap4URL] + toFolderURL:destImap4URL + password:[self imap4Password]]; } /* actions */ @@ -589,9 +603,31 @@ static BOOL debugBodyStructure = NO; /* operations */ - (NSException *)delete { + /* + Note: delete is different to DELETEAction: for mails! The 'delete' runs + either flags a message as deleted or moves it to the Trash while + the DELETEAction: really deletes a message (by flagging it as + deleted _AND_ performing an expunge). + */ // TODO: copy to Trash folder - return [[self mailManager] markURLDeleted:[self imap4URL] - password:[self imap4Password]]; + NSException *error; + + error = [[self mailManager] markURLDeleted:[self imap4URL] + password:[self imap4Password]]; + return error; +} +- (id)DELETEAction:(id)_ctx { + NSException *error; + + error = [[self mailManager] markURLDeleted:[self imap4URL] + password:[self imap4Password]]; + if (error != nil) return error; + + error = [[self mailManager] expungeAtURL:[[self container] imap4URL] + password:[self imap4Password]]; + if (error != nil) return error; // TODO: unflag as deleted? + + return [NSNumber numberWithBool:YES]; /* delete was successful */ } /* debugging */ diff --git a/SOGo/SoObjects/Mailer/Version b/SOGo/SoObjects/Mailer/Version index a5afd5ea..a2cadb18 100644 --- a/SOGo/SoObjects/Mailer/Version +++ b/SOGo/SoObjects/Mailer/Version @@ -1,6 +1,6 @@ # Version file -SUBMINOR_VERSION:=82 +SUBMINOR_VERSION:=83 # v0.9.69 requires libNGMime v4.5.210 # v0.9.55 requires libNGExtensions v4.5.136 -- 2.39.2