[VI]Version: {version} - built on {date}[/VI] Your local downloads for this instance |
// console.dir(args[2]) | // console.dir(args[2]) | ||||
console.log('nodeshellexec ::: ') | console.log('nodeshellexec ::: ') | ||||
console.log(`${args[0]} ${args[1].join(' ') }`) | |||||
console.log(`${args[0]} ${args[1].join(' ') } ${args[args.length-1].cwd}`) | |||||
const child = spawn(...args); | const child = spawn(...args); | ||||
var p = new Promise(function(resolve, reject){ | var p = new Promise(function(resolve, reject){ | ||||
process.stdout.write( chunk ) | process.stdout.write( chunk ) | ||||
}); | }); | ||||
child.on('error', (chunk) => { success = false; messages.push(chunk); /* console.error('e: ' + chunk) */ | child.on('error', (chunk) => { success = false; messages.push(chunk); /* console.error('e: ' + chunk) */ | ||||
console.log('Error exit not handled.') | |||||
} ); | |||||
console.error('Error exit not handled.') | |||||
}); | |||||
child.stderr.on('data', (chunk) => { | child.stderr.on('data', (chunk) => { | ||||
if(messages.join('').indexOf('fatal: not a git repository') > -1) opts.haserrors = true; | if(messages.join('').indexOf('fatal: not a git repository') > -1) opts.haserrors = true; | ||||
messages.push(chunk); | messages.push(chunk); |
// }).then(Tasq.then).catch(Tasq.catch) | // }).then(Tasq.then).catch(Tasq.catch) | ||||
// }) | // }) | ||||
var bowerRepos = [{ repo : 'client'}]; | |||||
var bowerRepos = [{ repo : 'elixir-client'}]; | |||||
var bowertasks = []; | var bowertasks = []; | ||||
bowerRepos.forEach(repodef => { | bowerRepos.forEach(repodef => { | ||||
bowertasks.push(() => { | bowertasks.push(() => { |
// }).then(Tasq.then).catch(Tasq.catch) | // }).then(Tasq.then).catch(Tasq.catch) | ||||
// }) | // }) | ||||
var bowerRepos = [{ repo : 'client'}]; | |||||
var bowerRepos = [{ repo : 'elixir-client'}]; | |||||
var bowertasks = []; | var bowertasks = []; | ||||
bowerRepos.forEach(repodef => { | bowerRepos.forEach(repodef => { | ||||
bowertasks.push(() => { | bowertasks.push(() => { |
// models\api\v1 | |||||
const fs = require('fs') | |||||
var path = require('path'); | |||||
const { readdir } = require("fs").promises | |||||
var verse = require('../serververse'); | |||||
const fswalk = verse.fs.walk | |||||
var path = require('path'); | |||||
const Rx = require('rxjs'); | |||||
const cliargs = verse.cliargs; | |||||
const processedArgs = cliargs(process.argv.slice(2)); | |||||
// console.dir(processedArgs) | |||||
// console.dir(Rx) | |||||
// https://github.com/coolaj86/node-walk | |||||
// PB : TODO -- convert to an input json config. | |||||
var outputfile = processedArgs._[0]; // ../elixir-client/physio/linkclient.bat | |||||
var startdir = processedArgs._[1]; // ../elixir-client/physio-1/app/models/api/v1 | |||||
var inprefix = processedArgs._[2]; // '../../../../../elixir-client/client/' | |||||
if(!inprefix) inprefix = '..\\client\\' | |||||
var unprefix = processedArgs._[3]; // ../elixir-client/physio-1/ | |||||
if(!unprefix) unprefix = '../elixir-client/physio-1/' | |||||
var outprefix = processedArgs._[4]; // '../../../../../elixir-client/physio/' | |||||
if(!outprefix) outprefix = '' | |||||
var fswalkoptions = {} // all files recurscively | |||||
// var fswalkoptions = { includerootdir : true, includedirectories : true, expand : true } // example walk and output everything. | |||||
// (unprefix, outprefix) | |||||
// console.log(path.normalize(unprefix)) | |||||
const writeStream = ( fs.createWriteStream(outputfile) ) | |||||
fswalk.call( fswalkoptions, startdir ).then( s => { | |||||
s.subscribe( entry => { | |||||
// var matches = /.*?data.*/.exec(utils.fs.direntToFullname(entry)) | |||||
// if(matches) console.dir( matches[0] ) // Filters can be done on the stream itself.. | |||||
var i = entry | |||||
var pathnodes = i.path.replace( path.normalize(unprefix), '' ).split('\\') | |||||
var relative = Array(pathnodes.length) | |||||
writeStream.write( '\nmklink ' + (entry.isDirectory() ? ' /D ' : ' ') + i.path.replace( path.normalize(unprefix), outprefix ) + ' ' | |||||
+ relative.join('..\\') + inprefix + i.path.replace( path.normalize(unprefix), outprefix ) | |||||
) | |||||
// console.dir( entry ) | |||||
} | |||||
) | |||||
// ; s.unsubscribe() | |||||
}) |
p_round: p_round, | p_round: p_round, | ||||
g_round: g_round, | g_round: g_round, | ||||
escapeRegExp(string) { | escapeRegExp(string) { | ||||
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string | |||||
return string.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'); // $& means the whole matched string | |||||
} | } | ||||
, getTZOffsetMilliseconds : (()=>{ | , getTZOffsetMilliseconds : (()=>{ | ||||
// }).then(Tasq.then).catch(Tasq.catch) | // }).then(Tasq.then).catch(Tasq.catch) | ||||
// }) | // }) | ||||
var bowerRepos = [{ repo : 'client'}]; | |||||
var bowerRepos = [{ repo : 'elixir-client'}]; | |||||
var bowertasks = []; | var bowertasks = []; | ||||
bowerRepos.forEach(repodef => { | bowerRepos.forEach(repodef => { | ||||
bowertasks.push(() => { | bowertasks.push(() => { |
var downloadtasks = []; | var downloadtasks = []; | ||||
var installtasks = []; | var installtasks = []; | ||||
// var prereqfilter = ['nvm'] | |||||
var prereqfilter = ['*'] | |||||
prerequisites.forEach(function(preq) { | prerequisites.forEach(function(preq) { | ||||
WScript.Echo(all) | |||||
if(!all && preq.optional) return | |||||
var p = preq.exists().then(function(exists) { | |||||
if (exists && !preq.forceinstall) console.log( preq.shellcmd + ' exists'); | |||||
else { | |||||
console.log('----------------------------') | |||||
console.log(exists) // PB : ??? Boolean true becomes -1 ??? | |||||
console.log('----------------------------') | |||||
if(!exists) console.log(preq.shellcmd + ' is not installed'); | |||||
else console.log(preq.shellcmd + ' is installed but forceinstall was specifed so re-installing'); | |||||
return preq.preinstallsteps().then(function(){ | |||||
// console.log(' task.install : ' + preq.install) | |||||
installtasks.push( function(){ return preq.install() } ); | |||||
// WScript.Echo('FFFFFFFFFFFFF : ' + preq.shellcmd) | |||||
for(var p=0; p < prereqfilter.length; p++) { | |||||
if( preq.shellcmd === prereqfilter[p] || prereqfilter[p] === '*' ) { | |||||
WScript.Echo(all) | |||||
if(!all && preq.optional) return | |||||
var p = preq.exists().then(function(exists) { | |||||
if (exists && !preq.forceinstall) console.log( preq.shellcmd + ' exists'); | |||||
else { | |||||
console.log('----------------------------') | |||||
console.log(exists) // PB : ??? Boolean true becomes -1 ??? | |||||
console.log('----------------------------') | |||||
if(!exists) console.log(preq.shellcmd + ' is not installed'); | |||||
else console.log(preq.shellcmd + ' is installed but forceinstall was specifed so re-installing'); | |||||
return preq.preinstallsteps().then(function(){ | |||||
// console.log(' task.install : ' + preq.install) | |||||
installtasks.push( function(){ return preq.install() } ); | |||||
}) | |||||
} | |||||
}) | }) | ||||
// .then(function(res){ console.log( 'preinstallsteps ' + res)}); | |||||
downloadtasks.push( p ) | |||||
} | } | ||||
}) | |||||
// .then(function(res){ console.log( 'preinstallsteps ' + res)}); | |||||
downloadtasks.push( p ) | |||||
} | |||||
}); | }); | ||||
// console.log('downloadtasks') | // console.log('downloadtasks') | ||||
// console.dir(downloadtasks[0]) | // console.dir(downloadtasks[0]) | ||||
// return any([any(steps), any(prompts)]) | // return any([any(steps), any(prompts)]) | ||||
} | } | ||||
} | } | ||||
, { | |||||
shellcmd: 'nvm', | |||||
url: 'https://github.com/coreybutler/nvm-windows/releases/download/1.1.11/nvm-setup.exe' | |||||
, installer: 'nvm-setup.exe' | |||||
, installcmd: ['cmd', ['/c', 'start', | |||||
'/WAIT', downloadsdir + '/' + 'nvm-setup.exe' | |||||
, '/VERYSILENT' | |||||
// , '/MERGETASKS=!runcode' // This is required only for vscode... | |||||
]] | |||||
, install : install | |||||
, exists : exists | |||||
, preinstallsteps: function() { | |||||
var self = this; | |||||
console.log('Node preinstall steps') | |||||
// console.log(this.installcmd) | |||||
// console.log(path.normalize(downloadsdir + '/' + 'node-v14.17.3-x64.msi')) | |||||
var steps = []; | |||||
steps.push( | |||||
function(){ | |||||
if (!existsSync(downloadsdir + '/' + self.installer)) { | |||||
return nodeShellExec(selectedinstance.root + '/.elxr/run-' + runtimestamp + '/download.bat', ['"' + self.url + '"', downloadsdir + '/' + self.installer] | |||||
, { waitmsg : 'downloading '+ self.shellcmd +' please wait' }) | |||||
} | |||||
else { | |||||
console.log(self.installer + ' Already exits Download skipped.') | |||||
return Promise.resolve(true) | |||||
} | |||||
} | |||||
) | |||||
return any(steps) | |||||
// return any([any(steps), any(prompts)]) | |||||
} | |||||
} | |||||
, { | , { | ||||
shellcmd: 'python' | shellcmd: 'python' | ||||
, optional : true | , optional : true | ||||
promises.push(verifyAndInstallPrerequisites()) | promises.push(verifyAndInstallPrerequisites()) | ||||
startPromises(); | startPromises(); | ||||
} | |||||
} | |||||
// Open JDK | |||||
// https://objects.githubusercontent.com/github-production-release-asset-2e65be/602574963/cd0ac1ad-740d-4616-aa96-157ac2e79a60?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAVCODYLSA53PQK4ZA%2F20240117%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20240117T055737Z&X-Amz-Expires=300&X-Amz-Signature=4c0ce9303027a065fed291a107ff0a5f7d7782a828f077873bd5111c8e6fa0f0&X-Amz-SignedHeaders=host&actor_id=0&key_id=0&repo_id=602574963&response-content-disposition=attachment%3B%20filename%3DOpenJDK21U-jdk_x64_windows_hotspot_21.0.1_12.msi&response-content-type=application%2Foctet-stream | |||||
// JRE for runtime | |||||
// https://my.visualstudio.com/Downloads?q=Visual%20Studio%202022 |
// }).then(Tasq.then).catch(Tasq.catch) | // }).then(Tasq.then).catch(Tasq.catch) | ||||
// }) | // }) | ||||
var bowerRepos = [{ repo : 'client'}] | |||||
var bowerRepos = [{ repo : 'elixir-client'}]; | |||||
var bowertasks = [] | var bowertasks = [] | ||||
bowerRepos.forEach(repodef => { | bowerRepos.forEach(repodef => { | ||||
bowertasks.push(() => { | bowertasks.push(() => { |
@echo off | |||||
echo %PATH% | |||||
set PATH=%PATH%;C:\Program Files\Git\cmd | |||||
set PATH=%PATH%;C:\Program Files\nodejs\ | |||||
set PATH=%PATH%;C:\Users\Pradeep\AppData\Local\Programs\Microsoft VS Code\bin | |||||
set PATH=%PATH%;C:\Python27 | |||||
SET LAUNCHEDWITHENV=YES && cscript D:\chess\elixir\dev\elxr\i.win.js /all:true |
"author": "", | "author": "", | ||||
"license": "ISC", | "license": "ISC", | ||||
"dependencies": { | "dependencies": { | ||||
"bbhverse": "git+http://git.bbh.org.in/chess/bbhverse", | |||||
"serververse": "git+http://git.bbh.org.in/chess/bbhverse", | |||||
"bbhverse": "file:../bbhverse", | |||||
"serververse": "file:../serververse", | |||||
"chalk": "^4.1.0", | "chalk": "^4.1.0", | ||||
"crossfilter2": "^1.5.4", | "crossfilter2": "^1.5.4", | ||||
"glob": "^7.1.2", | "glob": "^7.1.2", |
#xrdp | #xrdp | ||||
#----------------------- | #----------------------- | ||||
sudo apt install xrdp | sudo apt install xrdp | ||||
nano /etc/xrdp/startwm.sh | |||||
sudo nano /etc/xrdp/startwm.sh | |||||
Add in the very top: | Add in the very top: | ||||
unset DBUS_SESSION_BUS_ADDRESS | unset DBUS_SESSION_BUS_ADDRESS |
var shell_verse = { | var shell_verse = { | ||||
// getCommonTask is agnostic of whether we are running in an elevated shell or not. It runs in either case. | // getCommonTask is agnostic of whether we are running in an elevated shell or not. It runs in either case. | ||||
init( o ){ Object.assign(this, o) } | init( o ){ Object.assign(this, o) } | ||||
, downloadsdir : '../Downloads' | , downloadsdir : '../Downloads' | ||||
, getCommonTask( taskToRun ){ return ()=>{ return shell_verse.runTask(taskToRun) }} | , getCommonTask( taskToRun ){ return ()=>{ return shell_verse.runTask(taskToRun) }} | ||||
, runTask : ( taskToRun ) => { | , runTask : ( taskToRun ) => { | ||||
, elevatedRunner( taskToRun, inBatch ){ | , elevatedRunner( taskToRun, inBatch ){ | ||||
// PB : TODO -- Should be called only when we are in an elevated shell that was already requested from an unelevated shell with a batch of tasks. | // PB : TODO -- Should be called only when we are in an elevated shell that was already requested from an unelevated shell with a batch of tasks. | ||||
try { | try { | ||||
var runlogjson = `${selectedinstance.root}/.elxr/run-${taskToRun.runtimestamp}/run.log` | |||||
var runlogjson = `${taskToRun.selectedinstance.root}/.elxr/run-${taskToRun.runtimestamp}/run.log` | |||||
var __runasresult = null; | var __runasresult = null; | ||||
return taskToRun().then((r)=>{ | return taskToRun().then((r)=>{ | ||||
// PB : TODO -- Every elevation should have its own messaging file. Async writes from multiple processes are a problem here... | // PB : TODO -- Every elevation should have its own messaging file. Async writes from multiple processes are a problem here... | ||||
, requestElevation(elevatedRunner, taskToRun) { | , requestElevation(elevatedRunner, taskToRun) { | ||||
// PB : TODO -- Multiple parallel request elevations should be queued into a batch and serialized as a single promise. | // PB : TODO -- Multiple parallel request elevations should be queued into a batch and serialized as a single promise. | ||||
var processedArgs = taskToRun.processedArgs, selectedinstance = taskToRun.selectedinstance , statuslog = taskToRun.statuslog | |||||
var processedArgs = taskToRun.processedArgs, statuslog = taskToRun.statuslog | |||||
// Wait for the runas to complete before we read it. | // Wait for the runas to complete before we read it. | ||||
try { | try { | ||||
fs.unlinkSync('run.done') // Need a unique file for aech elevated run. | fs.unlinkSync('run.done') // Need a unique file for aech elevated run. | ||||
// Find node path to send to hta. | // Find node path to send to hta. | ||||
return nodeShellExec('where', ['node']).then(r => { | return nodeShellExec('where', ['node']).then(r => { | ||||
var namedArgs = []; | |||||
console.log('result : ' + JSON.stringify(r)) | |||||
Object.keys(processedArgs).forEach((v) => { v != '_' ? namedArgs.push('--' + v + '=' + processedArgs[v]) : null; }) | |||||
// PB : TODO -- Convert all the cli args back to string. | |||||
var args = [ path.normalize(`${selectedinstance.root}/.elxr/run-${taskToRun.runtimestamp}/windowselevate.hta`) ].concat(processedArgs._) | |||||
namedArgs.length > 0 ? args = args.concat(namedArgs.join(' ')) : null; | |||||
var args = taskToRun.args | |||||
var options = taskToRun.args ? taskToRun.args.pop() : { | |||||
inherit: true | |||||
, shell: true | |||||
, env: taskToRun.ENV | |||||
, runas: 'self' | |||||
, title: `runas` | |||||
} | |||||
options.env = Object.assign({}, taskToRun.ENV, { wd : options.cwd }) | |||||
var spawntimestamp = (new Date()).getTime() | |||||
if(!args) { | |||||
var namedArgs = []; | |||||
console.log('result : ' + JSON.stringify(r)) | |||||
Object.keys(processedArgs).forEach((v) => { v != '_' ? namedArgs.push('--' + v + '=' + processedArgs[v]) : null; }) | |||||
// PB : TODO -- Convert all the cli args back to string. | |||||
args = [].concat(processedArgs._) | |||||
namedArgs.length > 0 ? args = args.concat(namedArgs.join(' ')) : null; | |||||
} | |||||
else { | |||||
// args = args.splice(-1) -- Already popped | |||||
args.push(`--root=${selectedinstance.root}`); | |||||
} | |||||
args.splice(0,0, path.normalize(`${taskToRun.selectedinstance.root}/.elxr/run-${taskToRun.runtimestamp}/windowselevate.hta`)) | |||||
args.push('--runas=self'); | args.push('--runas=self'); | ||||
var elevatedruntimestamp = (new Date()).getTime() | |||||
args.push(`--runtimestamp=${elevatedruntimestamp}`); | |||||
// args.debug = true | |||||
if(args.debug) args.push(`--debug=${args.debug}`); | |||||
args.push(`--runtimestamp=${spawntimestamp}`); | |||||
// args.push(`--wd=${options.cwd}`); | |||||
// args.push('--nodepath=' + r.messages[r.messages.length - 1]) | // args.push('--nodepath=' + r.messages[r.messages.length - 1]) | ||||
// if (!processedArgs.node_env) args.push('--node_env=' + ENV.NODE_ENV) | // if (!processedArgs.node_env) args.push('--node_env=' + ENV.NODE_ENV) | ||||
console.dir(args) | console.dir(args) | ||||
// throw 'test' | // throw 'test' | ||||
return nodeShellExec('MSHTA', [`"${args.join('" "')}"`] | |||||
, { | |||||
inherit: true | |||||
, shell: true | |||||
, env: taskToRun.ENV | |||||
, runas: 'self' | |||||
, title: `runas` | |||||
} | |||||
).then(() => { | |||||
return nodeShellExec('MSHTA', [`"${args.join('" "')}"`], options ).then(() => { | |||||
// runas returned. | // runas returned. | ||||
try { | try { | ||||
// PB : TODO -- Log is comma prefixed. Needs to be proper JSON. | // PB : TODO -- Log is comma prefixed. Needs to be proper JSON. | ||||
var runlogjson = `${selectedinstance.root}/.elxr/run-${elevatedruntimestamp}/run.log` | |||||
var runlogjson = `${taskToRun.selectedinstance.root}/.elxr/run-${spawntimestamp}/run.log` | |||||
var runaslog = JSON.parse('[' + fs.readFileSync(runlogjson, { flags: 'a+' }) + ']'); | var runaslog = JSON.parse('[' + fs.readFileSync(runlogjson, { flags: 'a+' }) + ']'); | ||||
try { fs.unlinkSync(runlogjson) } catch(e){ } // PB : TODO -- Have a unique file for each elevated run. | try { fs.unlinkSync(runlogjson) } catch(e){ } // PB : TODO -- Have a unique file for each elevated run. | ||||
// console.log( "runaslog : " + runaslog.length ) | // console.log( "runaslog : " + runaslog.length ) | ||||
console.error('Run log error probably was not created by runas : ' + e) | console.error('Run log error probably was not created by runas : ' + e) | ||||
} | } | ||||
}) | }) | ||||
.catch(err => console.error('Elevation failed : ' + err)); | |||||
.catch(err => console.error('Elevation failed : ' + JSON.stringify(err))); | |||||
}) | }) | ||||
} | } | ||||
, launchui() { | , launchui() { |