Hide or show keyboard, accordingly, on rotation when folder filter is active
[pithos-ios] / Classes / AccountManager.m
1 //
2 //  AccountManager.m
3 //  OpenStack
4 //
5 //  Created by Mike Mayo on 10/21/10.
6 //  The OpenStack project is provided under the Apache 2.0 license.
7 //
8
9 #import "AccountManager.h"
10 #import "OpenStackAccount.h"
11 #import "OpenStackRequest.h"
12 #import "Provider.h"
13 #import "Container.h"
14 #import "Folder.h"
15 #import "StorageObject.h"
16 #import "GetContainersRequest.h"
17 #import "GetObjectsRequest.h"
18 #import "ASINetworkQueue.h"
19 #import "APICallback.h"
20 #import "JSON.h"
21 #import "OpenStackAppDelegate.h"
22
23 @implementation AccountManager
24
25 @synthesize account, queue, objectDownloadRequests;
26
27 #pragma mark - Callbacks
28
29 - (APICallback *)callbackWithRequest:(id)request success:(APIResponseBlock)success failure:(APIResponseBlock)failure {
30     APICallback *callback = [[[APICallback alloc] initWithAccount:self.account request:request] autorelease];
31     ((OpenStackRequest *)request).delegate = self;
32     ((OpenStackRequest *)request).callback = callback; 
33
34     [request setCompletionBlock:^{
35         if ([request isSuccess]) {
36             success(request);
37             [request notify];
38         } else {
39             failure(request);
40             [request notify];
41         }
42     }];
43     [request setFailedBlock:^{
44         failure(request);
45         [request notify];
46     }];
47     [request startAsynchronous];    
48     return callback;
49 }
50
51 - (APICallback *)callbackWithRequest:(id)request success:(APIResponseBlock)success {
52     return [self callbackWithRequest:request success:success failure:^(OpenStackRequest *request){}];
53 }
54
55 - (APICallback *)callbackWithRequest:(id)request {
56     return [self callbackWithRequest:request success:^(OpenStackRequest *request){} failure:^(OpenStackRequest *request){}];
57 }
58
59 #pragma mark - Notification
60
61 - (NSString *)notificationName:(NSString *)key identifier:(NSString *)identifier {
62     return [NSString stringWithFormat:@"%@-%@-%@", key, self.account.uuid, identifier];
63 }
64
65 - (void)requestFinished:(OpenStackRequest *)request {
66     NSString *notificationName = [request.userInfo objectForKey:@"notificationName"];
67     if (!notificationName)
68         return;
69     
70     id notificationObject = [request.userInfo objectForKey:@"notificationObject"];
71     if ([request isSuccess]) {
72         NSNotification *notification = [NSNotification notificationWithName:[NSString stringWithFormat:@"%@Succeeded", notificationName] object:notificationObject];
73         [[NSNotificationCenter defaultCenter] postNotification:notification];
74     } else {
75         NSNotification *notification = [NSNotification notificationWithName:[NSString stringWithFormat:@"%@Failed", notificationName] object:notificationObject userInfo:[NSDictionary dictionaryWithObject:request forKey:@"request"]];
76         [[NSNotificationCenter defaultCenter] postNotification:notification];
77     }
78 }
79
80 - (void)requestFailed:(OpenStackRequest *)request {
81     NSString *notificationName = [request.userInfo objectForKey:@"notificationName"];
82     if (!notificationName)
83         return;
84     
85     id notificationObject = [request.userInfo objectForKey:@"notificationObject"];
86     NSNotification *notification = [NSNotification notificationWithName:[NSString stringWithFormat:@"%@Failed", notificationName] object:notificationObject userInfo:[NSDictionary dictionaryWithObject:request forKey:@"request"]];
87     [[NSNotificationCenter defaultCenter] postNotification:notification];
88 }
89
90 - (void)notify:(NSString *)name request:(OpenStackRequest *)request {
91     NSNotification *notification = [NSNotification notificationWithName:name object:nil userInfo:[NSDictionary dictionaryWithObject:request forKey:@"request"]];
92     [[NSNotificationCenter defaultCenter] postNotification:notification];
93 }
94
95 - (void)notify:(NSString *)name request:(OpenStackRequest *)request object:(id)object {
96     NSNotification *notification = [NSNotification notificationWithName:name object:object userInfo:[NSDictionary dictionaryWithObject:request forKey:@"request"]];
97     [[NSNotificationCenter defaultCenter] postNotification:notification];
98 }
99
100 #pragma mark - API Calls
101
102 #pragma mark Object Storage
103
104 - (APICallback *)getStorageAccountInfo {
105     __block OpenStackRequest *request = [OpenStackRequest getStorageAccountInfoRequest:self.account];
106     return [self callbackWithRequest:request success:^(OpenStackRequest *request) {        
107         self.account.containerCount = [[[request responseHeaders] objectForKey:@"X-Account-Container-Count"] intValue];
108         NSString *numStr = [[request responseHeaders] objectForKey:@"X-Account-Bytes-Used"];
109         self.account.totalBytesUsed = strtoull([numStr UTF8String], NULL, 0);
110         [self.account persist];
111         self.account.containerCount = [self.account.containers count];        
112     }];
113 }
114
115 - (APICallback *)getSharingAccounts {
116     __block OpenStackRequest *request = [OpenStackRequest getSharingAccountsRequest:self.account];
117     return [self callbackWithRequest:request];        
118 }
119
120 - (APICallback *)getContainers {
121     __block OpenStackRequest *request = [OpenStackRequest filesRequest:self.account method:@"GET" path:@""];
122     return [self callbackWithRequest:request];    
123 }
124
125 - (APICallback *)createContainer:(Container *)container {
126     __block OpenStackRequest *request = [OpenStackRequest createContainerRequest:self.account container:container];
127     return [self callbackWithRequest:request success:^(OpenStackRequest *request) {
128         
129         [self.account.containers setObject:container forKey:container.name];        
130         [self.account persist];
131         self.account.containerCount = [self.account.containers count];        
132     }];
133 }
134
135 - (APICallback *)deleteContainer:(Container *)container {
136     __block OpenStackRequest *request = [OpenStackRequest deleteContainerRequest:self.account container:container];
137     return [self callbackWithRequest:request];
138     
139 }
140
141 - (void)getObjects:(Container *)container {
142     [self getObjects:container afterMarker:nil objectsBuffer:nil];
143 }
144
145 - (void)getObjects:(Container *)container
146        afterMarker:(NSString *)marker
147      objectsBuffer:(NSMutableDictionary *)objectsBuffer {
148     if (![self queue]) {
149         [self setQueue:(ASINetworkQueue *)[[[NSOperationQueue alloc] init] autorelease]];
150     }    
151     GetObjectsRequest *request = [GetObjectsRequest request:self.account container:container marker:marker objectsBuffer:objectsBuffer];
152     [queue addOperation:request];
153 }
154
155 - (void)getObjectsSucceeded:(OpenStackRequest *)request {
156     if ([request isSuccess]) {
157         Container *container = [request.userInfo objectForKey:@"container"];
158         NSMutableDictionary *objects = [request objects];
159         container.rootFolder = [Folder folder];
160         container.rootFolder.objects = objects;
161         [self.account persist];
162         
163         NSNotification *notification = [NSNotification notificationWithName:@"getObjectsSucceeded" object:self.account userInfo:[NSDictionary dictionaryWithObject:container forKey:@"container"]];
164         [[NSNotificationCenter defaultCenter] postNotification:notification];
165     } else {
166         NSNotification *notification = [NSNotification notificationWithName:@"getObjectsFailed" object:self.account userInfo:[NSDictionary dictionaryWithObject:request forKey:@"request"]];
167         [[NSNotificationCenter defaultCenter] postNotification:notification];
168     }
169 }
170
171 - (void)getObjectsFailed:(OpenStackRequest *)request {
172     NSNotification *notification = [NSNotification notificationWithName:@"getObjectsFailed" object:self.account userInfo:[NSDictionary dictionaryWithObject:request forKey:@"request"]];
173     [[NSNotificationCenter defaultCenter] postNotification:notification];
174 }
175
176 - (APICallback *)getContainerInfo:(Container *)container {
177     __block OpenStackRequest *request = [OpenStackRequest getContainerInfoRequest:self.account container:container];
178     return [self callbackWithRequest:request];
179 }
180
181 - (APICallback *)getObjectInfo:(Container *)container object:(StorageObject *)object {    
182     __block OpenStackRequest *request = [OpenStackRequest getObjectInfoRequest:self.account container:container object:object];
183     return [self callbackWithRequest:request];
184 }
185
186 - (APICallback *)getObjectInfo:(Container *)container object:(StorageObject *)object version:(NSString *)version {
187     if (!version)
188         return [self getObjectInfo:container object:object];
189     
190     __block OpenStackRequest *request = [OpenStackRequest getObjectInfoRequest:self.account container:container object:object version:version];
191     return [self callbackWithRequest:request];
192 }
193
194 - (APICallback *)getObjectVersionsList:(Container *)container object:(StorageObject *)object {
195     __block OpenStackRequest *request = [OpenStackRequest getObjectVersionsRequest:account container:container object:object];
196     return [self callbackWithRequest:request];
197 }
198
199 - (APICallback *)getObject:(Container *)container object:(StorageObject *)object downloadProgressDelegate:(id)downloadProgressDelegate {
200     return [self getObject:container object:object downloadProgressDelegate:downloadProgressDelegate requestUserInfo:nil];
201 }
202
203 - (APICallback *)getObject:(Container *)container
204                     object:(StorageObject *)object
205   downloadProgressDelegate:(id)downloadProgressDelegate
206            requestUserInfo:(NSDictionary *)requestUserInfo {
207     
208     return [self getObject:container object:object downloadProgressDelegate:downloadProgressDelegate requestUserInfo:requestUserInfo version:nil];
209 }
210
211 - (APICallback *)getObject:(Container *)container
212                     object:(StorageObject *)object
213   downloadProgressDelegate:(id)downloadProgressDelegate 
214            requestUserInfo:(NSDictionary *)requestUserInfo
215                    version:(NSString *)version{
216     __block OpenStackRequest *request = [OpenStackRequest getObjectRequest:self.account container:container object:object version:version];
217     request.delegate = self;
218     request.downloadProgressDelegate = downloadProgressDelegate;
219     request.showAccurateProgress = YES;  
220     if (requestUserInfo) {
221         request.userInfo = requestUserInfo;
222     }
223     if (!objectDownloadRequests)
224         self.objectDownloadRequests = [NSMutableDictionary dictionary];
225     [objectDownloadRequests setObject:request forKey:object.fullPath];
226     return [self callbackWithRequest:request success:^(OpenStackRequest *request) {
227         OpenStackAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
228         NSString *filePath = [appDelegate.cacheDirectoryPath stringByAppendingFormat:@"/%@.%@",object.hash, object.name.pathExtension];
229         [[request responseData] writeToFile:filePath atomically:YES];
230         @synchronized(appDelegate.cachedObjectsDictionary) {
231             if (!object.hash)
232                 object.hash = [request.responseHeaders objectForKey:@"X-Object-Hash"];
233             [appDelegate.cachedObjectsDictionary setObject:filePath forKey:object.hash];
234             [appDelegate saveCacheDictionary];
235         }
236         [objectDownloadRequests removeObjectForKey:object.fullPath];
237     }
238     failure:^(OpenStackRequest *request) { 
239         [objectDownloadRequests removeObjectForKey:object.fullPath];
240     }];
241 }
242
243 - (APICallback *)writeObject:(Container *)container object:(StorageObject *)object downloadProgressDelegate:(id)downloadProgressDelegate {
244     __block OpenStackRequest *request = [OpenStackRequest writeObjectRequest:self.account container:container object:object];
245     request.delegate = self;
246     request.uploadProgressDelegate = downloadProgressDelegate;
247     request.showAccurateProgress = YES;
248     
249     return [self callbackWithRequest:request];
250 }
251
252 - (APICallback *)deleteObject:(Container *)container object:(StorageObject *)object {
253     __block OpenStackRequest *request = [OpenStackRequest deleteObjectRequest:self.account container:container object:object];
254     return [self callbackWithRequest:request];
255 }
256
257 - (APICallback *)writeObjectMetadata:(Container *)container object:(StorageObject *)object {
258     __block OpenStackRequest *request = [OpenStackRequest writeObjectMetadataRequest:self.account container:container object:object];
259     return [self callbackWithRequest:request];
260 }
261
262 - (APICallback *)writeAccountMetadata:(NSDictionary *)accountInfo {
263     __block OpenStackRequest *request = [OpenStackRequest writeAccountMetadataRequest:self.account withAccountInfo:accountInfo];
264     return [self callbackWithRequest:request];
265 }
266
267 - (APICallback *)writeContainerPolicy:(Container *)container {
268     __block OpenStackRequest *request = [OpenStackRequest writeContainerPolicyRequest:self.account container:container];
269     return [self callbackWithRequest:request];
270 }
271
272 #pragma mark -
273 #pragma mark Memory Management
274
275 - (void)dealloc {
276     [objectDownloadRequests release];
277     [super dealloc];
278 }
279
280 @end