Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
*/
-// $Id$
-#include "SOGoFreeBusyObject.h"
-#include "common.h"
-#include <SOGo/AgenorUserManager.h>
-#include <NGiCal/NGiCal.h>
-#include <NGiCal/iCalRenderer.h>
+#import <Foundation/NSCalendarDate.h>
+#import <Foundation/NSDictionary.h>
+#import <Foundation/NSEnumerator.h>
+#import <Foundation/NSValue.h>
-@interface NSDate(UsedPrivates)
-- (NSString *)icalString; // declared in NGiCal
-@end
+#import <NGObjWeb/WOContext+SoObjects.h>
+#import <NGObjWeb/WOResponse.h>
+#import <NGExtensions/NSCalendarDate+misc.h>
+#import <NGCards/iCalCalendar.h>
+#import <NGCards/iCalFreeBusy.h>
+#import <NGCards/iCalPerson.h>
+
+#import <SOGo/LDAPUserManager.h>
+#import <SOGo/SOGoUser.h>
+#import <SOGo/SOGoPermissions.h>
+
+#import "SOGoAppointmentFolder.h"
+
+#import "SOGoFreeBusyObject.h"
@interface SOGoFreeBusyObject (PrivateAPI)
-- (NSString *)iCalStringForFreeBusyInfos:(NSArray *)_infos
- from:(NSCalendarDate *)_startDate
- to:(NSCalendarDate *)_endDate;
+- (NSString *) iCalStringForFreeBusyInfos: (NSArray *) _infos
+ from: (NSCalendarDate *) _startDate
+ to: (NSCalendarDate *) _endDate;
@end
@implementation SOGoFreeBusyObject
-- (NSString *)iCalString {
+- (NSString *) iCalString
+{
// for UI-X appointment viewer
return [self contentAsString];
}
-- (NSString *)contentAsString {
- NSCalendarDate *startDate, *endDate;
+- (NSString *) contentAsString
+{
+ NSCalendarDate *today, *startDate, *endDate;
+ NSTimeZone *timeZone;
- startDate = [[[NSCalendarDate calendarDate] mondayOfWeek] beginOfDay];
- endDate = [startDate dateByAddingYears:0
- months:0
- days:7
- hours:23
- minutes:59
- seconds:59];
- return [self contentAsStringFrom:startDate to:endDate];
+ today = [[NSCalendarDate calendarDate] beginOfDay];
+ timeZone = [[context activeUser] timeZone];
+ [today setTimeZone: timeZone];
+
+ startDate = [today dateByAddingYears: 0 months: 0 days: -14
+ hours: 0 minutes: 0 seconds: 0];
+ endDate = [startDate dateByAddingYears: 0 months: 1 days: 0
+ hours: 0 minutes: 0 seconds: 0];
+
+ return [self contentAsStringFrom: startDate to: endDate];
}
-- (NSString *)contentAsStringFrom:(NSCalendarDate *)_startDate
- to:(NSCalendarDate *)_endDate
+- (NSString *) contentAsStringFrom: (NSCalendarDate *) _startDate
+ to: (NSCalendarDate *) _endDate
{
NSArray *infos;
- infos = [self fetchFreebusyInfosFrom:_startDate to:_endDate];
+ infos = [self fetchFreeBusyInfosFrom:_startDate to:_endDate];
return [self iCalStringForFreeBusyInfos:infos from:_startDate to:_endDate];
}
-- (NSArray *)fetchFreebusyInfosFrom:(NSCalendarDate *)_startDate
- to:(NSCalendarDate *)_endDate
+- (NSArray *) fetchFreeBusyInfosFrom: (NSCalendarDate *) _startDate
+ to: (NSCalendarDate *) _endDate
{
- id userFolder, calFolder;
- NSArray *infos;
- AgenorUserManager *um;
- NSString *email;
- NSMutableArray *filtered;
- unsigned i, count;
-
- userFolder = [self container];
- calFolder = [userFolder lookupName:@"Calendar" inContext:nil acquire:NO];
- infos = [calFolder fetchFreebusyInfosFrom:_startDate to:_endDate];
- um = [AgenorUserManager sharedUserManager];
- email = [um getEmailForUID:[userFolder login]];
- count = [infos count];
- filtered = [[[NSMutableArray alloc] initWithCapacity:count] autorelease];
-
- for (i = 0; i < count; i++) {
- NSDictionary *info;
- NSArray *partmails;
- unsigned p, pCount;
-
- info = [infos objectAtIndex:i];
- partmails = [[info objectForKey:@"partmails"]
- componentsSeparatedByString:@"\n"];
- pCount = [partmails count];
- for (p = 0; p < pCount; p++) {
- NSString *pEmail;
-
- pEmail = [partmails objectAtIndex:p];
- if ([pEmail isEqualToString:email]) {
- NSArray *partstates;
- NSString *state;
-
- partstates = [[info objectForKey:@"partstates"]
- componentsSeparatedByString:@"\n"];
- state = [partstates objectAtIndex:p];
- if ([state intValue] == iCalPersonPartStatAccepted) {
- // TODO: add tentative apts as well, but put state and email
- // into info
- [filtered addObject:info];
- }
- break;
- }
- }
- }
- return filtered;
+ SOGoAppointmentFolder *calFolder;
+// SoSecurityManager *sm;
+ NSArray *infos;
+
+ calFolder = [[container lookupName: @"Calendar" inContext: nil acquire: NO]
+ lookupName: @"personal" inContext: nil acquire: NO];
+// sm = [SoSecurityManager sharedSecurityManager];
+// if (![sm validatePermission: SOGoPerm_FreeBusyLookup
+// onObject: calFolder
+// inContext: context])
+ infos = [calFolder fetchFreeBusyInfosFrom: _startDate
+ to: _endDate];
+// else
+// {
+// infos = [NSArray new];
+// [infos autorelease];
+// }
+
+ return infos;
}
/* Private API */
+- (iCalFreeBusyType) _fbTypeForEventStatus: (NSNumber *) eventStatus
+{
+ unsigned int status;
+ iCalFreeBusyType fbType;
+
+ status = [eventStatus unsignedIntValue];
+ if (status == 0)
+ fbType = iCalFBBusyTentative;
+ else if (status == 1)
+ fbType = iCalFBBusy;
+ else
+ fbType = iCalFBFree;
+
+ return fbType;
+}
-- (NSString *)iCalStringForFreeBusyInfos:(NSArray *)_infos
- from:(NSCalendarDate *)_startDate
- to:(NSCalendarDate *)_endDate
+- (iCalPerson *) iCalPersonWithUID: (NSString *) uid
{
- AgenorUserManager *um;
- NSMutableString *ms;
- NSString *uid, *x;
- unsigned i, count;
+ iCalPerson *person;
+ LDAPUserManager *um;
+ NSDictionary *contactInfos;
+
+ um = [LDAPUserManager sharedUserManager];
+ contactInfos = [um contactInfosForUserWithUIDorEmail: uid];
+
+ person = [iCalPerson new];
+ [person autorelease];
+ [person setCn: [contactInfos objectForKey: @"cn"]];
+ [person setEmail: [contactInfos objectForKey: @"c_email"]];
+
+ return person;
+}
+
+- (NSString *) iCalStringForFreeBusyInfos: (NSArray *) _infos
+ from: (NSCalendarDate *) _startDate
+ to: (NSCalendarDate *) _endDate
+{
+ NSString *uid;
+ NSEnumerator *events;
+ iCalCalendar *calendar;
+ iCalFreeBusy *freebusy;
+ NSDictionary *info;
+ iCalFreeBusyType type;
- um = [AgenorUserManager sharedUserManager];
uid = [[self container] login];
- ms = [[[NSMutableString alloc] initWithCapacity:128] autorelease];
-
- /* preamble */
- [ms appendString:@"BEGIN:VCALENDAR\r\n"];
- [ms appendString:@"BEGIN:VFREEBUSY\r\n"];
- /* PRODID */
- [ms appendString:@"PRODID:SOGo/0.9\r\n"];
- /* VERSION */
- [ms appendString:@"VERSION:2.0\r\n"];
- /* DTSTAMP */
- [ms appendString:@"DTSTAMP:"];
- [ms appendString:[[NSCalendarDate calendarDate] icalString]];
- [ms appendString:@"\r\n"];
-
+
+ calendar = [iCalCalendar groupWithTag: @"vcalendar"];
+ [calendar setProdID: @"//Inverse groupe conseil/SOGo 0.9"];
+ [calendar setVersion: @"2.0"];
+
+ freebusy = [iCalFreeBusy groupWithTag: @"vfreebusy"];
+ [freebusy addToAttendees: [self iCalPersonWithUID: uid]];
+ [freebusy setTimeStampAsDate: [NSCalendarDate calendarDate]];
+ [freebusy setStartDate: _startDate];
+ [freebusy setEndDate: _endDate];
+
/* ORGANIZER - strictly required but missing for now */
/* ATTENDEE */
- [ms appendString:@"ATTENDEE"];
- if ((x = [um getCNForUID:uid])) {
- [ms appendString:@";CN=\""];
- [ms appendString:[x iCalDQUOTESafeString]];
- [ms appendString:@"\""];
- }
- if ((x = [um getEmailForUID:uid])) {
- [ms appendString:@":"]; /* sic! */
- [ms appendString:[x iCalSafeString]];
- }
- [ms appendString:@"\r\n"];
-
- /* DTSTART */
- [ms appendString:@"DTSTART:"];
- [ms appendString:[_startDate icalString]];
- [ms appendString:@"\r\n"];
-
- /* DTEND */
- [ms appendString:@"DTEND:"];
- [ms appendString:[_endDate icalString]];
- [ms appendString:@"\r\n"];
+// person = [self iCalPersonWithUid: uid];
+// [person setTag: @"ATTENDEE"];
+// [ms appendString: [person versitString]];
/* FREEBUSY */
- count = [_infos count];
- for (i = 0; i < count; i++) {
- NSDictionary *info;
- NSCalendarDate *startDate, *endDate;
-
- info = [_infos objectAtIndex:i];
- startDate = [info objectForKey:@"startDate"];
- endDate = [info objectForKey:@"endDate"];
-
- /* NOTE: currently we cannot differentiate between all the types defined
- * in RFC2445, Section 4.2.9.
- * These are: FREE" / "BUSY" / "BUSY-UNAVAILABLE" / "BUSY-TENTATIVE"
- */
-
- [ms appendString:@"FREEBUSY;FBTYPE=BUSY:"];
- [ms appendString:[startDate icalString]];
- [ms appendString:@"/"];
- [ms appendString:[endDate icalString]];
- [ms appendString:@"\r\n"];
- }
-
- /* postamble */
- [ms appendString:@"END:VFREEBUSY\r\n"];
- [ms appendString:@"END:VCALENDAR\r\n"];
- return ms;
+ events = [_infos objectEnumerator];
+ info = [events nextObject];
+ while (info)
+ {
+ if ([[info objectForKey: @"c_isopaque"] boolValue])
+ {
+ type = [self _fbTypeForEventStatus: [info objectForKey: @"c_status"]];
+ [freebusy addFreeBusyFrom: [info objectForKey: @"startDate"]
+ to: [info objectForKey: @"endDate"]
+ type: type];
+ }
+ info = [events nextObject];
+ }
+
+ [calendar setUniqueChild: freebusy];
+
+ return [calendar versitString];
}
/* deliver content without need for view method */
-- (id)GETAction:(id)_ctx {
+- (id) GETAction: (id)_ctx
+{
WOResponse *r;
NSData *contentData;
- contentData = [[self contentAsString] dataUsingEncoding:NSUTF8StringEncoding];
+ contentData = [[self contentAsString] dataUsingEncoding: NSUTF8StringEncoding];
+
+ r = [(WOContext *) _ctx response];
+ [r setHeader: @"text/calendar" forKey: @"content-type"];
+ [r setContent: contentData];
+ [r setStatus: 200];
- r = [(WOContext *)_ctx response];
- [r setHeader:@"text/calendar" forKey:@"content-type"];
- [r setContent:contentData];
- [r setStatus:200];
return r;
}
+- (NSString *) davContentType
+{
+ return @"text/calendar";
+}
+
@end