//
-// PithosNode.m
+// PithosContainerNode.m
// pithos-macos
//
-// Copyright 2011 GRNET S.A. All rights reserved.
+// Copyright 2011-2012 GRNET S.A. All rights reserved.
//
// Redistribution and use in source and binary forms, with or
// without modification, are permitted provided that the following
#import "PithosContainerNode.h"
#import "PithosObjectNode.h"
#import "PithosSubdirNode.h"
+#import "ASIPithos.h"
#import "ASIPithosContainerRequest.h"
+#import "ASIPithosContainer.h"
#import "ASIPithosObject.h"
#import "ASIDownloadCache.h"
+#import "PithosUtilities.h"
+#import "PithosContainerNodeInfoController.h"
+#import "PithosActivityFacility.h"
-static NSImage *classIcon = nil;
+static NSImage *sharedIcon = nil;
@implementation PithosContainerNode
+@synthesize pithos, pithosContainer, prefix;
+@synthesize policyVersioning, policyQuota;
+ (void)initialize {
if (self == [PithosContainerNode class])
- classIcon = [[NSImage imageNamed:@"container"] retain];
+ sharedIcon = [[NSWorkspace sharedWorkspace] iconForFileType:NSFileTypeForHFSTypeCode(kGenericHardDiskIcon)];
}
#pragma mark -
#pragma mark Object Lifecycle
-- (id)initWithPithosContainer:(ASIPithosContainer *)aPithosContainer icon:(NSImage *)anIcon {
+- (id)initWithPithos:(ASIPithos *)aPithos pithosContainer:(ASIPithosContainer *)aPithosContainer icon:(NSImage *)anIcon {
if ((self = [super init])) {
- pithosContainer = [aPithosContainer retain];
- refreshing = NO;
+ self.pithos = aPithos;
+ self.pithosContainer = aPithosContainer;
prefix = nil;
-
- icon = [anIcon retain];
+ self.icon = anIcon;
}
return self;
}
-- (id)initWithPithosContainer:(ASIPithosContainer *)aPithosContainer {
- return [self initWithPithosContainer:aPithosContainer icon:nil];
+- (id)initWithPithos:(ASIPithos *)aPithos pithosContainer:(ASIPithosContainer *)aPithosContainer {
+ return [self initWithPithos:aPithos pithosContainer:aPithosContainer icon:nil];
}
-- (id)initWithContainerName:(NSString *)aContainerName icon:(NSImage *)anIcon {
+- (id)initWithPithos:(ASIPithos *)aPithos containerName:(NSString *)aContainerName icon:(NSImage *)anIcon {
ASIPithosContainer *container = [ASIPithosContainer container];
container.name = aContainerName;
- return [self initWithPithosContainer:container icon:anIcon];
+ return [self initWithPithos:aPithos pithosContainer:container icon:anIcon];
}
-- (id)initWithContainerName:(NSString *)aContainerName {
- return [self initWithContainerName:aContainerName icon:nil];
+- (id)initWithPithos:(ASIPithos *)aPithos containerName:(NSString *)aContainerName {
+ return [self initWithPithos:aPithos containerName:aContainerName icon:nil];
}
- (void)dealloc {
- [prefix release];
- [objects release];
- [pithosContainer release];
- [super dealloc];
+ [containerRequest clearDelegatesAndCancel];
+ [refreshMetadataContainerRequest clearDelegatesAndCancel];
+ [applyMetadataContainerRequest clearDelegatesAndCancel];
}
#pragma mark -
-#pragma mark ASIHTTPRequestDelegate
-
-- (void)requestFinished:(ASIPithosContainerRequest *)containerRequest {
- NSLog(@"URL: %@", [containerRequest url]);
- NSLog(@"cached: %d", [containerRequest didUseCachedResponse]);
+#pragma mark Properties
- NSArray *someObjects = [containerRequest objects];
- if (objects == nil) {
- objects = [[NSMutableArray alloc] initWithArray:someObjects];
- } else {
- [objects addObjectsFromArray:someObjects];
+- (void)setPithos:(ASIPithos *)aPithos {
+ if (aPithos && ![aPithos isEqualTo:pithos]) {
+ pithos = aPithos;
+ url = nil;
}
- if ([someObjects count] < 10000) {
- if (!containerRequest.didUseCachedResponse || ([objects count] != [someObjects count]) || !children) {
- // Save new children
- NSLog(@"using newChildren");
- NSMutableArray *newChildren = [NSMutableArray array];
- for (ASIPithosObject *object in objects) {
- if (object.subdir) {
- PithosSubdirNode *node = [[[PithosSubdirNode alloc] initWithPithosContainer:pithosContainer pithosObject:object] autorelease];
- if (children) {
- NSUInteger oldIndex = [children indexOfObject:node];
- if (oldIndex != NSNotFound)
- // Use the same pointer value, if possible
- node = [children objectAtIndex:oldIndex];
- }
- [newChildren addObject:node];
- } else {
- PithosObjectNode *node = [[[PithosObjectNode alloc] initWithPithosContainer:pithosContainer pithosObject:object] autorelease];
- if (children) {
- NSUInteger oldIndex = [children indexOfObject:node];
- if (oldIndex != NSNotFound)
- // Use the same pointer value, if possible
- node = [children objectAtIndex:oldIndex];
- }
- [newChildren addObject:node];
+}
+
+- (NSString *)url {
+ if (url == nil)
+ url = [[NSString alloc] initWithFormat:@"%@/%@%@",
+ (sharingAccount ? [pithos storageURLWithAuthUser:sharingAccount] : pithos.storageURL),
+ pithosContainer.name,
+ (shared ? @"?shared" : @"")];
+ return url;
+}
+
+- (NSArray *)children {
+ @synchronized(self) {
+ switch (freshness) {
+ case PithosNodeStateFresh:
+ break;
+ case PithosNodeStateRefreshNeeded:
+ freshness = PithosNodeStateRefreshing;
+ containerRequest = [ASIPithosContainerRequest listObjectsRequestWithPithos:pithos
+ containerName:pithosContainer.name
+ limit:0
+ marker:nil
+ prefix:prefix
+ delimiter:@"/"
+ path:nil
+ meta:nil
+ shared:shared
+ until:nil];
+ if (sharingAccount)
+ [containerRequest setRequestUserFromDefaultTo:sharingAccount withPithos:pithos];
+ else if (!forcedRefresh)
+ containerRequest.downloadCache = [ASIDownloadCache sharedCache];
+ containerRequest.delegate = self;
+ containerRequest.didFinishSelector = @selector(performRequestFinishedDelegateInBackground:);
+ containerRequest.didFailSelector = @selector(performRequestFailedDelegateInBackground:);
+ containerRequest.userInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
+ [NSNumber numberWithInteger:NSOperationQueuePriorityVeryHigh], @"priority",
+ [NSNumber numberWithUnsignedInteger:10], @"retries",
+ NSStringFromSelector(@selector(containerRequestFinished:)), @"didFinishSelector",
+ NSStringFromSelector(@selector(containerRequestFailed:)), @"didFailSelector",
+ nil];
+ [[PithosUtilities prepareRequest:containerRequest priority:NSOperationQueuePriorityVeryHigh] startAsynchronous];
+ break;
+ case PithosNodeStateRefreshing:
+ break;
+ case PithosNodeStateRefreshFinished:
+ if (newChildren) {
+ children = newChildren;
+ newChildren = nil;
}
- }
- [children release];
- children = [newChildren retain];
+ freshness = PithosNodeStateFresh;
+ default:
+ break;
}
- // Else cache was used and all results were fetched during this request, so previousChildren can be reused
- [objects release];
- objects = nil;
- // XXX sort then based on preferences
- refreshing = NO;
- // Notify observers that children are updated
- [[NSNotificationCenter defaultCenter] postNotificationName:@"PithosNodeChildrenUpdated" object:self];
+ return children;
+ }
+}
+
+- (NSString *)displayName {
+ return [pithosContainer.name copy];
+}
+
+- (void)setDisplayName:(NSString *)aDisplayName {
+}
+
+- (NSImage *)icon {
+ if (icon == nil) {
+ if ([pithosContainer.name isEqualToString:@"pithos"])
+ icon = [[NSWorkspace sharedWorkspace] iconForFileType:NSFileTypeForHFSTypeCode(kToolbarHomeIcon)];
+ else if ([pithosContainer.name isEqualToString:@"trash"])
+ icon = [[NSWorkspace sharedWorkspace] iconForFileType:NSFileTypeForHFSTypeCode(kFullTrashIcon)];
+ else
+ icon = sharedIcon;
+ }
+ return icon;
+}
+
+- (void)setPithosContainer:(ASIPithosContainer *)aPithosContainer {
+ if (![pithosContainer isEqualTo:aPithosContainer]) {
+ pithosContainer = aPithosContainer;
+ }
+ if (pithosContainer.policy) {
+ self.policyVersioning = [pithosContainer.policy objectForKey:@"versioning"];
+ self.policyQuota = [NSNumber numberWithLongLong:[[pithosContainer.policy objectForKey:@"quota"] longLongValue]];
} else {
- // Do an additional request to fetch more objects
- ASIPithosContainerRequest *newContainerRequest = [ASIPithosContainerRequest listObjectsRequestWithContainerName:pithosContainer.name
- limit:0
- marker:[[someObjects lastObject] name]
- prefix:prefix
- delimiter:@"/"
- path:nil
- meta:nil
- shared:NO
- until:nil];
- newContainerRequest.delegate = self;
- newContainerRequest.downloadCache = [ASIDownloadCache sharedCache];
- [newContainerRequest startAsynchronous];
+ self.policyVersioning = @"manual";
+ self.policyQuota = [NSNumber numberWithLongLong:0];
}
}
-- (void)requestFailed:(ASIPithosContainerRequest *)containerRequest {
- // XXX do something on error, cleanup
- NSLog(@"error:%@", [containerRequest error]);
- [objects release];
- objects = nil;
- childrenDirty = YES;
- refreshing = NO;
+- (void)setLimitedPithosContainer:(ASIPithosContainer *)aPithosContainer {
+ if (![pithosContainer isEqualTo:aPithosContainer]) {
+ self.pithosContainer.name = aPithosContainer.name;
+ self.pithosContainer.count = aPithosContainer.count;
+ self.pithosContainer.bytes = aPithosContainer.bytes;
+ self.pithosContainer.lastModified = aPithosContainer.lastModified;
+ self.pithosContainer.untilTimestamp = aPithosContainer.untilTimestamp;
+ if (!pithosNodeInfoController) {
+ self.pithosContainer.policy = aPithosContainer.policy;
+ self.pithosContainer = pithosContainer;
+ }
+ }
}
#pragma mark -
-#pragma mark Properties
+#pragma mark ASIHTTPRequestDelegate
-- (NSString *)url {
- if (url == nil)
- url = [[NSString alloc] initWithFormat:@"%@/%@", [ASIPithosRequest storageURL], pithosContainer.name];
- return url;
+- (void)containerRequestFailed:(ASIPithosContainerRequest *)request {
+ @autoreleasepool {
+ NSString *message;
+ NSError *error = [containerRequest error];
+ if (error)
+ message = [NSString stringWithFormat:@"Container listing %@ failed: %@", containerRequest.url, [error localizedDescription]];
+ else
+ message = [NSString stringWithFormat:@"Container listing %@ failed: (%d) %@",
+ containerRequest.url, containerRequest.responseStatusCode, containerRequest.responseStatusMessage];
+ dispatch_async(dispatch_get_main_queue(), ^{
+ [[PithosActivityFacility defaultPithosActivityFacility] startAndEndActivityWithType:PithosActivityOther message:message];
+ });
+ NSUInteger retries = [[containerRequest.userInfo objectForKey:@"retries"] unsignedIntegerValue];
+ if (retries > 0) {
+ ASIPithosContainerRequest *newContainerRequest = (ASIPithosContainerRequest *)[PithosUtilities copyRequest:containerRequest];
+ [(NSMutableDictionary *)(newContainerRequest.userInfo)setObject:[NSNumber numberWithUnsignedInteger:(--retries)] forKey:@"retries"];
+ containerRequest = newContainerRequest;
+ [[PithosUtilities prepareRequest:containerRequest priority:[[containerRequest.userInfo objectForKey:@"priority"] integerValue]] startAsynchronous];
+ } else {
+ newChildren = nil;
+ containerRequest = nil;
+ objects = nil;
+ forcedRefresh = NO;
+ @synchronized(self) {
+ freshness = PithosNodeStateRefreshNeeded;
+ }
+ }
+ }
}
-- (NSArray *)children {
- if (childrenDirty) {
- @synchronized (self) {
- if (!refreshing) {
- refreshing = YES;
- childrenDirty = NO;
- ASIPithosContainerRequest *containerRequest = [ASIPithosContainerRequest listObjectsRequestWithContainerName:pithosContainer.name
- limit:0
- marker:nil
- prefix:prefix
- delimiter:@"/"
- path:nil
- meta:nil
- shared:NO
- until:nil];
+- (void)containerRequestFinished:(ASIPithosContainerRequest *)request {
+ @autoreleasepool {
+ DLog(@"List container finished: %@", [containerRequest url]);
+ DLog(@"Cached: %d", [containerRequest didUseCachedResponse]);
+ if (containerRequest.responseStatusCode == 200) {
+ if ((pithosContainer.blockHash == nil) || (pithosContainer.blockSize == 0)) {
+ pithosContainer.blockHash = [containerRequest blockHash];
+ pithosContainer.blockSize = [containerRequest blockSize];
+ }
+
+ NSArray *someObjects = [containerRequest objects];
+ if (objects == nil) {
+ objects = [[NSMutableArray alloc] initWithArray:someObjects];
+ } else {
+ [objects addObjectsFromArray:someObjects];
+ }
+ if ([someObjects count] < 10000) {
+ if (!containerRequest.didUseCachedResponse || ([objects count] != [someObjects count]) || !children) {
+ // Save new children
+ DLog(@"using newChildren");
+ newChildren = [[NSMutableArray alloc] init];
+ NSArray *objectNames = [objects valueForKey:@"name"];
+ NSMutableIndexSet *keptNodes = [NSMutableIndexSet indexSet];
+ BOOL isSubdirNode = ([self class] == [PithosSubdirNode class]);
+ for (ASIPithosObject *object in objects) {
+ if (!isSubdirNode ||
+ ([object.name hasPrefix:[((PithosSubdirNode *)self).prefix stringByAppendingString:@"/"]] &&
+ ([object.name length] > [((PithosSubdirNode *)self).prefix length] + 1))) {
+ // The check above removes false objects due to trailing slash or same prefix
+ if (object.subdir) {
+ NSUInteger sameNameObjectIndex = [objectNames indexOfObject:[object.name substringToIndex:([object.name length] - 1)]];
+ if ((sameNameObjectIndex == NSNotFound) ||
+ ![PithosUtilities isContentTypeDirectory:[[objects objectAtIndex:sameNameObjectIndex] contentType]]) {
+ PithosSubdirNode *node = [[PithosSubdirNode alloc] initWithPithos:pithos
+ pithosContainer:pithosContainer
+ pithosObject:object];
+ node.parent = self;
+ node.shared = shared;
+ node.sharingAccount = sharingAccount;
+ node.inheritChildrenUpdatedNotificationName = inheritChildrenUpdatedNotificationName;
+ node.pithosAccountManager = pithosAccountManager;
+ if (children) {
+ NSUInteger oldIndex = [children indexOfObject:node];
+ if (oldIndex != NSNotFound) {
+ // Use the same pointer value, if possible
+ node = [children objectAtIndex:oldIndex];
+ node.pithosContainer = pithosContainer;
+// node.pithosObject = object;
+ [node setLimitedPithosObject:object];
+ [keptNodes addIndex:oldIndex];
+ }
+ }
+ if (sharingAccount)
+ node.pithosObject.allowedTo = @"read";
+ [newChildren addObject:node];
+ }
+ } else if ([PithosUtilities isContentTypeDirectory:object.contentType]) {
+ PithosSubdirNode *node = [[PithosSubdirNode alloc] initWithPithos:pithos
+ pithosContainer:pithosContainer
+ pithosObject:object];
+ node.parent = self;
+ node.shared = shared;
+ node.sharingAccount = sharingAccount;
+ node.inheritChildrenUpdatedNotificationName = inheritChildrenUpdatedNotificationName;
+ node.pithosAccountManager = pithosAccountManager;
+ if (children) {
+ NSUInteger oldIndex = [children indexOfObject:node];
+ if (oldIndex != NSNotFound) {
+ // Use the same pointer value, if possible
+ node = [children objectAtIndex:oldIndex];
+ node.pithosContainer = pithosContainer;
+// node.pithosObject = object;
+ [node setLimitedPithosObject:object];
+ [keptNodes addIndex:oldIndex];
+ }
+ }
+ [newChildren addObject:node];
+ } else {
+ PithosObjectNode *node = [[PithosObjectNode alloc] initWithPithos:pithos
+ pithosContainer:pithosContainer
+ pithosObject:object];
+ node.parent = self;
+ node.shared = shared;
+ node.sharingAccount = sharingAccount;
+ node.inheritChildrenUpdatedNotificationName = inheritChildrenUpdatedNotificationName;
+ node.pithosAccountManager = pithosAccountManager;
+ if (children) {
+ NSUInteger oldIndex = [children indexOfObject:node];
+ if (oldIndex != NSNotFound) {
+ // Use the same pointer value, if possible
+ node = [children objectAtIndex:oldIndex];
+ node.pithosContainer = pithosContainer;
+// node.pithosObject = object;
+ [node setLimitedPithosObject:object];
+ [keptNodes addIndex:oldIndex];
+ }
+ }
+ [newChildren addObject:node];
+ }
+ }
+ }
+ [[children objectsAtIndexes:
+ [[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, [children count])] indexesPassingTest:^(NSUInteger idx, BOOL *stop){
+ if ([keptNodes containsIndex:idx])
+ return NO;
+ return YES;
+ }]] makeObjectsPerformSelector:@selector(pithosNodeWillBeRemoved)];
+ }
+ // Else cache was used and all results were fetched during this request, so existing children can be reused
+ containerRequest = nil;
+ objects = nil;
+ forcedRefresh = NO;
+ @synchronized(self) {
+ freshness = PithosNodeStateRefreshFinished;
+ }
+ [self postChildrenUpdatedNotificationName];
+ } else {
+ // Do an additional request to fetch more objects
+ containerRequest = [ASIPithosContainerRequest listObjectsRequestWithPithos:pithos
+ containerName:pithosContainer.name
+ limit:0
+ marker:[[someObjects lastObject] name]
+ prefix:prefix
+ delimiter:@"/"
+ path:nil
+ meta:nil
+ shared:shared
+ until:nil];
+ if (sharingAccount)
+ [containerRequest setRequestUserFromDefaultTo:sharingAccount withPithos:pithos];
+ else if (!forcedRefresh)
+ containerRequest.downloadCache = [ASIDownloadCache sharedCache];
containerRequest.delegate = self;
- containerRequest.downloadCache = [ASIDownloadCache sharedCache];
- [containerRequest startAsynchronous];
+ containerRequest.didFinishSelector = @selector(performRequestFinishedDelegateInBackground:);
+ containerRequest.didFailSelector = @selector(performRequestFailedDelegateInBackground:);
+ containerRequest.userInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
+ [NSNumber numberWithInteger:NSOperationQueuePriorityVeryHigh], @"priority",
+ [NSNumber numberWithUnsignedInteger:10], @"retries",
+ NSStringFromSelector(@selector(containerRequestFinished:)), @"didFinishSelector",
+ NSStringFromSelector(@selector(containerRequestFailed:)), @"didFailSelector",
+ nil];
+ [[PithosUtilities prepareRequest:containerRequest priority:NSOperationQueuePriorityVeryHigh] startAsynchronous];
+ }
+ } else if (containerRequest.responseStatusCode == 304) {
+ // Container is not modified, so existing children can be reused
+ containerRequest = nil;
+ objects = nil;
+ forcedRefresh = NO;
+ @synchronized(self) {
+ freshness = PithosNodeStateRefreshFinished;
}
+ [self postChildrenUpdatedNotificationName];
+ } else {
+ [self containerRequestFailed:containerRequest];
}
}
- return children;
}
-- (NSString *)displayName {
- return [[pithosContainer.name copy] autorelease];
+- (void)containerMetadataRequestFinished:(ASIPithosContainerRequest *)request {
+ @autoreleasepool {
+ DLog(@"URL: %@", [request url]);
+ DLog(@"cached: %d", [request didUseCachedResponse]);
+
+ if ([request isEqualTo:applyMetadataContainerRequest]) {
+ @synchronized(self) {
+ applyMetadataContainerRequest = nil;
+ }
+ [self refreshInfo];
+ } else if ([request isEqualTo:refreshMetadataContainerRequest]) {
+ [[pithosNodeInfoController window] makeFirstResponder:nil];
+ self.pithosContainer = [refreshMetadataContainerRequest container];
+ @synchronized(self) {
+ refreshMetadataContainerRequest = nil;
+ }
+ }
+ }
}
-- (NSImage *)icon {
- if (icon)
- return icon;
- return classIcon;
+- (void)containerMetadataRequestFailed:(ASIPithosContainerRequest *)request {
+ @autoreleasepool {
+ NSUInteger retries = [[request.userInfo objectForKey:@"retries"] unsignedIntegerValue];
+ if (retries > 0) {
+ ASIPithosContainerRequest *newRequest = (ASIPithosContainerRequest *)[PithosUtilities copyRequest:request];
+ [(NSMutableDictionary *)(newRequest.userInfo)setObject:[NSNumber numberWithUnsignedInteger:(--retries)] forKey:@"retries"];
+ if ([request isEqualTo:applyMetadataContainerRequest]) {
+ @synchronized(self) {
+ applyMetadataContainerRequest = newRequest;
+ }
+ } else if ([request isEqualTo:refreshMetadataContainerRequest]) {
+ @synchronized(self) {
+ refreshMetadataContainerRequest = newRequest;
+ }
+ }
+ [[PithosUtilities prepareRequest:newRequest priority:[[newRequest.userInfo objectForKey:@"priority"] integerValue]] startAsynchronous];
+ } else {
+ if ([request isEqualTo:applyMetadataContainerRequest]) {
+ [PithosUtilities httpRequestErrorAlertWithRequest:applyMetadataContainerRequest];
+ @synchronized(self) {
+ applyMetadataContainerRequest = nil;
+ }
+ } else if ([request isEqualTo:refreshMetadataContainerRequest]) {
+ [PithosUtilities httpRequestErrorAlertWithRequest:refreshMetadataContainerRequest];
+ @synchronized(self) {
+ refreshMetadataContainerRequest = nil;
+ }
+ }
+ }
+ }
+}
+
+#pragma mark -
+#pragma mark Info
+
+- (void)applyInfo {
+ @synchronized(self) {
+ if (applyMetadataContainerRequest == nil) {
+ [[pithosNodeInfoController window] makeFirstResponder:nil];
+ applyMetadataContainerRequest = [ASIPithosContainerRequest updateContainerMetadataRequestWithPithos:pithos
+ containerName:pithosContainer.name
+ policy:[NSDictionary dictionaryWithObjectsAndKeys:
+ policyVersioning, @"versioning",
+ [policyQuota stringValue], @"quota",
+ nil]
+ metadata:pithosContainer.metadata
+ update:NO];
+ applyMetadataContainerRequest.delegate = self;
+ applyMetadataContainerRequest.didFinishSelector = @selector(performRequestFinishedDelegateInBackground:);
+ applyMetadataContainerRequest.didFailSelector = @selector(performRequestFailedDelegateInBackground:);
+ applyMetadataContainerRequest.userInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
+ [NSNumber numberWithInteger:NSOperationQueuePriorityHigh], @"priority",
+ [NSNumber numberWithUnsignedInteger:10], @"retries",
+ NSStringFromSelector(@selector(containerMetadataRequestFinished:)), @"didFinishSelector",
+ NSStringFromSelector(@selector(containerMetadataRequestFailed:)), @"didFailSelector",
+ nil];
+ [[PithosUtilities prepareRequest:applyMetadataContainerRequest priority:NSOperationQueuePriorityHigh] startAsynchronous];
+ }
+ }
+}
+
+- (void)refreshInfo {
+ @synchronized(self) {
+ if (refreshMetadataContainerRequest == nil) {
+ refreshMetadataContainerRequest = [ASIPithosContainerRequest containerMetadataRequestWithPithos:pithos
+ containerName:pithosContainer.name];
+ refreshMetadataContainerRequest.delegate = self;
+ refreshMetadataContainerRequest.didFinishSelector = @selector(performRequestFinishedDelegateInBackground:);
+ refreshMetadataContainerRequest.didFailSelector = @selector(performRequestFailedDelegateInBackground:);
+ refreshMetadataContainerRequest.userInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
+ [NSNumber numberWithInteger:NSOperationQueuePriorityHigh], @"priority",
+ [NSNumber numberWithUnsignedInteger:10], @"retries",
+ NSStringFromSelector(@selector(containerMetadataRequestFinished:)), @"didFinishSelector",
+ NSStringFromSelector(@selector(containerMetadataRequestFailed:)), @"didFailSelector",
+ nil];
+ if (!sharingAccount)
+ refreshMetadataContainerRequest.downloadCache = [ASIDownloadCache sharedCache];
+ [[PithosUtilities prepareRequest:refreshMetadataContainerRequest priority:NSOperationQueuePriorityHigh] startAsynchronous];
+ }
+ }
+}
+
+#pragma mark -
+#pragma mark Actions
+
+- (void)showPithosNodeInfo:(id)sender {
+ if (!pithosNodeInfoController) {
+ pithosNodeInfoController = [[PithosContainerNodeInfoController alloc] initWithPithosNode:self];
+ [self refreshInfo];
+ }
+ [pithosNodeInfoController showWindow:sender];
+ [[pithosNodeInfoController window] makeKeyAndOrderFront:sender];
+ [NSApp activateIgnoringOtherApps:YES];
}
@end