]> err.no Git - scalable-opengroupware.org/blob - SoObjects/Mailer/SOGoMailObject+Draft.m
91f3a17a93ee0eb7be84b9559baf29057066f3cf
[scalable-opengroupware.org] / SoObjects / Mailer / SOGoMailObject+Draft.m
1 /* SOGoMailObject+Draft.m - this file is part of SOGo
2  *
3  * Copyright (C) 2007 Inverse groupe conseil
4  *
5  * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
6  *
7  * This file is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2, or (at your option)
10  * any later version.
11  *
12  * This file is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; see the file COPYING.  If not, write to
19  * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22
23 #import <Foundation/NSArray.h>
24
25 #import <NGObjWeb/WOApplication.h>
26 #import <NGObjWeb/WOResponse.h>
27 #import <NGObjWeb/WOContext+SoObjects.h>
28 #import <NGExtensions/NSString+misc.h>
29 #import <NGExtensions/NSObject+Logs.h>
30
31 #import <SoObjects/SOGo/NSArray+Utilities.h>
32 #import <SoObjects/SOGo/SOGoUser.h>
33
34 #import "NSString+Mail.h"
35 #import "SOGoMailForward.h"
36 #import "SOGoMailObject+Draft.h"
37 #import "SOGoMailReply.h"
38
39 #define maxFilenameLength 64
40
41 @implementation SOGoMailObject (SOGoDraftObjectExtensions)
42
43 - (NSString *) subjectForReply
44 {
45   static NSString *replyPrefixes[] = {
46     @"Re:", // regular
47     @"RE:", // Outlook v11 (English?)
48     @"AW:", // German Outlook v11
49     @"Re[", // numbered Re, eg "Re[2]:"
50     nil
51   };
52   BOOL hasPrefix;
53   unsigned int i;
54   NSString *subject, *newSubject;
55
56   hasPrefix = NO;
57
58   subject = [self decodedSubject];
59   i = 0;
60   while (!hasPrefix && replyPrefixes[i])
61     if ([subject hasPrefix: replyPrefixes[i]])
62       hasPrefix = YES;
63     else
64       i++;
65
66   if (hasPrefix)
67     newSubject = subject;
68   else
69     newSubject = [NSString stringWithFormat: @"Re: %@", subject];
70
71   return newSubject;
72 }
73
74
75 - (NSString *) _contentForEditingFromKeys: (NSArray *) keys
76 {
77   NSArray *types;
78   NSDictionary *parts;
79   NSString *rawPart, *content, *contentKey;
80   int index;
81   BOOL htmlContent;
82
83   if ([keys count])
84     {
85       types = [keys objectsForKey: @"mimeType"];
86       index = [types indexOfObject: @"text/plain"];
87       if (index == NSNotFound)
88         {
89           index = [types indexOfObject: @"text/html"];
90           htmlContent = YES;
91         }
92       else
93         htmlContent = NO;
94       if (index == NSNotFound)
95         content = @"";
96       else
97         {
98           contentKey = [keys objectAtIndex: index];
99           parts = [self fetchPlainTextStrings:
100                           [NSArray arrayWithObject: contentKey]];
101           rawPart = [[parts allValues] objectAtIndex: 0];
102           if (htmlContent)
103             content = [rawPart htmlToText];
104           else
105             content = rawPart;
106         }
107     }
108   else
109     content = @"";
110
111   return content;
112 }
113
114 - (NSString *) contentForEditing
115 {
116   NSMutableArray *keys;
117   NSArray *acceptedTypes;
118
119   acceptedTypes
120     = [NSArray arrayWithObjects: @"text/plain", @"text/html", nil];
121   keys = [NSMutableArray new];
122   [self addRequiredKeysOfStructure: [self bodyStructure]
123         path: @"" toArray: keys acceptedTypes: acceptedTypes];
124
125   return [self _contentForEditingFromKeys: keys];
126 }
127
128 - (NSString *) contentForReply
129 {
130   SOGoUser *currentUser;
131   NSString *pageName;
132   SOGoMailReply *page;
133
134   currentUser = [context activeUser];
135   pageName = [NSString stringWithFormat: @"SOGoMail%@Reply",
136                        [currentUser language]];
137   page = [[WOApplication application] pageWithName: pageName
138                                       inContext: context];
139   [page setRepliedMail: self];
140
141   return [[page generateResponse] contentAsString];
142 }
143
144 - (NSString *) filenameForForward
145 {
146   NSString *subject;
147   NSMutableString *newSubject;
148   static NSString *sescape[] = { 
149     @"/", @"..", @"~", @"\"", @"'", @" ", @".", nil 
150   };
151   unsigned int count, length;
152
153   subject = [self decodedSubject];
154   length = [subject length];
155   if (!length)
156     {
157       subject = @"forward";
158       length = [subject length];
159     }
160
161   if (length > maxFilenameLength)
162     length = maxFilenameLength;
163   newSubject = [NSMutableString
164                  stringWithString: [subject substringToIndex: length]];
165   count = 0;
166   while (sescape[count])
167     {
168       [newSubject replaceString: sescape[count]
169                   withString: @"_"];
170       count++;
171     }
172   [newSubject appendString: @".eml"];
173
174   return newSubject;
175 }
176
177 - (NSString *) subjectForForward
178 {
179   NSString *subject, *newSubject;
180
181   subject = [self decodedSubject];
182   if ([subject length] > 0)
183     newSubject = [NSString stringWithFormat: @"[Fwd: %@]", subject];
184   else
185     newSubject = subject;
186
187   return newSubject;
188 }
189
190 - (NSString *) contentForInlineForward
191 {
192   SOGoUser *currentUser;
193   NSString *pageName;
194   SOGoMailForward *page;
195
196   currentUser = [context activeUser];
197   pageName = [NSString stringWithFormat: @"SOGoMail%@Forward",
198                        [currentUser language]];
199   page = [[WOApplication application] pageWithName: pageName
200                                       inContext: context];
201   [page setForwardedMail: self];
202
203   return [[page generateResponse] contentAsString];
204 }
205
206 - (void) _fetchFileAttachmentKey: (NSDictionary *) part
207                        intoArray: (NSMutableArray *) keys
208                         withPath: (NSString *) path
209 {
210   NSDictionary *disposition, *currentFile;
211   NSString *filename, *mimeType;
212
213   disposition = [part objectForKey: @"disposition"];
214   filename = [[disposition objectForKey: @"parameterList"]
215                objectForKey: @"filename"];
216   if (filename)
217     {
218       mimeType = [NSString stringWithFormat: @"%@/%@",
219                            [part objectForKey: @"type"],
220                            [part objectForKey: @"subtype"]];
221       currentFile = [NSDictionary dictionaryWithObjectsAndKeys:
222                                     filename, @"filename",
223                                   [mimeType lowercaseString], @"mimetype",
224                                   [part
225                                     objectForKey: @"encoding"], @"encoding",
226                                   path, @"path", nil];
227       [keys addObject: currentFile];
228     }
229 }
230
231 - (void) _fetchFileAttachmentKeysInPart: (NSDictionary *) part
232                               intoArray: (NSMutableArray *) keys
233                                withPath: (NSString *) path
234 {
235   NSEnumerator *subparts;
236   NSString *type;
237   unsigned int count;
238   NSDictionary *currentPart;
239   NSString *newPath;
240
241   type = [[part objectForKey: @"type"] lowercaseString];
242   if ([type isEqualToString: @"multipart"])
243     {
244       subparts = [[part objectForKey: @"parts"] objectEnumerator];
245       currentPart = [subparts nextObject];
246       count = 1;
247       while (currentPart)
248         {
249           if (path)
250             newPath = [NSString stringWithFormat: @"%@.%d", path, count];
251           else
252             newPath = [NSString stringWithFormat: @"%d", count];
253           [self _fetchFileAttachmentKeysInPart: currentPart
254                 intoArray: keys
255                 withPath: newPath];
256           currentPart = [subparts nextObject];
257           count++;
258         }
259     }
260   else
261     [self _fetchFileAttachmentKey: part intoArray: keys withPath: path];
262 }
263
264 #warning we might need to handle parts with a "name" attribute
265 - (NSArray *) fetchFileAttachmentKeys
266 {
267   NSMutableArray *keys;
268
269   keys = [NSMutableArray array];
270   [self _fetchFileAttachmentKeysInPart: [self bodyStructure]
271         intoArray: keys withPath: nil];
272
273   return keys;
274 }
275
276 @end