From 4a8699ab1dcc21ad886db93fb91918f3064b16db Mon Sep 17 00:00:00 2001 From: Miltiadis Vasilakis Date: Fri, 4 Nov 2011 16:01:26 +0200 Subject: [PATCH] Listing requests for account, container and sharing accounts implement retries and check for proper response status. --- pithos-macos/PithosAccountNode.m | 164 ++++++++++++-------- pithos-macos/PithosContainerNode.m | 240 +++++++++++++++++------------- pithos-macos/PithosSharingAccountsNode.m | 154 +++++++++++-------- 3 files changed, 333 insertions(+), 225 deletions(-) diff --git a/pithos-macos/PithosAccountNode.m b/pithos-macos/PithosAccountNode.m index e45b6d7..cf798b8 100644 --- a/pithos-macos/PithosAccountNode.m +++ b/pithos-macos/PithosAccountNode.m @@ -42,6 +42,7 @@ #import "ASIPithosContainer.h" #import "ASIDownloadCache.h" #import "PithosUtilities.h" +#import "PithosActivityFacility.h" static NSImage *sharedIcon = nil; @@ -95,6 +96,9 @@ static NSImage *sharedIcon = nil; accountRequest.delegate = self; accountRequest.didFinishSelector = @selector(accountRequestFinished:); accountRequest.didFailSelector = @selector(accountRequestFailed:); + accountRequest.userInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithUnsignedInteger:10], @"retries", + nil]; if (!forcedRefresh) accountRequest.downloadCache = [ASIDownloadCache sharedCache]; [[PithosUtilities prepareRequest:accountRequest priority:NSOperationQueuePriorityVeryHigh] startAsynchronous]; @@ -130,48 +134,109 @@ static NSImage *sharedIcon = nil; #pragma mark - #pragma mark ASIHTTPRequestDelegate -- (void)accountRequestFinished:(ASIPithosAccountRequest *)request { - NSLog(@"URL: %@", [accountRequest url]); - NSLog(@"cached: %d", [accountRequest didUseCachedResponse]); - - self.pithosAccount = [accountRequest account]; - - NSArray *someContainers = [accountRequest containers]; - if (containers == nil) { - containers = [[NSMutableArray alloc] initWithArray:someContainers]; +- (void)accountRequestFailed:(ASIPithosAccountRequest *)request { + NSUInteger retries = [[accountRequest.userInfo objectForKey:@"retries"] unsignedIntegerValue]; + if (retries > 0) { + ASIPithosAccountRequest *newAccountRequest = (ASIPithosAccountRequest *)[PithosUtilities copyRequest:accountRequest]; + [(NSMutableDictionary *)(newAccountRequest.userInfo)setObject:[NSNumber numberWithUnsignedInteger:(--retries)] forKey:@"retries"]; + [accountRequest release]; + accountRequest = newAccountRequest; + [[PithosUtilities prepareRequest:accountRequest priority:NSOperationQueuePriorityVeryHigh] startAsynchronous]; } else { - [containers addObjectsFromArray:someContainers]; + NSString *message; + NSError *error = [accountRequest error]; + if (error) + message = [NSString stringWithFormat:@"Account listing failed: %@", error]; + else + message = [NSString stringWithFormat:@"Account listing failed: (%d) %@", + accountRequest.responseStatusCode, accountRequest.responseStatusMessage]; + [[PithosActivityFacility defaultPithosActivityFacility] startAndEndActivityWithType:PithosActivityOther message:message]; + [newChildren release]; + newChildren = nil; + [accountRequest release]; + accountRequest = nil; + [containers release]; + containers = nil; + forcedRefresh = NO; + @synchronized(self) { + freshness = PithosNodeStateRefreshNeeded; + } } - if ([someContainers count] < 10000) { - if (!accountRequest.didUseCachedResponse || ([containers count] != [someContainers count]) || !children) { - // Save new children - NSLog(@"using newChildren"); - newChildren = [[NSMutableArray alloc] init]; - NSMutableIndexSet *keptNodes = [NSMutableIndexSet indexSet]; - for (ASIPithosContainer *container in containers) { - PithosContainerNode *node = [[[PithosContainerNode alloc] initWithPithosContainer:container] autorelease]; - node.parent = self; - node.shared = shared; - node.sharingAccount = sharingAccount; - if (children) { - NSUInteger oldIndex = [children indexOfObject:node]; - if (oldIndex != NSNotFound) { - // Use the same pointer value, if possible - node = [children objectAtIndex:oldIndex]; - node.pithosContainer = container; - [keptNodes addIndex:oldIndex]; +} + +- (void)accountRequestFinished:(ASIPithosAccountRequest *)request { + NSLog(@"List account finished: %@", [accountRequest url]); + NSLog(@"Cached: %d", [accountRequest didUseCachedResponse]); + if (accountRequest.responseStatusCode == 200) { + self.pithosAccount = [accountRequest account]; + + NSArray *someContainers = [accountRequest containers]; + if (containers == nil) { + containers = [[NSMutableArray alloc] initWithArray:someContainers]; + } else { + [containers addObjectsFromArray:someContainers]; + } + if ([someContainers count] < 10000) { + if (!accountRequest.didUseCachedResponse || ([containers count] != [someContainers count]) || !children) { + // Save new children + NSLog(@"using newChildren"); + newChildren = [[NSMutableArray alloc] init]; + NSMutableIndexSet *keptNodes = [NSMutableIndexSet indexSet]; + for (ASIPithosContainer *container in containers) { + PithosContainerNode *node = [[[PithosContainerNode alloc] initWithPithosContainer:container] autorelease]; + node.parent = self; + node.shared = shared; + node.sharingAccount = sharingAccount; + if (children) { + NSUInteger oldIndex = [children indexOfObject:node]; + if (oldIndex != NSNotFound) { + // Use the same pointer value, if possible + node = [children objectAtIndex:oldIndex]; + node.pithosContainer = container; + [keptNodes addIndex:oldIndex]; + } } + [newChildren addObject:node]; } - [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 + [accountRequest release]; + accountRequest = nil; + [containers release]; + containers = nil; + forcedRefresh = NO; + @synchronized(self) { + freshness = PithosNodeStateRefreshFinished; } - [[children objectsAtIndexes: - [[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, [children count])] indexesPassingTest:^(NSUInteger idx, BOOL *stop){ - if ([keptNodes containsIndex:idx]) - return NO; - return YES; - }]] makeObjectsPerformSelector:@selector(pithosNodeWillBeRemoved)]; + // Notify observers that children are updated + [[NSNotificationCenter defaultCenter] postNotificationName:@"PithosAccountNodeChildrenUpdated" object:self]; + } else { + [accountRequest release]; + // Do an additional request to fetch more objects + accountRequest = [[ASIPithosAccountRequest listContainersRequestWithLimit:0 + marker:[[someContainers lastObject] name] + shared:shared + until:nil] retain]; + if (sharingAccount) + [accountRequest setRequestUserFromDefaultTo:sharingAccount]; + accountRequest.delegate = self; + accountRequest.didFinishSelector = @selector(accountRequestFinished:); + accountRequest.didFailSelector = @selector(accountRequestFailed:); + accountRequest.userInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithUnsignedInteger:10], @"retries", + nil]; + if (!forcedRefresh) + accountRequest.downloadCache = [ASIDownloadCache sharedCache]; + [[PithosUtilities prepareRequest:accountRequest priority:NSOperationQueuePriorityVeryHigh] startAsynchronous]; } - // Else cache was used and all results were fetched during this request, so existing children can be reused + } else if (accountRequest.responseStatusCode == 304) { + // Account is not modified, so existing children can be reused [accountRequest release]; accountRequest = nil; [containers release]; @@ -183,32 +248,7 @@ static NSImage *sharedIcon = nil; // Notify observers that children are updated [[NSNotificationCenter defaultCenter] postNotificationName:@"PithosAccountNodeChildrenUpdated" object:self]; } else { - [accountRequest release]; - // Do an additional request to fetch more objects - accountRequest = [[ASIPithosAccountRequest listContainersRequestWithLimit:0 - marker:[[someContainers lastObject] name] - shared:shared - until:nil] retain]; - if (sharingAccount) - [accountRequest setRequestUserFromDefaultTo:sharingAccount]; - accountRequest.delegate = self; - if (!forcedRefresh) - accountRequest.downloadCache = [ASIDownloadCache sharedCache]; - [[PithosUtilities prepareRequest:accountRequest priority:NSOperationQueuePriorityVeryHigh] startAsynchronous]; - } -} - -- (void)accountRequestFailed:(ASIPithosAccountRequest *)request { - [PithosUtilities httpRequestErrorAlertWithRequest:request]; - [newChildren release]; - newChildren = nil; - [accountRequest release]; - accountRequest = nil; - [containers release]; - containers = nil; - forcedRefresh = NO; - @synchronized(self) { - freshness = PithosNodeStateRefreshNeeded; + [self accountRequestFailed:accountRequest]; } } diff --git a/pithos-macos/PithosContainerNode.m b/pithos-macos/PithosContainerNode.m index f29a8fe..5631490 100644 --- a/pithos-macos/PithosContainerNode.m +++ b/pithos-macos/PithosContainerNode.m @@ -44,6 +44,7 @@ #import "ASIDownloadCache.h" #import "PithosUtilities.h" #import "PithosContainerNodeInfoController.h" +#import "PithosActivityFacility.h" static NSImage *sharedIcon = nil; @@ -132,6 +133,9 @@ static NSImage *sharedIcon = nil; containerRequest.delegate = self; containerRequest.didFinishSelector = @selector(containerRequestFinished:); containerRequest.didFailSelector = @selector(containerRequestFailed:); + containerRequest.userInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithUnsignedInteger:10], @"retries", + nil]; if (!forcedRefresh) containerRequest.downloadCache = [ASIDownloadCache sharedCache]; [[PithosUtilities prepareRequest:containerRequest priority:NSOperationQueuePriorityVeryHigh] startAsynchronous]; @@ -188,37 +192,86 @@ static NSImage *sharedIcon = nil; #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]; +- (void)containerRequestFailed:(ASIPithosContainerRequest *)request { + 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 release]; + containerRequest = newContainerRequest; + [[PithosUtilities prepareRequest:containerRequest priority:NSOperationQueuePriorityVeryHigh] startAsynchronous]; } else { - [objects addObjectsFromArray:someObjects]; + NSString *message; + NSError *error = [containerRequest error]; + if (error) + message = [NSString stringWithFormat:@"Container listing failed: %@", error]; + else + message = [NSString stringWithFormat:@"Container listing failed: (%d) %@", + containerRequest.responseStatusCode, containerRequest.responseStatusMessage]; + [[PithosActivityFacility defaultPithosActivityFacility] startAndEndActivityWithType:PithosActivityOther message:message]; + [newChildren release]; + newChildren = nil; + [containerRequest release]; + containerRequest = nil; + [objects release]; + objects = nil; + forcedRefresh = NO; + @synchronized(self) { + freshness = PithosNodeStateRefreshNeeded; + } } - 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) || - ![PithosUtilities isContentTypeDirectory:[[objects objectAtIndex:sameNameObjectIndex] contentType]]) { +} + +- (void)containerRequestFinished:(ASIPithosContainerRequest *)request { + NSLog(@"List container finished: %@", [containerRequest url]); + NSLog(@"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 + 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) || + ![PithosUtilities isContentTypeDirectory:[[objects objectAtIndex:sameNameObjectIndex] contentType]]) { + PithosSubdirNode *node = [[[PithosSubdirNode alloc] initWithPithosContainer:pithosContainer pithosObject:object] autorelease]; + node.parent = self; + node.shared = shared; + node.sharingAccount = sharingAccount; + 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]; + } + } + if (sharingAccount) + node.pithosObject.allowedTo = [NSString stringWithString:@"read"]; + [newChildren addObject:node]; + } + } else if ([PithosUtilities isContentTypeDirectory:object.contentType]) { PithosSubdirNode *node = [[[PithosSubdirNode alloc] initWithPithosContainer:pithosContainer pithosObject:object] autorelease]; node.parent = self; node.shared = shared; @@ -233,53 +286,70 @@ static NSImage *sharedIcon = nil; [keptNodes addIndex:oldIndex]; } } - if (sharingAccount) - node.pithosObject.allowedTo = [NSString stringWithString:@"read"]; [newChildren addObject:node]; - } - } else if ([PithosUtilities isContentTypeDirectory:object.contentType]) { - PithosSubdirNode *node = [[[PithosSubdirNode alloc] initWithPithosContainer:pithosContainer pithosObject:object] autorelease]; - node.parent = self; - node.shared = shared; - node.sharingAccount = sharingAccount; - 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; - node.shared = shared; - node.sharingAccount = sharingAccount; - 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]; + } else { + PithosObjectNode *node = [[[PithosObjectNode alloc] initWithPithosContainer:pithosContainer pithosObject:object] autorelease]; + node.parent = self; + node.shared = shared; + node.sharingAccount = sharingAccount; + 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]; } - [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; + forcedRefresh = NO; + @synchronized(self) { + freshness = PithosNodeStateRefreshFinished; } - [[children objectsAtIndexes: - [[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, [children count])] indexesPassingTest:^(NSUInteger idx, BOOL *stop){ - if ([keptNodes containsIndex:idx]) - return NO; - return YES; - }]] makeObjectsPerformSelector:@selector(pithosNodeWillBeRemoved)]; + // 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:shared + until:nil] retain]; + if (sharingAccount) + [containerRequest setRequestUserFromDefaultTo:sharingAccount]; + containerRequest.delegate = self; + containerRequest.didFinishSelector = @selector(containerRequestFinished:); + containerRequest.didFailSelector = @selector(containerRequestFailed:); + containerRequest.userInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithUnsignedInteger:10], @"retries", + nil]; + if (!forcedRefresh) + containerRequest.downloadCache = [ASIDownloadCache sharedCache]; + [[PithosUtilities prepareRequest:containerRequest priority:NSOperationQueuePriorityVeryHigh] startAsynchronous]; } - // Else cache was used and all results were fetched during this request, so existing children can be reused + } else if (containerRequest.responseStatusCode == 304) { + // Container is not modified, so existing children can be reused [containerRequest release]; containerRequest = nil; [objects release]; @@ -291,37 +361,7 @@ static NSImage *sharedIcon = nil; // 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:shared - until:nil] retain]; - if (sharingAccount) - [containerRequest setRequestUserFromDefaultTo:sharingAccount]; - containerRequest.delegate = self; - if (!forcedRefresh) - containerRequest.downloadCache = [ASIDownloadCache sharedCache]; - [[PithosUtilities prepareRequest:containerRequest priority:NSOperationQueuePriorityVeryHigh] startAsynchronous]; - } -} - -- (void)containerRequestFailed:(ASIPithosContainerRequest *)request { - [PithosUtilities httpRequestErrorAlertWithRequest:request]; - [newChildren release]; - newChildren = nil; - [containerRequest release]; - containerRequest = nil; - [objects release]; - objects = nil; - forcedRefresh = NO; - @synchronized(self) { - freshness = PithosNodeStateRefreshNeeded; + [self containerRequestFailed:containerRequest]; } } diff --git a/pithos-macos/PithosSharingAccountsNode.m b/pithos-macos/PithosSharingAccountsNode.m index 9802260..029d331 100644 --- a/pithos-macos/PithosSharingAccountsNode.m +++ b/pithos-macos/PithosSharingAccountsNode.m @@ -41,6 +41,7 @@ #import "ASIPithosAccount.h" #import "ASIDownloadCache.h" #import "PithosUtilities.h" +#import "PithosActivityFacility.h" @implementation PithosSharingAccountsNode @@ -82,6 +83,9 @@ sharingAccountsRequest.delegate = self; sharingAccountsRequest.didFinishSelector = @selector(sharingAccountsRequestFinished:); sharingAccountsRequest.didFailSelector = @selector(sharingAccountsRequestFailed:); + sharingAccountsRequest.userInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithUnsignedInteger:10], @"retries", + nil]; if (!forcedRefresh) sharingAccountsRequest.downloadCache = [ASIDownloadCache sharedCache]; [[PithosUtilities prepareRequest:sharingAccountsRequest priority:NSOperationQueuePriorityVeryHigh] startAsynchronous]; @@ -111,80 +115,104 @@ #pragma mark - #pragma mark ASIHTTPRequestDelegate -- (void)sharingAccountsRequestFinished:(ASIPithosRequest *)request { - NSLog(@"URL: %@", [sharingAccountsRequest url]); - NSLog(@"cached: %d", [sharingAccountsRequest didUseCachedResponse]); - - NSArray *someSharingAccounts = [sharingAccountsRequest sharingAccounts]; - if (sharingAccounts == nil) { - sharingAccounts = [[NSMutableArray alloc] initWithArray:someSharingAccounts]; +- (void)sharingAccountsRequestFailed:(ASIPithosRequest *)request { + NSUInteger retries = [[sharingAccountsRequest.userInfo objectForKey:@"retries"] unsignedIntegerValue]; + if (retries > 0) { + ASIPithosRequest *newSharingAccountsRequest = (ASIPithosRequest *)[PithosUtilities copyRequest:sharingAccountsRequest]; + [(NSMutableDictionary *)(newSharingAccountsRequest.userInfo)setObject:[NSNumber numberWithUnsignedInteger:(--retries)] forKey:@"retries"]; + [sharingAccountsRequest release]; + sharingAccountsRequest = newSharingAccountsRequest; + [[PithosUtilities prepareRequest:sharingAccountsRequest priority:NSOperationQueuePriorityVeryHigh] startAsynchronous]; } else { - [sharingAccounts addObjectsFromArray:someSharingAccounts]; - } - if ([someSharingAccounts count] < 10000) { - if (!sharingAccountsRequest.didUseCachedResponse || ([sharingAccounts count] != [someSharingAccounts count]) || !children) { - // Save new children - NSLog(@"using newChildren"); - newChildren = [[NSMutableArray alloc] init]; - NSMutableIndexSet *keptNodes = [NSMutableIndexSet indexSet]; - for (ASIPithosAccount *account in sharingAccounts) { - if (![account.name isEqualToString:[ASIPithosRequest authUser]]) { - PithosAccountNode *node = [[[PithosAccountNode alloc] init] autorelease]; - node.parent = self; - node.shared = shared; - node.sharingAccount = account.name; - if (children) { - NSUInteger oldIndex = [children indexOfObject:node]; - if (oldIndex != NSNotFound) { - // Use the same pointer value, if possible - node = [children objectAtIndex:oldIndex]; - [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 + NSString *message; + NSError *error = [sharingAccountsRequest error]; + if (error) + message = [NSString stringWithFormat:@"Sharing accounts listing failed: %@", error]; + else + message = [NSString stringWithFormat:@"Sharing accounts listing failed: (%d) %@", + sharingAccountsRequest.responseStatusCode, sharingAccountsRequest.responseStatusMessage]; + [[PithosActivityFacility defaultPithosActivityFacility] startAndEndActivityWithType:PithosActivityOther message:message]; + [newChildren release]; + newChildren = nil; [sharingAccountsRequest release]; sharingAccountsRequest = nil; [sharingAccounts release]; sharingAccounts = nil; forcedRefresh = NO; @synchronized(self) { - freshness = PithosNodeStateRefreshFinished; + freshness = PithosNodeStateRefreshNeeded; } - // Notify observers that children are updated - [[NSNotificationCenter defaultCenter] postNotificationName:@"PithosSharingAccountsNodeChildrenUpdated" object:self]; - } else { - [sharingAccountsRequest release]; - // Do an additional request to fetch more objects - sharingAccountsRequest = [[ASIPithosRequest listSharingAccountsRequestWithLimit:0 - marker:[[someSharingAccounts lastObject] name]] retain]; - sharingAccountsRequest.delegate = self; - if (!forcedRefresh) - sharingAccountsRequest.downloadCache = [ASIDownloadCache sharedCache]; - [[PithosUtilities prepareRequest:sharingAccountsRequest priority:NSOperationQueuePriorityVeryHigh] startAsynchronous]; } } -- (void)accountRequestFailed:(ASIPithosRequest *)request { - [PithosUtilities httpRequestErrorAlertWithRequest:request]; - [newChildren release]; - newChildren = nil; - [sharingAccountsRequest release]; - sharingAccountsRequest = nil; - [sharingAccounts release]; - sharingAccounts = nil; - forcedRefresh = NO; - @synchronized(self) { - freshness = PithosNodeStateRefreshNeeded; +- (void)sharingAccountsRequestFinished:(ASIPithosRequest *)request { + NSLog(@"List sharing accounts finished: %@", [sharingAccountsRequest url]); + NSLog(@"Cached: %d", [sharingAccountsRequest didUseCachedResponse]); + if (sharingAccountsRequest.responseStatusCode == 200) { + NSArray *someSharingAccounts = [sharingAccountsRequest sharingAccounts]; + if (sharingAccounts == nil) { + sharingAccounts = [[NSMutableArray alloc] initWithArray:someSharingAccounts]; + } else { + [sharingAccounts addObjectsFromArray:someSharingAccounts]; + } + if ([someSharingAccounts count] < 10000) { + if (!sharingAccountsRequest.didUseCachedResponse || ([sharingAccounts count] != [someSharingAccounts count]) || !children) { + // Save new children + NSLog(@"using newChildren"); + newChildren = [[NSMutableArray alloc] init]; + NSMutableIndexSet *keptNodes = [NSMutableIndexSet indexSet]; + for (ASIPithosAccount *account in sharingAccounts) { + if (![account.name isEqualToString:[ASIPithosRequest authUser]]) { + PithosAccountNode *node = [[[PithosAccountNode alloc] init] autorelease]; + node.parent = self; + node.shared = shared; + node.sharingAccount = account.name; + if (children) { + NSUInteger oldIndex = [children indexOfObject:node]; + if (oldIndex != NSNotFound) { + // Use the same pointer value, if possible + node = [children objectAtIndex:oldIndex]; + [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 + [sharingAccountsRequest release]; + sharingAccountsRequest = nil; + [sharingAccounts release]; + sharingAccounts = nil; + forcedRefresh = NO; + @synchronized(self) { + freshness = PithosNodeStateRefreshFinished; + } + // Notify observers that children are updated + [[NSNotificationCenter defaultCenter] postNotificationName:@"PithosSharingAccountsNodeChildrenUpdated" object:self]; + } else { + [sharingAccountsRequest release]; + // Do an additional request to fetch more objects + sharingAccountsRequest = [[ASIPithosRequest listSharingAccountsRequestWithLimit:0 + marker:[[someSharingAccounts lastObject] name]] retain]; + sharingAccountsRequest.delegate = self; + sharingAccountsRequest.didFinishSelector = @selector(sharingAccountsRequestFinished:); + sharingAccountsRequest.didFailSelector = @selector(sharingAccountsRequestFailed:); + sharingAccountsRequest.userInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithUnsignedInteger:10], @"retries", + nil]; + if (!forcedRefresh) + sharingAccountsRequest.downloadCache = [ASIDownloadCache sharedCache]; + [[PithosUtilities prepareRequest:sharingAccountsRequest priority:NSOperationQueuePriorityVeryHigh] startAsynchronous]; + } + } else { + [self sharingAccountsRequestFailed:sharingAccountsRequest]; } } -- 1.7.10.4