]> err.no Git - scalable-opengroupware.org/blob - UI/MailPartViewers/UIxMailPartICalActions.m
git-svn-id: http://svn.opengroupware.org/SOGo/inverse/trunk@1305 d1b88da0-ebda-0310...
[scalable-opengroupware.org] / UI / MailPartViewers / UIxMailPartICalActions.m
1 /* UIxMailPartICalActions.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/NSCalendarDate.h>
24
25 #import <NGObjWeb/WOContext+SoObjects.h>
26 #import <NGObjWeb/WOResponse.h>
27
28 #import <NGCards/iCalCalendar.h>
29 #import <NGCards/iCalEvent.h>
30 #import <NGCards/iCalPerson.h>
31
32 #import <UI/Common/WODirectAction+SOGo.h>
33
34 #import <NGImap4/NGImap4EnvelopeAddress.h>
35
36 #import <SoObjects/Appointments/iCalPerson+SOGo.h>
37 #import <SoObjects/Appointments/SOGoAppointmentObject.h>
38 #import <SoObjects/Appointments/SOGoAppointmentFolder.h>
39 #import <SoObjects/Mailer/SOGoMailObject.h>
40 #import <SoObjects/SOGo/SOGoUser.h>
41 #import <SoObjects/SOGo/iCalEntityObject+Utilities.h>
42 #import <SoObjects/Mailer/SOGoMailBodyPart.h>
43
44 #import "UIxMailPartICalActions.h"
45
46 @implementation UIxMailPartICalActions
47
48 - (iCalEvent *) _emailEvent
49 {
50   NSData *content;
51   NSString *eventString;
52   iCalCalendar *emailCalendar;
53
54   content = [[self clientObject] fetchBLOB];
55   eventString = [[NSString alloc] initWithData: content
56                                   encoding: NSUTF8StringEncoding];
57   if (!eventString)
58     eventString = [[NSString alloc] initWithData: content
59                                     encoding: NSISOLatin1StringEncoding];
60   emailCalendar = [iCalCalendar parseSingleFromSource: eventString];
61
62   return (iCalEvent *) [emailCalendar firstChildWithTag: @"vevent"];
63 }
64
65 - (SOGoAppointmentObject *) _eventObjectWithUID: (NSString *) uid
66                                         forUser: (SOGoUser *) user
67 {
68   SOGoAppointmentFolder *personalFolder;
69   SOGoAppointmentObject *eventObject;
70   NSString *cname;
71
72   eventObject = nil;
73
74   personalFolder = [user personalCalendarFolderInContext: context];
75   cname = [personalFolder resourceNameForEventUID: uid];
76   if (cname)
77     {
78       eventObject = [personalFolder lookupName: cname
79                                     inContext: context acquire: NO];
80       if (![eventObject isKindOfClass: [SOGoAppointmentObject class]])
81         eventObject = nil;
82     }
83
84   if (!eventObject)
85     eventObject = [SOGoAppointmentObject objectWithName: uid
86                                          inContainer: personalFolder];
87   
88   return eventObject;
89 }
90
91 - (SOGoAppointmentObject *) _eventObjectWithUID: (NSString *) uid
92 {
93   return [self _eventObjectWithUID: uid forUser: [context activeUser]];
94 }
95
96 - (iCalEvent *)
97   _setupChosenEventAndEventObject: (SOGoAppointmentObject **) eventObject
98 {
99   iCalEvent *emailEvent, *calendarEvent, *chosenEvent;
100
101   emailEvent = [self _emailEvent];
102   if (emailEvent)
103     {
104       *eventObject = [self _eventObjectWithUID: [emailEvent uid]];
105       if ([*eventObject isNew])
106         chosenEvent = emailEvent;
107       else
108         {
109           calendarEvent = (iCalEvent *) [*eventObject component: NO
110                                                       secure: NO];
111           if ([calendarEvent compare: emailEvent] == NSOrderedAscending)
112             chosenEvent = emailEvent;
113           else
114             chosenEvent = calendarEvent;
115         }
116     }
117   else
118     chosenEvent = nil;
119
120   return chosenEvent;
121 }
122
123 #warning this is code copied from SOGoAppointmentObject...
124 - (void) _updateAttendee: (iCalPerson *) attendee
125             withSequence: (NSNumber *) sequence
126                andCalUID: (NSString *) calUID
127                   forUID: (NSString *) uid
128 {
129   SOGoAppointmentObject *eventObject;
130   iCalEvent *event;
131   iCalPerson *otherAttendee;
132   NSString *iCalString;
133
134   eventObject = [self _eventObjectWithUID: calUID
135                       forUser: [SOGoUser userWithLogin: uid roles: nil]];
136   if (![eventObject isNew])
137     {
138       event = [eventObject component: NO secure: NO];
139       if ([[event sequence] compare: sequence]
140           == NSOrderedSame)
141         {
142           otherAttendee
143             = [event findParticipantWithEmail: [attendee rfc822Email]];
144           [otherAttendee setPartStat: [attendee partStat]];
145           iCalString = [[event parent] versitString];
146           [eventObject saveContentString: iCalString];
147         }
148     }
149 }
150
151 - (WOResponse *) _changePartStatusAction: (NSString *) newStatus
152 {
153   WOResponse *response;
154   SOGoAppointmentObject *eventObject;
155   iCalEvent *chosenEvent;
156   iCalPerson *user;
157   iCalCalendar *emailCalendar, *calendar;
158   NSString *rsvp, *method, *organizerUID;
159
160   chosenEvent = [self _setupChosenEventAndEventObject: &eventObject];
161   if (chosenEvent)
162     {
163       user = [chosenEvent findParticipant: [context activeUser]];
164       [user setPartStat: newStatus];
165       calendar = [chosenEvent parent];
166       emailCalendar = [[self _emailEvent] parent];
167       method = [[emailCalendar method] lowercaseString];
168       if ([method isEqualToString: @"request"])
169         {
170           [calendar setMethod: @""];
171           rsvp = [[user rsvp] lowercaseString];
172         }
173       else
174         rsvp = nil;
175       [eventObject saveContentString: [calendar versitString]];
176       if ([rsvp isEqualToString: @"true"])
177         [eventObject sendResponseToOrganizer];
178       organizerUID = [[chosenEvent organizer] uid];
179       if (organizerUID)
180         [self _updateAttendee: user withSequence: [chosenEvent sequence]
181               andCalUID: [chosenEvent uid] forUID: organizerUID];
182       response = [self responseWith204];
183     }
184   else
185     {
186       response = [context response];
187       [response setStatus: 409];
188     }
189
190   return response;
191 }
192
193 - (WOResponse *) acceptAction
194 {
195   return [self _changePartStatusAction: @"ACCEPTED"];
196 }
197
198 - (WOResponse *) declineAction
199 {
200   return [self _changePartStatusAction: @"DECLINED"];
201 }
202
203 - (WOResponse *) deleteFromCalendarAction
204 {
205   iCalEvent *emailEvent;
206   SOGoAppointmentObject *eventObject;
207   WOResponse *response;
208
209   emailEvent = [self _emailEvent];
210   if (emailEvent)
211     {
212       eventObject = [self _eventObjectWithUID: [emailEvent uid]];
213       [eventObject delete];
214       response = [self responseWith204];
215     }
216   else
217     {
218       response = [context response];
219       [response setStatus: 409];
220     }
221
222   return response;
223 }
224
225 - (iCalPerson *) _emailParticipantWithEvent: (iCalEvent *) event
226 {
227   NSString *emailFrom;
228   SOGoMailObject *mailObject;
229   NGImap4EnvelopeAddress *address;
230
231   mailObject = [[self clientObject] mailObject];
232   address = [[mailObject fromEnvelopeAddresses] objectAtIndex: 0];
233   emailFrom = [address baseEMail];
234
235   return [event findParticipantWithEmail: emailFrom];
236 }
237
238 - (BOOL) _updateParticipantStatusInEvent: (iCalEvent *) calendarEvent
239                                fromEvent: (iCalEvent *) emailEvent
240                                 inObject: (SOGoAppointmentObject *) eventObject
241 {
242   iCalPerson *calendarParticipant, *mailParticipant;
243   NSString *partStat;
244   BOOL result;
245
246   calendarParticipant = [self _emailParticipantWithEvent: calendarEvent];
247   mailParticipant = [self _emailParticipantWithEvent: emailEvent];
248   if (calendarParticipant && mailParticipant)
249     {
250       result = YES;
251       partStat = [mailParticipant partStat];
252       if ([partStat caseInsensitiveCompare: [calendarParticipant partStat]]
253           != NSOrderedSame)
254         {
255           [calendarParticipant setPartStat: [partStat uppercaseString]];
256           [eventObject saveComponent: calendarEvent];
257         }
258     }
259   else
260     result = NO;
261
262   return result;
263 }
264
265 - (WOResponse *) updateUserStatusAction
266 {
267   iCalEvent *emailEvent, *calendarEvent;
268   SOGoAppointmentObject *eventObject;
269   WOResponse *response;
270
271   response = nil;
272
273   emailEvent = [self _emailEvent];
274   if (emailEvent)
275     {
276       eventObject = [self _eventObjectWithUID: [emailEvent uid]];
277       calendarEvent = [eventObject component: NO secure: NO];
278       if (([[emailEvent sequence] compare: [calendarEvent sequence]]
279           != NSOrderedDescending)
280           && ([self _updateParticipantStatusInEvent: calendarEvent
281                     fromEvent: emailEvent
282                     inObject: eventObject]))
283         response = [self responseWith204];
284     }
285
286   if (!response)
287     {
288       response = [context response];
289       [response setStatus: 409];
290     }
291
292   return response;
293 }
294
295 // - (WOResponse *) markTentativeAction
296 // {
297 //   return [self _changePartStatusAction: @"TENTATIVE"];
298 // }
299
300 // - (WOResponse *) addToCalendarAction
301 // {
302 //   return [self responseWithStatus: 404];
303 // }
304
305 // - (WOResponse *) deleteFromCalendarAction
306 // {
307 //   return [self responseWithStatus: 404];
308 // }
309
310 @end