Revision 7db1712d

b/Classes/ASIAuthenticationDialog.m
133 133
{
134 134
	[self showTitle];
135 135
	
136
	UIDeviceOrientation o = [[UIApplication sharedApplication] statusBarOrientation];
136
	UIDeviceOrientation o = [[UIDevice currentDevice] orientation];
137 137
	CGFloat angle = 0;
138 138
	switch (o) {
139 139
		case UIDeviceOrientationLandscapeLeft: angle = 90; break;
b/Classes/ASIDownloadCache.m
356 356

  
357 357
	BOOL isDirectory = NO;
358 358
	BOOL exists = [[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:&isDirectory];
359
	if (exists && !isDirectory || !exists) {
359
	if ((exists && !isDirectory) || !exists) {
360 360
		[[self accessLock] unlock];
361 361
		return;
362 362
	}
b/Classes/AccountDetailsViewController.m
16 16
#import "UIViewController+Conveniences.h"
17 17
#import "NSString+Conveniences.h"
18 18
#import "ActivityIndicatorView.h"
19
#import "APILogger.h"
20 19
#import "OpenStackAppDelegate.h"
21 20
#import "UIColor+MoreColors.h"
22 21

  
......
375 374
        if (loginURLPrefix.length > 0) {
376 375
            NSString *loginURL = [NSString stringWithFormat:@"%@?next=pithos://login", loginURLPrefix]; 
377 376

  
378
            NSLog(@"loginurl: %@", loginURL);
379 377
            [[UIApplication sharedApplication] openURL:[NSURL URLWithString:loginURL]];
380 378
        }
381 379
        [tableView deselectRowAtIndexPath:indexPath animated:NO];
b/Classes/AccountGroupsViewController.h
45 45
    OpenStackAccount *account;
46 46
    NSMutableDictionary *groups;
47 47
    NSMutableDictionary *metadata;
48
    ActivityIndicatorView *activityIndicatorView;
49
    
50
    id successObserver;
51
    id failureObserver;
48
    ActivityIndicatorView *activityIndicatorView;    
52 49
}
53 50

  
54 51
@property (nonatomic, retain) OpenStackAccount *account;
b/Classes/AccountGroupsViewController.m
41 41
#import "EditAccountGroupsViewController.h"
42 42
#import "UIViewController+Conveniences.h"
43 43
#import "NSString+Conveniences.h"
44
#import "APICallback.h"
44 45

  
45 46

  
46 47
@implementation AccountGroupsViewController
......
70 71
    activityIndicatorView = [[ActivityIndicatorView alloc] initWithFrame:[ActivityIndicatorView frameForText:activityMessage] text:activityMessage];
71 72
    [activityIndicatorView addToView:self.view];
72 73
    
73
    [self.account.manager getStorageAccountInfo];
74
    successObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"getStorageAccountInfoSucceeded" 
75
                                                                        object:account
76
                                                                         queue:[NSOperationQueue mainQueue]
77
                                                                    usingBlock:^(NSNotification *notification)
78
    {
79
        [activityIndicatorView removeFromSuperviewAndRelease];
80
        OpenStackRequest *request = [notification.userInfo objectForKey:@"request"];
81
        for (NSString *key in request.responseHeaders) {
82
            if ([key hasPrefix:@"X-Account-Group-"]) {
83
                NSString *groupUsers = [NSString decodeFromPercentEscape:[request.responseHeaders objectForKey:key]];
84
                NSString *groupName = [NSString decodeFromPercentEscape:[key substringFromIndex:16]];
85
                [groups setObject:groupUsers forKey:groupName];
86
            }
87
        }
88
        
89
        for (NSString *header in request.responseHeaders) {
90
            if ([header hasPrefix:@"X-Account-Meta-"])  {
91
                NSString *metadataKey = [NSString decodeFromPercentEscape:[header substringFromIndex:15]];
92
                NSString *metadataValue = [NSString decodeFromPercentEscape:[request.responseHeaders objectForKey:header]];
93
                [metadata setObject:metadataValue forKey:metadataKey];
94
            }
95
        }
96
        
97
        [self.tableView reloadData];
98
        [[NSNotificationCenter defaultCenter] removeObserver:successObserver];
99
    }];
100
    
101
    failureObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"getStorageAccountInfoFailed"
102
                                                                        object:account
103
                                                                         queue:[NSOperationQueue mainQueue]
104
                                                                    usingBlock:^(NSNotification *notification)
105
                       {
106
                           [activityIndicatorView removeFromSuperviewAndRelease];
107
                           [self alert:@"Error" message:@"Failed to get account information"];
108
                           [[NSNotificationCenter defaultCenter] removeObserver:successObserver];
109
                        }];
74
    [[self.account.manager getStorageAccountInfo] 
75
     success:^(OpenStackRequest *request) {
76
         [activityIndicatorView removeFromSuperviewAndRelease];
77
         for (NSString *key in request.responseHeaders) {
78
             if ([key hasPrefix:@"X-Account-Group-"]) {
79
                 NSString *groupUsers = [NSString decodeFromPercentEscape:[request.responseHeaders objectForKey:key]];
80
                 NSString *groupName = [NSString decodeFromPercentEscape:[key substringFromIndex:16]];
81
                 [groups setObject:groupUsers forKey:groupName];
82
             }
83
         }
84
         
85
         for (NSString *header in request.responseHeaders) {
86
             if ([header hasPrefix:@"X-Account-Meta-"])  {
87
                 NSString *metadataKey = [NSString decodeFromPercentEscape:[header substringFromIndex:15]];
88
                 NSString *metadataValue = [NSString decodeFromPercentEscape:[request.responseHeaders objectForKey:header]];
89
                 [metadata setObject:metadataValue forKey:metadataKey];
90
             }
91
         }
92

  
93
         [self.tableView reloadData];
94

  
95
     }
96
     failure:^(OpenStackRequest *request) {
97
         [activityIndicatorView removeFromSuperviewAndRelease];
98
         [self alert:@"Error" message:@"Failed to get account information"];
99
     }];
110 100
}
111 101

  
112 102
- (void)viewDidUnload
b/Classes/AccountHomeViewController.h
19 19
    
20 20
    NSInteger refreshCount;
21 21
    
22
    id authRetryFailedObserver;
23 22
    
24 23
    NSInteger totalRows;
25 24
    NSInteger computeRow;
b/Classes/AccountHomeViewController.m
10 10
#import "OpenStackAccount.h"
11 11
#import "Provider.h"
12 12
#import "ContactInformationViewController.h"
13
#import "APILogsViewController.h"
14 13
#import "ServersViewController.h"
15 14
#import "NSObject+Conveniences.h"
16 15
#import "RootViewController.h"
......
45 44
- (void)incrementRefreshCount {
46 45
    refreshCount++;
47 46
    //if (refreshCount == 2) {
48
        self.account.hasBeenRefreshed = YES;
49
        [self hideToolbarActivityMessage];
50
        refreshButton.enabled = YES;
47
    self.account.hasBeenRefreshed = YES;
48
    [self hideToolbarActivityMessage];
49
    refreshButton.enabled = YES;
51 50
    //}
52 51
}
53

  
54 52
- (void)viewDidLoad {
55 53
    [super viewDidLoad];
56 54
        
......
68 66
    accountMetadataRow = 1;
69 67

  
70 68
    
71
    authRetryFailedObserver = [[NSNotificationCenter defaultCenter] addObserverForName:[self.account.manager notificationName:@"authRetryFailed" identifier:0] object:nil
72
                                                                               queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notification)
73
    {
74
        [self hideToolbarActivityMessage];
75
        [self alert:@"Authentication failed.  Please check your username and API key." request:[notification.userInfo objectForKey:@"request"]];
76
        [[NSNotificationCenter defaultCenter] removeObserver:authRetryFailedObserver];
77
    }];    
78 69
    
79
    id getServersObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"getServersSucceeded" object:self.account 
80
                                                                           queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notification)
81
    {
82
        [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:computeRow inSection:0]] withRowAnimation:UITableViewRowAnimationNone];
83
        [self incrementRefreshCount];
84
    }];
85 70
    
86
    id getServersFailedObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"getServersFailed" object:self.account 
87
                                                                               queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notification)
88
    {
89
        [self incrementRefreshCount];
90
    }];
91

  
92 71
    id getContainersObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"getContainersSucceeded" object:self.account 
93
                                                                              queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notification)
94
    {
95
        [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:storageRow inSection:0]] withRowAnimation:UITableViewRowAnimationNone];
96
        [self incrementRefreshCount];
97
    }];
98
    id getContainersFailedObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"getContainersFailed" object:self.account 
99 72
                                                                                  queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notification)
100
    {
101
        [self incrementRefreshCount];
102
    }];
103
    id getLoadBalancersObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"getLoadBalancersSucceeded" object:self.account 
