Develop and Download Open Source Software

Browse Subversion Repository

Contents of /bathyscaphe/trunk/application/subproj/reply/error/SG2chErrorHandler.m

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1815 - (show annotations) (download)
Mon Mar 23 06:54:25 2015 UTC (9 years ago) by tsawada2
File size: 10899 byte(s)
Omake-commit: fix reply error parsing.
1 //
2 // SG2chErrorHandler.m
3 // BathyScaphe
4 //
5 // Updated by Tsutomu Sawada on 07/10/15.
6 // Copyright 2005-2015 BathyScaphe Project. All rights reserved.
7 // encoding="UTF-8"
8 //
9
10 #import "SG2chErrorHandler.h"
11 #import "SG2chConnector.h"
12 #import "URLConnector_Prefix.h"
13
14 #define k2ch_XCommentTypeFile @"ReplyErrorCode.plist"
15 #define IS_HTML(s) ((s) && [(s) rangeOfString:@"<html" options:NSCaseInsensitiveSearch].length != 0)
16
17
18 // Error Code Dictionary
19 enum {
20 ReplyErrorCodeTitleOr2ch_XDict = 1,
21 ReplyErrorCodeMessageBodyDict = 2,
22 };
23 typedef NSUInteger ReplyErrorCodeDictionaryType;
24 static NSDictionary *replyErrorCodeDictionary(ReplyErrorCodeDictionaryType type);
25
26 // 2ch_X comment
27 static NSString *scan2ch_XCommentStringWithHTML(NSString *contents);
28
29 // Constants
30 static NSString *const kHTMLBreakLine = @"<br>";
31 static NSString *const kHTMLHorizotalLine = @"<br>----------------<br>";
32
33 @implementation SG2chErrorHandler
34 + (id)handlerWithURL:(NSURL *)anURL
35 {
36 return [[[self alloc] initWithURL:anURL] autorelease];
37 }
38
39 - (id)initWithURL:(NSURL *)anURL
40 {
41 if (![[self class] canInitWithURL:anURL]) {
42 [self release];
43 return nil;
44 }
45 if (self = [super init]) {
46 [self setRequestURL:anURL];
47 [self setAdditionalFormsData:nil];
48 }
49 return self;
50 }
51
52 - (void)dealloc
53 {
54 [m_requestURL release];
55 [m_recentError release];
56 [m_additionalFormsData release];
57 [super dealloc];
58 }
59
60 + (BOOL)canInitWithURL:(NSURL *)anURL
61 {
62 const char *host_;
63 NSString *cgiName_;
64
65 host_ = [[anURL host] UTF8String];
66 cgiName_ = [[anURL absoluteString] lastPathComponent];
67 if (NULL == host_) return NO;
68
69 if (is_2channel(host_)) {
70 return [cgiName_ isEqualToString:@"bbs.cgi"];
71 }
72 if (is_machi(host_) || is_jbbs_livedoor(host_)) {
73 return [cgiName_ isEqualToString:@"write.cgi"];
74 }
75 return NO;
76 }
77
78 static NSString *titleForCode(NSInteger code)
79 {
80 if (code == k2chNinjaFirstAlertType) {
81 id template = SGTemplateResource(@"Reply - Ninja FirstWaitSeconds");
82 NSUInteger sec = [(NSNumber *)template unsignedIntegerValue];
83 return [NSString stringWithFormat:PluginLocalizedStringFromTable(@"k2chNinjaFirstAlertTitleFormat", nil, nil), (unsigned long)sec];
84 } else if (code == k2chBeLoginErrorType) {
85 return PluginLocalizedStringFromTable(@"k2chBeLoginErrorAlertTitle", nil, nil);
86 } else if (code == k2chSPIDCookieErrorType) {
87 return nil;
88 }
89 return @"ERROR";
90 }
91
92 - (NSError *)handleErrorWithContents:(NSString *)contents
93 {
94 NSInteger code = k2chUnknownErrorType;
95 NSString *title_ = @"";
96 NSString *message_ = @"";
97 NSMutableDictionary *userInfo = [NSMutableDictionary dictionaryWithCapacity:2];
98
99 if (IS_HTML(contents)) {
100 if ([self parseHTMLContents:contents intoTitle:&title_ intoMessage:&message_]) {
101 title_ = [title_ stringByStriped];
102 message_ = [message_ stringByStriped];
103 }
104
105 // ������������������������������������
106 code = [replyErrorCodeDictionary(ReplyErrorCodeTitleOr2ch_XDict) integerForKey:title_ defaultValue:k2chUnknownErrorType];
107
108 // ���������������������������������������������������������
109 // <!-- 2ch_X:... -->���������������
110 if (k2chUnknownErrorType == code) {
111 NSString *mark_;
112 mark_ = scan2ch_XCommentStringWithHTML(contents);
113 code = [replyErrorCodeDictionary(ReplyErrorCodeTitleOr2ch_XDict) integerForKey:mark_ defaultValue:k2chUnknownErrorType];
114 }
115
116 if (k2chAnyErrorType == code || k2chUnknownErrorType == code) {
117 // ������������������������������������������������������������������������������������be������������������������
118 NSDictionary *bodys = replyErrorCodeDictionary(ReplyErrorCodeMessageBodyDict);
119 NSArray *messages = [bodys allKeys];
120 for (NSString *foo in messages) {
121 NSRange range = [message_ rangeOfString:foo options:NSLiteralSearch range:[message_ range]];
122 if (range.location != NSNotFound) {
123 code = [bodys integerForKey:foo];
124 title_ = titleForCode(code) ?: foo;
125 break;
126 }
127 }
128 }
129
130 // hana=mogera
131 if (k2chContributionCheckErrorType == code || k2chSPIDCookieErrorType == code) {
132 NSDictionary *tmp_;
133 tmp_ = [self scanAdditionalFormsWithHTML:contents];
134 if (tmp_) {
135 [self setAdditionalFormsData:tmp_];
136 }
137 }
138 } else {
139 const char *host_ = [[[self requestURL] host] UTF8String];
140
141 if (is_jbbs_livedoor(host_) || is_machi(host_)) {
142 /*
143 2004-02-25 Takanori Ishikawa <takanori@gd5.so-net.ne.jp>
144 ----------------------------------------
145 ������������������������������������������html ������
146 */
147 /*
148 2007-08-08 tsawada2 <ben-sawa@td5.so-net.ne.jp>
149 ----------------------------------------
150 ������BBS������������������������
151 */
152 code = k2chNoneErrorType;
153 } else if (!contents || [contents isEmpty]) {
154 // Server's response contains no data.
155 code = k2chEmptyDataErrorType;
156 title_ = PluginLocalizedStringFromTable(@"k2chEmptyDataErrorType", nil, nil);
157 message_ = PluginLocalizedStringFromTable(@"k2chEmptyDataErrorType", nil, nil);
158 }
159 }
160
161 if (k2chUnknownErrorType == code) {
162 title_ = @"ERROR";
163 message_ = contents;
164 code = k2chAnyErrorType;
165 }
166
167 [userInfo setObject:title_ forKey:SG2chErrorTitleErrorKey];
168 [userInfo setObject:message_ forKey:SG2chErrorMessageErrorKey];
169
170 [self setRecentError:[NSError errorWithDomain:SG2chErrorHandlerErrorDomain code:code userInfo:userInfo]];
171 return [self recentError];
172 }
173
174 - (NSURL *)requestURL
175 {
176 return m_requestURL;
177 }
178
179 - (void)setRequestURL:(NSURL *)aRequestURL
180 {
181 [aRequestURL retain];
182 [m_requestURL release];
183 m_requestURL = aRequestURL;
184 }
185
186 - (NSError *)recentError
187 {
188 return m_recentError;
189 }
190
191 - (void)setRecentError:(NSError *)error
192 {
193 [error retain];
194 [m_recentError release];
195 m_recentError = error;
196 }
197
198 - (NSDictionary *)additionalFormsData
199 {
200 return m_additionalFormsData;
201 }
202
203 - (void)setAdditionalFormsData:(NSDictionary *)anAdditionalFormsData
204 {
205 [anAdditionalFormsData retain];
206 [m_additionalFormsData release];
207 m_additionalFormsData = anAdditionalFormsData;
208 }
209 #pragma mark HTML Utilities
210
211 #define HTML_TAG(xpp, tagName, theType) (theType == [xpp eventType] && [[xpp name] isEqualToString : tagName])
212
213 - (id<XmlPullParser>)setUpParserWithInputSource:(NSString *)htmlContents
214 {
215 if (!htmlContents) return nil;
216 id<XmlPullParser> xpp_ = [[[SGXmlPullParser alloc] initHTMLParser] autorelease];
217 // ������
218 // [xpp_ setInputSource:htmlContents];
219 NSString *fakeString = [htmlContents stringByReplaceCharacters:@"value=>" toString:@"value=\"\">"];
220 [xpp_ setInputSource:fakeString];
221 // ������������������
222 return xpp_;
223 }
224
225 - (BOOL)parseHTMLContents:(NSString *)htmlContents intoTitle:(NSString **)ptitle intoMessage:(NSString **)pbody
226 {
227 id<XmlPullParser> xpp_ = [self setUpParserWithInputSource:htmlContents];
228 if (!xpp_) return NO;
229
230 NSInteger type_;
231 NSMutableString *body_;
232 NSString *title_ = @"";
233
234 NS_DURING
235 body_ = [NSMutableString string];
236 while ((type_ = [xpp_ next]) != XMLPULL_END_DOCUMENT) {
237 if (HTML_TAG(xpp_, @"body", XMLPULL_START_TAG)) {
238 while ((type_ = [xpp_ next]) != XMLPULL_END_DOCUMENT) {
239 NSString *text_;
240
241 if (HTML_TAG(xpp_, @"body", XMLPULL_END_TAG))
242 break;
243
244 text_ = [xpp_ text];
245 if (text_) [body_ appendString:text_];
246
247 // ������
248 if (HTML_TAG(xpp_, @"br", XMLPULL_START_TAG))
249 [body_ appendString:kHTMLBreakLine];
250
251 // ������������
252 if (HTML_TAG(xpp_, @"hr", XMLPULL_START_TAG))
253 [body_ appendString:kHTMLHorizotalLine];
254 }
255 }
256
257 if (HTML_TAG(xpp_, @"head", XMLPULL_START_TAG)) {
258 while ((type_ = [xpp_ next]) != XMLPULL_END_DOCUMENT) {
259 if (HTML_TAG(xpp_, @"head", XMLPULL_END_TAG)) {
260 break;
261 } else if (HTML_TAG(xpp_, @"title", XMLPULL_START_TAG)) {
262 type_ = [xpp_ next];
263 if (XMLPULL_TEXT == type_)
264 title_ = [[[xpp_ text] copy] autorelease];
265 else
266 title_ = @"";
267 }
268 }
269 }
270 }
271 NS_HANDLER
272
273 title_ = nil;
274 body_ = nil;
275 UTILCatchException(XmlPullParserException) {
276 NSLog(@"***XMLPULL_EXCEPTION***%@", localException);
277
278 } else {
279 [localException raise];
280 }
281
282 NS_ENDHANDLER
283
284 if (!title_ && !body_)
285 return NO;
286
287 [body_ replaceCharacters:@"\n" toString:@""];
288 [body_ replaceCharacters:kHTMLBreakLine toString:@"\n"];
289
290 if (ptitle != NULL) *ptitle = title_;
291 if (pbody != NULL) *pbody = body_;
292
293 return YES;
294 }
295
296 - (NSDictionary *)scanAdditionalFormsWithHTML:(NSString *)htmlContents
297 {
298 id<XmlPullParser> xpp_ = [self setUpParserWithInputSource:htmlContents];
299
300 NSInteger type_;
301 NSMutableDictionary *additionalFormData_ = [[[NSMutableDictionary alloc] init] autorelease];
302 NSSet *defaultKeys_ = [NSSet setWithObjects:@"bbs", @"key", @"time", @"FROM", @"mail", @"MESSAGE", @"subject", nil];
303
304 NS_DURING
305 while ((type_ = [xpp_ next]) != XMLPULL_END_DOCUMENT) {
306 if (HTML_TAG(xpp_, @"form", XMLPULL_START_TAG)) {
307 while ((type_ = [xpp_ next]) != XMLPULL_END_DOCUMENT) {
308 if (HTML_TAG(xpp_, @"form", XMLPULL_END_TAG))
309 break;
310
311 if (HTML_TAG(xpp_, @"input", XMLPULL_START_TAG)) {
312
313 if ([[xpp_ attributeForName:@"type"] isEqualToString:@"hidden"]) {
314 NSString *value_ = [xpp_ attributeForName:@"name"];
315 if (value_ == NULL) break;
316
317 if (![defaultKeys_ containsObject:value_]) {
318 NSString *value2_ = [xpp_ attributeForName:@"value"];
319 if (value2_ == NULL) break;
320 [additionalFormData_ setObject:value2_ forKey:value_];
321 }
322 }
323 }
324 }
325 }
326 }
327 NS_HANDLER
328
329 UTILCatchException(XmlPullParserException) {
330 NSLog(@"***XMLPULL_EXCEPTION***%@", localException);
331 } else {
332 [localException raise];
333 }
334
335 NS_ENDHANDLER
336 if ([additionalFormData_ count] == 0) return nil;
337 return additionalFormData_;
338 }
339 @end
340
341 #pragma mark -
342 static NSDictionary *replyErrorCodeDictionary(ReplyErrorCodeDictionaryType type)
343 {
344 static NSDictionary *typeTbl;
345
346 if (!typeTbl) {
347 NSString *filepath_;
348
349 filepath_ = [PLUGIN_BUNDLE pathForResourceWithName:k2ch_XCommentTypeFile];
350 UTILCAssertNotNil(filepath_);
351 typeTbl = [[NSDictionary alloc] initWithContentsOfFile:filepath_];
352 UTILCAssertNotNil(typeTbl);
353 }
354
355 if (type == ReplyErrorCodeTitleOr2ch_XDict) {
356 return [typeTbl objectForKey:@"TitleOr2ch_X"];
357 } else if (type == ReplyErrorCodeMessageBodyDict) {
358 return [typeTbl objectForKey:@"MessageBody"];
359 }
360 return nil;
361 }
362
363 static NSString *scan2ch_XCommentStringWithHTML(NSString *contents)
364 {
365 NSScanner *scanner_;
366 NSString *mark_;
367
368 if (!contents) return nil;
369 scanner_ = [NSScanner scannerWithString:contents];
370 if (!scanner_) return nil;
371
372 [scanner_ scanUpToString:@"<!--" intoString:NULL];
373 [scanner_ scanString:@"<!--" intoString:NULL];
374 [scanner_ scanString:@"2ch_X" intoString:NULL];
375 [scanner_ scanString:@":" intoString:NULL];
376
377 if (![scanner_ scanCharactersFromSet:[NSCharacterSet alphanumericCharacterSet] intoString:&mark_]) {
378 return nil;
379 }
380 return mark_;
381 }

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26