added cli progress reporting...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2020-12-09 06:27:11 +03:00
parent 040f3a7e3a
commit 8e139a80e1
5 changed files with 172 additions and 52 deletions

View File

@ -21,6 +21,8 @@ var base = require('features/base')
if(typeof(process) != 'undefined'){
var pathlib = requirejs('path')
var argv = requirejs('lib/argv')
var progress = requirejs('cli-progress')
var colors = requirejs('colors')
}
@ -61,6 +63,8 @@ var CLIActions = actions.Actions({
// XXX should this be here???
// ...move this to progress...
// XXX we are missing some beats, is this because we do not let the
// bar update before closing???
__progress: null,
showProgress: ['- System/',
function(text, value, max){
@ -71,38 +75,102 @@ var CLIActions = actions.Actions({
text[0]
: text
var state = this.__progress = this.__progress || {}
state = state[text] = state[text] || {}
var settings = this.__progress = this.__progress || {}
var state = settings[text] = settings[text] || {}
var l = Math.max(text.length, settings.__text_length || 0)
// length changed -> update the bars...
l != settings.__text_length
&& Object.entries(settings)
.forEach(function([key, value]){
value instanceof Object
&& 'bar' in value
&& value.bar.update({text: key.padEnd(l)}) })
settings.__text_length = l
// 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 ?
value = state.value =
value != null ?
(typeof(value) == typeof('str') && /[+-][0-9]+/.test(value) ?
(state.value || 0) + parseInt(value)
: value)
: state.value
max = state.max =
max != null ?
(typeof(max) == typeof('str') && /[+-][0-9]+/.test(max) ?
(state.max || 0) + parseInt(max)
: max)
: state.max
// 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 +')'
: '...')
var container = settings.__multi_bar =
settings.__multi_bar
|| new progress.MultiBar({
// XXX make this simpler...
format: '{text} {bar} {percentage}% '
+'| ETA: {eta_formatted} | {value}/{total}',
autopadding: true,
},
progress.Presets.rect)
var bar = state.bar =
state.bar || container.create(0, 0, {text: text.padEnd(l)})
// XXX do a better printout -- ncurses???
msg != state.msg
&& console.log(text + msg)
state.msg = msg
bar.setTotal(Math.max(max, value))
bar.update(value)
}],
// handle logger progress...
// XXX this is a copy from ui-progress -- need to reuse...
handleLogItem: ['- System/',
function(logger, path, status, ...rest){
var msg = path.join(': ')
var l = (rest.length == 1 && rest[0] instanceof Array) ?
rest[0].length
: rest.length
// only pass the relevant stuff...
var attrs = {}
logger.ondone
&& (attrs.ondone = logger.ondone)
logger.onclose
&& (attrs.onclose = logger.onclose)
// get keywords...
var {add, done, skip, reset, close, error} =
this.config['progress-logger-keywords']
|| {}
// setup default aliases...
add = new Set([...(add || []), 'added'])
done = new Set([...(done || [])])
skip = new Set([...(skip || []), 'skipped'])
reset = new Set([...(reset || [])])
close = new Set([...(close || []), 'closed'])
error = new Set([...(error || [])])
// close...
if(status == 'close' || close.has(status)){
//this.showProgress(path, 'close')
// reset...
} else if(status == 'reset' || reset.has(status)){
//this.showProgress(path, 'reset')
// added new item -- increase max...
// XXX show msg in the progress bar???
} else if(status == 'add' || add.has(status)){
this.showProgress(path, '+0', '+'+l)
// resolved item -- increase done...
} else if(status == 'done' || done.has(status)){
this.showProgress(path, '+'+l)
// skipped item -- increase done...
// XXX should we instead decrease max here???
// ...if not this is the same as done -- merge...
} else if(status == 'skip' || skip.has(status)){
this.showProgress(path, '+'+l)
// error...
// XXX STUB...
} else if(status == 'error' || error.has(status)){
this.showProgress(['Error'].concat(msg), '+0', '+'+l) }
}],
startREPL: ['- System/Start CLI interpreter',
{cli: '@repl'},
@ -142,6 +210,10 @@ var CLIActions = actions.Actions({
// XXX
}],
// XXX metadata caching and preview creation are not in sync, can
// this be a problem???
// ...if not, add a note...
// XXX should we support creating multiple indexes at the same time???
// 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???
@ -156,7 +228,7 @@ var CLIActions = actions.Actions({
path = util.normalizePath(path)
// XXX should we use a clean index or do this in-place???
//var index = this.constructor()
//var index = this.constructor(..)
var index = this
return index.loadImages(path)
// save base index...
@ -166,7 +238,8 @@ var CLIActions = actions.Actions({
.then(function(){
if(index.makePreviews){
return Promise.all([
index.cacheMetadata('all'),
// NOTE: this is already running after .loadImages(..)
//index.cacheMetadata('all'),
index.makePreviews('all') ])} })
.then(function(){
return index
@ -216,7 +289,7 @@ module.CLI = core.ImageGridFeatures.Feature({
license: pkg.license,
'-verbose': {
doc: 'Enable verbose output',
doc: 'Enable verbose (very) output',
handler: function(){
that.logger
&& (that.logger.quiet = false) } },

View File

@ -490,14 +490,19 @@ var SharpActions = actions.Actions({
: logger,
})
// XXX handle errors -- rejected because image exists...
.then(function(res){
.then(
function(res){
// update metadata...
if(!base_path){
var preview = img.preview = img.preview || {}
preview[parseInt(size) + 'px'] = name
that.markChanged
&& that.markChanged('images', [gid]) }
return [gid, size, name] }) })) })],
return [gid, size, name] },
function(err){
// XXX error
logger && logger.emit('skipped', gid)
}) })) })],
// XXX add support for offloading the processing to a thread/worker...
// XXX revise logging and logger passing...

