]> err.no Git - sope/commitdiff
improved bodystructure support in envelope classes
authorhelge <helge@e4a50df8-12e2-0310-a44c-efbce7f8a7e3>
Sun, 30 Jan 2005 23:30:21 +0000 (23:30 +0000)
committerhelge <helge@e4a50df8-12e2-0310-a44c-efbce7f8a7e3>
Sun, 30 Jan 2005 23:30:21 +0000 (23:30 +0000)
git-svn-id: http://svn.opengroupware.org/SOPE/trunk@535 e4a50df8-12e2-0310-a44c-efbce7f8a7e3

sope-mime/ChangeLog
sope-mime/NGImap4/ChangeLog
sope-mime/NGImap4/NGImap4Envelope.h
sope-mime/NGImap4/NGImap4Envelope.m
sope-mime/NGImap4/NGImap4EnvelopeAddress.h
sope-mime/NGImap4/NGImap4EnvelopeAddress.m
sope-mime/NGImap4/NGImap4Message+BodyStructure.h
sope-mime/NGImap4/NGImap4ResponseNormalizer.m
sope-mime/NGImap4/NGImap4ResponseParser.m
sope-mime/NGImap4/NGSieveClient.m
sope-mime/Version

index c047e104cdc29ee72677d0f04bc6d0981ebb1de5..a86a36317ef8d3f1eb757ba0b7b2834f0701a046 100644 (file)
@@ -1,3 +1,14 @@
+2005-01-31  Helge Hess  <helge.hess@opengroupware.org>
+
+       * NGImap4: added support for creating envelope objects from body
+         structure dictionaries (v4.5.209)
+
+2005-01-30  Helge Hess  <helge.hess@opengroupware.org>
+
+       * NGImap4: code cleanup in response normalizer (v4.5.208)
+
+       * NGImap4: some fix in the Sieve script upload (v4.5.207)
+
 2005-01-30  Helge Hess  <helge.hess@skyrix.com>
 
        * v4.5.206
index 66b1316deeb1ec69aa2112975c483e5ef8c95172..4f5e08b1292c7669d7c09f584c7f9ea66b74c5a0 100644 (file)
@@ -1,3 +1,14 @@
+2005-01-31  Helge Hess  <helge.hess@opengroupware.org>
+
+       * NGImap4Envelope.m, NGImap4EnvelopeAddress.m: added support for
+         bodystructure dictionaries
+
+2005-01-30  Helge Hess  <helge.hess@opengroupware.org>
+
+       * NGImap4ResponseNormalizer.m: code cleanup
+
+       * NGSieveClient.m: removed a superflous "{" in the script-put call
+
 2005-01-30  Helge Hess  <helge.hess@skyrix.com>
 
        * NGImap4Client.m: minor code cleanups
index 9b78777900a8fc7778a277775857691d87e663ef..484f218ffafdb85a9791440d31f454cbcc6d75f0 100644 (file)
@@ -30,7 +30,7 @@
   Wraps the raw envelope as parsed from an IMAP4 fetch response.
 */
 
-@class NSString, NSArray, NSCalendarDate;
+@class NSString, NSArray, NSCalendarDate, NSDictionary;
 @class NGImap4EnvelopeAddress;
 
 @interface NGImap4Envelope : NSObject
@@ -52,6 +52,8 @@
   sender:(id)_sender replyTo:(id)_replyTo
   to:(NSArray *)_to cc:(NSArray *)_cc bcc:(NSArray *)_bcc;
 
+- (id)initWithBodyStructureInfo:(NSDictionary *)_info;
+
 /* accessors */
 
 - (NSCalendarDate *)date;
index ef9ae6c87f2ba38e586786cbd33b4d5f3a324187..d774dfe5c84c1d51141daf7fdb19598e88bb912b 100644 (file)
 
 #include "NGImap4Envelope.h"
 #include "NGImap4EnvelopeAddress.h"
+#include <NGMime/NGMimeHeaderFieldParser.h>
 #include "imCommon.h"
 
 @implementation NGImap4Envelope
 
+static NGMimeRFC822DateHeaderFieldParser *dateParser = nil;
+
++ (void)initialize {
+  dateParser = [[NGMimeRFC822DateHeaderFieldParser alloc] init];
+}
+
 - (id)newEnvelopeAddressForEMail:(id)_email {
   if (![_email isNotNull])
     return nil;
   
   if ([_email isKindOfClass:[NGImap4EnvelopeAddress class]])
     return [_email copy];
+
+  if ([_email isKindOfClass:[NSDictionary class]]) {
+    /* 
+       A body structure dictionary, contains those keys:
+         hostName, mailboxName, personalName, sourceRoute
+    */
+    return [[NGImap4EnvelopeAddress alloc] initWithBodyStructureInfo:_email];
+  }
   
   _email = [_email stringValue];
   if ([_email length] == 0)
   return self;
 }
 
