DropboxModel.m 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410
  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. //免費版當天只能限制dropbox 10個檔案同步
  232. NSUInteger count = [self numberOfUploadFile];
  233. if (self.filePathArray.count > (10-count)) {
  234. self.filePathArray = [filePathArray subarrayWithRange:NSMakeRange(0, 10-count)];
  235. }
  236. if ([self isLinked]) {
  237. [self uploadFileToServer];
  238. } else {
  239. if ([objectDelegate respondsToSelector:@selector(updateUploadProgressBar:withMessage:leftFilesString:)]) {
  240. [objectDelegate updateUploadProgressBar:0
  241. withMessage:NSLocalizedString(@"Authenticating...", nil)
  242. leftFilesString:nil];
  243. }
  244. [self linkServer];
  245. }
  246. return YES;
  247. }
  248. - (void)uploadFileToServer
  249. {
  250. _currentUploadPath = [_filePathArray objectAtIndex:0];
  251. [self newUploatFile];
  252. }
  253. - (void)newUploatFile
  254. {
  255. [self updateNumberOfUploadFile];
  256. NSData *fileData = [[NSData alloc] initWithContentsOfURL:[NSURL fileURLWithPath:_currentUploadPath]];
  257. NSString * path = [NSString stringWithFormat:@"/%@",[_currentUploadPath lastPathComponent]];
  258. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  259. DBUserClient * client = [DBClientsManager authorizedClient];
  260. self.uploadTask = [client.filesRoutes uploadData:path inputData:fileData];
  261. [[self.uploadTask setResponseBlock:^(DBFILESFileMetadata *result, DBFILESUploadError *routeError, DBRequestError *networkError) {
  262. if (result) {
  263. NSLog(@"---上传成功");
  264. self.syncDate = [self fileSyncDateStr];
  265. [[NSUserDefaults standardUserDefaults] setObject:self.syncDate forKey:FileSyncDateKey];
  266. [[NSUserDefaults standardUserDefaults] synchronize];
  267. NSInteger cnt = [_filePathArray count];
  268. NSInteger index = [_filePathArray indexOfObject:_currentUploadPath];
  269. if (1 == _progressValue && index < cnt - 1) {
  270. _currentUploadPath = [_filePathArray objectAtIndex:index + 1];
  271. [self newUploatFile];
  272. } else {
  273. self.filePathArray = nil;
  274. }
  275. } else {
  276. NSLog(@"---上传失败");
  277. [self newUploadFileState:networkError.statusCode.integerValue];
  278. }
  279. }] setProgressBlock:^(int64_t bytesUploaded, int64_t totalBytesUploaded, int64_t totalBytesExpectedToUploaded) {
  280. NSInteger cnt = [_filePathArray count];
  281. NSInteger index = [_filePathArray indexOfObject:_currentUploadPath];
  282. _progressValue = totalBytesUploaded/(CGFloat)(totalBytesExpectedToUploaded);
  283. float totalProgress = (index + _progressValue)/cnt;
  284. if ([objectDelegate respondsToSelector:@selector(updateUploadProgressBar:withMessage:leftFilesString:)]) {
  285. NSString * contenxtString = nil;
  286. if (self.filePathArray.count > 1) {
  287. contenxtString = [NSString stringWithFormat:NSLocalizedString(@"%ld files left", nil),cnt - index];
  288. } else {
  289. contenxtString = [NSString stringWithFormat:NSLocalizedString(@"%ld file left", nil),cnt - index];
  290. }
  291. [objectDelegate updateUploadProgressBar:totalProgress
  292. withMessage:NSLocalizedString(@"Uploading...", nil)
  293. leftFilesString:contenxtString];
  294. }
  295. }];
  296. });
  297. }
  298. - (void)newUploadFileState:(NSInteger)code
  299. {
  300. NSLog(@"---上传失败");
  301. self.filePathArray = nil;
  302. if ([objectDelegate respondsToSelector:@selector(cancelUpLoadProgressBar)]) {
  303. [objectDelegate cancelUpLoadProgressBar];
  304. }
  305. NSAlert *alert = [[NSAlert alloc] init];
  306. [alert setAlertStyle:NSAlertStyleCritical];
  307. NSString *tStrMessage = NSLocalizedString(@"Server Error", nil);
  308. switch (code) {
  309. case 400:
  310. {
  311. NSLog(@"Bad input parameter.");
  312. tStrMessage = NSLocalizedString(@"Upload Failed!", nil);
  313. }
  314. break;
  315. case 401:
  316. NSLog(@"Bad or expired token.");
  317. tStrMessage = NSLocalizedString(@"Authentication Failed!", nil);
  318. break;
  319. case 403:
  320. NSLog(@"Bad OAuth request.");
  321. tStrMessage = NSLocalizedString(@"Authentication Failed!", nil);
  322. break;
  323. case 404:
  324. NSLog(@"The file or folder is not found at the specified path.");
  325. tStrMessage = NSLocalizedString(@"Upload Failed!", nil);
  326. break;
  327. case 405:
  328. NSLog(@"Request method not expected (generally should be GET or POST).");
  329. tStrMessage = NSLocalizedString(@"Upload Failed!", nil);
  330. break;
  331. case 409:
  332. NSLog(@"Unlike many other error codes, it doesn’t have any specific meaning in the HTTP spec.");
  333. tStrMessage = NSLocalizedString(@"Unlike many other error codes, it doesn’t have any specific meaning in the HTTP spec.", nil);
  334. break;
  335. case 503:
  336. NSLog(@"Your app is making too many requests and is being rate limited.");
  337. tStrMessage = NSLocalizedString(@"Upload Failed!", nil);
  338. break;
  339. case 507:
  340. NSLog(@"User is over Dropbox storage quota.");
  341. tStrMessage = NSLocalizedString(@"Upload Failed!", nil);
  342. break;
  343. default:
  344. tStrMessage = NSLocalizedString(@"Server Error", nil);
  345. break;
  346. }
  347. [alert setMessageText:tStrMessage];
  348. [alert runModal];
  349. }
  350. - (void)cancleUploadFile
  351. {
  352. self.filePathArray = nil;
  353. if ([self isLinked]) {
  354. [self.uploadTask cancel];
  355. }
  356. }
  357. #pragma mark -
  358. - (NSString *)fileSyncDateStr
  359. {
  360. NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init];
  361. [dateFormatter setDateStyle:(kCFDateFormatterShortStyle)];
  362. [dateFormatter setTimeStyle:(kCFDateFormatterShortStyle)];
  363. return [dateFormatter stringFromDate:[NSDate date]];
  364. }
  365. @end