CatNiP prefinal
Sähköinen nuottikirja, HY-TKTKL-OHTUPROJ KESÄ11
|
00001 00012 #import "MediaWikiDownload.h" 00013 00014 @implementation MediaWikiDownload 00015 @synthesize mediaWikiURLString; 00016 @synthesize mediaWikiFilename; 00017 00028 -(NSInteger)expectedSize { 00029 return expectedSize; 00030 } 00031 00036 -(NSInteger)currentBytes { 00037 return currentBytes; 00038 } 00039 00043 -(id)init { 00044 if((self = [super init])) { 00045 expectedSize = NSIntegerMin; // MAAAGIC NUMBER 00046 currentBytes = 0; 00047 progressListeners = [[NSMutableSet alloc] init]; 00048 } 00049 return self; 00050 } 00051 00052 00058 -(id)initWithDelegate:(id <MediaWikiDownloadDelegate>)mediaWikiDownloadDelegate { 00059 if(!mediaWikiDownloadDelegate) { 00060 return nil; 00061 } 00062 if((self = [self init])) { 00063 // Won't work without a delegate 00064 //if(mediaWikiDownloadDelegate == nil) { 00065 // return nil; 00066 //} 00067 queryDelegate = mediaWikiDownloadDelegate; 00068 working = NO; 00069 } 00070 return self; 00071 } 00078 -(id)initWithDelegate:(id <MediaWikiDownloadDelegate>)mediaWikiDownloadDelegate mediaWikiURL:(NSString *)mwURLString { 00079 if(!mwURLString) { 00080 return nil; 00081 } 00082 self = [self initWithDelegate:mediaWikiDownloadDelegate]; 00083 if(self != nil) { 00084 self.mediaWikiURLString = mwURLString; 00085 } 00086 return self; 00087 } 00095 -(NSString*)buildQueryURL { 00096 return [self.mediaWikiURLString stringByAppendingString:self.mediaWikiFilename]; 00097 } 00107 -(BOOL)startQuery { 00108 NSString* queryURL = [self buildQueryURL]; 00109 if(!self.mediaWikiFilename || [self.mediaWikiFilename length] < 1) { 00110 return NO; 00111 } 00112 if(queryURL == nil || [queryURL length] < 3) { 00113 return NO; 00114 } 00115 if(working) { 00116 return NO; 00117 } 00118 // We probably need to ensure that we're not in the middle 00119 // of a request! 00120 // queryURL = [queryURL stringByAddingPercentEscapesUsingEncoding:NSISOLatin1StringEncoding]; 00121 queryURL = [queryURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; 00122 // The request is mutable so that we can set the cookie header ourselves 00123 mediaWikiRequest = [[NSMutableURLRequest alloc] initWithURL:[[[NSURL alloc] initWithString:queryURL] autorelease]]; 00124 //[queryURL release]; 00125 [mediaWikiRequest setHTTPShouldHandleCookies:NO]; 00126 // IMSLP won't let us download a file unless we have this cookie 00127 [mediaWikiRequest setValue:@"imslpdisclaimeraccepted=yes" forHTTPHeaderField:@"Cookie"]; 00128 00129 //NSLog(@"urlstring: %@ requestobj: %@", queryURL, mediaWikiRequest); 00130 //Is this the right spot for a retain? 00131 if(![NSURLConnection canHandleRequest:mediaWikiRequest]) { 00132 //[mediaWikiRequest release]; 00133 // TODO: Add an error message or something! 00134 return NO; 00135 } 00136 mediaWikiConnection = [[NSURLConnection alloc] initWithRequest:mediaWikiRequest delegate:self]; 00137 if(mediaWikiConnection) { 00138 //receivedData = [[NSMutableData data] retain]; 00139 [mediaWikiConnection start]; 00140 //[mediaWikiRequest release]; 00141 working = YES; 00142 } else { 00143 NSDictionary *errordata = 00144 [NSDictionary dictionaryWithObjectsAndKeys: 00145 @"Unknown error while opening HTTP connection", NSLocalizedFailureReasonErrorKey, 00146 [NSString stringWithFormat:@"Could not establish a connection to \"%@\".",queryURL], 00147 NSLocalizedDescriptionKey, nil]; 00148 [[CatNiPErrorManager sharedManager] reportError:[NSError errorWithDomain:NSPOSIXErrorDomain code:EIO userInfo:errordata]]; 00149 NSLog(@"NSURLConnection failed for some reason."); 00150 //[mediaWikiRequest release]; 00151 return NO; 00152 } 00153 return YES; 00154 00155 } 00159 - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { 00160 NSLog(@"received response with MIMEType:%@, resetting...", [response MIMEType]); 00161 // This method is called when the server has determined that it 00162 // has enough information to create the NSURLResponse. 00163 if([response expectedContentLength]) { 00164 expectedSize = [response expectedContentLength]; 00165 } else { 00166 expectedSize = -1; // Maaaagic number 2. 00167 } 00168 // It can be called multiple times, for example in the case of a 00169 // redirect, so each time we reset the data. 00170 //[receivedData setLength:0]; 00171 if(outHandle) { 00172 NSLog(@"Output file handle exists already, closing time."); 00173 [outHandle closeFile]; 00174 [outHandle release]; 00175 } 00176 // Create the output file path. 00177 if(!outputPath) { 00178 NSLog(@"No outputPath defined yet, creating..."); 00179 outputPath = [NSTemporaryDirectory() stringByAppendingPathComponent:self.mediaWikiFilename]; 00180 [outputPath retain]; 00181 NSLog(@"OutputPath is now %@",outputPath); 00182 } 00183 if([[NSFileManager defaultManager] createFileAtPath:outputPath contents:nil attributes:nil]) { 00184 NSLog(@"Succesfully created empty file"); 00185 outHandle = [[NSFileHandle fileHandleForWritingAtPath:outputPath] retain]; 00186 if(!outHandle) { 00187 NSLog(@"Got a null outHandle, oh god!"); 00188 } 00189 00190 } 00191 else { 00192 // Could not create temp file! 00193 NSLog(@"Could not create temp file, this is going to be ugly."); 00194 } 00195 00196 00197 } 00200 - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { 00201 // Append the new data to receivedData. 00202 // receivedData is an instance variable declared in the interface. 00203 //[receivedData appendData:data]; 00204 //NSLog(@"received data, %d bytes",[data length]); 00205 [outHandle writeData:data]; 00206 currentBytes += [data length]; 00207 for (id<MediaWikiProgressListener> listener in progressListeners) { 00208 [listener progressUpdate:self]; 00209 } 00210 } 00214 - (void)connection:(NSURLConnection *)connection 00215 didFailWithError:(NSError *)error { 00216 // release the connection, and the data object 00217 [mediaWikiConnection release]; 00218 //[receivedData release]; 00219 if(outHandle) { 00220 [outHandle closeFile]; 00221 [outHandle release]; 00222 } 00223 working = NO; 00224 if(outputPath) { 00225 [outputPath release]; 00226 } 00227 [[CatNiPErrorManager sharedManager] reportError:error]; 00228 00229 00230 // inform the user 00231 NSLog(@"Connection failed! Error - %@ %@", 00232 [error localizedDescription], 00233 [[error userInfo] objectForKey:NSURLErrorFailingURLStringErrorKey]); 00234 } 00237 - (void)connectionDidFinishLoading:(NSURLConnection *)connection { 00238 // do something with the data 00239 // receivedData is declared as a method instance elsewhere 00240 //NSData* tmp = [NSData dataWithData:receivedData]; 00241 [mediaWikiConnection release]; 00242 //[receivedData release]; 00243 if(outHandle) { 00244 [outHandle closeFile]; 00245 [outHandle release]; 00246 } 00247 working = NO; 00248 NSLog(@"connection ended succesfully, hooray"); 00249 NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 00250 NSString *documentsDirectory = [paths objectAtIndex:0]; 00251 documentsDirectory = [documentsDirectory stringByAppendingPathComponent:self.mediaWikiFilename]; 00252 NSError* copyError; 00253 if ([[NSFileManager defaultManager] fileExistsAtPath:documentsDirectory]) { 00254 [[NSFileManager defaultManager] removeItemAtPath:documentsDirectory error:©Error]; 00255 } 00256 if(![[NSFileManager defaultManager] moveItemAtPath:outputPath toPath:documentsDirectory error:©Error]) { 00257 //[outputPath autorelease]; 00258 [[CatNiPErrorManager sharedManager] reportError:copyError]; 00259 00260 } 00261 else { 00262 [queryDelegate didFinishDownload:[NSString stringWithString:documentsDirectory]]; 00263 } 00264 [outputPath release]; 00265 } 00266 00274 -(void)addProgressListener:(id <MediaWikiProgressListener>)listener { 00275 if([progressListeners containsObject:listener]) { 00276 return; 00277 } 00278 else { 00279 [progressListeners addObject:listener]; 00280 } 00281 } 00282 00287 -(void)removeProgressListener:(id <MediaWikiProgressListener>)listener { 00288 if([progressListeners containsObject:listener]) { 00289 [progressListeners removeObject:listener]; 00290 } 00291 } 00292 00297 -(void)abortRead { 00298 if(working) { 00299 [mediaWikiConnection cancel]; 00300 [mediaWikiConnection release]; 00301 //[receivedData release]; 00302 if(outHandle) { 00303 [outHandle closeFile]; 00304 [outHandle release]; 00305 } 00306 working = NO; 00307 if(outputPath) { 00308 [outputPath release]; 00309 } 00310 } 00311 } 00312 00313 00314 @end