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