root / pithos-macos / PithosAccountNode.m @ fb27f368
History | View | Annotate | Download (26 kB)
1 |
// |
---|---|
2 |
// PithosAccountNode.m |
3 |
// pithos-macos |
4 |
// |
5 |
// Copyright 2011-2013 GRNET S.A. All rights reserved. |
6 |
// |
7 |
// Redistribution and use in source and binary forms, with or |
8 |
// without modification, are permitted provided that the following |
9 |
// conditions are met: |
10 |
// |
11 |
// 1. Redistributions of source code must retain the above |
12 |
// copyright notice, this list of conditions and the following |
13 |
// disclaimer. |
14 |
// |
15 |
// 2. Redistributions in binary form must reproduce the above |
16 |
// copyright notice, this list of conditions and the following |
17 |
// disclaimer in the documentation and/or other materials |
18 |
// provided with the distribution. |
19 |
// |
20 |
// THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS |
21 |
// OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
22 |
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
23 |
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR |
24 |
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
25 |
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
26 |
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF |
27 |
// USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
28 |
// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
29 |
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
30 |
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
31 |
// POSSIBILITY OF SUCH DAMAGE. |
32 |
// |
33 |
// The views and conclusions contained in the software and |
34 |
// documentation are those of the authors and should not be |
35 |
// interpreted as representing official policies, either expressed |
36 |
// or implied, of GRNET S.A. |
37 |
|
38 |
#import "PithosAccountNode.h" |
39 |
#import "PithosContainerNode.h" |
40 |
#import "ASIPithos.h" |
41 |
#import "ASIPithosAccountRequest.h" |
42 |
#import "ASIPithosAccount.h" |
43 |
#import "ASIPithosContainer.h" |
44 |
#import "ASIDownloadCache.h" |
45 |
#import "PithosAccount.h" |
46 |
#import "PithosUtilities.h" |
47 |
#import "PithosActivityFacility.h" |
48 |
|
49 |
static NSImage *sharedIcon = nil; |
50 |
|
51 |
@implementation PithosAccountNode |
52 |
@synthesize pithosAccount, accountRequest, applyMetadataAccountRequest, refreshMetadataAccountRequest, translatedGroups; |
53 |
|
54 |
+ (void)initialize { |
55 |
if (self == [PithosAccountNode class]) |
56 |
sharedIcon = [[NSWorkspace sharedWorkspace] iconForFileType:NSFileTypeForHFSTypeCode(kUserIcon)]; |
57 |
} |
58 |
|
59 |
#pragma mark - |
60 |
#pragma mark Object Lifecycle |
61 |
|
62 |
- (void)dealloc { |
63 |
[accountRequest clearDelegatesAndCancel]; |
64 |
[refreshMetadataAccountRequest clearDelegatesAndCancel]; |
65 |
[applyMetadataAccountRequest clearDelegatesAndCancel]; |
66 |
} |
67 |
|
68 |
#pragma mark - |
69 |
#pragma mark Internal |
70 |
|
71 |
- (void)updateGroups { |
72 |
if (!pithosAccount) { |
73 |
self.translatedGroups = [NSMutableDictionary dictionary]; |
74 |
} else if (pithosAccountManager) { |
75 |
NSMutableSet *UUIDs = [NSMutableSet set]; |
76 |
for (NSString *groupName in pithosAccount.groups) { |
77 |
[UUIDs addObjectsFromArray:[pithosAccount.groups objectForKey:groupName]]; |
78 |
} |
79 |
[UUIDs removeObject:@""]; |
80 |
[UUIDs removeObject:@"*"]; |
81 |
if (UUIDs.count) { |
82 |
[pithosAccountManager updateUserCatalogForDisplaynames:nil UUIDs:[UUIDs allObjects]]; |
83 |
} |
84 |
|
85 |
NSMutableDictionary *newTranslatedGroups = [NSMutableDictionary dictionaryWithCapacity:pithosAccount.groups.count]; |
86 |
for (NSString *groupName in pithosAccount.groups) { |
87 |
NSMutableArray *groupUsers = [NSMutableArray array]; |
88 |
for (NSString *UUID in [pithosAccount.groups objectForKey:groupName]) { |
89 |
[groupUsers addObject:[pithosAccountManager displaynameForUUID:UUID safe:YES]]; |
90 |
} |
91 |
[newTranslatedGroups setObject:groupUsers forKey:groupName]; |
92 |
} |
93 |
self.translatedGroups = newTranslatedGroups; |
94 |
} else { |
95 |
self.translatedGroups = [pithosAccount.groups copy]; |
96 |
} |
97 |
} |
98 |
|
99 |
#pragma mark - |
100 |
#pragma mark Actions |
101 |
|
102 |
- (void)reset { |
103 |
[accountRequest clearDelegatesAndCancel]; |
104 |
self.accountRequest = nil; |
105 |
[refreshMetadataAccountRequest clearDelegatesAndCancel]; |
106 |
self.refreshMetadataAccountRequest = nil; |
107 |
[applyMetadataAccountRequest clearDelegatesAndCancel]; |
108 |
self.applyMetadataAccountRequest = nil; |
109 |
children = nil; |
110 |
newChildren = nil; |
111 |
self.pithosAccount = nil; |
112 |
freshness = PithosNodeStateRefreshNeeded; |
113 |
forcedRefresh = YES; |
114 |
[self postChildrenUpdatedNotificationName]; |
115 |
[self children]; |
116 |
} |
117 |
|
118 |
#pragma mark - |
119 |
#pragma mark Properties |
120 |
|
121 |
- (void)setPithosAccount:(ASIPithosAccount *)aPithosAccount { |
122 |
if (![pithosAccount isEqualTo:aPithosAccount]) { |
123 |
pithosAccount = aPithosAccount; |
124 |
[self updateGroups]; |
125 |
} |
126 |
} |
127 |
|
128 |
- (NSString *)url { |
129 |
return [NSString stringWithFormat:@"@account@%@%@", |
130 |
(sharingAccount ? sharingAccount : pithosAccountManager.pithos.authUser), |
131 |
(shared ? @"?shared" : @"")]; |
132 |
} |
133 |
|
134 |
- (NSArray *)children { |
135 |
@synchronized(self) { |
136 |
switch (freshness) { |
137 |
case PithosNodeStateFresh: |
138 |
break; |
139 |
case PithosNodeStateRefreshNeeded: |
140 |
freshness = PithosNodeStateRefreshing; |
141 |
self.accountRequest = [ASIPithosAccountRequest listContainersRequestWithPithos:pithosAccountManager.pithos |
142 |
limit:0 |
143 |
marker:nil |
144 |
shared:shared |
145 |
until:nil]; |
146 |
if (sharingAccount) |
147 |
[accountRequest setRequestUserFromDefaultTo:sharingAccount withPithos:pithosAccountManager.pithos]; |
148 |
else if (!forcedRefresh) |
149 |
accountRequest.downloadCache = [ASIDownloadCache sharedCache]; |
150 |
accountRequest.delegate = self; |
151 |
accountRequest.didFinishSelector = @selector(performRequestFinishedDelegateInBackground:); |
152 |
accountRequest.didFailSelector = @selector(performRequestFailedDelegateInBackground:); |
153 |
accountRequest.userInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys: |
154 |
[NSNumber numberWithInteger:NSOperationQueuePriorityVeryHigh], @"priority", |
155 |
[NSNumber numberWithUnsignedInteger:10], @"retries", |
156 |
NSStringFromSelector(@selector(accountRequestFinished:)), @"didFinishSelector", |
157 |
NSStringFromSelector(@selector(accountRequestFailed:)), @"didFailSelector", |
158 |
nil]; |
159 |
[[PithosUtilities prepareRequest:accountRequest priority:NSOperationQueuePriorityVeryHigh] startAsynchronous]; |
160 |
break; |
161 |
case PithosNodeStateRefreshing: |
162 |
break; |
163 |
case PithosNodeStateRefreshFinished: |
164 |
if (newChildren) { |
165 |
children = newChildren; |
166 |
newChildren = nil; |
167 |
} |
168 |
freshness = PithosNodeStateFresh; |
169 |
default: |
170 |
break; |
171 |
} |
172 |
return children; |
173 |
} |
174 |
} |
175 |
|
176 |
- (NSString *)displayName { |
177 |
if (displayName == nil) { |
178 |
if (!sharingAccount) { |
179 |
return @"account"; |
180 |
} else if (pithosAccountManager) { |
181 |
return [pithosAccountManager displaynameForUUID:sharingAccount safe:YES]; |
182 |
} else { |
183 |
return [sharingAccount copy]; |
184 |
} |
185 |
} |
186 |
return [displayName copy]; |
187 |
} |
188 |
|
189 |
- (NSImage *)icon { |
190 |
if (icon == nil) |
191 |
icon = sharedIcon; |
192 |
return icon; |
193 |
} |
194 |
|
195 |
#pragma mark - |
196 |
#pragma mark ASIHTTPRequestDelegate |
197 |
|
198 |
- (void)accountRequestFailed:(ASIPithosAccountRequest *)request { |
199 |
@autoreleasepool { |
200 |
NSString *message; |
201 |
NSError *error = [accountRequest error]; |
202 |
if (error) |
203 |
message = [NSString stringWithFormat:@"Account listing %@ failed: %@", accountRequest.url, [error localizedDescription]]; |
204 |
else |
205 |
message = [NSString stringWithFormat:@"Account listing %@ failed: (%d) %@", |
206 |
accountRequest.url, accountRequest.responseStatusCode, accountRequest.responseStatusMessage]; |
207 |
dispatch_async(dispatch_get_main_queue(), ^{ |
208 |
[[PithosActivityFacility defaultPithosActivityFacility] startAndEndActivityWithType:PithosActivityOther message:message]; |
209 |
}); |
210 |
NSUInteger retries = [[accountRequest.userInfo objectForKey:@"retries"] unsignedIntegerValue]; |
211 |
if (retries > 0) { |
212 |
ASIPithosAccountRequest *newAccountRequest = (ASIPithosAccountRequest *)[PithosUtilities copyRequest:accountRequest]; |
213 |
[(NSMutableDictionary *)(newAccountRequest.userInfo)setObject:[NSNumber numberWithUnsignedInteger:(--retries)] forKey:@"retries"]; |
214 |
self.accountRequest = newAccountRequest; |
215 |
[[PithosUtilities prepareRequest:accountRequest priority:[[accountRequest.userInfo objectForKey:@"priority"] integerValue]] startAsynchronous]; |
216 |
} else { |
217 |
newChildren = nil; |
218 |
self.accountRequest = nil; |
219 |
forcedRefresh = NO; |
220 |
@synchronized(self) { |
221 |
freshness = PithosNodeStateRefreshNeeded; |
222 |
} |
223 |
} |
224 |
} |
225 |
} |
226 |
|
227 |
- (void)accountRequestFinished:(ASIPithosAccountRequest *)request { |
228 |
@autoreleasepool { |
229 |
DLog(@"List account finished: %@", [accountRequest url]); |
230 |
DLog(@"Cached: %d", [accountRequest didUseCachedResponse]); |
231 |
if (accountRequest.responseStatusCode == 200) { |
232 |
self.pithosAccount = [accountRequest account]; |
233 |
|
234 |
NSMutableArray *containers = [accountRequest.userInfo objectForKey:@"containers"]; |
235 |
NSArray *someContainers = [accountRequest containers]; |
236 |
if (containers == nil) { |
237 |
containers = [NSMutableArray arrayWithArray:someContainers]; |
238 |
} else { |
239 |
[containers addObjectsFromArray:someContainers]; |
240 |
} |
241 |
if ([someContainers count] < 10000) { |
242 |
if (!accountRequest.didUseCachedResponse || ([containers count] != [someContainers count]) || !children) { |
243 |
// Save new children |
244 |
DLog(@"using newChildren"); |
245 |
newChildren = [[NSMutableArray alloc] init]; |
246 |
NSMutableIndexSet *keptNodes = [NSMutableIndexSet indexSet]; |
247 |
for (ASIPithosContainer *container in containers) { |
248 |
PithosContainerNode *node = [[PithosContainerNode alloc] initWithPithosAccountManager:pithosAccountManager |
249 |
pithosContainer:container]; |
250 |
node.parent = self; |
251 |
node.shared = shared; |
252 |
node.sharingAccount = sharingAccount; |
253 |
node.inheritChildrenUpdatedNotificationName = inheritChildrenUpdatedNotificationName; |
254 |
if (children) { |
255 |
NSUInteger oldIndex = [children indexOfObject:node]; |
256 |
if (oldIndex != NSNotFound) { |
257 |
// Use the same pointer value, if possible |
258 |
node = [children objectAtIndex:oldIndex]; |
259 |
// node.pithosContainer = container; |
260 |
[node setLimitedPithosContainer:container]; |
261 |
[keptNodes addIndex:oldIndex]; |
262 |
} |
263 |
} |
264 |
[newChildren addObject:node]; |
265 |
} |
266 |
[[children objectsAtIndexes: |
267 |
[[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, [children count])] indexesPassingTest:^(NSUInteger idx, BOOL *stop){ |
268 |
if ([keptNodes containsIndex:idx]) |
269 |
return NO; |
270 |
return YES; |
271 |
}]] makeObjectsPerformSelector:@selector(pithosNodeWillBeRemoved)]; |
272 |
} |
273 |
// Else cache was used and all results were fetched during this request, so existing children can be reused |
274 |
self.accountRequest = nil; |
275 |
forcedRefresh = NO; |
276 |
@synchronized(self) { |
277 |
freshness = PithosNodeStateRefreshFinished; |
278 |
} |
279 |
[self postChildrenUpdatedNotificationName]; |
280 |
} else { |
281 |
// Do an additional request to fetch more objects |
282 |
self.accountRequest = [ASIPithosAccountRequest listContainersRequestWithPithos:pithosAccountManager.pithos |
283 |
limit:0 |
284 |
marker:[[someContainers lastObject] name] |
285 |
shared:shared |
286 |
until:nil]; |
287 |
if (sharingAccount) |
288 |
[accountRequest setRequestUserFromDefaultTo:sharingAccount withPithos:pithosAccountManager.pithos]; |
289 |
else if (!forcedRefresh) |
290 |
accountRequest.downloadCache = [ASIDownloadCache sharedCache]; |
291 |
accountRequest.delegate = self; |
292 |
accountRequest.didFinishSelector = @selector(performRequestFinishedDelegateInBackground:); |
293 |
accountRequest.didFailSelector = @selector(performRequestFailedDelegateInBackground:); |
294 |
accountRequest.userInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys: |
295 |
[NSNumber numberWithInteger:NSOperationQueuePriorityVeryHigh], @"priority", |
296 |
[NSNumber numberWithUnsignedInteger:10], @"retries", |
297 |
NSStringFromSelector(@selector(accountRequestFinished:)), @"didFinishSelector", |
298 |
NSStringFromSelector(@selector(accountRequestFailed:)), @"didFailSelector", |
299 |
containers, @"containers", |
300 |
nil]; |
301 |
[[PithosUtilities prepareRequest:accountRequest priority:NSOperationQueuePriorityVeryHigh] startAsynchronous]; |
302 |
} |
303 |
} else if (accountRequest.responseStatusCode == 304) { |
304 |
// Account is not modified, so existing children can be reused |
305 |
self.accountRequest = nil; |
306 |
forcedRefresh = NO; |
307 |
@synchronized(self) { |
308 |
freshness = PithosNodeStateRefreshFinished; |
309 |
} |
310 |
[self postChildrenUpdatedNotificationName]; |
311 |
} else { |
312 |
[self accountRequestFailed:accountRequest]; |
313 |
} |
314 |
} |
315 |
} |
316 |
|
317 |
- (void)accountMetadataRequestFinished:(ASIPithosAccountRequest *)request { |
318 |
@autoreleasepool { |
319 |
DLog(@"URL: %@", [request url]); |
320 |
DLog(@"cached: %d", [request didUseCachedResponse]); |
321 |
|
322 |
if ([request isEqualTo:applyMetadataAccountRequest]) { |
323 |
@synchronized(self) { |
324 |
self.applyMetadataAccountRequest = nil; |
325 |
} |
326 |
[self refreshInfo]; |
327 |
} else if ([request isEqualTo:refreshMetadataAccountRequest]) { |
328 |
self.pithosAccount = [refreshMetadataAccountRequest account]; |
329 |
@synchronized(self) { |
330 |
self.refreshMetadataAccountRequest = nil; |
331 |
} |
332 |
} |
333 |
} |
334 |
} |
335 |
|
336 |
- (void)accountMetadataRequestFailed:(ASIPithosAccountRequest *)request { |
337 |
@autoreleasepool { |
338 |
NSUInteger retries = [[request.userInfo objectForKey:@"retries"] unsignedIntegerValue]; |
339 |
if (retries > 0) { |
340 |
ASIPithosAccountRequest *newRequest = (ASIPithosAccountRequest *)[PithosUtilities copyRequest:request]; |
341 |
[(NSMutableDictionary *)(newRequest.userInfo)setObject:[NSNumber numberWithUnsignedInteger:(--retries)] forKey:@"retries"]; |
342 |
if ([request isEqualTo:applyMetadataAccountRequest]) { |
343 |
@synchronized(self) { |
344 |
self.applyMetadataAccountRequest = newRequest; |
345 |
} |
346 |
} else if ([request isEqualTo:refreshMetadataAccountRequest]) { |
347 |
@synchronized(self) { |
348 |
self.refreshMetadataAccountRequest = newRequest; |
349 |
} |
350 |
} |
351 |
[[PithosUtilities prepareRequest:newRequest priority:[[newRequest.userInfo objectForKey:@"priority"] integerValue]] startAsynchronous]; |
352 |
} else { |
353 |
if ([request isEqualTo:applyMetadataAccountRequest]) { |
354 |
[PithosUtilities httpRequestErrorAlertWithRequest:applyMetadataAccountRequest]; |
355 |
@synchronized(self) { |
356 |
self.applyMetadataAccountRequest = nil; |
357 |
} |
358 |
} else if ([request isEqualTo:refreshMetadataAccountRequest]) { |
359 |
[PithosUtilities httpRequestErrorAlertWithRequest:refreshMetadataAccountRequest]; |
360 |
@synchronized(self) { |
361 |
self.refreshMetadataAccountRequest = nil; |
362 |
} |
363 |
} |
364 |
} |
365 |
} |
366 |
} |
367 |
|
368 |
#pragma mark - |
369 |
#pragma mark Info |
370 |
|
371 |
- (void)applyInfo { |
372 |
@synchronized(self) { |
373 |
if (applyMetadataAccountRequest == nil) { |
374 |
NSMutableDictionary *groups = [NSMutableDictionary dictionary]; |
375 |
if (translatedGroups.count) { |
376 |
for (NSString *groupName in translatedGroups) { |
377 |
if (!groupName.length || |
378 |
[groupName rangeOfCharacterFromSet:[NSCharacterSet characterSetWithCharactersInString:@" -_~,;"]].location != NSNotFound) { |
379 |
NSAlert *alert = [[NSAlert alloc] init]; |
380 |
[alert setMessageText:@"Invalid Input"]; |
381 |
[alert setInformativeText:@"Group names cannot be empty or contain ' ', '-', '_', '~', ',' or ';'."]; |
382 |
[alert addButtonWithTitle:@"OK"]; |
383 |
[alert runModal]; |
384 |
return; |
385 |
} |
386 |
} |
387 |
if (pithosAccountManager) { |
388 |
NSMutableSet *allGroupUsers = [NSMutableSet set]; |
389 |
for (NSMutableArray *groupUsers in [translatedGroups objectEnumerator]) { |
390 |
[allGroupUsers addObjectsFromArray:groupUsers]; |
391 |
} |
392 |
[allGroupUsers removeObject:@""]; |
393 |
[allGroupUsers removeObject:@"*"]; |
394 |
if (allGroupUsers.count) { |
395 |
ASIPithosRequest *userCatalogRequest = [pithosAccountManager updateUserCatalogForDisplaynames:[allGroupUsers allObjects] |
396 |
UUIDs:nil]; |
397 |
if (userCatalogRequest.error || ((userCatalogRequest.responseStatusCode != 200) && (userCatalogRequest.responseStatusCode != 404))) { |
398 |
return; |
399 |
} else if (userCatalogRequest.responseStatusCode == 200) { |
400 |
// Check if all users exist. |
401 |
NSDictionary *displaynameCatalog = [userCatalogRequest displaynameCatalog]; |
402 |
NSMutableArray *inexistentGroupUsers = [NSMutableArray array]; |
403 |
for (NSString *groupUser in allGroupUsers) { |
404 |
if (![displaynameCatalog objectForKey:groupUser]) { |
405 |
[inexistentGroupUsers addObject:groupUser]; |
406 |
} |
407 |
} |
408 |
if (!inexistentGroupUsers.count) { |
409 |
// Create groups. |
410 |
for (NSString *groupName in translatedGroups) { |
411 |
NSMutableArray *groupUsers = [NSMutableArray array]; |
412 |
for (NSString *groupUser in [translatedGroups objectForKey:groupName]) { |
413 |
[groupUsers addObject:([groupUser isEqualToString:@"*"] ? |
414 |
@"*" : [displaynameCatalog objectForKey:groupUser])]; |
415 |
} |
416 |
[groups setObject:groupUsers forKey:groupName]; |
417 |
} |
418 |
} else { |
419 |
NSAlert *alert = [[NSAlert alloc] init]; |
420 |
if (inexistentGroupUsers.count == 1) { |
421 |
[alert setMessageText:@"Invalid User"]; |
422 |
[alert setInformativeText:[NSString stringWithFormat:@"User '%@' doesn't exist.", [inexistentGroupUsers objectAtIndex:0]]]; |
423 |
} else { |
424 |
[alert setMessageText:@"Invalid Users"]; |
425 |
[alert setInformativeText:[NSString stringWithFormat:@"Users '%@' don't exist.", [inexistentGroupUsers componentsJoinedByString:@"', '"]]]; |
426 |
} |
427 |
[alert addButtonWithTitle:@"OK"]; |
428 |
[alert runModal]; |
429 |
return; |
430 |
} |
431 |
} else { |
432 |
// 404. Since we don't translate to UUIDs, check for invalid chars. |
433 |
BOOL valid = YES; |
434 |
for (NSString *groupUser in allGroupUsers) { |
435 |
if ([groupUser rangeOfCharacterFromSet:[NSCharacterSet characterSetWithCharactersInString:@" ~,;:"]].location != NSNotFound) { |
436 |
valid = NO; |
437 |
break; |
438 |
} |
439 |
} |
440 |
if (valid) { |
441 |
[groups addEntriesFromDictionary:translatedGroups]; |
442 |
} else { |
443 |
NSAlert *alert = [[NSAlert alloc] init]; |
444 |
[alert setMessageText:@"Invalid Input"]; |
445 |
[alert setInformativeText:@"Users cannot contain ' ', '~', ',', ';' or ':'."]; |
446 |
[alert addButtonWithTitle:@"OK"]; |
447 |
[alert runModal]; |
448 |
return; |
449 |
} |
450 |
} |
451 |
} else { |
452 |
for (NSString *groupName in translatedGroups) { |
453 |
if ([[translatedGroups objectForKey:groupName] containsObject:@"*"]) { |
454 |
[groups setObject:[NSMutableArray arrayWithObject:@"*"] forKey:groupName]; |
455 |
} |
456 |
} |
457 |
if (!groups.count) { |
458 |
[groups setObject:[NSArray arrayWithObject:@""] forKey:@"group"]; |
459 |
} |
460 |
} |
461 |
} else { |
462 |
[groups addEntriesFromDictionary:translatedGroups]; |
463 |
} |
464 |
} else { |
465 |
[groups setObject:[NSArray arrayWithObject:@""] forKey:@"group"]; |
466 |
} |
467 |
|
468 |
self.applyMetadataAccountRequest = [ASIPithosAccountRequest updateAccountMetadataRequestWithPithos:pithosAccountManager.pithos |
469 |
groups:groups |
470 |
metadata:pithosAccount.metadata |
471 |
update:NO]; |
472 |
applyMetadataAccountRequest.delegate = self; |
473 |
applyMetadataAccountRequest.didFinishSelector = @selector(performRequestFinishedDelegateInBackground:); |
474 |
applyMetadataAccountRequest.didFailSelector = @selector(performRequestFailedDelegateInBackground:); |
475 |
applyMetadataAccountRequest.userInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys: |
476 |
[NSNumber numberWithInteger:NSOperationQueuePriorityHigh], @"priority", |
477 |
[NSNumber numberWithUnsignedInteger:10], @"retries", |
478 |
NSStringFromSelector(@selector(accountMetadataRequestFinished:)), @"didFinishSelector", |
479 |
NSStringFromSelector(@selector(accountMetadataRequestFailed:)), @"didFailSelector", |
480 |
nil]; |
481 |
[[PithosUtilities prepareRequest:applyMetadataAccountRequest priority:NSOperationQueuePriorityHigh] startAsynchronous]; |
482 |
} |
483 |
} |
484 |
} |
485 |
|
486 |
- (void)refreshInfo { |
487 |
@synchronized(self) { |
488 |
if (refreshMetadataAccountRequest == nil) { |
489 |
self.refreshMetadataAccountRequest = [ASIPithosAccountRequest accountMetadataRequestWithPithos:pithosAccountManager.pithos]; |
490 |
refreshMetadataAccountRequest.delegate = self; |
491 |
refreshMetadataAccountRequest.didFinishSelector = @selector(performRequestFinishedDelegateInBackground:); |
492 |
refreshMetadataAccountRequest.didFailSelector = @selector(performRequestFailedDelegateInBackground:); |
493 |
refreshMetadataAccountRequest.userInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys: |
494 |
[NSNumber numberWithInteger:NSOperationQueuePriorityHigh], @"priority", |
495 |
[NSNumber numberWithUnsignedInteger:10], @"retries", |
496 |
NSStringFromSelector(@selector(accountMetadataRequestFinished:)), @"didFinishSelector", |
497 |
NSStringFromSelector(@selector(accountMetadataRequestFailed:)), @"didFailSelector", |
498 |
nil]; |
499 |
if (!sharingAccount) |
500 |
refreshMetadataAccountRequest.downloadCache = [ASIDownloadCache sharedCache]; |
501 |
[[PithosUtilities prepareRequest:refreshMetadataAccountRequest priority:NSOperationQueuePriorityHigh] startAsynchronous]; |
502 |
} |
503 |
} |
504 |
} |
505 |
|
506 |
@end |