diff options
Diffstat (limited to 'src/neoRuntime')
-rw-r--r-- | src/neoRuntime/index.js | 232 |
1 files changed, 232 insertions, 0 deletions
diff --git a/src/neoRuntime/index.js b/src/neoRuntime/index.js new file mode 100644 index 0000000..d34f4b4 --- /dev/null +++ b/src/neoRuntime/index.js @@ -0,0 +1,232 @@ +let fs = require("fs-extra"); +let path = require("path"); +let compileRun = require("../compileAndRun"); + +let listDirsInDir = p => fs.readdirSync(p).filter(f => fs.statSync(path.join(p, f)).isDirectory()); + +class neoRuntime { + + constructor(dirUsrData) { + this._proc = undefined; + this._cScript = "None"; + this._cScriptHasExited = false; + this._dirUsrData = dirUsrData; + } + + status() { + return { + "currentScript": this._cScript, + "scriptIsExited": this._cScriptHasExited, + "uptime": process.uptime() + }; + } + + listScripts() { + let localScripts = listDirsInDir(this._dirUsrData + "/usrCode/"); + let remoteScripts = listDirsInDir(this._dirUsrData + "/remoteCode/"); + let scriptList = []; + + for (let i = 0; i < localScripts.length; i++) { + if (fs.existsSync(this._dirUsrData + "/usrCode/" + localScripts[i] + "/script.py")) { + scriptList.push({ + "name": localScripts[i], + "loc": "local", + "path": "local/" + localScripts[i], + "lang": "python" + }); + } + } + + for (let i = 0; i < remoteScripts.length; i++) { + if (fs.existsSync(this._dirUsrData + "/remoteCode/" + remoteScripts[i] + "/script.py")) { + scriptList.push({ + "name": remoteScripts[i], + "loc": "remote", + "path": "remote/" + remoteScripts[i], + "lang": "python" + }); + } + } + + return scriptList; + } + + selectScript(path) { + global.log(`Selecting script \"${path}\"`, "event"); + + try { + this._proc.stop(); + } catch (err) { + global.log("Could not kill process: " + err, "error"); + } + + this._cScript = path; + path = path.split("/"); + let location = path.splice(0, 1).toString(); + if (location === "local") { path = this._dirUsrData + "/usrCode/" + path.join("/"); } + if (location === "remote") { path = this._dirUsrData + "/remoteCode/" + path.join("/"); } + //if (location === "base") { path = this._dirUsrData + "/src/compileAndRun/scripts/" + path.join("/"); } // TODO make this do something + + if (!fs.existsSync(path + "/script.py")) { + global.log(`No script file found when selecting script with real path \"${path}\"`, "ERROR"); + return; + } + + fs.removeSync(path + "/build/logs/log"); + + this._cScriptHasExited = false; + this._proc = new compileRun.Python(path, this._dirUsrData); + this._proc.compileAndRun(); + + fs.ensureFileSync(path + "/build/logs/log"); + this._proc.on("stdout::data", (_stdout) => { + fs.appendFile(path + "/build/logs/log", "\n====stdout====\n" + _stdout.toString().replace(/\n$/, "")); + }); + this._proc.on("stderr::data", (_stderr) => { + fs.appendFile(path + "/build/logs/log", "\n====stderr====\n" + _stderr.toString().replace(/\n$/, "")); + }); + this._proc.on("stderr::end", () => { + fs.appendFile(path + "/build/logs/log", "\n"); + }); + this._proc.on("stdout::end", () => { + fs.appendFile(path + "/build/logs/log", "\n"); + }); + this._proc.on("close", (_code) => { + fs.appendFile(path + "/build/logs/log","\n====close====\nScript exited with code " + _code.toString()); + this._cScriptHasExited = true; + }); + + } + + stopScript() { + try { + this._proc.stop(); + return { + success: true + } + } catch (err) { + return { + success: false, + error: {reason: err} + }; + } + } + + deleteScript(path) { + global.log(`Deleting script \"${path}\"`, "DEBUG"); + + let sPath = path.split("/"); + let location = sPath.splice(0, 1).toString(); + if (location === "remote") { + global.log(`Cannot delete remote script ${path}`, "DEBUG"); + return; + } + let absPath = this._dirUsrData + "/usrCode/" + sPath.join("/"); + + if (this._cScriptPath == path) { + try { + this._proc.stop(); + } catch (err) { + global.log("Could not kill process: " + err, "error"); + } + } + + fs.removeSync(absPath); + + } + + createEmptyScript(name) { + global.log(`Creating script with name \"${name}/"`, "DEBUG"); + + let scriptFolderPath = this._dirUsrData + "/usrCode/" + name; + if (fs.existsSync(scriptFolderPath)) { + global.log(`A Script with the name \"${name}\" already exists`, "ERROR"); + return; + } + + fs.ensureDirSync(scriptFolderPath); + fs.writeFile(scriptFolderPath + "/script.py", + "import LuxcenaNeo as neo # Can be imported as LuxcenaNeo as well. but anything else and it will fail...\n\nclass Main(neo.NeoBehaviour):\n\n def onStart(self):\n print (\"Script started\")\n\n def eachSecond(self):\n print (\"A second has passed\")", + (err) => { + if (err) { + global.log("Could not create script.py for profile \"" + name + "\"", "ERROR"); + } else { + global.log("Script \"" + name + "\" created.", "SUCCESS"); + } + } + ); + + } + + getScript(scriptPath) { + let sPath = scriptPath.split("/"); + let location = sPath.splice(0, 1).toString(); + if (location === "remote") { + global.log(`Cannot edit remote script ${path}`, "DEBUG"); + return; + } + let absPath = this._dirUsrData + "/usrCode/" + sPath.join("/"); + + if (!fs.existsSync(absPath + "/script.py")) { + return false; + } + + return { + name : sPath[sPath.length - 1], + files : { + main : fs.readFileSync(absPath + "/script.py", "utf8") + } + }; + } + + saveScript(script, callback) { + if (!fs.existsSync(this._dirUsrData + "/usrCode/" + script.name )) { + callback({success: false, error: {reason: "Script file not found"}}); + } + fs.writeFile(this._dirUsrData + "/usrCode/" + script.name + "/script.py", script.files.main, (err) => { + if (err) { + callback({success: false, error: {reason: err}}); + } else { + callback({success: true}); + } + }); + } + + getScriptOutput(scriptPath) { + if (scriptPath != this._cScript) { + return { + success: false, + error: {reason: "This is not the current running script"} + } + } + + let path = scriptPath.split("/"); + let location = path.splice(0, 1).toString(); + if (location === "local") { path = this._dirUsrData + "/usrCode/" + path.join("/"); } + if (location === "remote") { path = this._dirUsrData + "/remoteCode/" + path.join("/"); } + + if (!fs.existsSync(path + "/build/logs/log")){ + return { + success: false, + error: {reason: "No log file found"} + } + } + + try { + let output = fs.readFileSync(path + "/build/logs/log", "utf8"); + return { + success: true, + output: output + } + } catch (err) { + return { + success: false, + error: {reason: err} + }; + } + } +} + +module.exports = (dirUsrData) => { + return new neoRuntime(dirUsrData); +}; |