104
                                                                                     queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notification)
105
    {
106
        if (loadBalancingRow > 0) {
107
            [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:loadBalancingRow inSection:0]] withRowAnimation:UITableViewRowAnimationNone];
108
            [self incrementRefreshCount];
109
        }
110
    }];
111
    id createServerObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"createServerSucceeded" object:self.account 
112
                                                                           queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notification)
113
    {
114
        [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:computeRow inSection:0]] withRowAnimation:UITableViewRowAnimationNone];
115
    }];
73
                                {
74
                                    [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:storageRow inSection:0]] withRowAnimation:UITableViewRowAnimationNone];
75
                                    [self incrementRefreshCount];
76
                                }];
77
    id getContainersFailedObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"getContainersFailed" object:self.account 
78
                                                                                        queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notification)
79
                                      {
80
                                          [self incrementRefreshCount];
81
                                      }];
116 82
    id createContainerObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"createContainerSucceeded" object:self.account 
117
                                                                              queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notification)
118
    {
119
        [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:storageRow inSection:0]] withRowAnimation:UITableViewRowAnimationNone];
120
    }];
121
    id deleteServerObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"deleteServerSucceeded" object:self.account 
122
                                                                                 queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notification)
123
    {
124
        [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:computeRow inSection:0]] withRowAnimation:UITableViewRowAnimationNone];
125
    }];
83
                                                                                    queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notification)
84
                                  {
85
                                      [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:storageRow inSection:0]] withRowAnimation:UITableViewRowAnimationNone];
86
                                  }];
126 87
    id deleteContainerObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"deleteContainerSucceeded" object:self.account 
127 88
                                                                                    queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notification)
128
    {
129
        [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:storageRow inSection:0]] withRowAnimation:UITableViewRowAnimationNone];
130
    }];
89
                                  {
90
                                      [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:storageRow inSection:0]] withRowAnimation:UITableViewRowAnimationNone];
91
                                  }];
131 92
    
132
    observers = [[NSArray alloc] initWithObjects:getServersObserver, getServersFailedObserver, getContainersObserver, getContainersFailedObserver, createServerObserver, createContainerObserver, deleteServerObserver, deleteContainerObserver, getLoadBalancersObserver, nil];
93
    observers = [[NSArray alloc] initWithObjects: getContainersObserver, getContainersFailedObserver, createContainerObserver, deleteContainerObserver, nil];
133 94
    
95

  
134 96
}
135 97

  
136 98
- (void)viewWillAppear:(BOOL)animated {
......
174 136
- (void)viewDidAppear:(BOOL)animated {
175 137
    [super viewDidAppear:animated];
176 138
    if (!self.account.hasBeenRefreshed) {
177
        //[self showToolbarActivityMessage:@"Refreshing data..."];
178 139
        [self.account refreshCollections];
179 140
    }
180 141
}
181

  
182 142
- (void)viewWillDisappear:(BOOL)animated {
183
//    [rootViewController.tableView deselectRowAtIndexPath:rootViewIndexPath animated:YES];
143
    //    [rootViewController.tableView deselectRowAtIndexPath:rootViewIndexPath animated:YES];
184 144
    [super viewWillDisappear:animated];
185 145
}
186 146

  
......
188 148
    for (id observer in observers) {
189 149
        [[NSNotificationCenter defaultCenter] removeObserver:observer];
190 150
    }
191
    [[NSNotificationCenter defaultCenter] removeObserver:authRetryFailedObserver];
192

  
151
    
193 152
    [super viewDidUnload];
194 153
}
195

  
196 154
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
197 155
    return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) || (toInterfaceOrientation == UIInterfaceOrientationPortrait);
198 156
}
......
246 204
            } else {
247 205
                cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
248 206
            }
249
//    } else if (indexPath.row == kAPILogs) {
250
//        cell.textLabel.text = @"API Logs";
251 207
        } else if (indexPath.row == limitsRow) {
252 208
            cell.textLabel.text = @"API Rate Limits";
253 209
            cell.imageView.image = [UIImage imageNamed:@"api-rate-limits-icon.png"];
......
340 296
                [self.navigationController pushViewController:vc animated:YES];
341 297
            }
342 298
            [vc release];
343
//      } else if (indexPath.row == kAPILogs) {
344
//          APILogsViewController *vc = [[APILogsViewController alloc] initWithNibName:@"   APILogsViewController" bundle:nil];
345
//          vc.account = account;
346
//          [self.navigationController pushViewController:vc animated:YES];
347
//          [vc release];
348 299
        } else if (indexPath.row == limitsRow) {
349 300
            LimitsViewController *vc = [[LimitsViewController alloc] initWithNibName:@"LimitsViewController" bundle:nil];
350 301
            vc.account = account;
......
407 358
#pragma mark Button Handlers
408 359

  
409 360
- (void)refreshButtonPressed:(id)sender {
410
    //refreshButton.enabled = NO;
411 361
    refreshCount = 0;
412
    //[self showToolbarActivityMessage:@"Refreshing data..."];
413 362
    [self.account refreshCollections];    
414 363
}
415 364

  
b/Classes/AccountManager.h
52 52

  
53 53
// object storage
54 54

  
55
- (void)getStorageAccountInfo;
56
- (void)getSharingAccounts;
57
- (void)getContainers;
58
- (APICallback *)getContainersWithCallback;
59
- (void)createContainer:(Container *)container;
60
- (void)deleteContainer:(Container *)container;
55
- (APICallback *)getStorageAccountInfo;
56
- (APICallback *)getSharingAccounts;
57
- (APICallback *)getContainers;
58
- (APICallback *)createContainer:(Container *)container;
59
- (APICallback *)deleteContainer:(Container *)container;
61 60

  
62 61
- (void)getObjects:(Container *)container;
63 62
- (void)getObjects:(Container *)container afterMarker:(NSString *)marker objectsBuffer:(NSMutableDictionary *)objectsBuffer;
64
- (void)getObjectInfo:(Container *)container object:(StorageObject *)object;
65
- (void)getObject:(Container *)container object:(StorageObject *)object downloadProgressDelegate:(id)downloadProgressDelegate;
66
- (void)writeObject:(Container *)container object:(StorageObject *)object downloadProgressDelegate:(id)downloadProgressDelegate;
67
- (void)writeObjectMetadata:(Container *)container object:(StorageObject *)object;
68
- (void)deleteObject:(Container *)container object:(StorageObject *)object;
63
- (APICallback *)getObjectInfo:(Container *)container object:(StorageObject *)object;
64
- (APICallback *)getObject:(Container *)container object:(StorageObject *)object downloadProgressDelegate:(id)downloadProgressDelegate;
65
- (APICallback *)writeObject:(Container *)container object:(StorageObject *)object downloadProgressDelegate:(id)downloadProgressDelegate;
66
- (APICallback *)writeObjectMetadata:(Container *)container object:(StorageObject *)object;
67
- (APICallback *)deleteObject:(Container *)container object:(StorageObject *)object;
69 68

  
70 69
//account actions
71 70

  
72
- (void)writeAccountMetadata:(NSDictionary *)accountInfo;
71
- (APICallback *)writeAccountMetadata:(NSDictionary *)accountInfo;
73 72

  
74 73
// container actions
75 74
- (void)updateCDNContainer:(Container *)container;
76
- (void)writeContainerPolicy:(Container *)container;
75
- (APICallback *)writeContainerPolicy:(Container *)container;
77 76

  
78 77

  
79 78
// load balancing
b/Classes/AccountManager.m
205 205
        [self notify:@"deleteServerFailed" request:request object:[request.userInfo objectForKey:@"server"]];        
206 206
    }];
207 207
    if (![self queue]) {
208
        [self setQueue:[[[NSOperationQueue alloc] init] autorelease]];
208
        [self setQueue:(ASINetworkQueue *)[[[NSOperationQueue alloc] init] autorelease]];
209 209
    }
210 210
    [queue addOperation:request];    
211 211
}
......
232 232
        [self notify:@"createServerFailed" request:request object:[request.userInfo objectForKey:@"server"]];        
233 233
    }];
234 234
    if (![self queue]) {
235
        [self setQueue:[[[NSOperationQueue alloc] init] autorelease]];
235
        [self setQueue:(ASINetworkQueue *)[[[NSOperationQueue alloc] init] autorelease]];
236 236
    }
237 237
    [queue addOperation:request];
