Skip to content
This repository has been archived by the owner on Apr 24, 2021. It is now read-only.

Commit

Permalink
Implemented run python script
Browse files Browse the repository at this point in the history
  • Loading branch information
dinhvh committed Aug 5, 2014
1 parent 84dbbcf commit 5f26bed
Show file tree
Hide file tree
Showing 6 changed files with 4,999 additions and 0 deletions.
97 changes: 97 additions & 0 deletions ide/app/lib/wam/wamfs.dart
@@ -0,0 +1,97 @@
// Copyright (c) 2014, Google Inc. Please see the AUTHORS file for details.
// All rights reserved. Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

library spark.wamfs;

import 'dart:async';
import 'dart:js' as js;
import 'dart:typed_data';

class WAMFS {

// Javascript object to wrap.
js.JsObject _jsWAMFS;

WAMFS() {
_jsWAMFS = new js.JsObject(js.context['WAMFS'], []);
}

Future connect(String extensionID, String mountPath) {
Completer completer = new Completer();
Function callback = () {
completer.complete();
};
Function errorHandler = (error) {
completer.completeError(error);
};
_jsWAMFS.callMethod('connect', [extensionID, mountPath, callback, errorHandler]);
return completer.future;
}

Future copyFile(String source, String destination) {
Completer completer = new Completer();
Function callback = () {
completer.complete();
};
Function errorHandler = (error) {
completer.completeError(error);
};
_jsWAMFS.callMethod('copyFile', [source, destination, callback,
errorHandler]);
return completer.future;
}

Future<Uint8List> readFile(String filename) {
Completer completer = new Completer();
Function callback = (data) {
completer.complete(data);
};
Function errorHandler = (error) {
completer.completeError(error);
};
_jsWAMFS.callMethod('readFile', [callback, errorHandler]);
return completer.future;
}

Future writeDataToFile(String filename, Uint8List content) {
Completer completer = new Completer();
Function callback = () {
completer.complete();
};
Function errorHandler = (error) {
completer.completeError(error);
};
_jsWAMFS.callMethod('writeDataToFile', [filename, content, callback,
errorHandler]);
return completer.future;
}

Future writeStringToFile(String filename, String content) {
Completer completer = new Completer();
Function callback = () {
completer.complete();
};
Function errorHandler = (error) {
completer.completeError(error);
};
_jsWAMFS.callMethod('writeStringToFile', [filename, content, callback,
errorHandler]);
return completer.future;
}

Future executeCommand(String executablePath, List<String> parameters,
void printStdout(String string), void printStderr(String string)) {
Completer completer = new Completer();
Function callback = () {
completer.complete();
};
Function errorHandler = (error) {
completer.completeError(error);
};
_jsWAMFS.callMethod('executeCommand', [executablePath,
new js.JsObject.jsify(parameters), printStdout, printStderr, callback,
errorHandler]);
return completer.future;
}
}
141 changes: 141 additions & 0 deletions ide/app/lib/wam/wamfs.js
@@ -0,0 +1,141 @@
'use strict';

var WAMFS = function() {
// Our in-memory wam-ready file system.
this.jsfs = new wam.jsfs.FileSystem();
}

WAMFS.prototype.connect = function(extensionID, mountPath, onSuccess, onError) {
// Reflect our DOM file system into the wam file system.
this.jsfs.makeEntry('/domfs', new wam.jsfs.dom.FileSystem(),
function() {
this._mount(extensionID, mountPath, onSuccess, onError)
}.bind(this),
function(e) {
onError(e);
});
};

WAMFS.prototype._mount = function(id, path, onSuccess, onError) {
// wam remote file system object.
var rfs = null;

// Called when the remote file system becomes ready.
var onFileSystemReady = function() {
// Now that it's ready we can remove our initial listeners. These
// were only intended to cover the initial ready or close-with-error
// conditions. A longer term onClose listener should be installed to
// check for unexpected loss of the file system.
rfs.onReady.removeListener(onFileSystemReady);
rfs.onClose.removeListener(onFileSystemClose);

// Link the remote file system into our root file system under the given
// path.
this.jsfs.makeEntry(path, rfs, function() {
onSuccess();
}, function(value) {
transport.disconnect();
onError(value);
});
}.bind(this);

// Called when the remote file system gets closed.
var onFileSystemClose = function(value) {
rfs.onReady.removeListener(onFileSystemReady);
rfs.onClose.removeListener(onFileSystemClose);

onError(value);
};

// Connection failed at the transport level. The target app probably isn't
// installed or isn't willing to acknowledge us.
var onTransportClose = function(reason, value) {
transport.readyBinding.onClose.removeListener(onTransportClose);
transport.readyBinding.onReady.removeListener(onTransportReady);

onError(wam.mkerr('wam.FileSystem.Error.RuntimeError',
['Transport connection failed.']));
return;
};

// The target app accepted our connection request, now we've got to negotiate
// a wam channel.
var onTransportReady = function(reason, value) {
transport.readyBinding.onClose.removeListener(onTransportClose);
transport.readyBinding.onReady.removeListener(onTransportReady);

var channel = new wam.Channel(transport, 'crx:' + id);
// Uncomment the next line for verbose logging.
// channel.verbose = wam.Channel.verbosity.ALL;
rfs = new wam.jsfs.RemoteFileSystem(channel);
rfs.onReady.addListener(onFileSystemReady);
rfs.onClose.addListener(onFileSystemClose);
};

// Create a new chrome.runtime.connect based transport.
var transport = new wam.transport.ChromePort();

// Register our close and ready handlers.
transport.readyBinding.onClose.addListener(onTransportClose);
transport.readyBinding.onReady.addListener(onTransportReady);

// Connect to the target extension/app id.
transport.connect(id);
};

