Use user catalog displayname when displaying modified by
[pithos-macos] / pithos-macos / PithosSubdirNode.m
index c8175c7..46e52ce 100644 (file)
 #import "ASIPithosObject.h"
 #import "ASINetworkQueue.h"
 #import "ASIDownloadCache.h"
+#import "PithosAccount.h"
 #import "PithosUtilities.h"
 #import "PithosObjectNodeInfoController.h"
 
 static NSImage *sharedIcon = nil;
 
 @implementation PithosSubdirNode
-@synthesize pithosObject;
-@synthesize isPublic;
+@synthesize pithosObject, versions;
+@synthesize isPublic, translatedModifiedBy;
 
 + (void)initialize {
        if (self == [PithosSubdirNode class])
-        sharedIcon = [[[NSWorkspace sharedWorkspace] iconForFileType:NSFileTypeForHFSTypeCode(kGenericFolderIcon)] retain];
+        sharedIcon = [[NSWorkspace sharedWorkspace] iconForFileType:NSFileTypeForHFSTypeCode(kGenericFolderIcon)];
 }
 
 #pragma mark -
@@ -67,19 +68,36 @@ static NSImage *sharedIcon = nil;
         self.pithos = aPithos;
         self.pithosContainer = aPithosContainer;
         self.pithosObject = aPithosObject;
-        childrenUpdatedNotificationName = @"PithosSubdirNodeChildrenUpdated";
         refreshParent = NO;
     }
     return self;
 }
 
 - (void)dealloc {
+    [refreshVersionsObjectRequest clearDelegatesAndCancel];
     [refreshMetadataObjectRequest clearDelegatesAndCancel];
-    [refreshMetadataObjectRequest release];
     [applyMetadataObjectRequest clearDelegatesAndCancel];
-    [applyMetadataObjectRequest release];
-    [pithosObject release];
-    [super dealloc];
+}
+
+#pragma mark -
+#pragma mark Internal
+
+- (void)updateModifiedBy {
+    if (!pithosObject.modifiedBy) {
+        self.translatedModifiedBy = nil;
+    } else {
+        if (pithosAccountManager) {
+            NSString *displayname = [pithosAccountManager displaynameForUUID:pithosObject.modifiedBy safe:NO];
+            if (displayname) {
+                self.translatedModifiedBy = displayname;
+            } else {
+                [pithosAccountManager updateUserCatalogForForDisplaynames:nil UUIDs:[NSArray arrayWithObject:pithosObject.modifiedBy]];
+                self.translatedModifiedBy = [pithosAccountManager displaynameForUUID:pithosObject.modifiedBy safe:YES];
+            }
+        } else {
+            self.translatedModifiedBy = [pithosObject.modifiedBy copy];
+        }
+    }
 }
 
 #pragma mark -
@@ -87,9 +105,7 @@ static NSImage *sharedIcon = nil;
 
 - (void)setPithos:(ASIPithos *)aPithos {
     if (aPithos && ![aPithos isEqualTo:pithos]) {
-        [pithos release];
-        pithos = [aPithos retain];
-        [url release];
+        pithos = aPithos;
         url = nil;
     }
 }
@@ -109,9 +125,8 @@ static NSImage *sharedIcon = nil;
         displayName = [pithosObject.name lastPathComponent];
         if (!pithosObject.subdir && [pithosObject.name hasSuffix:@"/"])
             displayName = [displayName stringByAppendingString:@"/"];
-        [displayName retain];
     } 
