Prepare Build Testing
+ cleanup some comments functions + move some functions to startup.js + add ability to search videos with "startFrom" and "startTo" instead of "start" and "end"merge-requests/35/head
parent
e565b474a0
commit
224a06cb3e
|
@ -83,6 +83,6 @@ loadLib('ffmpeg')(s,config,function(){
|
|||
loadLib('cloudUploaders')(s,config,lang)
|
||||
//notifiers : discord..
|
||||
loadLib('notification')(s,config,lang)
|
||||
//on-start actions
|
||||
//on-start actions, daemon(s) starter
|
||||
loadLib('startup')(s,config,lang)
|
||||
})
|
||||
|
|
|
@ -348,7 +348,7 @@ module.exports = function(s,config,lang){
|
|||
var filename = s.formattedTime()+'.mp4'
|
||||
s.userLog(d,{type:"Traditional Recording",msg:"Started"})
|
||||
//-t 00:'+s.timeObject(new Date(detector_timeout * 1000 * 60)).format('mm:ss')+'
|
||||
s.group[d.ke].mon[d.id].eventBasedRecording.process = spawn(config.ffmpegDir,s.splitForFFPMEG(('-loglevel warning -analyzeduration 1000000 -probesize 1000000 -re -i http://'+config.ip+':'+config.port+'/'+d.auth+'/hls/'+d.ke+'/'+d.id+'/detectorStream.m3u8 -t 00:'+s.timeObject(new Date(detector_timeout * 1000 * 60)).format('mm:ss')+' -c:v copy -strftime 1 "'+s.getVideoDirectory(d.mon) + filename + '"').replace(/\s+/g,' ').trim()))
|
||||
s.group[d.ke].mon[d.id].eventBasedRecording.process = spawn(config.ffmpegDir,s.splitForFFPMEG(('-loglevel warning -analyzeduration 1000000 -probesize 1000000 -re -i http://'+config.ip+':'+config.port+'/'+d.auth+'/hls/'+d.ke+'/'+d.id+'/detectorStream.m3u8 -t 00:'+s.timeObject(new Date(detector_timeout * 1000 * 60)).format('mm:ss')+' -c:v copy -strftime 1 "'+s.getVideoDirectory(d.mon) + filename + '"')))
|
||||
var ffmpegError='';
|
||||
var error
|
||||
s.group[d.ke].mon[d.id].eventBasedRecording.process.stderr.on('data',function(data){
|
||||
|
|
|
@ -110,7 +110,7 @@ module.exports = function(s,config,onFinish){
|
|||
//ffmpeg string cleaner, splits for use with spawn()
|
||||
s.splitForFFPMEG = function (ffmpegCommandAsString) {
|
||||
//this function ignores spaces inside quotes.
|
||||
return ffmpegCommandAsString.match(/\\?.|^$/g).reduce((p, c) => {
|
||||
return ffmpegCommandAsString.replace(/\s+/g,' ').trim().match(/\\?.|^$/g).reduce((p, c) => {
|
||||
if(c === '"'){
|
||||
p.quote ^= 1;
|
||||
}else if(!p.quote && c === ' '){
|
||||
|
@ -758,7 +758,7 @@ module.exports = function(s,config,onFinish){
|
|||
x.pipe += ' -f singlejpeg '+x.detector_vf+x.cust_detect+x.dratio+' pipe:4';
|
||||
}
|
||||
}else{
|
||||
x.pipe+=' -f singlejpeg '+x.detector_vf+x.cust_detect+x.dratio+' pipe:3';
|
||||
x.pipe+=' -f image2pipe '+x.detector_vf+x.cust_detect+x.dratio+' pipe:3';
|
||||
}
|
||||
}
|
||||
//Traditional Recording Buffer
|
||||
|
@ -885,8 +885,8 @@ module.exports = function(s,config,onFinish){
|
|||
createPipeArray(e,x)
|
||||
//hold ffmpeg command for log stream
|
||||
s.group[e.ke].mon[e.mid].ffmpeg = x.ffmpegCommandString
|
||||
//clean the string of spatial impurities
|
||||
x.ffmpegCommandString = s.splitForFFPMEG(x.ffmpegCommandString.replace(/\s+/g,' ').trim())
|
||||
//clean the string of spatial impurities and split for spawn()
|
||||
x.ffmpegCommandString = s.splitForFFPMEG(x.ffmpegCommandString)
|
||||
//launch that bad boy
|
||||
return spawn(config.ffmpegDir,x.ffmpegCommandString,{detached: true,stdio:x.stdioPipes})
|
||||
}
|
||||
|
|
|
@ -1,12 +1,6 @@
|
|||
var exec = require('child_process').exec;
|
||||
var spawn = require('child_process').spawn;
|
||||
module.exports = function(s,config,lang,io){
|
||||
//check disk space every 20 minutes
|
||||
if(config.autoDropCache===true){
|
||||
setInterval(function(){
|
||||
exec('echo 3 > /proc/sys/vm/drop_caches',{detached: true})
|
||||
},60000*20);
|
||||
}
|
||||
s.sendDiskUsedAmountToClients = function(e){
|
||||
//send the amount used disk space to connected users
|
||||
if(s.group[e.ke]&&s.group[e.ke].init){
|
||||
|
@ -79,12 +73,4 @@ module.exports = function(s,config,lang,io){
|
|||
callback(0)
|
||||
}
|
||||
}
|
||||
//master node - startup functions
|
||||
setInterval(function(){
|
||||
s.cpuUsage(function(cpu){
|
||||
s.ramUsage(function(ram){
|
||||
s.tx({f:'os',cpu:cpu,ram:ram},'CPU');
|
||||
})
|
||||
})
|
||||
},10000);
|
||||
}
|
||||
|
|
16
libs/sql.js
16
libs/sql.js
|
@ -1,18 +1,16 @@
|
|||
var knex = require('knex');
|
||||
module.exports = function(s,config){
|
||||
//sql/database connection with knex
|
||||
var databaseOptions = {
|
||||
s.databaseOptions = {
|
||||
client: config.databaseType,
|
||||
connection: config.db,
|
||||
}
|
||||
if(databaseOptions.client.indexOf('sqlite')>-1){
|
||||
databaseOptions.client = 'sqlite3';
|
||||
databaseOptions.useNullAsDefault = true;
|
||||
if(s.databaseOptions.client.indexOf('sqlite')>-1){
|
||||
s.databaseOptions.client = 'sqlite3';
|
||||
s.databaseOptions.useNullAsDefault = true;
|
||||
}
|
||||
if(databaseOptions.client === 'sqlite3' && databaseOptions.connection.filename === undefined){
|
||||
databaseOptions.connection.filename = s.mainDirectory+"/shinobi.sqlite"
|
||||
if(s.databaseOptions.client === 'sqlite3' && s.databaseOptions.connection.filename === undefined){
|
||||
s.databaseOptions.connection.filename = s.mainDirectory+"/shinobi.sqlite"
|
||||
}
|
||||
s.databaseEngine = knex(databaseOptions)
|
||||
s.mergeQueryValues = function(query,values){
|
||||
if(!values){values=[]}
|
||||
var valuesNotFunction = true;
|
||||
|
@ -60,7 +58,7 @@ module.exports = function(s,config){
|
|||
console.log('s.sqlQuery ERROR',err)
|
||||
}
|
||||
if(onMoveOn && typeof onMoveOn === 'function'){
|
||||
switch(databaseOptions.client){
|
||||
switch(s.databaseOptions.client){
|
||||
case'sqlite3':
|
||||
if(!r)r=[]
|
||||
break;
|
||||
|
|
|
@ -132,10 +132,30 @@ module.exports = function(s,config,lang,io){
|
|||
}
|
||||
})
|
||||
}
|
||||
//check disk space every 20 minutes
|
||||
if(config.autoDropCache===true){
|
||||
setInterval(function(){
|
||||
exec('echo 3 > /proc/sys/vm/drop_caches',{detached: true})
|
||||
},60000*20)
|
||||
}
|
||||
//master node - startup functions
|
||||
setInterval(function(){
|
||||
s.cpuUsage(function(cpu){
|
||||
s.ramUsage(function(ram){
|
||||
s.tx({f:'os',cpu:cpu,ram:ram},'CPU');
|
||||
})
|
||||
})
|
||||
},10000)
|
||||
//run prerequsite queries, load users and monitors
|
||||
if(config.childNodes.mode !== 'child'){
|
||||
//sql/database connection with knex
|
||||
s.databaseEngine = require('knex')(s.databaseOptions)
|
||||
//run prerequsite queries
|
||||
s.preQueries()
|
||||
setTimeout(function(){
|
||||
//load administrators (groups)
|
||||
loadAdminUsers(function(){
|
||||
//load monitors (for groups)
|
||||
loadMonitors(function(){
|
||||
s.processReady()
|
||||
})
|
||||
|
|
|
@ -0,0 +1,103 @@
|
|||
module.exports = function(s,config,lang,app,io){
|
||||
var checkResult = function(functionName,expectedResult,testResult){
|
||||
if(expectedResult !== testResult){
|
||||
console.log(expectedResult,testResult)
|
||||
throw new Error('- ' + functionName + ' : Failed!')
|
||||
}else{
|
||||
console.log('- ' + functionName + ' : Success')
|
||||
}
|
||||
}
|
||||
var test = {
|
||||
"basic.js" : {
|
||||
checkRelativePath : function(){
|
||||
var expectedResult = s.mainDirectory + '/'
|
||||
var testResult = s.checkRelativePath('')
|
||||
checkResult('checkRelativePath',expectedResult,testResult)
|
||||
},
|
||||
parseJSON : function(){
|
||||
var expectedResult = {}
|
||||
var testResult = s.parseJSON('{}')
|
||||
checkResult('parseJSON',JSON.stringify(expectedResult),JSON.stringify(testResult))
|
||||
},
|
||||
stringJSON : function(){
|
||||
var expectedResult = '{}'
|
||||
var testResult = s.stringJSON({})
|
||||
checkResult('stringJSON',expectedResult,testResult)
|
||||
},
|
||||
addUserPassToUrl : function(){
|
||||
var expectedResult = 'http://user:pass@url.com'
|
||||
var testResult = s.addUserPassToUrl('http://url.com','user','pass')
|
||||
checkResult('addUserPassToUrl',expectedResult,testResult)
|
||||
},
|
||||
checkCorrectPathEnding : function(){
|
||||
var expectedResult = '/'
|
||||
var testResult = s.checkCorrectPathEnding('')
|
||||
checkResult('checkCorrectPathEnding',expectedResult,testResult)
|
||||
},
|
||||
md5 : function(){
|
||||
var expectedResult = '5f4dcc3b5aa765d61d8327deb882cf99'
|
||||
var testResult = s.md5('password')
|
||||
checkResult('md5',expectedResult,testResult)
|
||||
},
|
||||
sha256 : function(){
|
||||
var expectedResult = '9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08'
|
||||
var testResult = require('crypto').createHash('sha256').update('test').digest("hex")
|
||||
checkResult('createHash/sha256',expectedResult,testResult)
|
||||
},
|
||||
nameToTime : function(){
|
||||
var expectedResult = '2018-10-22 23:00:00'
|
||||
var testResult = s.nameToTime('2018-10-22T23-00-00.mp4')
|
||||
checkResult('nameToTime',expectedResult,testResult)
|
||||
},
|
||||
ipRange : function(){
|
||||
var expectedResult = [
|
||||
'192.168.1.1',
|
||||
'192.168.1.2',
|
||||
'192.168.1.3'
|
||||
]
|
||||
var testResult = s.ipRange('192.168.1.1','192.168.1.3')
|
||||
checkResult('ipRange',JSON.stringify(expectedResult),JSON.stringify(testResult))
|
||||
},
|
||||
portRange : function(){
|
||||
var expectedResult = [
|
||||
8000,
|
||||
8001,
|
||||
8002,
|
||||
]
|
||||
var testResult = s.portRange(8000,8002)
|
||||
checkResult('portRange',JSON.stringify(expectedResult),JSON.stringify(testResult))
|
||||
},
|
||||
getFunctionParamNames : function(){
|
||||
var testing = function(arg1,arg2){}
|
||||
var expectedResult = [
|
||||
'arg1',
|
||||
'arg2',
|
||||
]
|
||||
var testResult = s.getFunctionParamNames(testing)
|
||||
checkResult('getFunctionParamNames',JSON.stringify(expectedResult),JSON.stringify(testResult))
|
||||
}
|
||||
},
|
||||
"ffmpeg.js" : {
|
||||
splitForFFPMEG : function(){
|
||||
var expectedResult = [
|
||||
'flag1',
|
||||
'flag2',
|
||||
'flag3',
|
||||
]
|
||||
var testResult = s.splitForFFPMEG('flag1 flag2 "flag3"')
|
||||
checkResult('splitForFFPMEG',JSON.stringify(expectedResult),JSON.stringify(testResult))
|
||||
}
|
||||
}
|
||||
}
|
||||
console.log('----- Function Test Starting')
|
||||
Object.keys(test).forEach(function(libkey){
|
||||
var library = test[libkey]
|
||||
console.log('--- Testing ' + libkey + '...')
|
||||
Object.keys(library).forEach(function(key){
|
||||
var functionTest = library[key]
|
||||
functionTest()
|
||||
})
|
||||
console.log('-- Completed ' + libkey + '...')
|
||||
})
|
||||
console.log('---- Function Test Ended')
|
||||
}
|
|
@ -973,10 +973,16 @@ module.exports = function(s,config,lang,app){
|
|||
if(!req.query.endOperator||req.query.endOperator==''){
|
||||
req.query.endOperator='<='
|
||||
}
|
||||
var endIsStartTo
|
||||
var theEndParameter = '`end`'
|
||||
if(req.query.endIsStartTo){
|
||||
endIsStartTo = true
|
||||
theEndParameter = '`time`'
|
||||
}
|
||||
switch(true){
|
||||
case(req.query.start&&req.query.start!==''&&req.query.end&&req.query.end!==''):
|
||||
req.sql+=' AND `time` '+req.query.startOperator+' ? AND `end` '+req.query.endOperator+' ?';
|
||||
req.count_sql+=' AND `time` '+req.query.startOperator+' ? AND `end` '+req.query.endOperator+' ?';
|
||||
req.sql+=' AND `time` '+req.query.startOperator+' ? AND '+theEndParameter+' '+req.query.endOperator+' ?';
|
||||
req.count_sql+=' AND `time` '+req.query.startOperator+' ? AND '+theEndParameter+' '+req.query.endOperator+' ?';
|
||||
req.ar.push(req.query.start)
|
||||
req.ar.push(req.query.end)
|
||||
req.count_ar.push(req.query.start)
|
||||
|
@ -989,8 +995,8 @@ module.exports = function(s,config,lang,app){
|
|||
req.count_ar.push(req.query.start)
|
||||
break;
|
||||
case(req.query.end&&req.query.end!==''):
|
||||
req.sql+=' AND `end` '+req.query.endOperator+' ?';
|
||||
req.count_sql+=' AND `end` '+req.query.endOperator+' ?';
|
||||
req.sql+=' AND '+theEndParameter+' '+req.query.endOperator+' ?';
|
||||
req.count_sql+=' AND '+theEndParameter+' '+req.query.endOperator+' ?';
|
||||
req.ar.push(req.query.end)
|
||||
req.count_ar.push(req.query.end)
|
||||
break;
|
||||
|
@ -1021,7 +1027,7 @@ module.exports = function(s,config,lang,app){
|
|||
req.skip=0
|
||||
req.query.limit=parseInt(req.query.limit)
|
||||
}
|
||||
res.end(s.prettyPrint({isUTC:config.useUTC,total:count[0]['COUNT(*)'],limit:req.query.limit,skip:req.skip,videos:r}));
|
||||
res.end(s.prettyPrint({isUTC:config.useUTC,total:count[0]['COUNT(*)'],limit:req.query.limit,skip:req.skip,videos:r,endIsStartTo:endIsStartTo}));
|
||||
})
|
||||
})
|
||||
},res,req);
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
//
|
||||
// Shinobi
|
||||
// Copyright (C) 2016 Moe Alam, moeiscool
|
||||
//
|
||||
//
|
||||
// # Donate
|
||||
//
|
||||
// If you like what I am doing here and want me to continue please consider donating :)
|
||||
// PayPal : paypal@m03.ca
|
||||
//
|
||||
var os = require('os');
|
||||
var io = new (require('socket.io'))()
|
||||
// s = Shinobi
|
||||
s = {
|
||||
//Total Memory
|
||||
coreCount : os.cpus().length,
|
||||
//Total Memory
|
||||
totalmem : os.totalmem(),
|
||||
//Check Platform
|
||||
platform : os.platform(),
|
||||
//JSON stringify short-hand
|
||||
s : JSON.stringify,
|
||||
//Pretty Print JSON
|
||||
prettyPrint : function(obj){return JSON.stringify(obj,null,3)},
|
||||
//Check if Windows
|
||||
isWin : (process.platform === 'win32' || process.platform === 'win64'),
|
||||
//UTC Offset
|
||||
utcOffset : require('moment')().utcOffset(),
|
||||
//directory path for this file
|
||||
mainDirectory : __dirname
|
||||
}
|
||||
//library loader
|
||||
var loadLib = function(lib){
|
||||
return require(__dirname+'/libs/'+lib+'.js')
|
||||
}
|
||||
//process handlers
|
||||
loadLib('process')(process)
|
||||
//configuration loader
|
||||
var config = loadLib('config')(s)
|
||||
// change ports for test
|
||||
config.port = 9999
|
||||
if(config.childNodes && config.childNodes.enabled === true && config.childNodes.mode === 'master'){
|
||||
config.childNodes.port = 9998
|
||||
}
|
||||
//language loader
|
||||
var lang = loadLib('language')(s,config)
|
||||
//basic functions
|
||||
loadLib('basic')(s,config)
|
||||
//load extender functions
|
||||
loadLib('extenders')(s,config)
|
||||
//video processing engine
|
||||
loadLib('ffmpeg')(s,config,function(){
|
||||
//database connection : mysql, sqlite3..
|
||||
loadLib('sql')(s,config)
|
||||
//working directories : videos, streams, fileBin..
|
||||
loadLib('folders')(s,config)
|
||||
//authenticator functions : API, dashboard login..
|
||||
loadLib('auth')(s,config,lang)
|
||||
//express web server with ejs
|
||||
var app = loadLib('webServer')(s,config,lang,io)
|
||||
//web server routes : page handling..
|
||||
loadLib('webServerPaths')(s,config,lang,app)
|
||||
//web server routes for streams : streams..
|
||||
loadLib('webServerStreamPaths')(s,config,lang,app)
|
||||
//web server admin routes : create sub accounts, share monitors, share videos
|
||||
loadLib('webServerAdminPaths')(s,config,lang,app)
|
||||
//web server superuser routes : create admin accounts and manage system functions
|
||||
loadLib('webServerSuperPaths')(s,config,lang,app)
|
||||
//websocket connection handlers : login and streams..
|
||||
loadLib('socketio')(s,config,lang,io)
|
||||
//user and group functions
|
||||
loadLib('user')(s,config)
|
||||
//monitor/camera handlers
|
||||
loadLib('monitor')(s,config,lang)
|
||||
//event functions : motion, object matrix handler
|
||||
loadLib('events')(s,config,lang)
|
||||
//built-in detector functions : pam-diff..
|
||||
loadLib('detector')(s,config)
|
||||
//recording functions
|
||||
loadLib('videos')(s,config,lang)
|
||||
//plugins : websocket connected services..
|
||||
loadLib('plugins')(s,config,lang)
|
||||
//health : cpu and ram trackers..
|
||||
loadLib('health')(s,config,lang,io)
|
||||
//cluster module
|
||||
loadLib('childNode')(s,config,lang,app,io)
|
||||
//cloud uploaders : amazon s3, webdav, backblaze b2..
|
||||
loadLib('cloudUploaders')(s,config,lang)
|
||||
//notifiers : discord..
|
||||
loadLib('notification')(s,config,lang)
|
||||
//on-start actions, daemon(s) starter
|
||||
loadLib('test')(s,config,lang,app,io)
|
||||
})
|
Loading…
Reference in New Issue