#import "ASIPithosRequest.h"
#import "PithosAccountNode.h"
#import "PithosSharingAccountsNode.h"
+#import "PithosUtilities.h"
#import "pithos_macosAppDelegate.h"
@interface PithosAccount (Internal)
@end
@implementation PithosAccount
-@synthesize uniqueName, active, name;
+@synthesize uniqueName, active, name, clientVersion;
@synthesize syncActive, syncDirectoryPath, syncAccountsDictionary, syncSkipHidden, syncLastCompleted, syncDaemon;
-@synthesize serverURL, versionResource, loginResource, publicResource;
-@synthesize authUser, authToken, storageURLPrefix, authURL, loginURLPrefix, publicURLPrefix;
+@synthesize serverURL, versionResource, loginResource, publicResource, userCatalogResource;
+@synthesize authUser, authToken, storageURLPrefix, authURL, loginURLPrefix, publicURLPrefix, userCatalogURL, userCatalog;
@synthesize pithos, accountNode, sharingAccountsNode;
#pragma mark -
+ (id)pithosAccount {
PithosAccount *pithosAccount = [[self alloc] init];
pithosAccount.uniqueName = [NSString stringWithFormat:@"pithosAccount-%f", [NSDate timeIntervalSinceReferenceDate]];
+ pithosAccount.clientVersion = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"];
pithosAccount.syncSkipHidden = YES;
- pithosAccount.versionResource = @"v1";
- pithosAccount.loginResource = @"login";
return pithosAccount;
}
- (NSString *)description {
- return [NSString stringWithFormat:@"uniqueName: %@, active: %d, name: %@, syncActive: %d, syncDirectoryPath: %@, syncAccountsDictionary: %@, syncSkipHidden: %d, syncLastCompleted: %@, serverURL: %@, versionResource: %@, loginResource: %@, publicResource: %@, authUser: %@, authToken: %@, storageURLPrefix: %@, authURL: %@, loginURLPrefix: %@, publicURLPrefix: %@",
- uniqueName, active, name, syncActive, syncDirectoryPath, syncAccountsDictionary, syncSkipHidden, syncLastCompleted, serverURL, versionResource, loginResource, publicResource, authUser, authToken, storageURLPrefix, authURL, loginURLPrefix, publicURLPrefix];
+ return [NSString stringWithFormat:@"uniqueName: %@, active: %d, name: %@, clientVersion: %@, syncActive: %d, syncDirectoryPath: %@, syncAccountsDictionary: %@, syncSkipHidden: %d, syncLastCompleted: %@, serverURL: %@, versionResource: %@, loginResource: %@, publicResource: %@, userCatalogResource: %@, authUser: %@, authToken: %@, storageURLPrefix: %@, authURL: %@, loginURLPrefix: %@, publicURLPrefix: %@, userCatalogResource: %@",
+ uniqueName, active, name, clientVersion, syncActive, syncDirectoryPath, syncAccountsDictionary, syncSkipHidden, syncLastCompleted, serverURL, versionResource, loginResource, publicResource, userCatalogResource, authUser, authToken, storageURLPrefix, authURL, loginURLPrefix, publicURLPrefix, userCatalogResource];
}
#pragma mark -
- (NSMutableDictionary *)syncAccountsDictionary {
if (!syncAccountsDictionary) {
syncAccountsDictionary = [NSMutableDictionary dictionaryWithObject:[NSMutableDictionary dictionaryWithObject:[NSMutableSet set]
- forKey:@"pithos"]
- forKey:@""];
+ forKey:@"pithos"]
+ forKey:@""];
}
return syncAccountsDictionary;
}
NSDictionary *aSyncContainersDictionary = [aSyncAccountsDictionary objectForKey:accountName];
NSMutableDictionary *syncContainersDictionary = [NSMutableDictionary dictionary];
for (NSString *containerName in aSyncContainersDictionary) {
- if (![accountName isEqualToString:@""] || ![[containerName lowercaseString] isEqualToString:@"shared to me"])
+ if (![accountName isEqualToString:@""] || ![[containerName lowercaseString] isEqualToString:@"shared with me"])
[syncContainersDictionary setObject:[NSMutableSet setWithSet:[aSyncContainersDictionary objectForKey:containerName]]
forKey:containerName];
}
authURL = nil;
publicURLPrefix = nil;
loginURLPrefix = nil;
+ userCatalogURL = nil;
@synchronized(self) {
updatePithos = YES;
}
}
+- (NSString *)versionResource {
+ if (!versionResource) {
+ versionResource = @"v1";
+ }
+ return versionResource;
+}
+
+- (NSString *)loginResource {
+ if (!loginResource) {
+ loginResource = @"login";
+ }
+ return loginResource;
+}
+
+- (NSString *)userCatalogResource {
+ if (!userCatalogResource) {
+ userCatalogResource = @"user_catalogs";
+ }
+ return userCatalogResource;
+}
+
- (void)setAuthUser:(NSString *)anAuthUser {
if ([anAuthUser length] && ![anAuthUser isEqualToString:authUser]) {
authUser = anAuthUser;
- (NSString *)storageURLPrefix {
if (![self urlIsValid:storageURLPrefix]) {
- if (versionResource)
- storageURLPrefix = [self.serverURL stringByAppendingFormat:@"/%@", versionResource];
- else
- storageURLPrefix = [self.serverURL copy];
+ storageURLPrefix = [self.serverURL stringByAppendingFormat:@"/%@", self.versionResource];
}
return storageURLPrefix;
}
- (NSString *)authURL {
if (![self urlIsValid:authURL]) {
- if (versionResource)
- authURL = [self.serverURL stringByAppendingFormat:@"/%@", versionResource];
- else
- authURL = [self.serverURL copy];
+ authURL = [self.serverURL stringByAppendingFormat:@"/%@", self.versionResource];
}
return authURL;
}
- (NSString *)loginURLPrefix {
if (![self urlIsValid:loginURLPrefix]) {
- if (loginResource)
- loginURLPrefix = [self.serverURL stringByAppendingFormat:@"/%@", loginResource];
- else
- loginURLPrefix = [self.serverURL copy];
+ loginURLPrefix = [self.serverURL stringByAppendingFormat:@"/%@", self.loginResource];
}
return loginURLPrefix;
}
}
}
+- (NSString *)userCatalogURL {
+ if (![self urlIsValid:userCatalogURL]) {
+ userCatalogURL = [self.serverURL stringByAppendingFormat:@"/%@", self.userCatalogResource];
+ }
+ return userCatalogURL;
+}
+
+- (void)setUserCatalogURL:(NSString *)aUserCatalogURL {
+ if (![self.userCatalogURL isEqualToString:aUserCatalogURL] && [self urlIsValid:aUserCatalogURL]) {
+ userCatalogURL = aUserCatalogURL;
+ }
+}
+
+- (NSMutableDictionary *)userCatalog {
+ if (!userCatalog) {
+ userCatalog = [NSMutableDictionary dictionary];
+ }
+ return userCatalog;
+}
+
- (ASIPithos *)pithos {
@synchronized(self) {
if (!pithos || updatePithos) {
pithos.storageURLPrefix = self.storageURLPrefix;
pithos.authURL = self.authURL;
pithos.publicURLPrefix = self.publicURLPrefix;
+ pithos.userCatalogURL = self.userCatalogURL;
updatePithos = NO;
}
}
- (PithosAccountNode *)accountNode {
if (!accountNode) {
- accountNode = [[PithosAccountNode alloc] initWithPithos:self.pithos];
+ accountNode = [[PithosAccountNode alloc] initWithPithosAccountManager:self andPithos:self.pithos];
accountNode.childrenUpdatedNotificationName = nil;
accountNode.inheritChildrenUpdatedNotificationName = YES;
}
- (PithosSharingAccountsNode *)sharingAccountsNode {
if (!sharingAccountsNode) {
- sharingAccountsNode = [[PithosSharingAccountsNode alloc] initWithPithos:self.pithos];
+ sharingAccountsNode = [[PithosSharingAccountsNode alloc] initWithPithosAccountManager:self andPithos:self.pithos];
sharingAccountsNode.childrenUpdatedNotificationName = nil;
sharingAccountsNode.inheritChildrenUpdatedNotificationName = YES;
}
self.syncActive = NO;
// XXX Show preferences with self as the selected account?
} else {
+ [self updateUserCatalogForForDisplaynames:nil UUIDs:[NSArray arrayWithObject:authUser]];
+
self.active = YES;
if (syncDaemon) {
self.syncDaemon.pithos = self.pithos;
}
}
+- (ASIPithosRequest *)updateUserCatalogForForDisplaynames:(NSArray *)displaynames UUIDs:(NSArray *)UUIDs {
+ ASIPithosRequest *userCatalogRequest = [ASIPithosRequest userCatalogRequestWithPithos:self.pithos
+ displaynames:displaynames
+ UUIDs:UUIDs];
+ [PithosUtilities startAndWaitForRequest:userCatalogRequest];
+ if (userCatalogRequest.error || ((userCatalogRequest.responseStatusCode != 200) && (userCatalogRequest.responseStatusCode != 404))) {
+ // Don't show alert on 404, since it can be a pre-UUID server.
+ [PithosUtilities httpRequestErrorAlertWithRequest:userCatalogRequest];
+ } else if (userCatalogRequest.responseStatusCode == 200) {
+ NSDictionary *catalogs = [userCatalogRequest catalogs];
+ NSDictionary *displaynameCatalog = [catalogs objectForKey:@"displayname_catalog"];
+ for (NSString *displayname in displaynameCatalog) {
+ [self.userCatalog setObject:displayname forKey:[displaynameCatalog objectForKey:displayname]];
+ }
+ if (UUIDs) {
+ NSDictionary *UUIDCatalog = [catalogs objectForKey:@"uuid_catalog"];
+ for (NSString *UUID in UUIDs) {
+ NSString *displayname = [UUIDCatalog objectForKey:UUID];
+ if (displayname) {
+ [self.userCatalog setObject:displayname forKey:UUID];
+ } else {
+ [self.userCatalog removeObjectForKey:UUID];
+ }
+ }
+ }
+ }
+ return userCatalogRequest;
+}
+
+- (NSString *)displaynameForUUID:(NSString *)UUID safe:(BOOL)safe {
+ NSString *displayName = [userCatalog objectForKey:UUID];
+ if (safe && !displayName) {
+ return UUID;
+ } else {
+ return displayName;
+ }
+}
+
+- (NSString *)displaynameForUUID:(NSString *)UUID {
+ return [self displaynameForUUID:UUID safe:NO];
+}
+
#pragma mark -
#pragma mark NSCoding
self.uniqueName = [decoder decodeObjectForKey:@"uniqueName"];
self.active = [decoder decodeBoolForKey:@"active"];
name = [decoder decodeObjectForKey:@"name"];
+ self.clientVersion = [decoder decodeObjectForKey:@"clientVersion"];
self.syncActive = [decoder decodeBoolForKey:@"syncActive"];
self.syncDirectoryPath = [decoder decodeObjectForKey:@"syncDirectoryPath"];
self.versionResource = [decoder decodeObjectForKey:@"versionResource"];
self.loginResource = [decoder decodeObjectForKey:@"loginResource"];
self.publicResource = [decoder decodeObjectForKey:@"publicResource"];
+ self.userCatalogResource = [decoder decodeObjectForKey:@"userCatalogResource"];
self.authUser = [decoder decodeObjectForKey:@"authUser"];
self.authToken = [decoder decodeObjectForKey:@"authToken"];
self.authURL = [decoder decodeObjectForKey:@"authURL"];
self.publicURLPrefix = [decoder decodeObjectForKey:@"publicURLPrefix"];
self.loginURLPrefix = [decoder decodeObjectForKey:@"loginURLPrefix"];
+ self.userCatalogURL = [decoder decodeObjectForKey:@"userCatalogURL"];
+ self.userCatalog = [decoder decodeObjectForKey:@"userCatalog"];
if (![authUser length] || ![authToken length] || ![self.storageURLPrefix length])
self.active = NO;
- resetSyncDaemonLocalState = NO;
+ NSString *currentVersion = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"];
+ if (!clientVersion || ![clientVersion isEqualToString:currentVersion]) {
+ resetSyncDaemonLocalState = YES;
+ self.clientVersion = currentVersion;
+ } else {
+ resetSyncDaemonLocalState = NO;
+ }
}
return self;
}
[encoder encodeObject:uniqueName forKey:@"uniqueName"];
[encoder encodeBool:active forKey:@"active"];
[encoder encodeObject:name forKey:@"name"];
+ [encoder encodeObject:clientVersion forKey:@"clientVersion"];
[encoder encodeBool:syncActive forKey:@"syncActive"];
[encoder encodeObject:syncDirectoryPath forKey:@"syncDirectoryPath"];
[encoder encodeObject:versionResource forKey:@"versionResource"];
[encoder encodeObject:publicResource forKey:@"publicResource"];
[encoder encodeObject:loginResource forKey:@"loginResource"];
+ [encoder encodeObject:loginResource forKey:@"userCatalogResource"];
[encoder encodeObject:authUser forKey:@"authUser"];
[encoder encodeObject:authToken forKey:@"authToken"];
[encoder encodeObject:authURL forKey:@"authURL"];
[encoder encodeObject:publicURLPrefix forKey:@"publicURLPrefix"];
[encoder encodeObject:loginURLPrefix forKey:@"loginURLPrefix"];
+ [encoder encodeObject:userCatalogURL forKey:@"userCatalogURL"];
+ [encoder encodeObject:userCatalog forKey:@"userCatalog"];
}
@end