View File

@ -303,7 +303,6 @@ var ProgressActions = actions.Actions({
this.config['progress-done-delay'] || 1000))) } }],
// handle logger progress...
// XXX show progress after a timeout if still not finished...
handleLogItem: ['- System/',
function(logger, path, status, ...rest){
var msg = path.join(': ')

View File

@ -368,6 +368,50 @@
"restore-cursor": "^2.0.0"
}
},
"cli-progress": {
"version": "3.8.2",
"resolved": "https://registry.npmjs.org/cli-progress/-/cli-progress-3.8.2.tgz",
"integrity": "sha512-qRwBxLldMSfxB+YGFgNRaj5vyyHe1yMpVeDL79c+7puGujdKJHQHydgqXDcrkvQgJ5U/d3lpf6vffSoVVUftVQ==",
"requires": {
"colors": "^1.1.2",
"string-width": "^4.2.0"
},
"dependencies": {
"ansi-regex": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
"integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg=="
},
"emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
},
"is-fullwidth-code-point": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
},
"string-width": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
"integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
"requires": {
"emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0",
"strip-ansi": "^6.0.0"
}
},
"strip-ansi": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
"integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
"requires": {
"ansi-regex": "^5.0.0"
}
}
}
},
"cli-spinners": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.3.0.tgz",
@ -446,12 +490,12 @@
"integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c="
},
"color": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/color/-/color-3.1.2.tgz",
"integrity": "sha512-vXTJhHebByxZn3lDvDJYw4lR5+uB3vuoHsuYA5AKuxRVn5wzzIfQKGLBmgdVRHKTJYeK5rvJcHnrd0Li49CFpg==",
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/color/-/color-3.1.3.tgz",
"integrity": "sha512-xgXAcTHa2HeFCGLE9Xs/R82hujGtu9Jd9x4NW3T34+OMs7VoPsjwzRczKHvTAHeJwWFwX5j15+MgAppE8ztObQ==",
"requires": {
"color-convert": "^1.9.1",
"color-string": "^1.5.2"
"color-string": "^1.5.4"
}
},
"color-convert": {
@ -468,9 +512,9 @@
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
},
"color-string": {
"version": "1.5.3",
"resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz",
"integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==",
"version": "1.5.4",
"resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.4.tgz",
"integrity": "sha512-57yF5yt8Xa3czSEW1jfQDE79Idk0+AkN/4KWad6tbdxUmAs3MvjxlWSWD4deYytcRfoZ9nhKyFl1kj5tBvidbw==",
"requires": {
"color-name": "^1.0.0",
"simple-swizzle": "^0.2.2"
@ -479,8 +523,7 @@
"colors": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz",
"integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==",
"dev": true
"integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA=="
},
"combined-stream": {
"version": "1.0.8",
@ -1144,6 +1187,11 @@
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
"integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw=="
},
"is-arrayish": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
"integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ=="
},
"is-fullwidth-code-point": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
@ -2085,13 +2133,6 @@
"integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=",
"requires": {
"is-arrayish": "^0.3.1"
},
"dependencies": {
"is-arrayish": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
"integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ=="
}
}
},
"source-map": {

View File

@ -20,6 +20,8 @@
"dependencies": {
"app-module-path": "^1.0.6",
"async-json": "0.0.2",
"cli-progress": "^3.8.2",
"colors": "^1.4.0",
"electron": "^9.3.5",
"exif-reader": "^1.0.3",
"exiftool": "^0.0.3",