UNPKG

web-terminaljs

Version:

Web terminal, control actions and modules

488 lines (420 loc) 14.4 kB
'use strict' /* Author Alfredo Roman Description Core Module Install Version 0.5.1 */ const u = require('util').format const https = require('https'); const fs = require('fs'); const crypto= require('crypto'); const zlib = require('zlib'); const url = require('url'); const targz = require('targz'); const repoMaxTime = 300000;//300 seconds let repoTime = 0; const md5checksum = async function(str){ return await crypto.createHash('md5').update(str).digest("hex"); } async function get_page(dirurl) { let data = ''; return new Promise((resolve) => { const a = https.get(dirurl, res => { res.on('data', chunk => { data += chunk }) res.on('end', () => { resolve(data); }) }) a.setTimeout( 5000, function( ) { resolve('timeout'); }); }) } const unzip_and_write = function(socketID,filegz,spliter,tar){ this.emit(socketID+'progress',27); let data = fs.readFileSync(filegz); this.emit(socketID+'progress',45); data = zlib.unzipSync(data); this.emit(socketID+'progress',65); if( tar ){ const md5 = md5checksum(data) .then( md5checksum =>{ if( md5checksum == this.repo[spliter[0]][spliter[1]].md5){ this.emit(socketID,u('module installing MD5: "%s" %s',md5checksum,this.f.color('accepted','green'))); this.emit(socketID+'progress',75); this.wtm_install_write_tar(socketID,filegz,spliter); return; }else{ this.emit(socketID+'progress',-1); this.emit(socketID+'err',u('MD5: %s \r\nMD5: %s \r\n Not iqual.\r\n%s',md5checksum,this.repo[spliter[0]][spliter[1]].md5,'Error in checksum this module\r\nNot installer for security')); } }); return; } const md5 = md5checksum(data) .then( md5checksum =>{ if( md5checksum == this.repo[spliter[0]][spliter[1]].md5){ this.emit(socketID,u('module installing',md5checksum)); this.emit(socketID+'progress',75); this.wtm_install_write_file(socketID,filegz,spliter,data); }else{ this.emit(socketID+'progress',-1); this.emit(socketID+'err','Error in checksum this module\r\nNot installer for security'); } }); } const write_file = function(socketID,filegz,spliter,data){ fs.writeFile(this.options.path+spliter[0]+'.js', data, (err)=>{ if (err) { this.emit(socketID+'progress',-1); this.emit(socketID+'err','Error record Module\r\nNot installed'); return } this.emit(socketID+'progress',98); this.wtm_install_post_install(socketID,filegz,spliter); }); } const post_install = function(socketID,filegz,spliter){ //auto load installed this.emit(socketID,'module waiting to load '+spliter[0]); this._load_module(socketID,''+spliter[0],undefined,true); this.emit(socketID+'progress',99); this.emit(socketID,'module cleaning '+spliter[0]); fs.unlink(filegz, (e) => { if (e) { this.emit(socketID+'progress',-1); this.emit(socketID+'err',u(errors['UNDEFINED'],'Remove module',args[2],e)); return; } this.emit(socketID+'progress',100); return; }); } const write_tar = function(socketID,filegz,spliter){ try{ targz.decompress({ src: filegz, dest: this.options.path }, (err)=>{ if(err) { this.emit(socketID+'err',u(err)); } else { this.emit(socketID+'progress',98); this.wtm_install_post_install(socketID,filegz,spliter); } }); } catch(e){ this.emit(socketID,u('Error install module',e)); } } const get_file = async function(socketID,dirurl,file,spliter,tar) { let lwrite = 0; let fwrite; let maxbytes = 0; this.emit(socketID+'progress',2); const a = https.get(dirurl, response=> { if (response.statusCode > 300 && response.headers.location) { if (url.parse(response.headers.location).hostname) { this.wtm_install_get_file(socketID,response.headers.location,file,spliter,tar); return; //https.get(response.headers.location),writeToFile); } else { this.wtm_install_get_file(socketID,url.resolve(url.parse(TAR_URL).hostname, response.headers.location),file,spliter,tar); return; //https.get(url.resolve(url.parse(TAR_URL).hostname, response.headers.location),writeToFile); } } maxbytes = response.headers['content-length']; response.on('data', chunk => { if( fwrite === undefined){ fwrite = fs.createWriteStream(file); } fwrite.write(chunk); lwrite = parseInt(lwrite+chunk.length); this.emit(socketID+'progress',parseInt(1+(parseInt(lwrite/maxbytes))*25)); }) response.on('end', ()=> { fwrite.end( ()=>{ this.emit(socketID+'progress',26); this.wtm_install_unzip_and_write(socketID,file,spliter,tar); }); }); }) a.setTimeout( 5000, ()=> { this.emit(socketID+'progress',-1); this.emit(socketID+'err','Error in timeout this module\r\nNot installer, repositorie not respond'); }); } const errors = { PATH : 'Path not found \r\n %s', USAGE : 'Arguments error, using help \t\n OR help usage install', UNDEFINED : '%s internal error: \r\n %s', NOT_INSTALL : 'Module wtm %s not installed', NOT_EXIST : 'Module wtm %s not exist in repositorie\r\nUpdate list with command "install update". ', UNDEFINED : '%s internal error: \r\n %s\r\n%s' }; //BASE command const install = function(socketID,args){ try{ if( this['wtm_install_'+args[1]] === undefined){ this.emit(socketID+'err', u(errors['USAGE'])) return; } this['wtm_install_'+args[1]](socketID,args); }catch(e){ this.emit(socketID+'err',u(e)); } } //update list repositories const update = async function(socketID,args){ if( parseFloat(repoTime+repoMaxTime) > Date.now()){ this.emit(socketID,'Not Updating\r\ntime between update too short'); return true; } this.emit(socketID,'Repositorie Updating'); return await get_page(this.options.repoJson) .then( result=>{ try{ if( result == 'timeout'){ this.emit(socketID,'Repositorie timeout'); return; } this.repo = JSON.parse(result); this.emit(socketID,'Repositorie Updated'); repoTime = Date.now(); }catch(e){ this.emit(socketID+'err',u(errors['UNDEFINED'],'Result HTTPS JSON',e,result)); } return true; }); } //install function const modules = async function(socketID,args){ try { if( args[2] === undefined){ this.emit(socketID+'err', u(errors['USAGE'])); return; } // more time witch out install update, force update if( parseFloat(repoTime+repoMaxTime) < Date.now()){ await this.wtm_install_update(socketID,args); } const spliter = args[2].split('@');//separated for version module@version if( this.repo[spliter[0] ] === undefined){ this.emit(socketID+'err',u(errors['NOT_EXIST'],args[2])); return; } if( spliter[1] === undefined){spliter[1] = this.repo[spliter[0] ].lasted} if( this.repo[ spliter[0] ][spliter[1]] === undefined){ this.emit(socketID+'err',u(errors['NOT_EXIST'],args[2])); return; } const version = this.version; const pversion = parseInt( version.replace(/\./g,'')); if( this.repo[spliter[0]][spliter[1]].compatible === undefined){this.repo[spliter[0]][spliter[1]].compatible = '0'}; const cversion = parseInt( this.repo[spliter[0]][spliter[1]].compatible.replace(/\./g,'')); if( pversion >= cversion ){ this.emit(socketID,'\r\nCompatible:\t\t'+this.f.color('accepted','green')); }else{ this.emit(socketID,'\r\nCompatible:\t\t'+this.f.color('not compatible','red')); this.emit(socketID,'\r\n your version WT is '+version+' module need version >'+this.repo[spliter[0]][spliter[1]].compatible,'red'); return; } let TAR_URL = this.options.repoURL + this.repo[spliter[0]][spliter[1]].file + '.gz'; let tar = this.options.path+spliter[0]+'.js.gz' let tartf = false;//old versions 0.4.0 TAR True False if( this.repo[ spliter[0] ][ spliter[1] ].tar !== undefined ){ TAR_URL = this.options.repoURL + this.repo[ spliter[0] ][ spliter[1] ].tar; tar = this.repo[ spliter[0] ][ spliter[1] ].tar; tartf = true; this.emit(socketID,'module newVersion tar gz'); } this.emit(socketID,'module download '+spliter[0]+' version '+spliter[1]); this.emit(socketID+'progress',0); this.wtm_install_get_file(socketID,TAR_URL,tar,spliter,tartf); }catch(e){ this.emit(socketID+'err',u(errors['UNDEFINED'],'Install',e,'')); } } //uninstall funcion const remove = function(socketID,args){ //si no envia argumento no hacemos nada if( args[2] === undefined){ this.emit(socketID+'err', u(errors['USAGE'])); return; } //si no existe la carpeta, no hacemos nada if (! fs.existsSync(this.options.path)) { this.emit(socketID+'err',u(errors['PATH'],this.options.path)); return; } //si no esta instalado no hacemos nada console.log(this.list_modules); if( this.list_modules[args[2]] === undefined){ this.emit(socketID+'err',u(errors['NOT_INSTALL'],args[2])); return; } //unload module this.emit(socketID+'progress',0); try{ if( this.list_modules[args[2]]){ this._unload_module(socketID,args[2]); } }catch(e){ this.emit(socketID+'progress',-1); this.emit(socketID+'err',u(errors['UNDEFINED'],'unload module',args[2],e)); return } try{ this.emit(socketID+'progress',10); fs.unlink(this.installed[args[2]].path+args[2]+'.js', (e) => { if (e) { this.emit(socketID+'progress',-1); this.emit(socketID+'err',u(errors['UNDEFINED'],'Remove module',args[2],e)); return } this.emit(socketID+'progress',99); delete this.installed[args[2]]; this.emit(socketID+'progress',100); this.emit(socketID,'module removed'); }) }catch(e){ this.emit(socketID+'progress',-1); this.emit(socketID+'err',u(errors['UNDEFINED'],'unload module',args[2],e)); return } } //checksum function const checksum = async function(socketID,args){ //si no envia argumento no hacemos nada if( args[2] === undefined){ this.emit(socketID+'err', u(errors['USAGE'])); return; } const [err,md5] = await this.wtm_install_calc_checksum(args[2]) if(err){ this.emit(socketID+'err',u(err)); }else{ this.emit(socketID,md5); } } const calc_checksum = async function(name){ //si no existe la carpeta, no hacemos nada if (! fs.existsSync(this.options.path)) { return [u(errors['PATH'],this.options.path)]; } //si no esta instalado no hacemos nada if( this.list_modules[name] === undefined){ return [u(errors['NOT_INSTALL'],name)]; } const data = fs.readFileSync(this.options.path+name+'.js', {encoding:'utf8', flag:'r'}); const md5 = await md5checksum(data) .then( result=>{ return result }); return [null,md5]; } //list function const list_list = function(socketID,args,list){ let res =''; let pasa =0; if( args[2] !== undefined){ this.emit(socketID,'filter: '+args[2]); } for( let i in list){ if( args[2] !== undefined){ if( args[2] != i){continue;} } pasa = 0; res += this.f.col(i,0); for( let v in list[i]){ if( pasa == 1){ res += '\t\t\t';} res += this.f.col(v,0); res += this.f.col(list[i][v],0); res +='\r\n'; pasa = 1; } res +='\r\n'; } this.emit(socketID,res); } //search function const search = function(socketID,args){ this.wtm_install_list_list(socketID,args,this.repo); if( args[2] !== undefined){ this.wtm_install_info(socketID,args); } } const list = function(socketID,args){ this.wtm_install_list_list(socketID,args,this.installed); } const info = async function(socketID,args){ // more time witch out install update, force update if( parseFloat(repoTime+repoMaxTime) < Date.now()){ await this.wtm_install_update(socketID,args); } let res =''; try { if( args[2] === undefined){ this.emit(socketID,'Error command, please use help usage install'); return; } const spliter = args[2].split('@');//separated for version module@version if( this.repo[ spliter[0] ] === undefined){ this.emit(socketID+'err',u(errors['NOT_EXIST'],args[2])); return; } if( spliter[1] === undefined){spliter[1] = this.repo[spliter[0] ].lasted} if( this.repo[ spliter[0] ][spliter[1]] === undefined){ this.emit(socketID+'err',u(errors['NOT_EXIST'],args[2])); return; } const infoAuthor = this.repo[spliter[0]]; const infoModule = this.repo[spliter[0]][spliter[1]]; const version = this.version.substring(1); const pversion = parseInt( version.replace(/\./g,'')); if( infoModule.compatible === undefined){infoModule.compatible = '0'}; const cversion = parseInt( infoModule.compatible.replace(/\./g,'')); res = '\r\nInfo module: '+spliter[0]+'\r\n'; res += '\r\nAuthor:\t\t\t'+infoAuthor.author; res += '\r\nVersion:\t\t'+spliter[1]; res += '\r\nLicense:\t\t'+infoAuthor.license; res += '\r\nMd5:\t\t\t'+infoModule.md5; if( pversion >= cversion ){ res += '\r\nCompatible:\t\t'+this.f.color('accepted','green'); }else{ res += '\r\nCompatible:\t\t'+this.f.color('not compatible','red'); res += '\r\n your version WT is '+version+' module need version >'+infoModule.compatible,'red'; } res += '\r\nDescription:\t'+infoModule.description; this.emit(socketID,res); }catch(e){ this.emit(socketID+'err',u(e)); } } module.exports = { command : { install : { description : 'System Instalation Repositorie', usage : 'name [module|remove|update|checksum|search,|info|list]', auto : ['module','remove','update','checksum','search','info','list'] //or null } }, install, module : modules, remove, update, search, info, list_list, list, checksum, calc_checksum, get_file, unzip_and_write, write_file, write_tar, post_install, autoload : false }