1 /* UIxMailPartICalActions.m - this file is part of SOGo
3 * Copyright (C) 2007 Inverse groupe conseil
5 * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
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)
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.
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.
23 #import <Foundation/NSCalendarDate.h>
25 #import <NGObjWeb/WOContext+SoObjects.h>
26 #import <NGObjWeb/WOResponse.h>
28 #import <NGCards/iCalCalendar.h>
29 #import <NGCards/iCalEvent.h>
30 #import <NGCards/iCalPerson.h>
32 #import <UI/Common/WODirectAction+SOGo.h>
34 #import <NGImap4/NGImap4EnvelopeAddress.h>
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>
44 #import "UIxMailPartICalActions.h"
46 @implementation UIxMailPartICalActions
48 - (iCalEvent *) _emailEvent
51 NSString *eventString;
52 iCalCalendar *emailCalendar;
54 content = [[self clientObject] fetchBLOB];
55 eventString = [[NSString alloc] initWithData: content
56 encoding: NSUTF8StringEncoding];
58 eventString = [[NSString alloc] initWithData: content
59 encoding: NSISOLatin1StringEncoding];
60 emailCalendar = [iCalCalendar parseSingleFromSource: eventString];
62 return (iCalEvent *) [emailCalendar firstChildWithTag: @"vevent"];
65 - (SOGoAppointmentObject *) _eventObjectWithUID: (NSString *) uid
66 forUser: (SOGoUser *) user
68 SOGoAppointmentFolder *personalFolder;
69 SOGoAppointmentObject *eventObject;
74 personalFolder = [user personalCalendarFolderInContext: context];
75 cname = [personalFolder resourceNameForEventUID: uid];
78 eventObject = [personalFolder lookupName: cname
79 inContext: context acquire: NO];
80 if (![eventObject isKindOfClass: [SOGoAppointmentObject class]])
85 eventObject = [SOGoAppointmentObject objectWithName: uid
86 inContainer: personalFolder];
91 - (SOGoAppointmentObject *) _eventObjectWithUID: (NSString *) uid
93 return [self _eventObjectWithUID: uid forUser: [context activeUser]];
97 _setupChosenEventAndEventObject: (SOGoAppointmentObject **) eventObject
99 iCalEvent *emailEvent, *calendarEvent, *chosenEvent;
101 emailEvent = [self _emailEvent];
104 *eventObject = [self _eventObjectWithUID: [emailEvent uid]];
105 if ([*eventObject isNew])
106 chosenEvent = emailEvent;
109 calendarEvent = (iCalEvent *) [*eventObject component: NO
111 if ([calendarEvent compare: emailEvent] == NSOrderedAscending)
112 chosenEvent = emailEvent;
114 chosenEvent = calendarEvent;
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
129 SOGoAppointmentObject *eventObject;
131 iCalPerson *otherAttendee;
132 NSString *iCalString;
134 eventObject = [self _eventObjectWithUID: calUID
135 forUser: [SOGoUser userWithLogin: uid roles: nil]];
136 if (![eventObject isNew])
138 event = [eventObject component: NO secure: NO];
139 if ([[event sequence] compare: sequence]
143 = [event findParticipantWithEmail: [attendee rfc822Email]];
144 [otherAttendee setPartStat: [attendee partStat]];
145 iCalString = [[event parent] versitString];
146 [eventObject saveContentString: iCalString];
151 - (WOResponse *) _changePartStatusAction: (NSString *) newStatus
153 WOResponse *response;
154 SOGoAppointmentObject *eventObject;
155 iCalEvent *chosenEvent;
157 iCalCalendar *emailCalendar, *calendar;
158 NSString *rsvp, *method, *organizerUID;
160 chosenEvent = [self _setupChosenEventAndEventObject: &eventObject];
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"])
170 [calendar setMethod: @""];
171 rsvp = [[user rsvp] lowercaseString];
175 [eventObject saveContentString: [calendar versitString]];
176 if ([rsvp isEqualToString: @"true"])
177 [eventObject sendResponseToOrganizer];
178 organizerUID = [[chosenEvent organizer] uid];
180 [self _updateAttendee: user withSequence: [chosenEvent sequence]
181 andCalUID: [chosenEvent uid] forUID: organizerUID];
182 response = [self responseWith204];
186 response = [context response];
187 [response setStatus: 409];
193 - (WOResponse *) acceptAction
195 return [self _changePartStatusAction: @"ACCEPTED"];
198 - (WOResponse *) declineAction
200 return [self _changePartStatusAction: @"DECLINED"];
203 - (WOResponse *) deleteFromCalendarAction
205 iCalEvent *emailEvent;
206 SOGoAppointmentObject *eventObject;
207 WOResponse *response;
209 emailEvent = [self _emailEvent];
212 eventObject = [self _eventObjectWithUID: [emailEvent uid]];
213 [eventObject delete];
214 response = [self responseWith204];
218 response = [context response];
219 [response setStatus: 409];
225 - (iCalPerson *) _emailParticipantWithEvent: (iCalEvent *) event
228 SOGoMailObject *mailObject;
229 NGImap4EnvelopeAddress *address;
231 mailObject = [[self clientObject] mailObject];
232 address = [[mailObject fromEnvelopeAddresses] objectAtIndex: 0];
233 emailFrom = [address baseEMail];
235 return [event findParticipantWithEmail: emailFrom];
238 - (BOOL) _updateParticipantStatusInEvent: (iCalEvent *) calendarEvent
239 fromEvent: (iCalEvent *) emailEvent
240 inObject: (SOGoAppointmentObject *) eventObject
242 iCalPerson *calendarParticipant, *mailParticipant;
246 calendarParticipant = [self _emailParticipantWithEvent: calendarEvent];
247 mailParticipant = [self _emailParticipantWithEvent: emailEvent];
248 if (calendarParticipant && mailParticipant)
251 partStat = [mailParticipant partStat];
252 if ([partStat caseInsensitiveCompare: [calendarParticipant partStat]]
255 [calendarParticipant setPartStat: [partStat uppercaseString]];
256 [eventObject saveComponent: calendarEvent];
265 - (WOResponse *) updateUserStatusAction
267 iCalEvent *emailEvent, *calendarEvent;
268 SOGoAppointmentObject *eventObject;
269 WOResponse *response;
273 emailEvent = [self _emailEvent];
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];
288 response = [context response];
289 [response setStatus: 409];
295 // - (WOResponse *) markTentativeAction
297 // return [self _changePartStatusAction: @"TENTATIVE"];
300 // - (WOResponse *) addToCalendarAction
302 // return [self responseWithStatus: 404];
305 // - (WOResponse *) deleteFromCalendarAction
307 // return [self responseWithStatus: 404];