238 238
}
......
368 368

  
369 369
- (void)getServers {
370 370
    if (![self queue]) {
371
        [self setQueue:[[[NSOperationQueue alloc] init] autorelease]];
371
        [self setQueue:[[[ASINetworkQueue alloc] init] autorelease]];
372 372
    }
373 373
    GetServersRequest *request = [GetServersRequest request:self.account];
374 374
    [queue addOperation:request];
......
384 384

  
385 385
- (void)getFlavors {
386 386
    if (![self queue]) {
387
        [self setQueue:[[[NSOperationQueue alloc] init] autorelease]];
387
        [self setQueue:[[[ASINetworkQueue alloc] init] autorelease]];
388 388
    }
389 389
    GetFlavorsRequest *request = [GetFlavorsRequest request:self.account];
390 390
    [queue addOperation:request];
......
394 394

  
395 395
- (void)getImages {
396 396
    if (![self queue]) {
397
        [self setQueue:[[[NSOperationQueue alloc] init] autorelease]];
397
        [self setQueue:[[[ASINetworkQueue alloc] init] autorelease]];
398 398
    }
399 399
    GetImagesRequest *request = [GetImagesRequest request:self.account];
400 400
    [queue addOperation:request];
......
404 404
#pragma mark Object Storage
405 405

  
406 406

  
407
- (void)getStorageAccountInfo {
407
- (APICallback *)getStorageAccountInfo {
408 408
    __block OpenStackRequest *request = [OpenStackRequest getStorageAccountInfoRequest:self.account];
409
    
410
    request.delegate = self;
411
    [request setCompletionBlock:^{
412
        if ([request isSuccess]) {
413
            self.account.containerCount = [[[request responseHeaders] objectForKey:@"X-Account-Container-Count"] intValue];
414
            NSString *numStr = [[request responseHeaders] objectForKey:@"X-Account-Bytes-Used"];
415
            self.account.totalBytesUsed = strtoull([numStr UTF8String], NULL, 0);
416
            [self.account persist];
417
            [self notify:@"getStorageAccountInfoSucceeded" request:request object:self.account];
418
        } else {
419
            [self notify:@"getStorageAccountInfoFailed" request:request object:self.account];
420
        }
421
    }];
422
    [request setFailedBlock:^{
423
        [self notify:@"getStorageAccountInfoFailed" request:request object:self.account];
409
    return [self callbackWithRequest:request success:^(OpenStackRequest *request) {        
410
        self.account.containerCount = [[[request responseHeaders] objectForKey:@"X-Account-Container-Count"] intValue];
411
        NSString *numStr = [[request responseHeaders] objectForKey:@"X-Account-Bytes-Used"];
412
        self.account.totalBytesUsed = strtoull([numStr UTF8String], NULL, 0);
413
        [self.account persist];
414
        self.account.containerCount = [self.account.containers count];        
424 415
    }];
425
    [request startAsynchronous];
426 416
}
427 417

  
428
- (void)getSharingAccounts {
418
- (APICallback *)getSharingAccounts {
429 419
    __block OpenStackRequest *request = [OpenStackRequest getSharingAccountsRequest:self.account];
430
    
431
    request.delegate = self;
432
    [request setCompletionBlock:^{
433
        if ([request isSuccess]) {
434
            [self notify:@"getSharingAccountsSucceeed" request:request object:self.account];
435
        } else {
436
            [self notify:@"getSharingAccountsFailed" request:request object:self.account];
437
        }
438
    }];
439
    [request setFailedBlock:^{
440
        [self notify:@"getSharingAccountsFailed" request:request object:self.account];
441
    }];
442

  
443
    [request startAsynchronous];
444
}
445

  
446
- (void)getContainers {
447
    if (![self queue]) {
448
        [self setQueue:[[[NSOperationQueue alloc] init] autorelease]];
449
    }
450
    
451
    GetContainersRequest *request = [GetContainersRequest request:self.account];
452
    //[request startAsynchronous];
453
    [queue addOperation:request];
420
    return [self callbackWithRequest:request];        
454 421
}
455 422

  
456
- (APICallback *)getContainersWithCallback {
423
- (APICallback *)getContainers {
457 424
    __block OpenStackRequest *request = [OpenStackRequest filesRequest:self.account method:@"GET" path:@""];
458 425
    return [self callbackWithRequest:request];    
459 426
}
460 427

  
461
- (void)createContainer:(Container *)container {
428
- (APICallback *)createContainer:(Container *)container {
462 429
    TrackEvent(CATEGORY_CONTAINERS, EVENT_CREATED);
463
    
464
    OpenStackRequest *request = [OpenStackRequest createContainerRequest:self.account container:container];
465
    request.delegate = self;
466
    request.didFinishSelector = @selector(createContainerSucceeded:);
467
    request.didFailSelector = @selector(createContainerFailed:);
468
    request.userInfo = [NSDictionary dictionaryWithObject:container forKey:@"container"];
469
    [request startAsynchronous];
470
}
471 430

  
472
- (void)createContainerSucceeded:(OpenStackRequest *)request {
473
    if ([request isSuccess]) {        
474
        Container *container = [request.userInfo objectForKey:@"container"];
475
        container.metadata = [NSMutableDictionary dictionary];
431
    __block OpenStackRequest *request = [OpenStackRequest createContainerRequest:self.account container:container];
432
    return [self callbackWithRequest:request success:^(OpenStackRequest *request) {
433
        
476 434
        [self.account.containers setObject:container forKey:container.name];        
477 435
        [self.account persist];
478
        self.account.containerCount = [self.account.containers count];
479
        [self notify:@"createContainerSucceeded" request:request object:self.account];
480
    } else {
481
        [self notify:@"createContainerFailed" request:request object:self.account];
482
    }
483
}
484

  
485
- (void)createContainerFailed:(OpenStackRequest *)request {
486
    [self notify:@"createContainerFailed" request:request object:self.account];
436
        self.account.containerCount = [self.account.containers count];        
437
    }];
487 438
}
488 439

  
489
- (void)deleteContainer:(Container *)container {
440
- (APICallback *)deleteContainer:(Container *)container {
490 441
    TrackEvent(CATEGORY_CONTAINERS, EVENT_DELETED);
442
    __block OpenStackRequest *request = [OpenStackRequest deleteContainerRequest:self.account container:container];
443
    return [self callbackWithRequest:request];
491 444
    
492
    OpenStackRequest *request = [OpenStackRequest deleteContainerRequest:self.account container:container];
493
    request.delegate = self;
494
    request.didFinishSelector = @selector(deleteContainerSucceeded:);
495
    request.didFailSelector = @selector(deleteContainerFailed:);
496
    request.userInfo = [NSDictionary dictionaryWithObject:container forKey:@"container"];
497
    [request startAsynchronous];
498
}
499

  
500
- (void)deleteContainerSucceeded:(OpenStackRequest *)request {
501
    if ([request isSuccess] || [request responseStatusCode] == 404) {
502
        Container *container = [request.userInfo objectForKey:@"container"];
503
        [self.account.containers setObject:container forKey:container.name];                
504
        [self.account persist];        
505
        [self notify:@"deleteContainerSucceeded" request:request object:self.account];
506
        [self notify:@"deleteContainerSucceeded" request:request object:[request.userInfo objectForKey:@"container"]];
507
    } else {
508
        [self notify:@"deleteContainerFailed" request:request object:self.account];
509
        [self notify:@"deleteContainerFailed" request:request object:[request.userInfo objectForKey:@"container"]];
510
    }
511
}
512

  
513
- (void)deleteContainerFailed:(OpenStackRequest *)request {
514
    [self notify:@"deleteContainerFailed" request:request object:self.account];
515
    [self notify:@"deleteContainerFailed" request:request object:[request.userInfo objectForKey:@"container"]];
516 445
}
517 446

  
518 447
- (void)getObjects:(Container *)container {
......
523 452
       afterMarker:(NSString *)marker
524 453
     objectsBuffer:(NSMutableDictionary *)objectsBuffer {
525 454
    if (![self queue]) {
526
        [self setQueue:[[[NSOperationQueue alloc] init] autorelease]];
455
        [self setQueue:(ASINetworkQueue *)[[[NSOperationQueue alloc] init] autorelease]];
527 456
    }    
528 457
    GetObjectsRequest *request = [GetObjectsRequest request:self.account container:container marker:marker objectsBuffer:objectsBuffer];
529 458
    [queue addOperation:request];
......
533 462
    TrackEvent(CATEGORY_CONTAINERS, EVENT_UPDATED);
534 463
    
535 464
    if (![self queue]) {
536
        [self setQueue:[[[NSOperationQueue alloc] init] autorelease]];
465
        [self setQueue:(ASINetworkQueue *)[[[NSOperationQueue alloc] init] autorelease]];
537 466
    }
538 467
    UpdateCDNContainerRequest *request = [UpdateCDNContainerRequest request:self.account container:container];
539 468
    [queue addOperation:request];
......
560 489
    [[NSNotificationCenter defaultCenter] postNotification:notification];
561 490
}
562 491

  
563
- (void)getObjectInfo:(Container *)container object:(StorageObject *)object {
564
    OpenStackRequest *request = [OpenStackRequest getObjectInfoRequest:self.account container:container object:object];
565
    request.delegate = self;
566
    request.didFinishSelector = @selector(getObjectInfoSucceeded:);
567
    request.didFailSelector = @selector(getObjectInfoFailed:);
568
    request.userInfo = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:container, object, nil] forKeys:[NSArray arrayWithObjects:@"container", @"object", nil]];
569
    [request startAsynchronous];
570
}
571

  
572
- (void)getObjectInfoSucceeded:(OpenStackRequest *)request {
573
    if ([request isSuccess]) {
574
        NSNotification *notification = [NSNotification notificationWithName:@"getObjectInfoSucceeded" object:[request.userInfo objectForKey:@"object"] userInfo:[NSDictionary dictionaryWithObject:request forKey:@"request"]];
575
        [[NSNotificationCenter defaultCenter] postNotification:notification];
576
    } else {
577
        NSNotification *notification = [NSNotification notificationWithName:@"getObjectInfoFailed" object:self.account userInfo:[NSDictionary dictionaryWithObject:request forKey:@"request"]];
578
        [[NSNotificationCenter defaultCenter] postNotification:notification];
579
    }
580
}
581

  
582
- (void)getObjectInfoFailed:(OpenStackRequest *)request {
583
    NSNotification *notification = [NSNotification notificationWithName:@"getObjectInfoFailed" object:self.account userInfo:[NSDictionary dictionaryWithObject:request forKey:@"request"]];
584
    [[NSNotificationCenter defaultCenter] postNotification:notification];
492
- (APICallback *)getObjectInfo:(Container *)container object:(StorageObject *)object {    
493
    __block OpenStackRequest *request = [OpenStackRequest getObjectInfoRequest:self.account container:container object:object];
494
    return [self callbackWithRequest:request];
585 495
}
586 496

  
587
- (void)getObject:(Container *)container object:(StorageObject *)object downloadProgressDelegate:(id)downloadProgressDelegate {
588
    OpenStackRequest *request = [OpenStackRequest getObjectRequest:self.account container:container object:object];
497
- (APICallback *)getObject:(Container *)container object:(StorageObject *)object downloadProgressDelegate:(id)downloadProgressDelegate {
498
    __block OpenStackRequest *request = [OpenStackRequest getObjectRequest:self.account container:container object:object];
589 499
    request.delegate = self;
590 500
    request.downloadProgressDelegate = downloadProgressDelegate;
591 501
    request.showAccurateProgress = YES;    
592
    request.didFinishSelector = @selector(getObjectSucceeded:);
593
    request.didFailSelector = @selector(getObjectFailed:);
594
    request.userInfo = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:container, object, nil] forKeys:[NSArray arrayWithObjects:@"container", @"object", nil]];
595
    [request startAsynchronous];
596
}
597

  
598
- (void)getObjectSucceeded:(OpenStackRequest *)request {
599
    if ([request isSuccess]) {
600
        Container *container = [request.userInfo objectForKey:@"container"];
601
        StorageObject *object = [request.userInfo objectForKey:@"object"];
502
    return [self callbackWithRequest:request success:^(OpenStackRequest *request) {
503
        
602 504
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
603 505
        NSString *documentsDirectory = [paths objectAtIndex:0];        
604 506
        NSString *shortPath = [NSString stringWithFormat:@"/%@/%@", container.name, object.fullPath];
605 507
        NSString *filePath = [documentsDirectory stringByAppendingString:shortPath];
606 508
        NSString *directoryPath = [filePath stringByReplacingOccurrencesOfString:[NSString stringWithFormat:@"/%@", object.name] withString:@""];
607

  
509
        
608 510
        NSFileManager *fileManager = [NSFileManager defaultManager];
609 511
        if ([fileManager createDirectoryAtPath:directoryPath withIntermediateDirectories:YES attributes:nil error:nil]) {
610
            NSData *data = [request responseData];
611
            if ([data writeToFile:filePath atomically:YES]) {
612
                NSNotification *notification = [NSNotification notificationWithName:@"getObjectSucceeded" object:self.account userInfo:[NSDictionary dictionaryWithObject:request forKey:@"request"]];
613
                [[NSNotificationCenter defaultCenter] postNotification:notification];
614
            } else {
615
                NSNotification *notification = [NSNotification notificationWithName:@"getObjectFailed" object:self.account userInfo:[NSDictionary dictionaryWithObject:request forKey:@"request"]];
616
                [[NSNotificationCenter defaultCenter] postNotification:notification];
617
            }
618
        } else {
619
            NSNotification *notification = [NSNotification notificationWithName:@"getObjectFailed" object:self.account userInfo:[NSDictionary dictionaryWithObject:request forKey:@"request"]];
620
            [[NSNotificationCenter defaultCenter] postNotification:notification];
512
            
513
            [[request responseData] writeToFile:filePath atomically:YES];
514
            
621 515
        }
622
    } else {
623
        NSNotification *notification = [NSNotification notificationWithName:@"getObjectFailed" object:self.account userInfo:[NSDictionary dictionaryWithObject:request forKey:@"request"]];
624
        [[NSNotificationCenter defaultCenter] postNotification:notification];
625
    }
626
}
627 516

  
628
- (void)getObjectFailed:(OpenStackRequest *)request {
629
    NSNotification *notification = [NSNotification notificationWithName:@"getObjectFailed" object:self.account userInfo:[NSDictionary dictionaryWithObject:request forKey:@"request"]];
630
    [[NSNotificationCenter defaultCenter] postNotification:notification];
517
    }];
631 518
}
632 519

  
633
- (void)writeObject:(Container *)container object:(StorageObject *)object downloadProgressDelegate:(id)downloadProgressDelegate {
520
- (APICallback *)writeObject:(Container *)container object:(StorageObject *)object downloadProgressDelegate:(id)downloadProgressDelegate {
634 521
    TrackEvent(CATEGORY_FILES, EVENT_CREATED);
635 522
    
636
    OpenStackRequest *request = [OpenStackRequest writeObjectRequest:self.account container:container object:object];
523
    __block OpenStackRequest *request = [OpenStackRequest writeObjectRequest:self.account container:container object:object];
637 524
    request.delegate = self;
638
    request.didFinishSelector = @selector(writeObjectSucceeded:);
639
    request.didFailSelector = @selector(writeObjectFailed:);
640 525
    request.uploadProgressDelegate = downloadProgressDelegate;
641 526
    request.showAccurateProgress = YES;
642
    request.userInfo = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:container, object, nil] forKeys:[NSArray arrayWithObjects:@"container", @"object", nil]];
643
    [request startAsynchronous];
644
}
645

  
646
- (void)writeObjectSucceeded:(OpenStackRequest *)request {
647
    if ([request isSuccess]) {
648
        NSNotification *notification = [NSNotification notificationWithName:@"writeObjectSucceeded" object:[request.userInfo objectForKey:@"object"] userInfo:[NSDictionary dictionaryWithObject:request forKey:@"request"]];
649
        [[NSNotificationCenter defaultCenter] postNotification:notification];
650
    } else {
651
        NSNotification *notification = [NSNotification notificationWithName:@"writeObjectFailed" object:[request.userInfo objectForKey:@"object"] userInfo:[NSDictionary dictionaryWithObject:request forKey:@"request"]];
652
        [[NSNotificationCenter defaultCenter] postNotification:notification];
653
    }
654
}
655

  
656
- (void)writeObjectFailed:(OpenStackRequest *)request {
657
    NSNotification *notification = [NSNotification notificationWithName:@"writeObjectFailed" object:[request.userInfo objectForKey:@"object"] userInfo:[NSDictionary dictionaryWithObject:request forKey:@"request"]];
658
    [[NSNotificationCenter defaultCenter] postNotification:notification];
659
}
660

  
661
- (void)writeObjectMetadata:(Container *)container object:(StorageObject *)object {
662
    OpenStackRequest *request = [OpenStackRequest writeObjectMetadataRequest:self.account container:container object:object];
663
    request.delegate = self;
664
    request.didFinishSelector = @selector(writeObjectMetadataSucceeded:);
665
    request.didFailSelector = @selector(writeObjectMetadataFailed:);
666
    request.userInfo = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:container, object, nil] forKeys:[NSArray arrayWithObjects:@"container", @"object", nil]];
667
    [request startAsynchronous];
668
}
669

  
670
- (void)writeObjectMetadataSucceeded:(OpenStackRequest *)request {
671
    if ([request isSuccess]) {
672
        NSNotification *notification = [NSNotification notificationWithName:@"writeObjectMetadataSucceeded" object:[request.userInfo objectForKey:@"object"] userInfo:[NSDictionary dictionaryWithObject:request forKey:@"request"]];
673
        [[NSNotificationCenter defaultCenter] postNotification:notification];
674
    } else {
675
        NSNotification *notification = [NSNotification notificationWithName:@"writeObjectMetadataFailed" object:[request.userInfo objectForKey:@"object"] userInfo:[NSDictionary dictionaryWithObject:request forKey:@"request"]];
676
        [[NSNotificationCenter defaultCenter] postNotification:notification];
677
    }
678
}
679

  
680
- (void)writeObjectMetadataFailed:(OpenStackRequest *)request {
681
    NSNotification *notification = [NSNotification notificationWithName:@"writeObjectMetadataFailed" object:[request.userInfo objectForKey:@"object"] userInfo:[NSDictionary dictionaryWithObject:request forKey:@"request"]];
682
    [[NSNotificationCenter defaultCenter] postNotification:notification];
683
}
684

  
685
- (void)deleteObject:(Container *)container object:(StorageObject *)object {
686
    TrackEvent(CATEGORY_FILES, EVENT_DELETED);
687 527
    
688
    OpenStackRequest *request = [OpenStackRequest deleteObjectRequest:self.account container:container object:object];
689
    request.delegate = self;
690
    request.didFinishSelector = @selector(deleteObjectSucceeded:);
691
    request.didFailSelector = @selector(deleteObjectFailed:);
692
    request.userInfo = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:container, object, nil] forKeys:[NSArray arrayWithObjects:@"container", @"object", nil]];
693
    [request startAsynchronous];
694
}
695

  
696
- (void)deleteObjectSucceeded:(OpenStackRequest *)request {
697
    if ([request isSuccess] || [request responseStatusCode] == 404) {
698
        NSNotification *notification = [NSNotification notificationWithName:@"deleteObjectSucceeded" object:[request.userInfo objectForKey:@"object"] userInfo:[NSDictionary dictionaryWithObject:request forKey:@"request"]];
699
        [[NSNotificationCenter defaultCenter] postNotification:notification];
700
    } else {
701
        NSNotification *notification = [NSNotification notificationWithName:@"deleteObjectFailed" object:[request.userInfo objectForKey:@"object"] userInfo:[NSDictionary dictionaryWithObject:request forKey:@"request"]];
702
        [[NSNotificationCenter defaultCenter] postNotification:notification];
703
    }
704
}
705

  
706
- (void)deleteObjectFailed:(OpenStackRequest *)request {
707
    NSNotification *notification = [NSNotification notificationWithName:@"deleteObjectFailed" object:[request.userInfo objectForKey:@"object"] userInfo:[NSDictionary dictionaryWithObject:request forKey:@"request"]];
708
    [[NSNotificationCenter defaultCenter] postNotification:notification];
528
    return [self callbackWithRequest:request];
709 529
}
710 530

  
711

  
712
- (void)writeAccountMetadata:(NSDictionary *)accountInfo {
713
    OpenStackRequest *request = [OpenStackRequest writeAccountMetadataRequest:self.account withAccountInfo:accountInfo];
531
- (APICallback *)deleteObject:(Container *)container object:(StorageObject *)object {
532
    TrackEvent(CATEGORY_FILES, EVENT_DELETED);
714 533
    
715
    request.delegate = self;
716
    request.didFinishSelector = @selector(writeAccountMetadataSucceeded:);
717
    request.didFailSelector = @selector(writeAccountMetadataFailed:);
718
    [request startAsynchronous];
719
}
720

  
721
- (void)writeAccountMetadataSucceeded:(OpenStackRequest *)request
722
{
723
    if ([request isSuccess]) {
724
        NSNotification *notification = [NSNotification notificationWithName:@"writeAccountMetadataRequestSucceeded" object:self.account userInfo:[NSDictionary dictionaryWithObject:request forKey:@"request"]];
725
        [[NSNotificationCenter defaultCenter] postNotification:notification];
726
    } else {
727
        NSNotification *notification = [NSNotification notificationWithName:@"writeAccountMetadataRequestFailed" object:self.account userInfo:[NSDictionary dictionaryWithObject:request forKey:@"request"]];
728
        [[NSNotificationCenter defaultCenter] postNotification:notification];
729
    }
730
}
731

  
732
- (void)writeAccountMetadataFailed:(OpenStackRequest *)request
733
{
734
    NSNotification *notification = [NSNotification notificationWithName:@"writeAccountMetadataRequestFailed" object:[request.userInfo objectForKey:@"container"] userInfo:[NSDictionary dictionaryWithObject:request forKey:@"request"]];
735
    [[NSNotificationCenter defaultCenter] postNotification:notification];
534
    __block OpenStackRequest *request = [OpenStackRequest deleteObjectRequest:self.account container:container object:object];
535
    return [self callbackWithRequest:request];
736 536
}
737 537

  
738
- (void)writeContainerPolicy:(Container *)container {
739
    OpenStackRequest *request = [OpenStackRequest writeContainerPolicyRequest:self.account container:container];
740

  
741
    request.delegate = self;
742
    request.didFinishSelector = @selector(writeContainerPolicySucceeded:);
743
    request.didFailSelector = @selector(writeContainerPolicyFailed:);
744
    request.userInfo = [NSDictionary dictionaryWithObject:container forKey:@"container"];
745
    [request startAsynchronous];
538
- (APICallback *)writeObjectMetadata:(Container *)container object:(StorageObject *)object {
539
    __block OpenStackRequest *request = [OpenStackRequest writeObjectMetadataRequest:self.account container:container object:object];
540
    return [self callbackWithRequest:request];
746 541
}
747 542

  
748
- (void)writeContainerPolicySucceeded:(OpenStackRequest *)request {
749
    if ([request isSuccess]) {
750
        NSNotification *notification = [NSNotification notificationWithName:@"writeContainerPolicySucceeded" object:[request.userInfo objectForKey:@"container"] userInfo:[NSDictionary dictionaryWithObject:request forKey:@"request"]];
751
        [[NSNotificationCenter defaultCenter] postNotification:notification];
752
    } else {
753
        NSNotification *notification = [NSNotification notificationWithName:@"writeContainerPolicyFailed" object:[request.userInfo objectForKey:@"container"] userInfo:[NSDictionary dictionaryWithObject:request forKey:@"request"]];
754
        [[NSNotificationCenter defaultCenter] postNotification:notification];
755
    }
543
- (APICallback *)writeAccountMetadata:(NSDictionary *)accountInfo {
544
    __block OpenStackRequest *request = [OpenStackRequest writeAccountMetadataRequest:self.account withAccountInfo:accountInfo];
545
    return [self callbackWithRequest:request];
756 546
}
757 547

  
758
- (void)writeContainerPolicyFailed:(OpenStackRequest *)request {
759
    NSNotification *notification = [NSNotification notificationWithName:@"writeContainerPolicyFailed" object:[request.userInfo objectForKey:@"container"] userInfo:[NSDictionary dictionaryWithObject:request forKey:@"request"]];
760
    [[NSNotificationCenter defaultCenter] postNotification:notification];
548
- (APICallback *)writeContainerPolicy:(Container *)container {
549
    __block OpenStackRequest *request = [OpenStackRequest writeContainerPolicyRequest:self.account container:container];
550
    return [self callbackWithRequest:request];
761 551
}
762 552

  
763

  
764 553
#pragma mark -
765 554
#pragma mark Load Balancing
766 555

  
b/Classes/AccountSettingsViewController.m
228 228
    } else {
229 229
        cell = (RSTextFieldCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
230 230
        if (cell == nil) {
231
            cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
231
            cell = [[[RSTextFieldCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
232 232
        }
233 233
        
234 234
        cell.textLabel.text = @"Get Token";
b/Classes/AddContainerViewController.m
13 13
#import "Container.h"
14 14
#import "AccountManager.h"
15 15
#import "RSTextFieldCell.h"
16
#import "APICallback.h"
16 17

  
17 18

  
18 19
@implementation AddContainerViewController
......
80 81

  
81 82
        Container *container = [[Container alloc] init];
82 83
        container.name = nameTextField.text;
83
        [self.account.manager createContainer:container];
84
        [[self.account.manager createContainer:container] 
85
         success:^(OpenStackRequest *request) {
86
             [self.containersViewController hideToolbarActivityMessage];
87
             if (!account.sharingAccount)
88
                 [self.containersViewController showToolbarInfoMessage:self.containersViewController.accountUsageInfo];
89
             [self.containersViewController.tableView reloadData];
90
         }
91
         failure:^(OpenStackRequest *request) {
92
             [self.containersViewController hideToolbarActivityMessage];
93
             if (!account.sharingAccount)
94
                 [self.containersViewController showToolbarInfoMessage:self.containersViewController.accountUsageInfo];
95
             [self.containersViewController alert:@"There was a problem creating your container." request:request];
96
         }];
84 97
        [container release];
85
        
86 98
        [self dismissModalViewControllerAnimated:YES];
87 99
    }
88 100
}
b/Classes/AddFileViewController.m
262 262
        vc.isFromCamera = (picker.sourceType == UIImagePickerControllerSourceTypeCamera);
263 263
        [self.navigationController pushViewController:vc animated:NO];
264 264
        [vc release];
265
        [image release];
265 266
    }
266 267
    
267 268
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
b/Classes/AddFolderViewController.m
16 16
#import "Folder.h"
17 17
#import "StorageObject.h"
18 18
#import "FolderViewController.h"
19
#import "APICallback.h"
19 20

  
20 21

  
21 22
@implementation AddFolderViewController
......
53 54
            BOOL objectNameHasTrailingSlash = [textField.text hasSuffix:@"/"];
54 55
            NSUInteger indexOfFirstSlash = [textField.text rangeOfString:@"/"].location;
55 56
            
56
            if (!objectNameHasTrailingSlash && indexOfFirstSlash != NSNotFound || 
57
                objectNameHasTrailingSlash && indexOfFirstSlash < textField.text.length - 1) {
57
            if ((!objectNameHasTrailingSlash && indexOfFirstSlash != NSNotFound) || 
58
                (objectNameHasTrailingSlash && indexOfFirstSlash < textField.text.length - 1)) {
58 59
                [self alert:@"Invalid folder name" message:@"'/' characters are only allowed at the end of folder names"];
59 60
                return;
60 61
            }
......
90 91
            object.data = [NSData data];
91 92
            object.contentType = @"application/directory";
92 93

  
93
            [self.account.manager writeObject:self.container object:object downloadProgressDelegate:nil];
94
            
95
            // observe completion and remove activity view and dismiss the modal view controller
96
            successObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"writeObjectSucceeded" object:object 
97
                                                                                 queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notification)
98
            {
99
                Folder *newFolder = [[Folder alloc] init];
100
                if (objectNameHasTrailingSlash)
101
                    object.name = [object.name substringToIndex:object.name.length - 1];
102
                newFolder.name = [[object.name componentsSeparatedByString:@"/"] lastObject];
103
                if (objectNameHasTrailingSlash)
104
                    newFolder.name = [newFolder.name stringByAppendingString:@"/"];
105
                newFolder.parent = folder;
106
                newFolder.sharing = folder.sharing;
107
                [folder.folders setObject:newFolder forKey:newFolder.name];
108
                [folderViewController.tableView reloadData];
109
                allowOverwrite = NO;
110
                [activityIndicatorView removeFromSuperviewAndRelease];
111
                [self dismissModalViewControllerAnimated:YES];
112
                [newFolder release];
113
                [object release];
114
                [[NSNotificationCenter defaultCenter] removeObserver:successObserver];
115
            }];
116
            
117
            failureObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"writeObjectFailed" object:object 
118
                                                                                 queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notification)
119
            {
120
                allowOverwrite = NO;
121
                [activityIndicatorView removeFromSuperviewAndRelease];
122
                [self alert:@"There was a problem creating this folder." request:[notification.userInfo objectForKey:@"request"]];
123
                [object release];
124
                [[NSNotificationCenter defaultCenter] removeObserver:failureObserver];
125
            }];
126
            
94
            [[self.account.manager writeObject:self.container object:object downloadProgressDelegate:nil]
95
             success:^(OpenStackRequest *request) {
96
                 Folder *newFolder = [[Folder alloc] init];
97
                 if (objectNameHasTrailingSlash)
98
                     object.name = [object.name substringToIndex:object.name.length - 1];
99
                 newFolder.name = [[object.name componentsSeparatedByString:@"/"] lastObject];
100
                 if (objectNameHasTrailingSlash)
101
                     newFolder.name = [newFolder.name stringByAppendingString:@"/"];
102
                 newFolder.parent = folder;
103
                 newFolder.sharing = folder.sharing;
104
                 BOOL currentFolderIsRoot;
105
                 if ([folderViewController.folder isEqual:container.rootFolder]) {
106
                     currentFolderIsRoot = YES;
107
                 }
108
                 [folder.folders setObject:newFolder forKey:newFolder.name];
109
                 [folderViewController.tableView reloadData];
110
                 if (currentFolderIsRoot) {
111
                     container.count += 1;
112
                     container.rootFolder = folder;
113
                     [self.account.containers setObject:container forKey:container.name];
114
                 }
115
                 if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
116
                     [folderViewController setDetailViewController];
117
                 
118
                 allowOverwrite = NO;
119
                 [activityIndicatorView removeFromSuperviewAndRelease];
120
                 [self dismissModalViewControllerAnimated:YES];
121
                 [newFolder release];
122
                 [object release];
123
 
124
             }
125
             failure:^(OpenStackRequest *request) {
126
                 allowOverwrite = NO;
127
                 [activityIndicatorView removeFromSuperviewAndRelease];
128
                 [self alert:@"There was a problem creating this folder." request:request];
129
                 [object release];
130
             }];
127 131
        }
128 132
    }
129 133
}
b/Classes/AddLoadBalancerAlgorithmViewController.m
133 133
    UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
134 134
    if (cell == nil) {
135 135
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
136
        cell.selectionStyle = UITableViewCellEditingStyleNone;
136
        cell.selectionStyle = UITableViewCellSelectionStyleNone;
137 137
        
138 138
        loadBalancerIcon = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"load-balancers-icon.png"]];
139 139
        loadBalancerIcon.center = cell.center;
b/Classes/AddPhotoViewController.m
18 18
#import "Folder.h"
19 19
#import "FolderViewController.h"
20 20
#import "NSObject+Conveniences.h"
21
#import "APICallback.h"
21 22

  
22 23
#define kName 0
23 24

  
......
354 355
    BOOL objectNameHasTrailingSlash = [objectName hasSuffix:@"/"];
355 356
    NSUInteger indexOfFirstSlash = [objectName rangeOfString:@"/"].location;
356 357
    
357
    if (!objectNameHasTrailingSlash && indexOfFirstSlash != NSNotFound || 
358
        objectNameHasTrailingSlash && indexOfFirstSlash < objectName.length - 1) {
358
    if ((!objectNameHasTrailingSlash && indexOfFirstSlash != NSNotFound) || 
359
        (objectNameHasTrailingSlash && indexOfFirstSlash < objectName.length - 1)) {
359 360
        [self alert:@"Invalid file name" message:@"'/' characters are only allowed at the end of file names"];
360 361
        return;
361 362
    }
......
389 390
    object.data = data;
390 391
    object.bytes = [data length];
391 392
    
392
    [self.account.manager writeObject:self.container object:object downloadProgressDelegate:activityIndicatorView.progressView];
393

  
394
    successObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"writeObjectSucceeded" object:object queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification* notification) 
395
        {
396
            [activityIndicatorView removeFromSuperviewAndRelease];
397
            object.data = nil;
398
            object.sharing = folder.sharing;
399
            [folder.objects setObject:object forKey:object.name];
400
            [folderViewController.tableView reloadData];
401
            allowOverwrite = NO;
402
            [self dismissModalViewControllerAnimated:YES];
403
            [[NSNotificationCenter defaultCenter] removeObserver:successObserver];
404
        }];
405

  
406
    failureObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"writeObjectFailed" object:object queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification* notification) 
