From 2fe7e10750f1018530302377061bda8553faa434 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Thu, 25 Nov 2010 12:36:14 +1300 Subject: [PATCH] Handle download errors --- OpenRA.Launcher.Mac/Download.h | 4 ++- OpenRA.Launcher.Mac/Download.m | 31 +++++++++++++++-------- OpenRA.Launcher.Mac/JSBridge.m | 23 ++++++++++++----- mods/cnc/mod.html | 45 +++++++++++++++++++--------------- 4 files changed, 66 insertions(+), 37 deletions(-) diff --git a/OpenRA.Launcher.Mac/Download.h b/OpenRA.Launcher.Mac/Download.h index 71b452df92..4d673e780f 100644 --- a/OpenRA.Launcher.Mac/Download.h +++ b/OpenRA.Launcher.Mac/Download.h @@ -16,7 +16,8 @@ NSString *filename; GameInstall *game; NSTask *task; - NSString * status; + NSString *status; + NSString *error; int bytesCompleted; int bytesTotal; } @@ -25,6 +26,7 @@ @property(readonly) NSString *status; @property(readonly) int bytesCompleted; @property(readonly) int bytesTotal; +@property(readonly) NSString *error; + (id)downloadWithURL:(NSString *)aURL filename:(NSString *)aFilename key:(NSString *)aKey game:(GameInstall *)aGame; - (id)initWithURL:(NSString *)aURL filename:(NSString *)aFilename key:(NSString *)aKey game:(GameInstall *)game; diff --git a/OpenRA.Launcher.Mac/Download.m b/OpenRA.Launcher.Mac/Download.m index 0d2c973c3a..8558c0d43d 100644 --- a/OpenRA.Launcher.Mac/Download.m +++ b/OpenRA.Launcher.Mac/Download.m @@ -15,6 +15,7 @@ @synthesize status; @synthesize bytesCompleted; @synthesize bytesTotal; +@synthesize error; + (id)downloadWithURL:(NSString *)aURL filename:(NSString *)aFilename key:(NSString *)aKey game:(GameInstall *)aGame { @@ -32,17 +33,17 @@ filename = [aFilename retain]; key = [aKey retain]; game = [aGame retain]; + error = @""; if ([[NSFileManager defaultManager] fileExistsAtPath:filename]) { status = @"COMPLETE"; - bytesCompleted = bytesTotal = [[[NSFileManager defaultManager] attributesOfItemAtPath:filename error:nil] fileSize]; + bytesCompleted = bytesTotal = [[[NSFileManager defaultManager] attributesOfItemAtPath:filename error:NULL] fileSize]; } else { status = @"AVAILABLE"; - bytesCompleted = -1; - bytesTotal = -1; + bytesCompleted = bytesTotal = -1; } } return self; @@ -68,7 +69,13 @@ if ([type isEqualToString:@"Error"]) { status = @"ERROR"; + [error autorelease]; + if ([[message substringToIndex:36] isEqualToString:@"The remote server returned an error:"]) + error = [[message substringFromIndex:37] retain]; + else + error = [message retain]; } + else if ([type isEqualToString:@"Status"]) { if ([message isEqualToString:@"Completed"]) @@ -95,8 +102,6 @@ - (BOOL)start { status = @"DOWNLOADING"; - - NSLog(@"Starting download..."); task = [game runAsyncUtilityWithArg:[NSString stringWithFormat:@"--download-url=%@,%@",url,filename] delegate:self responseSelector:@selector(utilityResponded:) @@ -107,13 +112,13 @@ - (BOOL)cancel { - NSLog(@"Cancelling"); status = @"ERROR"; - NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; - [nc removeObserver:self name:NSFileHandleReadCompletionNotification object:[[task standardOutput] fileHandleForReading]]; - [nc removeObserver:self name:NSTaskDidTerminateNotification object:task]; + error = @"Download Cancelled"; + [[JSBridge sharedInstance] notifyDownloadProgress:self]; + [[NSNotificationCenter defaultCenter] removeObserver:self + name:NSFileHandleReadCompletionNotification + object:[[task standardOutput] fileHandleForReading]]; [task terminate]; - [task release]; task = nil; return YES; } @@ -124,6 +129,12 @@ [nc removeObserver:self name:NSFileHandleReadCompletionNotification object:[[task standardOutput] fileHandleForReading]]; [nc removeObserver:self name:NSTaskDidTerminateNotification object:task]; [task release]; task = nil; + + if (status == @"ERROR") + { + [[NSFileManager defaultManager] removeItemAtPath:filename error:NULL]; + bytesCompleted = bytesTotal = -1; + } } @end diff --git a/OpenRA.Launcher.Mac/JSBridge.m b/OpenRA.Launcher.Mac/JSBridge.m index ffac60be85..ebb7df40da 100644 --- a/OpenRA.Launcher.Mac/JSBridge.m +++ b/OpenRA.Launcher.Mac/JSBridge.m @@ -49,6 +49,7 @@ static JSBridge *SharedInstance; @"startDownload", NSStringFromSelector(@selector(startDownload:)), @"cancelDownload", NSStringFromSelector(@selector(cancelDownload:)), @"downloadStatus", NSStringFromSelector(@selector(downloadStatus:)), + @"downloadError", NSStringFromSelector(@selector(downloadError:)), @"bytesCompleted", NSStringFromSelector(@selector(bytesCompleted:)), @"bytesTotal", NSStringFromSelector(@selector(bytesTotal:)), nil] retain]; @@ -67,12 +68,6 @@ static JSBridge *SharedInstance; [super dealloc]; } -- (void)notifyDownloadProgress:(Download *)download -{ - [[[controller webView] windowScriptObject] evaluateWebScript: - [NSString stringWithFormat:@"downloadProgressed('%@')",[download key]]]; -} - #pragma mark JS API methods - (BOOL)launchMod:(NSString *)aMod @@ -119,6 +114,15 @@ static JSBridge *SharedInstance; return [d status]; } +- (NSString *)downloadError:(NSString *)key +{ + Download *d = [controller downloadWithKey:key]; + if (d == nil) + return @""; + + return [d error]; +} + - (BOOL)startDownload:(NSString *)key { Download *d = [controller downloadWithKey:key]; @@ -143,6 +147,13 @@ static JSBridge *SharedInstance; return (d == nil) ? -1 : [d bytesTotal]; } +- (void)notifyDownloadProgress:(Download *)download +{ + [[[controller webView] windowScriptObject] evaluateWebScript: + [NSString stringWithFormat:@"downloadProgressed('%@')",[download key]]]; +} + + - (void)log:(NSString *)message { NSLog(@"js: %@",message); diff --git a/mods/cnc/mod.html b/mods/cnc/mod.html index d4384ebd68..b75d6123d7 100644 --- a/mods/cnc/mod.html +++ b/mods/cnc/mod.html @@ -53,7 +53,7 @@ padding:20px; } - div.desc + .desc { font-size:0.75em; } @@ -102,15 +102,13 @@ function download() { + document.getElementById("download-status").value = "Initializing..." window.external.startDownload("cnc-packages"); - refreshDownloadButtons(); } function cancel() { window.external.cancelDownload("cnc-packages"); - // TODO: Remove incomplete file from cache - // TODO: Restore buttons to the before-downloading state } function extract() @@ -136,7 +134,10 @@ // Select the correct subsection if (installed == 0) { - window.external.registerDownload("cnc-packages", "http://localhost/~paul/cnc-packages.zip", "cnc-packages.zip"); + //var url = "http://localhost/~paul/cnc-packages.zip"; + //var url = "http://localhost/~paul/cnc-packages.bogus"; + var url = "http://open-ra.org/get-dependency.php?file=cnc-packages"; + window.external.registerDownload("cnc-packages", url, "cnc-packages.zip"); refreshDownloadButtons(); } } @@ -146,6 +147,7 @@ document.getElementById("download-available").style.display = "none"; document.getElementById("download-downloading").style.display = "none"; document.getElementById("download-extract").style.display = "none"; + document.getElementById("download-error").style.display = "none"; // status can be NOT_REGISTERED, AVAILABLE, DOWNLOADING, COMPLETE, ERROR var status = window.external.downloadStatus("cnc-packages"); @@ -153,22 +155,21 @@ // Download complete, offer button to extract it if (status == "COMPLETE") - { document.getElementById("download-extract").style.display = ""; - } // Show the download progress else if (status == "DOWNLOADING") - { document.getElementById("download-downloading").style.display = ""; - } // Show the download button - else if (status == "AVAILABLE" || status == "ERROR") - { + else if (status == "AVAILABLE") document.getElementById("download-available").style.display = ""; - - // Todo: set error message + + else if (status == "ERROR") + { + var message = window.external.downloadError("cnc-packages"); + document.getElementById("error-message").innerHTML = message; + document.getElementById("download-error").style.display = ""; } } @@ -181,14 +182,14 @@ var downloaded = window.external.bytesCompleted(file); window.external.log(file+" = total: "+total+" downloaded: "+downloaded); - if (downloaded == -1) - return; + if (downloaded > 0) + { + var multiplier = 1/1048576.0; + total = (total*multiplier).toPrecision(2); + downloaded = (downloaded*multiplier).toPrecision(2); - var multiplier = 1/1048576.0; - total = (total*multiplier).toPrecision(2); - downloaded = (downloaded*multiplier).toPrecision(2); - - document.getElementById("download-status").value = downloaded+"/"+total+" MB"; + document.getElementById("download-status").value = downloaded+"/"+total+" MB"; + } refreshDownloadButtons(); } @@ -225,6 +226,10 @@ +