2007-08-16 23:57:35 +02:00
|
|
|
/* SOGoMailObject+Draft.m - this file is part of SOGo
|
|
|
|
*
|
2008-08-18 17:21:23 +02:00
|
|
|
* Copyright (C) 2007-2008 Inverse groupe conseil
|
2007-08-16 23:57:35 +02:00
|
|
|
*
|
|
|
|
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
|
|
|
*
|
|
|
|
* This file is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2, or (at your option)
|
|
|
|
* any later version.
|
|
|
|
*
|
|
|
|
* This file is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; see the file COPYING. If not, write to
|
|
|
|
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
|
|
* Boston, MA 02111-1307, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#import <Foundation/NSArray.h>
|
2008-07-04 18:06:09 +02:00
|
|
|
#import <Foundation/NSDictionary.h>
|
|
|
|
#import <Foundation/NSEnumerator.h>
|
2008-09-05 17:29:42 +02:00
|
|
|
#import <Foundation/NSUserDefaults.h>
|
2007-08-16 23:57:35 +02:00
|
|
|
|
2007-08-22 17:14:06 +02:00
|
|
|
#import <NGObjWeb/WOApplication.h>
|
2007-11-08 21:35:09 +01:00
|
|
|
#import <NGObjWeb/WOResponse.h>
|
2007-08-22 17:14:06 +02:00
|
|
|
#import <NGObjWeb/WOContext+SoObjects.h>
|
2007-08-16 23:57:35 +02:00
|
|
|
#import <NGExtensions/NSString+misc.h>
|
|
|
|
#import <NGExtensions/NSObject+Logs.h>
|
|
|
|
|
2007-10-30 20:46:48 +01:00
|
|
|
#import <SoObjects/SOGo/NSArray+Utilities.h>
|
2007-08-22 17:14:06 +02:00
|
|
|
#import <SoObjects/SOGo/SOGoUser.h>
|
|
|
|
|
2007-10-30 20:46:48 +01:00
|
|
|
#import "NSString+Mail.h"
|
2007-08-22 17:14:06 +02:00
|
|
|
#import "SOGoMailForward.h"
|
2007-08-16 23:57:35 +02:00
|
|
|
#import "SOGoMailObject+Draft.h"
|
2007-11-01 21:22:56 +01:00
|
|
|
#import "SOGoMailReply.h"
|
2007-08-16 23:57:35 +02:00
|
|
|
|
|
|
|
#define maxFilenameLength 64
|
|
|
|
|
|
|
|
@implementation SOGoMailObject (SOGoDraftObjectExtensions)
|
|
|
|
|
2008-09-05 17:29:42 +02:00
|
|
|
- (BOOL) useOutlookStyleReplies
|
2008-09-05 17:07:24 +02:00
|
|
|
{
|
|
|
|
NSUserDefaults *ud;
|
2008-09-05 17:29:42 +02:00
|
|
|
static int useOutlookStyleReplies = -1;
|
2008-09-05 17:07:24 +02:00
|
|
|
|
2008-09-05 17:29:42 +02:00
|
|
|
if (useOutlookStyleReplies == -1)
|
|
|
|
{
|
|
|
|
ud = [NSUserDefaults standardUserDefaults];
|
|
|
|
useOutlookStyleReplies = [ud boolForKey: @"SOGoMailUseOutlookStyleReplies"];
|
|
|
|
}
|
|
|
|
|
|
|
|
return (useOutlookStyleReplies);
|
2008-09-05 17:07:24 +02:00
|
|
|
}
|
|
|
|
|
2007-08-16 23:57:35 +02:00
|
|
|
- (NSString *) subjectForReply
|
|
|
|
{
|
|
|
|
static NSString *replyPrefixes[] = {
|
|
|
|
@"Re:", // regular
|
|
|
|
@"RE:", // Outlook v11 (English?)
|
|
|
|
@"AW:", // German Outlook v11
|
|
|
|
@"Re[", // numbered Re, eg "Re[2]:"
|
|
|
|
nil
|
|
|
|
};
|
|
|
|
BOOL hasPrefix;
|
|
|
|
unsigned int i;
|
|
|
|
NSString *subject, *newSubject;
|
|
|
|
|
|
|
|
hasPrefix = NO;
|
|
|
|
|
2007-11-05 17:37:17 +01:00
|
|
|
subject = [self decodedSubject];
|
2007-08-16 23:57:35 +02:00
|
|
|
i = 0;
|
|
|
|
while (!hasPrefix && replyPrefixes[i])
|
|
|
|
if ([subject hasPrefix: replyPrefixes[i]])
|
|
|
|
hasPrefix = YES;
|
|
|
|
else
|
|
|
|
i++;
|
|
|
|
|
|
|
|
if (hasPrefix)
|
|
|
|
newSubject = subject;
|
|
|
|
else
|
|
|
|
newSubject = [NSString stringWithFormat: @"Re: %@", subject];
|
|
|
|
|
|
|
|
return newSubject;
|
|
|
|
}
|
|
|
|
|
2008-09-05 18:50:22 +02:00
|
|
|
|
2007-10-30 20:46:48 +01:00
|
|
|
- (NSString *) _contentForEditingFromKeys: (NSArray *) keys
|
2007-08-16 23:57:35 +02:00
|
|
|
{
|
2007-10-30 20:46:48 +01:00
|
|
|
NSArray *types;
|
|
|
|
NSDictionary *parts;
|
2007-11-05 18:30:44 +01:00
|
|
|
NSString *rawPart, *content, *contentKey;
|
2007-10-30 20:46:48 +01:00
|
|
|
int index;
|
|
|
|
BOOL htmlContent;
|
|
|
|
|
2007-11-16 22:15:38 +01:00
|
|
|
content = @"";
|
|
|
|
|
2007-10-30 20:46:48 +01:00
|
|
|
if ([keys count])
|
2007-08-16 23:57:35 +02:00
|
|
|
{
|
2007-10-30 20:46:48 +01:00
|
|
|
types = [keys objectsForKey: @"mimeType"];
|
|
|
|
index = [types indexOfObject: @"text/plain"];
|
|
|
|
if (index == NSNotFound)
|
2007-08-16 23:57:35 +02:00
|
|
|
{
|
2007-10-30 20:46:48 +01:00
|
|
|
index = [types indexOfObject: @"text/html"];
|
|
|
|
htmlContent = YES;
|
2007-08-16 23:57:35 +02:00
|
|
|
}
|
2007-11-05 18:30:44 +01:00
|
|
|
else
|
|
|
|
htmlContent = NO;
|
2007-11-16 22:15:38 +01:00
|
|
|
|
|
|
|
if (index != NSNotFound)
|
2007-10-30 20:46:48 +01:00
|
|
|
{
|
2007-11-05 18:30:44 +01:00
|
|
|
contentKey = [keys objectAtIndex: index];
|
|
|
|
parts = [self fetchPlainTextStrings:
|
|
|
|
[NSArray arrayWithObject: contentKey]];
|
2007-11-16 22:15:38 +01:00
|
|
|
if ([parts count] > 0)
|
|
|
|
{
|
|
|
|
rawPart = [[parts allValues] objectAtIndex: 0];
|
|
|
|
if (htmlContent)
|
|
|
|
content = [rawPart htmlToText];
|
|
|
|
else
|
|
|
|
content = rawPart;
|
|
|
|
}
|
2007-10-30 20:46:48 +01:00
|
|
|
}
|
2007-08-16 23:57:35 +02:00
|
|
|
}
|
2008-09-05 18:50:22 +02:00
|
|
|
|
2007-10-30 20:46:48 +01:00
|
|
|
return content;
|
2007-08-16 23:57:35 +02:00
|
|
|
}
|
|
|
|
|
2007-08-18 22:35:15 +02:00
|
|
|
- (NSString *) contentForEditing
|
2007-08-16 23:57:35 +02:00
|
|
|
{
|
2007-10-30 20:46:48 +01:00
|
|
|
NSMutableArray *keys;
|
|
|
|
NSArray *acceptedTypes;
|
2007-08-16 23:57:35 +02:00
|
|
|
|
2007-10-30 20:46:48 +01:00
|
|
|
acceptedTypes
|
|
|
|
= [NSArray arrayWithObjects: @"text/plain", @"text/html", nil];
|
|
|
|
keys = [NSMutableArray new];
|
|
|
|
[self addRequiredKeysOfStructure: [self bodyStructure]
|
|
|
|
path: @"" toArray: keys acceptedTypes: acceptedTypes];
|
2007-08-16 23:57:35 +02:00
|
|
|
|
2007-10-30 20:46:48 +01:00
|
|
|
return [self _contentForEditingFromKeys: keys];
|
2007-08-18 22:35:15 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
- (NSString *) contentForReply
|
2008-09-05 17:55:03 +02:00
|
|
|
{
|
|
|
|
SOGoUser *currentUser;
|
|
|
|
NSString *pageName;
|
2008-09-05 18:50:22 +02:00
|
|
|
SOGoMailReply *page;
|
2008-09-05 17:55:03 +02:00
|
|
|
|
|
|
|
currentUser = [context activeUser];
|
2008-09-05 18:50:22 +02:00
|
|
|
pageName = [NSString stringWithFormat: @"SOGoMail%@Reply",
|
2008-09-05 17:55:03 +02:00
|
|
|
[currentUser language]];
|
|
|
|
page = [[WOApplication application] pageWithName: pageName
|
|
|
|
inContext: context];
|
2008-09-05 18:50:22 +02:00
|
|
|
[page setSourceMail: self];
|
|
|
|
[page setOutlookMode: [self useOutlookStyleReplies]];
|
|
|
|
|
2008-09-05 17:55:03 +02:00
|
|
|
return [[page generateResponse] contentAsString];
|
|
|
|
}
|
|
|
|
|
2007-08-16 23:57:35 +02:00
|
|
|
- (NSString *) filenameForForward
|
|
|
|
{
|
|
|
|
NSString *subject;
|
|
|
|
NSMutableString *newSubject;
|
|
|
|
static NSString *sescape[] = {
|
|
|
|
@"/", @"..", @"~", @"\"", @"'", @" ", @".", nil
|
|
|
|
};
|
|
|
|
unsigned int count, length;
|
|
|
|
|
2007-11-05 17:37:17 +01:00
|
|
|
subject = [self decodedSubject];
|
2007-08-16 23:57:35 +02:00
|
|
|
length = [subject length];
|
|
|
|
if (!length)
|
|
|
|
{
|
|
|
|
subject = @"forward";
|
|
|
|
length = [subject length];
|
|
|
|
}
|
|
|
|
|
|
|
|
if (length > maxFilenameLength)
|
|
|
|
length = maxFilenameLength;
|
|
|
|
newSubject = [NSMutableString
|
|
|
|
stringWithString: [subject substringToIndex: length]];
|
|
|
|
count = 0;
|
|
|
|
while (sescape[count])
|
|
|
|
{
|
|
|
|
[newSubject replaceString: sescape[count]
|
|
|
|
withString: @"_"];
|
|
|
|
count++;
|
|
|
|
}
|
|
|
|
[newSubject appendString: @".eml"];
|
|
|
|
|
|
|
|
return newSubject;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSString *) subjectForForward
|
|
|
|
{
|
|
|
|
NSString *subject, *newSubject;
|
|
|
|
|
2007-11-05 17:37:17 +01:00
|
|
|
subject = [self decodedSubject];
|
2007-08-16 23:57:35 +02:00
|
|
|
if ([subject length] > 0)
|
2007-11-15 23:39:17 +01:00
|
|
|
newSubject = [NSString stringWithFormat: @"Fwd: %@", subject];
|
2007-08-16 23:57:35 +02:00
|
|
|
else
|
|
|
|
newSubject = subject;
|
|
|
|
|
|
|
|
return newSubject;
|
|
|
|
}
|
|
|
|
|
2007-08-22 17:14:06 +02:00
|
|
|
- (NSString *) contentForInlineForward
|
|
|
|
{
|
|
|
|
SOGoUser *currentUser;
|
|
|
|
NSString *pageName;
|
|
|
|
SOGoMailForward *page;
|
|
|
|
|
|
|
|
currentUser = [context activeUser];
|
|
|
|
pageName = [NSString stringWithFormat: @"SOGoMail%@Forward",
|
|
|
|
[currentUser language]];
|
|
|
|
page = [[WOApplication application] pageWithName: pageName
|
|
|
|
inContext: context];
|
2008-09-05 18:50:22 +02:00
|
|
|
[page setSourceMail: self];
|
2007-08-22 17:14:06 +02:00
|
|
|
|
|
|
|
return [[page generateResponse] contentAsString];
|
|
|
|
}
|
|
|
|
|
2007-08-18 22:35:15 +02:00
|
|
|
- (void) _fetchFileAttachmentKey: (NSDictionary *) part
|
|
|
|
intoArray: (NSMutableArray *) keys
|
|
|
|
withPath: (NSString *) path
|
|
|
|
{
|
2007-10-25 17:28:06 +02:00
|
|
|
NSDictionary *disposition, *currentFile;
|
2007-08-18 22:35:15 +02:00
|
|
|
NSString *filename, *mimeType;
|
|
|
|
|
2007-10-25 17:28:06 +02:00
|
|
|
disposition = [part objectForKey: @"disposition"];
|
|
|
|
filename = [[disposition objectForKey: @"parameterList"]
|
|
|
|
objectForKey: @"filename"];
|
|
|
|
if (filename)
|
2007-08-18 22:35:15 +02:00
|
|
|
{
|
|
|
|
mimeType = [NSString stringWithFormat: @"%@/%@",
|
|
|
|
[part objectForKey: @"type"],
|
|
|
|
[part objectForKey: @"subtype"]];
|
|
|
|
currentFile = [NSDictionary dictionaryWithObjectsAndKeys:
|
|
|
|
filename, @"filename",
|
|
|
|
[mimeType lowercaseString], @"mimetype",
|
2007-10-25 17:28:06 +02:00
|
|
|
[part
|
|
|
|
objectForKey: @"encoding"], @"encoding",
|
2007-08-18 22:35:15 +02:00
|
|
|
path, @"path", nil];
|
|
|
|
[keys addObject: currentFile];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) _fetchFileAttachmentKeysInPart: (NSDictionary *) part
|
|
|
|
intoArray: (NSMutableArray *) keys
|
|
|
|
withPath: (NSString *) path
|
|
|
|
{
|
|
|
|
NSEnumerator *subparts;
|
|
|
|
NSString *type;
|
|
|
|
unsigned int count;
|
|
|
|
NSDictionary *currentPart;
|
|
|
|
NSString *newPath;
|
|
|
|
|
|
|
|
type = [[part objectForKey: @"type"] lowercaseString];
|
|
|
|
if ([type isEqualToString: @"multipart"])
|
|
|
|
{
|
|
|
|
subparts = [[part objectForKey: @"parts"] objectEnumerator];
|
|
|
|
currentPart = [subparts nextObject];
|
|
|
|
count = 1;
|
|
|
|
while (currentPart)
|
|
|
|
{
|
|
|
|
if (path)
|
|
|
|
newPath = [NSString stringWithFormat: @"%@.%d", path, count];
|
|
|
|
else
|
|
|
|
newPath = [NSString stringWithFormat: @"%d", count];
|
|
|
|
[self _fetchFileAttachmentKeysInPart: currentPart
|
|
|
|
intoArray: keys
|
|
|
|
withPath: newPath];
|
|
|
|
currentPart = [subparts nextObject];
|
|
|
|
count++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
[self _fetchFileAttachmentKey: part intoArray: keys withPath: path];
|
|
|
|
}
|
|
|
|
|
|
|
|
#warning we might need to handle parts with a "name" attribute
|
|
|
|
- (NSArray *) fetchFileAttachmentKeys
|
|
|
|
{
|
|
|
|
NSMutableArray *keys;
|
|
|
|
|
|
|
|
keys = [NSMutableArray array];
|
|
|
|
[self _fetchFileAttachmentKeysInPart: [self bodyStructure]
|
|
|
|
intoArray: keys withPath: nil];
|
|
|
|
|
|
|
|
return keys;
|
|
|
|
}
|
|
|
|
|
2007-08-16 23:57:35 +02:00
|
|
|
@end
|