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;
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];
81 - (SOGoAppointmentObject *) _eventObjectWithUID: (NSString *) uid
83 return [self _eventObjectWithUID: uid forUser: [context activeUser]];
87 _setupChosenEventAndEventObject: (SOGoAppointmentObject **) eventObject
89 iCalEvent *emailEvent, *calendarEvent, *chosenEvent;
91 emailEvent = [self _emailEvent];
94 *eventObject = [self _eventObjectWithUID: [emailEvent uid]];
95 if ([*eventObject isNew])
96 chosenEvent = emailEvent;
99 calendarEvent = (iCalEvent *) [*eventObject component: NO secure: NO];
100 if ([calendarEvent compare: emailEvent] == NSOrderedAscending)
101 chosenEvent = emailEvent;
103 chosenEvent = calendarEvent;
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
118 SOGoAppointmentObject *eventObject;
120 iCalPerson *otherAttendee;
121 NSString *iCalString;
123 eventObject = [self _eventObjectWithUID: calUID
124 forUser: [SOGoUser userWithLogin: uid roles: nil]];
125 if (![eventObject isNew])
127 event = [eventObject component: NO secure: NO];
128 if ([[event sequence] compare: sequence]
132 = [event findParticipantWithEmail: [attendee rfc822Email]];
133 [otherAttendee setPartStat: [attendee partStat]];
134 iCalString = [[event parent] versitString];
135 [eventObject saveContentString: iCalString];
140 - (WOResponse *) _changePartStatusAction: (NSString *) newStatus
142 WOResponse *response;
143 SOGoAppointmentObject *eventObject;
144 iCalEvent *chosenEvent;
146 iCalCalendar *emailCalendar, *calendar;
147 NSString *rsvp, *method, *organizerUID;
149 chosenEvent = [self _setupChosenEventAndEventObject: &eventObject];
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"])
159 [calendar setMethod: @""];
160 rsvp = [[user rsvp] lowercaseString];
164 [eventObject saveContentString: [calendar versitString]];
165 if ([rsvp isEqualToString: @"true"])
166 [eventObject sendResponseToOrganizer];
167 organizerUID = [[chosenEvent organizer] uid];
169 [self _updateAttendee: user withSequence: [chosenEvent sequence]
170 andCalUID: [chosenEvent uid] forUID: organizerUID];
171 response = [self responseWith204];
175 response = [context response];
176 [response setStatus: 409];
182 - (WOResponse *) acceptAction
184 return [self _changePartStatusAction: @"ACCEPTED"];
187 - (WOResponse *) declineAction
189 return [self _changePartStatusAction: @"DECLINED"];
192 - (WOResponse *) deleteFromCalendarAction
194 iCalEvent *emailEvent;
195 SOGoAppointmentObject *eventObject;
196 WOResponse *response;
198 emailEvent = [self _emailEvent];
201 eventObject = [self _eventObjectWithUID: [emailEvent uid]];
202 response = [self responseWith204];
206 response = [context response];
207 [response setStatus: 409];
213 - (iCalPerson *) _emailParticipantWithEvent: (iCalEvent *) event
216 SOGoMailObject *mailObject;
217 NGImap4EnvelopeAddress *address;
219 mailObject = [[self clientObject] mailObject];
220 address = [[mailObject fromEnvelopeAddresses] objectAtIndex: 0];
221 emailFrom = [address baseEMail];
223 return [event findParticipantWithEmail: emailFrom];
226 - (BOOL) _updateParticipantStatusInEvent: (iCalEvent *) calendarEvent
227 fromEvent: (iCalEvent *) emailEvent
228 inObject: (SOGoAppointmentObject *) eventObject
230 iCalPerson *calendarParticipant, *mailParticipant;
234 calendarParticipant = [self _emailParticipantWithEvent: calendarEvent];
235 mailParticipant = [self _emailParticipantWithEvent: emailEvent];
236 if (calendarParticipant && mailParticipant)
239 partStat = [mailParticipant partStat];
240 if ([partStat caseInsensitiveCompare: [calendarParticipant partStat]]
243 [calendarParticipant setPartStat: [partStat uppercaseString]];
244 [eventObject saveComponent: calendarEvent];
253 - (WOResponse *) updateUserStatusAction
255 iCalEvent *emailEvent, *calendarEvent;
256 SOGoAppointmentObject *eventObject;
257 WOResponse *response;
261 emailEvent = [self _emailEvent];
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];
276 response = [context response];
277 [response setStatus: 409];
283 // - (WOResponse *) markTentativeAction
285 // return [self _changePartStatusAction: @"TENTATIVE"];
288 // - (WOResponse *) addToCalendarAction
290 // return [self responseWithStatus: 404];
293 // - (WOResponse *) deleteFromCalendarAction
295 // return [self responseWithStatus: 404];