407
        {
408
            [activityIndicatorView removeFromSuperviewAndRelease];
409
            allowOverwrite = NO;
410
            [self alert:@"There was a problem uploading this file." request:[notification.userInfo objectForKey:@"request"]];            
411
            [[NSNotificationCenter defaultCenter] removeObserver:failureObserver];
412
        }];
393
    [[self.account.manager writeObject:self.container object:object downloadProgressDelegate:activityIndicatorView.progressView]
394
     success:^(OpenStackRequest *request) {
395
         [activityIndicatorView removeFromSuperviewAndRelease];
396
         object.data = nil;
397
         object.sharing = folder.sharing;
398
         BOOL currentFolderIsRoot;
399
         if ([folderViewController.folder isEqual:container.rootFolder]) {
400
             currentFolderIsRoot = YES;
401
         }
402
         [folder.objects setObject:object forKey:object.name];
403
         [folderViewController.tableView reloadData];
404
         if (currentFolderIsRoot) {
405
             container.count += 1;
406
             container.rootFolder = folder;
407
             [self.account.containers setObject:container forKey:container.name];
408
         }
409
         if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
410
             [folderViewController setDetailViewController];
411
         allowOverwrite = NO;
412
         [self dismissModalViewControllerAnimated:YES];
413
     }
414
     failure:^(OpenStackRequest *request) {
415
         [activityIndicatorView removeFromSuperviewAndRelease];
416
         allowOverwrite = NO;
417
         [self alert:@"There was a problem uploading this file." request:request];            
418
     }];