+- (id)initWithBodyStructureInfo:(NSDictionary *)_info {
+  id lFrom, lReplyTo, lDate;
+  
+  if (![_info isNotNull]) {
+    [self release];
+    return nil;
+  }
+
+  lFrom    = [_info valueForKey:@"from"];
+  lReplyTo = [_info valueForKey:@"reply-to"];
+
+  if ([lFrom isKindOfClass:[NSArray class]])
+    lFrom = [lFrom count] > 0 ? [lFrom objectAtIndex:0] : nil;
+  if ([lReplyTo isKindOfClass:[NSArray class]])
+    lReplyTo = [lReplyTo count] > 0 ? [lReplyTo objectAtIndex:0] : nil;
+  
+  self = [self initWithMessageID:[_info valueForKey:@"messageId"]
+              subject:[_info valueForKey:@"subject"]
+              sender:lFrom replyTo:lReplyTo
+              to:[_info valueForKey:@"to"]
+              cc:[_info valueForKey:@"cc"]
+              bcc:[_info valueForKey:@"bcc"]];
+  if (self == nil) return nil;
+
+  /* extended ivars */
+  
+  self->inReplyTo = [[_info valueForKey:@"in-reply-to"] copy];
+  
+  if ([(lDate = [_info valueForKey:@"date"]) isNotNull]) {
+    if ([lDate isKindOfClass:[NSDate class]])
+      self->date = [lDate copy];
+    else
+      self->date = [[dateParser parseValue:lDate ofHeaderField:@"date"] copy];
+  }
+  
+  return self;
+}
+
 - (void)dealloc {
   [self->date      release];
   [self->subject   release];
index 0a331ff32ae699bf387d6dba692bb30b69aae360..28cb0d4899c4e27fe612b2c234ffb72b02a05fb3 100644 (file)
@@ -31,7 +31,7 @@
   response.
 */
 
-@class NSString;
+@class NSString, NSDictionary;
 
 @interface NGImap4EnvelopeAddress : NSObject < NSCopying >
 {
 
 - (id)initWithPersonalName:(NSString *)_pname sourceRoute:(NSString *)_route
   mailbox:(NSString *)_mbox host:(NSString *)_host;
+
 - (id)initWithString:(NSString *)_str;
 
+- (id)initWithBodyStructureInfo:(NSDictionary *)_info;
+
 /* accessors */
 
 - (NSString *)personalName;
index c1ac9a31cb2bb22d4dd929f00ca1ffbed2bfabaa..98d87a16500cb41bc96f3e2263f3d9c55cd70e7a 100644 (file)
               mailbox:_str host:nil];
 }
 
