Monotone-Parent: f4b1c33458e395b67d8a7e5d8465de2e7bb1bc50

Monotone-Revision: bb0d71310c5e05a41e1acc07768c6ec4c2b2b5fe

Monotone-Author: wsourdeau@inverse.ca
Monotone-Date: 2008-06-19T18:31:18
Monotone-Branch: ca.inverse.sogo
maint-2.0.2
Wolfgang Sourdeau 2008-06-19 18:31:18 +00:00
parent ee5713f146
commit b658f6890c
5 changed files with 142 additions and 163 deletions

View File

@ -1,3 +1,25 @@
2008-06-19 Wolfgang Sourdeau <wsourdeau@inverse.ca>
* UI/MainUI/SOGoUserHomePage.m ([SOGoUserHomePage
-readFreeBusyAction]): accelerated the process of rendering free
busy information by using ptr** instead of NSArray.
* SoObjects/Appointments/SOGoFreeBusyObject.m ([SOGoFreeBusyObject
+initialize]): initialize the default interval based on the new
"SOGoFreeBusyDefaultInterval" user default array.
([SOGoFreeBusyObject
-fetchFreeBusyInfosFrom:startDateto:endDate]): fetch the events
from all the owner calendars.
* SoObjects/Appointments/SOGoAppointmentFolder.m
([SOGoAppointmentFolder
-fetchFields:_fieldsfrom:_startDateto:_endDatetitle:titlecomponent:_componentadditionalFilters:filters]):
add processed recurrent events to the list of records.
([SOGoAppointmentFolder
-fetchFreeBusyInfosFrom:_startDateto:_endDate]): request the
"c_cycleinfo" field in order for the recurrent events to be taken
into account.
2008-06-13 Wolfgang Sourdeau <wsourdeau@inverse.ca>
* SoObjects/Appointments/SOGoAppointmentFolder.m

View File

