Expose the package downloading to js. Todo: cancel support, status callbacks.

This commit is contained in:
Paul Chote
2010-11-19 11:17:47 +13:00
parent cb93955cc5
commit c3521a2490
6 changed files with 83 additions and 18 deletions

View File

@@ -26,5 +26,5 @@
- (void)populateModInfo; - (void)populateModInfo;
- (SidebarEntry *)sidebarModsTree; - (SidebarEntry *)sidebarModsTree;
- (SidebarEntry *)sidebarOtherTree; - (SidebarEntry *)sidebarOtherTree;
- (BOOL)downloadUrl:(NSString *)url intoCache:(NSString *)filename withId:(NSString *)key;
@end @end

View File

@@ -90,6 +90,12 @@
[game launchMod:mod]; [game launchMod:mod];
} }
- (BOOL)downloadUrl:(NSString *)url intoCache:(NSString *)filename withId:(NSString *)key
{
id path = [[@"~/Library/Application Support/OpenRA/Downloads/" stringByAppendingPathComponent:filename] stringByExpandingTildeInPath];
return [game downloadUrl:url toPath:path withId:key];
}
#pragma mark Sidebar Datasource and Delegate #pragma mark Sidebar Datasource and Delegate
- (int)outlineView:(NSOutlineView *)anOutlineView numberOfChildrenOfItem:(id)item - (int)outlineView:(NSOutlineView *)anOutlineView numberOfChildrenOfItem:(id)item
{ {

View File

@@ -11,13 +11,14 @@
@class Mod; @class Mod;
@interface GameInstall : NSObject { @interface GameInstall : NSObject {
NSURL *gameURL; NSURL *gameURL;
NSMutableDictionary *downloadTasks;
} }
@property(readonly) NSURL *gameURL; @property(readonly) NSURL *gameURL;
-(id)initWithURL:(NSURL *)path; -(id)initWithURL:(NSURL *)path;
-(void)launchMod:(NSString *)mod; -(void)launchMod:(NSString *)mod;
- (NSString *)runUtilityQuery:(NSString *)arg; - (NSString *)runUtilityQuery:(NSString *)arg;
- (void)runUtilityQuery:(NSString *)arg handleOutput:(id)obj withMethod:(SEL)sel;
- (NSArray *)installedMods; - (NSArray *)installedMods;
- (NSDictionary *)infoForMods:(NSArray *)mods; - (NSDictionary *)infoForMods:(NSArray *)mods;
- (BOOL)downloadUrl:(NSString *)url toPath:(NSString *)filename withId:(NSString *)key;
@end @end

View File

@@ -18,6 +18,7 @@
if (self != nil) if (self != nil)
{ {
gameURL = [url retain]; gameURL = [url retain];
downloadTasks = [[NSMutableDictionary alloc] init];
} }
return self; return self;
} }
@@ -25,6 +26,7 @@
- (void)dealloc - (void)dealloc
{ {
[gameURL release]; gameURL = nil; [gameURL release]; gameURL = nil;
[downloadTasks release]; downloadTasks = nil;
[super dealloc]; [super dealloc];
} }
@@ -142,26 +144,71 @@
} }
- (void)runUtilityQuery:(NSString *)arg handleOutput:(id)obj withMethod:(SEL)sel - (BOOL)downloadUrl:(NSString *)url toPath:(NSString *)filename withId:(NSString *)key
{ {
NSTask *aTask = [[NSTask alloc] init]; NSLog(@"Starting download...");
NSPipe *aPipe = [NSPipe pipe]; if ([downloadTasks objectForKey:key] != nil)
NSFileHandle *readHandle = [aPipe fileHandleForReading]; {
NSLog(@"Error: a download is already in progress for %@",key);
return NO;
}
NSTask *task = [[[NSTask alloc] init] autorelease];
NSPipe *pipe = [NSPipe pipe];
NSMutableArray *taskArgs = [NSMutableArray arrayWithObject:@"OpenRA.Utility.exe"]; NSMutableArray *taskArgs = [NSMutableArray arrayWithObject:@"OpenRA.Utility.exe"];
NSString *arg = [NSString stringWithFormat:@"--download-url=%@,%@",url,filename];
[taskArgs addObject:arg]; [taskArgs addObject:arg];
[aTask setCurrentDirectoryPath:[gameURL absoluteString]]; [task setCurrentDirectoryPath:[gameURL absoluteString]];
[aTask setLaunchPath:@"/Library/Frameworks/Mono.framework/Commands/mono"]; [task setLaunchPath:@"/Library/Frameworks/Mono.framework/Commands/mono"];
[aTask setArguments:taskArgs]; [task setArguments:taskArgs];
[aTask setStandardOutput:aPipe]; [task setStandardOutput:pipe];
[aTask launch];
NSData *inData = nil; NSFileHandle *readHandle = [pipe fileHandleForReading];
while ((inData = [readHandle availableData]) && [inData length]) NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[obj performSelector:sel withObject:[NSString stringWithUTF8String:[inData bytes]]]; [nc addObserver:self
[aTask waitUntilExit]; selector:@selector(utilityResponded:)
[aTask release]; name:NSFileHandleReadCompletionNotification
object:readHandle];
[nc addObserver:self
selector:@selector(utilityTerminated:)
name:NSTaskDidTerminateNotification
object:task];
[task launch];
[readHandle readInBackgroundAndNotify];
[downloadTasks setObject:task forKey:key];
return YES;
} }
- (void)utilityResponded:(NSNotification *)n
{
NSData *data = [[n userInfo] valueForKey:NSFileHandleNotificationDataItem];
NSString *response = [[[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding] autorelease];
NSLog(@"r: %@",response);
// Keep reading
if ([n object] != nil)
[[n object] readInBackgroundAndNotify];
}
- (void)utilityTerminated:(NSNotification *)n
{
id task = [n object];
id pipe = [task standardOutput];
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc removeObserver:self name:NSFileHandleReadCompletionNotification object:[pipe fileHandleForReading]];
[nc removeObserver:self name:NSTaskDidTerminateNotification object:task];
}
- (void)cancelDownload:(NSString *)key
{
id task = [downloadTasks objectForKey:key];
if (task == nil)
return;
[task interrupt];
}
@end @end

