Handle download errors
This commit is contained in:
@@ -16,7 +16,8 @@
|
|||||||
NSString *filename;
|
NSString *filename;
|
||||||
GameInstall *game;
|
GameInstall *game;
|
||||||
NSTask *task;
|
NSTask *task;
|
||||||
NSString * status;
|
NSString *status;
|
||||||
|
NSString *error;
|
||||||
int bytesCompleted;
|
int bytesCompleted;
|
||||||
int bytesTotal;
|
int bytesTotal;
|
||||||
}
|
}
|
||||||
@@ -25,6 +26,7 @@
|
|||||||
@property(readonly) NSString *status;
|
@property(readonly) NSString *status;
|
||||||
@property(readonly) int bytesCompleted;
|
@property(readonly) int bytesCompleted;
|
||||||
@property(readonly) int bytesTotal;
|
@property(readonly) int bytesTotal;
|
||||||
|
@property(readonly) NSString *error;
|
||||||
|
|
||||||
+ (id)downloadWithURL:(NSString *)aURL filename:(NSString *)aFilename key:(NSString *)aKey game:(GameInstall *)aGame;
|
+ (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;
|
- (id)initWithURL:(NSString *)aURL filename:(NSString *)aFilename key:(NSString *)aKey game:(GameInstall *)game;
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
@synthesize status;
|
@synthesize status;
|
||||||
@synthesize bytesCompleted;
|
@synthesize bytesCompleted;
|
||||||
@synthesize bytesTotal;
|
@synthesize bytesTotal;
|
||||||
|
@synthesize error;
|
||||||
|
|
||||||
+ (id)downloadWithURL:(NSString *)aURL filename:(NSString *)aFilename key:(NSString *)aKey game:(GameInstall *)aGame
|
+ (id)downloadWithURL:(NSString *)aURL filename:(NSString *)aFilename key:(NSString *)aKey game:(GameInstall *)aGame
|
||||||
{
|
{
|
||||||
@@ -32,17 +33,17 @@
|
|||||||
filename = [aFilename retain];
|
filename = [aFilename retain];
|
||||||
key = [aKey retain];
|
key = [aKey retain];
|
||||||
game = [aGame retain];
|
game = [aGame retain];
|
||||||
|
error = @"";
|
||||||
|
|
||||||
if ([[NSFileManager defaultManager] fileExistsAtPath:filename])
|
if ([[NSFileManager defaultManager] fileExistsAtPath:filename])
|
||||||
{
|
{
|
||||||
status = @"COMPLETE";
|
status = @"COMPLETE";
|
||||||
bytesCompleted = bytesTotal = [[[NSFileManager defaultManager] attributesOfItemAtPath:filename error:nil] fileSize];
|
bytesCompleted = bytesTotal = [[[NSFileManager defaultManager] attributesOfItemAtPath:filename error:NULL] fileSize];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
status = @"AVAILABLE";
|
status = @"AVAILABLE";
|
||||||
bytesCompleted = -1;
|
bytesCompleted = bytesTotal = -1;
|
||||||
bytesTotal = -1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
@@ -68,7 +69,13 @@
|
|||||||
if ([type isEqualToString:@"Error"])
|
if ([type isEqualToString:@"Error"])
|
||||||
{
|
{
|
||||||
status = @"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"])
|
else if ([type isEqualToString:@"Status"])
|
||||||
{
|
{
|
||||||
if ([message isEqualToString:@"Completed"])
|
if ([message isEqualToString:@"Completed"])
|
||||||
@@ -95,8 +102,6 @@
|
|||||||
- (BOOL)start
|
- (BOOL)start
|
||||||
{
|
{
|
||||||
status = @"DOWNLOADING";
|
status = @"DOWNLOADING";
|
||||||
|
|
||||||
NSLog(@"Starting download...");
|
|
||||||
task = [game runAsyncUtilityWithArg:[NSString stringWithFormat:@"--download-url=%@,%@",url,filename]
|
task = [game runAsyncUtilityWithArg:[NSString stringWithFormat:@"--download-url=%@,%@",url,filename]
|
||||||
delegate:self
|
delegate:self
|
||||||
responseSelector:@selector(utilityResponded:)
|
responseSelector:@selector(utilityResponded:)
|
||||||
@@ -107,13 +112,13 @@
|
|||||||
|
|
||||||
- (BOOL)cancel
|
- (BOOL)cancel
|
||||||
{
|
{
|
||||||
NSLog(@"Cancelling");
|
|
||||||
status = @"ERROR";
|
status = @"ERROR";
|
||||||
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
|
error = @"Download Cancelled";
|
||||||
[nc removeObserver:self name:NSFileHandleReadCompletionNotification object:[[task standardOutput] fileHandleForReading]];
|
[[JSBridge sharedInstance] notifyDownloadProgress:self];
|
||||||
[nc removeObserver:self name:NSTaskDidTerminateNotification object:task];
|
[[NSNotificationCenter defaultCenter] removeObserver:self
|
||||||
|
name:NSFileHandleReadCompletionNotification
|
||||||
|
object:[[task standardOutput] fileHandleForReading]];
|
||||||
[task terminate];
|
[task terminate];
|
||||||
[task release]; task = nil;
|
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,6 +129,12 @@
|
|||||||
[nc removeObserver:self name:NSFileHandleReadCompletionNotification object:[[task standardOutput] fileHandleForReading]];
|
[nc removeObserver:self name:NSFileHandleReadCompletionNotification object:[[task standardOutput] fileHandleForReading]];
|
||||||
[nc removeObserver:self name:NSTaskDidTerminateNotification object:task];
|
[nc removeObserver:self name:NSTaskDidTerminateNotification object:task];
|
||||||
[task release]; task = nil;
|
[task release]; task = nil;
|
||||||
|
|
||||||
|
if (status == @"ERROR")
|
||||||
|
{
|
||||||
|
[[NSFileManager defaultManager] removeItemAtPath:filename error:NULL];
|
||||||
|
bytesCompleted = bytesTotal = -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ static JSBridge *SharedInstance;
|
|||||||
@"startDownload", NSStringFromSelector(@selector(startDownload:)),
|
@"startDownload", NSStringFromSelector(@selector(startDownload:)),
|
||||||
@"cancelDownload", NSStringFromSelector(@selector(cancelDownload:)),
|
@"cancelDownload", NSStringFromSelector(@selector(cancelDownload:)),
|
||||||
@"downloadStatus", NSStringFromSelector(@selector(downloadStatus:)),
|
@"downloadStatus", NSStringFromSelector(@selector(downloadStatus:)),
|
||||||
|
@"downloadError", NSStringFromSelector(@selector(downloadError:)),
|
||||||
@"bytesCompleted", NSStringFromSelector(@selector(bytesCompleted:)),
|
@"bytesCompleted", NSStringFromSelector(@selector(bytesCompleted:)),
|
||||||
@"bytesTotal", NSStringFromSelector(@selector(bytesTotal:)),
|
@"bytesTotal", NSStringFromSelector(@selector(bytesTotal:)),
|
||||||
nil] retain];
|
nil] retain];
|
||||||
@@ -67,12 +68,6 @@ static JSBridge *SharedInstance;
|
|||||||
[super dealloc];
|
[super dealloc];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)notifyDownloadProgress:(Download *)download
|
|
||||||
{
|
|
||||||
[[[controller webView] windowScriptObject] evaluateWebScript:
|
|
||||||
[NSString stringWithFormat:@"downloadProgressed('%@')",[download key]]];
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma mark JS API methods
|
#pragma mark JS API methods
|
||||||
|
|
||||||
- (BOOL)launchMod:(NSString *)aMod
|
- (BOOL)launchMod:(NSString *)aMod
|
||||||
@@ -119,6 +114,15 @@ static JSBridge *SharedInstance;
|
|||||||
return [d status];
|
return [d status];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (NSString *)downloadError:(NSString *)key
|
||||||
|
{
|
||||||
|
Download *d = [controller downloadWithKey:key];
|
||||||
|
if (d == nil)
|
||||||
|
return @"";
|
||||||
|
|
||||||
|
return [d error];
|
||||||
|
}
|
||||||
|
|
||||||
- (BOOL)startDownload:(NSString *)key
|
- (BOOL)startDownload:(NSString *)key
|
||||||
{
|
{
|
||||||
Download *d = [controller downloadWithKey:key];
|
Download *d = [controller downloadWithKey:key];
|
||||||
@@ -143,6 +147,13 @@ static JSBridge *SharedInstance;
|
|||||||
return (d == nil) ? -1 : [d bytesTotal];
|
return (d == nil) ? -1 : [d bytesTotal];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)notifyDownloadProgress:(Download *)download
|
||||||
|
{
|
||||||
|
[[[controller webView] windowScriptObject] evaluateWebScript:
|
||||||
|
[NSString stringWithFormat:@"downloadProgressed('%@')",[download key]]];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
- (void)log:(NSString *)message
|
- (void)log:(NSString *)message
|
||||||
{
|
{
|
||||||
NSLog(@"js: %@",message);
|
NSLog(@"js: %@",message);
|
||||||
|
|||||||
@@ -53,7 +53,7 @@
|
|||||||
padding:20px;
|
padding:20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.desc
|
.desc
|
||||||
{
|
{
|
||||||
font-size:0.75em;
|
font-size:0.75em;
|
||||||
}
|
}
|
||||||
@@ -102,15 +102,13 @@
|
|||||||
|
|
||||||
function download()
|
function download()
|
||||||
{
|
{
|
||||||
|
document.getElementById("download-status").value = "Initializing..."
|
||||||
window.external.startDownload("cnc-packages");
|
window.external.startDownload("cnc-packages");
|
||||||
refreshDownloadButtons();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function cancel()
|
function cancel()
|
||||||
{
|
{
|
||||||
window.external.cancelDownload("cnc-packages");
|
window.external.cancelDownload("cnc-packages");
|
||||||
// TODO: Remove incomplete file from cache
|
|
||||||
// TODO: Restore buttons to the before-downloading state
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function extract()
|
function extract()
|
||||||
@@ -136,7 +134,10 @@
|
|||||||
// Select the correct subsection
|
// Select the correct subsection
|
||||||
if (installed == 0)
|
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();
|
refreshDownloadButtons();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -146,6 +147,7 @@
|
|||||||
document.getElementById("download-available").style.display = "none";
|
document.getElementById("download-available").style.display = "none";
|
||||||
document.getElementById("download-downloading").style.display = "none";
|
document.getElementById("download-downloading").style.display = "none";
|
||||||
document.getElementById("download-extract").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
|
// status can be NOT_REGISTERED, AVAILABLE, DOWNLOADING, COMPLETE, ERROR
|
||||||
var status = window.external.downloadStatus("cnc-packages");
|
var status = window.external.downloadStatus("cnc-packages");
|
||||||
@@ -153,22 +155,21 @@
|
|||||||
|
|
||||||
// Download complete, offer button to extract it
|
// Download complete, offer button to extract it
|
||||||
if (status == "COMPLETE")
|
if (status == "COMPLETE")
|
||||||
{
|
|
||||||
document.getElementById("download-extract").style.display = "";
|
document.getElementById("download-extract").style.display = "";
|
||||||
}
|
|
||||||
|
|
||||||
// Show the download progress
|
// Show the download progress
|
||||||
else if (status == "DOWNLOADING")
|
else if (status == "DOWNLOADING")
|
||||||
{
|
|
||||||
document.getElementById("download-downloading").style.display = "";
|
document.getElementById("download-downloading").style.display = "";
|
||||||
}
|
|
||||||
|
|
||||||
// Show the download button
|
// Show the download button
|
||||||
else if (status == "AVAILABLE" || status == "ERROR")
|
else if (status == "AVAILABLE")
|
||||||
{
|
|
||||||
document.getElementById("download-available").style.display = "";
|
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);
|
var downloaded = window.external.bytesCompleted(file);
|
||||||
window.external.log(file+" = total: "+total+" downloaded: "+downloaded);
|
window.external.log(file+" = total: "+total+" downloaded: "+downloaded);
|
||||||
|
|
||||||
if (downloaded == -1)
|
if (downloaded > 0)
|
||||||
return;
|
{
|
||||||
|
|
||||||
var multiplier = 1/1048576.0;
|
var multiplier = 1/1048576.0;
|
||||||
total = (total*multiplier).toPrecision(2);
|
total = (total*multiplier).toPrecision(2);
|
||||||
downloaded = (downloaded*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();
|
refreshDownloadButtons();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -225,6 +226,10 @@
|
|||||||
<div id="download-extract" style="display:none">
|
<div id="download-extract" style="display:none">
|
||||||
<input type="button" class="button" onclick="extract();" value="Install" />
|
<input type="button" class="button" onclick="extract();" value="Install" />
|
||||||
</div>
|
</div>
|
||||||
|
<div id="download-error" style="display:none">
|
||||||
|
<input type="button" class="button" onclick="download();" value="Retry" />
|
||||||
|
<span class="desc" id="error-message"></span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="buttons-upgrade" class="buttons" style="display:none">
|
<div id="buttons-upgrade" class="buttons" style="display:none">
|
||||||
<div class="desc">
|
<div class="desc">
|
||||||
|
|||||||
Reference in New Issue
Block a user