Change default authURL
[pithos-ios] / Classes / AccountGroupsViewController.m
index 51a69a5..f9fd70d 100644 (file)
@@ -2,7 +2,7 @@
 //  AccountGroupsViewController.m
 //  pithos-ios
 //
-// Copyright 2011 GRNET S.A. All rights reserved.
+// Copyright 2011-2013 GRNET S.A. All rights reserved.
 //
 // Redistribution and use in source and binary forms, with or
 // without modification, are permitted provided that the following
 // or implied, of GRNET S.A.
 
 #import "AccountGroupsViewController.h"
+#import "OpenStackAccount.h"
+#import "ActivityIndicatorView.h"
 #import "AccountManager.h"
 #import "OpenStackRequest.h"
 #import "EditAccountGroupsViewController.h"
-
+#import "UIViewController+Conveniences.h"
+#import "NSString+Conveniences.h"
+#import "APICallback.h"
 
 @implementation AccountGroupsViewController
 
-@synthesize account, groups;
-
-
-- (void)dealloc
-{
-    [account release];
-    [groups release];
-    [metadata release];
-    [super dealloc];
-}
-
+@synthesize account, groups, metadata;
 
 #pragma mark - View lifecycle
 
-- (void)viewDidLoad
-{
-    [super viewDidLoad];
-    self.navigationItem.title = @"Groups";
-    groups = [[NSMutableDictionary alloc] init];
-    metadata = [[NSMutableDictionary alloc] init];
-    
-    NSString *activityMessage = @"Loading..";
-    activityIndicatorView = [[ActivityIndicatorView alloc] initWithFrame:[ActivityIndicatorView frameForText:activityMessage] text:activityMessage];
-    [activityIndicatorView addToView:self.view];
-    
-    [self.account.manager getStorageAccountInfo];
-    successObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"getStorageAccountInfoSucceeded" 
-                                                                        object:account
-                                                                         queue:[NSOperationQueue mainQueue]
-                                                                    usingBlock:^(NSNotification *notification)
-    {
-        [activityIndicatorView removeFromSuperviewAndRelease];
-        OpenStackRequest *request = [notification.userInfo objectForKey:@"request"];
-        for (NSString *key in request.responseHeaders) {
-            if ([key hasPrefix:@"X-Account-Group-"]) {
-                NSString *groupName = [key substringFromIndex:16];
-                NSString *groupUsers = [request.responseHeaders objectForKey:key];
-                [groups setObject:groupUsers forKey:groupName];
-            }
-        }
-        
-        for (NSString *header in request.responseHeaders) {
-            if ([header hasPrefix:@"X-Account-Meta-"])  {
-                NSString *metadataKey = [header substringFromIndex:15];
-                NSString *metadataValue = [request.responseHeaders objectForKey:header];
-                [metadata setObject:metadataValue forKey:metadataKey];
-            }
-        }
-        
-        [self.tableView reloadData];
-        [[NSNotificationCenter defaultCenter] removeObserver:successObserver];
-    }];
+- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
+    return ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) || (toInterfaceOrientation == UIInterfaceOrientationPortrait);
 }
 