View File

@@ -40,7 +40,9 @@ static JSBridge *SharedInstance;
methods = [[NSDictionary dictionaryWithObjectsAndKeys: methods = [[NSDictionary dictionaryWithObjectsAndKeys:
@"launchMod", NSStringFromSelector(@selector(launchMod:)), @"launchMod", NSStringFromSelector(@selector(launchMod:)),
@"log", NSStringFromSelector(@selector(log:)), @"log", NSStringFromSelector(@selector(log:)),
@"installCncPackagesFromWeb", NSStringFromSelector(@selector(installCncPackagesFromWeb)),
@"fileExistsInMod", NSStringFromSelector(@selector(fileExists:inMod:)), @"fileExistsInMod", NSStringFromSelector(@selector(fileExists:inMod:)),
@"downloadFileToCache",NSStringFromSelector(@selector(downloadFile:intoCacheWithName:id:)),
nil] retain]; nil] retain];
} }
return self; return self;
@@ -87,6 +89,13 @@ static JSBridge *SharedInstance;
return YES; return YES;
} }
- (void)downloadFile:(NSString *)url intoCacheWithName:(NSString *)name id:(NSString *)did
{
NSLog(@"downloadFile:%@ intoCacheWithName:%@ id:%@",url,name,did);
// Disallow traversing directories; take only the last component
[controller downloadUrl:url intoCache:[name lastPathComponent] withId:did];
}
- (void)log:(NSString *)message - (void)log:(NSString *)message
{ {
NSLog(@"js: %@",message); NSLog(@"js: %@",message);

View File

@@ -78,7 +78,8 @@
.button:hover .button:hover
{ {
background-color: #333; border-color:#fff;
background-color:#650b03;
cursor:pointer; cursor:pointer;
} }
@@ -107,7 +108,8 @@
function installFromWeb() function installFromWeb()
{ {
window.external.log("installFromWeb()"); window.external.downloadFileToCache("http://www.open-ra.org/get-dependency.php?file=cnc-packages","test.zip","cnc-packages");
//window.external.installCncPackagesFromWeb();
} }
function onLoad() function onLoad()