#import <SoObjects/SOGo/NSArray+Utilities.h>
#import <SoObjects/SOGo/NSCalendarDate+SOGo.h>
+#import <SoObjects/SOGo/NSString+Utilities.h>
#import <SoObjects/SOGo/SOGoMailer.h>
#import <SoObjects/SOGo/SOGoUser.h>
+
+#import "NSData+Mail.h"
#import "SOGoMailAccount.h"
#import "SOGoMailFolder.h"
#import "SOGoMailObject.h"
static NSString *contentTypeValue = @"text/plain; charset=utf-8";
static NSString *headerKeys[] = {@"subject", @"to", @"cc", @"bcc",
- @"from", @"replyTo", nil};
-
-@interface NSString (NGMimeHelpers)
-
-- (NSString *) asQPSubjectString: (NSString *) encoding;
-
-@end
-
-@implementation NSString (NGMimeHelpers)
-
-- (NSString *) asQPSubjectString: (NSString *) encoding;
-{
- NSString *qpString, *subjectString;
- NSData *subjectData, *destSubjectData;
-
- subjectData = [self dataUsingEncoding: NSUTF8StringEncoding];
- destSubjectData = [subjectData dataByEncodingQuotedPrintable];
-
- qpString = [[NSString alloc] initWithData: destSubjectData
- encoding: NSASCIIStringEncoding];
- [qpString autorelease];
- if ([qpString length] > [self length])
- subjectString = [NSString stringWithFormat: @"=?%@?Q?%@?=",
- encoding, qpString];
- else
- subjectString = self;
-
- return subjectString;
-}
-
-@end
+ @"from", @"replyTo",
+ nil};
@implementation SOGoDraftObject
text = @"";
sourceURL = nil;
sourceFlag = nil;
+ inReplyTo = nil;
}
return self;
[path release];
[sourceURL release];
[sourceFlag release];
+ [inReplyTo release];
[super dealloc];
}
id headerValue;
unsigned int count;
- for (count = 0; count < 6; count++)
+ for (count = 0; count < 7; count++)
{
headerValue = [newHeaders objectForKey: headerKeys[count]];
if (headerValue)
return text;
}
+- (void) setInReplyTo: (NSString *) newInReplyTo
+{
+ ASSIGN (inReplyTo, newInReplyTo);
+}
+
- (void) setSourceURL: (NSString *) newSourceURL
{
ASSIGN (sourceURL, newSourceURL);
[infos setObject: headers forKey: @"headers"];
if (text)
[infos setObject: text forKey: @"text"];
+ if (inReplyTo)
+ [infos setObject: inReplyTo forKey: @"inReplyTo"];
if (IMAP4ID > -1)
[infos setObject: [NSNumber numberWithInt: IMAP4ID]
forKey: @"IMAP4ID"];
value = [infoDict objectForKey: @"sourceFlag"];
if (value)
[self setSourceFlag: value];
+
+ value = [infoDict objectForKey: @"inReplyTo"];
+ if (value)
+ [self setInReplyTo: value];
}
- (NSString *) relativeImap4Name
}
}
+- (NSArray *) _attachmentBodiesFromPaths: (NSArray *) paths
+ fromResponseFetch: (NSDictionary *) fetch;
+{
+ NSEnumerator *attachmentKeys;
+ NSMutableArray *bodies;
+ NSString *currentKey;
+ NSDictionary *body;
+
+ bodies = [NSMutableArray array];
+
+ attachmentKeys = [paths objectEnumerator];
+ while ((currentKey = [attachmentKeys nextObject]))
+ {
+ body = [fetch objectForKey: [currentKey lowercaseString]];
+ [bodies addObject: [body objectForKey: @"data"]];
+ }
+
+ return bodies;
+}
+
- (void) _fetchAttachments: (NSArray *) parts
fromMail: (SOGoMailObject *) sourceMail
{
unsigned int count, max;
- NSDictionary *currentPart, *attachment, *body;
- NSArray *paths, *result;
+ NSArray *paths, *bodies;
+ NSData *body;
+ NSDictionary *currentInfo;
+ NGHashMap *response;
max = [parts count];
if (max > 0)
{
paths = [parts keysWithFormat: @"BODY[%{path}]"];
- result = [[sourceMail fetchParts: paths] objectForKey: @"fetch"];
+ response = [[sourceMail fetchParts: paths] objectForKey: @"RawResponse"];
+ bodies = [self _attachmentBodiesFromPaths: paths
+ fromResponseFetch: [response objectForKey: @"fetch"]];
for (count = 0; count < max; count++)
{
- currentPart = [parts objectAtIndex: count];
- body = [[result objectAtIndex: count] objectForKey: @"body"];
- attachment = [NSDictionary dictionaryWithObjectsAndKeys:
- [currentPart objectForKey: @"filename"],
- @"filename",
- [currentPart objectForKey: @"mimetype"],
- @"mime-type",
- nil];
- [self saveAttachment: [body objectForKey: @"data"]
- withMetadata: attachment];
+ currentInfo = [parts objectAtIndex: count];
+ body = [[bodies objectAtIndex: count]
+ bodyDataFromEncoding: [currentInfo
+ objectForKey: @"encoding"]];
+ [self saveAttachment: body withMetadata: currentInfo];
}
}
}
- (void) fetchMailForReplying: (SOGoMailObject *) sourceMail
toAll: (BOOL) toAll
{
- NSString *contentForReply;
+ NSString *contentForReply, *msgID;
NSMutableDictionary *info;
+ NGImap4Envelope *sourceEnvelope;
[sourceMail fetchCoreInfos];
info = [NSMutableDictionary dictionaryWithCapacity: 16];
[info setObject: [sourceMail subjectForReply] forKey: @"subject"];
+
+ sourceEnvelope = [sourceMail envelope];
[self _fillInReplyAddresses: info replyToAll: toAll
- envelope: [sourceMail envelope]];
+ envelope: sourceEnvelope];
+ msgID = [sourceEnvelope messageID];
+ if ([msgID length] > 0)
+ [self setInReplyTo: msgID];
contentForReply = [sourceMail contentForReply];
[self setText: contentForReply];
[self setHeaders: info];
// error = [newDraft saveAttachment:content withName:@"forward.mail"];
attachment = [NSDictionary dictionaryWithObjectsAndKeys:
[sourceMail filenameForForward], @"filename",
- @"message/rfc822", @"mime-type",
+ @"message/rfc822", @"mimetype",
nil];
[self saveAttachment: [sourceMail content]
withMetadata: attachment];
- (BOOL) isValidAttachmentName: (NSString *) _name
{
- static NSString *sescape[] = { @"/", @"..", @"~", @"\"", @"'", @" ", nil };
+ static NSString *sescape[] = { @"/", @"..", @"~", @"\"", @"'", nil };
unsigned i;
NSRange r;
withMetadata: (NSDictionary *) metadata
{
NSString *p, *name, *mimeType;
-
+ NSRange r;
+
if (![_attach isNotNull]) {
return [NSException exceptionWithHTTPStatus:400 /* Bad Request */
reason: @"Missing attachment content!"];
return [NSException exceptionWithHTTPStatus:500 /* Server Error */
reason: @"Could not create folder for draft!"];
}
+
name = [metadata objectForKey: @"filename"];
+ r = [name rangeOfString: @"\\"
+ options: NSBackwardsSearch];
+ if (r.length > 0)
+ name = [name substringFromIndex: r.location + 1];
+
if (![self isValidAttachmentName: name])
return [self invalidAttachmentNameError: name];
reason: @"Could not write attachment to draft!"];
}
- mimeType = [metadata objectForKey: @"mime-type"];
+ mimeType = [metadata objectForKey: @"mimetype"];
if ([mimeType length] > 0)
{
p = [self pathToAttachmentWithName:
[map setObjects:[map objectsForKey: @"from"] forKey: @"reply-to"];
/* add subject */
-
+ if (inReplyTo)
+ [map setObject: inReplyTo forKey: @"in-reply-to"];
+
if ([(s = [headers objectForKey: @"subject"]) length] > 0)
[map setObject: [s asQPSubjectString: @"utf-8"]
forKey: @"subject"];