From: helge Date: Wed, 27 Oct 2004 14:59:40 +0000 (+0000) Subject: added some mail send functionality X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3a21cc2a6604566e29a33d4fbebad0457cf8e95c;p=scalable-opengroupware.org added some mail send functionality git-svn-id: http://svn.opengroupware.org/SOGo/trunk@430 d1b88da0-ebda-0310-925b-ed51d893ca5b --- diff --git a/SOGo/SoObjects/Mailer/ChangeLog b/SOGo/SoObjects/Mailer/ChangeLog index f89955bf..50ad7438 100644 --- a/SOGo/SoObjects/Mailer/ChangeLog +++ b/SOGo/SoObjects/Mailer/ChangeLog @@ -1,5 +1,7 @@ 2004-10-27 Helge Hess + * SOGoDraftObject.m: added mail send functionality (v0.9.41) + * SOGoDraftObject.m: added ability to create NGMime objects from draft (v0.9.40) diff --git a/SOGo/SoObjects/Mailer/SOGoDraftObject.h b/SOGo/SoObjects/Mailer/SOGoDraftObject.h index 65d6f200..4ad00754 100644 --- a/SOGo/SoObjects/Mailer/SOGoDraftObject.h +++ b/SOGo/SoObjects/Mailer/SOGoDraftObject.h @@ -34,7 +34,7 @@ folder are some kind of "mail creation transaction". */ -@class NSString, NSArray, NSDictionary, NSData; +@class NSString, NSArray, NSDictionary, NSData, NSException; @class NGMimeMessage; @interface SOGoDraftObject : SOGoMailBaseObject @@ -57,6 +57,15 @@ - (NGMimeMessage *)mimeMessage; +- (NSString *)saveMimeMessageToTemporaryFile; +- (NSException *)sendMimeMessageAtPath:(NSString *)_path; + +- (NSException *)sendMail; + +/* operations */ + +- (NSException *)delete; + @end #endif /* __Mailer_SOGoDraftObject_H__ */ diff --git a/SOGo/SoObjects/Mailer/SOGoDraftObject.m b/SOGo/SoObjects/Mailer/SOGoDraftObject.m index 16c893ea..c6612328 100644 --- a/SOGo/SoObjects/Mailer/SOGoDraftObject.m +++ b/SOGo/SoObjects/Mailer/SOGoDraftObject.m @@ -21,9 +21,11 @@ #include "SOGoDraftObject.h" #include +#include +#include #include -#include #include +#include #include #include #include "common.h" @@ -32,6 +34,8 @@ static NGMimeType *TextPlainType = nil; static NGMimeType *MultiMixedType = nil; +static BOOL draftDeleteDisabled = NO; // for debugging +static BOOL debugOn = NO; + (void)initialize { TextPlainType = [[NGMimeType mimeType:@"text" subType:@"plain"] copy]; @@ -120,6 +124,14 @@ static NGMimeType *MultiMixedType = nil; return self->info; } +/* accessors */ + +- (NSString *)sender { + return [[self fetchInfo] objectForKey:@"from"]; +} + +/* attachments */ + - (NSArray *)fetchAttachmentNames { NSMutableArray *ma; NSFileManager *fm; @@ -412,14 +424,17 @@ static NGMimeType *MultiMixedType = nil; /* add senders */ - if ((s = [lInfo objectForKey:@"from"]) != nil) + if ([(s = [lInfo objectForKey:@"from"]) length] > 0) [map setObject:s forKey:@"from"]; - if ((s = [lInfo objectForKey:@"replyTo"]) != nil) + + if ([(s = [lInfo objectForKey:@"replyTo"]) length] > 0) + [map setObject:s forKey:@"reply-to"]; + else if ([(s = [lInfo objectForKey:@"from"]) length] > 0) [map setObject:s forKey:@"reply-to"]; /* add subject */ - if ((s = [lInfo objectForKey:@"subject"]) != nil) + if ([(s = [lInfo objectForKey:@"subject"]) length] > 0) [map setObject:s forKey:@"subject"]; /* add standard headers */ @@ -446,14 +461,14 @@ static NGMimeType *MultiMixedType = nil; if ((map = [self mimeHeaderMap]) == nil) return nil; - [self logWithFormat:@"MIME Envelope: %@", map]; + [self debugWithFormat:@"MIME Envelope: %@", map]; if ((bodyParts = [self bodyPartsForAllAttachments]) == nil) { [self logWithFormat: @"ERROR: could not create body parts for attachments!"]; return nil; // TODO: improve error handling, return exception } - [self logWithFormat:@"attachments: %@", bodyParts]; + [self debugWithFormat:@"attachments: %@", bodyParts]; if ([bodyParts count] == 0) { /* no attachments */ @@ -464,11 +479,178 @@ static NGMimeType *MultiMixedType = nil; message = [self mimeMultiPartMessageWithHeaderMap:map andBodyParts:bodyParts]; } - [self logWithFormat:@"message: %@", message]; + [self debugWithFormat:@"message: %@", message]; message = [message retain]; [pool release]; return [message autorelease]; } +- (NSString *)saveMimeMessageToTemporaryFile { + NGMimeMessageGenerator *gen; + NSAutoreleasePool *pool; + NGMimeMessage *message; + NSString *tmpPath; + + pool = [[NSAutoreleasePool alloc] init]; + + message = [self mimeMessage]; + if (![message isNotNull]) + return nil; + + gen = [[NGMimeMessageGenerator alloc] init]; + tmpPath = [[gen generateMimeFromPartToFile:message] copy]; + [gen release]; gen = nil; + + [pool release]; + return [tmpPath autorelease]; +} + +- (void)deleteTemporaryMessageFile:(NSString *)_path { + NSFileManager *fm; + + if (![_path isNotNull]) + return; + + fm = [NSFileManager defaultManager]; + if (![fm fileExistsAtPath:_path]) + return; + + [fm removeFileAtPath:_path handler:nil]; +} + +- (NSArray *)allRecipients { + NSDictionary *lInfo; + NSMutableArray *ma; + NSArray *tmp; + + if ((lInfo = [self fetchInfo]) == nil) + return nil; + + ma = [NSMutableArray arrayWithCapacity:16]; + if ((tmp = [lInfo objectForKey:@"to"]) != nil) + [ma addObjectsFromArray:tmp]; + if ((tmp = [lInfo objectForKey:@"cc"]) != nil) + [ma addObjectsFromArray:tmp]; + if ((tmp = [lInfo objectForKey:@"bcc"]) != nil) + [ma addObjectsFromArray:tmp]; + return ma; +} + +- (NSException *)sendMimeMessageAtPath:(NSString *)_path { + static NGSendMail *mailer = nil; + NSArray *recipients; + NSString *from; + + /* validate */ + + recipients = [self allRecipients]; + from = [self sender]; + if ([recipients count] == 0) { + return [NSException exceptionWithHTTPStatus:500 /* server error */ + reason:@"draft has no recipients set!"]; + } + if ([from length] == 0) { + return [NSException exceptionWithHTTPStatus:500 /* server error */ + reason:@"draft has no sender (from) set!"]; + } + + /* setup mailer object */ + + if (mailer == nil) + mailer = [[NGSendMail sharedSendMail] retain]; + if (![mailer isSendMailAvailable]) { + [self logWithFormat:@"ERROR: missing sendmail binary!"]; + return [NSException exceptionWithHTTPStatus:500 /* server error */ + reason:@"did not find sendmail binary!"]; + } + + /* send mail */ + + return [mailer sendMailAtPath:_path toRecipients:recipients sender:from]; +} + +- (NSException *)sendMail { + NSException *error; + NSString *tmpPath; + + /* save MIME mail to file */ + + tmpPath = [self saveMimeMessageToTemporaryFile]; + if (![tmpPath isNotNull]) { + return [NSException exceptionWithHTTPStatus:500 /* server error */ + reason:@"could not save MIME message for draft!"]; + } + + /* send mail */ + error = [self sendMimeMessageAtPath:tmpPath]; + + /* delete temporary file */ + [self deleteTemporaryMessageFile:tmpPath]; + + return error; +} + +/* operations */ + +- (NSException *)delete { + NSFileManager *fm; + NSString *p, *sp; + NSEnumerator *e; + + if ((fm = [self spoolFileManager]) == nil) { + [self logWithFormat:@"ERROR: missing spool file manager!"]; + return [NSException exceptionWithHTTPStatus:500 /* server error */ + reason:@"missing spool file manager!"]; + } + + p = [self draftFolderPath]; + if (![fm fileExistsAtPath:p]) { + return [NSException exceptionWithHTTPStatus:404 /* not found */ + reason:@"did not find draft!"]; + } + + e = [[fm directoryContentsAtPath:p] objectEnumerator]; + while ((sp = [e nextObject])) { + sp = [p stringByAppendingPathComponent:sp]; + if (draftDeleteDisabled) { + [self logWithFormat:@"should delete draft file %@ ...", sp]; + continue; + } + + if (![fm removeFileAtPath:sp handler:nil]) { + return [NSException exceptionWithHTTPStatus:500 /* server error */ + reason:@"failed to delete draft!"]; + } + } + + if (draftDeleteDisabled) { + [self logWithFormat:@"should delete draft directory: %@", p]; + } + else { + if (![fm removeFileAtPath:p handler:nil]) { + return [NSException exceptionWithHTTPStatus:500 /* server error */ + reason:@"failed to delete draft directory!"]; + } + } + return nil; +} + +/* actions */ + +- (id)DELETEAction:(id)_ctx { + NSException *error; + + if ((error = [self delete]) != nil) + return error; + + return [NSNumber numberWithBool:YES]; /* delete worked out ... */ +} + +/* debugging */ + +- (BOOL)isDebuggingEnabled { + return debugOn; +} + @end /* SOGoDraftObject */ diff --git a/SOGo/SoObjects/Mailer/Version b/SOGo/SoObjects/Mailer/Version index 7c8be669..56ded08c 100644 --- a/SOGo/SoObjects/Mailer/Version +++ b/SOGo/SoObjects/Mailer/Version @@ -1,6 +1,7 @@ # Version file -SUBMINOR_VERSION:=40 +SUBMINOR_VERSION:=41 +# v0.9.51 requires NGMime v4.3.190 # v0.9.35 requires SOGoLogic v0.9.24 # v0.9.34 requires SOGoLogic v0.9.22 diff --git a/SOGo/UI/Mailer/ChangeLog b/SOGo/UI/Mailer/ChangeLog index aea7aa96..04c476f4 100644 --- a/SOGo/UI/Mailer/ChangeLog +++ b/SOGo/UI/Mailer/ChangeLog @@ -1,5 +1,11 @@ 2004-10-27 Helge Hess + * v0.9.49 + + * UIxMailEditor.m: send mail using draft object + + * UIxMailListView.wox: do not wrap title line + * UIxMailEditor.m: added send related code (v0.9.49) 2004-10-26 Helge Hess diff --git a/SOGo/UI/Mailer/UIxMailEditor.m b/SOGo/UI/Mailer/UIxMailEditor.m index ac23275c..8ad6a2ea 100644 --- a/SOGo/UI/Mailer/UIxMailEditor.m +++ b/SOGo/UI/Mailer/UIxMailEditor.m @@ -37,7 +37,6 @@ NSArray *bcc; NSString *subject; NSString *text; - NSString *tmpMessagePath; } @end @@ -58,23 +57,7 @@ static NSArray *infoKeys = nil; nil]; } -- (void)deleteTemporaryMessageFile { - NSFileManager *fm; - - if (![self->tmpMessagePath isNotNull]) - return; - - fm = [NSFileManager defaultManager]; - if (![fm fileExistsAtPath:self->tmpMessagePath]) - return; - - [fm removeFileAtPath:self->tmpMessagePath handler:nil]; -} - - (void)dealloc { - [self deleteTemporaryMessageFile]; - [self->tmpMessagePath release]; - [self->text release]; [self->subject release]; [self->to release]; @@ -145,28 +128,24 @@ static NSArray *infoKeys = nil; return [self valuesForKeys:infoKeys]; } -/* MIME message */ - -- (NSString *)saveMessageToTemporaryFile:(NGMimeMessage *)_message { - NGMimeMessageGenerator *gen; - NSString *path; - - if (![_message isNotNull]) - return nil; - - gen = [[NGMimeMessageGenerator alloc] init]; - path = [gen generateMimeFromPartToFile:_message]; - [gen release]; gen = nil; - - return path; -} - /* requests */ - (BOOL)shouldTakeValuesFromRequest:(WORequest *)_rq inContext:(WOContext*)_c{ return YES; } +/* IMAP4 store */ + +- (void)patchFlagsInStore { + /* + Flags we should set: + if the draft is a reply => [message markAnswered] + if the draft is a forward => [message addFlag:@"forwarded"] + + This is hard, we would need to find the original message in Cyrus. + */ +} + /* actions */ - (BOOL)_saveFormInfo { @@ -203,7 +182,7 @@ static NSArray *infoKeys = nil; } - (id)sendAction { - NGMimeMessage *message; + NSException *error; /* first, save form data */ @@ -212,37 +191,25 @@ static NSArray *infoKeys = nil; /* then, send mail */ - if ((message = [[self clientObject] mimeMessage]) == nil) { - return [NSException exceptionWithHTTPStatus:500 /* server error */ - reason:@"could not create MIME message for draft!"]; + if ((error = [[self clientObject] sendMail]) != nil) { + // TODO: improve error handling + return error; } - self->tmpMessagePath = [[self saveMessageToTemporaryFile:message] copy]; - if (![self->tmpMessagePath isNotNull]) { - return [NSException exceptionWithHTTPStatus:500 /* server error */ - reason:@"could not save MIME message for draft!"]; - } - - [self logWithFormat:@"saved message to: %@", self->tmpMessagePath]; - - [self logWithFormat:@"TODO: send mail ..."]; - - /* - Flags we should set: - if the draft is a reply => [message markAnswered] - if the draft is a forward => [message addFlag:@"forwarded"] - - This is hard, we would need to find the original message in Cyrus. - */ + /* patch flags in store for replies etc */ - /* delete draft */ + [self patchFlagsInStore]; /* finally store in Sent */ [self logWithFormat:@"TODO: store mail in Sent folder ..."]; + /* delete draft */ + + if ((error = [[self clientObject] delete]) != nil) + return error; + // if everything is ok, close the window (send a JS closing the Window) - [self deleteTemporaryMessageFile]; return self; } diff --git a/SOGo/UI/Mailer/UIxMailListView.wox b/SOGo/UI/Mailer/UIxMailListView.wox index 669958c1..58fa4a6c 100644 --- a/SOGo/UI/Mailer/UIxMailListView.wox +++ b/SOGo/UI/Mailer/UIxMailListView.wox @@ -9,7 +9,7 @@ className="UIxMailMainFrame" title="name" > -
+
:,