UNPKG

droidscript-cli

Version:

DroidScript command line utility

264 lines (230 loc) 6.66 kB
/* * Based on the work of Dave Smart, https://plus.google.com/u/0/102457040597863456686 * */ import WebSocket = require("ws"); import path = require("path"); import fetch from "node-fetch"; import { opts, CommandLineOptions, generateHelp } from "./options"; let ws: WebSocket; let base = "192.168.0.7:8088"; interface Info { status: string; lastprog: string; appname: string; usepass: boolean; devicename: string; macaddress: string; premium: boolean; language: string; } async function cmd(args: {[key: string]:string|number}) { const packed = Object.keys(args).map(key=>`${key}=${encodeURIComponent(`${args[key]}`)}`).join("&"); const url = `http://${base}/ide?${packed}`; const response = await fetch(url); return response.text(); } /* test(); async function test() { console.log(await GetInfo()); console.log(await stopProgram()); console.log(await runProgram("gps-droid-firebase")); StartDebug(); } */ // run the specified program async function runProgram(prog: string) { const response = await cmd({ cmd: "run", prog: prog }); return; } // stop the currently running program async function stopProgram() { const response = JSON.parse(await cmd({ cmd: "stop" })); console.log("stopped"); return; } // get useful info from phone. async function GetInfo() { const response = JSON.parse(await cmd({cmd: "getinfo"})) as Info; return response; } /* //Add a new program to IDE. function AddProgram( type ) { //Get program title from text box. var name = txtAdd.value; //Send 'Add' command to phone. xmlHttp = new XMLHttpRequest(); xmlHttp.onload = function() { alert(xmlHttp.responseText); }; if( type=="html" ) xmlHttp.open( "get", "http://192.168.1.121:8088/ide?cmd=add&prog="+name+"&type=html", true ); else xmlHttp.open( "get", "http://192.168.1.121:8088/ide?cmd=add&prog="+name, true ); xmlHttp.send(); } //Rename a file (or folder). //eg. img/mypic.png -> img/mypic2.png //eg. myprog.js -> myprog2.js function RenameFile() { //Get old and new name from text box. var file = txtOld.value; var newname = txtNew.value; //Send 'Rename' command to phone. xmlHttp = new XMLHttpRequest(); xmlHttp.onload = function() { alert(xmlHttp.responseText); }; xmlHttp.open( "get", "http://192.168.1.121:8088/ide?cmd=rename&file="+file+"&newname="+newname, true ); xmlHttp.send(); } //Delete a file. //eg. img/mypic.png //Note: '..' in file name is not allowed! function DeleteFile() { //Get name from text box. var file = txtFile.value; //Send 'Delete' command to phone. xmlHttp = new XMLHttpRequest(); xmlHttp.onload = function() { alert(xmlHttp.responseText); }; xmlHttp.open( "get", "http://192.168.1.121:8088/ide?cmd=delete&file="+file, true ); xmlHttp.send(); } //List asset files in given subfolder. function ListFiles( subdir ) { xmlHttp = new XMLHttpRequest(); //if( subdir=="img" ) xmlHttp.onload = ShowFiles; //else xmlHttp.onload = function() { alert( xmlHttp.responseText ); } xmlHttp.open( "get", "http://192.168.1.121:8088/ide?cmd=list&dir=" + subdir, true ); xmlHttp.send(); } //Show listed files in browser. function ShowFiles() { var html = ""; var files = JSON.parse(xmlHttp.responseText).list; //alert( files ); for( i=0; i<files.length; i++ ) { html += "<img width=64 src=\"http://192.168.1.121:8088/img/"+files[i]+"\">"; } divImg.innerHTML = html; } //Get a file/asset from phone. //(Only assets or paths below /sdcard/AndroidScript/ are allowed) function GetFile( file ) { xmlHttp = new XMLHttpRequest(); xmlHttp.onload = function() { alert( JSON.parse(xmlHttp.responseText).file ); }; xmlHttp.open( "get", "http://192.168.1.121:8088/ide?cmd=get&file="+file, true ); xmlHttp.send(); } //Get a list of all samples. function GetSamples() { xmlHttp = new XMLHttpRequest(); xmlHttp.onload = function() { alert( xmlHttp.responseText ); }; xmlHttp.open( "get", "http://192.168.1.121:8088/ide?cmd=getsamples", true ); xmlHttp.send(); } */ // connect to debug output via web sockets. function StartDebug() { ws = new WebSocket(`ws://${base}`, { perMessageDeflate: false }); ws.on("open", () => { ws.send("debug", err => { if(!err) { console.log("debugger connected"); } else { console.log("can't connect"); } }); }); ws.on("message", data => { console.log(data); }); ws.on("close", () => { console.log("debugger disconnected"); }); ws.on("error", e => { console.error(e); }); } main(process.argv); async function main(argv: string[]) { let options: CommandLineOptions; try { options = opts(argv); } catch(ex) { console.log(ex.message); return -1; } const noRequiredOptions = ( options.run === undefined && options.debug === undefined && options.info === undefined && options.stop === undefined ); if(options.help || noRequiredOptions) { console.log(argv.length); console.log(generateHelp()); process.exit(0); } if(options.host) { base = options.host; } else { const env = process.env["DROIDSCRIPT_HOST"]; if(env !== undefined) { base = env; } else { console.log("Specify the host address with --host or with the DROIDSCRIPT_HOST environment variable."); process.exit(0); } } if(options.info) { try { const info = await GetInfo(); console.log("DroidScript OK!"); Object.keys(info).forEach(k => { console.log(`${k}: ${(info as any)[k]}`); }) //process.exit(0); } catch(err) { console.error(`Can't connect to DroidScript at ${base}:`); if(err.code === "ECONNREFUSED") { err = "Connection refused."; } console.error(err); process.exit(0); } } if(options.debug) { StartDebug(); } if(options.run !== undefined) { let programName: string; if(options.program !== undefined) { programName = options.program; } else { const info = await GetInfo(); programName = info.lastprog; } await runProgram(programName); if(!options.debug) { process.exit(0); } else { process.stdin.setRawMode!(true); process.stdin.resume(); process.stdin.on('data', async ()=>{ await stopProgram(); process.exit(0); }); } } if(options.stop) { await stopProgram(); } }