Reset sync daemon local state if the client version has changed
[pithos-macos] / pithos-macos / PithosAccount.m
index b271ce0..fe5ca8d 100644 (file)
@@ -41,6 +41,7 @@
 #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;
 }
     }
 }
 
+- (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;
         }
     }
         accountNode = [[PithosAccountNode alloc] initWithPithos:self.pithos];
         accountNode.childrenUpdatedNotificationName = nil;
         accountNode.inheritChildrenUpdatedNotificationName = YES;
+        accountNode.pithosAccountManager = self;
     }
     return accountNode;
 }
         sharingAccountsNode = [[PithosSharingAccountsNode alloc] initWithPithos:self.pithos];
         sharingAccountsNode.childrenUpdatedNotificationName = nil;
         sharingAccountsNode.inheritChildrenUpdatedNotificationName = YES;
+        sharingAccountsNode.pithosAccountManager = self;
     }
     return sharingAccountsNode;
 }
         }
         if (sharingAccountsNode && self.sharingAccountsNode.children) {
         }
+        
+        [self updateUserCatalogForForDisplaynames:nil UUIDs:[NSArray arrayWithObject:authUser]];
     }
 }
 
     }    
 }
 
+- (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