Alex A. Naanou 040f3a7e3a working on logging in cli...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
2020-12-09 03:53:57 +03:00

278 lines
7.0 KiB
JavaScript
Executable File

/**********************************************************************
*
*
*
**********************************************************************/
((typeof define)[0]=='u'?function(f){module.exports=f(require)}:define)
(function(require){ var module={} // make module AMD/node compatible...
/*********************************************************************/
var util = require('lib/util')
var actions = require('lib/actions')
var features = require('lib/features')
var data = require('imagegrid/data')
var images = require('imagegrid/images')
var core = require('features/core')
var base = require('features/base')
if(typeof(process) != 'undefined'){
var pathlib = requirejs('path')
var argv = requirejs('lib/argv')
}
/*********************************************************************/
// XXX what we need here is:
// - base introspection
// - list features
// - list actions
// - list action scripts / commands
// - call action
// - call action script (a-la git commands)
// - repl (debug/testing)
//
// XXX the main functionality:
// - make previews
// - make index
// - merge
// - clone
//
// XXX a different approach to this would be an "external" cli controller
// script that would contain only cli code and load the ImageGrid
// only in the handler...
// + would be allot faster to load.
// + more flexible as we can load more than one instance...
// This could still be done via features, just load the cli feature
// alone at first and then either create new instances or setup
// additional features as needed...
var CLIActions = actions.Actions({
get cliActions(){
return this.actions
.filter(function(action){
return this.getActionAttr(action, 'cli') }.bind(this)) },
// XXX should this be here???
// ...move this to progress...
__progress: null,
showProgress: ['- System/',
function(text, value, max){
var msg = text instanceof Array ?
text.slice(1).join(': ')
: null
text = text instanceof Array ?
text[0]
: text
var state = this.__progress = this.__progress || {}
state = state[text] = state[text] || {}
// normalize max and value...
max = state.max = max != null ?
(typeof(max) == typeof('str') && /[+-][0-9]+/.test(max) ?
(state.max || 0) + parseInt(max)
: max)
: state.max
value = state.value = value != null ?
(typeof(value) == typeof('str') && /[+-][0-9]+/.test(value) ?
(state.value || 0) + parseInt(value)
: value)
: state.value
// format the message...
msg = msg ? ': '+msg : ''
msg = ' '+ msg
//+ (value && value >= (max || 0) ? ' ('+value+' done)'
+ (value && value >= (max || 0) ?
' (done)'
: value && max && value != max ?
' ('+ value +' of '+ max +')'
: '...')
// XXX do a better printout -- ncurses???
msg != state.msg
&& console.log(text + msg)
state.msg = msg
}],
startREPL: ['- System/Start CLI interpreter',
{cli: '@repl'},
function(){
var repl = nodeRequire('repl')
this._keep_running = true
// setup the global ns...
global.ig =
global.ImageGrid =
this
require('features/all')
global.ImageGridFeatures = core.ImageGridFeatures
//var ig = core.ImageGridFeatures
repl
.start({
prompt: 'ig> ',
useGlobal: true,
input: process.stdin,
output: process.stdout,
//ignoreUndefined: true,
})
.on('exit', function(){
//ig.stop()
process.exit() }) }],
// XXX
startGUI: ['- System/Start viewer GUI',
{cli: '@gui'},
function(){
// XXX
}],
// XXX this is reletively generic, might be useful globally...
// XXX add support for cwd and relative paths...
// XXX should we use a clean index or do this in-place???
makeIndex: ['- System/Make index',
{cli: {
name: '@make',
arg: 'PATH',
valueRequired: true,
}},
function(path){
var that = this
path = util.normalizePath(path)
// XXX should we use a clean index or do this in-place???
//var index = this.constructor()
var index = this
return index.loadImages(path)
// save base index...
.then(function(){
return index.saveIndex() })
// sharp stuff...
.then(function(){
if(index.makePreviews){
return Promise.all([
index.cacheMetadata('all'),
index.makePreviews('all') ])} })
.then(function(){
return index
.sortImages()
.saveIndex() }) }],
})
// XXX revise architecture....
// XXX move this to the argv parser used in object.js
var CLI =
module.CLI = core.ImageGridFeatures.Feature({
title: '',
doc: '',
tag: 'commandline',
depends: [
'lifecycle',
'logger',
],
// XXX should this be ONLY node???
isApplicable: function(){
return this.runtime.node && !this.runtime.browser },
actions: CLIActions,
handlers: [
// supress logging by default...
['start.pre',
function(){
this.logger
&& (this.logger.quiet = true) }],
// handle args...
['ready',
function(){
var that = this
var pkg = nodeRequire('./package.json')
argv.Parser({
// XXX argv.js is not picking these up because
// of the require(..) mixup...
author: pkg.author,
version: pkg.version,
license: pkg.license,
'-verbose': {
doc: 'Enable verbose output',
handler: function(){
that.logger
&& (that.logger.quiet = false) } },
// XXX setup presets...
// ...load sets of features and allow user
// to block/add specific features...
// XXX feature config...
// ...get/set persistent config values...
// build the action command list...
...this.cliActions
.reduce(function(res, action){
var cmd = that.getActionAttr(action, 'cli')
if(typeof(cmd) == typeof('str') || cmd === true){
var name = cmd
var cmd = {name} }
var name = name === true ?
action
: cmd.name
res[name] = {
doc: (that.getActionAttr(action, 'doc') || '')
.split(/[\\\/]/g).pop(),
// XXX revise argument passing...
// ...this must be as flexible as possible...
handler: function(rest, key, value){
return that[action](value) },
...cmd,
}
return res }, {}),
})
.onNoArgs(function(args){
console.log('No args.')
// XXX we should either start the GUI here or print help...
args.push('--help')
//args.push('gui')
})
.then(function(){
// XXX
})()
// XXX is this the right way to trigger state change
// from within a state action...
!this._keep_running
&& this.afterAction(function(){ process.exit() })
}],
],
})
/**********************************************************************
* vim:set ts=4 sw=4 : */
return module })