CatNiP prefinal
Sähköinen nuottikirja, HY-TKTKL-OHTUPROJ KESÄ11
/Users/awniemel/Notepad-SVN/svn/trunk/CatNiP/CatNiP/MediaWikiPageQuery.m
Go to the documentation of this file.
00001 
00011 #import "MediaWikiPageQuery.h"
00012 
00013 
00014 @implementation MediaWikiPageQuery
00015 @synthesize parameters;
00016 @synthesize pageDelegate;
00017 @synthesize composerName;
00018 
00019 -(void)setWikiAction:(NSString *)wikiAction {
00020     [self.parameters setValue:[NSString stringWithString:wikiAction] forKey:@"action"];
00021 }
00022 -(NSString *)wikiAction {
00023     return [self.parameters valueForKey:@"action"];
00024 }
00025 -(void)setWikiTitle:(NSString *)wikiTitle {
00026     [self.parameters setValue:[NSString stringWithString:wikiTitle] forKey:@"title"];
00027 }
00028 -(NSString *)wikiTitle {
00029     return [self.parameters valueForKey:@"title"];
00030 }
00039 + (MediaWikiPageQuery*) newPageQuery:(NSString*)URL delegate:(id <MediaWikiPageQueryDelegate>)qDelegate {
00040     
00041     if(qDelegate == nil) {
00042         return nil;
00043     }
00044     MediaWikiPageQuery* cQuery = [MediaWikiPageQuery alloc];
00045     cQuery = [cQuery initWithDelegate:cQuery mediaWikiURL:URL];
00046     cQuery.pageDelegate = qDelegate;
00047     return cQuery;
00048 }
00049 
00051 -init {
00052     if((self = [super init])) {
00053         self.parameters = [[[NSMutableDictionary alloc] init] autorelease];
00054 
00055         return self;
00056     }
00057     return nil;
00058 }
00060 - (NSString*) buildQueryURL {
00061     return [NSString stringWithFormat: @"%@?%@", self.mediaWikiURLString, [self _buildGetParams]];
00062 }
00063 
00069 -(void)didReceiveMediaWikiData:(NSData *)data {
00070     //data contains the whole raw page in wikitext format
00071     NSString* fullString = [[NSString alloc] initWithBytes:[data bytes] length:[data length] encoding:NSUTF8StringEncoding];
00072     CompositionData* comp = [[CompositionData alloc] init];
00073     /*NSLog(@"received data, size is %d and string length is %d",[data length],
00074       [fullString length]); */
00075 
00076     /* We could theoretically parse this from the wikiTitle, but it's better
00077        to use the one passed to us. */
00078     comp.composerName = self.composerName;
00079     comp.compositionName = self.wikiTitle;
00080     /* An array for all the score files we find in the wiki page */
00081     NSMutableArray* scores = [[NSMutableArray alloc] init];
00082     ScoreData* score; 
00083     
00084     /* An error object for catching regexp errors. If we were smart we'd
00085        actually check this... Oh well, ACTION POINT!*/
00086     NSError* error = NULL;
00087     /* Finds every imslpfile template block in the wikitext */
00088     NSRegularExpression* imslpFileRegexp = [NSRegularExpression regularExpressionWithPattern:@"(\\n=+([^=]*?)=+\\n)?\\{\\{#fte:imslpfile(.*?)^\\}\\}$" options:(NSRegularExpressionCaseInsensitive | NSRegularExpressionDotMatchesLineSeparators | NSRegularExpressionAnchorsMatchLines) error:&error];
00089     if(error) {
00090         [[CatNiPErrorManager sharedManager] reportError:error];
00091     }
00092     /* Checks whether a string contains a wikitext header */
00093     NSRegularExpression* imslpFileHeaderRegexp = [NSRegularExpression regularExpressionWithPattern:@"\\n?=+(.*?)=+\\n" options:0 error:&error];
00094     if(error) {
00095         [[CatNiPErrorManager sharedManager] reportError:error];
00096     }
00097     /* Reads every name=value pair found in a imslp file template block. */
00098     NSRegularExpression* imslpPropertiesRegexp = 
00099     [NSRegularExpression regularExpressionWithPattern:@"^\\|+(.*)=(.*)$" options:(NSRegularExpressionAnchorsMatchLines) error:&error];
00100     if(error) {
00101         [[CatNiPErrorManager sharedManager] reportError:error];
00102     }
00103     /* Checks whether the name of a property contains a discrete number as the last character(s) */
00104     NSRegularExpression* imslpPropNameRegexp = 
00105     [NSRegularExpression regularExpressionWithPattern:@"(\\D+)\\s(\\d+)" options:0 error:&error];
00106     if(error) {
00107         [[CatNiPErrorManager sharedManager] reportError:error];
00108     }
00109 
00110 
00111     NSString* propName;
00112     NSString* propValue;
00113 //    NSUInteger numMatches = [imslpFileRegexp numberOfMatchesInString:fullString options:0 range:NSMakeRange(0, [fullString length])];
00114     //NSLog(@"number of file template matches in full string is %d",numMatches);
00115     
00116     NSArray* fileMatches = [imslpFileRegexp matchesInString:fullString options:0 range:NSMakeRange(0, [fullString length])];
00117     for(NSTextCheckingResult *match in fileMatches) {
00118       /* We're going to start by creating a new string which represents
00119          the single file template block we're currently looking at */
00120         NSString* fileEntry = [fullString substringWithRange:[match range]]; 
00121         /* Each file block should contain at least one File Name #=something
00122            name/value pair, where the # is a number (eg. File Name 1=what.pdf)
00123            and we're interested in these; each one defines one score file. */
00124         NSMutableDictionary* fileData = [[NSMutableDictionary alloc] init ];
00125         NSMutableDictionary* commonData = [[NSMutableDictionary alloc] init];
00126         /* First though, we check if we caught a header for this template. */
00127         NSTextCheckingResult* headerResult = [imslpFileHeaderRegexp firstMatchInString:fileEntry options:0 range:NSMakeRange(0, [fileEntry length])];
00128         NSString* fileHeader = @"";
00129         if(headerResult) {
00130             fileHeader = [fileEntry substringWithRange:[headerResult rangeAtIndex:1]];
00131         }
00132         NSLog(@"File header: %@",fileHeader);
00133         
00134 //        numMatches = [imslpPropertiesRegexp numberOfMatchesInString:fileEntry options:0 range:NSMakeRange(0, [fileEntry length])];
00135         //        NSLog(@" + number of property row matches in file string (len %d) is %d",[fileEntry length], numMatches);
00136         NSArray* propMatches = [imslpPropertiesRegexp matchesInString:fileEntry options:0 range:NSMakeRange(0, [fileEntry length])];
00137 
00138         /* We now check each property found in the block */
00139         for(NSTextCheckingResult *propMatch in propMatches) {
00140           /* The propName is the first parenthesized value in the 
00141              imslPropertiesRegexp expression, propName the second, and
00142              we get them with rangeAtIndex. rangeAtIndex:0 would give us
00143              the whole "|Ladedah=Whatever" string.
00144           */
00145             propName = [fileEntry substringWithRange:[propMatch rangeAtIndex:1]];
00146             propValue = [fileEntry substringWithRange:[propMatch rangeAtIndex:2]];
00147             /* We now see if this property is one of the "number indexed" ones
00148                ie. basically one of the multifile properties. Note that
00149                even if there is only one file in the block it will have a
00150                number index, and all it's properties (eg. page count) will
00151                be indexed to it as well
00152             */
00153             NSTextCheckingResult* indexResult = [imslpPropNameRegexp firstMatchInString:propName options:0 range:NSMakeRange(0, [propName length])];
00154             if(indexResult) {
00155                 // We have a Blah blah 5=Somethingsomething result
00156                 // Blah blah is in rangeAtIndex:1 and the number is in
00157                 // rangeAtIndex:2
00158 //                NSInteger idx = [[propName substringWithRange:[indexResult rangeAtIndex:2]] integerValue];
00159                 NSString* idxString = [propName substringWithRange:[indexResult rangeAtIndex:2]];
00160                 NSString* nameString = [propName substringWithRange:[indexResult rangeAtIndex:1]]; 
00161                 /* All properties with a number index of x are for the file
00162                    defined by File Name x=whatever.pdf so we save them
00163                    all in a nice little dictionary for later. */
00164                 if(![fileData objectForKey:idxString]) {
00165                     NSMutableDictionary* specificFileData = [[[NSMutableDictionary alloc] init] autorelease];
00166                     [fileData setObject:specificFileData forKey:idxString];
00167 
00168                 }
00169                 [[fileData objectForKey:idxString] setObject:propValue forKey:nameString];
00170                 
00171 //                NSLog(@"  - indexed match found, [%d] %@",idx,propName);                
00172                 
00173             } 
00174             else {
00175               /* non-indexed properties are for every file found in the block */
00176                 [commonData setObject:propValue forKey:propName];
00177             }
00178             //            NSLog(@"  - match found as %@ is %@",propName, propValue);
00179         }
00180         
00181         /* We've read all the properties in the block. Now we need to create
00182            a score data object for every file in the block and apply the common
00183            data to each one */
00184         NSEnumerator* fileEntriesEnumerator = [fileData keyEnumerator];
00185         id key;
00186         while((key = [fileEntriesEnumerator nextObject])) {
00187             score = [[ScoreData alloc] init];
00188             NSMutableDictionary* combinedDictionary = [[NSMutableDictionary alloc] initWithDictionary:[fileData objectForKey:key]];
00189             [combinedDictionary addEntriesFromDictionary:commonData];
00190             NSEnumerator* dataEnumerator = [combinedDictionary keyEnumerator];
00191             id dataKey;
00192             NSMutableString* metaDataString = [[NSMutableString alloc] init];
00193             NSMutableDictionary* resultDictionary = [[NSMutableDictionary alloc] init];
00194             // Default description if no other is read
00195             score.description = @"(No description)";
00196             while((dataKey = [dataEnumerator nextObject])) {
00197                 if([dataKey caseInsensitiveCompare:@"File Name"] == NSOrderedSame) {
00198                     score.pdf = [combinedDictionary objectForKey:dataKey];
00199                 }
00200                 else if([dataKey caseInsensitiveCompare:@"File Description"] == NSOrderedSame) {
00201                     score.description = [NSString stringWithFormat:@"%@ %@", [combinedDictionary objectForKey:dataKey], fileHeader];
00202                 }
00203                 
00204                 else {
00205                     [metaDataString appendFormat:@"%@ = %@\n",dataKey,[combinedDictionary objectForKey:dataKey]];
00206                     [resultDictionary setObject:[combinedDictionary objectForKey:dataKey] forKey:dataKey];
00207                 }
00208             }
00209             
00210         
00211             score.fullMetaData = [NSString stringWithString:metaDataString];
00212             score.metaDataDict = resultDictionary;
00213             /* Release some objects ... */
00214             [combinedDictionary removeAllObjects];
00215             [combinedDictionary release];
00216             [resultDictionary release]; //not emptying it because we gave it away to score
00217             [metaDataString release];
00218 
00219 
00220             /* finally add the build scoredata object into the list of all
00221                scores found on this page */
00222             if (score.pdf) [scores addObject:score];
00223             [score release];
00224         }
00225         [fileData removeAllObjects];
00226         [commonData removeAllObjects];
00227         [fileData release];
00228         [commonData release];
00229         
00230         //NSLog(@"result range: %@", match);
00231     }
00232     comp.musicScores = [[[NSArray alloc] initWithArray:scores] autorelease];
00233     [scores removeAllObjects];
00234     [scores release];
00235     [fullString release];
00236     /* Tell the delegate that we've read all the scores from the page */
00237     [self.pageDelegate didReceiveCompositionData:[comp autorelease]];
00238 }
00239 @end
00240 
00241 @implementation MediaWikiPageQuery(Private)
00242 
00244 - (NSString*)_buildGetParams {
00245     NSMutableString* qString=[[[NSMutableString alloc] init] autorelease];
00246     NSEnumerator *enumerator = [self.parameters keyEnumerator];
00247     id key;
00248     
00249     while ((key = [enumerator nextObject])) {
00250         [qString appendString: key];
00251         [qString appendString:@"="];
00252         [qString appendString: [self.parameters valueForKey:key]];
00253         [qString appendString:@"&"];
00254     }
00255     
00256     return [[[NSString alloc] initWithString:qString] autorelease];
00257 }
00258 
00259 @end
 All Classes Files Functions Variables Enumerations Enumerator Properties Defines