Browse Source

listing, displaying and downloading of gdrivefiles

Signed-off-by: Felix Paul Kühne <fkuehne@videolan.org>
Carola Nitz 11 years ago
parent
commit
5df918d58c

+ 1 - 0
AspenProject/VLCGoogleDriveConstants.h

@@ -8,6 +8,7 @@
 //  Refer to the COPYING file of the official project for license.
 //
 #define kVLCGoogleDriveClientID @"775640710334.apps.googleusercontent.com"
+#define kKeychainItemName @"vlc-ios"
 #warning Google Drive app secret missing, login will fail
 #define kVLCGoogleDriveClientSecret @""
 //#define kVLCGoogleDriveAppKey @"a60fc6qj9zdg7bw"

+ 3 - 1
AspenProject/VLCGoogleDriveController.h

@@ -8,6 +8,8 @@
 //  Refer to the COPYING file of the official project for license.
 //
 #import "GTLDrive.h"
+#import "GTMOAuth2ViewControllerTouch.h"
+#import "VLCGoogleDriveConstants.h"
 
 @protocol VLCGoogleDriveController
 @required
@@ -31,6 +33,6 @@
 - (void)startSession;
 - (void)logout;
 - (void)requestDirectoryListingAtPath:(NSString *)path;
-//- (void)downloadFileToDocumentFolder:(DBMetadata *)file;
+- (void)downloadFileToDocumentFolder:(GTLDriveFile *)file;
 
 @end

+ 95 - 88
AspenProject/VLCGoogleDriveController.m

@@ -12,15 +12,13 @@
 #import "NSString+SupportedMedia.h"
 #import "VLCAppDelegate.h"
 #import "HTTPMessage.h"
-#import "VLCGoogleDriveConstants.h"
-
-static NSString *const kKeychainItemName = @"Google Drive Quickstart #2";
 
 @interface VLCGoogleDriveController ()
 {
     GTLDriveFileList *_fileList;
-    NSError *_fileListFetchError;
     GTLServiceTicket *_fileListTicket;
+    NSError *_fileListFetchError;
+
     NSArray *_currentFileList;
 
     NSMutableArray *_listOfGoogleDriveFilesToDownload;
@@ -43,6 +41,8 @@ static NSString *const kKeychainItemName = @"Google Drive Quickstart #2";
 
 - (void)logout
 {
+    [GTMOAuth2ViewControllerTouch removeAuthFromKeychainForName:kKeychainItemName];
+    self.driveService.authorizer = nil;
 }
 
 - (BOOL)isAuthorized
@@ -68,9 +68,9 @@ static NSString *const kKeychainItemName = @"Google Drive Quickstart #2";
         [self listFiles];
 }
 
-- (void)downloadFileToDocumentFolder:(DBMetadata *)file
+- (void)downloadFileToDocumentFolder:(GTLDriveFile *)file
 {
-    if (!file.isDirectory) {
+    if (![file.mimeType isEqualToString:@"application/vnd.google-apps.folder"]) {
         if (!_listOfGoogleDriveFilesToDownload)
             _listOfGoogleDriveFilesToDownload = [[NSMutableArray alloc] init];
         [_listOfGoogleDriveFilesToDownload addObject:file];
@@ -90,23 +90,10 @@ static NSString *const kKeychainItemName = @"Google Drive Quickstart #2";
     GTLServiceDrive *service = self.driveService;
 
     GTLQueryDrive *query = [GTLQueryDrive queryForFilesList];
-
-    // maxResults specifies the number of results per page.  Since we earlier
-    // specified shouldFetchNextPages=YES, all results should be fetched,
-    // though specifying a larger maxResults will reduce the number of fetches
-    // needed to retrieve all pages.
     query.maxResults = 150;
 
-    // The Drive API's file entries are chock full of data that the app may not
-    // care about. Specifying the fields we want here reduces the network
-    // bandwidth and memory needed for the collection.
-    //
-    // For example, leave query.fields as nil during development.
-    // When ready to test and optimize your app, specify just the fields needed.
-    // For example, this sample app might use
-    //
-    // query.fields = @"kind,etag,items(id,downloadUrl,editable,etag,exportLinks,kind,labels,originalFilename,title)";
-    //TODO:specify query.fields 
+    query.fields = @"items(originalFilename,title,mimeType,fileExtension,fileSize,iconLink)";
+    //+ (id)queryForChildrenListWithFolderId:(NSString *)folderId;
 
     _fileListTicket = [service executeQuery:query
                           completionHandler:^(GTLServiceTicket *ticket,
@@ -117,10 +104,8 @@ static NSString *const kKeychainItemName = @"Google Drive Quickstart #2";
                               
                               _fileListFetchError = error;
                               _fileListTicket = nil;
-                              [self listOfGoodFiles];
+                              [self listOfGoodFilesAndFolders];
                           }];
-
-  //  [self updateUI];
 }
 
 - (void)_triggerNextDownload
@@ -134,12 +119,12 @@ static NSString *const kKeychainItemName = @"Google Drive Quickstart #2";
     }
 }
 
