// // DropboxModel.m // PDF Reader // // Created by HuFeng on 13-3-27. // Copyright (c) 2013年 zhangjie. All rights reserved. // __MAC_10_9 #import "DropboxModel.h" //#import "Constant.h" //#import "KMMember+Receipt.h" //#import "KMPurchaseCompareTool.h" //#import "PDFReaderAppDelegate.h" #if __MAC_OS_X_VERSION_MAX_ALLOWED > __MAC_10_9 #import #endif #define UserNameKey @"GetUserName" #define FileSyncDateKey @"FileSyncDate" #define UserEmailKey @"GetEmailName" @interface DropboxModel () @property(nonatomic, copy) NSString *appKey; @property(nonatomic, copy) NSString *appSecret; @property(nonatomic, copy) NSString *root; #if __MAC_OS_X_VERSION_MAX_ALLOWED > __MAC_10_9 @property (nonatomic,retain) DBUploadTask *uploadTask; #endif @end @implementation DropboxModel @synthesize objectDelegate; @synthesize appKey = _appKey; @synthesize appSecret = _appSecret; @synthesize root = _root; @synthesize filePathArray = _filePathArray; @synthesize currentUploadPath = _currentUploadPath; @synthesize userName = _userName; @synthesize syncDate = _syncDate; + (DropboxModel *)shared { static DropboxModel *sharedModel = nil; static dispatch_once_t predicate; dispatch_once(&predicate, ^{ sharedModel = [[DropboxModel alloc] init]; }); return sharedModel; } - (id)init { self = [super init]; if (self) { // 设置 Dropbox 的app参数,由彦忠管理, #if VERSION_PRO self.appKey = @"amipzwtlg9lrwyl"; #else self.appKey = @"jxjlqfm1cfp2mjj"; #endif NSString *registeredUrlToHandle = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleURLTypes"][0][@"CFBundleURLSchemes"][0]; if (!self.appKey || [registeredUrlToHandle rangeOfString:@"<"].location != NSNotFound) { NSString *message = @"You need to set `appKey` variable in `AppDelegate.m`, as well as add to `Info.plist`, before you can use DBRoulette."; NSLog(@"%@", message); NSLog(@"Terminating..."); exit(1); } self.userName = [[NSUserDefaults standardUserDefaults] objectForKey:UserNameKey]; self.syncDate = [[NSUserDefaults standardUserDefaults] objectForKey:FileSyncDateKey]; self.userEmail = [[NSUserDefaults standardUserDefaults] objectForKey:UserEmailKey]; } return self; } #pragma mark - #pragma mark ===== User Login ===== - (void)handleAppleEvent:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent { NSURL *url = [NSURL URLWithString:[[event paramDescriptorForKeyword:keyDirectObject] stringValue]]; // [DBClientsManager handleRedirectURL:url completion:^(DBOAuthResult * _Nullable authResult) { // if (authResult != nil) { // if ([authResult isSuccess]) { // NSLog(@"Success! User is logged into Dropbox."); // if( [self isLinked]){ // [self loadAccountInfomation]; // // if (nil != self.filePathArray) { // [self uploadFileToServer]; // } // } // // } else if ([authResult isCancel]) { // if ([objectDelegate respondsToSelector:@selector(cancelUpLoadProgressBar)]) { // [objectDelegate cancelUpLoadProgressBar]; // } // } else if ([authResult isError]) { // if ([objectDelegate respondsToSelector:@selector(cancelUpLoadProgressBar)]) { // [objectDelegate cancelUpLoadProgressBar]; // } // // NSAlert *alert = [[NSAlert alloc] init]; // [alert setAlertStyle:NSAlertStyleCritical]; // [alert setMessageText:authResult.errorDescription]; // [alert runModal]; // NSLog(@"Error: %@", authResult); // } // } // }]; } - (void)handleAuthResult:(DBOAuthResult *)authResult { if (authResult != nil) { if ([authResult isSuccess]) { NSLog(@"Success! User is logged into Dropbox."); if( [self isLinked]){ [self loadAccountInfomation]; if (nil != self.filePathArray) { [self uploadFileToServer]; } } } else if ([authResult isCancel]) { if ([objectDelegate respondsToSelector:@selector(cancelUpLoadProgressBar)]) { [objectDelegate cancelUpLoadProgressBar]; } } else if ([authResult isError]) { if ([objectDelegate respondsToSelector:@selector(cancelUpLoadProgressBar)]) { [objectDelegate cancelUpLoadProgressBar]; } NSAlert *alert = [[NSAlert alloc] init]; [alert setAlertStyle:NSAlertStyleCritical]; [alert setMessageText:authResult.errorDescription]; [alert runModal]; NSLog(@"Error: %@", authResult); } } } - (void)loadAccountInfomation { DBUserClient *client = [DBClientsManager authorizedClient]; [[client.usersRoutes getCurrentAccount] setResponseBlock:^(DBUSERSFullAccount * _Nullable result, DBNilObject * _Nullable routeError, DBRequestError * _Nullable networkError) { if (![_userName isEqualToString:result.name.givenName]) { self.userName = result.name.givenName; [[NSUserDefaults standardUserDefaults] setObject:self.userName forKey:UserNameKey]; [[NSUserDefaults standardUserDefaults] synchronize]; } self.userEmail = result.email; [[NSUserDefaults standardUserDefaults] setObject:self.userEmail forKey:UserEmailKey]; [[NSNotificationCenter defaultCenter] postNotificationName:kUpdateUserName object:self.userName]; }]; } #pragma mark - #pragma mark ===== authenticate ===== - (void)linkServer { [DBClientsManager authorizeFromControllerDesktop:[NSWorkspace sharedWorkspace] controller:nil openURL:^(NSURL *url){ [[NSWorkspace sharedWorkspace] openURL:url]; }]; } - (void)unlinkAll { if ([DBClientsManager authorizedClient]) { [DBClientsManager unlinkAndResetClients]; self.userName = NSLocalizedString(@"Invalid Username",nil); [[NSUserDefaults standardUserDefaults] setObject:self.userName forKey:UserNameKey]; [[NSUserDefaults standardUserDefaults] synchronize]; [[NSNotificationCenter defaultCenter] postNotificationName:kUpdateUserName object:self.userName]; } } - (BOOL)isLinked { return ([DBClientsManager authorizedClient] ? YES : NO); } - (void)getUrl:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent { // This gets called when the user clicks Show "App name". You don't need to do anything for Dropbox here } #define FreeVersion_UploadInformation @"FreeVersionUploadInformation" #define FreeVersion_UploadInformation_UploadDate @"UploadDate" #define FreeVersion_UploadInformation_FileCount @"UploadFileCount" - (void)updateNumberOfUploadFile { if ([[NSUserDefaults standardUserDefaults] objectForKey:FreeVersion_UploadInformation]) { if ([self numberOfUploadFile] != 0) { NSDictionary *dic = [[NSUserDefaults standardUserDefaults] objectForKey:FreeVersion_UploadInformation]; NSNumber *number = [dic objectForKey:FreeVersion_UploadInformation_FileCount]; NSInteger count = [number integerValue]; count++; NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys: [NSDate date],FreeVersion_UploadInformation_UploadDate, [NSNumber numberWithInteger:count],FreeVersion_UploadInformation_FileCount,nil]; [[NSUserDefaults standardUserDefaults] setObject:dictionary forKey:FreeVersion_UploadInformation]; [[NSUserDefaults standardUserDefaults] synchronize]; return; } } NSDictionary *dic = [NSDictionary dictionaryWithObjectsAndKeys: [NSDate date],FreeVersion_UploadInformation_UploadDate, [NSNumber numberWithInteger:1],FreeVersion_UploadInformation_FileCount,nil]; [[NSUserDefaults standardUserDefaults] setObject:dic forKey:FreeVersion_UploadInformation]; [[NSUserDefaults standardUserDefaults] synchronize]; } - (NSInteger)numberOfUploadFile { NSDateComponents *ccomps = [[NSCalendar currentCalendar] components:(NSYearCalendarUnit | NSMonthCalendarUnit |NSDayCalendarUnit) fromDate:[NSDate date]]; NSInteger cyear = [ccomps year]; NSInteger cmonth = [ccomps month]; NSInteger cday = [ccomps day]; if ([[NSUserDefaults standardUserDefaults] objectForKey:FreeVersion_UploadInformation]) { NSDictionary *dic = [[NSUserDefaults standardUserDefaults] objectForKey:FreeVersion_UploadInformation]; NSDate *date = [dic objectForKey:FreeVersion_UploadInformation_UploadDate]; NSNumber *number = [dic objectForKey:FreeVersion_UploadInformation_FileCount]; if (date) { NSDateComponents *comps = [[NSCalendar currentCalendar] components:(NSYearCalendarUnit | NSMonthCalendarUnit |NSDayCalendarUnit) fromDate:date]; NSInteger year = [comps year]; NSInteger month = [comps month]; NSInteger day = [comps day]; if (year == cyear && month == cmonth && day == cday) { return [number integerValue]; } else { return 0; } } else { return 0; } } return 0; } #pragma mark - #pragma mark ===== UPload files ===== - (BOOL)uploadFile:(NSArray *)filePathArray { self.filePathArray = filePathArray; //免費版當天只能限制dropbox 10個檔案同步 NSUInteger count = [self numberOfUploadFile]; if (self.filePathArray.count > (10-count)) { self.filePathArray = [filePathArray subarrayWithRange:NSMakeRange(0, 10-count)]; } if ([self isLinked]) { [self uploadFileToServer]; } else { if ([objectDelegate respondsToSelector:@selector(updateUploadProgressBar:withMessage:leftFilesString:)]) { [objectDelegate updateUploadProgressBar:0 withMessage:NSLocalizedString(@"Authenticating...", nil) leftFilesString:nil]; } [self linkServer]; } return YES; } - (void)uploadFileToServer { _currentUploadPath = [_filePathArray objectAtIndex:0]; [self newUploatFile]; } - (void)newUploatFile { [self updateNumberOfUploadFile]; NSData *fileData = [[NSData alloc] initWithContentsOfURL:[NSURL fileURLWithPath:_currentUploadPath]]; NSString * path = [NSString stringWithFormat:@"/%@",[_currentUploadPath lastPathComponent]]; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ DBUserClient * client = [DBClientsManager authorizedClient]; self.uploadTask = [client.filesRoutes uploadData:path inputData:fileData]; [[self.uploadTask setResponseBlock:^(DBFILESFileMetadata *result, DBFILESUploadError *routeError, DBRequestError *networkError) { if (result) { NSLog(@"---上传成功"); self.syncDate = [self fileSyncDateStr]; [[NSUserDefaults standardUserDefaults] setObject:self.syncDate forKey:FileSyncDateKey]; [[NSUserDefaults standardUserDefaults] synchronize]; NSInteger cnt = [_filePathArray count]; NSInteger index = [_filePathArray indexOfObject:_currentUploadPath]; if (1 == _progressValue && index < cnt - 1) { _currentUploadPath = [_filePathArray objectAtIndex:index + 1]; [self newUploatFile]; } else { self.filePathArray = nil; } } else { NSLog(@"---上传失败"); [self newUploadFileState:networkError.statusCode.integerValue]; } }] setProgressBlock:^(int64_t bytesUploaded, int64_t totalBytesUploaded, int64_t totalBytesExpectedToUploaded) { NSInteger cnt = [_filePathArray count]; NSInteger index = [_filePathArray indexOfObject:_currentUploadPath]; _progressValue = totalBytesUploaded/(CGFloat)(totalBytesExpectedToUploaded); float totalProgress = (index + _progressValue)/cnt; if ([objectDelegate respondsToSelector:@selector(updateUploadProgressBar:withMessage:leftFilesString:)]) { NSString * contenxtString = nil; if (self.filePathArray.count > 1) { contenxtString = [NSString stringWithFormat:NSLocalizedString(@"%ld files left", nil),cnt - index]; } else { contenxtString = [NSString stringWithFormat:NSLocalizedString(@"%ld file left", nil),cnt - index]; } [objectDelegate updateUploadProgressBar:totalProgress withMessage:NSLocalizedString(@"Uploading...", nil) leftFilesString:contenxtString]; } }]; }); } - (void)newUploadFileState:(NSInteger)code { NSLog(@"---上传失败"); self.filePathArray = nil; if ([objectDelegate respondsToSelector:@selector(cancelUpLoadProgressBar)]) { [objectDelegate cancelUpLoadProgressBar]; } NSAlert *alert = [[NSAlert alloc] init]; [alert setAlertStyle:NSAlertStyleCritical]; NSString *tStrMessage = NSLocalizedString(@"Server Error", nil); switch (code) { case 400: { NSLog(@"Bad input parameter."); tStrMessage = NSLocalizedString(@"Upload Failed!", nil); } break; case 401: NSLog(@"Bad or expired token."); tStrMessage = NSLocalizedString(@"Authentication Failed!", nil); break; case 403: NSLog(@"Bad OAuth request."); tStrMessage = NSLocalizedString(@"Authentication Failed!", nil); break; case 404: NSLog(@"The file or folder is not found at the specified path."); tStrMessage = NSLocalizedString(@"Upload Failed!", nil); break; case 405: NSLog(@"Request method not expected (generally should be GET or POST)."); tStrMessage = NSLocalizedString(@"Upload Failed!", nil); break; case 409: NSLog(@"Unlike many other error codes, it doesn’t have any specific meaning in the HTTP spec."); tStrMessage = NSLocalizedString(@"Unlike many other error codes, it doesn’t have any specific meaning in the HTTP spec.", nil); break; case 503: NSLog(@"Your app is making too many requests and is being rate limited."); tStrMessage = NSLocalizedString(@"Upload Failed!", nil); break; case 507: NSLog(@"User is over Dropbox storage quota."); tStrMessage = NSLocalizedString(@"Upload Failed!", nil); break; default: tStrMessage = NSLocalizedString(@"Server Error", nil); break; } [alert setMessageText:tStrMessage]; [alert runModal]; } - (void)cancleUploadFile { self.filePathArray = nil; if ([self isLinked]) { [self.uploadTask cancel]; } } #pragma mark - - (NSString *)fileSyncDateStr { NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init]; [dateFormatter setDateStyle:(kCFDateFormatterShortStyle)]; [dateFormatter setTimeStyle:(kCFDateFormatterShortStyle)]; return [dateFormatter stringFromDate:[NSDate date]]; } @end