]> err.no Git - scalable-opengroupware.org/blob - SoObjects/Appointments/SOGoCalendarComponent.m
git-svn-id: http://svn.opengroupware.org/SOGo/inverse/trunk@1014 d1b88da0-ebda-0310...
[scalable-opengroupware.org] / SoObjects / Appointments / SOGoCalendarComponent.m
1 /* SOGoCalendarComponent.m - this file is part of SOGo
2  *
3  * Copyright (C) 2006 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/NSString.h>
24
25 #import <NGCards/iCalCalendar.h>
26 #import <NGCards/iCalPerson.h>
27 #import <NGCards/iCalRepeatableEntityObject.h>
28 #import <NGMime/NGMime.h>
29 #import <NGMail/NGMail.h>
30 #import <NGMail/NGSendMail.h>
31
32 #import <SOGo/AgenorUserManager.h>
33
34 #import "common.h"
35
36 #import "SOGoAptMailNotification.h"
37 #import "SOGoCalendarComponent.h"
38
39 static NSString *mailTemplateDefaultLanguage = nil;
40 static BOOL sendEMailNotifications = NO;
41
42 @implementation SOGoCalendarComponent
43
44 + (void) initialize
45 {
46   NSUserDefaults      *ud;
47   static BOOL         didInit = NO;
48   
49   if (!didInit)
50     {
51       didInit = YES;
52   
53       ud = [NSUserDefaults standardUserDefaults];
54       mailTemplateDefaultLanguage = [[ud stringForKey:@"SOGoDefaultLanguage"]
55                                       retain];
56       if (!mailTemplateDefaultLanguage)
57         mailTemplateDefaultLanguage = @"French";
58
59       sendEMailNotifications
60         = [ud boolForKey: @"SOGoAppointmentSendEMailNotifications"];
61     }
62 }
63
64 - (id) init
65 {
66   if ((self = [super init]))
67     {
68       calendar = nil;
69     }
70
71   return self;
72 }
73
74 - (void) dealloc
75 {
76   if (calendar)
77     [calendar release];
78   [super dealloc];
79 }
80
81 - (NSString *) davContentType
82 {
83   return @"text/calendar";
84 }
85
86 - (iCalCalendar *) calendar
87 {
88   NSString *iCalString;
89
90   if (!calendar)
91     {
92       iCalString = [self contentAsString];
93       if (iCalString)
94         {
95           calendar = [iCalCalendar parseSingleFromSource: iCalString];
96           [calendar retain];
97         }
98     }
99
100   return calendar;
101 }
102
103 /* raw saving */
104
105 - (NSException *) primarySaveContentString: (NSString *) _iCalString
106 {
107   return [super saveContentString: _iCalString];
108 }
109
110 - (NSException *) primaryDelete
111 {
112   return [super delete];
113 }
114
115 - (NSException *) deleteWithBaseSequence: (int) a
116 {
117   [self subclassResponsibility: _cmd];
118
119   return nil;
120 }
121
122 - (NSException *) delete
123 {
124   return [self deleteWithBaseSequence:0];
125 }
126
127 /* EMail Notifications */
128 - (NSString *) homePageURLForPerson: (iCalPerson *) _person
129 {
130   NSString *baseURL;
131   NSString *uid;
132   WOContext *ctx;
133   NSArray *traversalObjects;
134
135   /* generate URL from traversal stack */
136   ctx = [[WOApplication application] context];
137   traversalObjects = [ctx objectTraversalStack];
138   if ([traversalObjects count] > 0)
139     baseURL = [[traversalObjects objectAtIndex:0] baseURLInContext:ctx];
140   else
141     {
142       baseURL = @"http://localhost/";
143       [self warnWithFormat:@"Unable to create baseURL from context!"];
144     }
145   uid = [[AgenorUserManager sharedUserManager]
146           getUIDForEmail: [_person rfc822Email]];
147
148   return ((uid)
149           ? [NSString stringWithFormat:@"%@%@", baseURL, uid]
150           : nil);
151 }
152
153 - (BOOL) sendEMailNotifications
154 {
155   return sendEMailNotifications;
156 }
157
158 - (void) sendEMailUsingTemplateNamed: (NSString *) _pageName
159                         forOldObject: (iCalRepeatableEntityObject *) _oldObject
160                         andNewObject: (iCalRepeatableEntityObject *) _newObject
161                          toAttendees: (NSArray *) _attendees
162 {
163   NSString *pageName;
164   iCalPerson *organizer;
165   NSString *cn, *sender, *iCalString;
166   NGSendMail *sendmail;
167   WOApplication *app;
168   unsigned i, count;
169   iCalPerson *attendee;
170   NSString *recipient;
171   SOGoAptMailNotification *p;
172   NSString *subject, *text, *header;
173   NGMutableHashMap *headerMap;
174   NGMimeMessage *msg;
175   NGMimeBodyPart *bodyPart;
176   NGMimeMultipartBody *body;
177
178   if ([_attendees count])
179     {
180       /* sender */
181
182       organizer = [_newObject organizer];
183       cn = [organizer cnWithoutQuotes];
184       if (cn)
185         sender = [NSString stringWithFormat:@"%@ <%@>",
186                            cn,
187                            [organizer rfc822Email]];
188       else
189         sender = [organizer rfc822Email];
190
191       /* generate iCalString once */
192       iCalString = [[_newObject parent] versitString];
193   
194       /* get sendmail object */
195       sendmail = [NGSendMail sharedSendMail];
196
197       /* get WOApplication instance */
198       app = [WOApplication application];
199
200       /* generate dynamic message content */
201
202       count = [_attendees count];
203       for (i = 0; i < count; i++)
204         {
205           attendee = [_attendees objectAtIndex:i];
206
207           /* construct recipient */
208           cn = [attendee cn];
209           if (cn)
210             recipient = [NSString stringWithFormat: @"%@ <%@>",
211                                   cn,
212                                   [attendee rfc822Email]];
213           else
214             recipient = [attendee rfc822Email];
215
216           /* create page name */
217           // TODO: select user's default language?
218           pageName = [NSString stringWithFormat: @"SOGoAptMail%@%@",
219                                mailTemplateDefaultLanguage,
220                                _pageName];
221           /* construct message content */
222           p = [app pageWithName: pageName inContext: [WOContext context]];
223           [p setNewApt: _newObject];
224           [p setOldApt: _oldObject];
225           [p setHomePageURL: [self homePageURLForPerson: attendee]];
226           [p setViewTZ: [self userTimeZone: cn]];
227           subject = [p getSubject];
228           text = [p getBody];
229
230           /* construct message */
231           headerMap = [NGMutableHashMap hashMapWithCapacity: 5];
232     
233           /* NOTE: multipart/alternative seems like the correct choice but
234            * unfortunately Thunderbird doesn't offer the rich content alternative
235            * at all. Mail.app shows the rich content alternative _only_
236            * so we'll stick with multipart/mixed for the time being.
237            */
238           [headerMap setObject: @"multipart/mixed" forKey: @"content-type"];
239           [headerMap setObject: sender forKey: @"From"];
240           [headerMap setObject: recipient forKey: @"To"];
241           [headerMap setObject: [NSCalendarDate date] forKey: @"date"];
242           [headerMap setObject: subject forKey: @"Subject"];
243           msg = [NGMimeMessage messageWithHeader: headerMap];
244
245           /* multipart body */
246           body = [[NGMimeMultipartBody alloc] initWithPart: msg];
247     
248           /* text part */
249           headerMap = [NGMutableHashMap hashMapWithCapacity: 1];
250           [headerMap setObject: @"text/plain; charset=utf-8"
251                      forKey: @"content-type"];
252           bodyPart = [NGMimeBodyPart bodyPartWithHeader: headerMap];
253           [bodyPart setBody: [text dataUsingEncoding: NSUTF8StringEncoding]];
254
255           /* attach text part to multipart body */
256           [body addBodyPart: bodyPart];
257     
258           /* calendar part */
259           header = [NSString stringWithFormat: @"text/calendar; method=%@;"
260                              @" charset=utf-8",
261                              [(iCalCalendar *) [_newObject parent] method]];
262           headerMap = [NGMutableHashMap hashMapWithCapacity: 1];
263           [headerMap setObject:header forKey: @"content-type"];
264           bodyPart = [NGMimeBodyPart bodyPartWithHeader: headerMap];
265           [bodyPart setBody: [iCalString dataUsingEncoding: NSUTF8StringEncoding]];
266
267           /* attach calendar part to multipart body */
268           [body addBodyPart: bodyPart];
269     
270           /* attach multipart body to message */
271           [msg setBody: body];
272           [body release];
273
274           /* send the damn thing */
275           [sendmail sendMimePart: msg
276                     toRecipients: [NSArray arrayWithObject: [attendee rfc822Email]]
277                     sender: [organizer rfc822Email]];
278         }
279     }
280 }
281
282 @end