@ -512,29 +512,29 @@ static Class sogoAppointmentFolderKlass = Nil;
fetchRange: (NGCalendarDateRange *) _r
{
NSMutableDictionary *md;
id tmp;
md = [[_record mutableCopy] autorelease];
if ((tmp = [_record objectForKey:@"c_startdate"])) {
tmp = [[NSCalendarDate alloc] initWithTimeIntervalSince1970:
(NSTimeInterval)[tmp unsignedIntValue]];
[tmp setTimeZone: timeZone];
if (tmp) [md setObject:tmp forKey:@"startDate"];
[tmp release];
}
else
[self logWithFormat:@"missing 'startdate' in record?"];
static NSString *fields[] = { @"c_startdate", @"startDate",
@"c_enddate", @"endDate" };
unsigned int count;
NSCalendarDate *date;
NSNumber *dateValue;
if ((tmp = [_record objectForKey:@"c_enddate"])) {
tmp = [[NSCalendarDate alloc] initWithTimeIntervalSince1970:
(NSTimeInterval)[tmp unsignedIntValue]];
[tmp setTimeZone: timeZone];
if (tmp) [md setObject:tmp forKey:@"endDate"];
[tmp release];
}
else
[self logWithFormat:@"missing 'enddate' in record?"];
md = [[_record mutableCopy] autorelease];
for (count = 0; count < 2; count++)
{
dateValue = [_record objectForKey: fields[count * 2]];
if (dateValue)
{
date = [NSCalendarDate dateWithTimeIntervalSince1970:
(NSTimeInterval) [dateValue unsignedIntValue]];
if (date)
{
[date setTimeZone: timeZone];
[md setObject: date forKey: fields[count * 2 + 1]];
}
}
else
[self logWithFormat:@"missing '%@' in record?", fields[count * 2]];
}
return md;
}
@ -797,11 +797,11 @@ static Class sogoAppointmentFolderKlass = Nil;
records = [folder fetchFields: fields matchingQualifier: qualifier];
if (records)
{
if (r) {
if (r)
records = [self fixupCyclicRecords: records fetchRange: r];
}
if (!ma)
ma = [NSMutableArray arrayWithCapacity: [records count]];
[ma addObjectsFromArray: records];
}
else if (!ma)
{
@ -1772,7 +1772,7 @@ _selectorForProperty (NSString *property)
if (!infos)
infos = [[NSArray alloc] initWithObjects: @"c_partmails", @"c_partstates",
@"c_isopaque", @"c_status", nil];
@"c_isopaque", @"c_status", @"c_cycleinfo", nil];
return [self fetchFields: infos
from: _startDate to: _endDate

View File

@ -23,6 +23,7 @@
#import <Foundation/NSDictionary.h>
#import <Foundation/NSEnumerator.h>
#import <Foundation/NSValue.h>
#import <Foundation/NSUserDefaults.h>
#import <NGObjWeb/WOContext+SoObjects.h>
#import <NGObjWeb/WOResponse.h>
@ -36,9 +37,13 @@
#import <SOGo/SOGoPermissions.h>
#import "SOGoAppointmentFolder.h"
#import "SOGoAppointmentFolders.h"
#import "SOGoFreeBusyObject.h"
static unsigned int freebusyRangeStart = 0;
static unsigned int freebusyRangeEnd = 0;
@interface SOGoFreeBusyObject (PrivateAPI)
- (NSString *) iCalStringForFreeBusyInfos: (NSArray *) _infos
from: (NSCalendarDate *) _startDate
@ -47,6 +52,25 @@
@implementation SOGoFreeBusyObject
+ (void) initialize
{
NSArray *freebusyDateRange;
NSUserDefaults *ud;
ud = [NSUserDefaults standardUserDefaults];
freebusyDateRange = [ud arrayForKey: @"SOGoFreeBusyDefaultInterval"];
if (freebusyDateRange && [freebusyDateRange count] > 1)
{
freebusyRangeStart = [[freebusyDateRange objectAtIndex: 0] unsignedIntValue];
freebusyRangeEnd = [[freebusyDateRange objectAtIndex: 1] unsignedIntValue];
}
else
{
freebusyRangeStart = 7;
freebusyRangeEnd = 7;
}
}
- (NSString *) contentAsString
{
NSCalendarDate *today, *startDate, *endDate;
@ -56,9 +80,9 @@
timeZone = [[context activeUser] timeZone];
[today setTimeZone: timeZone];
startDate = [today dateByAddingYears: 0 months: 0 days: -14
startDate = [today dateByAddingYears: 0 months: 0 days: -freebusyRangeStart
hours: 0 minutes: 0 seconds: 0];
endDate = [startDate dateByAddingYears: 0 months: 1 days: 0
endDate = [startDate dateByAddingYears: 0 months: 0 days: freebusyRangeEnd
hours: 0 minutes: 0 seconds: 0];
return [self contentAsStringFrom: startDate to: endDate];
@ -70,29 +94,32 @@
NSArray *infos;
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
{
SOGoAppointmentFolder *calFolder;
// SoSecurityManager *sm;
NSArray *infos;
NSArray *folders;
NSMutableArray *infos;
unsigned int count, max;
calFolder = [[container lookupName: @"Calendar" inContext: context acquire: NO]
lookupName: @"personal" inContext: context 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];
// }
infos = [NSMutableArray array];
folders = [[container lookupName: @"Calendar"
inContext: context
acquire: NO] subFolders];
max = [folders count];
for (count = 0; count < max; count++)
{
calFolder = [folders objectAtIndex: count];
if (![calFolder isSubscription])
[infos addObjectsFromArray: [calFolder fetchFreeBusyInfosFrom: startDate
to: endDate]];
}
return infos;
}
@ -169,18 +196,14 @@
/* FREEBUSY */
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];
}
while ((info = [events nextObject]))
if ([[info objectForKey: @"c_isopaque"] boolValue])
{
type = [self _fbTypeForEventStatus: [info objectForKey: @"c_status"]];
[freebusy addFreeBusyFrom: [info objectForKey: @"startDate"]
to: [info objectForKey: @"endDate"]
type: type];
}
[calendar setUniqueChild: freebusy];

View File

@ -52,21 +52,6 @@
@implementation SOGoUserFolder
// + (void) initialize
// {
// SoClassSecurityInfo *sInfo;
// NSArray *basicRoles;
// sInfo = [self soClassSecurityInfo];
// [sInfo declareObjectProtected: SoPerm_View];
// basicRoles = [NSArray arrayWithObject: SoRole_Authenticated];
// /* require Authenticated role for View and WebDAV */
// [sInfo declareRoles: basicRoles asDefaultForPermission: SoPerm_View];
// [sInfo declareRoles: basicRoles asDefaultForPermission: SoPerm_WebDAVAccess];
// }
/* hierarchy */
- (NSArray *) toManyRelationshipKeys
@ -413,20 +398,6 @@
return r;
}
// - (SOGoGroupsFolder *) lookupGroupsFolder
// {
// return [self lookupName: @"Groups" inContext: nil acquire: NO];
// }
/* name lookup */
// - (NSString *) permissionForKey: (NSString *) key
// {
// return ([key isEqualToString: @"freebusy.ifb"]
// ? SoPerm_WebDAVAccess
// : [super permissionForKey: key]);
// }
- (SOGoAppointmentFolders *) privateCalendars: (NSString *) key
inContext: (WOContext *) localContext
{
@ -456,12 +427,6 @@
return contacts;
}
// - (id) groupsFolder: (NSString *) _key
// inContext: (WOContext *) _ctx
// {
// return [$(@"SOGoGroupsFolder") objectWithName: _key inContainer: self];
// }
- (id) mailAccountsFolder: (NSString *) _key
inContext: (WOContext *) _ctx
{
@ -489,13 +454,8 @@
if ([_key isEqualToString: @"Calendar"]
&& [currentUser canAccessModule: _key])
obj = [self privateCalendars: @"Calendar" inContext: _ctx];
// if (![_key isEqualToString: @"Calendar"])
// obj = [obj lookupName: [_key pathExtension]
// inContext: _ctx acquire: NO];
else if ([_key isEqualToString: @"Contacts"])
obj = [self privateContacts: _key inContext: _ctx];
// else if ([_key isEqualToString: @"Groups"])
// obj = [self groupsFolder: _key inContext: _ctx];
else if ([_key isEqualToString: @"Mail"]
&& [currentUser canAccessModule: _key])
obj = [self mailAccountsFolder: _key inContext: _ctx];
@ -511,39 +471,6 @@
return obj;
}
// /* FIXME: here is a vault of hackish ways to gain access to subobjects by
// granting ro access to the homepage depending on the subobject in question.
// This is wrong and dangerous. */
// - (NSString *) roleOfUser: (NSString *) uid
// inContext: (WOContext *) context
// {
// NSArray *roles, *traversalPath;
// NSString *objectName, *role;
// role = nil;
// traversalPath = [context objectForKey: @"SoRequestTraversalPath"];
// if ([traversalPath count] > 1)
// {
// objectName = [traversalPath objectAtIndex: 1];
// if ([objectName isEqualToString: @"Calendar"]
// || [objectName isEqualToString: @"Contacts"])
// {
// roles = [[context activeUser]
// rolesForObject: [self lookupName: objectName
// inContext: context
// acquire: NO]
// inContext: context];
// if ([roles containsObject: SOGoRole_Assistant]
// || [roles containsObject: SOGoRole_Delegate])
// role = SOGoRole_Assistant;
// }
// else if ([objectName isEqualToString: @"freebusy.ifb"])
// role = SOGoRole_Assistant;
// }
// return role;
// }
/* WebDAV */
- (NSArray *) fetchContentObjectNames

View File

@ -41,6 +41,8 @@
#import <SoObjects/SOGo/NSCalendarDate+SOGo.h>
#import <SOGoUI/UIxComponent.h>
#define intervalSeconds 900 /* 15 minutes */
static NSString *defaultModule = nil;
@interface SOGoUserHomePage : UIxComponent
@ -87,60 +89,65 @@ static NSString *defaultModule = nil;
return [self redirectToLocation: [moduleURL absoluteString]];
}
- (void) _fillFreeBusyItems: (NSMutableArray *) items
withRecords: (NSEnumerator *) records
- (void) _fillFreeBusyItems: (unsigned int *) items
count: (unsigned int) itemCount
withRecords: (NSArray *) records
fromStartDate: (NSCalendarDate *) startDate
toEndDate: (NSCalendarDate *) endDate
{
NSDictionary *record;
int count, startInterval, endInterval, value;
NSNumber *status;
int recordCount, recordMax, count, startInterval, endInterval;
NSCalendarDate *currentDate;
while ((record = [records nextObject]))
recordMax = [records count];
for (recordCount = 0; recordCount < recordMax; recordCount++)
{
status = [record objectForKey: @"c_status"];
value = [[record objectForKey: @"c_startdate"] intValue];
currentDate = [NSCalendarDate dateWithTimeIntervalSince1970: value];
if ([currentDate earlierDate: startDate] == currentDate)
startInterval = 0;
else
startInterval
= ([currentDate timeIntervalSinceDate: startDate] / 900);
record = [records objectAtIndex: recordCount];
if ([[record objectForKey: @"c_isopaque"] boolValue])
{
currentDate = [record objectForKey: @"startDate"];
if ([currentDate earlierDate: startDate] == currentDate)
startInterval = 0;
else
startInterval = ([currentDate timeIntervalSinceDate: startDate]
/ intervalSeconds);
value = [[record objectForKey: @"c_enddate"] intValue];
currentDate = [NSCalendarDate dateWithTimeIntervalSince1970: value];
if ([currentDate earlierDate: endDate] == endDate)
endInterval = [items count] - 1;
else
endInterval = ([currentDate timeIntervalSinceDate: startDate] / 900);
currentDate = [record objectForKey: @"endDate"];
if ([currentDate earlierDate: endDate] == endDate)
endInterval = itemCount - 1;
else
endInterval = ([currentDate timeIntervalSinceDate: startDate]
/ intervalSeconds);
for (count = startInterval; count < endInterval; count++)
[items replaceObjectAtIndex: count withObject: status];
for (count = startInterval; count < endInterval; count++)
*(items + count) = 1;
}
}
}
- (NSString *) _freeBusyAsTextFromStartDate: (NSCalendarDate *) startDate
toEndDate: (NSCalendarDate *) endDate
forFreeBusy: (SOGoFreeBusyObject *) fb
{
NSEnumerator *records;
NSMutableArray *freeBusyItems;
NSMutableString *response;
unsigned int *freeBusyItems;
NSTimeInterval interval;
int count, intervals;
unsigned int count, intervals;
interval = [endDate timeIntervalSinceDate: startDate] + 60;
intervals = interval / 900; /* slices of 15 minutes */
freeBusyItems = [NSMutableArray arrayWithCapacity: intervals];
for (count = 1; count < intervals; count++)
[freeBusyItems addObject: @"0"];
records = [[fb fetchFreeBusyInfosFrom: startDate to: endDate] objectEnumerator];
[self _fillFreeBusyItems: freeBusyItems withRecords: records
intervals = interval / intervalSeconds; /* slices of 15 minutes */
freeBusyItems = calloc (intervals, sizeof (int));
[self _fillFreeBusyItems: freeBusyItems count: intervals
withRecords: [fb fetchFreeBusyInfosFrom: startDate to: endDate]
fromStartDate: startDate toEndDate: endDate];
return [freeBusyItems componentsJoinedByString: @","];
response = [NSMutableString string];
for (count = 0; count < intervals; count++)
[response appendFormat: @"%d,", *(freeBusyItems + count)];
[response deleteCharactersInRange: NSMakeRange (intervals * 2 - 1, 1)];
free (freeBusyItems);
return response;
}
- (NSString *) _freeBusyAsText