-- (void)viewDidUnload
-{
-    [super viewDidUnload];
-    // Release any retained subviews of the main view.
-    // e.g. self.myOutlet = nil;
-}
-
-- (void)viewWillAppear:(BOOL)animated
-{
+- (void)viewWillAppear:(BOOL)animated {
     [super viewWillAppear:animated];
-    [self.tableView reloadData];
+    self.navigationItem.title = @"Groups";
 }
 
-- (void)viewDidAppear:(BOOL)animated
-{
+- (void)viewDidAppear:(BOOL)animated {
     [super viewDidAppear:animated];
+    __block ActivityIndicatorView *activityIndicatorView = [ActivityIndicatorView activityIndicatorViewWithText:@"Loading groups..."
+                                                                                                   andAddToView:self.view];
+    [[self.account.manager getStorageAccountInfo]
+     success:^(OpenStackRequest *request) {
+         self.groups = [NSMutableDictionary dictionary];
+         self.metadata = [NSMutableDictionary dictionary];
+     
+         for (NSString *headerName in request.responseHeaders) {
+             if ([headerName hasPrefix:@"X-Account-Group-"]) {
+                 [groups setObject:[[NSString decodeFromPercentEscape:[request.responseHeaders objectForKey:headerName]] componentsSeparatedByString:@","]
+                            forKey:[NSString decodeFromPercentEscape:[headerName substringFromIndex:16]]];
+              } else if ([headerName hasPrefix:@"X-Account-Meta-"]) {
+                 [metadata setObject:[NSString decodeFromPercentEscape:[request.responseHeaders objectForKey:headerName]]
+                              forKey:[NSString decodeFromPercentEscape:[headerName substringFromIndex:15]]];
+             }
+         }
+         
+         NSMutableArray *UUIDs = [NSMutableArray array];
+         for (NSString *groupName in groups) {
+             [UUIDs addObjectsFromArray:[groups objectForKey:groupName]];
+         }
+         if (UUIDs.count) {
+             [[self.account.manager userCatalogForDisplaynames:nil UUIDs:UUIDs]
+              success:^(OpenStackRequest *request) {
+                  [activityIndicatorView stopAnimatingAndRemoveFromSuperview];
+                  [self.tableView reloadData];
+              }
+              failure:^(OpenStackRequest *request) {
+                  [activityIndicatorView stopAnimatingAndRemoveFromSuperview];
+                  [self.tableView reloadData];
+                  if (request.responseStatusCode != 404) {
+                      // Don't show alert on 404, since it can be a pre-UUID server.
+                      [self alert:@"Failed to translate group UUIDs." request:request];
+                  }
+              }];
+         } else {
+             [activityIndicatorView stopAnimatingAndRemoveFromSuperview];
+             [self.tableView reloadData];
+         }
+     }
+     failure:^(OpenStackRequest *request) {
+         [activityIndicatorView stopAnimatingAndRemoveFromSuperview];
+         [self alert:@"Failed to get account information." request:request];
+     }];
 }
 
-- (void)viewWillDisappear:(BOOL)animated
-{
-    [super viewWillDisappear:animated];
-}
+#pragma mark - Internal
 
-- (void)viewDidDisappear:(BOOL)animated
-{
-    [super viewDidDisappear:animated];
+- (NSMutableArray *)groupUsersForGroupName:(NSString *)groupName {
+    NSArray *groupUUIDs = [groups objectForKey:groupName];
+    NSMutableArray *groupUsers = [NSMutableArray arrayWithCapacity:groupUUIDs.count];
+    for (NSString *UUID in groupUUIDs) {
+        [groupUsers addObject:[self.account displaynameForUUID:UUID safe:YES]];
+    }
+    return groupUsers;
 }
 
-- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
-{
-    // Return YES for supported orientations
-    return (interfaceOrientation == UIInterfaceOrientationPortrait);
+- (NSMutableString *)groupUsersStringForGroupName:(NSString *)groupName {
+    NSMutableArray *groupUsers = [self groupUsersForGroupName:groupName];
+    NSMutableString *groupUsersString = [NSMutableString string];
+    for (NSUInteger index = 0; index < groupUsers.count; index++) {
+        if (index) {
+            [groupUsersString appendString:@","];
+        }
+        [groupUsersString appendString:[groupUsers objectAtIndex:index]];
+    }
+    return groupUsersString;
 }
 
-#pragma mark - Table view data source
+#pragma mark - Memory management
 
-- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
-{
-    return 1;
+- (void)dealloc {
+    [account release];
+    [groups release];
+    [metadata release];
+    [super dealloc];
 }
 
-- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
-{
-    return [groups count] + 1;
-}
+#pragma mark - UITableViewDataSource
 
-- (CGFloat)findLabelHeight:(NSString*)text font:(UIFont *)font {
-    CGSize textLabelSize;    
-    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
-        // 616, 678
-        textLabelSize = CGSizeMake(596.0, 9000.0f);
-    } else {
-        textLabelSize = CGSizeMake(280.0, 9000.0f);
-    }
-    CGSize stringSize = [text sizeWithFont:font constrainedToSize:textLabelSize lineBreakMode:UILineBreakModeCharacterWrap];
-    return stringSize.height;
+- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
+    return (groups.count + 1);
 }
 
 - (CGFloat)tableView:(UITableView *)aTableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
-    CGFloat result = aTableView.rowHeight;
-    
-    if ([groups count] > 0 && indexPath.row < [groups count]) {
-        NSString *groupName = [[groups allKeys] objectAtIndex:indexPath.row];
-        NSString *groupUsers = [groups objectForKey:groupName];
-        
-        result = 22.0 + [self findLabelHeight:[[NSString stringWithFormat:@"%@", groupUsers] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding] font:[UIFont systemFontOfSize:18.0]];
-    
+    CGFloat result;
+    if (indexPath.row < groups.count) {
+        NSString *groupName = [[[groups allKeys] sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)] objectAtIndex:indexPath.row];
+        result = 22.0 + [[self groupUsersStringForGroupName:groupName] sizeWithFont:[UIFont systemFontOfSize:18.0]
+                                                                  constrainedToSize:(([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) ?
+                                                                                     CGSizeMake(596.0, 9000.0) :
+                                                                                     CGSizeMake(280.0, 9000.0))
+                                                                      lineBreakMode:UILineBreakModeCharacterWrap].height;
         return MAX(aTableView.rowHeight, result);
     }
     return aTableView.rowHeight;
 }
 
 
-- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
-{
+- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
     static NSString *CellIdentifier = @"Cell";
-    
     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
     if (cell == nil) {
         cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] autorelease];
     }
     
     cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
-    if (indexPath.row < [groups count]) {
-        NSString *groupName = [[groups allKeys] objectAtIndex:indexPath.row];
+    if (indexPath.row < groups.count) {
+        NSString *groupName = [[[groups allKeys] sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)] objectAtIndex:indexPath.row];
         cell.textLabel.text = groupName;
-        cell.detailTextLabel.text = [groups objectForKey:groupName];
+        cell.detailTextLabel.text = [self groupUsersStringForGroupName:groupName];
         cell.detailTextLabel.numberOfLines = 0;
         cell.detailTextLabel.lineBreakMode = UILineBreakModeCharacterWrap;
-    }
-    else {
+    } else {
         cell.textLabel.text = @"Add Group";
         cell.detailTextLabel.text = @"";
     }
 }
 
 
-#pragma mark - Table view delegate
+#pragma mark - UITableViewDelegate
 
-- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
-{
+- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
     EditAccountGroupsViewController *vc = [[EditAccountGroupsViewController alloc] initWithNibName:@"EditAccountGroupsViewController" bundle:nil];
-    
     vc.account = self.account;
     vc.metadata = metadata;
     vc.groups = groups;
-    if (indexPath.row < [groups count]) {        
-        NSString *groupName = [[groups allKeys] objectAtIndex:indexPath.row];
-        NSString *groupUsers = [groups objectForKey:groupName];
-        
+    if (indexPath.row < groups.count) {
+        NSString *groupName = [[[groups allKeys] sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)] objectAtIndex:indexPath.row];
         vc.removeGroupEnabled = YES;
         vc.groupName = groupName;
-        vc.groupUsers = groupUsers;
         vc.navigationItem.title = @"Edit Group";
-    }
-    else {
+    } else {
         vc.removeGroupEnabled = NO;
         vc.groupName = @"";
-        vc.groupUsers = @"";
         vc.navigationItem.title = @"Add Group";
     }