/
WikiTextSectionUploader.m
228 lines (185 loc) · 9.41 KB
/
WikiTextSectionUploader.m
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
#import "WikiTextSectionUploader.h"
@import WMF;
@implementation WikiTextSectionUploader
- (void)addSectionWithSummary:(NSString *)summary
text:(NSString *)text
forArticleURL:(NSURL *)articleURL
completion:(void (^)(NSDictionary * _Nullable result, NSError * _Nullable error))completion {
NSString *title = articleURL.wmf_title;
if (!title) {
completion(nil, [WMFFetcher invalidParametersError]);
return;
}
NSMutableDictionary *params =
@{
@"action": @"edit",
@"text": text,
@"summary": summary,
@"section": @"new",
@"title": articleURL.wmf_title,
@"format": @"json"
}
.mutableCopy;
[self updateWithArticleURL:articleURL parameters:params captchaWord:nil completion:completion];
}
- (void)appendToSection:(NSString *)section
text:(NSString *)text
forArticleURL:(NSURL *)articleURL
completion:(void (^)(NSDictionary * _Nullable result, NSError * _Nullable error))completion {
NSString *title = articleURL.wmf_title;
if (!title) {
completion(nil, [WMFFetcher invalidParametersError]);
return;
}
NSMutableDictionary *params =
@{
@"action": @"edit",
@"appendtext": text,
@"section": section,
@"title": articleURL.wmf_title,
@"format": @"json"
}
.mutableCopy;
[self updateWithArticleURL:articleURL parameters:params captchaWord:nil completion:completion];
}
- (void)prependToSectionID:(NSString *)sectionID
text:(NSString *)text
forArticleURL:(NSURL *)articleURL
isMinorEdit:(BOOL)isMinorEdit
baseRevID:(nullable NSNumber *)baseRevID
completion:(void (^)(NSDictionary * _Nullable result, NSError * _Nullable error))completion {
NSString *title = articleURL.wmf_title;
if (!title) {
completion(nil, [WMFFetcher invalidParametersError]);
return;
}
NSMutableDictionary *params =
@{
@"action": @"edit",
@"prependtext": text,
@"section": sectionID,
@"title": articleURL.wmf_title,
@"format": @"json"
}
.mutableCopy;
if (isMinorEdit) {
params[@"minor"] = @"1";
}
if (baseRevID) {
params[@"baserevid"] = [NSString stringWithFormat:@"%@", baseRevID];
}
[self updateWithArticleURL:articleURL parameters:params captchaWord:nil completion:completion];
}
- (void)uploadWikiText:(nullable NSString *)wikiText
forArticleURL:(NSURL *)articleURL
section:(NSString *)section
summary:(nullable NSString *)summary
isMinorEdit:(BOOL)isMinorEdit
addToWatchlist:(BOOL)addToWatchlist
baseRevID:(nullable NSNumber *)baseRevID
captchaId:(nullable NSString *)captchaId
captchaWord:(nullable NSString *)captchaWord
completion:(void (^)(NSDictionary * _Nullable result, NSError * _Nullable error))completion {
wikiText = wikiText ? wikiText : @"";
section = section ? section : @"";
summary = summary ? summary : @"";
NSString *title = articleURL.wmf_title;
if (!title) {
completion(nil, [WMFFetcher invalidParametersError]);
return;
}
NSMutableDictionary *params =
@{
@"action": @"edit",
@"text": wikiText,
@"summary": summary,
@"section": section,
@"title": articleURL.wmf_title,
@"format": @"json",
}
.mutableCopy;
if (isMinorEdit) {
params[@"minor"] = @"1";
}
if (addToWatchlist) {
params[@"watchlist"] = @"watch";
}
if (baseRevID) {
params[@"baserevid"] = [NSString stringWithFormat:@"%@", baseRevID];
}
if (captchaWord && captchaId) {
params[@"captchaid"] = captchaId;
params[@"captchaword"] = captchaWord;
}
[self updateWithArticleURL:articleURL parameters:params captchaWord:captchaWord completion:completion];
}
- (void)updateWithArticleURL: (NSURL *)articleURL parameters: (NSDictionary<NSString *, NSString *> *)parameters captchaWord: (nullable NSString *)captchaWord completion:(void (^)(NSDictionary * _Nullable result, NSError * _Nullable error))completion {
[self performMediaWikiAPIPOSTWithCSRFTokenForURL:articleURL withBodyParameters:parameters completionHandler:^(NSDictionary<NSString *,id> * _Nullable responseObject, NSHTTPURLResponse * _Nullable response, NSError * _Nullable networkError) {
if (networkError) {
completion(nil, networkError);
return;
}
//NSLog(@"JSON: %@", responseObject);
// Fake out an error if non-dictionary response received.
if (![responseObject isKindOfClass:[NSDictionary class]]) {
responseObject = @{ @"error": @{@"info": @"WikiText upload data not found."} };
}
//NSLog(@"ACCT CREATION DATA RETRIEVED = %@", responseObject);
// Handle case where response is received, but API reports error.
NSError *error = nil;
if (responseObject[@"error"]) {
NSMutableDictionary *errorDict = [responseObject[@"error"] mutableCopy];
errorDict[NSLocalizedDescriptionKey] = errorDict[@"info"];
error = [NSError errorWithDomain:@"WikiText Uploader"
code:WikiTextSectionUploaderErrorTypeServer
userInfo:errorDict];
}
NSDictionary *resultDict = responseObject[@"edit"];
NSString *result = resultDict[@"result"];
if (!error && !result) {
NSMutableDictionary *errorDict = [@{} mutableCopy];
errorDict[NSLocalizedDescriptionKey] = WMFLocalizedStringWithDefaultValue(@"wikitext-upload-result-unknown", nil, nil, @"Unable to determine wikitext upload result.", @"Alert text shown when the result of saving section wikitext changes is unknown");
// Set error condition so dependent ops don't even start and so the errorBlock below will fire.
error = [NSError errorWithDomain:@"Upload Wikitext Op" code:WikiTextSectionUploaderErrorTypeUnknown userInfo:errorDict];
}
if (!error && result && [result isEqualToString:@"Failure"]) {
if (responseObject[@"edit"][@"captcha"]) {
NSMutableDictionary *errorDict = [@{} mutableCopy];
errorDict[NSLocalizedDescriptionKey] = (captchaWord && (captchaWord.length > 0)) ? WMFLocalizedStringWithDefaultValue(@"wikitext-upload-captcha-error", nil, nil, @"CAPTCHA verification error.", @"Alert text shown when section wikitext upload captcha fails")
: WMFLocalizedStringWithDefaultValue(@"wikitext-upload-captcha-needed", nil, nil, @"Need CAPTCHA verification.", @"Alert text shown when section wikitext upload captcha is required");
// Make the capcha id and url available from the error.
errorDict[@"captchaId"] = responseObject[@"edit"][@"captcha"][@"id"];
errorDict[@"captchaUrl"] = responseObject[@"edit"][@"captcha"][@"url"];
// Set error condition so dependent ops don't even start and so the errorBlock below will fire.
error = [NSError errorWithDomain:@"Upload Wikitext Op" code:WikiTextSectionUploaderErrorTypeNeedsCaptcha userInfo:errorDict];
} else if (responseObject[@"edit"][@"code"]) {
NSString *abuseFilterCode = responseObject[@"edit"][@"code"];
WikiTextSectionUploaderErrorType errorType = WikiTextSectionUploaderErrorTypeUnknown;
if ([abuseFilterCode hasPrefix:@"abusefilter-warning"]) {
errorType = WikiTextSectionUploaderErrorTypeAbuseFilterWarning;
} else if ([abuseFilterCode hasPrefix:@"abusefilter-disallowed"]) {
errorType = WikiTextSectionUploaderErrorTypeAbuseFilterDisallowed;
} else if ([abuseFilterCode hasPrefix:@"abusefilter"]) {
errorType = WikiTextSectionUploaderErrorTypeAbuseFilterOther;
}
switch (errorType) {
case WikiTextSectionUploaderErrorTypeAbuseFilterWarning:
case WikiTextSectionUploaderErrorTypeAbuseFilterDisallowed:
case WikiTextSectionUploaderErrorTypeAbuseFilterOther: {
NSMutableDictionary *errorDict = [@{} mutableCopy];
errorDict[NSLocalizedDescriptionKey] = responseObject[@"edit"][@"info"];
// Make the verbose warning available from the error.
errorDict[@"warning"] = responseObject[@"edit"][@"warning"];
errorDict[@"code"] = abuseFilterCode;
// Set error condition so dependent ops don't even start and so the errorBlock below will fire.
error = [NSError errorWithDomain:@"Upload Wikitext Op" code:errorType userInfo:errorDict];
} break;
default:
break;
}
}
}
completion(resultDict, error);
}];
}
@end