CatNiP prefinal
Sähköinen nuottikirja, HY-TKTKL-OHTUPROJ KESÄ11
|
00001 00024 #import "IMSLPQueryHelper.h" 00025 00026 00027 @implementation IMSLPQueryHelper 00028 @synthesize categoryName; 00029 @synthesize composerName; 00030 @synthesize targetArray; 00031 @synthesize working; 00032 @synthesize targetMethod; 00033 @synthesize targetObject; 00034 @synthesize stopRequested; 00035 @synthesize pageTitle; 00036 @synthesize thisComposition; 00037 @synthesize queryStatus; 00038 00039 static NSMutableDictionary* imslpQueries; 00040 static NSString* imslpAPIURL; 00041 static NSString* imslpFetchURL; 00042 static NSString* imslpFileURL; 00043 00044 00050 + (void)initialize { 00051 if (self == [IMSLPQueryHelper class]) { 00052 imslpQueries = [[NSMutableDictionary alloc] init]; 00053 [imslpQueries retain]; 00054 imslpAPIURL = @"http://www.imslp.org/api.php"; 00055 imslpFetchURL = @"http://www.imslp.org/index.php"; 00056 imslpFileURL = @"http://imslp.org/index.php?title=Special:Filepath&file="; 00057 /* 00058 00059 This code tried to create a cookie to handle the imslpdisclaimeraccepted 00060 cookie thing IMSLP requires to actually SERVE the file instead of a "hey accept 00061 the disclaimer" html page. 00062 00063 It is saved here for posterity ++ avjn 00064 00065 NSHTTPCookie *imslpCookie; 00066 NSMutableDictionary *cookieHeaders = [[NSMutableDictionary alloc] init]; 00067 [cookieHeaders setObject:@"yes" forKey:NSHTTPCookieValue]; 00068 [cookieHeaders setObject:@"imslpdisclaimeraccepted" forKey:NSHTTPCookieName]; 00069 [cookieHeaders setObject:@"imslp.org" forKey:NSHTTPCookieDomain]; 00070 imslpCookie = [NSHTTPCookie cookieWithProperties: cookieHeaders]; 00071 [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:imslpCookie]; 00072 */ 00073 } 00074 00075 } 00076 00077 #pragma mark - Static variable accessor methods 00078 00083 +(NSString *)imslpAPIURL { 00084 return imslpAPIURL; 00085 } 00093 +(void)setImslpAPIURL:(NSString *)newUrl { 00094 imslpAPIURL = [NSString stringWithString:newUrl]; 00095 } 00096 00101 +(NSString *)imslpFetchURL { 00102 return imslpFetchURL; 00103 } 00104 00112 +(void)setImslpFetchURL:(NSString *)newUrl { 00113 imslpFetchURL = [NSString stringWithString:newUrl]; 00114 } 00115 00120 +(NSString *)imslpFileURL { 00121 return imslpFileURL; 00122 } 00123 00133 +(void)setImslpFileURL:(NSString *)newUrl { 00134 imslpFileURL = [NSString stringWithString:newUrl]; 00135 } 00136 00137 #pragma mark - IMSLP Read Operation Request Methods 00138 00156 +(BOOL)readIMSLPCategory:(NSString *)categoryName reportTo:(id)targetObj withMethod:(SEL)targetMethod { 00157 //FIXME: This is copypastecoding, ugh 00158 if(!imslpQueries) { 00159 imslpQueries = [[NSMutableDictionary alloc] init]; 00160 //[imslpQueries retain]; 00161 } 00162 if([imslpQueries objectForKey:categoryName]) { 00163 IMSLPQueryHelper* workerObj = (IMSLPQueryHelper*)[imslpQueries objectForKey:categoryName]; 00164 if(workerObj.working && !workerObj.stopRequested) { 00165 return NO; 00166 } 00167 else { 00168 [imslpQueries removeObjectForKey:categoryName]; 00169 } 00170 } 00171 NSMutableArray* mutableArray = [[NSMutableArray alloc] init]; 00172 //[mutableArray retain]; 00173 IMSLPQueryHelper* workerObj = [[[IMSLPQueryHelper alloc] initWithCategory:categoryName intoArray:mutableArray] autorelease]; 00174 //[workerObj retain]; 00175 [imslpQueries setObject:workerObj forKey:categoryName]; 00176 workerObj.targetMethod = targetMethod; 00177 workerObj.targetObject = targetObj; 00178 workerObj.queryStatus = MWQueryStarting; 00179 [workerObj startCategoryFetch]; 00180 00181 return YES; 00182 00183 00184 } 00185 00203 +(BOOL)readIMSLPPage:(NSString *)pageName composerName:(NSString*)cName reportTo:(id)targetObj withMethod:(SEL)targetMethod { 00204 //FIXME: This is copypastecoding, ugh 00205 if(!imslpQueries) { 00206 imslpQueries = [[NSMutableDictionary alloc] init]; 00207 //[imslpQueries retain]; 00208 } 00209 if([imslpQueries objectForKey:pageName]) { 00210 IMSLPQueryHelper* workerObj = (IMSLPQueryHelper*)[imslpQueries objectForKey:pageName]; 00211 if(workerObj.working && !workerObj.stopRequested) { 00212 return NO; 00213 } 00214 else { 00215 [imslpQueries removeObjectForKey:pageName]; 00216 } 00217 } 00218 IMSLPQueryHelper* workerObj = [[[IMSLPQueryHelper alloc] initWithTitle:pageName] autorelease]; 00219 // [workerObj retain]; 00220 [imslpQueries setObject:workerObj forKey:pageName]; 00221 workerObj.composerName = cName; 00222 workerObj.targetMethod = targetMethod; 00223 workerObj.targetObject = targetObj; 00224 workerObj.queryStatus = MWQueryStarting; 00225 [workerObj startPageFetch]; 00226 00227 return YES; 00228 00229 00230 } 00249 +(BOOL)readIMSLPFile:(NSString *)fileName ofComposition:(CompositionData*)theCompo reportTo:(id)targetObj withMethod:(SEL)targetMethod { 00250 //FIXME: This is copypastecoding, ugh 00251 if(!imslpQueries) { 00252 imslpQueries = [[NSMutableDictionary alloc] init]; 00253 //[imslpQueries retain]; 00254 } 00255 if(!fileName || [fileName length] < 1) { 00256 return NO; 00257 } 00258 if([imslpQueries objectForKey:fileName]) { 00259 IMSLPQueryHelper* workerObj = (IMSLPQueryHelper*)[imslpQueries objectForKey:fileName]; 00260 if(workerObj.working && !workerObj.stopRequested) { 00261 return NO; 00262 } 00263 else { 00264 [imslpQueries removeObjectForKey:fileName]; 00265 } 00266 } 00267 IMSLPQueryHelper* workerObj = [[[IMSLPQueryHelper alloc] initWithTitle:fileName] autorelease]; 00268 //[workerObj retain]; 00269 [imslpQueries setObject:workerObj forKey:fileName]; 00270 workerObj.thisComposition = theCompo; 00271 workerObj.targetMethod = targetMethod; 00272 workerObj.targetObject = targetObj; 00273 workerObj.queryStatus = MWQueryStarting; 00274 [workerObj startDownload]; 00275 00276 return YES; 00277 } 00278 00279 #pragma mark - Read operation progress report methods 00280 00287 +(BOOL)readInProgressFor:(NSString*)destination { 00288 if(!imslpQueries) { 00289 return NO; 00290 } 00291 if([imslpQueries objectForKey:destination]) { 00292 IMSLPQueryHelper* workerObj = (IMSLPQueryHelper*)[imslpQueries objectForKey:destination]; 00293 if(workerObj.working && !workerObj.stopRequested) { 00294 return YES; 00295 } 00296 } 00297 return NO; 00298 00299 } 00308 +(int)queryStatusFor:(NSString *)destination { 00309 if(!imslpQueries) { 00310 return MWQueryNoStatus; 00311 } 00312 if([imslpQueries objectForKey:destination]) { 00313 IMSLPQueryHelper* workerObj = (IMSLPQueryHelper*)[imslpQueries objectForKey:destination]; 00314 return workerObj.queryStatus; 00315 } 00316 return MWQueryNoStatus; 00317 } 00318 00329 +(float)downloadProgressFor:(NSString *)fileName { 00330 if(!imslpQueries) { 00331 return -1.0; 00332 } 00333 if([imslpQueries objectForKey:fileName]) { 00334 IMSLPQueryHelper* workerObj = (IMSLPQueryHelper*)[imslpQueries objectForKey:fileName]; 00335 return [workerObj getDownloadProgress]; 00336 } 00337 return MWQueryNoStatus; 00338 00339 } 00340 00341 #pragma mark - Read operation cancellation methods 00342 00346 +(BOOL)abortRead:(NSString *)destination { 00347 if(!imslpQueries) { 00348 return NO; 00349 } 00350 if([imslpQueries objectForKey:destination]) { 00351 IMSLPQueryHelper* workerObj = (IMSLPQueryHelper*)[imslpQueries objectForKey:destination]; 00352 workerObj.stopRequested = YES; 00353 workerObj.queryStatus = MWQueryCancelled; 00354 return YES; 00355 } 00356 return NO; 00357 00358 } 00359 00365 +(BOOL)abortAllReads { 00366 id key; 00367 NSEnumerator* enumer = [imslpQueries keyEnumerator]; 00368 while((key = [enumer nextObject])) { 00369 IMSLPQueryHelper *workerObj = [imslpQueries objectForKey:key]; 00370 workerObj.stopRequested = YES; 00371 workerObj.queryStatus = MWQueryCancelled; 00372 } 00373 return YES; 00374 } 00375 00376 #pragma mark - IMSLPQueryHelper worker object initialization methods 00377 00387 -initWithCategory:(NSString*)category intoArray:(NSMutableArray *)mutableArray { 00388 if(!category || !mutableArray) { 00389 return nil; 00390 } 00391 if((self = [super init])) { 00392 // whee we're an object now 00393 self.categoryName = category; 00394 self.targetArray = mutableArray; 00395 00396 self.stopRequested = NO; 00397 self.working = NO; 00398 self.queryStatus = MWQueryNoStatus; 00399 00400 return self; 00401 } 00402 return nil; 00403 00404 } 00405 00414 -(id)initWithTitle:(NSString *)pTitle { 00415 if(!pTitle) { 00416 return nil; 00417 } 00418 if((self = [super init])) { 00419 // whee we're an object now 00420 self.pageTitle = pTitle; 00421 self.stopRequested = NO; 00422 self.working = NO; 00423 self.queryStatus = MWQueryNoStatus; 00424 00425 return self; 00426 } 00427 return nil; 00428 } 00429 00430 #pragma mark - Read operation starter methods 00431 00436 -(void)startCategoryFetch { 00437 if(!myCategoryQuery) { 00438 myCategoryQuery = [MediaWikiCategoryQuery newCategoryQuery:[IMSLPQueryHelper imslpAPIURL] delegate:self]; 00439 } 00440 myCategoryQuery.categoryName = self.categoryName; 00441 myCategoryQuery.chunkSize = @"500"; 00442 [myCategoryQuery addProgressListener:self]; 00443 self.working = YES; 00444 self.queryStatus = MWQueryInProgress; 00445 [myCategoryQuery startQuery]; 00446 00447 00448 } 00449 00454 -(void)startPageFetch { 00455 if(!myPageQuery) { 00456 myPageQuery = [MediaWikiPageQuery newPageQuery:[IMSLPQueryHelper imslpFetchURL] delegate:self]; 00457 } 00458 myPageQuery.wikiTitle = self.pageTitle; 00459 myPageQuery.wikiAction = @"raw"; 00460 myPageQuery.composerName = self.composerName; 00461 [myPageQuery addProgressListener:self]; 00462 self.working = YES; 00463 self.queryStatus = MWQueryInProgress; 00464 [myPageQuery startQuery]; 00465 00466 } 00467 00471 -(void)startDownload { 00472 00473 myDownload = [[MediaWikiDownload alloc] initWithDelegate:self mediaWikiURL:imslpFileURL]; 00474 myDownload.mediaWikiFilename = self.pageTitle; 00475 [myDownload addProgressListener:self]; 00476 self.working = YES; 00477 self.queryStatus = MWQueryInProgress; 00478 [myDownload startQuery]; 00479 00480 } 00481 00482 #pragma mark - MediaWiki... delegate method implementations 00483 00495 -(void)didReceiveCategoryArray:(NSArray *)categoryArray { 00496 //NSLog(@"got %d data and cmcontinue was %@",[categoryArray count],myCategoryQuery.continueFrom); 00497 if(self.stopRequested) { 00498 [myCategoryQuery release]; 00499 self.working = NO; 00500 self.stopRequested = NO; 00501 self.queryStatus = MWQueryCancelled; 00502 return; 00503 } 00504 NSEnumerator *e = [categoryArray objectEnumerator]; 00505 NSString* catname; 00506 while((catname = (NSString*)[e nextObject])) { 00507 catname = [catname stringByReplacingOccurrencesOfString:@"Category:" withString:@""]; 00508 [self.targetArray addObject:catname]; 00509 00510 } 00511 //[self.targetArray addObjectsFromArray:categoryArray]; 00512 if(myCategoryQuery.continueFrom) { 00513 [self.targetObject performSelector:self.targetMethod withObject:nil]; 00514 [myCategoryQuery startQuery]; 00515 } 00516 else { 00517 self.working = NO; 00518 self.queryStatus = MWQueryCompleted; 00519 if(targetObject) { 00520 [self.targetObject performSelector:self.targetMethod withObject:[NSArray arrayWithArray:self.targetArray]]; 00521 } 00522 00523 } 00524 } 00531 -(void)categoryParseFailed:(NSError *)error { 00532 //FIXME: This should probably do something! 00533 self.working = NO; 00534 self.queryStatus = MWQueryFailed; 00535 [[CatNiPErrorManager sharedManager] reportError:error]; 00536 //NSLog(@"IMSLPQueryHelper received XML parse/validate error: %@",error); 00537 } 00538 00549 -(void)didReceiveCompositionData:(id)compData { 00550 self.working = NO; 00551 self.queryStatus = MWQueryCompleted; 00552 if(targetObject) { 00553 [self.targetObject performSelector:self.targetMethod withObject:compData]; 00554 } 00555 } 00565 -(void)didFinishDownload:(NSString *)loadedFilePath { 00566 self.working = NO; 00567 if(loadedFilePath) { 00568 self.queryStatus = MWQueryCompleted; 00569 } 00570 else { 00571 self.queryStatus = MWQueryFailed; 00572 } 00573 NSArray* fileNameParams = [NSArray arrayWithObjects:self.pageTitle, loadedFilePath, nil]; 00574 if(targetObject) { 00575 [self.targetObject performSelector:self.targetMethod withObject:fileNameParams withObject:self.thisComposition]; 00576 } 00577 00578 } 00579 00586 -(void)progressUpdate:(id)from { 00587 // id is either a MediaWikiDownload or MediaWikiQuery 00588 00589 if(self.stopRequested) { 00590 if([from isKindOfClass:[MediaWikiDownload class]]) { 00591 self.working = NO; 00592 self.queryStatus = MWQueryCancelled; 00593 self.stopRequested = NO; 00594 MediaWikiDownload* dl = from; 00595 [dl abortRead]; 00596 [dl removeProgressListener:self]; 00597 } 00598 } 00599 if(self.queryStatus != MWQueryCancelled) { 00600 // NSInteger current = [from currentBytes]; 00601 // NSInteger expected = [from expectedSize]; 00602 // NSString* title = (pageTitle ? pageTitle : categoryName); 00603 // float status = [IMSLPQueryHelper downloadProgressFor:title]; 00604 //NSLog(@"Read progress for %@ (%f): %d bytes out of %d.",title,status,current,expected); 00605 } 00606 } 00607 00618 -(float)getDownloadProgress { 00619 if(myDownload) { 00620 float expected = (float)[myDownload expectedSize]; 00621 float received = (float)[myDownload currentBytes]; 00622 float ratio = received / expected; 00623 return ratio; 00624 00625 } 00626 return -1.0; 00627 } 00628 00629 #pragma mark - IMSLPQueryHelper worker object dealloc method 00630 00631 -(void)dealloc { 00632 if(targetObject) { 00633 [targetArray release]; 00634 } 00635 [myDownload release]; 00636 [myCategoryQuery release]; 00637 [myPageQuery release]; 00638 [super dealloc]; 00639 } 00640 @end