See ChangeLog
Monotone-Parent: ef0aa48a6604ad9c6048a42d79be6779460dcd1a Monotone-Revision: 485b2bbaa9cf22a075daa65673c3fac7256a86e4 Monotone-Author: ludovic@Sophos.ca Monotone-Date: 2009-02-24T01:54:59 Monotone-Branch: ca.inverse.sogomaint-2.0.2
parent
5605ebc668
commit
282be5d22b
11
ChangeLog
11
ChangeLog
|
@ -1,3 +1,14 @@
|
|||
2009-02-23 Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
|
||||
* Updated German translation. Patch from
|
||||
Alexander Greiner-Baer <sogo-algb@freenet.de>
|
||||
* Added Italian translation. Patch from
|
||||
Marco Lertora <marco.lertora@infoporto.it>
|
||||
* Combined the various caches and moved the logic
|
||||
towards the SOGoCache class. Deprecated the
|
||||
SOGoLDAPUserManagerCleanupInterval defaults.
|
||||
Now only SOGoCacheCleanupInterval should be used.
|
||||
|
||||
2009-02-19 Francis Lachapelle <flachapelle@inverse.ca>
|
||||
|
||||
* UI/Contacts/UIxContactsListView.m ([UIxContactsListView
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* LDAPUserManager.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2007 Inverse inc.
|
||||
* Copyright (C) 2007-2009 Inverse inc.
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
@ -34,11 +34,9 @@
|
|||
|
||||
@interface LDAPUserManager : NSObject
|
||||
{
|
||||
NSMutableDictionary *sources;
|
||||
NSMutableDictionary *sourcesMetadata;
|
||||
NSTimeInterval cleanupInterval;
|
||||
NSTimer *cleanupTimer;
|
||||
NSMutableDictionary *users;
|
||||
@private
|
||||
NSMutableDictionary *sources;
|
||||
NSMutableDictionary *sourcesMetadata;
|
||||
}
|
||||
|
||||
+ (id) sharedUserManager;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* LDAPUserManager.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2007-2008 Inverse inc.
|
||||
* Copyright (C) 2007-2009 Inverse inc.
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
@ -22,6 +22,7 @@
|
|||
|
||||
#import <Foundation/NSArray.h>
|
||||
#import <Foundation/NSDictionary.h>
|
||||
#import <Foundation/NSDistributedNotificationCenter.h>
|
||||
#import <Foundation/NSEnumerator.h>
|
||||
#import <Foundation/NSLock.h>
|
||||
#import <Foundation/NSString.h>
|
||||
|
@ -33,6 +34,7 @@
|
|||
#import "NSArray+Utilities.h"
|
||||
#import "LDAPSource.h"
|
||||
#import "LDAPUserManager.h"
|
||||
#import "SOGoCache.h"
|
||||
|
||||
static NSString *defaultMailDomain = nil;
|
||||
static NSString *LDAPContactInfoAttribute = nil;
|
||||
|
@ -147,7 +149,6 @@ static NSLock *lock = nil;
|
|||
- (id) init
|
||||
{
|
||||
NSUserDefaults *ud;
|
||||
NSString *cleanupSetting;
|
||||
|
||||
if ((self = [super init]))
|
||||
{
|
||||
|
@ -155,27 +156,6 @@ static NSLock *lock = nil;
|
|||
|
||||
sources = nil;
|
||||
sourcesMetadata = nil;
|
||||
users = [NSMutableDictionary new];
|
||||
cleanupSetting
|
||||
= [ud objectForKey: @"SOGoLDAPUserManagerCleanupInterval"];
|
||||
if (cleanupSetting)
|
||||
cleanupInterval = [cleanupSetting doubleValue];
|
||||
else
|
||||
cleanupInterval = 0.0;
|
||||
if (cleanupInterval > 0.0)
|
||||
{
|
||||
cleanupTimer
|
||||
= [NSTimer scheduledTimerWithTimeInterval: cleanupInterval
|
||||
target: self
|
||||
selector: @selector (_cleanupSources)
|
||||
userInfo: nil
|
||||
repeats: YES];
|
||||
[self logWithFormat: @"cleanup interval set every %f seconds",
|
||||
cleanupInterval];
|
||||
}
|
||||
else
|
||||
[self
|
||||
logWithFormat: @"no cleanup interval set: memory usage will grow"];
|
||||
[self _prepareLDAPSourcesWithDefaults: ud];
|
||||
}
|
||||
|
||||
|
@ -185,7 +165,6 @@ static NSLock *lock = nil;
|
|||
- (void) dealloc
|
||||
{
|
||||
[sources release];
|
||||
[users release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
|
@ -312,16 +291,15 @@ static NSLock *lock = nil;
|
|||
- (BOOL) checkLogin: (NSString *) login
|
||||
andPassword: (NSString *) password
|
||||
{
|
||||
BOOL checkOK;
|
||||
NSDate *cleanupDate;
|
||||
NSMutableDictionary *currentUser;
|
||||
NSString *dictPassword;
|
||||
BOOL checkOK;
|
||||
|
||||
#if defined(THREADSAFE)
|
||||
[lock lock];
|
||||
#endif
|
||||
|
||||
currentUser = [users objectForKey: login];
|
||||
currentUser = [[SOGoCache sharedCache] userAttributesForLogin: login];
|
||||
dictPassword = [currentUser objectForKey: @"password"];
|
||||
if (currentUser && dictPassword)
|
||||
checkOK = ([dictPassword isEqualToString: password]);
|
||||
|
@ -331,19 +309,13 @@ static NSLock *lock = nil;
|
|||
if (!currentUser)
|
||||
{
|
||||
currentUser = [NSMutableDictionary dictionary];
|
||||
[users setObject: currentUser forKey: login];
|
||||
[[SOGoCache sharedCache] cacheAttributes: currentUser forLogin: login];
|
||||
}
|
||||
[currentUser setObject: password forKey: @"password"];
|
||||
}
|
||||
else
|
||||
checkOK = NO;
|
||||
|
||||
if (cleanupInterval)
|
||||
{
|
||||
cleanupDate = [[NSDate date] addTimeInterval: cleanupInterval];
|
||||
[currentUser setObject: cleanupDate forKey: @"cleanupDate"];
|
||||
}
|
||||
|
||||
#if defined(THREADSAFE)
|
||||
[lock unlock];
|
||||
#endif
|
||||
|
@ -422,35 +394,59 @@ static NSLock *lock = nil;
|
|||
[self _fillContactMailRecords: currentUser];
|
||||
}
|
||||
|
||||
//
|
||||
// We cache here all identities, including those
|
||||
// associated with email addresses.
|
||||
//
|
||||
- (void) _retainUser: (NSDictionary *) newUser
|
||||
{
|
||||
NSString *key;
|
||||
NSEnumerator *emails;
|
||||
|
||||
NSString *key;
|
||||
|
||||
#if defined(THREADSAFE)
|
||||
[lock lock];
|
||||
#endif
|
||||
key = [newUser objectForKey: @"c_uid"];
|
||||
if (key)
|
||||
[users setObject: newUser forKey: key];
|
||||
[[SOGoCache sharedCache] cacheAttributes: newUser forLogin: key];
|
||||
emails = [[newUser objectForKey: @"emails"] objectEnumerator];
|
||||
while ((key = [emails nextObject]))
|
||||
[users setObject: newUser forKey: key];
|
||||
{
|
||||
[[SOGoCache sharedCache] cacheAttributes: newUser forLogin: key];
|
||||
}
|
||||
#if defined(THREADSAFE)
|
||||
[lock unlock];
|
||||
#endif
|
||||
|
||||
// We propagate the loaded LDAP attributes to other sogod instances
|
||||
// which will cache them in SOGoCache (excluding for the instance
|
||||
// that actually posts the notification)
|
||||
if ([newUser objectForKey: @"c_uid"])
|
||||
{
|
||||
NSMutableDictionary *d;
|
||||
|
||||
d = [NSMutableDictionary dictionary];
|
||||
[d setObject: newUser forKey: @"values"];
|
||||
[d setObject: [newUser objectForKey: @"c_uid"]
|
||||
forKey: @"uid"];
|
||||
|
||||
[[NSDistributedNotificationCenter defaultCenter]
|
||||
postNotificationName: @"SOGoUserAttributesHaveLoaded"
|
||||
object: nil
|
||||
userInfo: d
|
||||
deliverImmediately: YES];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSDictionary *) contactInfosForUserWithUIDorEmail: (NSString *) uid
|
||||
{
|
||||
NSMutableDictionary *currentUser, *contactInfos;
|
||||
NSDate *cleanupDate;
|
||||
BOOL newUser;
|
||||
|
||||
if ([uid length] > 0)
|
||||
{
|
||||
contactInfos = [NSMutableDictionary dictionary];
|
||||
currentUser = [users objectForKey: uid];
|
||||
currentUser = [[SOGoCache sharedCache] userAttributesForLogin: uid];
|
||||
#if defined(THREADSAFE)
|
||||
[lock lock];
|
||||
#endif
|
||||
|
@ -475,11 +471,6 @@ static NSLock *lock = nil;
|
|||
}
|
||||
}
|
||||
|
||||
if (cleanupInterval && currentUser)
|
||||
{
|
||||
cleanupDate = [[NSDate date] addTimeInterval: cleanupInterval];
|
||||
[currentUser setObject: cleanupDate forKey: @"cleanupDate"];
|
||||
}
|
||||
#if defined(THREADSAFE)
|
||||
[lock unlock];
|
||||
#endif
|
||||
|
@ -583,40 +574,4 @@ static NSLock *lock = nil;
|
|||
matching: filter];
|
||||
}
|
||||
|
||||
- (void) _cleanupSources
|
||||
{
|
||||
NSEnumerator *userIDs;
|
||||
NSString *currentID;
|
||||
NSDictionary *currentUser;
|
||||
NSDate *now;
|
||||
unsigned int count;
|
||||
|
||||
#if defined(THREADSAFE)
|
||||
[lock lock];
|
||||
#endif
|
||||
|
||||
now = [NSDate date];
|
||||
|
||||
count = 0;
|
||||
|
||||
userIDs = [[users allKeys] objectEnumerator];
|
||||
while ((currentID = [userIDs nextObject]))
|
||||
{
|
||||
currentUser = [users objectForKey: currentID];
|
||||
if ([now earlierDate:
|
||||
[currentUser objectForKey: @"cleanupDate"]] == now)
|
||||
{
|
||||
[users removeObjectForKey: currentID];
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
if (count)
|
||||
[self logWithFormat: @"cleaned %d users records from cache", count];
|
||||
|
||||
#if defined(THREADSAFE)
|
||||
[lock unlock];
|
||||
#endif
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* SOGoCache.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2008 Inverse inc.
|
||||
* Copyright (C) 2008-2009 Inverse inc.
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
* Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
|
@ -54,12 +54,11 @@
|
|||
- (void) registerUser: (SOGoUser *) user;
|
||||
- (id) userNamed: (NSString *) name;
|
||||
|
||||
+ (void) setCachedUserDefaults: (SOGoUserDefaults *) theDefaults
|
||||
user: (NSString *) login;
|
||||
+ (NSDictionary *) cachedUserDefaults;
|
||||
+ (void) setCachedUserSettings: (SOGoUserDefaults *) theSettings
|
||||
user: (NSString *) login;
|
||||
+ (NSDictionary *) cachedUserSettings;
|
||||
- (void) cacheAttributes: (NSDictionary *) theAttributes
|
||||
forLogin: (NSString *) theLogin;
|
||||
- (NSMutableDictionary *) userAttributesForLogin: (NSString *) theLogin;
|
||||
- (SOGoUserDefaults *) userDefaultsForLogin: (NSString *) theLogin;
|
||||
- (SOGoUserDefaults *) userSettingsForLogin: (NSString *) theLogin;
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* SOGoCache.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2008 Inverse inc.
|
||||
* Copyright (C) 2008-2009 Inverse inc.
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
* Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
|
@ -21,6 +21,24 @@
|
|||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* [ Structure ]
|
||||
* users: key = user ID value = NSMutableDictionary instance
|
||||
* value: key = @"user" value = SOGOUser instance
|
||||
* key = @"cleanupDate" value = NSDate instance
|
||||
* key = @"defaults" value = SOGoUserDefaults instance
|
||||
* key = @"settings" value = SOGoUserDefaults instance
|
||||
* key = @"attributes" value = NSDictionary instance (attributes from LDAP)
|
||||
*
|
||||
* [ Workflows - processes A and B ]
|
||||
*
|
||||
* A cache user defaults and posts the notification
|
||||
* B ....
|
||||
*
|
||||
* B crashes
|
||||
* B receives a notificaion update
|
||||
*/
|
||||
|
||||
#import <Foundation/NSArray.h>
|
||||
#import <Foundation/NSDictionary.h>
|
||||
#import <Foundation/NSDistributedNotificationCenter.h>
|
||||
|
@ -42,14 +60,11 @@
|
|||
// We define the default value for cleaning up cached
|
||||
// users' preferences. This value should be relatively
|
||||
// high to avoid useless database calls.
|
||||
static NSTimeInterval cleanupInterval = 1800;
|
||||
static NSTimeInterval cleanupInterval = 300;
|
||||
|
||||
static NSMutableDictionary *cache = nil;
|
||||
static NSMutableDictionary *users = nil;
|
||||
|
||||
static NSMutableDictionary *s_userDefaults = nil;
|
||||
static NSMutableDictionary *s_userSettings = nil;
|
||||
|
||||
static SOGoCache *sharedCache = nil;
|
||||
|
||||
#if defined(THREADSAFE)
|
||||
|
@ -60,11 +75,9 @@ static NSLock *lock;
|
|||
|
||||
+ (void) initialize
|
||||
{
|
||||
#if defined(THREADSAFE)
|
||||
#if defined(THREADSAFE)
|
||||
lock = [NSLock new];
|
||||
#endif
|
||||
s_userDefaults = [[NSMutableDictionary alloc] init];
|
||||
s_userSettings = [[NSMutableDictionary alloc] init];
|
||||
}
|
||||
|
||||
+ (NSTimeInterval) cleanupInterval
|
||||
|
@ -92,7 +105,6 @@ static NSLock *lock;
|
|||
[lock lock];
|
||||
#endif
|
||||
[cache removeAllObjects];
|
||||
[users removeAllObjects];
|
||||
#if defined(THREADSAFE)
|
||||
[lock unlock];
|
||||
#endif
|
||||
|
@ -108,12 +120,30 @@ static NSLock *lock;
|
|||
users = [[NSMutableDictionary alloc] init];
|
||||
|
||||
// We register ourself for notifications
|
||||
[[NSDistributedNotificationCenter defaultCenter]
|
||||
addObserver: self
|
||||
selector: @selector(_userAttributesHaveLoaded:)
|
||||
name: @"SOGoUserAttributesHaveLoaded"
|
||||
object: nil];
|
||||
|
||||
[[NSDistributedNotificationCenter defaultCenter]
|
||||
addObserver: self
|
||||
selector: @selector(_userDefaultsHaveLoaded:)
|
||||
name: @"SOGoUserDefaultsHaveLoaded"
|
||||
object: nil];
|
||||
|
||||
[[NSDistributedNotificationCenter defaultCenter]
|
||||
addObserver: self
|
||||
selector: @selector(_userDefaultsHaveChanged:)
|
||||
name: @"SOGoUserDefaultsHaveChanged"
|
||||
object: nil];
|
||||
|
||||
[[NSDistributedNotificationCenter defaultCenter]
|
||||
addObserver: self
|
||||
selector: @selector(_userSettingsHaveLoaded:)
|
||||
name: @"SOGoUserSettingsHaveLoaded"
|
||||
object: nil];
|
||||
|
||||
[[NSDistributedNotificationCenter defaultCenter]
|
||||
addObserver: self
|
||||
selector: @selector(_userSettingsHaveChanged:)
|
||||
|
@ -132,7 +162,7 @@ static NSLock *lock;
|
|||
selector: @selector(_cleanupSources)
|
||||
userInfo: nil
|
||||
repeats: YES];
|
||||
[self logWithFormat: @"cleanup interval set every %f seconds",
|
||||
[self logWithFormat: @"Cache cleanup interval set every %f seconds",
|
||||
cleanupInterval];
|
||||
}
|
||||
|
||||
|
@ -141,10 +171,25 @@ static NSLock *lock;
|
|||
|
||||
- (void) dealloc
|
||||
{
|
||||
[[NSDistributedNotificationCenter defaultCenter]
|
||||
removeObserver: self
|
||||
name: @"SOGoUserAttributesHaveLoaded"
|
||||
object: nil];
|
||||
|
||||
[[NSDistributedNotificationCenter defaultCenter]
|
||||
removeObserver: self
|
||||
name: @"SOGoUserDefaultsHaveLoaded"
|
||||
object: nil];
|
||||
|
||||
[[NSDistributedNotificationCenter defaultCenter]
|
||||
removeObserver: self
|
||||
name: @"SOGoUserDefaultsHaveChanged"
|
||||
object: nil];
|
||||
|
||||
[[NSDistributedNotificationCenter defaultCenter]
|
||||
removeObserver: self
|
||||
name: @"SOGoUserSettingsHaveLoaded"
|
||||
object: nil];
|
||||
|
||||
[[NSDistributedNotificationCenter defaultCenter]
|
||||
removeObserver: self
|
||||
|
@ -157,7 +202,7 @@ static NSLock *lock;
|
|||
}
|
||||
|
||||
- (NSString *) _pathFromObject: (SOGoObject *) container
|
||||
withName: (NSString *) name
|
||||
withName: (NSString *) name
|
||||
{
|
||||
NSString *fullPath, *nameInContainer;
|
||||
NSMutableArray *names;
|
||||
|
@ -197,14 +242,11 @@ withName: (NSString *) name
|
|||
#endif
|
||||
if (![cache objectForKey: fullPath])
|
||||
{
|
||||
// NSLog (@"registering '%@'", fullPath);
|
||||
[cache setObject: object forKey: fullPath];
|
||||
}
|
||||
#if defined(THREADSAFE)
|
||||
[lock unlock];
|
||||
#endif
|
||||
// else
|
||||
// NSLog (@"'%@' already registered", fullPath);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -223,11 +265,21 @@ withName: (NSString *) name
|
|||
|
||||
- (void) registerUser: (SOGoUser *) user
|
||||
{
|
||||
NSData *cleanupDate;
|
||||
|
||||
#if defined(THREADSAFE)
|
||||
[lock lock];
|
||||
#endif
|
||||
[users setObject: user
|
||||
forKey: [user login]];
|
||||
|
||||
cleanupDate = [[NSDate date] addTimeInterval: [SOGoCache cleanupInterval]];
|
||||
|
||||
if (![users objectForKey: [user login]])
|
||||
[users setObject: [NSMutableDictionary dictionary] forKey: [user login]];
|
||||
|
||||
[[users objectForKey: [user login]] setObject: user forKey: @"user"];
|
||||
[[users objectForKey: [user login]] setObject: [[NSDate date] addTimeInterval: [SOGoCache cleanupInterval]]
|
||||
forKey: @"cleanupDate"];
|
||||
|
||||
#if defined(THREADSAFE)
|
||||
[lock unlock];
|
||||
#endif
|
||||
|
@ -235,99 +287,184 @@ withName: (NSString *) name
|
|||
|
||||
- (id) userNamed: (NSString *) name
|
||||
{
|
||||
return [users objectForKey: name];
|
||||
return [[users objectForKey: name] objectForKey: @"user"];
|
||||
}
|
||||
|
||||
+ (NSDictionary *) cachedUserDefaults
|
||||
- (void) cacheAttributes: (NSDictionary *) theAttributes
|
||||
forLogin: (NSString *) theLogin
|
||||
{
|
||||
return s_userDefaults;
|
||||
if (![users objectForKey: theLogin])
|
||||
[users setObject: [NSMutableDictionary dictionary] forKey: theLogin];
|
||||
|
||||
[[users objectForKey: theLogin] setObject: theAttributes forKey: @"attributes"];
|
||||
[[users objectForKey: theLogin] setObject: [[NSDate date] addTimeInterval: [SOGoCache cleanupInterval]]
|
||||
forKey: @"cleanupDate"];
|
||||
}
|
||||
|
||||
/* defaults */
|
||||
+ (void) setCachedUserDefaults: (SOGoUserDefaults *) theDefaults
|
||||
user: (NSString *) login
|
||||
- (NSMutableDictionary *) userAttributesForLogin: (NSString *) theLogin
|
||||
{
|
||||
NSDate *cleanupDate;
|
||||
return [[users objectForKey: theLogin] objectForKey: @"attributes"];
|
||||
}
|
||||
|
||||
- (SOGoUserDefaults *) userDefaultsForLogin: (NSString *) theLogin
|
||||
{
|
||||
return [[users objectForKey: theLogin] objectForKey: @"defaults"];
|
||||
}
|
||||
|
||||
- (SOGoUserDefaults *) userSettingsForLogin: (NSString *) theLogin
|
||||
{
|
||||
return [[users objectForKey: theLogin] objectForKey: @"settings"];
|
||||
}
|
||||
|
||||
//
|
||||
// Notification callbacks.
|
||||
//
|
||||
- (void) _cacheValues: (NSDictionary *) theValues
|
||||
login: (NSString *) theLogin
|
||||
url: (NSString *) theURL
|
||||
key: (NSString *) theKey
|
||||
{
|
||||
SOGoUserDefaults *defaults;
|
||||
NSURL *url;
|
||||
|
||||
#if defined(THREADSAFE)
|
||||
[lock lock];
|
||||
#endif
|
||||
cleanupDate = [[NSDate date] addTimeInterval: [SOGoCache cleanupInterval]];
|
||||
[s_userDefaults setObject: [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
theDefaults, @"dictionary",
|
||||
cleanupDate, @"cleanupDate", nil]
|
||||
forKey: login];
|
||||
url = [[[NSURL alloc] initWithString: theURL] autorelease];
|
||||
|
||||
defaults = [[[SOGoUserDefaults alloc] initWithTableURL: url
|
||||
uid: theLogin
|
||||
fieldName: [NSString stringWithFormat: @"c_%@", theKey]]
|
||||
autorelease];
|
||||
|
||||
if (![users objectForKey: theLogin])
|
||||
[users setObject: [NSMutableDictionary dictionary] forKey: theLogin];
|
||||
|
||||
[[users objectForKey: theLogin] setObject: defaults forKey: theKey];
|
||||
[[users objectForKey: theLogin] setObject: [[NSDate date] addTimeInterval: [SOGoCache cleanupInterval]]
|
||||
forKey: @"cleanupDate"];
|
||||
|
||||
//NSLog(@"\n\n\nCached user %@ for UID: %@\nvalues: %@\n\n", theKey, theLogin, theValues);
|
||||
|
||||
#if defined(THREADSAFE)
|
||||
[lock unlock];
|
||||
#endif
|
||||
}
|
||||
|
||||
+ (NSDictionary *) cachedUserSettings
|
||||
- (void) _userAttributesHaveLoaded: (NSNotification *) theNotification
|
||||
{
|
||||
return s_userSettings;
|
||||
NSString *uid;
|
||||
|
||||
uid = [[theNotification userInfo] objectForKey: @"uid"];
|
||||
//NSLog(@"Caching user attributes for UID: %@", uid);
|
||||
if (![self userAttributesForLogin: uid])
|
||||
{
|
||||
NSEnumerator *emails;
|
||||
NSDictionary *values;
|
||||
NSString *key;
|
||||
|
||||
if (![users objectForKey: uid])
|
||||
[users setObject: [NSMutableDictionary dictionary] forKey: uid];
|
||||
|
||||
values = [[theNotification userInfo] objectForKey: @"values"];
|
||||
[self cacheAttributes: values forLogin: uid];
|
||||
|
||||
emails = [[values objectForKey: @"emails"] objectEnumerator];
|
||||
while ((key = [emails nextObject]))
|
||||
{
|
||||
[self cacheAttributes: values forLogin: key];
|
||||
}
|
||||
|
||||
[[users objectForKey: uid] setObject: [[NSDate date] addTimeInterval: [SOGoCache cleanupInterval]]
|
||||
forKey: @"cleanupDate"];
|
||||
}
|
||||
}
|
||||
|
||||
+ (void) setCachedUserSettings: (SOGoUserDefaults *) theSettings
|
||||
user: (NSString *) login
|
||||
- (void) _userDefaultsHaveLoaded: (NSNotification *) theNotification
|
||||
{
|
||||
NSDate *cleanupDate;
|
||||
|
||||
#if defined(THREADSAFE)
|
||||
[lock lock];
|
||||
#endif
|
||||
cleanupDate = [[NSDate date] addTimeInterval: [SOGoCache cleanupInterval]];
|
||||
[s_userSettings setObject: [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
theSettings, @"dictionary",
|
||||
cleanupDate, @"cleanupDate", nil]
|
||||
forKey: login];
|
||||
#if defined(THREADSAFE)
|
||||
[lock unlock];
|
||||
#endif
|
||||
NSString *uid;
|
||||
|
||||
uid = [[theNotification userInfo] objectForKey: @"uid"];
|
||||
//NSLog(@"Loading user defaults for UID: %@", uid);
|
||||
if (![self userDefaultsForLogin: uid])
|
||||
{
|
||||
[self _cacheValues: [[theNotification userInfo] objectForKey: @"values"]
|
||||
login: uid
|
||||
url: [[theNotification userInfo] objectForKey: @"url"]
|
||||
key: @"defaults"];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) _userDefaultsHaveChanged: (NSNotification *) theNotification
|
||||
{
|
||||
SOGoUser *user;
|
||||
NSString *uid;
|
||||
SOGoUserDefaults *defaults;
|
||||
NSString *uid;
|
||||
|
||||
uid = [[theNotification userInfo] objectForKey: @"uid"];
|
||||
|
||||
#if defined(THREADSAFE)
|
||||
[lock lock];
|
||||
#endif
|
||||
if ((user = [users objectForKey: uid]))
|
||||
//NSLog(@"Updating user defaults for UID: %@", uid);
|
||||
defaults = (SOGoUserDefaults *)[self userDefaultsForLogin: uid];
|
||||
if (defaults)
|
||||
{
|
||||
defaults = (SOGoUserDefaults *) [user userDefaults];
|
||||
#if defined(THREADSAFE)
|
||||
[lock lock];
|
||||
#endif
|
||||
[defaults setValues: [[theNotification userInfo] objectForKey: @"values"]];
|
||||
[SOGoCache setCachedUserDefaults: defaults user: uid];
|
||||
[[users objectForKey: uid] setObject: [[NSDate date] addTimeInterval: [SOGoCache cleanupInterval]]
|
||||
forKey: @"cleanupDate"];
|
||||
#if defined(THREADSAFE)
|
||||
[lock unlock];
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
[s_userDefaults removeObjectForKey: uid];
|
||||
[self _cacheValues: [[theNotification userInfo] objectForKey: @"values"]
|
||||
login: uid
|
||||
url: [[theNotification userInfo] objectForKey: @"url"]
|
||||
key: @"defaults"];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) _userSettingsHaveLoaded: (NSNotification *) theNotification
|
||||
{
|
||||
NSString *uid;
|
||||
|
||||
uid = [[theNotification userInfo] objectForKey: @"uid"];
|
||||
//NSLog(@"Loading user settings for UID: %@", uid);
|
||||
if (![self userSettingsForLogin: uid])
|
||||
{
|
||||
[self _cacheValues: [[theNotification userInfo] objectForKey: @"values"]
|
||||
login: uid
|
||||
url: [[theNotification userInfo] objectForKey: @"url"]
|
||||
key: @"settings"];
|
||||
}
|
||||
#if defined(THREADSAFE)
|
||||
[lock unlock];
|
||||
#endif
|
||||
}
|
||||
|
||||
- (void) _userSettingsHaveChanged: (NSNotification *) theNotification
|
||||
{
|
||||
SOGoUser *user;
|
||||
SOGoUserDefaults *settings;
|
||||
NSString *uid;
|
||||
SOGoUserDefaults *settings;
|
||||
|
||||
|
||||
uid = [[theNotification userInfo] objectForKey: @"uid"];
|
||||
|
||||
if ((user = [users objectForKey: uid]))
|
||||
//NSLog(@"Updating user settings for UID: %@", uid);
|
||||
settings = (SOGoUserDefaults *)[self userSettingsForLogin: uid];
|
||||
if (settings)
|
||||
{
|
||||
settings = (SOGoUserDefaults *) [user userSettings];
|
||||
#if defined(THREADSAFE)
|
||||
[lock lock];
|
||||
#endif
|
||||
[settings setValues: [[theNotification userInfo] objectForKey: @"values"]];
|
||||
[SOGoCache setCachedUserSettings: settings user: uid];
|
||||
[[users objectForKey: uid] setObject: [[NSDate date] addTimeInterval: [SOGoCache cleanupInterval]]
|
||||
forKey: @"cleanupDate"];
|
||||
#if defined(THREADSAFE)
|
||||
[lock unlock];
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
[s_userSettings removeObjectForKey: uid];
|
||||
[self _cacheValues: [[theNotification userInfo] objectForKey: @"values"]
|
||||
login: uid
|
||||
url: [[theNotification userInfo] objectForKey: @"url"]
|
||||
key: @"settings"];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -345,40 +482,23 @@ withName: (NSString *) name
|
|||
#endif
|
||||
|
||||
now = [NSDate date];
|
||||
|
||||
// We cleanup the user defaults
|
||||
userIDs = [[s_userDefaults allKeys] objectEnumerator];
|
||||
count = 0;
|
||||
while ((currentID = [userIDs nextObject]))
|
||||
{
|
||||
currentEntry = [s_userDefaults objectForKey: currentID];
|
||||
|
||||
if ([now earlierDate: [currentEntry objectForKey: @"cleanupDate"]] == now)
|
||||
{
|
||||
[s_userDefaults removeObjectForKey: currentID];
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
if (count)
|
||||
[self logWithFormat: @"cleaned %d users records from user defaults cache", count];
|
||||
|
||||
// We cleanup the user settings
|
||||
userIDs = [[s_userSettings allKeys] objectEnumerator];
|
||||
// We cleanup the user cache
|
||||
userIDs = [[users allKeys] objectEnumerator];
|
||||
count = 0;
|
||||
while ((currentID = [userIDs nextObject]))
|
||||
{
|
||||
currentEntry = [s_userSettings objectForKey: currentID];
|
||||
currentEntry = [users objectForKey: currentID];
|
||||
|
||||
if ([now earlierDate: [currentEntry objectForKey: @"cleanupDate"]] == now)
|
||||
{
|
||||
[s_userSettings removeObjectForKey: currentID];
|
||||
[users removeObjectForKey: currentID];
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
if (count)
|
||||
[self logWithFormat: @"cleaned %d users records from user settings cache",
|
||||
[self logWithFormat: @"cleaned %d users records from users cache",
|
||||
count];
|
||||
|
||||
#if defined(THREADSAFE)
|
||||
|
|
|
@ -85,30 +85,13 @@ extern NSString *SOGoWeekStartFirstFullWeek;
|
|||
- (NSString *) currentPassword;
|
||||
|
||||
/* properties */
|
||||
|
||||
// - (NSString *) fullEmail;
|
||||
|
||||
// - (NSString *) primaryEmail;
|
||||
// - (NSString *) systemEmail;
|
||||
- (NSArray *) allEmails;
|
||||
|
||||
- (BOOL) hasEmail: (NSString *) email;
|
||||
|
||||
- (NSString *) cn;
|
||||
- (NSURL *) freeBusyURL;
|
||||
|
||||
- (SOGoDateFormatter *) dateFormatterInContext: (WOContext *) context;
|
||||
|
||||
/* shares and identities */
|
||||
|
||||
// - (NSString *) primaryIMAP4AccountString;
|
||||
|
||||
// - (NSString *) primaryIMAP4AccountString;
|
||||
// - (NSString *) primaryMailServer;
|
||||
// - (NSArray *) additionalIMAP4AccountStrings;
|
||||
// - (NSArray *) additionalEMailAddresses;
|
||||
// - (NSDictionary *) additionalIMAP4AccountsAndEMails;
|
||||
|
||||
/* defaults */
|
||||
- (NSUserDefaults *) userDefaults;
|
||||
- (NSUserDefaults *) userSettings;
|
||||
|
|
|
@ -23,11 +23,13 @@
|
|||
#import <Foundation/NSArray.h>
|
||||
#import <Foundation/NSCalendarDate.h>
|
||||
#import <Foundation/NSDictionary.h>
|
||||
#import <Foundation/NSDistributedNotificationCenter.h>
|
||||
#import <Foundation/NSEnumerator.h>
|
||||
#import <Foundation/NSNull.h>
|
||||
#import <Foundation/NSTimeZone.h>
|
||||
#import <Foundation/NSUserDefaults.h>
|
||||
#import <Foundation/NSValue.h>
|
||||
#import <Foundation/NSURL.h>
|
||||
#import <NGObjWeb/WOApplication.h>
|
||||
#import <NGObjWeb/WOContext.h>
|
||||
#import <NGObjWeb/WORequest.h>
|
||||
|
@ -330,20 +332,6 @@ _timeValue (NSString *key)
|
|||
}
|
||||
|
||||
/* properties */
|
||||
|
||||
// - (NSString *) fullEmail
|
||||
// {
|
||||
// return [[LDAPUserManager sharedUserManager] getFullEmailForUID: login];
|
||||
// }
|
||||
|
||||
// - (NSString *) primaryEmail
|
||||
// {
|
||||
// if (!allEmails)
|
||||
// [self _fetchAllEmails];
|
||||
|
||||
// return [allEmails objectAtIndex: 0];
|
||||
// }
|
||||
|
||||
- (NSArray *) allEmails
|
||||
{
|
||||
if (!allEmails)
|
||||
|
@ -415,26 +403,6 @@ _timeValue (NSString *key)
|
|||
@" variable(s) mentionned above are configured"];
|
||||
}
|
||||
|
||||
// - (NSString *) primaryMailServer
|
||||
// {
|
||||
// return [[self userManager] getServerForUID: [self login]];
|
||||
// }
|
||||
|
||||
// - (NSArray *) additionalIMAP4AccountStrings
|
||||
// {
|
||||
// return [[self userManager]getSharedMailboxAccountStringsForUID: [self login]];
|
||||
// }
|
||||
|
||||
// - (NSArray *) additionalEMailAddresses
|
||||
// {
|
||||
// return [[self userManager] getSharedMailboxEMailsForUID: [self login]];
|
||||
// }
|
||||
|
||||
// - (NSDictionary *) additionalIMAP4AccountsAndEMails
|
||||
// {
|
||||
// return [[self userManager] getSharedMailboxesAndEMailsForUID: [self login]];
|
||||
// }
|
||||
|
||||
- (NSURL *) freeBusyURL
|
||||
{
|
||||
return nil;
|
||||
|
@ -491,15 +459,16 @@ _timeValue (NSString *key)
|
|||
- (NSUserDefaults *) userDefaults
|
||||
{
|
||||
SOGoUserDefaults *defaults;
|
||||
NSDictionary *cachedDefaults;
|
||||
|
||||
cachedDefaults = [[SOGoCache cachedUserDefaults] objectForKey: login];
|
||||
if (cachedDefaults)
|
||||
defaults = [cachedDefaults objectForKey: @"dictionary"];
|
||||
else
|
||||
defaults = [[SOGoCache sharedCache] userDefaultsForLogin: login];
|
||||
|
||||
if (!defaults)
|
||||
{
|
||||
NSMutableDictionary *d;
|
||||
|
||||
defaults = [self primaryUserDefaults];
|
||||
/* Required parameters for the web interface */
|
||||
|
||||
// Required parameters for the Web interface
|
||||
if (![[defaults stringForKey: @"ReplyPlacement"] length])
|
||||
[defaults setObject: defaultReplyPlacement forKey: @"ReplyPlacement"];
|
||||
if (![[defaults stringForKey: @"SignaturePlacement"] length])
|
||||
|
@ -509,8 +478,22 @@ _timeValue (NSString *key)
|
|||
if (![[defaults stringForKey: @"MessageCheck"] length])
|
||||
[defaults setObject: defaultMessageCheck forKey: @"MessageCheck"];
|
||||
|
||||
[SOGoCache setCachedUserDefaults: defaults user: login];
|
||||
// We propagate the loaded user defaults to other sogod instances
|
||||
// which will cache them in SOGoCache (including for the instance
|
||||
// that actually posts the notification)
|
||||
d = [NSMutableDictionary dictionary];
|
||||
[d setObject: [defaults values] forKey: @"values"];
|
||||
[d setObject: login forKey: @"uid"];
|
||||
[d setObject: [SOGoProfileURL absoluteString] forKey: @"url"];
|
||||
|
||||
[[NSDistributedNotificationCenter defaultCenter]
|
||||
postNotificationName: @"SOGoUserDefaultsHaveLoaded"
|
||||
object: nil
|
||||
userInfo: d
|
||||
deliverImmediately: YES];
|
||||
}
|
||||
//else
|
||||
// NSLog(@"User defaults cache hit for %@", login);
|
||||
|
||||
return (NSUserDefaults *) defaults;
|
||||
}
|
||||
|
@ -518,16 +501,31 @@ _timeValue (NSString *key)
|
|||
- (NSUserDefaults *) userSettings
|
||||
{
|
||||
SOGoUserDefaults *settings;
|
||||
NSDictionary *cachedSettings;
|
||||
|
||||
cachedSettings = [[SOGoCache cachedUserSettings] objectForKey: login];
|
||||
if (cachedSettings)
|
||||
settings = [cachedSettings objectForKey: @"dictionary"];
|
||||
else
|
||||
settings = [[SOGoCache sharedCache] userSettingsForLogin: login];
|
||||
|
||||
if (!settings)
|
||||
{
|
||||
NSMutableDictionary *d;
|
||||
|
||||
settings = [self primaryUserSettings];
|
||||
[SOGoCache setCachedUserSettings: settings user: login];
|
||||
[settings fetchProfile];
|
||||
// We propagate the loaded user settings to other sogod instances
|
||||
// which will cache them in SOGoCache (including for the instance
|
||||
// that actually posts the notification)
|
||||
d = [NSMutableDictionary dictionary];
|
||||
[d setObject: [settings values] forKey: @"values"];
|
||||
[d setObject: login forKey: @"uid"];
|
||||
[d setObject: [SOGoProfileURL absoluteString] forKey: @"url"];
|
||||
|
||||
[[NSDistributedNotificationCenter defaultCenter]
|
||||
postNotificationName: @"SOGoUserSettingsHaveLoaded"
|
||||
object: nil
|
||||
userInfo: d
|
||||
deliverImmediately: YES];
|
||||
}
|
||||
//else
|
||||
// NSLog(@"User settings cache hit for %@", login);
|
||||
|
||||
return (NSUserDefaults *) settings;
|
||||
}
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
/*
|
||||
Copyright (C) 2005 SKYRIX Software AG
|
||||
Copyright (C) 2008-2009 Inverse inc.
|
||||
|
||||
This file is part of OpenGroupware.org.
|
||||
This file is part of SOGo.
|
||||
|
||||
OGo is free software; you can redistribute it and/or modify it under
|
||||
SOGo 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
|
||||
SOGo 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.
|
||||
|
@ -46,7 +47,6 @@
|
|||
{
|
||||
int modified: 1;
|
||||
int isNew: 1;
|
||||
int reserved: 30;
|
||||
} defFlags;
|
||||
}
|
||||
|
||||
|
@ -56,6 +56,7 @@
|
|||
|
||||
/* value access */
|
||||
- (void) setValues: (NSDictionary *) theValues;
|
||||
- (NSDictionary *) values;
|
||||
|
||||
- (void) setObject: (id) value
|
||||
forKey: (NSString *) key;
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
/*
|
||||
Copyright (C) 2005 SKYRIX Software AG
|
||||
Copyright (C) 2008 Inverse inc.
|
||||
Copyright (C) 2008-2009 Inverse inc.
|
||||
|
||||
This file is part of OpenGroupware.org.
|
||||
This file is part of SOGo.
|
||||
|
||||
OGo is free software; you can redistribute it and/or modify it under
|
||||
SOGo 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
|
||||
SOGo 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.
|
||||
|
@ -159,7 +159,7 @@ static NSString *uidColumnName = @"c_uid";
|
|||
else
|
||||
values = [NSMutableDictionary new];
|
||||
|
||||
ASSIGN (lastFetch, [NSCalendarDate date]);
|
||||
ASSIGN(lastFetch, [NSCalendarDate date]);
|
||||
defFlags.modified = NO;
|
||||
rc = YES;
|
||||
}
|
||||
|
@ -292,6 +292,7 @@ static NSString *uidColumnName = @"c_uid";
|
|||
d = [NSMutableDictionary dictionary];
|
||||
[d setObject: values forKey: @"values"];
|
||||
[d setObject: uid forKey: @"uid"];
|
||||
[d setObject: [url absoluteString] forKey: @"url"];
|
||||
|
||||
[[NSDistributedNotificationCenter defaultCenter]
|
||||
postNotificationName: ([fieldName isEqualToString: @"c_defaults"]
|
||||
|
@ -322,6 +323,14 @@ static NSString *uidColumnName = @"c_uid";
|
|||
{
|
||||
[values removeAllObjects];
|
||||
[values addEntriesFromDictionary: theValues];
|
||||
ASSIGN(lastFetch, [NSCalendarDate date]);
|
||||
defFlags.modified = NO;
|
||||
defFlags.isNew = NO;
|
||||
}
|
||||
|
||||
- (NSDictionary *) values
|
||||
{
|
||||
return values;
|
||||
}
|
||||
|
||||
- (void) setObject: (id) value
|
||||
|
|
|
@ -37,6 +37,6 @@
|
|||
"The user rights cannot be edited for this object!" = "I permessi di questo oggetto non possono essere modificati!";
|
||||
|
||||
"You are not allowed to access this module or this system. Please contact your system administrator."
|
||||
= "You are not allowed to access this module or this system. Please contact your system administrator.";
|
||||
= "Non sei abilitato ad accedere a questo modulo. Contatta il tuo amministratore di sistema.";
|
||||
"You don't have the required privileges to perform the operation."
|
||||
= "You don't have the required privileges to perform the operation.";
|
||||
= "Non disponi dei privilegi richiesti per eseguire questa operazione.";
|
||||
|
|
|
@ -67,7 +67,7 @@
|
|||
"Remove" = "Löschen";
|
||||
|
||||
"Please wait..." = "Bitte warten...";
|
||||
"No possible subscription" = "Kein abonnieren möglich";
|
||||
"No possible subscription" = "Kein Abonnieren möglich";
|
||||
|
||||
"Preferred" = "Bevorzugt";
|
||||
"Card for %@" = "%@";
|
||||
|
@ -114,22 +114,22 @@
|
|||
"Blind Carbon Copy" = "Blindkopie";
|
||||
|
||||
"New Addressbook..." = "Neues Adressbuch...";
|
||||
"Subscribe to an Addressbook..." = "Abonnieren...";
|
||||
"Remove the selected Addressbook" = "Adressbuch löschen";
|
||||
"Subscribe to an Addressbook..." = "Ein Adressbuch abonnieren...";
|
||||
"Remove the selected Addressbook" = "Gewähltes Adressbuch löschen";
|
||||
|
||||
"Name of the Address Book" = "Adressbuch-Name";
|
||||
"Are you sure you want to delete the selected address book?"
|
||||
= "Wollen Sie wirklich das ausgewählte Adressbuch löschen?";
|
||||
= "Wollen Sie wirklich das gewählte Adressbuch löschen?";
|
||||
"You cannot remove nor unsubscribe from a public addressbook."
|
||||
= "Sie können das gemeinsame Adressbuch nicht löschen.";
|
||||
"You cannot remove nor unsubscribe from your personal addressbook."
|
||||
= "Sie können ihr Persönliches Adressbuch nicht löschen.";
|
||||
|
||||
"Are you sure you want to delete the selected contacts?"
|
||||
= "Wollen Sie wirklich die ausgewählte Karten löschen?";
|
||||
= "Wollen Sie wirklich die gewählten Karten löschen?";
|
||||
|
||||
"You cannot delete the selected contact(s)"
|
||||
= "Ausgewählte Karten können nicht gelöscht werden.";
|
||||
= "Gewählte Karten können nicht gelöscht werden.";
|
||||
"You cannot delete the card of \"%{0}\"."
|
||||
= "Sie können die Karte von \"%{0}\" nicht löschen.";
|
||||
|
||||
|
@ -140,7 +140,7 @@
|
|||
"Unable to subscribe to that folder!"
|
||||
= "Abonnieren des Ordners nicht möglich!";
|
||||
|
||||
"Default Roles" = "Standard-Rollen";
|
||||
"Default Roles" = "Standardrechte";
|
||||
"User rights for:" = "Benutzerrechte für:";
|
||||
|
||||
"This person can add cards to this addressbook."
|
||||
|
@ -152,7 +152,7 @@
|
|||
"This person can read the cards of this addressbook."
|
||||
= "Diese Person kann Karten dieses Adressbuches anzeigen.";
|
||||
"This person can erase cards from this addressbook."
|
||||
= "Diese Person kann Karten aus diesem Adressbuch löschen";
|
||||
= "Diese Person kann Karten aus diesem Adressbuch löschen.";
|
||||
|
||||
"The selected contact has no email address."
|
||||
= "Der gewählte Kontakt hat keine E-Mail-Adresse.";
|
||||
|
@ -163,8 +163,8 @@
|
|||
|
||||
"SoAccessDeniedException" = "Sie können nicht auf dieses Adressbuch schreiben.";
|
||||
"Forbidden" = "Sie können nicht auf dieses Adressbuch schreiben.";
|
||||
"Invalid Contact" = "Der ausgewählte Kontakt existiert nicht mehr.";
|
||||
"Unknown Destination Folder" = "Das ausgewählte Ziel-Adressbuch existiert nicht mehr.";
|
||||
"Invalid Contact" = "Der gewählte Kontakt existiert nicht mehr.";
|
||||
"Unknown Destination Folder" = "Das gewählte Ziel-Adressbuch existiert nicht mehr.";
|
||||
|
||||
"Move To" = "Verschieben in";
|
||||
"Copy To" = "Kopieren in";
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
"Addressbook" = "Rubrica";
|
||||
"Addresses" = "Indirizzi";
|
||||
"Update" = "Aggiorna";
|
||||
"Cancel" = "Anulla";
|
||||
"Cancel" = "Annulla";
|
||||
"Common" = "Comuni";
|
||||
"Contact editor" = "Editor dei contatti";
|
||||
"Contact viewer" = "Visulizzatore dei contatti";
|
||||
|
@ -42,7 +42,7 @@
|
|||
"delete" = "cancella";
|
||||
"edit" = "modifica";
|
||||
"invalidemailwarn" = "L'indirizzo email specificato non è valido";
|
||||
"new" = "new";
|
||||
"new" = "nuovo";
|
||||
"Preferred Phone" = "Telefono lavoro";
|
||||
|
||||
/* Tooltips */
|
||||
|
@ -71,8 +71,8 @@
|
|||
"Add..." = "Aggiungi...";
|
||||
"Remove" = "Rimuovi";
|
||||
|
||||
"Please wait..." = "Please wait...";
|
||||
"No possible subscription" = "No possible subscription";
|
||||
"Please wait..." = "Attendere prego...";
|
||||
"No possible subscription" = "Nessuna sottoscrizione possibile";
|
||||
|
||||
"Preferred" = "Predefinito";
|
||||
"Card for %@" = "Biglietto da visita di %@";
|
||||
|
@ -125,6 +125,9 @@
|
|||
"Carbon Copy" = "Copia Carbone";
|
||||
"Blind Carbon Copy" = "Copia Carbone Nascosta";
|
||||
|
||||
"Move To" = "Sposta in ";
|
||||
"Copy To" = "Copia in ";
|
||||
|
||||
"New Addressbook..." = "Nuova rubrica...";
|
||||
"Subscribe to an Addressbook..." = "Sottoscrivi una rubrica...";
|
||||
"Remove the selected Addressbook" = "Rimuovi la rubrica selezionata";
|
||||
|
@ -133,9 +136,9 @@
|
|||
"Are you sure you want to delete the selected address book?"
|
||||
= "Sei sicuro di voler cancellare la rubrica selezionata?";
|
||||
"You cannot remove nor unsubscribe from a public addressbook."
|
||||
= "You cannot remove nor unsubscribe from a public addressbook.";
|
||||
= "Non puoi rimuovere una rubrica pubblica.";
|
||||
"You cannot remove nor unsubscribe from your personal addressbook."
|
||||
= "You cannot remove nor unsubscribe from your personal addressbook.";
|
||||
= "Non puoi rimuovere la tua rubrica personale.";
|
||||
|
||||
"Are you sure you want to delete the selected contacts?"
|
||||
= "Sei sicuro di voler eliminare i contatti selezionati?";
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
ACCEPTED = "akzeptiert";
|
||||
COMPLETED = "abgeschlossen";
|
||||
DECLINED = "zurückgewiesen";
|
||||
DELEGATED = "weitergeleited";
|
||||
DELEGATED = "weitergeleitet";
|
||||
IN-PROCESS = "in Bearbeitung";
|
||||
NEEDS-ACTION = "Reaktion erwarted";
|
||||
TENTATIVE = "vorläufig";
|
||||
organized_by_you = "von Ihnen organisiert";
|
||||
you_are_an_attendee = "sind sind ein Teilnehmer";
|
||||
you_are_an_attendee = "Sie sind ein Teilnehmer";
|
||||
add_info_text = "iMIP 'ADD' Anfragen werden von SOGo noch nicht unterstützt.";
|
||||
publish_info_text = "Der Sender informiert Sie über den angefügten Termin.";
|
||||
cancel_info_text = "Ihre Einladung zu dem Termin wurde abgesagt.";
|
||||
|
@ -16,7 +16,7 @@ Appointment = "Termin";
|
|||
Organizer = "Organisator";
|
||||
Time = "Zeit";
|
||||
Attendees = "Teilnehmer";
|
||||
request_info = "lädt sie ein an einem Treffen teilzunehmen.";
|
||||
request_info = "lädt sie ein, an einem Treffen teilzunehmen.";
|
||||
"Add to calendar" = "Zum Kalender hinzufügen";
|
||||
"Delete from calendar" = "Aus Kalender entfernen";
|
||||
"Update status" = "Status aktualisieren";
|
||||
|
|
|
@ -7,7 +7,7 @@ NEEDS-ACTION = "richiede un'azione";
|
|||
TENTATIVE = "tentativo";
|
||||
organized_by_you = "organizzata da te";
|
||||
you_are_an_attendee = "sei uno degli invitati";
|
||||
add_info_text = "Le richieste iMIP 'ADD' non sono ancora supportate da SOGo.";
|
||||
add_info_text = "Le richieste IMIP 'ADD' non sono ancora supportate da SOGo.";
|
||||
publish_info_text = "Il mittente ti invia in allegato informazioni sull'evento.";
|
||||
cancel_info_text = "Il tuo invito o l'intero evento sono stati cancellati.";
|
||||
request_info_no_attendee = "sta proponento un incontro agli invitati. Ricevi questa email come notifica, non sei incluso come partecipante.";
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
"Create" = "Crea";
|
||||
"Empty Trash" = "Svuota cestino";
|
||||
"Delete" = "Cancella";
|
||||
"Expunge" = "Expunge";
|
||||
"Expunge" = "Pulisci";
|
||||
"Forward" = "Inoltra";
|
||||
"Get Mail" = "Scarica posta";
|
||||
"Junk" = "Indesiderato";
|
||||
|
@ -13,15 +13,15 @@
|
|||
"Print" = "Stampa";
|
||||
"Stop" = "Stop";
|
||||
"Write" = "Scrivi";
|
||||
"Attachment" = "Attachment";
|
||||
"Unread" = "Unread";
|
||||
"Attachment" = "Allegato";
|
||||
"Unread" = "Non letta";
|
||||
"Flagged" = "Flagged";
|
||||
|
||||
"Send" = "Invia";
|
||||
"Contacts" = "Contatti";
|
||||
"Attach" = "Allegato";
|
||||
"Save" = "Salva";
|
||||
"Priority" = "Priority";
|
||||
"Priority" = "Priorità";
|
||||
|
||||
/* Tooltips */
|
||||
|
||||
|
@ -74,7 +74,7 @@
|
|||
"Add subfolders to this folder" = "Aggiungi sottocartelle a questa cartella";
|
||||
"Remove this folder" = "Rimuovi questa cartella";
|
||||
"Erase mails from this folder" = "Elimina emails da questa cartella";
|
||||
"Expunge this folder" = "Expugne per questa cartella";
|
||||
"Expunge this folder" = "Pulisci questa cartella";
|
||||
"Modify the acl of this folder" = "Modifica i permessi per questa cartella";
|
||||
|
||||
"Update" = "Aggiorna";
|
||||
|
@ -104,15 +104,15 @@
|
|||
"Anais" = "Anais";
|
||||
|
||||
"Edit Draft..." = "Modifica bozza...";
|
||||
"Load Images" = "Load Images";
|
||||
"Load Images" = "Carica Immagini";
|
||||
|
||||
"highest" = "Highest";
|
||||
"high" = "High";
|
||||
"normal" = "Normal";
|
||||
"low" = "Low";
|
||||
"lowest" = "Lowest";
|
||||
"highest" = "Molto alta";
|
||||
"high" = "Alta";
|
||||
"normal" = "Normale";
|
||||
"low" = "Bassa";
|
||||
"lowest" = "Molto bassa";
|
||||
|
||||
"This mail is being sent from an unsecure network!" = "Questa email è stata spedita da un network contrassegnato come non sicuro!";
|
||||
"This mail is being sent from an unsecure network!" = "Questa email è stata spedita da una rete contrassegnata come non sicuro!";
|
||||
|
||||
/* Popup "show" */
|
||||
|
||||
|
@ -205,9 +205,9 @@
|
|||
"View Message Source" = "Visualizza sorgente";
|
||||
"Print..." = "Stampa...";
|
||||
"Delete Message" = "Cancella messaggio";
|
||||
"Delete Selected Messages" = "Delete Selected Messages";
|
||||
"Delete Selected Messages" = "Cancella i messaggi selezionati";
|
||||
|
||||
"This Folder" = "This Folder";
|
||||
"This Folder" = "Questa cartella";
|
||||
|
||||
/* Label popup menu */
|
||||
"None" = "Nessuno";
|
||||
|
@ -230,7 +230,7 @@
|
|||
/* Folder operations */
|
||||
"Name :" = "Nome :";
|
||||
"Enter the new name of your folder :"
|
||||
= "Inserisci il nuovo nome della tua cartella :";
|
||||
= "Inserisci il nuovo nome della cartella :";
|
||||
"Do you really want to move this folder into the trash ?"
|
||||
= "Sei sicuro di voler spostare la cartella nel cestino ?";
|
||||
"Operation failed" = "Operazione non riuscita";
|
||||
|
@ -243,15 +243,15 @@
|
|||
"Please select only one message to print." = "Per favore seleziona un solo messaggio da stampare.";
|
||||
|
||||
"The folder with name \"%{0}\" could not be created."
|
||||
= "The folder with name \"%{0}\" could not be created.";
|
||||
= "La cartella con nome \"%{0}\" non può essere creata.";
|
||||
"This folder could not be renamed to \"%{0}\"."
|
||||
= "This folder could not be renamed to \"%{0}\".";
|
||||
= "Questa cartella non puo essere rinominata in \"%{0}\".";
|
||||
"The folder could not be deleted."
|
||||
= "The folder could not be deleted.";
|
||||
= "Questa cartella non può essere eliminata.";
|
||||
"The trash could not be emptied."
|
||||
= "The trash could not be emptied.";
|
||||
= "Il cestino non puo essere svuotato.";
|
||||
"The folder functionality could not be changed."
|
||||
= "The folder functionality could not be changed.";
|
||||
= "La funzionalita della cartella non puo essere cambiata.";
|
||||
|
||||
"You need to choose a non-virtual folder!" = "Devi selezionare una cartella fisica, non virtuale!";
|
||||
|
||||
|
|
|
@ -23,12 +23,12 @@
|
|||
NSShortDateFormatString = "%d/%m/%y";
|
||||
NSShortMonthNameArray = (Gen, Feb, Mar, Apr, Mag, Giu, Lug, Ago, Set, Ott, Nov, Dic);
|
||||
NSShortTimeDateFormatString = "%d/%m/%y %H:%M";
|
||||
NSShortWeekDayNameArray = (Lun, Mar, Mer, Gio, Ven, Sab, Dom);
|
||||
NSShortWeekDayNameArray = (Dom, Lun, Mar, Mer, Gio, Ven, Sab);
|
||||
NSThisDayDesignations = (oggi, ora);
|
||||
NSThousandsSeparator = ",";
|
||||
NSTimeDateFormatString = "%A, %e %B, %Y %H:%M:%S %Z";
|
||||
NSTimeFormatString = "%H:%M:%S";
|
||||
NSWeekDayNameArray = (Lunedi, Martedi, Mercoledi, Giovedi, Venerdi, Sabato, Domenica);
|
||||
NSWeekDayNameArray = (Domenica, Lunedi, Martedi, Mercoledi, Giovedi, Venerdi, Sabato);
|
||||
NSYearMonthWeekDesignations = (anno, mese, settimana);
|
||||
NSPositiveCurrencyFormatString = "⬠9,999.00";
|
||||
NSNegativeCurrencyFormatString = "-⬠9,999.00";
|
||||
|
|
|
@ -14,8 +14,8 @@
|
|||
"alternativeBrowserSafari" = "Alternativamente, puoi utilizzare Safari.";
|
||||
"Download" = "Scarica";
|
||||
|
||||
"Language:" = "Language:";
|
||||
"choose" = "Choose ...";
|
||||
"Language:" = "Lingua:";
|
||||
"choose" = "Scegli...";
|
||||
"Dutch" = "Dutch";
|
||||
"English" = "Inglese";
|
||||
"French" = "Francese";
|
||||
|
|
|
@ -83,14 +83,14 @@
|
|||
"Default identity:" = "Identità principale:";
|
||||
"Manage identities..." = "Gestisci identità...";
|
||||
"Signature" = "Firma";
|
||||
"replyplacement_above" = "replyplacement_above";
|
||||
"replyplacement_below" = "replyplacement_below";
|
||||
"And place my signature" = "And place my signature";
|
||||
"signatureplacement_above" = "signatureplacement_above";
|
||||
"signatureplacement_below" = "signatureplacement_below";
|
||||
"replyplacement_above" = "Inizia la risposta sopra il testo a cui si risponde";
|
||||
"replyplacement_below" = "Inizia la risposta sotto il testo a cui si risponde";
|
||||
"And place my signature" = "Metti la firma";
|
||||
"signatureplacement_above" = "sopra il testo a cui si risponde";
|
||||
"signatureplacement_below" = "sotto il testo a cui si risponde";
|
||||
|
||||
/* Additional Parameters */
|
||||
"Additional Parameters" = "Additional Parameters";
|
||||
"Additional Parameters" = "Parametri addizionali";
|
||||
|
||||
/* password */
|
||||
"New password:" = "Nuova password:";
|
||||
|
|
|
@ -111,7 +111,7 @@
|
|||
|
||||
/* acls */
|
||||
|
||||
"Default Roles" = "Standard-Rollen";
|
||||
"Default Roles" = "Standardrechte";
|
||||
"User rights for:" = "Benutzerrechte für:";
|
||||
|
||||
"label_Public" = "Öffentlich";
|
||||
|
@ -131,9 +131,9 @@
|
|||
"None" = "Keine";
|
||||
|
||||
"This person can create objects in my calendar."
|
||||
= "Diese Person kann Termine in meinem Kalender hinzufügen.";
|
||||
= "Diese Person kann Objekte in meinem Kalender hinzufügen.";
|
||||
"This person can erase objects from my calendar."
|
||||
= "Diese Person kann Termine in meinem Kalender löschen.";
|
||||
= "Diese Person kann Objekte in meinem Kalender löschen.";
|
||||
|
||||
/* Button Titles */
|
||||
|
||||
|
@ -397,7 +397,7 @@
|
|||
|
||||
/* transparency */
|
||||
|
||||
"Show Time as Free" = "Zeige Zeit als Frei";
|
||||
"Show Time as Free" = "Zeige Zeit als Verfügbar";
|
||||
|
||||
/* validation errors */
|
||||
|
||||
|
@ -439,7 +439,7 @@ validate_endbeforestart = "Ihr Beginn ist nach dem Ende";
|
|||
"taskDeleteConfirmation" = "Wollen Sie diese Aufgabe wirklich dauerhaft löschen?";
|
||||
|
||||
"Are you sure you want to delete the calendar \"%{0}\"?"
|
||||
= "Wollen Sie diesen Kalender wirklich dauerhaft löschen \"%{0}\"?";
|
||||
= "Wollen Sie diesen Kalender wirklich löschen \"%{0}\"?";
|
||||
|
||||
/* Legend */
|
||||
"Required participant" = "notwendiger Teilnehmer";
|
||||
|
@ -458,8 +458,8 @@ validate_endbeforestart = "Ihr Beginn ist nach dem Ende";
|
|||
|
||||
/* FreeBusy panel buttons */
|
||||
"Suggest time slot:" = "Termin vorschlagen:";
|
||||
"Previous slot" = "Vorherige";
|
||||
"Next slot" = "Nächste";
|
||||
"Previous slot" = "Vorheriger";
|
||||
"Next slot" = "Nächster";
|
||||
"Previous hour" = "Vorherige Stunde";
|
||||
"Next hour" = "Nächste Stunde";
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
"Thursday" = "Giovedi";
|
||||
"Friday" = "Venerdi";
|
||||
"Saturday" = "Sabato";
|
||||
"DayOfTheMonth" = "Giorno del mese";
|
||||
|
||||
"Sun" = "Dom";
|
||||
"Mon" = "Lun";
|
||||
|
@ -95,7 +96,7 @@
|
|||
"Sharing..." = "Condivisione";
|
||||
"Export Calendar..." = "Esporta calendario...";
|
||||
"Publish Calendar..." = "Pubblica calendario...";
|
||||
"Reload Remote Calendars" = "Aggiorna calendari Remoti";
|
||||
"Reload Remote Calendars" = "Aggiorna calendari remoti";
|
||||
"Properties" = "Proprietà";
|
||||
|
||||
"Compose E-Mail to All Attendees" = "Invia Email a tutti gli invitati";
|
||||
|
@ -196,7 +197,7 @@
|
|||
"Duration" = "Durata";
|
||||
"Attendees:" = "Partecipanti:";
|
||||
"Resources" = "Risorse";
|
||||
"Organizer:" = "Organizzatore:";
|
||||
"Organizer:" = "Proprietario:";
|
||||
"Description:" = "Descrizione:";
|
||||
"Document:" = "Documento:";
|
||||
"Category:" = "Categoria:";
|
||||
|
@ -256,7 +257,10 @@
|
|||
"All day Event" = "Tutta la giornata";
|
||||
"check for conflicts" = "Controlla conflitti";
|
||||
|
||||
"Browse URL" = "Cerca URL";
|
||||
"Browse URL" = "Mostra URL";
|
||||
|
||||
"newAttendee" = "Nuovo partecipante";
|
||||
|
||||
|
||||
/* calendar modes */
|
||||
|
||||
|
@ -396,7 +400,7 @@
|
|||
|
||||
/* transparency */
|
||||
|
||||
"Show Time as Free" = "Show Time as Free";
|
||||
"Show Time as Free" = "Mostra comunque come libero";
|
||||
|
||||
/* validation errors */
|
||||
|
||||
|
@ -443,7 +447,7 @@ validate_endbeforestart = "La data finale specificata è precedente alla data
|
|||
/* Legend */
|
||||
"Required participant" = "Richiede partecipanti";
|
||||
"Optional participant" = "Partecipanti opzionali";
|
||||
"Chair" = "Chair";
|
||||
"Chair" = "Sedia";
|
||||
|
||||
"Needs action" = "Richiede un'azione";
|
||||
"Accepted" = "Accettato";
|
||||
|
@ -491,4 +495,4 @@ vtodo_class2 = "(Attività confidenziale)";
|
|||
/* Properties dialog */
|
||||
"Name:" = "Nome:";
|
||||
"Color:" = "Colore:";
|
||||
"Tag:" = "Tag:";
|
||||
"Tag:" = "Etichetta:";
|
||||
|
|
Loading…
Reference in New Issue