-    return [[displayName copy] autorelease];
+    return [displayName copy];
 }
 
 - (void)setDisplayName:(NSString *)aDisplayName {    
@@ -119,20 +134,20 @@ static NSImage *sharedIcon = nil;
 
 - (NSImage *)icon {
     if (icon == nil)
-        icon = [sharedIcon retain];
+        icon = sharedIcon;
     return icon;
 }
 
 - (void)setPithosObject:(ASIPithosObject *)aPithosObject {
     if (![pithosObject isEqualTo:aPithosObject]) {
-        [pithosObject release];
-        pithosObject = [aPithosObject retain];
+        pithosObject = aPithosObject;
     }
     if (pithosObject.subdir) {
         self.prefix = [pithosObject.name substringToIndex:([pithosObject.name length] - 1)];
     } else {
         self.prefix = [NSString stringWithString:pithosObject.name];
     }
+    [self updateModifiedBy];
     self.isPublic = (pithosObject.publicURI != nil);
     // Refresh browser if the object is in my shared and is no longer shared
     if (shared && !pithosObject.subdir && !pithosObject.sharing) {
@@ -140,79 +155,109 @@ static NSImage *sharedIcon = nil;
     }
 }
 
-#pragma mark -
-#pragma mark ASIHTTPRequestDelegate
-
-- (void)objectRequestFinished:(ASIPithosObjectRequest *)request {
-    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-    NSLog(@"URL: %@", [request url]);
-    NSLog(@"cached: %d", [request didUseCachedResponse]);
-    
-    if ([request isEqualTo:applyMetadataObjectRequest]) {
-        int responseStatusCode = applyMetadataObjectRequest.responseStatusCode;
-        if ((responseStatusCode != 201) && (responseStatusCode != 202))
-            [PithosUtilities unexpectedResponseStatusAlertWithRequest:applyMetadataObjectRequest];
-        @synchronized(self) {
-            [applyMetadataObjectRequest release];
-            applyMetadataObjectRequest = nil;
-        }
-        if ((responseStatusCode == 201) || (responseStatusCode == 202))
-            [self refreshInfo];
-    } else if ([request isEqualTo:refreshMetadataObjectRequest]) {
-        [[pithosNodeInfoController window] makeFirstResponder:nil];
-        self.pithosObject = [refreshMetadataObjectRequest object];
-        if (refreshParent) {
-            // Ask the parent for refresh for the case where an object was removed
-            // It is done here so that it doesn't affect the info window refresh
-            [parent refresh];
-            refreshParent = NO;
-        }
-        @synchronized(self) {
-            [refreshMetadataObjectRequest release];
-            refreshMetadataObjectRequest = nil;
+- (void)setLimitedPithosObject:(ASIPithosObject *)aPithosObject {
+    if (![pithosObject isEqualTo:aPithosObject]) {
+        self.pithosObject.subdir = aPithosObject.subdir;
+        self.pithosObject.name = aPithosObject.name;
+        self.pithosObject.hash = aPithosObject.hash;
+        self.pithosObject.objectHash = aPithosObject.objectHash;
+        self.pithosObject.UUID = aPithosObject.UUID;
+        self.pithosObject.bytes = aPithosObject.bytes;
+        self.pithosObject.contentType = aPithosObject.contentType;
+        self.pithosObject.lastModified = aPithosObject.lastModified;
+        self.pithosObject.version = aPithosObject.version;
+        self.pithosObject.versionTimestamp = aPithosObject.versionTimestamp;
+        self.pithosObject.modifiedBy = aPithosObject.modifiedBy;
+        self.pithosObject.sharedBy = aPithosObject.sharedBy;
+        self.pithosObject.allowedTo = aPithosObject.allowedTo;
+        if (!pithosNodeInfoController) {
+            self.pithosObject.sharing = aPithosObject.sharing;
+            self.pithosObject.publicURI = aPithosObject.publicURI;
+            self.pithosObject = pithosObject;
+        } else {
+            [self updateModifiedBy];
         }
     }
-    [pool drain];
 }
 
-- (void)objectRequestFailed:(ASIPithosObjectRequest *)request {
-    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-    NSUInteger retries = [[request.userInfo objectForKey:@"retries"] unsignedIntegerValue];
-    if (retries > 0) {
-        ASIPithosObjectRequest *newRequest = (ASIPithosObjectRequest *)[PithosUtilities copyRequest:request];
-        [(NSMutableDictionary *)(newRequest.userInfo)setObject:[NSNumber numberWithUnsignedInteger:(--retries)] forKey:@"retries"];
+#pragma mark -
+#pragma mark ASIHTTPRequestDelegate
+
+- (void)objectRequestFinished:(ASIPithosObjectRequest *)request {
+    @autoreleasepool {
+        DLog(@"URL: %@", [request url]);
+        DLog(@"cached: %d", [request didUseCachedResponse]);
+        
         if ([request isEqualTo:applyMetadataObjectRequest]) {
+            int responseStatusCode = applyMetadataObjectRequest.responseStatusCode;
+            if ((responseStatusCode != 201) && (responseStatusCode != 202))
+                [PithosUtilities unexpectedResponseStatusAlertWithRequest:applyMetadataObjectRequest];
             @synchronized(self) {
-                [applyMetadataObjectRequest release];
-                applyMetadataObjectRequest = newRequest;
+                applyMetadataObjectRequest = nil;
             }
+            if ((responseStatusCode == 201) || (responseStatusCode == 202))
+                [self refreshInfo];
         } else if ([request isEqualTo:refreshMetadataObjectRequest]) {
+            [[pithosNodeInfoController window] makeFirstResponder:nil];
+            self.pithosObject = [refreshMetadataObjectRequest object];
+            if (refreshParent) {
+                // Ask the parent for refresh for the case where an object was removed
+                // It is done here so that it doesn't affect the info window refresh
+                [parent refresh];
+                refreshParent = NO;
+            }
             @synchronized(self) {
-                [refreshMetadataObjectRequest release];
-                refreshMetadataObjectRequest = newRequest;
+                refreshMetadataObjectRequest = nil;
             }
-        }
-        [[PithosUtilities prepareRequest:newRequest priority:[[newRequest.userInfo objectForKey:@"priority"] integerValue]] startAsynchronous];
-    } else {
-        if ([request isEqualTo:applyMetadataObjectRequest]) {
-            dispatch_async(dispatch_get_main_queue(), ^{
-                [PithosUtilities httpRequestErrorAlertWithRequest:applyMetadataObjectRequest];
-            });
+        } else if ([request isEqualTo:refreshVersionsObjectRequest]) {
+            [[pithosNodeInfoController window] makeFirstResponder:nil];
+            self.versions = [refreshVersionsObjectRequest versions];
             @synchronized(self) {
-                [applyMetadataObjectRequest release];
-                applyMetadataObjectRequest = nil;
+                refreshVersionsObjectRequest = nil;
             }
-        } else if ([request isEqualTo:refreshMetadataObjectRequest]) {
-            dispatch_async(dispatch_get_main_queue(), ^{
+        }
+    }
+}
+
+- (void)objectRequestFailed:(ASIPithosObjectRequest *)request {
+    @autoreleasepool {
+        NSUInteger retries = [[request.userInfo objectForKey:@"retries"] unsignedIntegerValue];
+        if (retries > 0) {
+            ASIPithosObjectRequest *newRequest = (ASIPithosObjectRequest *)[PithosUtilities copyRequest:request];
+            [(NSMutableDictionary *)(newRequest.userInfo)setObject:[NSNumber numberWithUnsignedInteger:(--retries)] forKey:@"retries"];
+            if ([request isEqualTo:applyMetadataObjectRequest]) {
+                @synchronized(self) {
+                    applyMetadataObjectRequest = newRequest;
+                }
+            } else if ([request isEqualTo:refreshMetadataObjectRequest]) {
+                @synchronized(self) {
+                    refreshMetadataObjectRequest = newRequest;
+                }
+            } else if ([request isEqualTo:refreshVersionsObjectRequest]) {
+                @synchronized(self) {
+                    refreshVersionsObjectRequest = newRequest;
+                }
+            }
+            [[PithosUtilities prepareRequest:newRequest priority:[[newRequest.userInfo objectForKey:@"priority"] integerValue]] startAsynchronous];
+        } else {
+            if ([request isEqualTo:applyMetadataObjectRequest]) {
+                [PithosUtilities httpRequestErrorAlertWithRequest:applyMetadataObjectRequest];
+                @synchronized(self) {
+                    applyMetadataObjectRequest = nil;
+                }
+            } else if ([request isEqualTo:refreshMetadataObjectRequest]) {
                 [PithosUtilities httpRequestErrorAlertWithRequest:refreshMetadataObjectRequest];
-            });
-            @synchronized(self) {
-                [refreshMetadataObjectRequest release];
-                refreshMetadataObjectRequest = nil;
+                @synchronized(self) {
+                    refreshMetadataObjectRequest = nil;
+                }
+            } else if ([request isEqualTo:refreshVersionsObjectRequest]) {
+                [PithosUtilities httpRequestErrorAlertWithRequest:refreshVersionsObjectRequest];
+                @synchronized(self) {
+                    refreshVersionsObjectRequest = nil;
+                }
             }
         }
     }
-    [pool drain];
 }
 
 #pragma mark -
@@ -227,18 +272,16 @@ static NSImage *sharedIcon = nil;
                 ASIPithosObjectRequest *request = [ASIPithosObjectRequest objectMetadataRequestWithPithos:pithos 
                                                                                             containerName:pithosContainer.name 
                                                                                                objectName:prefix];
-                ASINetworkQueue *networkQueue = [ASINetworkQueue queue];
-                [networkQueue go];
-                [networkQueue addOperations:[NSArray arrayWithObject:[PithosUtilities prepareRequest:request]] waitUntilFinished:YES];
+                [PithosUtilities startAndWaitForRequest:request];
                 if ([request error]) {
-                    alert = [[[NSAlert alloc] init] autorelease];
+                    alert = [[NSAlert alloc] init];
                     [alert setMessageText:@"HTTP Request Error"];
-                    [alert setInformativeText:[NSString stringWithFormat:@"An error occured: %@", [request error]]];
+                    [alert setInformativeText:[NSString stringWithFormat:@"An error occured: %@", [[request error] localizedDescription]]];
                     [alert addButtonWithTitle:@"OK"];
                     [alert runModal];
                     return;
                 } else if (request.responseStatusCode == 200) {
-                    alert = [[[NSAlert alloc] init] autorelease];
+                    alert = [[NSAlert alloc] init];
                     [alert setMessageText:@"Apply changes"];
                     [alert setInformativeText:[NSString stringWithFormat:@"In order to apply the changes in '%@', the object at the same path must be replaced. Continue?", self.displayName]];
                     [alert addButtonWithTitle:@"OK"];
@@ -248,13 +291,11 @@ static NSImage *sharedIcon = nil;
                         request = [ASIPithosObjectRequest deleteObjectRequestWithPithos:pithos 
                                                                           containerName:pithosContainer.name 
                                                                              objectName:prefix];
-                        ASINetworkQueue *networkQueue = [ASINetworkQueue queue];
-                        [networkQueue go];
-                        [networkQueue addOperations:[NSArray arrayWithObject:[PithosUtilities prepareRequest:request]] waitUntilFinished:YES];
+                        [PithosUtilities startAndWaitForRequest:request];
                         if ([request error]) {
-                            alert = [[[NSAlert alloc] init] autorelease];
+                            alert = [[NSAlert alloc] init];
                             [alert setMessageText:@"HTTP Request Error"];
-                            [alert setInformativeText:[NSString stringWithFormat:@"An error occured: %@", [request error]]];
+                            [alert setInformativeText:[NSString stringWithFormat:@"An error occured: %@", [[request error] localizedDescription]]];
                             [alert addButtonWithTitle:@"OK"];
                             [alert runModal];
                             return;
@@ -275,7 +316,7 @@ static NSImage *sharedIcon = nil;
                 }
                 if (createObject) {
                     [[pithosNodeInfoController window] makeFirstResponder:nil];
-                    applyMetadataObjectRequest = [[ASIPithosObjectRequest writeObjectDataRequestWithPithos:pithos 
+                    applyMetadataObjectRequest = [ASIPithosObjectRequest writeObjectDataRequestWithPithos:pithos 
                                                                                              containerName:pithosContainer.name 
                                                                                                 objectName:prefix 
                                                                                                       eTag:nil
@@ -286,7 +327,7 @@ static NSImage *sharedIcon = nil;
                                                                                                    sharing:pithosObject.sharing 
                                                                                                   isPublic:(isPublic ? ASIPithosObjectRequestPublicTrue : ASIPithosObjectRequestPublicFalse) 
                                                                                                   metadata:pithosObject.metadata 
-                                                                                                      data:[NSData data]] retain];
+                                                                                                      data:[NSData data]];
                     pithosObject.subdir = NO;
                     applyMetadataObjectRequest.delegate = self;
                     applyMetadataObjectRequest.didFinishSelector = @selector(performRequestFinishedDelegateInBackground:);
@@ -302,7 +343,7 @@ static NSImage *sharedIcon = nil;
             } else {
                 [[pithosNodeInfoController window] makeFirstResponder:nil];
                 if (sharingAccount) {
-                    applyMetadataObjectRequest = [[ASIPithosObjectRequest updateObjectMetadataRequestWithPithos:pithos 
+                    applyMetadataObjectRequest = [ASIPithosObjectRequest updateObjectMetadataRequestWithPithos:pithos 
                                                                                                   containerName:pithosContainer.name 
                                                                                                      objectName:pithosObject.name 
                                                                                                 contentEncoding:nil
@@ -311,10 +352,10 @@ static NSImage *sharedIcon = nil;
                                                                                                         sharing:nil 
                                                                                                        isPublic:(isPublic ? ASIPithosObjectRequestPublicTrue : ASIPithosObjectRequestPublicFalse) 
                                                                                                        metadata:pithosObject.metadata
-                                                                                                         update:NO] retain];
+                                                                                                         update:NO];
                     [applyMetadataObjectRequest setRequestUserFromDefaultTo:sharingAccount withPithos:pithos];
                 } else {
-                    applyMetadataObjectRequest = [[ASIPithosObjectRequest updateObjectMetadataRequestWithPithos:pithos 
+                    applyMetadataObjectRequest = [ASIPithosObjectRequest updateObjectMetadataRequestWithPithos:pithos 
                                                                                                   containerName:pithosContainer.name 
                                                                                                      objectName:pithosObject.name 
                                                                                                 contentEncoding:pithosObject.contentEncoding
@@ -323,7 +364,7 @@ static NSImage *sharedIcon = nil;
                                                                                                         sharing:(pithosObject.sharing ? pithosObject.sharing : @"") 
                                                                                                        isPublic:(isPublic ? ASIPithosObjectRequestPublicTrue : ASIPithosObjectRequestPublicFalse) 
                                                                                                        metadata:pithosObject.metadata
-                                                                                                         update:NO] retain];
+                                                                                                         update:NO];
                 }
                 applyMetadataObjectRequest.delegate = self;
                 applyMetadataObjectRequest.didFinishSelector = @selector(performRequestFinishedDelegateInBackground:);
@@ -344,10 +385,11 @@ static NSImage *sharedIcon = nil;
     @synchronized(self) {
         if (pithosObject.subdir) {
             self.pithosObject = [ASIPithosObject subdirWithName:pithosObject.name];
+            return;
         } else if (refreshMetadataObjectRequest == nil) {
-            refreshMetadataObjectRequest = [[ASIPithosObjectRequest objectMetadataRequestWithPithos:pithos 
+            refreshMetadataObjectRequest = [ASIPithosObjectRequest objectMetadataRequestWithPithos:pithos 
                                                                                       containerName:pithosContainer.name 
-                                                                                         objectName:prefix] retain];
+                                                                                         objectName:prefix];
             if (sharingAccount)
                 [refreshMetadataObjectRequest setRequestUserFromDefaultTo:sharingAccount withPithos:pithos];
             refreshMetadataObjectRequest.delegate = self;
@@ -359,18 +401,51 @@ static NSImage *sharedIcon = nil;
                                                      NSStringFromSelector(@selector(objectRequestFinished:)), @"didFinishSelector", 
                                                      NSStringFromSelector(@selector(objectRequestFailed:)), @"didFailSelector", 
                                                      nil];
-            refreshMetadataObjectRequest.downloadCache = [ASIDownloadCache sharedCache];
+            if (!sharingAccount)
+                refreshMetadataObjectRequest.downloadCache = [ASIDownloadCache sharedCache];
             [[PithosUtilities prepareRequest:refreshMetadataObjectRequest priority:NSOperationQueuePriorityHigh] startAsynchronous];
         }
     }
+    [self refreshVersions];
+}
+
+#pragma mark -
+#pragma mark Versions
+
+- (void)refreshVersions {
+    @synchronized(self) {
+        if (pithosObject.subdir) {
+            return;
+        } else if (refreshVersionsObjectRequest == nil) {
+            refreshVersionsObjectRequest = [ASIPithosObjectRequest objectVersionsRequestWithPithos:pithos 
+                                                                                      containerName:pithosContainer.name 
+                                                                                         objectName:pithosObject.name];
+            if (sharingAccount)
+                [refreshVersionsObjectRequest setRequestUserFromDefaultTo:sharingAccount withPithos:pithos];
+            refreshVersionsObjectRequest.delegate = self;
+            refreshVersionsObjectRequest.didFinishSelector = @selector(performRequestFinishedDelegateInBackground:);
+            refreshVersionsObjectRequest.didFailSelector = @selector(performRequestFailedDelegateInBackground:);
+            refreshVersionsObjectRequest.userInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
+                                                     [NSNumber numberWithInteger:NSOperationQueuePriorityHigh], @"priority", 
+                                                     [NSNumber numberWithUnsignedInteger:10], @"retries", 
+                                                     NSStringFromSelector(@selector(objectRequestFinished:)), @"didFinishSelector", 
+                                                     NSStringFromSelector(@selector(objectRequestFailed:)), @"didFailSelector", 
+                                                     nil];
+            if (!sharingAccount)
+                refreshVersionsObjectRequest.downloadCache = [ASIDownloadCache sharedCache];
+            [[PithosUtilities prepareRequest:refreshVersionsObjectRequest priority:NSOperationQueuePriorityHigh] startAsynchronous];
+        }
+    }
 }
 
 #pragma mark -
 #pragma mark Actions
 
 - (void)showPithosNodeInfo:(id)sender {
-    if (!pithosNodeInfoController)
+    if (!pithosNodeInfoController) {
         pithosNodeInfoController = [[PithosObjectNodeInfoController alloc] initWithPithosNode:self];
+        [self refreshInfo];
+    }
     [pithosNodeInfoController showWindow:sender];
     [[pithosNodeInfoController window] makeKeyAndOrderFront:sender];
     [NSApp activateIgnoringOtherApps:YES];