llearn
Version:
Bad-ass developers create awesome apps
520 lines (477 loc) • 19.4 kB
JavaScript
// console.log("Starting llearnearn.js...");
// llearn.jsn.js
// Purpose: The purpose of this....
// Date Created: 5/31/2018
// Created by : Perez Lamed van Niekerk
// ------------------------------------------------------
/*jshint esversion: 6 */
const _log = console.log;
const _JSONstr = (object) => JSON.stringify(object, undefined, 2);
const _logJSON = (object) => console.log(_JSONstr(object));
const _logLine = () => _log('-------------------------------------------------------');
const _chalk = require('chalk'); // npm i chalk -s
const _logGreen = (msg) => _log(_chalk.green.bold(msg));
const _logBold = (msg) => _log(_chalk.white.bold(msg));
const _logReverse = (msg) => _log(_chalk.black.bgWhite.bold(msg));
const _logRed = (msg) => _log(_chalk.red.bold(msg));
// ------------------------------------------------------
const _fs = require('fs');
const _helper = require("./helper");
const _opn = require('opn'); // npm i opn -s
const _ = require('lodash'); // npm install lodash --save
const _folderRecursive = require("recursive-readdir"); // npm i recursive-readdir -s
const _package = require('../package.json');
const _config = _package.config;
const _cmd1 = require('node-run-cmd'); // npm i node-run-cmd --save
// const _cmd2 = require('node-cmd'); // npm i node-cmd --save
const _$ = require('larray'); // npm i larray -s
const _io = require('../src/helper_io');
const _lfolder = require('lfolder'); // npm i lfolder -s
/* Get the version from the package.json file */
var Version = () => {
return _package.version;
};
var _larray = require('larray');
/* MS code.exe setup*/
const _os = require('os');
const _msCode = 'code64_' + _os.userInfo().username + '.bat';
// const _msPath = __dirname.replace('\\src', '');
const _msPath = _lfolder.rootFolder_Project();
if (_fs.existsSync(_msPath + _msCode) === false) {
_logLine();
_logRed(`Error: File "${_msPath +_msCode}" does not exist!`);
_log(`Copy 'code64.bat' to '${_msCode}' to correct.`);
_logLine();
process.exit();
}
/* Save the command that was used. */
const LocalStorage = require('node-localstorage').LocalStorage; // npm i node-localstorage -s
const _localStorage = new LocalStorage('./appSettings');
var _setupEnv = _localStorage.getItem("environment");
if (_$.notOk(_setupEnv)) {
_setupEnv = "JSN";
_localStorage.setItem("environment", _setupEnv);
}
var _setupEnvName = _localStorage.getItem("environmentName");
if (_$.notOk(_setupEnvName)) {
_setupEnvName = "(Unknown)";
_localStorage.setItem("environmentName", _setupEnvName);
}
// _log(_setupEnv);
var _setupEnvGlobal = _localStorage.getItem("environmentGlobal");
if (_$.notOk(_setupEnvGlobal)) {
_setupEnvGlobal = true;
_localStorage.setItem("environmentGlobal", _setupEnvGlobal);
}
/* Setup the search folder */
const _setupDir = _lfolder.fromRootFolder('templates/');
let _setupSearchDir = "";
if (_setupEnv.substring(1, 2) === ':') {
_setupSearchDir = _setupEnv;
} else if (_setupEnv.substring(0, 1) === '/') {
_setupSearchDir = _lfolder.fromRootFolder(_setupEnv);
} else {
_setupSearchDir = _lfolder.fromRootFolder('templates/' + _setupEnv);
}
// _log(_setupSearchDir);
const _setupGlobalDir = _lfolder.fromRootFolder('templates/_global/');
/* Save the history */
function historyPush(file) {
let lastFile = _localStorage.getItem("1");
/* Minimize duplicates */
if (file !== lastFile) {
_localStorage.setItem("6", '' + _localStorage.getItem("5"));
_localStorage.setItem("5", '' + _localStorage.getItem("4"));
_localStorage.setItem("4", '' + _localStorage.getItem("3"));
_localStorage.setItem("3", '' + _localStorage.getItem("2"));
_localStorage.setItem("2", '' + _localStorage.getItem("1"));
_localStorage.setItem("1", file);
}
}
/* Show the history */
function historyShow(option) {
let files = [];
for (let ii = 1; ii <= 10; ii++) {
let no = `${ii}`;
let item = _localStorage.getItem(no);
if (item !== 'null' && item !== null) files[ii - 1] = item;
}
if (files.length > 1) files = _.uniq(files);
option.showFiles = true;
showTemplateFiles(option, files);
}
/* Let the user choose the default environment */
function setupKnowledgeBase(privatePath) {
/* Setup of environment */
let base = _config.knowledgebase;
if (privatePath !== '') {
let privateFile = require(privatePath);
let private = privateFile.knowledgebase;
if (private.length > 0) {
base = base.concat(private);
}
}
_logGreen("\nPlease choose knowledge base:");
let no = 1;
for (let ii = 0; ii < base.length; ii++) {
let item = `${no++}. ${base[ii].name}`;
if (item.includes(_setupEnvName)) {
_logGreen(item);
} else _log(item);
}
no--;
_helper.IO().readLine(`Please select option 1..${no} ?`)
.then((index) => {
let env = base[index - 1];
let globalOn = true;
if (_$.notOk(env.global)) globalOn = true;
else globalOn = env.global;
// _log({env});
// _log({globalOn});
_localStorage.setItem("environment", env.folder);
_localStorage.setItem("environmentName", env.name);
_localStorage.setItem("environmentGlobal", globalOn);
_log(`Knowledge base was set to:\n ->'${env.name}'; Folder: '${env.folder}'`);
})
.catch(() => {
_logRed("You did not make a valid choice!");
// return;
})
}
/*------[Program start here]---------- */
function llearn() {
_helper.checkParm()
.then(templateFilter)
.catch((error) => {
// console.error(error.stack);
// console.trace(); // In order to trace the source better, comment out the catch
showError(error);
});
}
llearn();
/* ------------------------------ */
/* Remove the root folders from the template file */
function compress_file(fileTest, option) {
// _log({fileTest});
fileTest = fileTest
.replaceAll('\\', '/');
fileTest = fileTest
.replace(option.folder, '')
.replace(option.folder2, '')
.replace(_setupDir, '')
.replace('_global_', '');
// _log({fileTest});
//if (option.keyword1 !== '') fileTest = fileTest.replace(option.keyword1 + "\\", '');
return fileTest;
}
/* Return folder from file path */
function folder_get(filePath, seperator = '\\') {
return filePath.substring(0, filePath.lastIndexOf(seperator) + 1);
}
/* Remove root folders from path */
function compress_folder(path, option) {
// _log({path});
path = folder_get(path);
path = path
.replaceAll('\\', '/')
.replace(option.folder, '')
.replace(option.folder2, 'global/');
return path;
}
/* Execute the command line parameters - eq. search for templates for keyword */
function templateFilter(option) {
/* Parameters are ok -> continue to format settings */
/* Ensure template folders exist */
option.folder = _setupSearchDir;
if (!_fs.existsSync(option.folder)) _fs.mkdirSync(option.folder); // search folder
if (_setupEnvGlobal !== 'false') {
option.folder2 = _setupGlobalDir;
if (!_fs.existsSync(option.folder2)) _fs.mkdirSync(option.folder2); // global folder
}
// _log({_setupEnvGlobal});
// _log({option});
_log('lLearn version ' + Version())
if (option.topic === 'setup') {
/* setup */
let privatePath = _config.privateKnowledge;
// _log({privatePath});
_io.IO().exist(privatePath)
.then((err) => {
_log({privatePath});
setupKnowledgeBase(privatePath);
})
.catch((err) => {
_logRed(`Private knowledge base '${privatePath}' does not exits. (Fix in package.json).`);
setupKnowledgeBase('');
});
} else if (option.topic === 'templates') {
historyShow(option);
} else if (option.topic === 'edit' || option.topic === 'folder') {
let editFile = _localStorage.getItem("1").replaceAll('/', '\\'); // Change folder paths
let path = folder_get(editFile, '\\');
// _log({editFile});
// _log({path});
// Copy path to clipboard
copy2Clipboard(path);
if (option.topic === 'edit') {
/* edit template */
if (_$.Ok(editFile)) {
// let cmd = 'code64.bat "' + editFile + '"';
let cmd = _msCode +' "'+ editFile + '"';
_log(cmd);
_cmd1.run(cmd, showError)
.catch((err) => {
});
} else {
_logRed("There is no template to edit - please select one first.")
}
}
} else {
if (option.keyword[0] === undefined || option.keyword[0] === true) option.keyword[0] = '';
else option.value = option.keyword[0].toLowerCase();
if (option.topic === 'all' && option.keyword[0] === '') option.showFiles = false;
else option.showFiles = true;
/* Display search settings */
_logLine();
// _log(`Searching in: "${option.folder}"`);
if (option.showFiles) {
_log("Description : " + option.description);
// _log(`Keyword(s) : "${option.keyword[0]}", "${option.keyword[1]}"`);
_log(`Keyword(s) : [${option.keyword}]`);
if (option.remove.length !== 0) {
_log(`Remove: : [${option.remove}]`);
}
_log(`Topic : ${option.topic.toUpperCase()}`);
} else _log("Description : Showing template folders");
_log(`Environment : ${_setupEnv}`);
_logLine();
templateSearch(option).then((files) => showTemplateFiles(option, files));
}
}
/* Search {folder} for file containing {option.value} */
function fileFilter(stats, file, option) {
if (stats.isDirectory()) return false;
// if (file.includes('\\.git\\')) return true; // Remove git files
// if (file.includes('\\appSettings\\')) return true; // Remove appSettings folder
if (file.includesAny([
'\\.git\\',
'\\appSettings\\',
'.zip',
'\~$'] // '.pdf',
)) return true;
//let fileTest = file_compress(file, option);
/* remove base folder */
// _log(file);
let file1 = file.toLowerCase();
let found = file1.includesAll(option.keyword);
if (found) {
if (file1.includes('.readme')) found = false;
if (option.remove.length !== 0) {
if ( file1.includesAll(option.remove)) found = false;
}
}
// if (found) _log({found});
return !found;
}
/* Search in all folders */
function templateSearch(option) {
return new Promise((resolve, reject) => {
/* search templates */
_folderRecursive(option.folder, [(file, stats) => {
return fileFilter(stats, file, option);
}]).then((files) => {
if (_$.notOk(option.folder2)) resolve(files);
else {
/* search global templates */
_folderRecursive(option.folder2, [(file2, stats) => {
return fileFilter(stats, file2, option);
}]).then((files2) => {
if (files2.length > 0) files = files.concat(files2); // add global search
files = _.sortBy(files);
resolve(files);
})
}
}).catch((err) => reject(err));
});
}
/* Display the template files */
function showTemplateFiles(option, files) {
option.files = files;
/* Only one file found */
if (files.length === 1) {
if (files[0] == null) {
_log('No templates found!');
return;
} else {
_logGreen("-> " + files[0]);
templateChoice(option, 1);
return;
}
}
/* Show the files and let the user choose the correct one */
var no = 1;
var folderSave = '';
option.group = [];
for (let ii = 0; ii < files.length; ii++) {
let space = ' ';
if (no < 10) space = ' ';
if (option.showFiles) {
/* Show files */
let fileTest = compress_file(files[ii], option);
_log(`${space}${no++}. ${fileTest}`);
} else {
/* Show folders */
let folderTest = compress_folder(files[ii], option);
if (folderTest !== folderSave && folderTest !== '') {
option.group[no - 1] = folderTest;
folderSave = folderTest;
_log(`${space}${no++}. ${folderTest}`);
}
}
}
// _log({files});
// _log('group:',option.group);
no--;
if (files.length === 0)
_log('No templates found!');
else {
_log(`Total templates: ${files.length}`);
/* Let the user choose a template */
_helper.IO().readLine(`Please select template (1...${no}) : `)
.then((index) => templateChoice(option, index))
.catch((error) => {
/* No template chosen -> copy folder to clipboard */
let path = option.folder.replaceAll('/', '\\');
_helper.Clipboard().CopyTo(path)
.then(_logGreen(`-> "${path}" was copied to clipboard.`));
});
}
}
/* Evaluate the template choice */
function templateChoice(option, index) {
// _log('templateChoice');
if (option.showFiles) {
/* copy template to clipboard */
let template = option.files[index - 1]
.replaceAll('\\', '/');
_logBold("You choose: " + template);
historyPush(template);
let item = '';
if (template.includes('.xls')) item = 'starter.bat excel "' + template +'"';
if (template.includes('.doc')) item = 'starter.bat winword "' + template +'"';
if (template.includes('.png')) item = 'starter.bat mspaint "' + template +'"';
if (item === '') copyTemplate2Clipboard(template);
else {
// This is a document you need to open
item = item.replaceAll('/','\\');
_log({item});
_log('(Run "ll -f" for the folder)');
_cmd1.run(item).catch((err) => {
});
}
} else {
/* folder was chosen -> show folder contents */
let template = option.group[index - 1];
template = template.substring(0, template.length - 1).toLowerCase();
let key = template.split('/'); // Make key an array
_log(`\n\nSearching: '${key}'\n`);
// _log({key});
option.keyword = key;
option.files = key;
option.showFiles = true;
// _log({option});
templateSearch(option).then((files) => showTemplateFiles(option, files));
}
}
/* copy code 2 clipboard */
function copy2Clipboard(code) {
// Copy code the clipboard
_log('\n');
_log('Copy to clipboard:');
_logGreen(code);
_helper.Clipboard().CopyTo(code)
.then(() => {
})
.catch(showError);
}
/* Read the template file and copy to the clipboard */
function copyTemplate2Clipboard(file) {
historyPush(file);
_helper.IO().readFile(file)
.then((code) => {
/* set standard parameters */
code = code.replace('$END$', '');
code = code.replaceAll('$DATE$', new Date().toStr());
code = code.replaceAll('$USER$', 'Perez Lamed van Niekerk');
// _log({code});
/* search for parameters in the template */
_helper.parametersGet(code)
.then((parse) => {
if (parse !== '') {
/* replace the parameters */
// _log({parse});
if (_$.Ok(parse.keyword1)) {
code = code.replaceAll(`$${parse.parameter1}$`, parse.keyword1);
if (_$.Ok(parse.parameter2)) {
code = code.replaceAll(`$${parse.parameter2}$`, parse.keyword2);
}
} else _logRed("No parameter given - nothing replaced!");
}
/* Show the template in blue*/
/* copy template to clipboard */
code = code.replace('/* Edit code before run */', '');
let comment = _helper.Comment(code);
if (comment) {
code = code.replace('/?' + comment, '');
_log('\n----------------------------------------');
_log(comment);
_log('----------------------------------------');
}
if (file.includes('.bat')) {
code = code.replace('\n', ''); // Only one liners supported for commands
// bat file
if (code.includes('http')) {
_log({code});
_opn(code);
_log('\nUrl was opened.');
} else {
// var run = 'run.bat '+ code;
// _log(code);
_cmd1.run(code).catch((err) => {
});
code = code.replace('explorer ', ''); // remove 'explorer' from the command -> only folder path remains
// _log(run);
}
} else if (file.includes('.md')) {
// Markdown file.
// let code2 = 'explorer "' + file +'"';
// let code2 = 'md32.bat ' + file;
// _log({file});
code = folder_get(file, '/').replaceAll('/', '\\'); // Get the folder of the file.
// _log({code});
// let code2 = 'code64.bat ' + file;
let code2 = _msCode +' "'+ file + '"';
_log(code2);
_cmd1.run(code2).catch((err) => {
}); // this will only work for windows;
}
// Copy code the clipboard
//_log("123423");
copy2Clipboard(code);
})
.catch(showError);
})
.catch(showError);
}
/* show error message in red*/
function showError(error) {
_log();
_logLine();
_logRed("Catch -> " + error);
_logLine();
console.error(error.stack);
_helper.help_parameters();
}
module.exports = {
ll: llearn
};