2016-07-28 23:44:24 +00:00
/ *
Node - OpenDroneMap Node . js App and REST API to access OpenDroneMap .
2016-07-18 22:56:27 +00:00
Copyright ( C ) 2016 Node - OpenDroneMap Contributors
This program is free software : you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation , either version 3 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program . If not , see < http : //www.gnu.org/licenses/>.
* /
2016-07-08 20:44:48 +00:00
"use strict" ;
2016-09-25 00:07:02 +00:00
let fs = require ( 'fs' ) ;
let path = require ( 'path' ) ;
2016-08-02 16:07:54 +00:00
let assert = require ( 'assert' ) ;
2016-07-08 20:44:48 +00:00
let spawn = require ( 'child_process' ) . spawn ;
2016-07-29 00:31:30 +00:00
let config = require ( '../config.js' ) ;
2016-07-30 18:30:56 +00:00
let logger = require ( './logger' ) ;
2016-07-08 20:44:48 +00:00
2016-09-25 00:07:02 +00:00
2016-07-08 20:44:48 +00:00
module . exports = {
2017-03-29 18:50:57 +00:00
run : function ( options , projectName , done , outputReceived ) {
assert ( projectName !== undefined , "projectName must be specified" ) ;
2016-08-02 16:07:54 +00:00
assert ( options [ "project-path" ] !== undefined , "project-path must be defined" ) ;
2016-07-08 20:44:48 +00:00
2016-09-25 22:35:44 +00:00
let command = [ path . join ( config . odm _path , "run.py" ) ] ;
2016-07-29 22:16:22 +00:00
for ( var name in options ) {
let value = options [ name ] ;
// Skip false booleans
if ( value === false ) continue ;
command . push ( "--" + name ) ;
// We don't specify "--time true" (just "--time")
if ( typeof value !== 'boolean' ) {
command . push ( value ) ;
}
}
2016-07-30 18:30:56 +00:00
2017-03-29 18:50:57 +00:00
command . push ( projectName ) ;
2016-07-30 18:30:56 +00:00
logger . info ( ` About to run: python ${ command . join ( " " ) } ` ) ;
2016-09-25 00:07:02 +00:00
if ( config . test ) {
logger . info ( "Test mode is on, command will not execute" ) ;
2016-09-25 22:35:44 +00:00
let outputTestFile = path . join ( ".." , "tests" , "odm_output.txt" ) ;
fs . readFile ( path . resolve ( _ _dirname , outputTestFile ) , 'utf8' , ( err , text ) => {
if ( ! err ) {
let lines = text . split ( "\n" ) ;
lines . forEach ( line => outputReceived ( line ) ) ;
done ( null , 0 , null ) ;
} else {
logger . warn ( ` Error: ${ err . message } ` ) ;
done ( err ) ;
}
} ) ;
2016-09-25 00:07:02 +00:00
return ; // Skip rest
}
2016-07-08 20:44:48 +00:00
// Launch
2016-07-29 22:16:22 +00:00
let childProcess = spawn ( "python" , command , { cwd : config . odm _path } ) ;
2016-07-08 20:44:48 +00:00
childProcess
2016-07-28 21:46:28 +00:00
. on ( 'exit' , ( code , signal ) => done ( null , code , signal ) )
2016-07-08 20:44:48 +00:00
. on ( 'error' , done ) ;
2016-07-28 21:46:28 +00:00
childProcess . stdout . on ( 'data' , chunk => outputReceived ( chunk . toString ( ) ) ) ;
childProcess . stderr . on ( 'data' , chunk => outputReceived ( chunk . toString ( ) ) ) ;
2016-07-08 20:44:48 +00:00
return childProcess ;
2016-07-25 20:10:34 +00:00
} ,
getJsonOptions : function ( done ) {
2016-09-25 00:07:02 +00:00
// In test mode, we don't call ODM,
// instead we return a mock
if ( config . test ) {
2016-09-25 22:35:44 +00:00
let optionsTestFile = path . join ( ".." , "tests" , "odm_options.json" ) ;
2016-09-25 00:07:02 +00:00
fs . readFile ( path . resolve ( _ _dirname , optionsTestFile ) , 'utf8' , ( err , json ) => {
if ( ! err ) {
try {
let options = JSON . parse ( json ) ;
done ( null , options ) ;
} catch ( e ) {
2016-09-25 22:35:44 +00:00
logger . warn ( ` Invalid test options ${ optionsTestFile } : ${ err . message } ` ) ;
2016-09-25 00:07:02 +00:00
done ( e ) ;
}
} else {
2016-09-25 22:35:44 +00:00
logger . warn ( ` Error: ${ err . message } ` ) ;
2016-09-25 00:07:02 +00:00
done ( err ) ;
}
} ) ;
return ; // Skip rest
}
2016-07-25 20:10:34 +00:00
// Launch
2016-09-25 22:35:44 +00:00
let childProcess = spawn ( "python" , [ path . join ( _ _dirname , ".." , "helpers" , "odmOptionsToJson.py" ) ,
2017-03-29 18:50:57 +00:00
"--project-path" , config . odm _path , "bogusname" ] ) ;
2016-07-25 20:10:34 +00:00
let output = [ ] ;
childProcess
. on ( 'exit' , ( code , signal ) => {
try {
let json = JSON . parse ( output . join ( "" ) ) ;
done ( null , json ) ;
} catch ( err ) {
2017-01-24 13:15:43 +00:00
done ( new Error ( ` Could not load list of options from OpenDroneMap. Is OpenDroneMap installed in ${ config . odm _path } ? Make sure that OpenDroneMap is installed and that --odm_path is set properly: ${ err . message } ` ) ) ;
2016-07-25 20:10:34 +00:00
}
} )
. on ( 'error' , done ) ;
2016-07-28 21:46:28 +00:00
let processOutput = chunk => output . push ( chunk . toString ( ) ) ;
2016-07-25 20:10:34 +00:00
childProcess . stdout . on ( 'data' , processOutput ) ;
childProcess . stderr . on ( 'data' , processOutput ) ;
2016-07-08 20:44:48 +00:00
}
} ;