mirror of
https://github.com/inverse-inc/sogo.git
synced 2026-10-05 12:00:33 +00:00
Monotone-Parent: 29948ba19f24f47aa6c1b2c0764586b89ff9493f
Monotone-Revision: 1a5434f30282a4932bf29227da4cf2da44ef5783 Monotone-Author: wsourdeau@inverse.ca Monotone-Date: 2008-07-11T22:28:12 Monotone-Branch: ca.inverse.sogo
This commit is contained in:
@@ -17,9 +17,6 @@ ADDITIONAL_INCLUDE_DIRS += -I../SOPE
|
||||
ADDITIONAL_LIB_DIRS += -L../SOPE/GDLContentStore/obj
|
||||
|
||||
libOGoContentStore_OBJC_FILES += \
|
||||
iCalEntityObject+OCS.m \
|
||||
iCalRepeatableEntityObject+OCS.m \
|
||||
\
|
||||
OCSiCalFieldExtractor.m \
|
||||
OCSContactFieldExtractor.m \
|
||||
|
||||
|
||||
@@ -19,34 +19,21 @@
|
||||
02111-1307, USA.
|
||||
*/
|
||||
|
||||
#import <Foundation/NSArray.h>
|
||||
#import <Foundation/NSCalendarDate.h>
|
||||
#import <Foundation/NSNull.h>
|
||||
#import <Foundation/NSDictionary.h>
|
||||
#import <Foundation/NSString.h>
|
||||
#import <Foundation/NSValue.h>
|
||||
|
||||
#import <NGExtensions/NSNull+misc.h>
|
||||
#import <NGExtensions/NSObject+Logs.h>
|
||||
#import <NGCards/iCalCalendar.h>
|
||||
|
||||
#import "iCalEntityObject+OCS.h"
|
||||
#import "iCalRepeatableEntityObject+OCS.h"
|
||||
#import <SoObjects/Appointments/iCalRepeatableEntityObject+SOGo.h>
|
||||
|
||||
#import "OCSiCalFieldExtractor.h"
|
||||
|
||||
@implementation OCSiCalFieldExtractor
|
||||
|
||||
static NSCalendarDate *distantFuture = nil;
|
||||
static NSNumber *distantFutureNumber = nil;
|
||||
|
||||
+ (void) initialize
|
||||
{
|
||||
if (!distantFuture)
|
||||
{
|
||||
distantFuture = [[NSCalendarDate distantFuture] retain];
|
||||
/* INT_MAX due to Postgres constraint */
|
||||
distantFutureNumber = [[NSNumber numberWithUnsignedInt: INT_MAX] retain];
|
||||
}
|
||||
}
|
||||
|
||||
+ (id) sharedICalFieldExtractor
|
||||
{
|
||||
static OCSiCalFieldExtractor *extractor = nil;
|
||||
@@ -59,287 +46,6 @@ static NSNumber *distantFutureNumber = nil;
|
||||
|
||||
/* operations */
|
||||
|
||||
- (NSNumber *) numberForDate: (NSCalendarDate *) _date
|
||||
{
|
||||
return ((_date == distantFuture)
|
||||
? distantFutureNumber
|
||||
: [NSNumber numberWithUnsignedInt: [_date timeIntervalSince1970]]);
|
||||
}
|
||||
|
||||
- (NSMutableDictionary *) extractQuickFieldsFromEvent: (iCalEvent *) _event
|
||||
{
|
||||
NSMutableDictionary *row;
|
||||
NSCalendarDate *startDate, *endDate;
|
||||
NSArray *attendees;
|
||||
NSString *uid, *title, *location, *status;
|
||||
NSNumber *sequence, *dateNumber;
|
||||
id organizer;
|
||||
id participants, partmails;
|
||||
NSMutableString *partstates;
|
||||
unsigned int i, count;
|
||||
BOOL isAllDay;
|
||||
iCalAccessClass accessClass;
|
||||
|
||||
if (_event == nil)
|
||||
return nil;
|
||||
|
||||
/* extract values */
|
||||
|
||||
startDate = [_event startDate];
|
||||
endDate = [_event endDate];
|
||||
uid = [_event uid];
|
||||
title = [_event summary];
|
||||
if (![title isNotNull])
|
||||
title = @"";
|
||||
location = [_event location];
|
||||
sequence = [_event sequence];
|
||||
accessClass = [_event symbolicAccessClass];
|
||||
isAllDay = [_event isAllDay];
|
||||
status = [[_event status] uppercaseString];
|
||||
|
||||
attendees = [_event attendees];
|
||||
partmails = [attendees valueForKey: @"rfc822Email"];
|
||||
partmails = [partmails componentsJoinedByString: @"\n"];
|
||||
participants = [attendees valueForKey: @"cn"];
|
||||
participants = [participants componentsJoinedByString: @"\n"];
|
||||
|
||||
/* build row */
|
||||
|
||||
row = [NSMutableDictionary dictionaryWithCapacity:8];
|
||||
|
||||
[row setObject: @"vevent" forKey: @"c_component"];
|
||||
|
||||
if ([uid isNotNull])
|
||||
[row setObject:uid forKey: @"c_uid"];
|
||||
else
|
||||
[self logWithFormat: @"WARNING: could not extract a uid from event!"];
|
||||
|
||||
|
||||
[row setObject: [NSNumber numberWithBool: isAllDay]
|
||||
forKey: @"c_isallday"];
|
||||
[row setObject: [NSNumber numberWithBool: [_event isRecurrent]]
|
||||
forKey: @"c_iscycle"];
|
||||
[row setObject: [NSNumber numberWithBool: [_event isOpaque]]
|
||||
forKey: @"c_isopaque"];
|
||||
[row setObject: [NSNumber numberWithInt: [_event priorityNumber]]
|
||||
forKey: @"c_priority"];
|
||||
|
||||
[row setObject: title forKey: @"c_title"];
|
||||
if ([location isNotNull]) [row setObject: location forKey: @"c_location"];
|
||||
if ([sequence isNotNull]) [row setObject: sequence forKey: @"c_sequence"];
|
||||
|
||||
if ([startDate isNotNull])
|
||||
[row setObject: [self numberForDate: startDate]
|
||||
forKey: @"c_startdate"];
|
||||
if ([endDate isNotNull])
|
||||
{
|
||||
if (endDate == distantFuture)
|
||||
dateNumber = distantFutureNumber;
|
||||
else
|
||||
{
|
||||
if (isAllDay)
|
||||
i = 1;
|
||||
else
|
||||
i = 0;
|
||||
dateNumber
|
||||
= [NSNumber numberWithUnsignedInt:
|
||||
[endDate timeIntervalSince1970] - i];
|
||||
}
|
||||
[row setObject: dateNumber forKey: @"c_enddate"];
|
||||
}
|
||||
|
||||
if ([_event isRecurrent]) {
|
||||
NSCalendarDate *date;
|
||||
|
||||
date = [_event lastPossibleRecurrenceStartDate];
|
||||
if (!date) {
|
||||
/* this could also be *nil*, but in the end it makes the fetchspecs
|
||||
more complex - thus we set it to a "reasonable" distant future */
|
||||
date = distantFuture;
|
||||
}
|
||||
[row setObject:[self numberForDate:date] forKey: @"c_cycleenddate"];
|
||||
[row setObject:[_event cycleInfo] forKey: @"c_cycleinfo"];
|
||||
}
|
||||
|
||||
if ([participants length] > 0)
|
||||
[row setObject: participants forKey: @"c_participants"];
|
||||
if ([partmails length] > 0)
|
||||
[row setObject: partmails forKey: @"c_partmails"];
|
||||
|
||||
if ([status isNotNull]) {
|
||||
int code = 1;
|
||||
|
||||
if ([status isEqualToString: @"TENTATIVE"])
|
||||
code = 2;
|
||||
else if ([status isEqualToString: @"CANCELLED"])
|
||||
code = 0;
|
||||
[row setObject:[NSNumber numberWithInt:code] forKey: @"c_status"];
|
||||
}
|
||||
else {
|
||||
/* confirmed by default */
|
||||
[row setObject: [NSNumber numberWithInt:1] forKey: @"c_status"];
|
||||
}
|
||||
|
||||
[row setObject: [NSNumber numberWithUnsignedInt: accessClass]
|
||||
forKey: @"c_classification"];
|
||||
|
||||
organizer = [_event organizer];
|
||||
if (organizer) {
|
||||
NSString *email;
|
||||
|
||||
email = [organizer valueForKey: @"rfc822Email"];
|
||||
if (email)
|
||||
[row setObject:email forKey: @"c_orgmail"];
|
||||
}
|
||||
|
||||
/* construct partstates */
|
||||
count = [attendees count];
|
||||
partstates = [[NSMutableString alloc] initWithCapacity:count * 2];
|
||||
for ( i = 0; i < count; i++) {
|
||||
iCalPerson *p;
|
||||
iCalPersonPartStat stat;
|
||||
|
||||
p = [attendees objectAtIndex:i];
|
||||
stat = [p participationStatus];
|
||||
if(i != 0)
|
||||
[partstates appendString: @"\n"];
|
||||
[partstates appendFormat: @"%d", stat];
|
||||
}
|
||||
[row setObject:partstates forKey: @"c_partstates"];
|
||||
[partstates release];
|
||||
return row;
|
||||
}
|
||||
|
||||
- (NSMutableDictionary *) extractQuickFieldsFromTodo: (iCalToDo *) _task
|
||||
{
|
||||
NSMutableDictionary *row;
|
||||
NSCalendarDate *startDate, *dueDate;
|
||||
NSArray *attendees;
|
||||
NSString *uid, *title, *location, *status;
|
||||
NSNumber *sequence;
|
||||
id organizer, date;
|
||||
id participants, partmails;
|
||||
NSMutableString *partstates;
|
||||
unsigned i, count, code;
|
||||
iCalAccessClass accessClass;
|
||||
|
||||
if (_task == nil)
|
||||
return nil;
|
||||
|
||||
/* extract values */
|
||||
|
||||
startDate = [_task startDate];
|
||||
dueDate = [_task due];
|
||||
uid = [_task uid];
|
||||
title = [_task summary];
|
||||
if (![title isNotNull])
|
||||
title = @"";
|
||||
location = [_task location];
|
||||
sequence = [_task sequence];
|
||||
accessClass = [_task symbolicAccessClass];
|
||||
status = [[_task status] uppercaseString];
|
||||
|
||||
attendees = [_task attendees];
|
||||
partmails = [attendees valueForKey: @"rfc822Email"];
|
||||
partmails = [partmails componentsJoinedByString: @"\n"];
|
||||
participants = [attendees valueForKey: @"cn"];
|
||||
participants = [participants componentsJoinedByString: @"\n"];
|
||||
|
||||
/* build row */
|
||||
|
||||
row = [NSMutableDictionary dictionaryWithCapacity:8];
|
||||
|
||||
[row setObject: @"vtodo" forKey: @"c_component"];
|
||||
|
||||
if ([uid isNotNull])
|
||||
[row setObject:uid forKey: @"c_uid"];
|
||||
else
|
||||
[self logWithFormat: @"WARNING: could not extract a uid from event!"];
|
||||
|
||||
[row setObject:[NSNumber numberWithBool:[_task isRecurrent]]
|
||||
forKey: @"c_iscycle"];
|
||||
[row setObject:[NSNumber numberWithInt:[_task priorityNumber]]
|
||||
forKey: @"c_priority"];
|
||||
|
||||
[row setObject: [NSNumber numberWithBool: NO]
|
||||
forKey: @"c_isallday"];
|
||||
[row setObject: [NSNumber numberWithBool: NO]
|
||||
forKey: @"c_isopaque"];
|
||||
|
||||
[row setObject: title forKey: @"c_title"];
|
||||
if ([location isNotNull]) [row setObject: location forKey: @"c_location"];
|
||||
if ([sequence isNotNull]) [row setObject: sequence forKey: @"c_sequence"];
|
||||
|
||||
if ([startDate isNotNull])
|
||||
date = [self numberForDate: startDate];
|
||||
else
|
||||
date = [NSNull null];
|
||||
[row setObject: date forKey: @"c_startdate"];
|
||||
|
||||
if ([dueDate isNotNull])
|
||||
date = [self numberForDate: dueDate];
|
||||
else
|
||||
date = [NSNull null];
|
||||
[row setObject: date forKey: @"c_enddate"];
|
||||
|
||||
if ([_task isRecurrent])
|
||||
{
|
||||
[row setObject: [self numberForDate: distantFuture]
|
||||
forKey: @"c_cycleenddate"];
|
||||
[row setObject: [_task cycleInfo]
|
||||
forKey: @"c_cycleinfo"];
|
||||
}
|
||||
|
||||
if ([participants length] > 0)
|
||||
[row setObject:participants forKey: @"c_participants"];
|
||||
if ([partmails length] > 0)
|
||||
[row setObject:partmails forKey: @"c_partmails"];
|
||||
|
||||
if ([status isNotNull]) {
|
||||
code = 0; /* NEEDS-ACTION */
|
||||
if ([status isEqualToString: @"COMPLETED"])
|
||||
code = 1;
|
||||
else if ([status isEqualToString: @"IN-PROCESS"])
|
||||
code = 2;
|
||||
else if ([status isEqualToString: @"CANCELLED"])
|
||||
code = 3;
|
||||
[row setObject: [NSNumber numberWithInt: code] forKey: @"c_status"];
|
||||
}
|
||||
else {
|
||||
/* confirmed by default */
|
||||
[row setObject:[NSNumber numberWithInt:1] forKey: @"c_status"];
|
||||
}
|
||||
|
||||
[row setObject: [NSNumber numberWithUnsignedInt: accessClass]
|
||||
forKey: @"c_classification"];
|
||||
|
||||
organizer = [_task organizer];
|
||||
if (organizer) {
|
||||
NSString *email;
|
||||
|
||||
email = [organizer valueForKey: @"rfc822Email"];
|
||||
if (email)
|
||||
[row setObject:email forKey: @"c_orgmail"];
|
||||
}
|
||||
|
||||
/* construct partstates */
|
||||
count = [attendees count];
|
||||
partstates = [[NSMutableString alloc] initWithCapacity:count * 2];
|
||||
for ( i = 0; i < count; i++) {
|
||||
iCalPerson *p;
|
||||
iCalPersonPartStat stat;
|
||||
|
||||
p = [attendees objectAtIndex:i];
|
||||
stat = [p participationStatus];
|
||||
if(i != 0)
|
||||
[partstates appendString: @"\n"];
|
||||
[partstates appendFormat: @"%d", stat];
|
||||
}
|
||||
[row setObject:partstates forKey: @"c_partstates"];
|
||||
[partstates release];
|
||||
return row;
|
||||
}
|
||||
|
||||
- (CardGroup *) firstElementFromCalendar: (iCalCalendar *) ical
|
||||
{
|
||||
NSArray *elements;
|
||||
@@ -349,13 +55,7 @@ static NSNumber *distantFutureNumber = nil;
|
||||
elements = [ical allObjects];
|
||||
count = [elements count];
|
||||
if (count)
|
||||
{
|
||||
if (count > 1)
|
||||
[self logWithFormat:
|
||||
@"WARNING: given calendar contains more than one event: %@",
|
||||
ical];
|
||||
element = [elements objectAtIndex: 0];
|
||||
}
|
||||
element = [elements objectAtIndex: 0];
|
||||
else
|
||||
{
|
||||
[self logWithFormat: @"ERROR: given calendar contains no elements: %@", ical];
|
||||
@@ -365,34 +65,32 @@ static NSNumber *distantFutureNumber = nil;
|
||||
return element;
|
||||
}
|
||||
|
||||
- (NSMutableDictionary *)extractQuickFieldsFromContent:(NSString *)_content {
|
||||
NSDictionary *fields;
|
||||
- (NSMutableDictionary *) extractQuickFieldsFromContent: (NSString *) _content
|
||||
{
|
||||
NSMutableDictionary *fields;
|
||||
id cal;
|
||||
|
||||
if ([_content length] == 0)
|
||||
return nil;
|
||||
|
||||
cal = [iCalCalendar parseSingleFromSource: _content];
|
||||
|
||||
fields = nil;
|
||||
if (cal)
|
||||
|
||||
if ([_content length])
|
||||
{
|
||||
if ([cal isKindOfClass:[iCalCalendar class]])
|
||||
cal = [self firstElementFromCalendar: cal];
|
||||
cal = [iCalCalendar parseSingleFromSource: _content];
|
||||
if (cal)
|
||||
{
|
||||
if ([cal isKindOfClass: [iCalCalendar class]])
|
||||
cal = [self firstElementFromCalendar: cal];
|
||||
|
||||
if ([cal isKindOfClass:[iCalEvent class]])
|
||||
fields = [[self extractQuickFieldsFromEvent:cal] retain];
|
||||
else if ([cal isKindOfClass:[iCalToDo class]])
|
||||
fields = [[self extractQuickFieldsFromTodo:cal] retain];
|
||||
else if ([cal isNotNull]) {
|
||||
[self logWithFormat: @"ERROR: unexpected iCalendar parse result: %@",
|
||||
cal];
|
||||
}
|
||||
if ([cal isKindOfClass: [iCalRepeatableEntityObject class]])
|
||||
fields = [cal quickRecord];
|
||||
else if ([cal isNotNull])
|
||||
[self logWithFormat: @"ERROR: unexpected iCalendar parse result: %@",
|
||||
cal];
|
||||
}
|
||||
else
|
||||
[self logWithFormat: @"ERROR: parsing source didn't return anything"];
|
||||
}
|
||||
else
|
||||
[self logWithFormat: @"ERROR: parsing source didn't return anything"];
|
||||
|
||||
return [fields autorelease];
|
||||
return fields;
|
||||
}
|
||||
|
||||
@end /* OCSiCalFieldExtractor */
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
Copyright (C) 2004-2005 SKYRIX Software AG
|
||||
|
||||
This file is part of OpenGroupware.org.
|
||||
|
||||
OGo is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU Lesser General Public License as published by the
|
||||
Free Software Foundation; either version 2, or (at your option) any
|
||||
later version.
|
||||
|
||||
OGo is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with OGo; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __OGoContentStore_iCalEntityObject_OCS_H_
|
||||
#define __OGoContentStore_iCalEntityObject_OCS_H_
|
||||
|
||||
#include <NGCards/NGCards.h>
|
||||
|
||||
@interface iCalEntityObject (OCS)
|
||||
|
||||
- (int)priorityNumber;
|
||||
|
||||
@end
|
||||
|
||||
#endif /* __OGoContentStore_iCalEntityObject_OCS_H_ */
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
Copyright (C) 2004-2005 SKYRIX Software AG
|
||||
|
||||
This file is part of OpenGroupware.org.
|
||||
|
||||
OGo is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU Lesser General Public License as published by the
|
||||
Free Software Foundation; either version 2, or (at your option) any
|
||||
later version.
|
||||
|
||||
OGo is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with OGo; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
02111-1307, USA.
|
||||
*/
|
||||
|
||||
#import "iCalEntityObject+OCS.h"
|
||||
|
||||
@implementation iCalEntityObject (OCS)
|
||||
|
||||
- (int)priorityNumber {
|
||||
NSString *prio;
|
||||
|
||||
prio = [self priority];
|
||||
if(prio) {
|
||||
NSRange r;
|
||||
|
||||
r = [prio rangeOfString:@";"];
|
||||
if(r.length > 0) {
|
||||
prio = [prio substringToIndex:r.location];
|
||||
}
|
||||
return [prio intValue];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -26,59 +26,4 @@
|
||||
|
||||
@implementation iCalRepeatableEntityObject (OCS)
|
||||
|
||||
- (NSArray *) _indexedRules: (NSArray *) rules
|
||||
{
|
||||
NSMutableArray *ma;
|
||||
unsigned int i, count;
|
||||
NSString *valuesString;
|
||||
|
||||
ma = nil;
|
||||
count = [rules count];
|
||||
if (count > 0)
|
||||
{
|
||||
ma = [NSMutableArray arrayWithCapacity:count];
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
iCalRecurrenceRule *rule;
|
||||
|
||||
rule = [rules objectAtIndex:i];
|
||||
#warning we could return an NSArray instead and feed it as such to the iCalRecurrenceRule in SOGoAppointmentFolder...
|
||||
valuesString = [[rule values] componentsJoinedByString: @";"];
|
||||
[ma addObject: valuesString];
|
||||
}
|
||||
}
|
||||
|
||||
return ma;
|
||||
}
|
||||
|
||||
- (NSString *) cycleInfo
|
||||
{
|
||||
NSArray *rules;
|
||||
NSString *value;
|
||||
NSMutableDictionary *cycleInfo;
|
||||
|
||||
if ([self isRecurrent])
|
||||
{
|
||||
cycleInfo = [NSMutableDictionary dictionaryWithCapacity: 3];
|
||||
|
||||
/* rules */
|
||||
rules = [self _indexedRules: [self recurrenceRules]];
|
||||
if (rules)
|
||||
[cycleInfo setObject: rules forKey: @"rules"];
|
||||
|
||||
rules = [self _indexedRules: [self exceptionRules]];
|
||||
if (rules)
|
||||
[cycleInfo setObject: rules forKey: @"exRules"];
|
||||
|
||||
rules = [self _indexedRules: [self exceptionDates]];
|
||||
if (rules)
|
||||
[cycleInfo setObject: rules forKey: @"exDates"];
|
||||
|
||||
value = [cycleInfo description];
|
||||
}
|
||||
else
|
||||
value = nil;
|
||||
|
||||
return value;
|
||||
}
|
||||
@end
|
||||
|
||||
Reference in New Issue
Block a user