+- (id)initWithBodyStructureInfo:(NSDictionary *)_info {
+  if (![_info isNotNull]) {
+    [self release];
+    return nil;
+  }
+  return [self initWithPersonalName:[_info valueForKey:@"personalName"]
+              sourceRoute:[_info valueForKey:@"sourceRoute"]
+              mailbox:[_info valueForKey:@"mailboxName"]
+              host:[_info valueForKey:@"hostName"]];
+}
+
 - (void)dealloc {
   [self->personalName release];
   [self->sourceRoute  release];
index 288dd468b5be4ae96ce1848d6ec96120bb0bd23d..3fe0874aa520447c0e58702e799dd1b25c224fc5 100644 (file)
@@ -84,19 +84,19 @@ static id _buildMessage(id self, NSURL *_baseUrl, NSDictionary *_dict) {
 
   map = [NGMutableHashMap hashMapWithCapacity:4];
 
-  if ((value = [_dict objectForKey:@"subject"])) {
+  if ([(value = [_dict objectForKey:@"subject"]) isNotNull])
     [map setObject:value forKey:Fields->subject];
-  }
-  if ((value = [_dict objectForKey:@"messageId"])) {
+  
+  if ([(value = [_dict objectForKey:@"messageId"]) isNotNull])
     [map setObject:value forKey:Fields->messageID];
-  }
-  if ((value = [_dict objectForKey:@"in-reply-to"])) {
+  
+  if ([(value = [_dict objectForKey:@"in-reply-to"]) isNotNull])
     [map setObject:value forKey:@"in-reply-to"];
-  }
-  if ((value = [_dict objectForKey:Fields->contentLength])) {
+  
+  if ([(value = [_dict objectForKey:Fields->contentLength]) isNotNull])
     [map setObject:value forKey:Fields->contentLength];
-  }
-  if ((value = [_dict objectForKey:@"date"])) {
+  
+  if ([(value = [_dict objectForKey:@"date"]) isNotNull]) {
     NSCalendarDate *d;
 
     if ((d = [NSCalendarDate calendarDateWithRfc822DateString:value])) 
index 09a61b98cd20ceb8a08e25ec98eb2e1e29406afd..8863cac120b948c8d8e4faabd043bb42861d8081 100644 (file)
@@ -285,63 +285,7 @@ static int      LogImapEnabled = -1;
   dictionary for each response to the 'fetch' key of the normalized response
   dictionary (as retrieved by 'normalizeResponse')
 */
-- (NSDictionary *)normalizeFetchResponse:(NGHashMap *)_map {
-  /*
-    Raw Sample (Courier):
-      C[0x8b4e754]: 27 uid fetch 635 (body)
-      S[0x8c8b4e4]: * 627 FETCH (UID 635 BODY 
-        ("text" "plain" ("charset" "iso-8859-1" "format" "flowed") 
-        NIL NIL "8bit" 2474 51))
-      S[0x8c8b4e4]: * 627 FETCH (FLAGS (\Seen))
-      S[0x8c8b4e4]: 27 OK FETCH completed.
-    - this results in two result records (one for UID and one for FLAGS)
-      TODO: should we coalesce?
-
-    Raw Sample (Cyrus):
-      C[0x8c8ec64]: 14 uid fetch 20199 (body)
-      S[0x8da46a4]: * 93 FETCH (UID 20199 BODY 
-        ((("TEXT" "PLAIN" ("CHARSET" "utf-8") NIL "signed data" "7BIT" 691 17)
-          ("APPLICATION" "PKCS7-SIGNATURE" ("NAME" "smime.p7s") NIL 
-           "signature" "BASE64" 2936) "SIGNED")
-          ("TEXT" "PLAIN" ("CHARSET" "us-ascii") NIL NIL "7BIT" 146 4) 
-          "MIXED"))
-      S[0x8da46a4]: 14 OK Completed
-    - UID key is mapped to 'uid'
-    - BODY key is mapped to a nested body structure
-    - MSN is added for the '93'? (TODO: make sure this is the case)
-
-    Sample returns (not for the above code!):
-      {
-        // other message stuff
-        fetch = (
-          {
-            header = < NSData containing the header >;
-            size   = 3314;
-            uid    = 20187;
-            msn    = 72;
-            flags  = ( answered, deleted, seen );
-          },
-          ... for each fetch message ...
-        )
-      }
-  */
-  NSMutableDictionary *result;
-  id                  obj;
-  NSEnumerator        *enumerator;
-  NSMutableArray      *fetchResponseRecords;
-
-  // TODO: describe what the generic normalize does.
-  //       Q: do we need to run this before the following section or can we
-  //          call this method just before [result setObject:...] ? (I guess
-  //          the latter, because 'result' is not accessed, but who knows
-  //          about side effects in this JR cruft :-( )
-  result = [self normalizeResponse:_map];
-  
-  fetchResponseRecords = [[NSMutableArray alloc] initWithCapacity:512];
-  
-  /* walk over each response tag which is keyed by 'fetch' in the hashmap */
-  enumerator = [_map objectEnumeratorForKey:@"fetch"];
-  while ((obj = [enumerator nextObject])) {
+- (NSDictionary *)normalizeFetchResponsePart:(id)obj {
     // TODO: shouldn't we use a specific object instead of NSDict for that?
     NSDictionary *entry;
     NSEnumerator *keyEnum;
@@ -361,7 +305,7 @@ static int      LogImapEnabled = -1;
     
     // TODO: this should add some error handling wrt the count?
     // TODO: this could return multiple values for the same key?! => fix that
-    while ((key = [keyEnum nextObject]) && (count < 9)) {
+    while (((key = [keyEnum nextObject]) != nil) && (count < 9)) {
       unsigned klen;
       unichar  c;
       
@@ -440,7 +384,68 @@ static int      LogImapEnabled = -1;
       ? [[DictClass alloc] initWithObjects:values forKeys:keys count:count]
       : nil;
     
-    if (entry == nil)
+    return entry; /* returns retained object! */
+}
+- (NSDictionary *)normalizeFetchResponse:(NGHashMap *)_map {
+  /*
+    Raw Sample (Courier):
+      C[0x8b4e754]: 27 uid fetch 635 (body)
+      S[0x8c8b4e4]: * 627 FETCH (UID 635 BODY 
+        ("text" "plain" ("charset" "iso-8859-1" "format" "flowed") 
+        NIL NIL "8bit" 2474 51))
+      S[0x8c8b4e4]: * 627 FETCH (FLAGS (\Seen))
+      S[0x8c8b4e4]: 27 OK FETCH completed.
+    - this results in two result records (one for UID and one for FLAGS)
+      TODO: should we coalesce?
+
+    Raw Sample (Cyrus):
+      C[0x8c8ec64]: 14 uid fetch 20199 (body)
+      S[0x8da46a4]: * 93 FETCH (UID 20199 BODY 
+        ((("TEXT" "PLAIN" ("CHARSET" "utf-8") NIL "signed data" "7BIT" 691 17)
+          ("APPLICATION" "PKCS7-SIGNATURE" ("NAME" "smime.p7s") NIL 
+           "signature" "BASE64" 2936) "SIGNED")
+          ("TEXT" "PLAIN" ("CHARSET" "us-ascii") NIL NIL "7BIT" 146 4) 
+          "MIXED"))
+      S[0x8da46a4]: 14 OK Completed
+    - UID key is mapped to 'uid'
+    - BODY key is mapped to a nested body structure
+    - MSN is added for the '93'? (TODO: make sure this is the case)
+
+    Sample returns (not for the above code!):
+      {
+        // other message stuff
+        fetch = (
+          {
+            header = < NSData containing the header >;
+            size   = 3314;
+            uid    = 20187;
+            msn    = 72;
+            flags  = ( answered, deleted, seen );
+          },
+          ... for each fetch message ...
+        )
+      }
+  */
+  NSMutableDictionary *result;
+  id                  obj;
+  NSEnumerator        *enumerator;
+  NSMutableArray      *fetchResponseRecords;
+
+  // TODO: describe what the generic normalize does.
+  //       Q: do we need to run this before the following section or can we
+  //          call this method just before [result setObject:...] ? (I guess
+  //          the latter, because 'result' is not accessed, but who knows
+  //          about side effects in this JR cruft :-( )
+  result = [self normalizeResponse:_map];
+  
+  fetchResponseRecords = [[NSMutableArray alloc] initWithCapacity:512];
+  
+  /* walk over each response tag which is keyed by 'fetch' in the hashmap */
+  enumerator = [_map objectEnumeratorForKey:@"fetch"];
+  while ((obj = [enumerator nextObject]) != nil) {
+    NSDictionary *entry;
+    
+    if ((entry = [self normalizeFetchResponsePart:obj]) == nil)
       continue;
     
     [fetchResponseRecords addObject:entry];
index 7e1c12030cb41f3afadef67e93b8c6ddf37baf0d..7fd988d7955a30229f7cb8a6ecef51ed422d492e 100644 (file)
@@ -1039,7 +1039,7 @@ static BOOL _parseThreadResponse(NGImap4ResponseParser *self,
        mailbox name
        hostname
      eg: 
-       (NIL NIL "helge.hess" "opengroupware.org")
+       ("Helge Hess" NIL "helge.hess" "opengroupware.org")
   */
   NGImap4EnvelopeAddress *address;
   NSString *pname, *route, *mailbox, *host;
@@ -1080,6 +1080,11 @@ static BOOL _parseThreadResponse(NGImap4ResponseParser *self,
 }
 
 - (NSArray *)_parseEnvelopeAddressStructures {
+  /*
+    Parses an array of envelopes, most common:
+      ((NIL NIL "users-admin" "opengroupware.org"))
+    (just one envelope in the array)
+  */
   NSMutableArray *ma;
   
   if (_la(self, 0) != '(') {
index b37496046912b9fcb403e4b825858e3611bc75ef..1f4c673af739cf446534588ef5cf0d6ff7639323 100644 (file)
@@ -419,7 +419,7 @@ static BOOL     debugImap4         = NO;
   
   s = @"PUTSCRIPT \"";
   s = [s stringByAppendingString:_name];
-  s = [s stringByAppendingString:@"\" {"];
+  s = [s stringByAppendingString:@"\" "];
   s = [s stringByAppendingFormat:@"{%d+}\r\n%@", [_script length], _script];
   s = [s stringByAppendingString:@"\r\n"];
   map = [self processCommand:s];
index 74d1c71b3eb2d2568a1777462a089b76c39b45eb..87dde2f4fa0d2e5a4bf075edbb0b1f8ba9f765d8 100644 (file)
@@ -2,6 +2,6 @@
 
 MAJOR_VERSION:=4
 MINOR_VERSION:=5
-SUBMINOR_VERSION:=206
+SUBMINOR_VERSION:=209
 
 # v4.2.149 requires libNGStreams v4.2.34