2022-02-15 04:33:19 +01:00
const logger = require ( './logger.js' ) ;
const util = require ( './util.js' ) ;
const Keyfilter = require ( './keyfilter.js' ) ;
const cli = require ( './cli.js' ) ;
const spawn = require ( 'child_process' ) . spawn ;
const inputDevices = '/dev/input/' ;
const inputDevicesById = '/dev/input/by-id/' ;
class Watcher {
constructor ( config , callback ) {
if ( config == undefined || config . device == undefined ) {
return ;
}
for ( var key in config ) {
this [ key ] = config [ key ] ;
}
this . keyfilter = new Keyfilter ( config . keys ) ;
this . callback = callback ;
}
start ( ) {
if ( this . process != undefined ) {
return ;
}
logger . debug ( 'starting watcher \'' + this . device + '\'...' ) ;
2022-02-18 00:30:56 +01:00
this . process = spawn ( "evtest" , [ this . device , "|" , "grep" , "EV_KEY" ] ) ;
2022-02-15 04:33:19 +01:00
this . attachListeners ( ) ;
2022-02-16 03:28:17 +01:00
logger . info ( 'watcher \'' + this . device + '\' initialized and capturing configured events' ) ;
2022-02-15 04:33:19 +01:00
}
stop ( ) {
if ( this . process == undefined ) {
return ;
}
logger . debug ( 'stopping watcher \'' + this . device + '\'...' ) ;
this . process . kill ( ) ;
2022-02-16 03:28:17 +01:00
logger . info ( 'watcher \'' + this . device + '\' stopped' ) ;
2022-02-15 04:33:19 +01:00
}
attachListeners ( ) {
if ( this . process == undefined ) {
return ;
}
this . addStdOutListener ( ) ;
this . addStdErrListener ( ) ;
this . addCloseListener ( ) ;
this . addErrorListener ( ) ;
}
addStdOutListener ( ) {
if ( this . process == undefined ) {
return ;
}
logger . debug ( 'adding stdout listener to watcher \'' + this . device + '\'...' ) ;
this . process . stdout . on ( 'data' , ( data ) => {
if ( this . keyfilter == undefined ) {
return ;
}
var filtered = this . keyfilter . filter ( data ) ;
if ( filtered == undefined ) {
return ;
}
var msg = 'watcher \'' + this . device + '\' captured event' ;
if ( filtered . delayed ) {
logger . debug ( 'delaying captured \'' + filtered . type + '\' event for \'' + filtered . key + '\' from watcher \'' + this . device + '\'' ) ;
return ;
}
logger . info ( 'executing command \'' + filtered . command + '\' (args: \'' + filtered . args + '\') registered for captured \'' + filtered . type + '\' event for \'' + filtered . key + '\' from watcher \'' + this . device + '\'' ) ;
cli . execute ( filtered . command , filtered . args )
. then ( logger . info )
. catch ( logger . error ) ;
} ) ;
}
addStdErrListener ( ) {
if ( this . process == undefined ) {
return ;
}
logger . debug ( 'adding stderr listener to watcher \'' + this . device + '\'...' ) ;
this . process . stderr . on ( 'data' , ( data ) => {
logger . error ( data ) ;
} ) ;
}
addCloseListener ( ) {
if ( this . process == undefined ) {
return ;
}
logger . debug ( 'adding close listener to watcher \'' + this . device + '\'...' ) ;
this . process . on ( 'close' , ( code ) => {
2022-02-16 03:28:17 +01:00
if ( code == undefined ) {
code = 0 ;
}
this . code = code ;
2022-02-15 04:33:19 +01:00
logger . info ( 'watcher \'' + this . device + '\' finished with exit code ' + code ) ;
if ( this . callback != undefined ) {
2022-02-16 03:28:17 +01:00
this . callback ( this . device ) ;
2022-02-15 04:33:19 +01:00
}
} ) ;
}
addErrorListener ( ) {
if ( this . process == undefined ) {
return ;
}
logger . debug ( 'adding error listener to \'' + this . device + '\'...' ) ;
this . process . on ( 'error' , ( err ) => {
2022-02-16 02:08:21 +01:00
logger . error ( 'watcher \'' + this . device + '\' encountered an error >>> ' + err ) ;
2022-02-15 04:33:19 +01:00
} ) ;
}
check ( ) {
return new Promise ( ( resolve , reject ) => {
2022-02-16 02:08:21 +01:00
if ( ! this . keyfilter . isValid ( ) ) {
reject ( 'no key(s) defined for watcher \'' + this . device + '\'' ) ;
}
Promise . any ( [ this . device , inputDevices + this . device , inputDevicesById + this . device ] . map ( util . fileExists ) )
2022-02-15 04:33:19 +01:00
. then ( ( result ) => {
if ( result . path != this . device ) {
logger . info ( 'resolved watcher for device \'' + this . device + '\' to \'' + result . path + '\'' )
}
this . device = result . path ;
2022-02-16 03:28:17 +01:00
resolve ( this ) ;
2022-02-15 04:33:19 +01:00
} )
. catch ( reject ) ;
} ) ;
}
}
module . exports = Watcher ;