413 419
}
414 420

  
415 421
#pragma mark - Alertview delegate
b/Classes/Archiver.m
15 15
    NSString *documentsDirectory = [paths objectAtIndex:0];
16 16
    NSString *filePath = [documentsDirectory stringByAppendingString:[NSString stringWithFormat:@"/%@.archive", key]];
17 17
//    NSLog(@"filepath: %@", filePath);
18
    return [[NSKeyedUnarchiver unarchiveObjectWithFile:filePath] retain];
18
    return [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
19 19
    /* TODO: fixme on potential leak - "retrieve" doesn't match copy or alloc pattern, and hence should be returning autoreleased object
20 20
     * Not changing right now, but documenting for later fixing - need to see how and where [Archiver.. retrieve:key] is used to make sure 
21 21
     * switching this won't cause a crash
b/Classes/ContainerDetailViewController.m
20 20
#import "EditPolicyViewController.h"
21 21
#import "Folder.h"
22 22
#import "FolderViewController.h"
23
#import "OpenStackRequest.h"
24
#import "APICallback.h"
23 25

  
24 26
#define kOverview 0
25 27
#define kMetadata 1
......
398 400
            cell.textLabel.text = @"Versioning";
399 401
            cell.detailTextLabel.text = container.versioning;
400 402
            cell.accessoryType = UITableViewCellAccessoryNone;
401
            cell.selectionStyle = UITableViewCellEditingStyleNone;
403
            cell.selectionStyle = UITableViewCellSelectionStyleNone;
402 404
        }
403 405
        else if (indexPath.row == 1) {
404 406
            cell.textLabel.text = @"Quota";
405 407
            cell.detailTextLabel.text = [NSString stringWithFormat:@"%u", container.quota];
406 408
            cell.accessoryType = UITableViewCellAccessoryNone;
407
            cell.selectionStyle = UITableViewCellEditingStyleNone;
409
            cell.selectionStyle = UITableViewCellSelectionStyleNone;
408 410
        }
409 411
        else {
410 412
            cell.textLabel.text = @"Edit policy";
......
622 624
         
623 625
            NSString *activityMessage = @"Deleting container...";
624 626
            activityIndicatorView = [[ActivityIndicatorView alloc] initWithFrame:[ActivityIndicatorView frameForText:activityMessage] text:activityMessage];
625
            [activityIndicatorView addToView:self.view scrollOffset:self.tableView.contentOffset.y];    
627
            [activityIndicatorView addToView:self.view scrollOffset:self.tableView.contentOffset.y];  
626 628
            
627
            [self.account.manager deleteContainer:self.container];
628
            
629
            successObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"deleteContainerSucceeded" object:self.container
630
                                                                                 queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification* notification) 
631
            {
632
                [activityIndicatorView removeFromSuperviewAndRelease];
633

  
629
            [[self.account.manager deleteContainer:self.container] success:^(OpenStackRequest *request) {
630
                
631
                [activityIndicatorView removeFromSuperviewAndRelease];                
634 632
                [self.account.containers removeObjectForKey:self.container.name];
635 633
                [self.account persist];
636
                
637
                /*if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad && [self.account.containers count] == 0) { 
638
                    // on ipad, delete needs to get rid of the container on the main view
639
                    self.container = nil;
640
                    [self setBackgroundView];
641
                    [self.tableView reloadData];
642
                } else {
643
                    [self.navigationController popViewControllerAnimated:YES];
644
                }*/
645 634
                if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
646 635
                    [self.containersViewController.navigationController popViewControllerAnimated:YES];
647 636
                else
648 637
                    [self.navigationController popViewControllerAnimated:YES];
649 638
                
650 639
                [self deleteContainerRow];
651
                //[NSTimer scheduledTimerWithTimeInterval:0.75 target:self selector:@selector(deleteContainerRow) userInfo:nil repeats:NO];
640

  
652 641
                
653
                [[NSNotificationCenter defaultCenter] removeObserver:successObserver];
654
            }];
