From 6f66a19b18b6fa6bf1a221a64f20d9d144189127 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Thu, 25 Nov 2010 11:24:10 +1300 Subject: [PATCH] Clean up file downloading. --- OpenRA.Launcher.Mac/Controller.h | 3 +- OpenRA.Launcher.Mac/Controller.m | 15 ++---- OpenRA.Launcher.Mac/Download.h | 4 +- OpenRA.Launcher.Mac/Download.m | 48 +++++++++++------- OpenRA.Launcher.Mac/JSBridge.m | 38 +++++++-------- mods/cnc/mod.html | 83 +++++++++++++++++++++----------- 6 files changed, 109 insertions(+), 82 deletions(-) diff --git a/OpenRA.Launcher.Mac/Controller.h b/OpenRA.Launcher.Mac/Controller.h index 3af55df9d1..d0a8bb53f0 100644 --- a/OpenRA.Launcher.Mac/Controller.h +++ b/OpenRA.Launcher.Mac/Controller.h @@ -30,8 +30,7 @@ - (SidebarEntry *)sidebarModsTree; - (SidebarEntry *)sidebarOtherTree; -- (BOOL)downloadUrl:(NSString *)url toFile:(NSString *)filename withId:(NSString *)key; -- (void)cancelDownload:(NSString *)key; +- (BOOL)registerDownload:(NSString *)key withURL:(NSString *)url filePath:(NSString *)path; - (Download *)downloadWithKey:(NSString *)key; @end diff --git a/OpenRA.Launcher.Mac/Controller.m b/OpenRA.Launcher.Mac/Controller.m index 14ef0c6583..48417cd47e 100644 --- a/OpenRA.Launcher.Mac/Controller.m +++ b/OpenRA.Launcher.Mac/Controller.m @@ -94,25 +94,16 @@ [game launchMod:mod]; } -- (BOOL)downloadUrl:(NSString *)url toFile:(NSString *)path withId:(NSString *)key +- (BOOL)registerDownload:(NSString *)key withURL:(NSString *)url filePath:(NSString *)path; { if ([downloads objectForKey:key] != nil) - { - NSLog(@"Download already in progress for %@",key); return NO; - } - Download *download = [Download downloadWithURL:url filename:path key:key game:game]; - [downloads setObject:download forKey:key]; + [downloads setObject:[Download downloadWithURL:url filename:path key:key game:game] + forKey:key]; return YES; } -- (void)cancelDownload:(NSString *)key -{ - [[downloads objectForKey:key] cancel]; - [downloads removeObjectForKey:key]; -} - - (Download *)downloadWithKey:(NSString *)key { return [downloads objectForKey:key]; diff --git a/OpenRA.Launcher.Mac/Download.h b/OpenRA.Launcher.Mac/Download.h index 92c32863de..71b452df92 100644 --- a/OpenRA.Launcher.Mac/Download.h +++ b/OpenRA.Launcher.Mac/Download.h @@ -20,6 +20,7 @@ int bytesCompleted; int bytesTotal; } + @property(readonly) NSString *key; @property(readonly) NSString *status; @property(readonly) int bytesCompleted; @@ -27,6 +28,7 @@ + (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; -- (void)cancel; +- (BOOL)start; +- (BOOL)cancel; @end \ No newline at end of file diff --git a/OpenRA.Launcher.Mac/Download.m b/OpenRA.Launcher.Mac/Download.m index 17b8fa91e5..0d2c973c3a 100644 --- a/OpenRA.Launcher.Mac/Download.m +++ b/OpenRA.Launcher.Mac/Download.m @@ -32,16 +32,18 @@ filename = [aFilename retain]; key = [aKey retain]; game = [aGame retain]; - status = @"Initializing"; - bytesCompleted = -1; - bytesTotal = -1; - NSLog(@"Starting download..."); - task = [game runAsyncUtilityWithArg:[NSString stringWithFormat:@"--download-url=%@,%@",url,filename] - delegate:self - responseSelector:@selector(utilityResponded:) - terminatedSelector:@selector(utilityTerminated:)]; - [task retain]; + if ([[NSFileManager defaultManager] fileExistsAtPath:filename]) + { + status = @"COMPLETE"; + bytesCompleted = bytesTotal = [[[NSFileManager defaultManager] attributesOfItemAtPath:filename error:nil] fileSize]; + } + else + { + status = @"AVAILABLE"; + bytesCompleted = -1; + bytesTotal = -1; + } } return self; } @@ -65,17 +67,13 @@ if ([type isEqualToString:@"Error"]) { - status = @"Error"; + status = @"ERROR"; } else if ([type isEqualToString:@"Status"]) { - if ([message isEqualToString:@"Initializing"]) + if ([message isEqualToString:@"Completed"]) { - status = @"Initializing"; - } - else if ([message isEqualToString:@"Completed"]) - { - status = @"Complete"; + status = @"COMPLETE"; } // Parse download status info @@ -94,15 +92,29 @@ [[n object] readInBackgroundAndNotify]; } -- (void)cancel +- (BOOL)start +{ + status = @"DOWNLOADING"; + + NSLog(@"Starting download..."); + task = [game runAsyncUtilityWithArg:[NSString stringWithFormat:@"--download-url=%@,%@",url,filename] + delegate:self + responseSelector:@selector(utilityResponded:) + terminatedSelector:@selector(utilityTerminated:)]; + [task retain]; + return YES; +} + +- (BOOL)cancel { NSLog(@"Cancelling"); - status = @"Cancelled"; + status = @"ERROR"; NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; [nc removeObserver:self name:NSFileHandleReadCompletionNotification object:[[task standardOutput] fileHandleForReading]]; [nc removeObserver:self name:NSTaskDidTerminateNotification object:task]; [task terminate]; [task release]; task = nil; + return YES; } - (void)utilityTerminated:(NSNotification *)n diff --git a/OpenRA.Launcher.Mac/JSBridge.m b/OpenRA.Launcher.Mac/JSBridge.m index 96c101eb9d..ffac60be85 100644 --- a/OpenRA.Launcher.Mac/JSBridge.m +++ b/OpenRA.Launcher.Mac/JSBridge.m @@ -45,8 +45,8 @@ static JSBridge *SharedInstance; @"existsInMod", NSStringFromSelector(@selector(fileExists:inMod:)), // File downloading - @"existsInCache", NSStringFromSelector(@selector(existsInCache:)), - @"downloadToCache", NSStringFromSelector(@selector(downloadUrl:withName:key:)), + @"registerDownload", NSStringFromSelector(@selector(registerDownload:withURL:filename:)), + @"startDownload", NSStringFromSelector(@selector(startDownload:)), @"cancelDownload", NSStringFromSelector(@selector(cancelDownload:)), @"downloadStatus", NSStringFromSelector(@selector(downloadStatus:)), @"bytesCompleted", NSStringFromSelector(@selector(bytesCompleted:)), @@ -103,36 +103,34 @@ static JSBridge *SharedInstance; return YES; } -- (BOOL)existsInCache:(NSString *)name +- (BOOL)registerDownload:(NSString *)key withURL:(NSString *)url filename:(NSString *)filename { // Disallow traversing directories; take only the last component - id path = [[@"~/Library/Application Support/OpenRA/Downloads/" stringByAppendingPathComponent:[name lastPathComponent]] stringByExpandingTildeInPath]; - return [[NSFileManager defaultManager] fileExistsAtPath:path]; -} - -- (void)downloadUrl:(NSString *)url withName:(NSString *)name key:(NSString *)key -{ - NSLog(@"downloadFile:%@ intoCacheWithName:%@ key:%@",url,name,key); - - // Disallow traversing directories; take only the last component - id path = [[@"~/Library/Application Support/OpenRA/Downloads/" stringByAppendingPathComponent:[name lastPathComponent]] stringByExpandingTildeInPath]; - [controller downloadUrl:url toFile:path withId:key]; -} - -- (void)cancelDownload:(NSString *)key -{ - [controller cancelDownload:key]; + id path = [[@"~/Library/Application Support/OpenRA/Downloads/" stringByAppendingPathComponent:[filename lastPathComponent]] stringByExpandingTildeInPath]; + return [controller registerDownload:key withURL:url filePath:path]; } - (NSString *)downloadStatus:(NSString *)key { Download *d = [controller downloadWithKey:key]; if (d == nil) - return @"Invalid"; + return @"NOT_REGISTERED"; return [d status]; } +- (BOOL)startDownload:(NSString *)key +{ + Download *d = [controller downloadWithKey:key]; + return (d == nil) ? NO : [d start]; +} + +- (BOOL)cancelDownload:(NSString *)key +{ + Download *d = [controller downloadWithKey:key]; + return (d == nil) ? NO : [d cancel]; +} + - (int)bytesCompleted:(NSString *)key { Download *d = [controller downloadWithKey:key]; diff --git a/mods/cnc/mod.html b/mods/cnc/mod.html index 875274d73a..d4384ebd68 100644 --- a/mods/cnc/mod.html +++ b/mods/cnc/mod.html @@ -102,9 +102,8 @@ function download() { - window.external.downloadToCache("http://localhost/~paul/cnc-packages.zip","cnc-packages.zip","cnc-packages"); - document.getElementById("install-download").style.display = "none"; - document.getElementById("install-downloading").style.display = ""; + window.external.startDownload("cnc-packages"); + refreshDownloadButtons(); } function cancel() @@ -120,8 +119,15 @@ } function onLoad() + { + refreshSections(); + } + + function refreshSections() { var installed = packagesInstalled(); + window.external.log("installed: "+installed); + document.getElementById("buttons-install").style.display = (installed == 0) ? "" : "none"; document.getElementById("buttons-upgrade").style.display = (installed == 1) ? "" : "none"; document.getElementById("buttons-play").style.display = (installed == 2) ? "" : "none"; @@ -130,10 +136,39 @@ // Select the correct subsection if (installed == 0) { - var downloaded = window.external.existsInCache("cnc-packages.zip"); - window.external.log("downloaded: "+downloaded); - document.getElementById("install-extract").style.display = downloaded ? "" : "none"; - document.getElementById("install-download").style.display = !downloaded ? "" : "none"; + window.external.registerDownload("cnc-packages", "http://localhost/~paul/cnc-packages.zip", "cnc-packages.zip"); + refreshDownloadButtons(); + } + } + + function refreshDownloadButtons() + { + document.getElementById("download-available").style.display = "none"; + document.getElementById("download-downloading").style.display = "none"; + document.getElementById("download-extract").style.display = "none"; + + // status can be NOT_REGISTERED, AVAILABLE, DOWNLOADING, COMPLETE, ERROR + var status = window.external.downloadStatus("cnc-packages"); + window.external.log("status: "+status); + + // 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") + { + document.getElementById("download-available").style.display = ""; + + // Todo: set error message } } @@ -142,29 +177,19 @@ if (file != "cnc-packages") return; - var status = window.external.downloadStatus(file); - if (status == "Complete") - { - document.getElementById("install-extract").style.display = ""; - document.getElementById("install-downloading").style.display = "none"; - } var total = window.external.bytesTotal(file); var downloaded = window.external.bytesCompleted(file); + window.external.log(file+" = total: "+total+" downloaded: "+downloaded); + + if (downloaded == -1) + return; - var multiplier = 1/1024.0; - var unit = "kB"; - - var max = max(total,downloaded); // total may be -1 if the server doesn't supply a size - if (max > 1.1*1024*1024) - { - multiplier /= 1024; - unit = "MB"; - } + var multiplier = 1/1048576.0; total = (total*multiplier).toPrecision(2); downloaded = (downloaded*multiplier).toPrecision(2); - document.getElementById("download-status").value = downloaded+"/"+total+" "+unit; - window.external.log("file: "+file+" "+downloaded+"/"+total+" ("+percent+"%)"); + document.getElementById("download-status").value = downloaded+"/"+total+" MB"; + refreshDownloadButtons(); } @@ -186,19 +211,19 @@ -
+