// 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 "PithosFileUtilities.h"
+#import "PithosUtilities.h"
#import "PithosContainerNodeInfoController.h"
+#import "PithosActivityFacility.h"
static NSImage *sharedIcon = nil;
@implementation PithosContainerNode
-@synthesize pithosContainer, prefix;
+@synthesize pithos, pithosContainer, prefix;
@synthesize policyVersioning, policyQuota;
+ (void)initialize {
if (self == [PithosContainerNode class])
- sharedIcon = [[[NSWorkspace sharedWorkspace] iconForFileType:NSFileTypeForHFSTypeCode(kGenericHardDiskIcon)] 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])) {
+ self.pithos = aPithos;
self.pithosContainer = aPithosContainer;
prefix = nil;
- icon = [anIcon retain];
- childrenUpdatedNotificationName = @"PithosContainerNodeChildrenUpdated";
+ 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 {
[containerRequest clearDelegatesAndCancel];
- [containerRequest release];
[refreshMetadataContainerRequest clearDelegatesAndCancel];
- [refreshMetadataContainerRequest release];
[applyMetadataContainerRequest clearDelegatesAndCancel];
- [applyMetadataContainerRequest release];
- [policyQuota release];
- [policyVersioning release];
- [childrenUpdatedNotificationName release];
- [prefix release];
- [objects release];
- [pithosContainer release];
- [super dealloc];
}
#pragma mark -
-#pragma mark ASIHTTPRequestDelegate
-
-- (void)containerRequestFinished:(ASIPithosContainerRequest *)request {
- NSLog(@"URL: %@", [containerRequest url]);
- NSLog(@"cached: %d", [containerRequest didUseCachedResponse]);
-
- 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
- NSLog(@"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:@"/"]]) {
- // 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) ||
- ![[[objects objectAtIndex:sameNameObjectIndex] contentType] isEqualToString:@"application/directory"]) {
- PithosSubdirNode *node = [[[PithosSubdirNode alloc] initWithPithosContainer:pithosContainer pithosObject:object] autorelease];
- node.parent = self;
- 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;
- [keptNodes addIndex:oldIndex];
- }
- }
- [newChildren addObject:node];
- }
- } else if ([object.contentType isEqualToString:@"application/directory"]) {
- PithosSubdirNode *node = [[[PithosSubdirNode alloc] initWithPithosContainer:pithosContainer pithosObject:object] autorelease];
- node.parent = self;
- 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;
- [keptNodes addIndex:oldIndex];
- }
- }
- [newChildren addObject:node];
- } else {
- PithosObjectNode *node = [[[PithosObjectNode alloc] initWithPithosContainer:pithosContainer pithosObject:object] autorelease];
- node.parent = self;
- 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;
- [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 release];
- containerRequest = nil;
- [objects release];
- objects = nil;
- @synchronized(self) {
- freshness = PithosNodeStateRefreshFinished;
- }
- // Notify observers that children are updated
- [[NSNotificationCenter defaultCenter] postNotificationName:childrenUpdatedNotificationName object:self];
- } else {
- [containerRequest release];
- // Do an additional request to fetch more objects
- containerRequest = [[ASIPithosContainerRequest listObjectsRequestWithContainerName:pithosContainer.name
- limit:0
- marker:[[someObjects lastObject] name]
- prefix:prefix
- delimiter:@"/"
- path:nil
- meta:nil
- shared:NO
- until:nil] retain];
- containerRequest.delegate = self;
- containerRequest.downloadCache = [ASIDownloadCache sharedCache];
- [containerRequest startAsynchronous];
- }
-}
-
-- (void)containerRequestFailed:(ASIPithosContainerRequest *)request {
- [PithosFileUtilities httpRequestErrorAlertWithRequest:request];
- [newChildren release];
- newChildren = nil;
- [containerRequest release];
- containerRequest = nil;
- [objects release];
- objects = nil;
- @synchronized(self) {
- freshness = PithosNodeStateRefreshNeeded;
- }
-}
-
-- (void)containerMetadataRequestFinished:(ASIPithosContainerRequest *)request {
- NSLog(@"URL: %@", [request url]);
- NSLog(@"cached: %d", [request didUseCachedResponse]);
-
- if ([request isEqualTo:applyMetadataContainerRequest]) {
- @synchronized(self) {
- [applyMetadataContainerRequest release];
- applyMetadataContainerRequest = nil;
- }
- [self refreshInfo];
- } else if ([request isEqualTo:refreshMetadataContainerRequest]) {
- [[pithosNodeInfoController window] makeFirstResponder:nil];
- self.pithosContainer = [refreshMetadataContainerRequest container];
- @synchronized(self) {
- [refreshMetadataContainerRequest release];
- refreshMetadataContainerRequest = nil;
- }
- }
-}
+#pragma mark Properties
-- (void)containerMetadataRequestFailed:(ASIPithosContainerRequest *)request {
- if ([request isEqualTo:applyMetadataContainerRequest]) {
- [PithosFileUtilities httpRequestErrorAlertWithRequest:applyMetadataContainerRequest];
- @synchronized(self) {
- [applyMetadataContainerRequest release];
- applyMetadataContainerRequest = nil;
- }
- } else if ([request isEqualTo:refreshMetadataContainerRequest]) {
- [PithosFileUtilities httpRequestErrorAlertWithRequest:refreshMetadataContainerRequest];
- @synchronized(self) {
- [refreshMetadataContainerRequest release];
- refreshMetadataContainerRequest = nil;
- }
+- (void)setPithos:(ASIPithos *)aPithos {
+ if (aPithos && ![aPithos isEqualTo:pithos]) {
+ pithos = aPithos;
+ url = nil;
}
}
-#pragma mark -
-#pragma mark Properties
-
- (NSString *)url {
- if (url == nil)
- url = [[NSString alloc] initWithFormat:@"%@/%@", [ASIPithosRequest storageURL], pithosContainer.name];
+ if (url == nil)
+ url = [[NSString alloc] initWithFormat:@"%@/%@%@",
+ (sharingAccount ? [pithos storageURLWithAuthUser:sharingAccount] : pithos.storageURL),
+ pithosContainer.name,
+ (shared ? @"?shared" : @"")];
return url;
}
break;
case PithosNodeStateRefreshNeeded:
freshness = PithosNodeStateRefreshing;
- containerRequest = [[ASIPithosContainerRequest listObjectsRequestWithContainerName:pithosContainer.name
- limit:0
- marker:nil
- prefix:prefix
- delimiter:@"/"
- path:nil
- meta:nil
- shared:NO
- until:nil] retain];
+ 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(containerRequestFinished:);
- containerRequest.didFailSelector = @selector(containerRequestFailed:);
- 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];
break;
case PithosNodeStateRefreshing:
break;
case PithosNodeStateRefreshFinished:
if (newChildren) {
- [children release];
children = newChildren;
newChildren = nil;
}
}
- (NSString *)displayName {
- return [[pithosContainer.name copy] autorelease];
+ return [pithosContainer.name copy];
}
-- (NSImage *)icon {
- if (icon)
- return icon;
- return sharedIcon;
+- (void)setDisplayName:(NSString *)aDisplayName {
}
-- (void)setIcon:(NSImage *)anIcon {
- [icon release];
- icon = [anIcon retain];
+- (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 release];
- pithosContainer = [aPithosContainer retain];
+ pithosContainer = aPithosContainer;
}
if (pithosContainer.policy) {
self.policyVersioning = [pithosContainer.policy objectForKey:@"versioning"];
}
}
+- (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 ASIHTTPRequestDelegate
+
+- (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;
+ }
+ }
+ }
+}
+
+- (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.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];
+ }
+ }
+}
+
+- (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;
+ }
+ }
+ }
+}
+
+- (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
@synchronized(self) {
if (applyMetadataContainerRequest == nil) {
[[pithosNodeInfoController window] makeFirstResponder:nil];
- applyMetadataContainerRequest = [[ASIPithosContainerRequest updateContainerMetadataRequestWithContainerName:pithosContainer.name
- policy:[NSDictionary dictionaryWithObjectsAndKeys:
- policyVersioning, @"versioning",
- [policyQuota stringValue], @"quota",
- nil]
- metadata:pithosContainer.metadata
- update:NO] retain];
+ 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(containerMetadataRequestFinished:);
- applyMetadataContainerRequest.didFailSelector = @selector(containerMetadataRequestFailed:);
- [applyMetadataContainerRequest startAsynchronous];
+ 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 containerMetadataRequestWithContainerName:pithosContainer.name] retain];
+ refreshMetadataContainerRequest = [ASIPithosContainerRequest containerMetadataRequestWithPithos:pithos
+ containerName:pithosContainer.name];
refreshMetadataContainerRequest.delegate = self;
- refreshMetadataContainerRequest.didFinishSelector = @selector(containerMetadataRequestFinished:);
- refreshMetadataContainerRequest.didFailSelector = @selector(containerMetadataRequestFailed:);
- refreshMetadataContainerRequest.downloadCache = [ASIDownloadCache sharedCache];
- [refreshMetadataContainerRequest startAsynchronous];
+ 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 Actions
- (void)showPithosNodeInfo:(id)sender {
- if (!pithosNodeInfoController)
+ if (!pithosNodeInfoController) {
pithosNodeInfoController = [[PithosContainerNodeInfoController alloc] initWithPithosNode:self];
+ [self refreshInfo];
+ }
[pithosNodeInfoController showWindow:sender];
[[pithosNodeInfoController window] makeKeyAndOrderFront:sender];
[NSApp activateIgnoringOtherApps:YES];