DropboxModel.m 15 KB

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