]> err.no Git - scalable-opengroupware.org/commitdiff
added some mail send functionality
authorhelge <helge@d1b88da0-ebda-0310-925b-ed51d893ca5b>
Wed, 27 Oct 2004 14:59:40 +0000 (14:59 +0000)
committerhelge <helge@d1b88da0-ebda-0310-925b-ed51d893ca5b>
Wed, 27 Oct 2004 14:59:40 +0000 (14:59 +0000)
git-svn-id: http://svn.opengroupware.org/SOGo/trunk@430 d1b88da0-ebda-0310-925b-ed51d893ca5b

SOGo/SoObjects/Mailer/ChangeLog
SOGo/SoObjects/Mailer/SOGoDraftObject.h
SOGo/SoObjects/Mailer/SOGoDraftObject.m
SOGo/SoObjects/Mailer/Version
SOGo/UI/Mailer/ChangeLog
SOGo/UI/Mailer/UIxMailEditor.m
SOGo/UI/Mailer/UIxMailListView.wox
SOGo/UI/Mailer/Version

index f89955bfd892bb0f4002c6a03f5bae902c88433f..50ad743864a5feccb54318c705b428f51706ab17 100644 (file)
@@ -1,5 +1,7 @@
 2004-10-27  Helge Hess  <helge.hess@opengroupware.org>
 
+       * SOGoDraftObject.m: added mail send functionality (v0.9.41)
+
        * SOGoDraftObject.m: added ability to create NGMime objects from draft
          (v0.9.40)
 
index 65d6f200179b443b238af28fa62822e5b910b565..4ad007541585ccebfd12a1ed7b0142bab5b8ad0b 100644 (file)
@@ -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
 
 - (NGMimeMessage *)mimeMessage;
 
+- (NSString *)saveMimeMessageToTemporaryFile;
+- (NSException *)sendMimeMessageAtPath:(NSString *)_path;
+
+- (NSException *)sendMail;
+
+/* operations */
+
+- (NSException *)delete;
+
 @end
 
 #endif /* __Mailer_SOGoDraftObject_H__ */
index 16c893ea6f137fa7dfc1ab5981b411384394dc35..c66123287f7f9439eaed149dea86d8ad63febe87 100644 (file)
 
 #include "SOGoDraftObject.h"
 #include <NGMail/NGMimeMessage.h>
+#include <NGMail/NGMimeMessageGenerator.h>
+#include <NGMail/NGSendMail.h>
 #include <NGMime/NGMimeBodyPart.h>
-#include <NGMime/NGMimeMultipartBody.h>
 #include <NGMime/NGMimeFileData.h>
+#include <NGMime/NGMimeMultipartBody.h>
 #include <NGMime/NGMimeType.h>
 #include <NGExtensions/NSFileManager+Extensions.h>
 #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 */
index 7c8be669329e44202d61ec9dd1818d88a8dedd45..56ded08c4bf9e552f4ff83d548c98a6efc18ffcf 100644 (file)
@@ -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
index aea7aa96306a70b1f47c603dec18094eead8931c..04c476f4473eadf760f7ffa8bc5ebbbde33173e1 100644 (file)
@@ -1,5 +1,11 @@
 2004-10-27  Helge Hess  <helge.hess@opengroupware.org>
 
+       * 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  <helge.hess@opengroupware.org>
index ac23275c6aa907b81583ae7249bf4ae54bf01919..8ad6a2eaa5b26298c301c4731def22469afb8608 100644 (file)
@@ -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;
 }
 
index 669958c142be67319011dbb062d86a328f3aa6be..58fa4a6c6e273213ca78cc87af444e0afaac93ef 100644 (file)
@@ -9,7 +9,7 @@
   className="UIxMailMainFrame"
   title="name"
 >
-  <div class="titlediv">
+  <div class="titlediv" style="white-space: nowrap;">
     <a rsrc:href="tbird_073_mailwelcome.png"
     ><var:string label:value="View" />:</a>, <!-- TODO ;-) -->
     <select name="viewfilter">    <!-- var:popup? -->
index 13cb5e08b9f114416b2d222354b13f39bea0dd94..10d5dbea4aa899e015dc90f07918160662a81276 100644 (file)
@@ -1,6 +1,7 @@
 # $Id$
 
-SUBMINOR_VERSION:=49
+SUBMINOR_VERSION:=50
 
+# v0.9.50 requires NGMime   v4.3.190
 # v0.9.43 requires NGObjWeb v4.3.73
 # v0.9.42 requires NGObjWeb v4.3.72