mirror of
https://github.com/inverse-inc/sogo.git
synced 2026-09-15 02:18:00 +00:00
Monotone-Parent: 19b0008e26816c6e8c6ccdb5329120a04a33f229
Monotone-Revision: 1a3634c32194a58102b74c15f2af08066e7d4e91 Monotone-Author: wsourdeau@inverse.ca Monotone-Date: 2010-05-17T15:29:57 Monotone-Branch: ca.inverse.sogo
This commit is contained in:
@@ -1068,325 +1068,4 @@ _computeBlocksPosition (NSArray *blocks)
|
||||
return [self _responseWithData: filteredTasks];
|
||||
}
|
||||
|
||||
|
||||
- (void) _fillFreeBusy: (unsigned int *) fb
|
||||
forUid: (NSString *) uid
|
||||
fromDate: (NSCalendarDate *) start
|
||||
{
|
||||
SOGoUser *user;
|
||||
SOGoFreeBusyObject *fbObject;
|
||||
NSCalendarDate *end;
|
||||
NSArray *records;
|
||||
NSDictionary *record;
|
||||
NSArray *emails, *partstates;
|
||||
NSCalendarDate *currentDate;
|
||||
unsigned int recordCount, recordMax;
|
||||
int count, startInterval, endInterval, i, type;
|
||||
int itemCount = (offsetBlocks + maxBlocks);
|
||||
|
||||
user = [SOGoUser userWithLogin: uid];
|
||||
fbObject
|
||||
= [[user homeFolderInContext: context] freeBusyObject: @"freebusy.ifb"
|
||||
inContext: context];
|
||||
|
||||
end = [start addTimeInterval: (itemCount * quarterLength)];
|
||||
|
||||
records = [fbObject fetchFreeBusyInfosFrom: start to: end];
|
||||
recordMax = [records count];
|
||||
|
||||
for (recordCount = 0; recordCount < recordMax; recordCount++)
|
||||
{
|
||||
record = [records objectAtIndex: recordCount];
|
||||
if ([[record objectForKey: @"c_isopaque"] boolValue])
|
||||
{
|
||||
type = 0;
|
||||
|
||||
// If the event has NO organizer (which means it's the user that has created it) OR
|
||||
// If we are the organizer of the event THEN we are automatically busy
|
||||
if ([[record objectForKey: @"c_orgmail"] length] == 0 ||
|
||||
[user hasEmail: [record objectForKey: @"c_orgmail"]])
|
||||
{
|
||||
type = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// We check if the user has accepted/declined or needs action
|
||||
// on the current event.
|
||||
emails = [[record objectForKey: @"c_partmails"] componentsSeparatedByString: @"\n"];
|
||||
|
||||
for (i = 0; i < [emails count]; i++)
|
||||
{
|
||||
if ([user hasEmail: [emails objectAtIndex: i]])
|
||||
{
|
||||
// We now fetch the c_partstates array and get the participation
|
||||
// status of the user for the event
|
||||
partstates = [[record objectForKey: @"c_partstates"] componentsSeparatedByString: @"\n"];
|
||||
|
||||
if (i < [partstates count])
|
||||
{
|
||||
type = ([[partstates objectAtIndex: i] intValue] < 2 ? 1 : 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
currentDate = [record objectForKey: @"startDate"];
|
||||
if ([currentDate earlierDate: start] == currentDate)
|
||||
startInterval = 0;
|
||||
else
|
||||
startInterval = ([currentDate timeIntervalSinceDate: start]
|
||||
/ quarterLength);
|
||||
|
||||
currentDate = [record objectForKey: @"endDate"];
|
||||
if ([currentDate earlierDate: end] == end)
|
||||
endInterval = itemCount - 1;
|
||||
else
|
||||
endInterval = ([currentDate timeIntervalSinceDate: start]
|
||||
/ quarterLength);
|
||||
|
||||
if (type == 1)
|
||||
for (count = startInterval; count < endInterval; count++)
|
||||
*(fb + count) = 1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
- (unsigned int **) _loadFreeBusyForUsers: (NSArray *) uids
|
||||
fromDate: (NSCalendarDate *) start
|
||||
{
|
||||
unsigned int **fbData, **node;
|
||||
int count, max;
|
||||
|
||||
max = [uids count];
|
||||
fbData = calloc (max, sizeof (unsigned int *));
|
||||
for (count = 0; count < max; count++)
|
||||
{
|
||||
node = fbData + count;
|
||||
*node = calloc (offsetBlocks + maxBlocks, sizeof (unsigned int *));
|
||||
[self _fillFreeBusy: *node forUid: [uids objectAtIndex: count]
|
||||
fromDate: start];
|
||||
}
|
||||
|
||||
return fbData;
|
||||
}
|
||||
|
||||
- (BOOL) _possibleBlock: (int) block
|
||||
forUsers: (int) users
|
||||
freeBusy: (unsigned int **) fbData
|
||||
interval: (int) blocks
|
||||
{
|
||||
unsigned int *node;
|
||||
int bCount, uCount;
|
||||
BOOL rc = YES;
|
||||
|
||||
for (uCount = 0; uCount < users; uCount++)
|
||||
{
|
||||
node = *(fbData + uCount);
|
||||
for (bCount = block; bCount < block + blocks; bCount++)
|
||||
{
|
||||
if (*(node+bCount) != 0)
|
||||
{
|
||||
rc = NO;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
- (NSCalendarDate *) _parseDateField: (NSString *) dateF
|
||||
timeField: (NSString *) timeF
|
||||
{
|
||||
NSString *buffer;
|
||||
NSCalendarDate *rc;
|
||||
|
||||
buffer = [NSString stringWithFormat: @"%@ %@",
|
||||
[[context request] formValueForKey: dateF],
|
||||
[[context request] formValueForKey: timeF]];
|
||||
rc = [NSCalendarDate dateWithString: buffer
|
||||
calendarFormat: @"%Y%m%d %H:%M"];
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
- (NSMutableDictionary *) _makeValidResponseFrom: (NSCalendarDate *) nStart
|
||||
to: (NSCalendarDate *) nEnd
|
||||
{
|
||||
NSMutableDictionary *rc;
|
||||
|
||||
rc = [NSMutableDictionary dictionaryWithCapacity: 512];
|
||||
[rc setObject: [nStart descriptionWithCalendarFormat: @"%Y%m%d"]
|
||||
forKey: @"startDate"];
|
||||
[rc setObject: [nStart descriptionWithCalendarFormat: @"%H"]
|
||||
forKey: @"startHour"];
|
||||
[rc setObject: [nStart descriptionWithCalendarFormat: @"%M"]
|
||||
forKey: @"startMinute"];
|
||||
|
||||
[rc setObject: [nEnd descriptionWithCalendarFormat: @"%Y%m%d"]
|
||||
forKey: @"endDate"];
|
||||
[rc setObject: [nEnd descriptionWithCalendarFormat: @"%H"]
|
||||
forKey: @"endHour"];
|
||||
[rc setObject: [nEnd descriptionWithCalendarFormat: @"%M"]
|
||||
forKey: @"endMinute"];
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
- (BOOL) _validateStart: (NSCalendarDate *) start
|
||||
andEnd: (NSCalendarDate *) end
|
||||
against: (NSArray *) limits
|
||||
{
|
||||
NSCalendarDate *sFrom, *sTo, *eFrom, *eTo;
|
||||
BOOL rc = YES;
|
||||
|
||||
sFrom = [NSCalendarDate dateWithYear: [start yearOfCommonEra]
|
||||
month: [start monthOfYear]
|
||||
day: [start dayOfMonth]
|
||||
hour: [[limits objectAtIndex: 0] hourOfDay]
|
||||
minute: [[limits objectAtIndex: 0] minuteOfHour]
|
||||
second: 0
|
||||
timeZone: [start timeZone]];
|
||||
sTo = [NSCalendarDate dateWithYear: [start yearOfCommonEra]
|
||||
month: [start monthOfYear]
|
||||
day: [start dayOfMonth]
|
||||
hour: [[limits objectAtIndex: 1] hourOfDay]
|
||||
minute: [[limits objectAtIndex: 1] minuteOfHour]
|
||||
second: 0
|
||||
timeZone: [start timeZone]];
|
||||
|
||||
eFrom = [NSCalendarDate dateWithYear: [end yearOfCommonEra]
|
||||
month: [end monthOfYear]
|
||||
day: [end dayOfMonth]
|
||||
hour: [[limits objectAtIndex: 0] hourOfDay]
|
||||
minute: [[limits objectAtIndex: 0] minuteOfHour]
|
||||
second: 0
|
||||
timeZone: [end timeZone]];
|
||||
eTo = [NSCalendarDate dateWithYear: [end yearOfCommonEra]
|
||||
month: [end monthOfYear]
|
||||
day: [end dayOfMonth]
|
||||
hour: [[limits objectAtIndex: 1] hourOfDay]
|
||||
minute: [[limits objectAtIndex: 1] minuteOfHour]
|
||||
second: 0
|
||||
timeZone: [end timeZone]];
|
||||
|
||||
// start < sFrom
|
||||
if ([sFrom compare: start] == NSOrderedDescending)
|
||||
rc = NO;
|
||||
// start > sTo
|
||||
if ([sTo compare: start] == NSOrderedAscending)
|
||||
rc = NO;
|
||||
|
||||
// end > eTo
|
||||
if ([eTo compare: end] == NSOrderedAscending)
|
||||
rc = NO;
|
||||
// end < eFrom
|
||||
if ([eFrom compare: end] == NSOrderedDescending)
|
||||
rc = NO;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
- (NSArray *) _loadScheduleLimitsForUsers: (NSArray *) users
|
||||
{
|
||||
SOGoUserDefaults *ud;
|
||||
NSCalendarDate *from, *to, *maxFrom, *maxTo;
|
||||
int count;
|
||||
|
||||
maxFrom = [NSCalendarDate dateWithString: @"00:01"
|
||||
calendarFormat: @"%H:%M"];
|
||||
maxTo = [NSCalendarDate dateWithString: @"23:59"
|
||||
calendarFormat: @"%H:%M"];
|
||||
|
||||
for (count = 0; count < [users count]; count++)
|
||||
{
|
||||
ud = [[SOGoUser userWithLogin: [users objectAtIndex: count]
|
||||
roles: nil] userDefaults];
|
||||
if (ud)
|
||||
{
|
||||
from = [NSCalendarDate dateWithString: [ud dayStartTime]
|
||||
calendarFormat: @"%H:%M"];
|
||||
to = [NSCalendarDate dateWithString: [ud dayEndTime]
|
||||
calendarFormat: @"%H:%M"];
|
||||
maxFrom = (NSCalendarDate *)[from laterDate: maxFrom];
|
||||
maxTo = (NSCalendarDate *)[to earlierDate: maxTo];
|
||||
}
|
||||
}
|
||||
|
||||
return [NSArray arrayWithObjects: maxFrom, maxTo, nil];
|
||||
}
|
||||
|
||||
- (WOResponse *) findPossibleSlotAction
|
||||
{
|
||||
WORequest *r;
|
||||
NSCalendarDate *nStart, *nEnd;
|
||||
NSArray *uids, *limits;
|
||||
NSMutableDictionary *rc;
|
||||
int direction, count, blockDuration, step;
|
||||
unsigned int **fbData;
|
||||
BOOL isAllDay = NO, onlyOfficeHours = YES;
|
||||
|
||||
r = [context request];
|
||||
rc = nil;
|
||||
|
||||
uids = [[r formValueForKey: @"uids"] componentsSeparatedByString: @","];
|
||||
if ([uids count] > 0)
|
||||
{
|
||||
isAllDay = [[r formValueForKey: @"isAllDay"] boolValue];
|
||||
onlyOfficeHours = [[r formValueForKey: @"onlyOfficeHours"] boolValue];
|
||||
direction = [[r formValueForKey: @"direction"] intValue];
|
||||
limits = [self _loadScheduleLimitsForUsers: uids];
|
||||
|
||||
if (isAllDay)
|
||||
step = direction * 96;
|
||||
else
|
||||
step = direction;
|
||||
|
||||
nStart = [[self _parseDateField: @"startDate"
|
||||
timeField: @"startTime"]
|
||||
addTimeInterval: quarterLength * step];
|
||||
nEnd = [[self _parseDateField: @"endDate"
|
||||
timeField: @"endTime"]
|
||||
addTimeInterval: quarterLength * step];
|
||||
blockDuration = [nEnd timeIntervalSinceDate: nStart] / quarterLength;
|
||||
|
||||
fbData = [self _loadFreeBusyForUsers: uids
|
||||
fromDate: [nStart addTimeInterval: -offsetSeconds]];
|
||||
|
||||
for (count = offsetBlocks;
|
||||
(count < offsetBlocks + maxBlocks) && count >= 0;
|
||||
count += step)
|
||||
{
|
||||
//NSLog (@"Trying %@ -> %@", nStart, nEnd);
|
||||
if ((onlyOfficeHours && [self _validateStart: nStart
|
||||
andEnd: nEnd
|
||||
against: limits])
|
||||
|| !onlyOfficeHours)
|
||||
{
|
||||
//NSLog (@"valid");
|
||||
if ([self _possibleBlock: count
|
||||
forUsers: [uids count]
|
||||
freeBusy: fbData
|
||||
interval: blockDuration])
|
||||
{
|
||||
//NSLog (@"possible");
|
||||
rc = [self _makeValidResponseFrom: nStart
|
||||
to: nEnd];
|
||||
break;
|
||||
}
|
||||
}
|
||||
nStart = [nStart addTimeInterval: quarterLength * step];
|
||||
nEnd = [nEnd addTimeInterval: quarterLength * step];
|
||||
}
|
||||
|
||||
for (count = 0; count < [uids count]; count++)
|
||||
free (*(fbData+count));
|
||||
free (fbData);
|
||||
}
|
||||
|
||||
return [self _responseWithData: [NSArray arrayWithObjects: rc, nil]];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
Reference in New Issue
Block a user