WAMFS.prototype.copyFile = function(source, destination, onSuccess, onError) {
var executeContext = this.jsfs.defaultBinding.createExecuteContext();
executeContext.copyFile(source, destination,
function() {
onSuccess();
}, function(e) {
onError(e);
});
};

WAMFS.prototype.readFile = function(filename, onSuccess, onError) {
var executeContext = this.jsfs.defaultBinding.createExecuteContext();
executeContext.readFile(filename,
function() {
onSuccess();
}, function(e) {
onError(e);
});
};

WAMFS.prototype.writeDataToFile = function(filename, content, onSuccess, onError) {
this.jsfs.defaultBinding.writeFile(filename,
{mode: {create: true}},
{dataType: 'arraybuffer', data: content},
function() {
onSuccess();
}, function(e) {
onError();
});
};

WAMFS.prototype.writeStringToFile = function(filename, stringContent, onSuccess, onError) {
this.jsfs.defaultBinding.writeFile(filename,
{mode: {create: true}},
{dataType: 'utf8-string', data: stringContent},
function() {
onSuccess();
}, function(e) {
onError(e);
});
};

WAMFS.prototype.executeCommand = function(executablePath, parameters,
printStdout, printStderr, onSuccess, onError) {
var executeContext = this.jsfs.defaultBinding.createExecuteContext();
executeContext.onStdOut.addListener(function(l) {
printStdout(l);
});
executeContext.onStdErr.addListener(function(l) {
printStderr(l);
});
executeContext.onClose.addListener(function() {
onSuccess();
});
executeContext.execute(executablePath, parameters);
}
37 changes: 37 additions & 0 deletions ide/app/spark.dart
Expand Up @@ -53,6 +53,7 @@ import 'lib/webstore_client.dart';
import 'lib/workspace.dart' as ws;
import 'lib/workspace_utils.dart' as ws_utils;
import 'test/all.dart' as all_tests;
import 'lib/wam/wamfs.dart';

import 'spark_flags.dart';
import 'spark_model.dart';
Expand Down Expand Up @@ -527,6 +528,7 @@ abstract class Spark
actionManager.registerAction(new SendFeedbackAction(this));
actionManager.registerAction(new ShowSearchView(this));
actionManager.registerAction(new ShowFilesView(this));
actionManager.registerAction(new RunPythonAction(this));

actionManager.registerKeyListener();

Expand Down Expand Up @@ -3948,6 +3950,41 @@ class ShowFilesView extends SparkAction {
}
}

class RunPythonAction extends SparkAction {
WAMFS _fs;
bool _connected;

RunPythonAction(Spark spark) : super(spark, 'run-python', 'Run Python') {
_fs = new WAMFS();
}

Future _connect() {
if (_connected) return new Future.value();
return _fs.connect('bjffolomlcjmflonfneaijabbpnflija', '/saltpig').then((_) {
_connected = true;
});
}

void _invoke([context]) {
List<ws.Resource> selection = spark._getSelection();
if (selection.length == 0) return;
ws.File file = selection.first;
file.getContents().then((content) {
return _connect().then((_) {
return _fs.writeStringToFile('/saltpig/domfs/foo.py', content).then((_) {
_fs.executeCommand('/saltpig/exe/python', ['/mnt/html5/foo.py'],
(String string) {
print('stdout: ${string}');
}, (String string) {
print('stderr: ${string}');
});
});
});
});
}

}

// Analytics code.

void _handleUncaughtException(error, [StackTrace stackTrace]) {
Expand Down
2 changes: 2 additions & 0 deletions ide/app/spark_polymer.html
Expand Up @@ -146,6 +146,8 @@

<script type="application/javascript" src="third_party/uuid.js/uuid.js"></script>
<script type="application/javascript" src="lib/mobile/android_rsa.js"></script>
<script type="application/javascript" src="third_party/wam/wam_fs.concat.js"></script>
<script type="application/javascript" src="lib/wam/wamfs.js"></script>

<!-- Start Spark in a deployed build. -->
<script type="application/dart" src="spark_polymer.dart"></script>
Expand Down
2 changes: 2 additions & 0 deletions ide/app/spark_polymer_ui.html
Expand Up @@ -108,6 +108,8 @@
<spark-menu-separator></spark-menu-separator>
<spark-menu-item action-id="run-tests" label="Run Tests">
</spark-menu-item>
<spark-menu-item action-id="run-python" label="Run Python">
</spark-menu-item>
</template>

<spark-menu-separator></spark-menu-separator>
Expand Down

0 comments on commit 5f26bed

Please sign in to comment.