Skip to content

Commit

Permalink
console (#7)
Browse files Browse the repository at this point in the history
* first try with console

* trying to compile

* almost there

* almost there

* I think I got it

* Update README.md

* Update README.md

* test with old file-client

* cleanup

* cjs to esm converer!

* cjs to esm converter!

* added new tests

* added upload/download/copy

* added upload/download/copy

* readme updates

* sol bursts forth

* sol improvements

* changed upload param order

* changed upload param order

* sol README

* npmignore changes
  • Loading branch information
jeff-zucker authored Jan 5, 2019
1 parent b9280b6 commit 9c97799
Show file tree
Hide file tree
Showing 31 changed files with 2,302 additions and 828 deletions.
107 changes: 107 additions & 0 deletions .bin/sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
#!/usr/bin/env node
const program = require('commander'); // the command-line interface
const sol = require('./sol.run.js'); // the commands
const sh = require('./sol.shell.js'); // the interactive interface
const batch = require('../src/batch'); // the batch interface
/*
* This file is the command-line interface
*/
program
.name('sol')
.description('Command line and interactive shell tool for Solid')
.version("0.1.0")
;
program
.command('shell')
.alias('sh')
.description('run as an interactive shell')
.action( () => {
sol("login").then(()=>{sh()},err=>console.log(err));
});
program
.command('read <URL>')
.alias('r')
.description('read a file on a Solid server')
.action( (URL) => {
sol("login").then( ()=> {
sol("read",[URL]).then(()=>{
},err=>console.log(err));
},err=>console.log(err));
});
program
.command('readFolder <URL>')
.alias('rf')
.description("list a Solid server folder's directory")
.action( (URL) => {
sol("login").then( ()=> {
sol("read",["folder",URL]).then(()=>{
},err=>console.log(err));
},err=>console.log(err));
});
program
.command('createFolder <URL...>')
.alias('cf')
.description('create one or more folders')
.action( URL => {
sol("login").then( ()=> {
sol("createFolder",[URL]).then(()=>{
},err=>console.log(err));
},err=>console.log(err));
});
program
.command('delete <URL...>')
.alias('rm')
.description('delete a file or empty folder on a Solid server')
.action( URL => {
sol("login").then( ()=> {
sol("delete",[URL]).then(()=>{
},err=>console.log(err));
},err=>console.log(err));
});
program
.command('upload <target> <files...>')
.alias("up")
.description('upload file(s) to a Solid server')
.action( (target,files) => {
sol("login").then( ()=>{
sol("upload",[target,files]).then( ()=>{
},err=>console.log(err));
},err=>console.log(err));
},err=>console.log(err));
program
.command('download <target> <URL>')
.alias("dn")
.description('download a Solid file')
.action( (target,URL) => {
sol("login").then( ()=>{
sol("download",[target,URL]).then( ()=>{
},err=>console.log(err));
},err=>console.log(err));
});
program
.command('copy <oldURL> <newURL>')
.alias('cp')
.description('copy a file from one remote location to another')
.action( (oldURL,newURL) => {
sol("login").then( ()=> {
sol("copy",[oldURL,newURL]).then(()=>{
},err=>console.log(err));
},err=>console.log(err));
});
/* TBD
program
.command('batch <scriptFile>')
.description('batch run commands in a script file')
.action( (scriptFile) => {
sol("login").then(()=>{
sol("batch",[scriptFile]).then(()=>{
},err=>console.log(err) )
},err=>console.log(err) )
},err=>console.log(err))
*/
if(process.argv.length<3){
process.argv.push("-h");
}
program.parse(process.argv);


256 changes: 256 additions & 0 deletions .bin/sol.run.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,256 @@
const fs = require("fs");
const path = require("path");
//const fc = require("../dist/console/index.js");
const fc = require("../src/index.js");
const show = require("./sol.show.js");
const batch = require("../src/batch");
let credentials;

module.exports = runSol;
async function runSol(com,args) {
let fn,source,target;
return new Promise((resolve,reject)=>{ switch(com){

case "help" :
case "h" :
show("help");
resolve();
break;

case "login" :
console.log("logging in ...");
fc.getCredentials().then ( creds => {
credentials = creds;
fc.login( credentials ).then( session => {
console.log("logged in");
resolve();
}, err => reject("error logging in : "+err) );
}, err => reject("error getting credentials : "+err) );
break;

case "rf" :
case "readFolder" :
source = mungeURL(args[0]);
console.log("fetching from "+source)
fc.readFolder(source).then( folderObject => {
show("folder",folderObject);
resolve()
},err=>console.log(err));
break;


case "r" :
case "read" :
case "readFile" :
source = mungeURL(args[0]);
console.log("fetching from file "+source);
fc.readFile(source).then( fileBody =>{
show("file",fileBody);
resolve()
},err=>console.log(err));
break;

case "rm" :
case "delete" :
if( args.length>1 ){
target = [ args ] // in shell, multiple args
}
else target = args[0];
if( typeof(target)!="string" && target.length<2){
target = target[0];
}
if( typeof(target)==="string" ){
target = mungeURL(target);
if( target.match(/\*$/) ){
target = target.replace(/\*$/,'');
fc.readFolder(target).then( gotFolder => {
let all= gotFolder.folders.concat(gotFolder.files);
doMany("rm",all).then( ()=>{
resolve()
},err=>console.log(err));
},err=>console.log(err));
break;
}
console.log("deleting "+target);
fc.deleteFile(target).then( () => {
console.log("deleted");
resolve();
}, err => reject("error deleting "+err) );
break;
}
else {
doMany("delete",target).then( ()=>{
resolve()
}, err => reject(err) )
break;
}
break;

case "cf" :
case "createFolder" :
if( args.length>1 ){
target = [ args ]
}
else target = args[0];
if( typeof(target)!="string" && target.length<2){
target = target[0];
}
if( typeof(target)==="string" ){
target = mungeURL(target);
console.log("creating folder '"+target+"'");
fc.createFolder(target).then( () => {
console.log("created folder");
resolve();
}, err => reject("error creating folder "+err) );
}
else {
doMany("createFolder",target).then( ()=>{
resolve()
}, err => reject(err) )
break;
}
break;

case "dn" :
case "download" :
[target,source] = args;
fn = path.join( target , source.replace(/.*\//,'') )
source = mungeURL(source);
target = path.join(__dirname,fn);
console.log("downloading from "+source+" to "+fn);
fc.downloadFile(source,target).then( () => {
console.log("downloaded");
resolve();
}, err => reject("error downloading file "+err) );
break;

case "up" :
case "upload" :
[ target, source ] = args;
target = mungeURL(target);
if( source.match && source.match(/\*$/) ){ // shell
source = source.replace(/\*$/,'');
source = path.join(__dirname,source);
fs.readdir(source, (err,files) => {
if(err) reject(err);
else {
files = files.map(x=>path.join(source,x))
doMany("upload",files,target).then( ()=>{
resolve()
}, err => reject(err) )
}
},err=>reject(err));
break;
}
if( typeof(source)!="string" ){
doMany("upload",source,target).then( ()=>{
resolve()
}, err => reject(err) )
break;
}
if( fs.lstatSync(source).isFile() ){
fn = source.replace(/.*\//,'')
console.log("uploading file "+target+fn);
fc.uploadFile(source,target).then( () => {
console.log("uploaded file");
resolve();
}, err => reject("error uploading file "+err) );
break;
}
else if( fs.lstatSync(source).isDirectory() ){
source = source.replace(/.*\//,'')
target = path.join(target,source).replace(/^https:\//,"https://")
console.log("uploading folder "+target);
fc.createFolder(target).then( () => {
console.log("uploaded folder");
resolve();
}, err => reject("error uploading folder "+err) );
}
break;

case "cp" :
case "copy" :
args[0] = mungeURL(args[0]);
args[1] = mungeURL(args[1]);
console.log("copying "+args[0]+" to "+args[1]);
fc.copyFile(args[0],args[1]).then( () => {
console.log("copied");
resolve();
}, err => reject("error copying file "+err) );
break;

case "batch" :
source = path.join(__dirname,args[0])
fs.readFile( source, 'utf-8', (err,content) => {
if(err) reject(err);
else {
let set = []
let commands = content.split("\n")
for(c in commands){
let line = commands[c].trim()
if( !line ) continue;
let newArgs = line.split(/\s+/)
let newCom = newArgs.shift()
set.push( function(){
runSol( newCom, newArgs ).then( ()=> {
batch.skip()
},err=>batch.skip(err) )
})
}
batch.run(set);
}
},err=>reject(err));
break;

default :
if( com.match && com.match(/^\!/) ){
/* issue shell command, needs work
const shell = require('shelljs');
shell.config.silent = true; // suppress stdout
com = com.replace(/^\!/,'');
results = shell.exec( com );
console.log(results.stdout);
resolve();
*/
}
else if(com) console.log("can't parse last command")
resolve();
}});
}
function mungeURL(url) {
if( url && url.match(/^https:\/[^/]/) )
url = url.replace(/^https:\//,"https://")
if( url && !url.match(/^http/) && credentials && credentials.base)
return credentials.base + url;
else
return url;
}
function mungeLocalFolder(source){
let files = [];
for(var s in source){
if( fs.lstatSync(source[s]).isFile() ){
files.push(source[s]);
}
}
return(files)
}
async function doMany(com,files,targetDir){
if( files.length < 1 ) return;
let file = files.shift();
if( typeof(file)!="string" ){
file = file.url;
}
let fn = file.replace(/.*\//,'');
if( targetDir ){
// let target = path.join(targetDir,fn).replace(/:\//,'://');
runSol(com,[targetDir,file]).then( ()=>{
doMany(com,files,targetDir);
});
}
else {
runSol(com,[file]).then( ()=>{
doMany(com,files);
});
}
}

25 changes: 25 additions & 0 deletions .bin/sol.shell.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
const sol = require('./sol.run.js');

function prompt(question, callback) {
var stdin = process.stdin, stdout = process.stdout;
stdin.resume();
stdout.write(question);
stdin.once('data', function (data) {
callback(data.toString().trim());
});
}
function sh(){
prompt("> ", data => {
/*
* TBD : real command parsing rather than split
*/
let args = data.split(/\s+/)
let com = args.shift()
if( com.match(/(q|quit|exit)/) ) process.exit();
sol( com, args ).then(()=>{sh()},err=>{
console.log(err);
sh();
});
});
}
module.exports = sh;
Loading

0 comments on commit 9c97799

Please sign in to comment.