diff --git a/ChangeLog b/ChangeLog index 3686ee661..5e379f2ba 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2010-06-04 Wolfgang Sourdeau + + * SoObjects/Appointments/SOGoAppointmentFolderXML.[hm]: same as + below for XML. + + * SoObjects/Appointments/SOGoAppointmentFolderICS.[hm]: new class + module that exports personal calendars as one ICS file. + + * SoObjects/Appointments/SOGoAppointmentFolders.m + (-folderObjectKeys): new method that return the "toOne..." keys + mapping XML or ICS representation of calendars. + 2010-06-03 Wolfgang Sourdeau * UI/WebServerResources/generic.js (CurrentModule): new function diff --git a/SoObjects/Appointments/GNUmakefile b/SoObjects/Appointments/GNUmakefile index 45771bc29..ad3b7e790 100644 --- a/SoObjects/Appointments/GNUmakefile +++ b/SoObjects/Appointments/GNUmakefile @@ -14,7 +14,7 @@ Appointments_OBJC_FILES = \ iCalRepeatableEntityObject+SOGo.m \ iCalEvent+SOGo.m \ iCalEventChanges+SOGo.m \ - iCalPerson+SOGo.m \ + iCalPerson+SOGo.m \ iCalToDo+SOGo.m \ \ SOGoCalendarComponent.m \ @@ -22,10 +22,13 @@ Appointments_OBJC_FILES = \ SOGoTaskObject.m \ SOGoComponentOccurence.m \ SOGoAppointmentOccurence.m \ - SOGoTaskOccurence.m \ + SOGoTaskOccurence.m \ SOGoAppointmentFolder.m \ - SOGoAppointmentInboxFolder.m \ - SOGoWebAppointmentFolder.m \ + SOGoAppointmentFolderICS.m \ + SOGoAppointmentFolderObject.m \ + SOGoAppointmentFolderXML.m \ + SOGoAppointmentInboxFolder.m \ + SOGoWebAppointmentFolder.m \ SOGoAppointmentFolders.m \ SOGoFreeBusyObject.m \ SOGoUser+Appointments.m \ diff --git a/SoObjects/Appointments/SOGoAppointmentFolderICS.h b/SoObjects/Appointments/SOGoAppointmentFolderICS.h new file mode 100644 index 000000000..1b81c814b --- /dev/null +++ b/SoObjects/Appointments/SOGoAppointmentFolderICS.h @@ -0,0 +1,32 @@ +/* SOGoAppointmentFolderICS.h - this file is part of SOGo + * + * Copyright (C) 2010 Inverse inc. + * + * Author: Wolfgang Sourdeau + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This file 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef SOGOAPPOINTMENTFOLDERICS_H +#define SOGOAPPOINTMENTFOLDERICS_H + +#import "SOGoAppointmentFolderObject.h" + +@interface SOGoAppointmentFolderICS : SOGoAppointmentFolderObject + +@end + +#endif /* SOGOAPPOINTMENTFOLDERICS_H */ diff --git a/SoObjects/Appointments/SOGoAppointmentFolderICS.m b/SoObjects/Appointments/SOGoAppointmentFolderICS.m new file mode 100644 index 000000000..5289327ee --- /dev/null +++ b/SoObjects/Appointments/SOGoAppointmentFolderICS.m @@ -0,0 +1,41 @@ + /* SOGoAppointmentFolderICS.m - this file is part of SOGo + * + * Copyright (C) 2010 Inverse inc. + * + * Author: Wolfgang Sourdeau + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This file 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#import + +#import + +#import "SOGoAppointmentFolderICS.h" + +@implementation SOGoAppointmentFolderICS + +- (NSString *) contentAsString +{ + return [[self contentCalendar] versitString]; +} + +- (NSString *) davContentType +{ + return @"text/calendar"; +} + +@end diff --git a/SoObjects/Appointments/SOGoAppointmentFolderObject.h b/SoObjects/Appointments/SOGoAppointmentFolderObject.h new file mode 100644 index 000000000..c69d6a444 --- /dev/null +++ b/SoObjects/Appointments/SOGoAppointmentFolderObject.h @@ -0,0 +1,39 @@ +/* SOGoAppointmentFolderObject.h - this file is part of SOGo + * + * Copyright (C) 2010 Inverse inc. + * + * Author: Wolfgang Sourdeau + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This file 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef SOGOAPPOINTMENTFOLDEROBJECT_H +#define SOGOAPPOINTMENTFOLDEROBJECT_H + +#import + +@class SOGoAppointmentFolder; + +@interface SOGoAppointmentFolderObject : SOGoObject +{ + SOGoAppointmentFolder *folder; +} + +- (iCalCalendar *) contentCalendar; + +@end + +#endif /* SOGOAPPOINTMENTFOLDEROBJECT_H */ diff --git a/SoObjects/Appointments/SOGoAppointmentFolderObject.m b/SoObjects/Appointments/SOGoAppointmentFolderObject.m new file mode 100644 index 000000000..223115ccf --- /dev/null +++ b/SoObjects/Appointments/SOGoAppointmentFolderObject.m @@ -0,0 +1,185 @@ + /* SOGoAppointmentFolderObject.m - this file is part of SOGo + * + * Copyright (C) 2010 Inverse inc. + * + * Author: Wolfgang Sourdeau + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This file 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#import +#import +#import + +#import +#import + +#import +#import + +#import "SOGoAppointmentFolder.h" +#import "SOGoCalendarComponent.h" + +#import "SOGoAppointmentFolderObject.h" + +@implementation SOGoAppointmentFolderObject + +- (id) init +{ + if ((self = [super init])) + { + folder = nil; + } + + return self; +} + +- (void) dealloc +{ + [folder release]; + [super dealloc]; +} + +- (BOOL) isFolderish +{ + return NO; +} + +- (SOGoAppointmentFolder *) _folder +{ + NSString *folderName; + int length; + + if (!folder) + { + length = [nameInContainer length]; + if (length > 3) + { + folderName = [nameInContainer substringToIndex: length - 4]; + folder = [container lookupName: folderName + inContext: context + acquire: NO]; + [folder retain]; + } + } + + return folder; +} + +- (NSArray *) aclsForUser: (NSString *) login +{ + return [[self _folder] aclsForUser: login]; +} + +- (void) _extractTimeZones: (NSArray *) timeZones + intoDictionary: (NSMutableDictionary *) tzDict +{ + int count, max; + iCalTimeZone *timeZone; + NSString *tzId; + + max = [timeZones count]; + for (count = 0; count < max; count++) + { + timeZone = [timeZones objectAtIndex: count]; + tzId = [timeZone tzId]; + if (![tzDict objectForKey: tzId]) + [tzDict setObject: timeZone forKey: tzId]; + } +} + +- (void) _extractCalendarsData: (NSArray *) calendars + intoTimeZones: (NSMutableDictionary *) timeZones + andComponents: (NSMutableArray *) components +{ + int count, max; + iCalCalendar *calendar; + + max = [calendars count]; + for (count = 0; count < max; count++) + { + calendar = [calendars objectAtIndex: count]; + [self _extractTimeZones: [calendar timezones] + intoDictionary: timeZones]; + [components addObjectsFromArray: [calendar allObjects]]; + } +} + +- (NSArray *) _folderCalendars +{ + NSArray *names; + int count, max; + SOGoCalendarComponent *component; + NSMutableArray *calendars; + + names = [[self _folder] toOneRelationshipKeys]; + max = [names count]; + calendars = [NSMutableArray arrayWithCapacity: max]; + + for (count = 0; count < max; count++) + { + component = [folder lookupName: [names objectAtIndex: count] + inContext: context + acquire: NO]; + [calendars addObject: [component calendar: NO secure: YES]]; + } + + return calendars; +} + +- (iCalCalendar *) contentCalendar +{ + NSArray *calendars; + iCalCalendar *calendar; + NSMutableDictionary *timeZones; + NSMutableArray *components; + + calendars = [self _folderCalendars]; + timeZones = [NSMutableDictionary dictionaryWithCapacity: 16]; + components = [NSMutableArray arrayWithCapacity: [calendars count] * 2]; + [self _extractCalendarsData: calendars + intoTimeZones: timeZones andComponents: components]; + + calendar = [iCalCalendar groupWithTag: @"vcalendar"]; + [calendar setMethod: @"PUBLISH"]; + [calendar setVersion: @"2.0"]; + [calendar setProdID: @"-//Inverse inc./SOGo 1.0//EN"]; + [calendar addChildren: [timeZones allValues]]; + [calendar addChildren: components]; + + return calendar; +} + +- (id) davEntityTag +{ + return [[self _folder] davCollectionTag]; +} + +- (NSString *) contentAsString +{ + [self subclassResponsibility: _cmd]; + + return nil; +} + +- (NSString *) davContentType +{ + [self subclassResponsibility: _cmd]; + + return nil; +} + +@end diff --git a/SoObjects/Appointments/SOGoAppointmentFolderXML.h b/SoObjects/Appointments/SOGoAppointmentFolderXML.h new file mode 100644 index 000000000..5ebe1838c --- /dev/null +++ b/SoObjects/Appointments/SOGoAppointmentFolderXML.h @@ -0,0 +1,32 @@ +/* SOGoAppointmentFolderXML.h - this file is part of SOGo + * + * Copyright (C) 2010 Inverse inc. + * + * Author: Wolfgang Sourdeau + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This file 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef SOGOAPPOINTMENTFOLDERXML_H +#define SOGOAPPOINTMENTFOLDERXML_H + +#import "SOGoAppointmentFolderObject.h" + +@interface SOGoAppointmentFolderXML : SOGoAppointmentFolderObject + +@end + +#endif /* SOGOAPPOINTMENTFOLDERXML_H */ diff --git a/SoObjects/Appointments/SOGoAppointmentFolderXML.m b/SoObjects/Appointments/SOGoAppointmentFolderXML.m new file mode 100644 index 000000000..bfe40bc67 --- /dev/null +++ b/SoObjects/Appointments/SOGoAppointmentFolderXML.m @@ -0,0 +1,45 @@ +/* SOGoAppointmentFolderXML.m - this file is part of SOGo + * + * Copyright (C) 2010 Inverse inc. + * + * Author: Wolfgang Sourdeau + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This file 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#import + +#import + +#import "SOGoAppointmentFolderXML.h" + +@implementation SOGoAppointmentFolderXML + +- (NSString *) contentAsString +{ + iCalXMLRenderer *renderer; + + renderer = [iCalXMLRenderer sharedXMLRenderer]; + + return [renderer render: [self contentCalendar]]; +} + +- (NSString *) davContentType +{ + return @"application/xml+calendar"; +} + +@end diff --git a/SoObjects/Appointments/SOGoAppointmentFolders.h b/SoObjects/Appointments/SOGoAppointmentFolders.h index 4699966af..0d392a923 100644 --- a/SoObjects/Appointments/SOGoAppointmentFolders.h +++ b/SoObjects/Appointments/SOGoAppointmentFolders.h @@ -28,6 +28,9 @@ @class NSArray; @interface SOGoAppointmentFolders : SOGoParentFolder +{ + NSMutableArray *folderObjectKeys; +} - (NSArray *) webCalendarIds; - (void) reloadWebCalendars: (BOOL) forceReload; diff --git a/SoObjects/Appointments/SOGoAppointmentFolders.m b/SoObjects/Appointments/SOGoAppointmentFolders.m index 4931c66f8..cd14805f4 100644 --- a/SoObjects/Appointments/SOGoAppointmentFolders.m +++ b/SoObjects/Appointments/SOGoAppointmentFolders.m @@ -47,6 +47,8 @@ #import #import "SOGoAppointmentFolder.h" +#import "SOGoAppointmentFolderICS.h" +#import "SOGoAppointmentFolderXML.h" #import "SOGoAppointmentInboxFolder.h" #import "SOGoWebAppointmentFolder.h" #import "SOGoUser+Appointments.h" @@ -63,6 +65,22 @@ @implementation SOGoAppointmentFolders +- (id) init +{ + if ((self = [super init])) + { + folderObjectKeys = nil; + } + + return self; +} + +- (void) dealloc +{ + [folderObjectKeys release]; + [super dealloc]; +} + + (NSString *) gcsFolderType { return @"Appointment"; @@ -118,6 +136,42 @@ return keys; } +- (NSArray *) folderObjectKeys +{ + NSArray *folders; + SOGoAppointmentFolder *folder; + NSString *folderObjectKey; + int count, max; + + if (!folderObjectKeys) + { + folders = [self subFolders]; + max = [folders count]; + folderObjectKeys = [[NSMutableArray alloc] initWithCapacity: max]; + for (count = 0; count < max; count++) + { + folder = [folders objectAtIndex: count]; + if ([folder isMemberOfClass: [SOGoAppointmentFolder class]] + && ![folder isSubscription]) + { + folderObjectKey = [NSString stringWithFormat: @"%@.ics", + [folder nameInContainer]]; + [folderObjectKeys addObject: folderObjectKey]; + folderObjectKey = [NSString stringWithFormat: @"%@.xml", + [folder nameInContainer]]; + [folderObjectKeys addObject: folderObjectKey]; + } + } + } + + return folderObjectKeys; +} + +- (NSArray *) toOneRelationshipKeys +{ + return [self folderObjectKeys]; +} + - (id) lookupName: (NSString *) name inContext: (WOContext *) lookupContext acquire: (BOOL) acquire @@ -127,6 +181,17 @@ if ([name isEqualToString: @"inbox"]) obj = [SOGoAppointmentInboxFolder objectWithName: name inContainer: self]; + else if ([[self folderObjectKeys] containsObject: name]) + { + if ([name hasSuffix: @".ics"]) + obj = [SOGoAppointmentFolderICS objectWithName: name + inContainer: self]; + else if ([name hasSuffix: @".xml"]) + obj = [SOGoAppointmentFolderXML objectWithName: name + inContainer: self]; + else + obj = nil; + } else obj = [super lookupName: name inContext: lookupContext acquire: NO]; diff --git a/SoObjects/Appointments/product.plist b/SoObjects/Appointments/product.plist index 865942b97..ac04c7d41 100644 --- a/SoObjects/Appointments/product.plist +++ b/SoObjects/Appointments/product.plist @@ -22,12 +22,12 @@ "ViewDAndTOfPublicRecords" = ( "Owner", "PublicDAndTViewer" ); "ViewDAndTOfPrivateRecords" = ( "Owner", "PrivateDAndTViewer" ); "ViewDAndTOfConfidentialRecords" = ( "Owner", "ConfidentialDAndTViewer" ); - "ModifyPublicRecords" = ( ); - "ModifyPrivateRecords" = ( ); - "ModifyConfidentialRecords" = ( ); - "RespondToPublicRecords" = ( ); - "RespondToPrivateRecords" = ( ); - "RespondToConfidentialRecords" = ( ); + "ModifyPublicRecords" = ( "NoOne" ); + "ModifyPrivateRecords" = ( "NoOne" ); + "ModifyConfidentialRecords" = ( "NoOne" ); + "RespondToPublicRecords" = ( "NoOne" ); + "RespondToPrivateRecords" = ( "NoOne" ); + "RespondToConfidentialRecords" = ( "NoOne" ); }; }; SOGoAppointmentFolder = { @@ -49,10 +49,25 @@ "RespondToConfidentialRecords" = ( "Owner", "ConfidentialModifier", "ConfidentialResponder" ); }; }; + SOGoAppointmentFolderObject = { + superclass = "SOGoAppointmentFolder"; + protectedBy = "Access Contents Information"; + defaultRoles = { + "Access Contents Information" = ( "Owner", "PublicResponder", "PublicModifier", "PublicViewer", "PublicDAndTViewer", "PrivateResponder", "PrivateModifier", "PrivateViewer", "PrivateDAndTViewer", "ConfidentialResponder", "ConfidentialModifier", "ConfidentialViewer", "ConfidentialDAndTViewer", "AuthorizedSubscriber" ); + "WebDAV Access" = ( "Owner", "Authenticated", "PublicUser" ); + "Change Images And Files" = ( "NoOne" ); + }; + }; + SOGoAppointmentFolderICS = { + superclass = "SOGoAppointmentFolderObject"; + }; + SOGoAppointmentFolderXML = { + superclass = "SOGoAppointmentFolderObject"; + }; SOGoAppointmentInboxFolder = { superclass = "SOGoAppointmentFolder"; defaultRoles = { - "Access Contents Information" = ( "Owner", "AuthorizedSubscriber" ); + "Access Contents Information" = ( "Owner" ); }; }; SOGoCalendarComponent = {