655
            
656
            failureObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"deleteContainerFailed" object:self.container
657
                                                                                 queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification* notification) 
658
            {
659
                [activityIndicatorView removeFromSuperviewAndRelease];
660
                [self alert:@"There was a problem deleting this container." request:[notification.userInfo objectForKey:@"request"]];
661
                [[NSNotificationCenter defaultCenter] removeObserver:failureObserver];
642
            } failure:^(OpenStackRequest *request) {
643
                
644
                // 404 Not Found means it's not there, so we can show the user that it's deleted
645
                if ([request responseStatusCode] == 404) {
646
                    [self.account.containers removeObjectForKey:container.name];
647
                    [self.account persist];
648
                    
649
                } else {
650
                    [activityIndicatorView removeFromSuperviewAndRelease];
651
                    [self alert:@"There was a problem deleting this container." request:request];
652
                }
662 653
            }];
663
            
654
                        
664 655
        }
665
        
666 656
        [self.tableView deselectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:deleteSection] animated:YES];
667 657
    }
668 658
}
b/Classes/ContainersViewController.h
14 14
@interface ContainersViewController : OpenStackViewController <UITableViewDelegate, UITableViewDataSource> {
15 15
    IBOutlet UITableView *tableView;
16 16
    OpenStackAccount *account;
17
    
18
    id successObserver;
19
    id failureObserver;
20
    
17
        
21 18
    IBOutlet UIBarButtonItem *refreshButton;
22 19
    
23 20
    id getContainersSucceededObserver;
b/Classes/ContainersViewController.m
51 51

  
52 52
- (void)viewWillAppear:(BOOL)animated {
53 53
    [super viewWillAppear:animated];
54
    
55
    successObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"createContainerSucceeded" object:self.account 
56
                                                                         queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notification)
57
       {
58
           [self hideToolbarActivityMessage];
59
           if (!account.sharingAccount)
60
               [self showToolbarInfoMessage:accountUsageInfo];
61
           [self.tableView reloadData];
62
       }];
