From 87e89240d04eb9fb9eea10a14417cad4af198eee Mon Sep 17 00:00:00 2001 From: wolfgang Date: Fri, 29 Jun 2007 22:13:24 +0000 Subject: [PATCH] git-svn-id: http://svn.opengroupware.org/SOGo/inverse/trunk@1092 d1b88da0-ebda-0310-925b-ed51d893ca5b --- ChangeLog | 41 +++++ Main/GNUmakefile.preamble | 2 +- Main/SOGo.m | 119 +++++++++++-- Main/common.h | 33 ---- Main/sogod.m | 24 ++- .../sql/generate-folderinfo-sql-for-users.sh | 164 ------------------ .../Appointments/SOGoAppointmentFolder.m | 11 +- SoObjects/Contacts/SOGoContactFolders.m | 58 +++++-- SoObjects/Contacts/SOGoContactGCSFolder.m | 5 + SoObjects/Mailer/SOGoMailObject.m | 19 +- SoObjects/SOGo/AgenorUserDefaults.m | 16 +- SoObjects/SOGo/SOGoFolder.h | 2 + SoObjects/SOGo/SOGoFolder.m | 56 ++++-- SoObjects/SOGo/SOGoUserFolder.m | 19 +- UI/MailerUI/WOContext+UIxMailer.m | 42 ++--- .../MainUI/AgenorProfile.sql | 3 +- UI/MainUI/GNUmakefile | 4 +- .../MainUI/OCSFolderInfo.sql | 16 +- UI/Scheduler/French.lproj/Localizable.strings | 2 +- UI/Templates/MailerUI/UIxMailView.wox | 2 +- UI/WebServerResources/SchedulerUI.js | 2 +- 21 files changed, 320 insertions(+), 320 deletions(-) delete mode 100644 Main/common.h delete mode 100755 OGoContentStore/sql/generate-folderinfo-sql-for-users.sh rename OGoContentStore/sql/profile-create.psql => UI/MainUI/AgenorProfile.sql (61%) rename OGoContentStore/sql/folderinfo-create.psql => UI/MainUI/OCSFolderInfo.sql (65%) diff --git a/ChangeLog b/ChangeLog index 24e07bf2..176fc004 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,46 @@ +2007-06-29 Wolfgang Sourdeau + + * SoObjects/SOGo/AgenorUserDefaults.m ([AgenorUserDefaults + -generateSQLForInsert]): initialize error to nil before the + serialization. Otherwise the method can get confused if it ever is + initialized to something else. + + * SoObjects/SOGo/SOGoUserFolder.m ([SOGoUserFolder + -folderIsMandatory]): returns NO unconditionnally. + + * SoObjects/Contacts/SOGoContactFolders.m ([SOGoContactFolders + -appendPersonalSources]): add the "personal" folder to the list of + user folders even if it doesn't exist, so that it is created when + the user accesses it. + + * SoObjects/Contacts/SOGoContactGCSFolder.m ([SOGoContactGCSFolder + -folderIsMandatory]): returns YES if nameInContainer is set to + "personal", which is the default address book. + + * SoObjects/Appointments/SOGoAppointmentFolder.m + ([SOGoAppointmentFolder -folderIsMandatory]): returns YES since + users must have one Calendar folder (one and only one). + ([SOGoAppointmentFolder -_privacySqlString]): unescape the + escaping '\' so make the carriage return a real one. This way, + PgSQL 8 won't complain about escaping the string. + + * SoObjects/SOGo/SOGoFolder.m ([SOGoFolder -ocsFolder]): new + method that create the folder if considered mandatory. + ([SOGoFolder -folderIsMandatory]): new method that determines + whether the folder should be created automatically or not. To be + overriden by subclasses. + + * Main/SOGo.m ([SOGo -run]): override method and create the + missing system tables if needed. + 2007-06-28 Wolfgang Sourdeau + * UI/MailerUI/WOContext+UIxMailer.m ([WOContext + -mailDateFormatter]): returns the user's date formatter. + + * SoObjects/Mailer/SOGoMailObject.m ([SOGoMailObject -date]): + applies the user timezone to the date object before returning it. + * UI/Common/UIxSortButton.m: removed useless class module. * UI/Common/UIxSortableTableHeader.m: removed useless class diff --git a/Main/GNUmakefile.preamble b/Main/GNUmakefile.preamble index 9938d4af..6d8c1dc9 100644 --- a/Main/GNUmakefile.preamble +++ b/Main/GNUmakefile.preamble @@ -7,7 +7,7 @@ ADDITIONAL_CPPFLAGS += \ ADDITIONAL_INCLUDE_DIRS += \ -I../SoObjects/ \ - -I../.. + -I.. ADDITIONAL_LIB_DIRS += \ -L../SoObjects/SOGo/$(GNUSTEP_OBJ_DIR)/ \ diff --git a/Main/SOGo.m b/Main/SOGo.m index b6406ceb..218c1448 100644 --- a/Main/SOGo.m +++ b/Main/SOGo.m @@ -19,11 +19,37 @@ 02111-1307, USA. */ -#include +#import +#import +#import +#import +#import +#import + +#import +#import + +#import +#import +#import +#import + +#import +#import +#import +#import + +#import + +#import +#import +#import + +#import "SOGoProductLoader.h" @interface SOGo : SoApplication { - NSMutableDictionary *localeLUT; + NSMutableDictionary *localeLUT; } - (NSDictionary *) currentLocaleConsideringLanguages:(NSArray *)_langs; @@ -31,17 +57,11 @@ @end -#include "SOGoProductLoader.h" -#include -#include -#include -#include -#include "common.h" - @implementation SOGo static unsigned int vMemSizeLimit = 0; static BOOL doCrashOnSessionCreate = NO; +static BOOL hasCheckedTables = NO; #ifdef GNUSTEP_BASE_LIBRARY static BOOL debugObjectAllocation = NO; @@ -123,6 +143,83 @@ static BOOL debugObjectAllocation = NO; [super dealloc]; } +- (void) _checkTableWithCM: (GCSChannelManager *) cm + tableURL: (NSString *) url + andType: (NSString *) tableType +{ + NSString *tableName, *descFile; + EOAdaptorChannel *tc; + NGBundleManager *bm; + NSBundle *bundle; + unsigned int length; + + bm = [NGBundleManager defaultBundleManager]; + + tc = [cm acquireOpenChannelForURL: [NSURL URLWithString: url]]; + + tableName = [url lastPathComponent]; + if ([tc evaluateExpressionX: + [NSString stringWithFormat: @"SELECT count(*) FROM %@", tableName]]) + { + bundle = [bm bundleWithName: @"MainUI" type: @"SOGo"]; + length = [tableType length] - 3; + descFile = [bundle pathForResource: [tableType substringToIndex: length] + ofType: @"sql"]; + if (![tc evaluateExpressionX: + [NSString stringWithContentsOfFile: descFile]]) + [self logWithFormat: @"table '%@' successfully created!", tableName]; + } + else + NSLog (@"YES"); + + [cm releaseChannel: tc]; + +// [self terminate]; +// NSLog (@"not yet"); +} + +- (BOOL) _checkMandatoryTables +{ + GCSChannelManager *cm; + NSString *urlStrings[] = {@"AgenorProfileURL", @"OCSFolderInfoURL", nil}; + NSString **urlString; + NSString *value; + NSUserDefaults *ud; + BOOL ok; + + ud = [NSUserDefaults standardUserDefaults]; + ok = YES; + cm = [GCSChannelManager defaultChannelManager]; + + urlString = urlStrings; + while (ok && *urlString) + { + value = [ud stringForKey: *urlString]; + if (value) + { + [self _checkTableWithCM: cm tableURL: value andType: *urlString]; + urlString++; + } + else + { + NSLog (@"No value specified for '%@'", *urlString); + ok = NO; + } + } + + return ok; +} + +- (void) run +{ + if (!hasCheckedTables) + { + hasCheckedTables = YES; + [self _checkMandatoryTables]; + } + [super run]; +} + /* authenticator */ - (id) authenticatorInContext: (id) _ctx @@ -145,8 +242,8 @@ static BOOL debugObjectAllocation = NO; } - (id)lookupUser:(NSString *)_key inContext:(id)_ctx { - return [[[$(@"SOGoUserFolder") alloc] - initWithName:_key inContainer:self] autorelease]; + return [$(@"SOGoUserFolder") objectWithName:_key + inContainer: self]; } - (void) _setupLocaleInContext: (WOContext *) _ctx diff --git a/Main/common.h b/Main/common.h deleted file mode 100644 index f29bf747..00000000 --- a/Main/common.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - Copyright (C) 2002-2004 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 - -#if NeXT_Foundation_LIBRARY || COCOA_Foundation_LIBRARY -# include -# include -#endif - -#include -#include -#include - -#include diff --git a/Main/sogod.m b/Main/sogod.m index 3dfb7920..fc858303 100644 --- a/Main/sogod.m +++ b/Main/sogod.m @@ -21,11 +21,12 @@ #import -#import +#import +#import #import +#import -#import -#import "common.h" +#import int main (int argc, char **argv, char **env) @@ -37,27 +38,24 @@ main (int argc, char **argv, char **env) pool = [NSAutoreleasePool new]; + rc = -1; + if (getuid() > 0) { - rc = 0; #if LIB_FOUNDATION_LIBRARY [NSProcessInfo initializeWithArguments: argv count: argc environment: env]; #endif - [NGBundleManager defaultBundleManager]; - ud = [NSUserDefaults standardUserDefaults]; + rc = 0; tzName = [ud stringForKey: @"SOGoServerTimeZone"]; if (!tzName) - tzName = @"Canada/Eastern"; - [NSTimeZone setDefaultTimeZone: [NSTimeZone timeZoneWithName: tzName]]; - + tzName = @"UTC"; + [NSTimeZone setDefaultTimeZone: + [NSTimeZone timeZoneWithName: tzName]]; WOWatchDogApplicationMain (@"SOGo", argc, (void *) argv); } else - { - NSLog (@"Don't run SOGo as root!"); - rc = -1; - } + NSLog (@"Don't run SOGo as root!"); [pool release]; diff --git a/OGoContentStore/sql/generate-folderinfo-sql-for-users.sh b/OGoContentStore/sql/generate-folderinfo-sql-for-users.sh deleted file mode 100755 index 5190b2fa..00000000 --- a/OGoContentStore/sql/generate-folderinfo-sql-for-users.sh +++ /dev/null @@ -1,164 +0,0 @@ -#!/bin/bash -# -# Usage: generate-folderinfo-sql-for-users user1 [user2] [user3] [...] -# - -DB_USER="sogo" -DB_PASS="sogo" -DB_HOST="192.168.0.4" -DB_PORT="5432" -DB_NAME="sogo" -TIMEZONE="Canada/Eastern" - - -while [ "$1" != "" ]; do -USER_ID=$1 -USER_TABLE=`echo $USER_ID | tr -s [:punct:] _` -cat << EOF --- --- (C) 2004 SKYRIX Software AG --- --- TODO: --- add a unique constraints on path - -DELETE FROM SOGo_folder_info WHERE c_path2 = '${USER_ID}'; - -INSERT INTO SOGo_folder_info - ( c_path, c_path1, c_path2, c_path3, c_path4, c_foldername, - c_location, c_quick_location, c_acl_location, c_folder_type ) -VALUES - ( '/Users/${USER_ID}', - 'Users', - '${USER_ID}', - NULL, - NULL, - '${USER_ID}', - 'http://${DB_USER}:${DB_PASS}@${DB_HOST}:${DB_PORT}/${DB_NAME}/SOGo_${USER_TABLE}_folder', - 'http://${DB_USER}:${DB_PASS}@${DB_HOST}:${DB_PORT}/${DB_NAME}/SOGo_${USER_TABLE}_quick', - 'http://${DB_USER}:${DB_PASS}@${DB_HOST}:${DB_PORT}/${DB_NAME}/SOGo_${USER_TABLE}_acl', - 'Container' ); - -INSERT INTO SOGo_folder_info - ( c_path, c_path1, c_path2, c_path3, c_path4, c_foldername, - c_location, c_quick_location, c_acl_location, c_folder_type ) -VALUES - ( '/Users/${USER_ID}/Calendar', - 'Users', - '${USER_ID}', - 'Calendar', - NULL, - 'Calendar', - 'http://${DB_USER}:${DB_PASS}@${DB_HOST}:${DB_PORT}/${DB_NAME}/SOGo_${USER_TABLE}_privcal', - 'http://${DB_USER}:${DB_PASS}@${DB_HOST}:${DB_PORT}/${DB_NAME}/SOGo_${USER_TABLE}_privcal_quick', - 'http://${DB_USER}:${DB_PASS}@${DB_HOST}:${DB_PORT}/${DB_NAME}/SOGo_${USER_TABLE}_privcal_acl', - 'Appointment' ); - -INSERT INTO SOGo_folder_info - ( c_path, c_path1, c_path2, c_path3, c_path4, c_foldername, - c_location, c_quick_location, c_acl_location, c_folder_type ) -VALUES - ( '/Users/${USER_ID}/Contacts/personal', - 'Users', - '${USER_ID}', - 'Contacts', - 'personal', - 'Contacts', - 'http://${DB_USER}:${DB_PASS}@${DB_HOST}:${DB_PORT}/${DB_NAME}/SOGo_${USER_TABLE}_contacts', - 'http://${DB_USER}:${DB_PASS}@${DB_HOST}:${DB_PORT}/${DB_NAME}/SOGo_${USER_TABLE}_contacts_quick', - 'http://${DB_USER}:${DB_PASS}@${DB_HOST}:${DB_PORT}/${DB_NAME}/SOGo_${USER_TABLE}_contacts_acl', - 'Contact' ); - -DROP TABLE SOGo_${USER_TABLE}_privcal_quick; -DROP TABLE SOGo_${USER_TABLE}_privcal; - -CREATE TABLE SOGo_${USER_TABLE}_privcal_quick ( - c_name VARCHAR(256) NOT NULL PRIMARY KEY, -- the filename - uid VARCHAR(256) NOT NULL, - startdate INT NULL, - enddate INT NULL, - cycleenddate INT NULL, -- enddate for cyclic events - title VARCHAR(1000) NOT NULL, - cycleinfo VARCHAR(1000) NULL, -- property list with cycle infos - participants VARCHAR(100000) NULL, -- the CNs of the participants - isallday INT NULL, - iscycle INT NULL, -- client needs to fetch to resolve - classification INT NOT NULL, - status INT NOT NULL, - priority INT NOT NULL, -- for marking high prio apts - isopaque INT NULL, - location VARCHAR(256) NULL, - orgmail VARCHAR(256) NULL, - partmails VARCHAR(100000) NULL, -- the emails of the participants - partstates VARCHAR(256) NOT NULL, -- the status of each participant - sequence INT NULL, -- the iCal sequence - component VARCHAR(10) NOT NULL -- the type of component (vevent/vtodo) in the vcalendar -); - -CREATE TABLE SOGo_${USER_TABLE}_privcal ( - c_name VARCHAR(256) NOT NULL PRIMARY KEY, -- the filename - c_content VARCHAR(100000) NOT NULL, -- the BLOB - c_creationdate INT NOT NULL, -- creation date - c_lastmodified INT NOT NULL, -- last modification (UPDATE) - c_version INT NOT NULL -- version counter -); - -DROP TABLE SOGo_${USER_TABLE}_contacts_quick; -DROP TABLE SOGo_${USER_TABLE}_contacts; - -CREATE TABLE SOGo_${USER_TABLE}_contacts_quick ( - c_name VARCHAR(256) NOT NULL PRIMARY KEY, -- the filename - givenname VARCHAR(256), - cn VARCHAR(256), - sn VARCHAR(256), - screenname VARCHAR(256), - l VARCHAR(256), - mail VARCHAR(256), - o VARCHAR(256), - ou VARCHAR(256), - telephonenumber VARCHAR(256) -); - -CREATE TABLE SOGo_${USER_TABLE}_contacts ( - c_name VARCHAR(256) NOT NULL PRIMARY KEY, -- the filename - c_content VARCHAR(100000) NOT NULL, -- the BLOB - c_creationdate INT NOT NULL, -- creation date - c_lastmodified INT NOT NULL, -- last modification (UPDATE) - c_version INT NOT NULL -- version counter -); - -DROP TABLE SOGo_${USER_TABLE}_acl; -DROP TABLE SOGo_${USER_TABLE}_privcal_acl; -DROP TABLE SOGo_${USER_TABLE}_contacts_acl; - -CREATE TABLE SOGo_${USER_TABLE}_acl ( - c_uid VARCHAR(256) NOT NULL, - c_object VARCHAR(256) NOT NULL, - c_role VARCHAR(80) NOT NULL -); - -CREATE TABLE SOGo_${USER_TABLE}_privcal_acl ( - c_uid VARCHAR(256) NOT NULL, - c_object VARCHAR(256) NOT NULL, - c_role VARCHAR(80) NOT NULL -); - -CREATE TABLE SOGo_${USER_TABLE}_contacts_acl ( - c_uid VARCHAR(256) NOT NULL, - c_object VARCHAR(256) NOT NULL, - c_role VARCHAR(80) NOT NULL -); - -DELETE FROM SOGo_user_profile WHERE uid = '${USER_ID}'; - -INSERT INTO SOGo_user_profile ( - uid, - defaults, - settings -) -VALUES ( - '${USER_ID}', '{}', '{}' -); - -EOF -shift -done diff --git a/SoObjects/Appointments/SOGoAppointmentFolder.m b/SoObjects/Appointments/SOGoAppointmentFolder.m index 66d5c14c..6f098b7b 100644 --- a/SoObjects/Appointments/SOGoAppointmentFolder.m +++ b/SoObjects/Appointments/SOGoAppointmentFolder.m @@ -111,6 +111,11 @@ static NSNumber *sharedYes = nil; return logger; } +- (BOOL) folderIsMandatory +{ + return YES; +} + /* selection */ - (NSArray *) calendarUIDs @@ -745,12 +750,12 @@ static NSNumber *sharedYes = nil; privacySqlString = [NSString stringWithFormat: @"(%@(orgmail = '%@')" - @" or ((partmails caseInsensitiveLike '%@%%'" - @" or partmails caseInsensitiveLike '%%\\n%@%%')))", + @" or ((partmails caseInsensitiveLike '%@%%'" + @" or partmails caseInsensitiveLike '%%\n%@%%')))", [self _privacyClassificationStringsForUID: login], email, email, email]; } - + return privacySqlString; } diff --git a/SoObjects/Contacts/SOGoContactFolders.m b/SoObjects/Contacts/SOGoContactFolders.m index 0aeeab8f..f166515a 100644 --- a/SoObjects/Contacts/SOGoContactFolders.m +++ b/SoObjects/Contacts/SOGoContactFolders.m @@ -72,15 +72,52 @@ [super dealloc]; } -- (void) appendPersonalSources +- (void) _fetchPersonalFolders: (NSString *) sql + withChannel: (EOAdaptorChannel *) fc { + NSArray *attrs; + NSDictionary *row; SOGoContactGCSFolder *ab; + BOOL hasPersonal; + NSString *key, *path; + + hasPersonal = NO; + [fc evaluateExpressionX: sql]; + attrs = [fc describeResults: NO]; + row = [fc fetchAttributes: attrs withZone: NULL]; + while (row) + { + ab = [SOGoContactGCSFolder + contactFolderWithName: [row objectForKey: @"c_path4"] + andDisplayName: [row objectForKey: @"c_foldername"] + inContainer: self]; + key = [row objectForKey: @"c_path4"]; + hasPersonal = (hasPersonal || [key isEqualToString: @"personal"]); + [ab setOCSPath: [NSString stringWithFormat: @"%@/%@", + OCSPath, key]]; + [contactFolders setObject: ab forKey: key]; + row = [fc fetchAttributes: attrs withZone: NULL]; + } + + if (!hasPersonal) + { + ab = [SOGoContactGCSFolder contactFolderWithName: @"personal" + andDisplayName: @"Contacts" + inContainer: self]; + path = [NSString stringWithFormat: + @"/Users/%@/Contacts/personal", + [self ownerInContext: context]]; + [ab setOCSPath: path]; + [contactFolders setObject: ab forKey: @"personal"]; + } +} + +- (void) appendPersonalSources +{ GCSChannelManager *cm; EOAdaptorChannel *fc; NSURL *folderLocation; NSString *sql; - NSArray *attrs; - NSDictionary *row; cm = [GCSChannelManager defaultChannelManager]; folderLocation @@ -93,20 +130,7 @@ @" WHERE c_path2 = '%@'" @" AND c_folder_type = 'Contact'"), [folderLocation gcsTableName], [self ownerInContext: context]]; - [fc evaluateExpressionX: sql]; - attrs = [fc describeResults: NO]; - row = [fc fetchAttributes: attrs withZone: NULL]; - while (row) - { - ab = [SOGoContactGCSFolder contactFolderWithName: [row objectForKey: @"c_path4"] - andDisplayName: [row objectForKey: @"c_foldername"] - inContainer: self]; - [ab setOCSPath: [NSString stringWithFormat: @"%@/%@", - OCSPath, [row objectForKey: @"c_path4"]]]; - [contactFolders setObject: ab forKey: [row objectForKey: @"c_path4"]]; - row = [fc fetchAttributes: attrs withZone: NULL]; - } - + [self _fetchPersonalFolders: sql withChannel: fc]; [cm releaseChannel: fc]; // sql = [sql stringByAppendingFormat:@" WHERE %@ = '%@'", // uidColumnName, [self uid]]; diff --git a/SoObjects/Contacts/SOGoContactGCSFolder.m b/SoObjects/Contacts/SOGoContactGCSFolder.m index d47e8ee3..04263df9 100644 --- a/SoObjects/Contacts/SOGoContactGCSFolder.m +++ b/SoObjects/Contacts/SOGoContactGCSFolder.m @@ -64,6 +64,11 @@ return self; } +- (BOOL) folderIsMandatory +{ + return [nameInContainer isEqualToString: @"personal"]; +} + - (NSString *) displayName { return displayName; diff --git a/SoObjects/Mailer/SOGoMailObject.m b/SoObjects/Mailer/SOGoMailObject.m index bfa226d5..6f7d6ad7 100644 --- a/SoObjects/Mailer/SOGoMailObject.m +++ b/SoObjects/Mailer/SOGoMailObject.m @@ -20,6 +20,7 @@ */ #import +#import #import #import #import @@ -251,12 +252,24 @@ static BOOL debugSoParts = NO; - (NGImap4Envelope *)envelope { return [[self fetchCoreInfos] valueForKey:@"envelope"]; } -- (NSString *)subject { + +- (NSString *) subject +{ return [[self envelope] subject]; } -- (NSCalendarDate *)date { - return [[self envelope] date]; + +- (NSCalendarDate *) date +{ + NSTimeZone *userTZ; + NSCalendarDate *date; + + userTZ = [[context activeUser] timeZone]; + date = [[self envelope] date]; + [date setTimeZone: userTZ]; + + return date; } + - (NSArray *)fromEnvelopeAddresses { return [[self envelope] from]; } diff --git a/SoObjects/SOGo/AgenorUserDefaults.m b/SoObjects/SOGo/AgenorUserDefaults.m index c1104ceb..10b88155 100644 --- a/SoObjects/SOGo/AgenorUserDefaults.m +++ b/SoObjects/SOGo/AgenorUserDefaults.m @@ -193,18 +193,23 @@ static NSString *uidColumnName = @"uid"; @" VALUES ('%@', '%@')"), [[self tableURL] gcsTableName], uidColumnName, fieldName, [self uid], - [serializedDefaults stringByReplacingString:@"'" withString:@"''"]]; + [serializedDefaults stringByReplacingString: @"'" + withString:@"''"]]; #else NSData *serializedDefaultsData; NSString *error; + error = nil; serializedDefaultsData = [NSPropertyListSerialization dataFromPropertyList: values format: NSPropertyListOpenStepFormat errorDescription: &error]; if (error) - sql = nil; + { + sql = nil; + [error release]; + } else { serializedDefaults = [[NSString alloc] initWithData: serializedDefaultsData @@ -242,11 +247,11 @@ static NSString *uidColumnName = @"uid"; NSData *serializedDefaultsData; NSString *error; + error = nil; serializedDefaultsData = [NSPropertyListSerialization dataFromPropertyList: values format: NSPropertyListOpenStepFormat errorDescription: &error]; - error = nil; if (error) { sql = nil; @@ -262,7 +267,8 @@ static NSString *uidColumnName = @"uid"; @" WHERE %@ = '%@'"), [[self tableURL] gcsTableName], fieldName, - [serializedDefaults stringByReplacingString:@"'" withString:@"''"], + [serializedDefaults stringByReplacingString: @"'" + withString: @"''"], uidColumnName, [self uid]]; [serializedDefaults release]; } @@ -393,7 +399,7 @@ static NSString *uidColumnName = @"uid"; /* ensure fetched data (more or less guaranteed by modified!=0) */ if (![self fetchProfile]) return NO; - + /* store */ if (![self primaryStoreProfile]) { diff --git a/SoObjects/SOGo/SOGoFolder.h b/SoObjects/SOGo/SOGoFolder.h index a6aaf18d..f4263b69 100644 --- a/SoObjects/SOGo/SOGoFolder.h +++ b/SoObjects/SOGo/SOGoFolder.h @@ -68,6 +68,8 @@ - (NSString *) outlookFolderClass; +- (BOOL) folderIsMandatory; + - (BOOL) create; - (NSException *) delete; diff --git a/SoObjects/SOGo/SOGoFolder.m b/SoObjects/SOGo/SOGoFolder.m index 7d914d39..5eb8adb8 100644 --- a/SoObjects/SOGo/SOGoFolder.m +++ b/SoObjects/SOGo/SOGoFolder.m @@ -130,7 +130,7 @@ static NSString *defaultUserID = @""; if (!folderManager) { folderManager = [GCSFolderManager defaultFolderManager]; - [folderManager setFolderNamePrefix: @"SOGo_"]; + [folderManager setFolderNamePrefix: @"SOGo"]; } return folderManager; @@ -138,7 +138,14 @@ static NSString *defaultUserID = @""; - (GCSFolder *) ocsFolderForPath: (NSString *) _path { - return [[self folderManager] folderAtPath:_path]; + return [[self folderManager] folderAtPath: _path]; +} + +- (BOOL) folderIsMandatory +{ + [self subclassResponsibility: _cmd]; + + return NO; } - (GCSFolder *) ocsFolder @@ -146,7 +153,14 @@ static NSString *defaultUserID = @""; GCSFolder *folder; if (!ocsFolder) - ocsFolder = [[self ocsFolderForPath:[self ocsPath]] retain]; + { + ocsFolder = [self ocsFolderForPath: [self ocsPath]]; + if (!ocsFolder + && [self folderIsMandatory] + && [self create]) + ocsFolder = [self ocsFolderForPath: [self ocsPath]]; + [ocsFolder retain]; + } if ([ocsFolder isNotNull]) folder = ocsFolder; @@ -176,18 +190,20 @@ static NSString *defaultUserID = @""; return [[self folderManager] deleteFolderAtPath: ocsPath]; } -- (NSArray *)fetchContentObjectNames { +- (NSArray *) fetchContentObjectNames +{ NSArray *fields, *records; - fields = [NSArray arrayWithObject:@"c_name"]; + fields = [NSArray arrayWithObject: @"c_name"]; records = [[self ocsFolder] fetchFields:fields matchingQualifier:nil]; - if (![records isNotNull]) { - [self errorWithFormat:@"(%s): fetch failed!", __PRETTY_FUNCTION__]; - return nil; - } - if ([records isKindOfClass:[NSException class]]) + if (![records isNotNull]) + { + [self errorWithFormat: @"(%s): fetch failed!", __PRETTY_FUNCTION__]; + return nil; + } + if ([records isKindOfClass: [NSException class]]) return records; - return [records valueForKey:@"c_name"]; + return [records valueForKey: @"c_name"]; } - (BOOL) nameExistsInFolder: (NSString *) objectName @@ -207,14 +223,16 @@ static NSString *defaultUserID = @""; && [records count] > 0); } -- (NSDictionary *)fetchContentStringsAndNamesOfAllObjects { +- (NSDictionary *) fetchContentStringsAndNamesOfAllObjects +{ NSDictionary *files; files = [[self ocsFolder] fetchContentsOfAllFiles]; - if (![files isNotNull]) { - [self errorWithFormat:@"(%s): fetch failed!", __PRETTY_FUNCTION__]; - return nil; - } + if (![files isNotNull]) + { + [self errorWithFormat:@"(%s): fetch failed!", __PRETTY_FUNCTION__]; + return nil; + } if ([files isKindOfClass:[NSException class]]) return files; return files; @@ -222,7 +240,8 @@ static NSString *defaultUserID = @""; /* reflection */ -- (NSString *)defaultFilenameExtension { +- (NSString *) defaultFilenameExtension +{ /* Override to add an extension to a filename @@ -252,7 +271,8 @@ static NSString *defaultUserID = @""; return @"httpd/unix-directory"; } -- (NSArray *) toOneRelationshipKeys { +- (NSArray *) toOneRelationshipKeys +{ /* toOneRelationshipKeys are the 'files' contained in a folder */ NSMutableArray *ma; NSArray *names; diff --git a/SoObjects/SOGo/SOGoUserFolder.m b/SoObjects/SOGo/SOGoUserFolder.m index 3fc0684e..933779c3 100644 --- a/SoObjects/SOGo/SOGoUserFolder.m +++ b/SoObjects/SOGo/SOGoUserFolder.m @@ -86,7 +86,7 @@ - (NSString *) ocsPath { - return [@"/Users/" stringByAppendingString: [self login]]; + return [NSString stringWithFormat: @"/Users/%@", nameInContainer]; } - (NSString *) ocsUserPath @@ -94,6 +94,11 @@ return [self ocsPath]; } +- (BOOL) folderIsMandatory +{ + return NO; +} + - (NSString *) ocsPrivateCalendarPath { return [[self ocsUserPath] stringByAppendingString:@"/Calendar"]; @@ -163,13 +168,11 @@ obj = [super lookupName: _key inContext: _ctx acquire: NO]; if (!obj) { - if ([_key hasPrefix: @"Calendar"]) - { - obj = [self privateCalendar: @"Calendar" inContext: _ctx]; - if (![_key isEqualToString: @"Calendar"]) - obj = [obj lookupName: [_key pathExtension] - inContext: _ctx acquire: NO]; - } + if ([_key isEqualToString: @"Calendar"]) + obj = [self privateCalendar: @"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"]) diff --git a/UI/MailerUI/WOContext+UIxMailer.m b/UI/MailerUI/WOContext+UIxMailer.m index fb4b4432..504e9be9 100644 --- a/UI/MailerUI/WOContext+UIxMailer.m +++ b/UI/MailerUI/WOContext+UIxMailer.m @@ -19,47 +19,37 @@ 02111-1307, USA. */ -#include "WOContext+UIxMailer.h" -#include "UIxMailFormatter.h" -#include "common.h" -#include +#import +#import + +#import "UIxMailFormatter.h" +#import "common.h" + +#import "WOContext+UIxMailer.h" @implementation WOContext(UIxMailer) // TODO: make configurable // TODO: cache! -- (NSFormatter *)mailSubjectFormatter { +- (NSFormatter *) mailSubjectFormatter +{ return [[[UIxSubjectFormatter alloc] init] autorelease]; } -- (NSFormatter *)mailDateFormatter +- (NSFormatter *) mailDateFormatter { - NSTimeZone *userTZ; - NSString *userTZString; - id userPrefs; - static id dateFormatter = nil; - - if (!dateFormatter) - { - dateFormatter = [UIxMailDateFormatter new]; - userPrefs = [[self activeUser] userDefaults]; - userTZString = [userPrefs stringForKey: @"timezonename"]; - if ([userTZString length] > 0) - { - userTZ = [NSTimeZone timeZoneWithName: userTZString]; - [dateFormatter setTimeZone: userTZ]; - } - } - - return dateFormatter; + return [[self activeUser] dateFormatterInContext: self]; } -- (NSFormatter *)mailEnvelopeAddressFormatter { +- (NSFormatter *) mailEnvelopeAddressFormatter +{ return [[[UIxEnvelopeAddressFormatter alloc] init] autorelease]; } -- (NSFormatter *)mailEnvelopeFullAddressFormatter { + +- (NSFormatter *) mailEnvelopeFullAddressFormatter +{ return [[[UIxEnvelopeAddressFormatter alloc] initWithMaxLength:256 generateFullEMail:YES] autorelease]; } diff --git a/OGoContentStore/sql/profile-create.psql b/UI/MainUI/AgenorProfile.sql similarity index 61% rename from OGoContentStore/sql/profile-create.psql rename to UI/MainUI/AgenorProfile.sql index 5bc85312..2012e7dd 100644 --- a/OGoContentStore/sql/profile-create.psql +++ b/UI/MainUI/AgenorProfile.sql @@ -1,5 +1,6 @@ -- --- (C) 2005 SKYRIX Software AG +-- (C) 2004-2005 SKYRIX Software AG +-- (C) 2006-2007 Inverse groupe conseil -- CREATE TABLE SOGo_user_profile ( diff --git a/UI/MainUI/GNUmakefile b/UI/MainUI/GNUmakefile index 0432e77f..6ea51ebe 100644 --- a/UI/MainUI/GNUmakefile +++ b/UI/MainUI/GNUmakefile @@ -17,7 +17,9 @@ MainUI_OBJC_FILES += \ MainUI_RESOURCE_FILES += \ Version \ - product.plist + product.plist \ + OCSFolderInfo.sql \ + AgenorProfile.sql MainUI_LOCALIZED_RESOURCE_FILES += \ Locale Localizable.strings diff --git a/OGoContentStore/sql/folderinfo-create.psql b/UI/MainUI/OCSFolderInfo.sql similarity index 65% rename from OGoContentStore/sql/folderinfo-create.psql rename to UI/MainUI/OCSFolderInfo.sql index 30559779..f9fcde20 100644 --- a/OGoContentStore/sql/folderinfo-create.psql +++ b/UI/MainUI/OCSFolderInfo.sql @@ -1,20 +1,10 @@ -- -- (C) 2004-2005 SKYRIX Software AG +-- (C) 2006-2007 Inverse groupe conseil -- --- TODO: --- add a unique constraints on path - -DROP SEQUENCE SOGo_folder_info_seq; - -CREATE SEQUENCE SOGo_folder_info_seq; - -DROP TABLE SOGo_folder_info; CREATE TABLE SOGo_folder_info ( - c_folder_id INTEGER - DEFAULT nextval('SOGo_folder_info_seq') - NOT NULL - PRIMARY KEY, -- the primary key + c_folder_id SERIAL, c_path VARCHAR(255) NOT NULL, -- the full path to the folder c_path1 VARCHAR(255) NOT NULL, -- parts (for fast queries) c_path2 VARCHAR(255) NULL, -- parts (for fast queries) @@ -23,6 +13,6 @@ CREATE TABLE SOGo_folder_info ( c_foldername VARCHAR(255) NOT NULL, -- last path component c_location VARCHAR(2048) NOT NULL, -- URL to folder c_quick_location VARCHAR(2048) NULL, -- URL to quicktable of folder - c_acl_location VARCHAR(2048) NULL, -- URL to quicktable of folder + c_acl_location VARCHAR(2048) NULL, -- URL to quicktable of folder c_folder_type VARCHAR(255) NOT NULL -- the folder type ... ); diff --git a/UI/Scheduler/French.lproj/Localizable.strings b/UI/Scheduler/French.lproj/Localizable.strings index 0ce5f40d..9fb1d9fc 100644 --- a/UI/Scheduler/French.lproj/Localizable.strings +++ b/UI/Scheduler/French.lproj/Localizable.strings @@ -212,7 +212,7 @@ "Search appointments" = "Recherche de rendez-vous"; "Search in Anais" = "Recherche par Anaïs"; -"All day Event" = "Événement sur la journéee"; +"All day Event" = "Événement sur la journée"; "check for conflicts" = "Vérifier les conflits"; "Browse URL" = "Visiter l'URL"; diff --git a/UI/Templates/MailerUI/UIxMailView.wox b/UI/Templates/MailerUI/UIxMailView.wox index 965cc197..fb45e713 100644 --- a/UI/Templates/MailerUI/UIxMailView.wox +++ b/UI/Templates/MailerUI/UIxMailView.wox @@ -25,7 +25,7 @@ - : + : diff --git a/UI/WebServerResources/SchedulerUI.js b/UI/WebServerResources/SchedulerUI.js index d5e22f6b..e9d014c6 100644 --- a/UI/WebServerResources/SchedulerUI.js +++ b/UI/WebServerResources/SchedulerUI.js @@ -10,7 +10,7 @@ var selectedCalendarCell; var showCompletedTasks = 0; var currentDay = ''; -var currentView = "dayview"; +var currentView = "weekview"; var cachedDateSelectors = new Array(); -- 2.39.5