]> err.no Git - scalable-opengroupware.org/commitdiff
body part fetching
authorhelge <helge@d1b88da0-ebda-0310-925b-ed51d893ca5b>
Sun, 3 Oct 2004 23:06:37 +0000 (23:06 +0000)
committerhelge <helge@d1b88da0-ebda-0310-925b-ed51d893ca5b>
Sun, 3 Oct 2004 23:06:37 +0000 (23:06 +0000)
git-svn-id: http://svn.opengroupware.org/SOGo/trunk@351 d1b88da0-ebda-0310-925b-ed51d893ca5b

SOGo/SoObjects/Mailer/ChangeLog
SOGo/SoObjects/Mailer/SOGoMailBodyPart.h
SOGo/SoObjects/Mailer/SOGoMailBodyPart.m
SOGo/SoObjects/Mailer/SOGoMailObject.h
SOGo/SoObjects/Mailer/SOGoMailObject.m
SOGo/SoObjects/Mailer/Version

index 07a7a049a91d361f3755a7539ca8fa8ec50c69e3..ab7fbe1234c5bbf63018ef91d0444781e51744b6 100644 (file)
@@ -1,5 +1,8 @@
 2004-10-04  Helge Hess  <helge.hess@opengroupware.org>
 
+       * SOGoMailBodyPart.m, SOGoMailObject.m: finished first part fetching
+         support (v0.9.23)
+
        * SOGoMailObject.m: added method to fetch core infos of a mail, added
          various methods to retrieve core info data (like subject or date)
          (v0.9.22)
index 39e130384713c241bd127557017cc7a138c814ff..606f144222cf36bc3bd44a76b50413ed940a0665 100644 (file)
   commands in NGImap4.
 */
 
+@class NSString, NSArray;
 @class SOGoMailObject;
 
 @interface SOGoMailBodyPart : SOGoMailBaseObject
 {
+  NSArray  *pathToPart;
+  NSString *identifier;
+  id       partInfo;
 }
 
 /* hierarchy */
 
 /* IMAP4 */
 
+- (NSString *)bodyPartName;
+- (NSArray *)bodyPartPath;
 - (NSString *)bodyPartIdentifier;
 
+/* part info */
+
+- (id)partInfo;
+
 @end
 
 #endif /* __Mailer_SOGoMailBodyPart_H__ */
index b326af03dc3a15561118c0ed7a6c2f5a3d4c2e62..828eb7a5e36cac31587bc02ec6ed47798d0c4edf 100644 (file)
@@ -27,6 +27,9 @@
 @implementation SOGoMailBodyPart
 
 - (void)dealloc {
+  [self->partInfo   release];
+  [self->identifier release];
+  [self->pathToPart release];
   [super dealloc];
 }
 
 
 /* IMAP4 */
 
-- (NSString *)bodyPartIdentifier {
-  NSMutableString *ms;
+- (NSString *)bodyPartName {
+  NSString *s;
+  NSRange  r;
+
+  s = [self nameInContainer];
+  r = [s rangeOfString:@"."]; /* strip extensions */
+  if (r.length == 0)
+    return s;
+  return [s substringToIndex:r.location];
+}
+
+- (NSArray *)bodyPartPath {
+  NSMutableArray *p;
   id obj;
   
-  ms = [NSMutableString stringWithCapacity:16];
+  if (self->pathToPart != nil)
+    return [self->pathToPart isNotNull] ? self->pathToPart : nil;
+  
+  p = [[NSMutableArray alloc] initWithCapacity:8];
   for (obj = self; [obj isKindOfClass:[SOGoMailBodyPart class]]; 
        obj = [obj container]) {
-    NSString *s;
-    NSRange  r;
-
-    s = [self nameInContainer];
-    r = [s rangeOfString:@"."]; /* strip extensions */
-    if (r.length > 0)
-      s = [s substringToIndex:r.location];
-    
-    if ([ms length] > 0) {
-      [ms insertString:@"." atIndex:0];
-      [ms insertString:s atIndex:0];
-    }
-    else
-      [ms appendString:s];
+    [p insertObject:[obj bodyPartName] atIndex:0];
   }
-  return ms;
+  
+  self->pathToPart = [p copy];
+  [p release];
+  return self->pathToPart;
+}
+
+- (NSString *)bodyPartIdentifier {
+  if (self->identifier != nil)
+    return [self->identifier isNotNull] ? self->identifier : nil;
+  
+  self->identifier =
+    [[[self bodyPartPath] componentsJoinedByString:@"."] copy];
+  return self->identifier;
 }
 
 - (NSURL *)imap4URL {
   return [[self mailObject] imap4URL];
 }
 
+/* part info */
+
+- (id)partInfo {
+  if (self->partInfo != nil)
+    return [self->partInfo isNotNull] ? self->partInfo : nil;
+
+  self->partInfo =
+    [[[self mailObject] lookupInfoForBodyPart:[self bodyPartPath]] retain];
+  return self->partInfo;
+}
+
 /* name lookup */
 
 - (id)lookupImap4BodyPartKey:(NSString *)_key inContext:(id)_ctx {
 
 - (NSData *)fetchBLOB {
   // HEADER, HEADER.FIELDS, HEADER.FIELDS.NOT, MIME, TEXT
-  return [[self mailManager] fetchContentOfBodyPart:[self bodyPartIdentifier]
+  NSString *enc;
+  NSData *data;
+  
+  data = [[self mailManager] fetchContentOfBodyPart:[self bodyPartIdentifier]
                             atURL:[self imap4URL]
                             password:[self imap4Password]];
+  if (data == nil) return nil;
+
+  /* check for content encodings */
+  
+  if ((enc = [[self partInfo] valueForKey:@"encoding"]) != nil) {
+    enc = [enc uppercaseString];
+    
+    if ([enc isEqualToString:@"BASE64"])
+      data = [data dataByDecodingBase64];
+    else if ([enc isEqualToString:@"7BIT"])
+      ; /* keep data as is */ // TODO: do we need to change encodings?
+    else
+      [self debugWithFormat:@"ERROR: unsupported encoding: %@", enc];
+  }
+  
+  return data;
 }
 
 /* WebDAV */
 
+- (NSString *)contentTypeForBodyPartInfo:(id)_info {
+  NSString *mt, *st;
+    
+  if (![_info isNotNull])
+    return nil;
+  
+  mt = [_info valueForKey:@"type"];    if (![mt isNotNull]) return nil;
+  st = [_info valueForKey:@"subtype"]; if (![st isNotNull]) return nil;
+  
+  // TODO: we could add the parameter list?!
+  return [[mt stringByAppendingString:@"/"] stringByAppendingString:st];
+}
+
 - (NSString *)davContentType {
   // TODO: what about the content-type and other headers?
   //       => we could pass them in as the extension? (eg generate 1.gif!)
   NSString *pe;
   
+  /* try type from body structure info */
+  
+  if ((pe = [self contentTypeForBodyPartInfo:[self partInfo]]) != nil)
+    return pe;
+  
+  /* construct type */
+  
   pe = [[self nameInContainer] pathExtension];
   if ([pe length] == 0)
     return @"application/octet-stream";
     return [NSException exceptionWithHTTPStatus:404 /* not found */
                        reason:@"did not find body part"];
   }
-
-  [self debugWithFormat:@"  fetched %d bytes.", [data length]];
   
+  [self debugWithFormat:@"  fetched %d bytes: %@", [data length],
+       [self partInfo]];
+  
+  // TODO: wrong, could be encoded
   r = [_ctx response];
   [r setHeader:[self davContentType] forKey:@"content-type"];
   [r setHeader:[NSString stringWithFormat:@"%d", [data length]]
index 09c01a7569b6c050746dab63cdf1ab7f27920245..d727785ac325e50e56b92274520f074f4872ad79 100644 (file)
@@ -61,6 +61,8 @@
 - (NSArray *)toEnvelopeAddresses;
 - (NSArray *)ccEnvelopeAddresses;
 
+- (id)lookupInfoForBodyPart:(NSArray *)_path;
+
 @end
 
 #endif /* __Mailer_SOGoMailObject_H__ */
index fb29a6a9363e34a4229bedcf67e0ab022dba4bd9..e22a5ca8b10ac501eca7e1c278d721db46a3c477 100644 (file)
@@ -80,6 +80,10 @@ static NSArray *coreInfoKeys = nil;
   return self->coreInfos;
 }
 
+- (id)bodyStructure {
+  return [[self fetchCoreInfos] valueForKey:@"body"];
+}
+
 - (NGImap4Envelope *)envelope {
   return [[self fetchCoreInfos] valueForKey:@"envelope"];
 }
@@ -99,6 +103,29 @@ static NSArray *coreInfoKeys = nil;
   return [[self envelope] cc];
 }
 
+- (id)lookupInfoForBodyPart:(NSArray *)_path {
+  NSEnumerator *pe;
+  NSString *p;
+  id info;
+  
+  info = [self bodyStructure];
+  pe = [_path objectEnumerator];
+  while ((p = [pe nextObject])) {
+    unsigned idx;
+    NSArray  *parts;
+    
+    idx = [p intValue] - 1;
+    
+    parts = [info valueForKey:@"parts"];
+    if (idx >= [parts count]) {
+      [self logWithFormat:@"ERROR: body part index out of bounds: %d", idx+1];
+      return nil;
+    }
+    info = [parts objectAtIndex:idx];
+  }
+  return [info isNotNull] ? info : nil;
+}
+
 /* name lookup */
 
 - (BOOL)isBodyPartKey:(NSString *)_key inContext:(id)_ctx {
index 78237daff645932d2dc39c82a83a2f6fffffed9c..8a19b3e3468cf58736fef0c8c36b3b6210ce79fe 100644 (file)
@@ -1,3 +1,3 @@
 # $Id$
 
-SUBMINOR_VERSION:=22
+SUBMINOR_VERSION:=23