forked from PoomSmart/Return-YouTube-Dislikes
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Vote.x
110 lines (105 loc) · 4.38 KB
/
Vote.x
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#import "unicode/unum.h"
#import "Vote.h"
#import "API.h"
#import "TweakSettings.h"
#import "../Return-YouTube-Dislikes/API.h"
NSString *formattedLongNumber(NSNumber *number, NSString *error) {
return error ?: [NSNumberFormatter localizedStringFromNumber:number numberStyle:NSNumberFormatterDecimalStyle];
}
static NSString *getXPointYFormat(NSString *count, char c) {
char firstInt = [count characterAtIndex:0];
char secondInt = [count characterAtIndex:1];
if (secondInt == '0')
return [NSString stringWithFormat:@"%c%c", firstInt, c];
return [NSString stringWithFormat:@"%c.%c%c", firstInt, secondInt, c];
}
// https://gist.github.com/danpashin/5951706a6aa25748a7faa1acd5c1db8b
API_AVAILABLE(ios(13))
static NSString *formattedShortNumber(int64_t number) {
UErrorCode status;
status = U_ZERO_ERROR;
NSString *currentLocale = [[[NSLocale preferredLanguages] firstObject] stringByReplacingOccurrencesOfString:@"-" withString:@"_"];
UNumberFormat *formatter = unum_open(UNUM_DECIMAL_COMPACT_SHORT, NULL, 0, [currentLocale UTF8String], NULL, &status);
assert(!U_FAILURE(status));
status = U_ZERO_ERROR;
int32_t used = unum_formatInt64(formatter, number, NULL, 0, NULL, &status);
NSString *resultString = nil;
if (status == U_BUFFER_OVERFLOW_ERROR) {
NSUInteger length = sizeof(UChar) * (NSUInteger)used;
UChar *ustr = (UChar *)CFAllocatorAllocate(kCFAllocatorSystemDefault, (CFIndex)length + 1, 0);
status = U_ZERO_ERROR;
unum_formatInt64(formatter, number, ustr, used, NULL, &status);
resultString = [[NSString alloc] initWithBytesNoCopy:ustr length:length encoding:NSUTF16LittleEndianStringEncoding freeWhenDone:YES];
}
unum_close(formatter);
formatter = NULL;
return resultString;
}
NSString *getNormalizedDislikes(NSNumber *dislikeNumber, NSString *error) {
if (!dislikeNumber) return FAILED;
if (error) return error;
if (ExactDislikeNumber())
return formattedLongNumber(dislikeNumber, nil);
NSString *dislikeCount = [dislikeNumber stringValue];
NSUInteger digits = dislikeCount.length;
if (digits <= 3) // 0 - 999
return dislikeCount;
if (@available(iOS 13.0, *))
return formattedShortNumber([dislikeNumber unsignedIntegerValue]);
if (digits == 4) // 1000 - 9999
return getXPointYFormat(dislikeCount, 'K');
if (digits <= 6) // 10_000 - 999_999
return [NSString stringWithFormat:@"%@K", [dislikeCount substringToIndex:digits - 3]];
if (digits <= 9) // 1_000_000 - 999_999_999
return [NSString stringWithFormat:@"%@M", [dislikeCount substringToIndex:digits - 6]];
return [NSString stringWithFormat:@"%@B", [dislikeCount substringToIndex:digits - 9]]; // 1_000_000_000+
}
void getVoteFromVideoWithHandler(NSCache <NSString *, NSDictionary *> *cache, NSString *videoId, int retryCount, void (^handler)(NSDictionary *d, NSString *error)) {
if (retryCount <= 0) return;
NSDictionary *data = [cache objectForKey:videoId];
if (data) {
handler(data, nil);
return;
}
fetch(
[NSString stringWithFormat:@"/votes?videoId=%@", videoId],
@"GET",
nil,
^(NSDictionary *data) {
[cache setObject:data forKey:videoId];
handler(data, nil);
},
^BOOL(NSUInteger responseCode) {
if (responseCode == 502 || responseCode == 503) {
handler(nil, @"CON"); // connection error
return NO;
}
if (responseCode == 401 || responseCode == 403 || responseCode == 407) {
handler(nil, @"AUTH"); // unauthorized
return NO;
}
if (responseCode == 429) {
handler(nil, @"RL"); // rate limit
return NO;
}
if (responseCode == 404) {
handler(nil, @"NULL"); // non-existing video
return NO;
}
if (responseCode == 400) {
handler(nil, @"INV"); // malformed video
return NO;
}
return YES;
},
^() {
handler(nil, FAILED);
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
getVoteFromVideoWithHandler(cache, videoId, retryCount - 1, handler);
});
},
^() {
handler(nil, FAILED);
}
);
}