-- (void)_reallyDownloadFileToDocumentFolder:(DBMetadata *)file
+- (void)_reallyDownloadFileToDocumentFolder:(GTLDriveFile *)file
 {
     NSArray *searchPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
-    NSString *filePath = [searchPaths[0] stringByAppendingFormat:@"/%@", file.filename];
+    NSString *filePath = [searchPaths[0] stringByAppendingFormat:@"/%@", file.originalFilename];
 
-    //[[self restClient] loadFile:file.path intoPath:filePath];
+    [self loadFile:file intoPath:filePath];
 
     if ([self.delegate respondsToSelector:@selector(operationWithProgressInformationStarted)])
         [self.delegate operationWithProgressInformationStarted];
@@ -147,7 +132,6 @@ static NSString *const kKeychainItemName = @"Google Drive Quickstart #2";
     _downloadInProgress = YES;
 }
 
-#pragma mark - restClient delegate
 - (BOOL)_supportedFileExtension:(NSString *)filename
 {
     if ([filename isSupportedMediaFormat] || [filename isSupportedAudioMediaFormat] || [filename isSupportedSubtitleFormat])
@@ -156,15 +140,15 @@ static NSString *const kKeychainItemName = @"Google Drive Quickstart #2";
     return NO;
 }
 
-- (void)listOfGoodFiles
+- (void)listOfGoodFilesAndFolders
 {
     NSMutableArray *listOfGoodFilesAndFolders = [[NSMutableArray alloc] init];
     
     for (GTLDriveFile *driveFile in _fileList.items)
     {
         BOOL isDirectory = [driveFile.mimeType isEqualToString:@"application/vnd.google-apps.folder"];
-        if (isDirectory || [self _supportedFileExtension:driveFile.fileExtension]) {
-             [listOfGoodFilesAndFolders addObject:driveFile];
+        if (isDirectory || [self _supportedFileExtension:[NSString stringWithFormat:@".%@",driveFile.fileExtension ]]) {
+            [listOfGoodFilesAndFolders addObject:driveFile];
         }
     }
 
@@ -175,66 +159,89 @@ static NSString *const kKeychainItemName = @"Google Drive Quickstart #2";
         [self.delegate mediaListUpdated];
 }
 
-//- (void)restClient:(DBRestClient *)client loadMetadataFailedWithError:(NSError *)error
-//{
-//    APLog(@"DBMetadata download failed with error %i", error.code);
-//}
-//
-//- (void)restClient:(DBRestClient*)client loadedFile:(NSString*)localPath
-//{
-//    /* update library now that we got a file */
-//    VLCAppDelegate *appDelegate = [UIApplication sharedApplication].delegate;
-//    [appDelegate updateMediaList];
-//
-//    if ([self.delegate respondsToSelector:@selector(operationWithProgressInformationStopped)])
-//        [self.delegate operationWithProgressInformationStopped];
-//    _downloadInProgress = NO;
-//
-//    [self _triggerNextDownload];
-//}
-//
-//- (void)restClient:(DBRestClient*)client loadFileFailedWithError:(NSError*)error
-//{
-//    APLog(@"DBFile download failed with error %i", error.code);
-//    if ([self.delegate respondsToSelector:@selector(operationWithProgressInformationStopped)])
-//        [self.delegate operationWithProgressInformationStopped];
-//    _downloadInProgress = NO;
-//
-//    [self _triggerNextDownload];
-//}
-//
-//- (void)restClient:(DBRestClient*)client loadProgress:(CGFloat)progress forFile:(NSString*)destPath
-//{
-//    if ([self.delegate respondsToSelector:@selector(currentProgressInformation:)])
-//        [self.delegate currentProgressInformation:progress];
-//}
-//
-//#pragma mark - DBSession delegate
-//
-//- (void)sessionDidReceiveAuthorizationFailure:(DBSession *)session userId:(NSString *)userId
-//{
-//    APLog(@"DriveSession received authorization failure with user ID %@", userId);
-//}
-//
-//#pragma mark - DBNetworkRequest delegate
-//- (void)networkRequestStarted
-//{
-//    _outstandingNetworkRequests++;
-//    if (_outstandingNetworkRequests == 1) {
-//        [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
-//        [(VLCAppDelegate*)[UIApplication sharedApplication].delegate disableIdleTimer];
-//    }
-//}
-
-- (void)networkRequestStopped
-{
-    _outstandingNetworkRequests--;
-    if (_outstandingNetworkRequests == 0) {
-        [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
-        [(VLCAppDelegate*)[UIApplication sharedApplication].delegate activateIdleTimer];
+- (void)loadFile:(GTLDriveFile*)file intoPath:(NSString*)destinationPath
+{
+
+    NSString *exportURLStr = file.downloadUrl;
+
+    if ([exportURLStr length] > 0) {
+        NSString *suggestedName = file.originalFilename;
+        if ([suggestedName length] == 0) {
+            suggestedName = file.title;
+        }
+
+        NSURL *url = [NSURL URLWithString:exportURLStr];
+        NSURLRequest *request = [NSURLRequest requestWithURL:url];
+        GTMHTTPFetcher *fetcher = [GTMHTTPFetcher fetcherWithRequest:request];
+
+        // Requests of user data from Google services must be authorized.
+        fetcher.authorizer = self.driveService.authorizer;
+
+        // The fetcher can save data directly to a file.
+        fetcher.downloadPath = destinationPath;
+
+        // Fetcher logging can include comments.
+        [fetcher setCommentWithFormat:@"Downloading \"%@\"", file.title];
+
+        __weak GTMHTTPFetcher *weakFetcher = fetcher;
+
+        fetcher.receivedDataBlock = ^(NSData *receivedData) {
+            float progress = (float)weakFetcher.downloadedLength / (float)[file.fileSize longLongValue];
+
+            if ([self.delegate respondsToSelector:@selector(currentProgressInformation:)])
+                [self.delegate currentProgressInformation:progress];
+        };
+
+        [fetcher beginFetchWithCompletionHandler:^(NSData *data, NSError *error) {
+            // Callback
+            //TODO:localize Strings
+            if (error == nil) {
+                UIAlertView *alert;
+                alert = [[UIAlertView alloc] initWithTitle: @"Downloaded"
+                                                   message: @"your file has been sucessfully downloaded"
+                                                  delegate: nil
+                                         cancelButtonTitle: @"OK"
+                                         otherButtonTitles: nil];
+                [alert show];
+                [self downloadSucessfull];
+            } else {
+                UIAlertView *alert;
+                alert = [[UIAlertView alloc] initWithTitle: @"Error"
+                                                   message: @"AN Error occured while downloading"
+                                                  delegate: nil
+                                         cancelButtonTitle: @"OK"
+                                         otherButtonTitles: nil];
+                [alert show];
+                [self downloadFailedWithError:error];
+            }
+        }];
     }
 }
 
+- (void)downloadSucessfull
+{
+    /* update library now that we got a file */
+    APLog(@"DriveFile download was sucessful");
+    VLCAppDelegate *appDelegate = [UIApplication sharedApplication].delegate;
+    [appDelegate updateMediaList];
+
+    if ([self.delegate respondsToSelector:@selector(operationWithProgressInformationStopped)])
+        [self.delegate operationWithProgressInformationStopped];
+    _downloadInProgress = NO;
+
+    [self _triggerNextDownload];
+}
+
+- (void)downloadFailedWithError:(NSError*)error
+{
+    APLog(@"DriveFile download failed with error %i", error.code);
+    if ([self.delegate respondsToSelector:@selector(operationWithProgressInformationStopped)])
+        [self.delegate operationWithProgressInformationStopped];
+    _downloadInProgress = NO;
+
+    [self _triggerNextDownload];
+}
+
 #pragma mark - VLC internal communication and delegate
 
 - (NSArray *)currentListFiles

+ 2 - 3
AspenProject/VLCGoogleDriveTableViewCell.h

@@ -7,8 +7,7 @@
 //
 //  Refer to the COPYING file of the official project for license.
 //
-
-//#import <DropboxSDK/DropboxSDK.h>
+#import "GTLDrive.h"
 
 @interface VLCGoogleDriveTableViewCell : UITableViewCell
 
@@ -17,7 +16,7 @@
 @property (nonatomic, strong) IBOutlet UILabel *subtitleLabel;
 @property (nonatomic, strong) IBOutlet UIImageView *thumbnailView;
 
-//@property (nonatomic, retain) DBMetadata *fileMetadata;
+@property (nonatomic) GTLDriveFile *driveFile;
 
 + (VLCGoogleDriveTableViewCell *)cellWithReuseIdentifier:(NSString *)ident;
 + (CGFloat)heightOfCell;

+ 30 - 0
AspenProject/VLCGoogleDriveTableViewCell.m

@@ -22,8 +22,38 @@
     return cell;
 }
 
+- (void)setDriveFile:(GTLDriveFile *)driveFile
+{
+    if (driveFile != _driveFile)
+        _driveFile = driveFile;
+
+    [self _updatedDisplayedInformation];
+}
+
 - (void)_updatedDisplayedInformation
 {
+    BOOL isDirectory = [self.driveFile.mimeType isEqualToString:@"application/vnd.google-apps.folder"];
+    if (isDirectory) {
+        self.folderTitleLabel.text = self.driveFile.title;
+        self.titleLabel.text = @"";
+        self.subtitleLabel.text = @"";
+    } else {
+        self.titleLabel.text = self.driveFile.title;
+        self.subtitleLabel.text = (self.driveFile.fileSize > 0) ? [NSByteCountFormatter stringFromByteCount:[self.driveFile.fileSize longLongValue] countStyle:NSByteCountFormatterCountStyleFile]: @"";
+        self.folderTitleLabel.text = @"";
+    }
+
+    NSString *iconName = self.driveFile.iconLink;
+    if ([iconName isEqualToString:@"https://ssl.gstatic.com/docs/doclist/images/icon_11_shared_collection_list.png"] || [iconName isEqualToString:@"https://ssl.gstatic.com/docs/doclist/images/icon_11_collection_list.png"]) {
+        self.thumbnailView.image = [UIImage imageNamed:@"folder"];
+    } else if ([iconName isEqualToString:@"https://ssl.gstatic.com/docs/doclist/images/icon_10_audio_list.png"]) {
+        self.thumbnailView.image = [UIImage imageNamed:@"blank"];
+    } else if ([iconName isEqualToString:@"https://ssl.gstatic.com/docs/doclist/images/icon_11_video_list.png"]) {
+        self.thumbnailView.image = [UIImage imageNamed:@"movie"];
+    } else {
+        self.thumbnailView.image = [UIImage imageNamed:@"blank"];
+        APLog(@"missing icon for type '%@'", self.driveFile.iconLink);
+    }
     [self setNeedsDisplay];
 }
 

+ 23 - 29
AspenProject/VLCGoogleDriveTableViewController.m

@@ -17,12 +17,11 @@
 #import "VLCGoogleDriveConstants.h"
 #import "GTMOAuth2ViewControllerTouch.h"
 
-static NSString *const kKeychainItemName = @"Google Drive Quickstart #3";
-
 @interface VLCGoogleDriveTableViewController ()
 {
-    VLCGoogleDriveController *_googleDriveController;
+    GTLDriveFile *_selectedFile;
     GTMOAuth2ViewControllerTouch *_authController;
+
     NSString *_currentPath;
 
     UIBarButtonItem *_backButton;
@@ -34,6 +33,8 @@ static NSString *const kKeychainItemName = @"Google Drive Quickstart #3";
     UIProgressView *_progressView;
 
     UIActivityIndicatorView *_activityIndicator;
+
+    VLCGoogleDriveController *_googleDriveController;
 }
 
 @end
@@ -82,7 +83,7 @@ static NSString *const kKeychainItemName = @"Google Drive Quickstart #3";
 
 - (GTMOAuth2ViewControllerTouch *)createAuthController
 {
-    _authController = [[GTMOAuth2ViewControllerTouch alloc] initWithScope:kGTLAuthScopeDriveFile
+    _authController = [[GTMOAuth2ViewControllerTouch alloc] initWithScope:kGTLAuthScopeDrive
                                                                 clientID:kVLCGoogleDriveClientID
                                                             clientSecret:kVLCGoogleDriveClientSecret
                                                         keychainItemName:kKeychainItemName
@@ -91,17 +92,12 @@ static NSString *const kKeychainItemName = @"Google Drive Quickstart #3";
     return _authController;
 }
 
-- (void)viewController:(GTMOAuth2ViewControllerTouch *)viewController
-      finishedWithAuth:(GTMOAuth2Authentication *)authResult
-                 error:(NSError *)error
+- (void)viewController:(GTMOAuth2ViewControllerTouch *)viewController finishedWithAuth:(GTMOAuth2Authentication *)authResult error:(NSError *)error
 {
-    if (error != nil)
-    {
+    if (error != nil) {
         [self showAlert:@"Authentication Error" message:error.localizedDescription];
         _googleDriveController.driveService.authorizer = nil;
-    }
-    else
-    {
+    } else {
         _googleDriveController.driveService.authorizer = authResult;
     }
     [self updateViewAfterSessionChange];
@@ -195,7 +191,7 @@ static NSString *const kKeychainItemName = @"Google Drive Quickstart #3";
     if (cell == nil)
         cell = [VLCGoogleDriveTableViewCell cellWithReuseIdentifier:CellIdentifier];
 
-   // cell.fileMetadata = _googleDriveController.currentListFiles[indexPath.row];
+    cell.driveFile = _googleDriveController.currentListFiles[indexPath.row];
 
     return cell;
 }
@@ -209,27 +205,27 @@ static NSString *const kKeychainItemName = @"Google Drive Quickstart #3";
 
 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
 {
-//    _selectedFile = _googleDriveController.currentListFiles[indexPath.row];
-//    if (!_selectedFile.isDirectory) {
-//        /* selected item is a proper file, ask the user if s/he wants to download it */
-//        UIAlertView * alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"GOOGLE_DRIVE_DOWNLOAD", @"") message:[NSString stringWithFormat:NSLocalizedString(@"GOOGLE_DRIVE_DL_LONG", @""), _selectedFile.filename, [[UIDevice currentDevice] model]] delegate:self cancelButtonTitle:NSLocalizedString(@"BUTTON_CANCEL", @"") otherButtonTitles:NSLocalizedString(@"BUTTON_DOWNLOAD", @""), nil];
-//        [alert show];
-//    } else {
-//        /* dive into subdirectory */
-//        _currentPath = [_currentPath stringByAppendingFormat:@"/%@", _selectedFile.filename];
-//        [self _requestInformationForCurrentPath];
-//        _selectedFile = nil;
-//    }
+    _selectedFile = _googleDriveController.currentListFiles[indexPath.row];
+    if (![_selectedFile.mimeType isEqualToString:@"application/vnd.google-apps.folder"]) {
+        /* selected item is a proper file, ask the user if s/he wants to download it */
+        UIAlertView * alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"GOOGLE_DRIVE_DOWNLOAD", @"") message:[NSString stringWithFormat:NSLocalizedString(@"GOOGLE_DRIVE_DL_LONG", @""), _selectedFile.title, [[UIDevice currentDevice] model]] delegate:self cancelButtonTitle:NSLocalizedString(@"BUTTON_CANCEL", @"") otherButtonTitles:NSLocalizedString(@"BUTTON_DOWNLOAD", @""), nil];
+        [alert show];
+    } else {
+        /* dive into subdirectory */
+           _currentPath = [_currentPath stringByAppendingFormat:@"/%@", _selectedFile.title];
+        [self _requestInformationForCurrentPath];
+        _selectedFile = nil;
+    }
 
     [self.tableView deselectRowAtIndexPath:indexPath animated:NO];
 }
 
 - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
 {
-   // if (buttonIndex == 1)
-      //  [_googleDriveController downloadFileToDocumentFolder:_selectedFile];
+    if (buttonIndex == 1)
+        [_googleDriveController downloadFileToDocumentFolder:_selectedFile];
 
-   // _selectedFile = nil;
+    _selectedFile = nil;
 }
 
 #pragma mark - dropbox controller delegate
@@ -288,10 +284,8 @@ static NSString *const kKeychainItemName = @"Google Drive Quickstart #3";
 - (IBAction)loginToGoogleDriveAction:(id)sender
 {
     if (![_googleDriveController isAuthorized]) {
-        _googleDriveController.isAuthorized = NO;
         [self.navigationController pushViewController:[self createAuthController] animated:YES];
     } else {
-        _googleDriveController.isAuthorized = YES;
         [_googleDriveController logout];
     }
 }

+ 5 - 1
AspenProject/VLCSettingsController.m

@@ -15,6 +15,7 @@
 #import "IASKAppSettingsViewController.h"
 #import "PAPasscodeViewController.h"
 #import <DropboxSDK/DropboxSDK.h>
+#import "VLCGoogleDriveController.h"
 
 @interface VLCSettingsController ()<PAPasscodeViewControllerDelegate, IASKSettingsDelegate>
 @end
@@ -54,8 +55,11 @@
 }
 
 - (void)settingsViewController:(IASKAppSettingsViewController*)sender buttonTappedForSpecifier:(IASKSpecifier*)specifier {
-    if ([specifier.key isEqualToString:@"UnlinkDropbox"])
+    if ([specifier.key isEqualToString:@"UnlinkDropbox"]) {
         [[DBSession sharedSession] unlinkAll];
+    } else if ([specifier.key isEqualToString:@"UnlinkGoogleDrive"]) {
+        [GTMOAuth2ViewControllerTouch removeAuthFromKeychainForName:kKeychainItemName];
+    }
 }
 
 #pragma mark - PAPasscode delegate

+ 8 - 0
Resources/Settings.bundle/Root.inApp.plist

@@ -338,6 +338,14 @@
 			<key>Type</key>
 			<string>IASKButtonSpecifier</string>
 		</dict>
+		<dict>
+			<key>Key</key>
+			<string>UnlinkGoogleDrive</string>
+			<key>Title</key>
+			<string>SETTINGS_UNLINK_GOOGLEDRIVE</string>
+			<key>Type</key>
+			<string>IASKButtonSpecifier</string>
+		</dict>
 	</array>
 	<key>StringsTable</key>
 	<string>Root</string>