DropboxModel.m 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417
  1. //
  2. // DropboxModel.m
  3. // PDF Reader
  4. //
  5. // Created by HuFeng on 13-3-27.
  6. // Copyright (c) 2013年 zhangjie. All rights reserved.
  7. // __MAC_10_9
  8. #import "DropboxModel.h"
  9. //#import "Constant.h"
  10. //#import "KMMember+Receipt.h"
  11. //#import "KMPurchaseCompareTool.h"
  12. //#import "PDFReaderAppDelegate.h"
  13. #if __MAC_OS_X_VERSION_MAX_ALLOWED > __MAC_10_9
  14. #import <ObjectiveDropboxOfficial/ObjectiveDropboxOfficial.h>
  15. #endif
  16. #define UserNameKey @"GetUserName"
  17. #define FileSyncDateKey @"FileSyncDate"
  18. #define UserEmailKey @"GetEmailName"
  19. @interface DropboxModel ()
  20. @property(nonatomic, copy) NSString *appKey;
  21. @property(nonatomic, copy) NSString *appSecret;
  22. @property(nonatomic, copy) NSString *root;
  23. #if __MAC_OS_X_VERSION_MAX_ALLOWED > __MAC_10_9
  24. @property (nonatomic,retain) DBUploadTask *uploadTask;
  25. #endif
  26. @end
  27. @implementation DropboxModel
  28. @synthesize objectDelegate;
  29. @synthesize appKey = _appKey;
  30. @synthesize appSecret = _appSecret;
  31. @synthesize root = _root;
  32. @synthesize filePathArray = _filePathArray;
  33. @synthesize currentUploadPath = _currentUploadPath;
  34. @synthesize userName = _userName;
  35. @synthesize syncDate = _syncDate;
  36. + (DropboxModel *)shared {
  37. static DropboxModel *sharedModel = nil;
  38. static dispatch_once_t predicate;
  39. dispatch_once(&predicate, ^{
  40. sharedModel = [[DropboxModel alloc] init];
  41. });
  42. return sharedModel;
  43. }
  44. - (id)init {
  45. self = [super init];
  46. if (self) {
  47. // 设置 Dropbox 的app参数,由彦忠管理,
  48. #if VERSION_PRO
  49. self.appKey = @"amipzwtlg9lrwyl";
  50. #else
  51. self.appKey = @"jxjlqfm1cfp2mjj";
  52. #endif
  53. NSString *registeredUrlToHandle = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleURLTypes"][0][@"CFBundleURLSchemes"][0];
  54. if (!self.appKey ||
  55. [registeredUrlToHandle rangeOfString:@"<"].location != NSNotFound) {
  56. NSString *message = @"You need to set `appKey` variable in `AppDelegate.m`, as well as add to `Info.plist`, before you can use DBRoulette.";
  57. NSLog(@"%@", message);
  58. NSLog(@"Terminating...");
  59. exit(1);
  60. }
  61. self.userName = [[NSUserDefaults standardUserDefaults] objectForKey:UserNameKey];
  62. self.syncDate = [[NSUserDefaults standardUserDefaults] objectForKey:FileSyncDateKey];
  63. self.userEmail = [[NSUserDefaults standardUserDefaults] objectForKey:UserEmailKey];
  64. }
  65. return self;
  66. }
  67. #pragma mark -
  68. #pragma mark ===== User Login =====
  69. - (void)handleAppleEvent:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent
  70. {
  71. NSURL *url = [NSURL URLWithString:[[event paramDescriptorForKeyword:keyDirectObject] stringValue]];
  72. // [DBClientsManager handleRedirectURL:url completion:^(DBOAuthResult * _Nullable authResult) {
  73. // if (authResult != nil) {
  74. // if ([authResult isSuccess]) {
  75. // NSLog(@"Success! User is logged into Dropbox.");
  76. // if( [self isLinked]){
  77. // [self loadAccountInfomation];
  78. //
  79. // if (nil != self.filePathArray) {
  80. // [self uploadFileToServer];
  81. // }
  82. // }
  83. //
  84. // } else if ([authResult isCancel]) {
  85. // if ([objectDelegate respondsToSelector:@selector(cancelUpLoadProgressBar)]) {
  86. // [objectDelegate cancelUpLoadProgressBar];
  87. // }
  88. // } else if ([authResult isError]) {
  89. // if ([objectDelegate respondsToSelector:@selector(cancelUpLoadProgressBar)]) {
  90. // [objectDelegate cancelUpLoadProgressBar];
  91. // }
  92. //
  93. // NSAlert *alert = [[NSAlert alloc] init];
  94. // [alert setAlertStyle:NSAlertStyleCritical];
  95. // [alert setMessageText:authResult.errorDescription];
  96. // [alert runModal];
  97. // NSLog(@"Error: %@", authResult);
  98. // }
  99. // }
  100. // }];
  101. }
  102. - (void)handleAuthResult:(DBOAuthResult *)authResult {
  103. if (authResult != nil) {
  104. if ([authResult isSuccess]) {
  105. NSLog(@"Success! User is logged into Dropbox.");
  106. if( [self isLinked]){
  107. [self loadAccountInfomation];
  108. if (nil != self.filePathArray) {
  109. [self uploadFileToServer];
  110. }
  111. }
  112. } else if ([authResult isCancel]) {
  113. if ([objectDelegate respondsToSelector:@selector(cancelUpLoadProgressBar)]) {
  114. [objectDelegate cancelUpLoadProgressBar];
  115. }
  116. } else if ([authResult isError]) {
  117. if ([objectDelegate respondsToSelector:@selector(cancelUpLoadProgressBar)]) {
  118. [objectDelegate cancelUpLoadProgressBar];
  119. }
  120. NSAlert *alert = [[NSAlert alloc] init];
  121. [alert setAlertStyle:NSAlertStyleCritical];
  122. [alert setMessageText:authResult.errorDescription];
  123. [alert runModal];
  124. NSLog(@"Error: %@", authResult);
  125. }
  126. }
  127. }
  128. - (void)loadAccountInfomation
  129. {
  130. DBUserClient *client = [DBClientsManager authorizedClient];
  131. [[client.usersRoutes getCurrentAccount] setResponseBlock:^(DBUSERSFullAccount * _Nullable result, DBNilObject * _Nullable routeError, DBRequestError * _Nullable networkError) {
  132. if (![_userName isEqualToString:result.name.givenName]) {
  133. self.userName = result.name.givenName;
  134. [[NSUserDefaults standardUserDefaults] setObject:self.userName forKey:UserNameKey];
  135. [[NSUserDefaults standardUserDefaults] synchronize];
  136. }
  137. self.userEmail = result.email;
  138. [[NSUserDefaults standardUserDefaults] setObject:self.userEmail forKey:UserEmailKey];
  139. [[NSNotificationCenter defaultCenter] postNotificationName:kUpdateUserName object:self.userName];
  140. }];
  141. }
  142. #pragma mark -
  143. #pragma mark ===== authenticate =====
  144. - (void)linkServer
  145. {
  146. [DBClientsManager authorizeFromControllerDesktop:[NSWorkspace sharedWorkspace]
  147. controller:nil
  148. openURL:^(NSURL *url){
  149. [[NSWorkspace sharedWorkspace] openURL:url];
  150. }];
  151. }
  152. - (void)unlinkAll
  153. {
  154. if ([DBClientsManager authorizedClient])
  155. {
  156. [DBClientsManager unlinkAndResetClients];
  157. self.userName = NSLocalizedString(@"Invalid Username",nil);
  158. [[NSUserDefaults standardUserDefaults] setObject:self.userName forKey:UserNameKey];
  159. [[NSUserDefaults standardUserDefaults] synchronize];
  160. [[NSNotificationCenter defaultCenter] postNotificationName:kUpdateUserName object:self.userName];
  161. }
  162. }
  163. - (BOOL)isLinked
  164. {
  165. return ([DBClientsManager authorizedClient] ? YES : NO);
  166. }
  167. - (void)getUrl:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent
  168. {
  169. // This gets called when the user clicks Show "App name". You don't need to do anything for Dropbox here
  170. }
  171. #define FreeVersion_UploadInformation @"FreeVersionUploadInformation"
  172. #define FreeVersion_UploadInformation_UploadDate @"UploadDate"
  173. #define FreeVersion_UploadInformation_FileCount @"UploadFileCount"
  174. - (void)updateNumberOfUploadFile
  175. {
  176. if ([[NSUserDefaults standardUserDefaults] objectForKey:FreeVersion_UploadInformation]) {
  177. if ([self numberOfUploadFile] != 0) {
  178. NSDictionary *dic = [[NSUserDefaults standardUserDefaults] objectForKey:FreeVersion_UploadInformation];
  179. NSNumber *number = [dic objectForKey:FreeVersion_UploadInformation_FileCount];
  180. NSInteger count = [number integerValue];
  181. count++;
  182. NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:
  183. [NSDate date],FreeVersion_UploadInformation_UploadDate,
  184. [NSNumber numberWithInteger:count],FreeVersion_UploadInformation_FileCount,nil];
  185. [[NSUserDefaults standardUserDefaults] setObject:dictionary forKey:FreeVersion_UploadInformation];
  186. [[NSUserDefaults standardUserDefaults] synchronize];
  187. return;
  188. }
  189. }
  190. NSDictionary *dic = [NSDictionary dictionaryWithObjectsAndKeys:
  191. [NSDate date],FreeVersion_UploadInformation_UploadDate,
  192. [NSNumber numberWithInteger:1],FreeVersion_UploadInformation_FileCount,nil];
  193. [[NSUserDefaults standardUserDefaults] setObject:dic forKey:FreeVersion_UploadInformation];
  194. [[NSUserDefaults standardUserDefaults] synchronize];
  195. }
  196. - (NSInteger)numberOfUploadFile
  197. {
  198. NSDateComponents *ccomps = [[NSCalendar currentCalendar] components:(NSYearCalendarUnit | NSMonthCalendarUnit |NSDayCalendarUnit)
  199. fromDate:[NSDate date]];
  200. NSInteger cyear = [ccomps year];
  201. NSInteger cmonth = [ccomps month];
  202. NSInteger cday = [ccomps day];
  203. if ([[NSUserDefaults standardUserDefaults] objectForKey:FreeVersion_UploadInformation]) {
  204. NSDictionary *dic = [[NSUserDefaults standardUserDefaults] objectForKey:FreeVersion_UploadInformation];
  205. NSDate *date = [dic objectForKey:FreeVersion_UploadInformation_UploadDate];
  206. NSNumber *number = [dic objectForKey:FreeVersion_UploadInformation_FileCount];
  207. if (date) {
  208. NSDateComponents *comps = [[NSCalendar currentCalendar] components:(NSYearCalendarUnit | NSMonthCalendarUnit |NSDayCalendarUnit)
  209. fromDate:date];
  210. NSInteger year = [comps year];
  211. NSInteger month = [comps month];
  212. NSInteger day = [comps day];
  213. if (year == cyear &&
  214. month == cmonth &&
  215. day == cday) {
  216. return [number integerValue];
  217. } else {
  218. return 0;
  219. }
  220. } else {
  221. return 0;
  222. }
  223. }
  224. return 0;
  225. }
  226. #pragma mark -
  227. #pragma mark ===== UPload files =====
  228. - (BOOL)uploadFile:(NSArray *)filePathArray
  229. {
  230. self.filePathArray = filePathArray;
  231. // if (![IAPProductsManager defaultManager].isAvailableAllFunction) {
  232. //免費版當天只能限制dropbox 10個檔案同步
  233. NSUInteger count = [self numberOfUploadFile];
  234. // if (10 <= count) {
  235. // [KMPurchaseCompareTool showPurchaseCompareWindowController];
  236. // return NO;
  237. // } else if (count<10 && count > 0) {
  238. if (self.filePathArray.count > (10-count)) {
  239. self.filePathArray = [filePathArray subarrayWithRange:NSMakeRange(0, 10-count)];
  240. }
  241. // }
  242. // }
  243. if ([self isLinked]) {
  244. [self uploadFileToServer];
  245. } else {
  246. if ([objectDelegate respondsToSelector:@selector(updateUploadProgressBar:withMessage:leftFilesString:)]) {
  247. [objectDelegate updateUploadProgressBar:0
  248. withMessage:NSLocalizedString(@"Authenticating...", nil)
  249. leftFilesString:nil];
  250. }
  251. [self linkServer];
  252. }
  253. return YES;
  254. }
  255. - (void)uploadFileToServer
  256. {
  257. _currentUploadPath = [_filePathArray objectAtIndex:0];
  258. [self newUploatFile];
  259. }
  260. - (void)newUploatFile
  261. {
  262. [self updateNumberOfUploadFile];
  263. NSData *fileData = [[NSData alloc] initWithContentsOfURL:[NSURL fileURLWithPath:_currentUploadPath]];
  264. NSString * path = [NSString stringWithFormat:@"/%@",[_currentUploadPath lastPathComponent]];
  265. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  266. DBUserClient * client = [DBClientsManager authorizedClient];
  267. self.uploadTask = [client.filesRoutes uploadData:path inputData:fileData];
  268. [[self.uploadTask setResponseBlock:^(DBFILESFileMetadata *result, DBFILESUploadError *routeError, DBRequestError *networkError) {
  269. if (result) {
  270. NSLog(@"---上传成功");
  271. self.syncDate = [self fileSyncDateStr];
  272. [[NSUserDefaults standardUserDefaults] setObject:self.syncDate forKey:FileSyncDateKey];
  273. [[NSUserDefaults standardUserDefaults] synchronize];
  274. NSInteger cnt = [_filePathArray count];
  275. NSInteger index = [_filePathArray indexOfObject:_currentUploadPath];
  276. if (1 == _progressValue && index < cnt - 1) {
  277. _currentUploadPath = [_filePathArray objectAtIndex:index + 1];
  278. [self newUploatFile];
  279. } else {
  280. self.filePathArray = nil;
  281. }
  282. } else {
  283. NSLog(@"---上传失败");
  284. [self newUploadFileState:networkError.statusCode.integerValue];
  285. }
  286. }] setProgressBlock:^(int64_t bytesUploaded, int64_t totalBytesUploaded, int64_t totalBytesExpectedToUploaded) {
  287. NSInteger cnt = [_filePathArray count];
  288. NSInteger index = [_filePathArray indexOfObject:_currentUploadPath];
  289. _progressValue = totalBytesUploaded/(CGFloat)(totalBytesExpectedToUploaded);
  290. float totalProgress = (index + _progressValue)/cnt;
  291. if ([objectDelegate respondsToSelector:@selector(updateUploadProgressBar:withMessage:leftFilesString:)]) {
  292. NSString * contenxtString = nil;
  293. if (self.filePathArray.count > 1) {
  294. contenxtString = [NSString stringWithFormat:NSLocalizedString(@"%ld files left", nil),cnt - index];
  295. } else {
  296. contenxtString = [NSString stringWithFormat:NSLocalizedString(@"%ld file left", nil),cnt - index];
  297. }
  298. [objectDelegate updateUploadProgressBar:totalProgress
  299. withMessage:NSLocalizedString(@"Uploading...", nil)
  300. leftFilesString:contenxtString];
  301. }
  302. }];
  303. });
  304. }
  305. - (void)newUploadFileState:(NSInteger)code
  306. {
  307. NSLog(@"---上传失败");
  308. self.filePathArray = nil;
  309. if ([objectDelegate respondsToSelector:@selector(cancelUpLoadProgressBar)]) {
  310. [objectDelegate cancelUpLoadProgressBar];
  311. }
  312. NSAlert *alert = [[NSAlert alloc] init];
  313. [alert setAlertStyle:NSAlertStyleCritical];
  314. NSString *tStrMessage = NSLocalizedString(@"Server Error", nil);
  315. switch (code) {
  316. case 400:
  317. {
  318. NSLog(@"Bad input parameter.");
  319. tStrMessage = NSLocalizedString(@"Upload Failed!", nil);
  320. }
  321. break;
  322. case 401:
  323. NSLog(@"Bad or expired token.");
  324. tStrMessage = NSLocalizedString(@"Authentication Failed!", nil);
  325. break;
  326. case 403:
  327. NSLog(@"Bad OAuth request.");
  328. tStrMessage = NSLocalizedString(@"Authentication Failed!", nil);
  329. break;
  330. case 404:
  331. NSLog(@"The file or folder is not found at the specified path.");
  332. tStrMessage = NSLocalizedString(@"Upload Failed!", nil);
  333. break;
  334. case 405:
  335. NSLog(@"Request method not expected (generally should be GET or POST).");
  336. tStrMessage = NSLocalizedString(@"Upload Failed!", nil);
  337. break;
  338. case 409:
  339. NSLog(@"Unlike many other error codes, it doesn’t have any specific meaning in the HTTP spec.");
  340. tStrMessage = NSLocalizedString(@"Unlike many other error codes, it doesn’t have any specific meaning in the HTTP spec.", nil);
  341. break;
  342. case 503:
  343. NSLog(@"Your app is making too many requests and is being rate limited.");
  344. tStrMessage = NSLocalizedString(@"Upload Failed!", nil);
  345. break;
  346. case 507:
  347. NSLog(@"User is over Dropbox storage quota.");
  348. tStrMessage = NSLocalizedString(@"Upload Failed!", nil);
  349. break;
  350. default:
  351. tStrMessage = NSLocalizedString(@"Server Error", nil);
  352. break;
  353. }
  354. [alert setMessageText:tStrMessage];
  355. [alert runModal];
  356. }
  357. - (void)cancleUploadFile
  358. {
  359. self.filePathArray = nil;
  360. if ([self isLinked]) {
  361. [self.uploadTask cancel];
  362. }
  363. }
  364. #pragma mark -
  365. - (NSString *)fileSyncDateStr
  366. {
  367. NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init];
  368. [dateFormatter setDateStyle:(kCFDateFormatterShortStyle)];
  369. [dateFormatter setTimeStyle:(kCFDateFormatterShortStyle)];
  370. return [dateFormatter stringFromDate:[NSDate date]];
  371. }
  372. @end