63
    
64
    failureObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"createContainerFailed" object:self.account 
65
                                                                         queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notification)
66
       {
67
           [self hideToolbarActivityMessage];
68
           if (!account.sharingAccount)
69
               [self showToolbarInfoMessage:accountUsageInfo];
70
           [self alert:@"There was a problem creating your container." request:[notification.userInfo objectForKey:@"request"]];
71
       }];
72
    
54
        
73 55
    if ([self.account.containers count] == 0) {
74 56
        self.tableView.allowsSelection = NO;
75 57
        self.tableView.scrollEnabled = NO;
......
95 77

  
96 78
- (void)viewDidDisappear:(BOOL)animated {
97 79
    [super viewDidDisappear:animated];
98
    [[NSNotificationCenter defaultCenter] removeObserver:successObserver];
99
    [[NSNotificationCenter defaultCenter] removeObserver:failureObserver];
100 80
}
101 81

  
102 82
#pragma mark -
......
136 116
        [self hideToolbarInfoMessage];
137 117
    [self showToolbarActivityMessage:@"Refreshing containers..."];
138 118
    
139
    [[self.account.manager getContainersWithCallback] success:^(OpenStackRequest *request) {
119
    [[self.account.manager getContainers] success:^(OpenStackRequest *request) {
140 120
        self.account.containers = [request containers];
141 121
        self.account.containerCount = [self.account.containers count];
142 122
        self.account.totalBytesUsed = [[request.responseHeaders objectForKey:@"X-Account-Bytes-Used"] longLongValue];
......
303 283
    [self showToolbarActivityMessage:@"Creating container..."];
304 284
    Container *container = [[Container alloc] init];
305 285
    container.name = containerName;
306
    [self.account.manager createContainer:container];
286
    [[self.account.manager createContainer:container]
287
     success:^(OpenStackRequest *request) {
288
         [self hideToolbarActivityMessage];
289
         if (!account.sharingAccount)
290
             [self showToolbarInfoMessage:accountUsageInfo];
291
         [self.tableView reloadData];
292
     }
293
     failure:^(OpenStackRequest *request) {
294
         [self hideToolbarActivityMessage];
295
         if (!account.sharingAccount)
296
             [self showToolbarInfoMessage:accountUsageInfo];
297
         [self alert:@"There was a problem creating your container." request:request];
298
     }];
307 299
    [container release];
308 300
}
309 301

  
b/Classes/EditAccountGroupsViewController.h
49 49
    NSMutableDictionary *metadata;
50 50
    
51 51
    BOOL removeGroupEnabled;
52
    
53
    id successObserver;
54
    id failureObserver;
55
    
52
        
56 53
    ActivityIndicatorView *activityIndicatorView;
57 54
}
58 55

  
b/Classes/EditAccountGroupsViewController.m
39 39
#import "UIViewController+Conveniences.h"
40 40
#import "AccountManager.h"
41 41
#import "OpenStackRequest.h"
42
#import "APICallback.h"
42 43

  
43 44
#define kGroupDetails 0 
44 45
#define kSave 1
......
221 222
                                        metadata, @"metadata",
222 223
                                        nil
223 224
                                        ];
224
        [self.account.manager writeAccountMetadata:accountInfo];
225
        successObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"writeAccountMetadataRequestSucceeded"
226
                                                                            object:self.account
227
                                                                             queue:[NSOperationQueue mainQueue]
228
                                                                        usingBlock:^(NSNotification *notification)
229
                            {                                   
230
                                [activityIndicatorView removeFromSuperviewAndRelease];
231
                                self.groupName = newGroupName;
232
                                self.groupUsers = newGroupUsers;
233
                                self.removeGroupEnabled = YES;
234
                                self.navigationItem.title = @"Edit Group";
235
                                [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
236
                                [self.tableView reloadData];
237
                                [[NSNotificationCenter defaultCenter] removeObserver:successObserver];
238
                            }];
239
        
240
        failureObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"writeAccountMetadataRequestFailed" 
241
                                                                            object:self.account 
242
                                                                             queue:[NSOperationQueue mainQueue] 
243
                                                                        usingBlock:^(NSNotification *notification)
244
                            {
245
                                [activityIndicatorView removeFromSuperviewAndRelease];
246
                                [groups removeObjectForKey:newGroupName];
247
                                [groups setObject:self.groupUsers forKey:self.groupName];
248
                                [self.tableView reloadData];
249
                                [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
250
                                [self alert:@"There was a problem saving the group information." request:[notification.userInfo objectForKey:@"request"]];
251
                                   
252
                                [[NSNotificationCenter defaultCenter] removeObserver:failureObserver];
253
                            }];
225
        [[self.account.manager writeAccountMetadata:accountInfo] 
226
         success:^(OpenStackRequest *request) {
227
             [activityIndicatorView removeFromSuperviewAndRelease];
228
             self.groupName = newGroupName;
229
             self.groupUsers = newGroupUsers;
230
             self.removeGroupEnabled = YES;
231
             self.navigationItem.title = @"Edit Group";
232
             [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
233
             [self.tableView reloadData]; 
234
         }
235
         failure:^(OpenStackRequest *request) {
236
             [activityIndicatorView removeFromSuperviewAndRelease];
237
             [groups removeObjectForKey:newGroupName];
238
             [groups setObject:self.groupUsers forKey:self.groupName];
239
             [self.tableView reloadData];
240
             [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
241
             [self alert:@"There was a problem saving the group information." request:request];
242
         }];
254 243
    } else if (indexPath.section == kRemove) {
255 244
        activityMessage = @"Removing group";
256 245
        activityIndicatorView = [[ActivityIndicatorView alloc] initWithFrame:[ActivityIndicatorView frameForText:activityMessage] text:activityMessage];
......
262 251
                                        nil
263 252
                                        ];
264 253

  
265
        [self.account.manager writeAccountMetadata:accountInfo];
266
        successObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"writeAccountMetadataRequestSucceeded"
267
                                                                            object:self.account
268
                                                                             queue:[NSOperationQueue mainQueue]
269
                                                                        usingBlock:^(NSNotification *notification)
270
                            {
271
                                [activityIndicatorView removeFromSuperviewAndRelease];
272
                                self.groupName = @"";
273
                                self.groupUsers = @"";
274
                                self.removeGroupEnabled = NO;
275
                                [self.tableView reloadData];
276
                                [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
277
                                [[NSNotificationCenter defaultCenter] removeObserver:successObserver];
278
                            }];
279
        
280
        failureObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"writeAccountMetadataRequestFailed" 
281
                                                                            object:self.account 
282
                                                                             queue:[NSOperationQueue mainQueue] 
283
                                                                        usingBlock:^(NSNotification *notification)
284
                            {
285
                                [activityIndicatorView removeFromSuperviewAndRelease];
286
                                [groups setObject:groupUsers forKey:groupName];
287
                                [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
288
                                [self alert:@"There was a problem removing the group information." request:[notification.userInfo objectForKey:@"request"]];
289
                                   
290
                                [[NSNotificationCenter defaultCenter] removeObserver:failureObserver];
291
                            }];
254
        [[self.account.manager writeAccountMetadata:accountInfo] 
255
         success:^(OpenStackRequest *request) {
256
             [activityIndicatorView removeFromSuperviewAndRelease];
257
             self.groupName = @"";
258
             self.groupUsers = @"";
259
             self.removeGroupEnabled = NO;
260
             [self.tableView reloadData];
261
             [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
262
         }
263
         failure:^(OpenStackRequest *request) {
264
             [activityIndicatorView removeFromSuperviewAndRelease];
265
             [groups setObject:groupUsers forKey:groupName];
266
             [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
267
             [self alert:@"There was a problem removing the group information." request:request];
268
         }];
292 269
    }
293

  
294 270
}
295 271

  
296 272
#pragma mark - Textfield delegate
b/Classes/EditMetadataViewController.h
41 41
#import "StorageObject.h"
42 42
#import "ActivityIndicatorView.h"
43 43

  
44
@class FolderViewController;
44
@class FolderViewController, OpenStackRequest;
45 45

  
46 46
@interface EditMetadataViewController : UITableViewController <UITextFieldDelegate, UIAlertViewDelegate> {
47 47
    
......
55 55
    NSString *newMetadataValue;
56 56
    
57 57
    ActivityIndicatorView *activityIndicatorView;
58
    id successObserver;
59
    id failureObserver;
60
    id addFolderSuccessObserver;
61
    id addFolderFailureObserver;
62 58
    
63 59
    BOOL objectIsFolder;
64 60
    BOOL objectIsContainer;
......
78 74
@property (nonatomic, assign) BOOL removeMetadataEnabled;
79 75
@property (nonatomic, retain) FolderViewController *folderViewController;
80 76

  
81
- (void)addNewFolderRequestObservers;
77
- (void)createNewFolder;
82 78

  
83 79
@end
b/Classes/EditMetadataViewController.m
41 41
#import "FolderViewController.h"
42 42
#import "Folder.h"
43 43
#import "PithosUtilities.h"
44
#import "APICallback.h"
44 45

  
45 46

  
46 47

  
......
239 240
                    object.name = object.fullPath;
240 241
                    object.contentType = @"application/directory";
241 242
                    object.data = [NSData data];
242
                    [self addNewFolderRequestObservers];
243
                    [self.account.manager writeObject:self.container object:object downloadProgressDelegate:nil];  
243
                    [self createNewFolder];
244 244
                    return;
245 245
                }
246 246
            }
......
249 249
            activityIndicatorView = [[ActivityIndicatorView alloc] initWithFrame:[ActivityIndicatorView frameForText:activityMessage] text:activityMessage];
250 250
            [activityIndicatorView addToView:self.view];
251 251

  
252
            [self.account.manager writeObjectMetadata:container object:object];
253
            successObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"writeObjectMetadataSucceeded"
254
                                                                                object:object
255
                                                                                 queue:[NSOperationQueue mainQueue]
256
                                                                            usingBlock:^(NSNotification *notification)
257
                               {
258
                                   self.metadataKey = newMetadataKey;
259
                                   self.metadataValue = newMetadataValue;
260
                                   removeMetadataEnabled = YES;
261
                                   [self.tableView reloadData];
262
                                   [activityIndicatorView removeFromSuperviewAndRelease];
263
                                   [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
264
                                   if (objectIsContainer) {
265
                                       container.metadata = object.metadata;
266
                                       [self.account.containers setObject:container forKey:container.name];
267
                                   }
268
                                   [[NSNotificationCenter defaultCenter] removeObserver:successObserver];
269
                               }];
270
            
271
            failureObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"writeObjectMetadataFailed" 
272
                                                                                object:object 
273
                                                                                 queue:[NSOperationQueue mainQueue] 
274
                                                                            usingBlock:^(NSNotification *notification)
275
                               {
276
                                   [object.metadata removeObjectForKey:newMetadataKey];
277
                                   [object.metadata setObject:metadataValue forKey:metadataKey];
278
                                   [activityIndicatorView removeFromSuperviewAndRelease];
279
                                   [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
280
                                   [self alert:@"There was a problem saving the metadata." request:[notification.userInfo objectForKey:@"request"]];
281
                                   
282
                                   [[NSNotificationCenter defaultCenter] removeObserver:failureObserver];
283
                               }];
284
            
252
            [[self.account.manager writeObjectMetadata:container object:object] 
253
             success:^(OpenStackRequest *request) {
254
                 self.metadataKey = newMetadataKey;
255
                 self.metadataValue = newMetadataValue;
256
                 removeMetadataEnabled = YES;
257
                 [self.tableView reloadData];
258
                 [activityIndicatorView removeFromSuperviewAndRelease];
259
                 [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
260
                 if (objectIsContainer) {
261
                     container.metadata = object.metadata;
262
                     [self.account.containers setObject:container forKey:container.name];
263
                 }
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff