You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

190 lines
7.0KB

  1. #include "TFDTSRootListController.h"
  2. @implementation TFDTSRootListController
  3. - (instancetype)init {
  4. self = [super init];
  5. if (self) {
  6. }
  7. return self;
  8. }
  9. - (NSArray *)specifiers {
  10. if (!_specifiers) {
  11. _specifiers = [self loadSpecifiersFromPlistName:@"Root" target:self];
  12. }
  13. return _specifiers;
  14. }
  15. - (id)readPreferenceValue:(PSSpecifier*)specifier {
  16. NSString *path = [NSString stringWithFormat:@"/User/Library/Preferences/%@.plist", specifier.properties[@"defaults"]];
  17. NSMutableDictionary *settings = [NSMutableDictionary dictionary];
  18. [settings addEntriesFromDictionary:[NSDictionary dictionaryWithContentsOfFile:path]];
  19. return (settings[specifier.properties[@"key"]]) ?: specifier.properties[@"default"];
  20. }
  21. - (void)setPreferenceValue:(id)value specifier:(PSSpecifier*)specifier {
  22. NSString *path = [NSString stringWithFormat:@"/User/Library/Preferences/%@.plist", specifier.properties[@"defaults"]];
  23. NSMutableDictionary *settings = [NSMutableDictionary dictionary];
  24. [settings addEntriesFromDictionary:[NSDictionary dictionaryWithContentsOfFile:path]];
  25. [settings setObject:value forKey:specifier.properties[@"key"]];
  26. [settings writeToFile:path atomically:YES];
  27. CFStringRef notificationName = (__bridge CFStringRef)specifier.properties[@"PostNotification"];
  28. if (notificationName) {
  29. CFNotificationCenterPostNotification(CFNotificationCenterGetDarwinNotifyCenter(), notificationName, NULL, NULL, YES);
  30. }
  31. }
  32. - (void)checkLatest:(PSSpecifier *)arg1 {
  33. NSIndexPath *indexPath = [self indexPathForSpecifier:arg1];
  34. UITableViewCell *cell = [self.table cellForRowAtIndexPath:indexPath];
  35. cell.userInteractionEnabled = NO;
  36. NSInteger activityIndicatorStyle = SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"13.0") ? UIActivityIndicatorViewStyleMedium : 2; // UIActivityIndicatorViewStyleGray == 2
  37. UIActivityIndicatorView *activityView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:activityIndicatorStyle];
  38. [cell setAccessoryView:activityView];
  39. [activityView startAnimating];
  40. // removes latest time rows if they already exist
  41. if (_latestPostSpecifier) {
  42. [self removeSpecifier:_latestPostSpecifier animated:YES];
  43. _latestPostSpecifier = nil;
  44. }
  45. if (_latestCommentSpecifier) {
  46. [self removeSpecifier:_latestCommentSpecifier animated:YES];
  47. _latestCommentSpecifier = nil;
  48. }
  49. // performs the requests for the most recent comment and post
  50. [self performPushshiftRequest:YES insertAfterSpecifier:arg1];
  51. [self performPushshiftRequest:NO insertAfterSpecifier:arg1];
  52. }
  53. - (void)performPushshiftRequest:(BOOL)isComment insertAfterSpecifier:(PSSpecifier *)arg2 {
  54. NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
  55. //NSOperationQueue *queue = [[NSOperationQueue alloc] init];
  56. if (isComment){
  57. [request setURL:[NSURL URLWithString:@"https://api.pushshift.io/reddit/search/comment/?fields=created_utc&size=1"]];
  58. } else {
  59. [request setURL:[NSURL URLWithString:@"https://api.pushshift.io/reddit/search/submission/?fields=created_utc&size=1"]];
  60. }
  61. NSMutableDictionary *prefs = [NSMutableDictionary dictionary];
  62. [prefs addEntriesFromDictionary:[NSDictionary dictionaryWithContentsOfFile:@"/User/Library/Preferences/com.lint.undelete.prefs.plist"]];
  63. NSInteger timeout = [prefs objectForKey:@"requestTimeoutValue"] ? [[prefs objectForKey:@"requestTimeoutValue"] doubleValue] : 10;
  64. [request setHTTPMethod:@"GET"];
  65. [request setTimeoutInterval:timeout];
  66. NSURLSessionDataTask *dataTask = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
  67. //[NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
  68. NSString *resultText;
  69. if (data) {
  70. id jsonData = [[NSJSONSerialization JSONObjectWithData:data options:0 error:&error] objectForKey:@"data"];
  71. if (jsonData && [jsonData count] != 0) {
  72. NSString *epochStr = jsonData[0][@"created_utc"];
  73. NSDate *creationDate = [NSDate dateWithTimeIntervalSince1970:[epochStr intValue]];
  74. // months and years? not really needed
  75. unsigned int unitFlags = NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;
  76. NSDateComponents *components = [[NSCalendar currentCalendar] components:unitFlags fromDate:creationDate toDate:[NSDate date] options:0];
  77. NSInteger days = [components day];
  78. NSInteger hours = [components hour];
  79. NSInteger minutes = [components minute];
  80. NSInteger seconds = [components second];
  81. NSMutableString *timeSinceString = [NSMutableString string];
  82. BOOL prevComponentUsed = NO;
  83. if (days > 0) {
  84. [timeSinceString appendFormat:@"%lid, ", (long)days];
  85. prevComponentUsed = YES;
  86. }
  87. if (hours > 0 || prevComponentUsed) {
  88. [timeSinceString appendFormat:@"%lih, ", (long)hours];
  89. prevComponentUsed = YES;
  90. }
  91. if (minutes > 0 || prevComponentUsed) {
  92. [timeSinceString appendFormat:@"%lim, ", (long)minutes];
  93. prevComponentUsed = YES;
  94. }
  95. if (seconds > 0 || prevComponentUsed) {
  96. [timeSinceString appendFormat:@"%lis ", (long)seconds];
  97. }
  98. [timeSinceString appendString:@"ago"];
  99. resultText = timeSinceString;
  100. } else {
  101. resultText = @"no data returned";
  102. }
  103. }
  104. if (error) {
  105. resultText = [NSString stringWithFormat:@"HTTP Status: %li, Error: %@",
  106. (long)((NSHTTPURLResponse *)response).statusCode, [error localizedDescription]];
  107. }
  108. NSString *labelText = [NSString stringWithFormat:@"Last %@: %@", isComment ? @"Comment" : @"Post", resultText];
  109. // specifier to create new table row
  110. PSSpecifier *customSpecifier = [PSSpecifier preferenceSpecifierNamed:labelText target:self set:NULL get:NULL detail:Nil cell:PSStaticTextCell edit:Nil];
  111. [customSpecifier setProperty:labelText forKey:@"label"];
  112. [customSpecifier setProperty: @"PSStaticTextCell" forKey:@"cell"];
  113. if (isComment) {
  114. _latestCommentSpecifier = customSpecifier;
  115. } else {
  116. _latestPostSpecifier = customSpecifier;
  117. }
  118. NSDictionary *dataDict = @{@"custom_specifier" : customSpecifier, @"after_specifier" : arg2};
  119. [self performSelectorOnMainThread:@selector(insertLatestTimeCell:) withObject:dataDict waitUntilDone:NO];
  120. [self performSelectorOnMainThread:@selector(possiblyBothChecksComplete:) withObject:arg2 waitUntilDone:NO];
  121. }];
  122. [dataTask resume];
  123. }
  124. - (void)insertLatestTimeCell:(NSDictionary *)data {
  125. if (data[@"custom_specifier"] && data[@"after_specifier"]) {
  126. [self insertSpecifier:data[@"custom_specifier"] afterSpecifier:data[@"after_specifier"] animated:YES];
  127. }
  128. }
  129. - (void)possiblyBothChecksComplete:(PSSpecifier *)arg1 {
  130. // only when both the comment and the post request have finished
  131. if (_latestPostSpecifier && _latestCommentSpecifier) {
  132. NSIndexPath *indexPath = [self indexPathForSpecifier:arg1];
  133. UITableViewCell *cell = [self.table cellForRowAtIndexPath:indexPath];
  134. if (cell) {
  135. UIActivityIndicatorView *activityView = (UIActivityIndicatorView *)[cell accessoryView];
  136. [activityView stopAnimating];
  137. [cell setAccessoryView:nil];
  138. cell.userInteractionEnabled = YES;
  139. }
  140. }
  141. }
  142. @end