1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 | process.on('uncaughtException', function (err) {
|
12 | console.error('Uncaught Exception occured!');
|
13 | console.error(err.stack);
|
14 | });
|
15 | var fs = require('fs');
|
16 | var os = require('os');
|
17 | var URL = require('url');
|
18 | var path = require('path');
|
19 | var mysql = require('mysql');
|
20 | var moment = require('moment');
|
21 | var request = require("request");
|
22 | var express = require('express');
|
23 | var app = express();
|
24 | var appHTTPS = express();
|
25 | var http = require('http');
|
26 | var https = require('https');
|
27 | var server = http.createServer(app);
|
28 | var bodyParser = require('body-parser');
|
29 | var CircularJSON = require('circular-json');
|
30 | var ejs = require('ejs');
|
31 | var io = new (require('socket.io'))();
|
32 | var execSync = require('child_process').execSync;
|
33 | var exec = require('child_process').exec;
|
34 | var spawn = require('child_process').spawn;
|
35 | var crypto = require('crypto');
|
36 | var webdav = require("webdav");
|
37 | var jsonfile = require("jsonfile");
|
38 | var connectionTester = require('connection-tester');
|
39 | var events = require('events');
|
40 | var Cam = require('onvif').Cam;
|
41 | var location = {}
|
42 | location.super = __dirname+'/super.json'
|
43 | location.config = __dirname+'/conf.json'
|
44 | location.languages = __dirname+'/languages'
|
45 | location.definitions = __dirname+'/definitions'
|
46 | var config = require(location.config);
|
47 | if(!config.productType){
|
48 | config.productType='CE'
|
49 | }
|
50 | if(config.productType==='Pro'){
|
51 | var LdapAuth = require('ldapauth-fork');
|
52 | }
|
53 | if(!config.language){
|
54 | config.language='en_CA'
|
55 | }
|
56 | try{
|
57 | var lang = require(location.languages+'/'+config.language+'.json');
|
58 | }catch(er){
|
59 | console.error(er)
|
60 | console.log('There was an error loading your language file.')
|
61 | var lang = require(location.languages+'/en_CA.json');
|
62 | }
|
63 | try{
|
64 | var definitions = require(location.definitions+'/'+config.language+'.json');
|
65 | }catch(er){
|
66 | console.error(er)
|
67 | console.log('There was an error loading your language file.')
|
68 | var definitions = require(location.definitions+'/en_CA.json');
|
69 | }
|
70 | process.send = process.send || function () {};
|
71 | if(config.mail){
|
72 | var nodemailer = require('nodemailer').createTransport(config.mail);
|
73 | }
|
74 |
|
75 | if(config.cpuUsageMarker===undefined){config.cpuUsageMarker='%Cpu'}
|
76 | if(config.autoDropCache===undefined){config.autoDropCache=true}
|
77 | if(config.doSnapshot===undefined){config.doSnapshot=true}
|
78 | if(config.restart===undefined){config.restart={}}
|
79 | if(config.systemLog===undefined){config.systemLog=true}
|
80 | if(config.deleteCorruptFiles===undefined){config.deleteCorruptFiles=true}
|
81 | if(config.restart.onVideoNotExist===undefined){config.restart.onVideoNotExist=true}
|
82 | if(config.ip===undefined||config.ip===''||config.ip.indexOf('0.0.0.0')>-1){config.ip='localhost'}else{config.bindip=config.ip};
|
83 | if(config.cron===undefined)config.cron={};
|
84 | if(config.cron.deleteOverMax===undefined)config.cron.deleteOverMax=true;
|
85 | if(config.cron.deleteOverMaxOffset===undefined)config.cron.deleteOverMaxOffset=0.9;
|
86 | if(config.pluginKeys===undefined)config.pluginKeys={};
|
87 | s={factorAuth:{},child_help:false,totalmem:os.totalmem(),platform:os.platform(),s:JSON.stringify,isWin:(process.platform==='win32')};
|
88 |
|
89 | s.loadedLanguages={}
|
90 | s.loadedLanguages[config.language]=lang;
|
91 | s.getLanguageFile=function(rule){
|
92 | if(rule&&rule!==''){
|
93 | var file=s.loadedLanguages[file]
|
94 | if(!file){
|
95 | try{
|
96 | s.loadedLanguages[rule]=require(location.languages+'/'+rule+'.json')
|
97 | file=s.loadedLanguages[rule]
|
98 | }catch(err){
|
99 | file=lang
|
100 | }
|
101 | }
|
102 | }else{
|
103 | file=lang
|
104 | }
|
105 | return file
|
106 | }
|
107 |
|
108 | s.loadedDefinitons={}
|
109 | s.loadedDefinitons[config.language]=definitions;
|
110 | s.getDefinitonFile=function(rule){
|
111 | if(rule&&rule!==''){
|
112 | var file=s.loadedDefinitons[file]
|
113 | if(!file){
|
114 | try{
|
115 | s.loadedDefinitons[rule]=require(location.definitions+'/'+rule+'.json')
|
116 | file=s.loadedDefinitons[rule]
|
117 | }catch(err){
|
118 | file=definitions
|
119 | }
|
120 | }
|
121 | }else{
|
122 | file=definitions
|
123 | }
|
124 | return file
|
125 | }
|
126 | s.connectSQL=function(){
|
127 | sql = mysql.createConnection(config.db);
|
128 | sql.connect(function(err){if(err){s.systemLog(lang['Error Connecting']+' : DB',err);setTimeout(s.connectSQL, 2000);}});
|
129 | sql.on('error',function(err) {s.systemLog(lang['DB Lost.. Retrying..']);s.systemLog(err);s.connectSQL();return;});
|
130 | sql.on('connect',function() {
|
131 | s.sqlQuery = function(query,values,callback){
|
132 | if(!values){values=[]}
|
133 | return sql.query(query,values,function(err,r){
|
134 | if(err)
|
135 | s.systemLog('s.sqlQuery',err)
|
136 | if(callback)
|
137 | callback(err,r)
|
138 | })
|
139 | }
|
140 | s.sqlQuery('ALTER TABLE `Videos` ADD COLUMN `details` TEXT NULL DEFAULT NULL AFTER `status`;',function(err){
|
141 | if(err){
|
142 | s.systemLog("Critical update 1/2 already applied");
|
143 | }
|
144 | s.sqlQuery("CREATE TABLE IF NOT EXISTS `Files` (`ke` varchar(50) NOT NULL,`mid` varchar(50) NOT NULL,`name` tinytext NOT NULL,`size` float NOT NULL DEFAULT '0',`details` text NOT NULL,`status` int(1) NOT NULL DEFAULT '0') ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;",function(err){
|
145 | if(err){
|
146 | s.systemLog("Critical update 2/2 NOT applied, this could be bad");
|
147 | }else{
|
148 | s.systemLog("Critical update 2/2 already applied");
|
149 | }
|
150 | });
|
151 | });
|
152 | });
|
153 | }
|
154 | s.connectSQL();
|
155 |
|
156 | s.ffmpegKill=function(){
|
157 | var cmd=''
|
158 | if(s.isWin===true){
|
159 | cmd="Taskkill /IM ffmpeg.exe /F"
|
160 | }else{
|
161 | cmd="ps aux | grep -ie ffmpeg | awk '{print $2}' | xargs kill -9"
|
162 | }
|
163 | exec(cmd,{detached: true})
|
164 | };
|
165 | process.on('exit',s.ffmpegKill.bind(null,{cleanup:true}));
|
166 | process.on('SIGINT',s.ffmpegKill.bind(null, {exit:true}));
|
167 |
|
168 | s.child_nodes={};
|
169 | s.child_key='3123asdasdf1dtj1hjk23sdfaasd12asdasddfdbtnkkfgvesra3asdsd3123afdsfqw345';
|
170 | s.checkRelativePath=function(x){
|
171 | if(x.charAt(0)!=='/'){
|
172 | x=__dirname+'/'+x
|
173 | }
|
174 | return x
|
175 | }
|
176 | s.checkCorrectPathEnding=function(x){
|
177 | var length=x.length
|
178 | if(x.charAt(length-1)!=='/'){
|
179 | x=x+'/'
|
180 | }
|
181 | return x.replace('__DIR__',__dirname)
|
182 | }
|
183 | s.md5=function(x){return crypto.createHash('md5').update(x).digest("hex");}
|
184 | s.tx=function(z,y,x){if(x){return x.broadcast.to(y).emit('f',z)};io.to(y).emit('f',z);}
|
185 | s.cx=function(z,y,x){if(x){return x.broadcast.to(y).emit('c',z)};io.to(y).emit('c',z);}
|
186 | s.txWithSubPermissions=function(z,y,permissionChoices){
|
187 | if(typeof permissionChoices==='string'){
|
188 | permissionChoices=[permissionChoices]
|
189 | }
|
190 | if(s.group[z.ke]){
|
191 | Object.keys(s.group[z.ke].users).forEach(function(v){
|
192 | var user = s.group[z.ke].users[v]
|
193 | if(user.details.sub){
|
194 | if(user.details.allmonitors!=='1'){
|
195 | var valid=0
|
196 | var checked=permissionChoices.length
|
197 | permissionChoices.forEach(function(b){
|
198 | if(user.details[b].indexOf(z.mid)!==-1){
|
199 | ++valid
|
200 | }
|
201 | })
|
202 | if(valid===checked){
|
203 | s.tx(z,user.cnid)
|
204 | }
|
205 | }else{
|
206 | s.tx(z,user.cnid)
|
207 | }
|
208 | }else{
|
209 | s.tx(z,user.cnid)
|
210 | }
|
211 | })
|
212 | }
|
213 | }
|
214 |
|
215 | s.nameToTime=function(x){x=x.split('.')[0].split('T'),x[1]=x[1].replace(/-/g,':');x=x.join(' ');return x;}
|
216 | s.ratio=function(width,height,ratio){ratio = width / height;return ( Math.abs( ratio - 4 / 3 ) < Math.abs( ratio - 16 / 9 ) ) ? '4:3' : '16:9';}
|
217 | s.randomNumber=function(x){
|
218 | if(!x){x=10};
|
219 | return Math.floor((Math.random() * x) + 1);
|
220 | };
|
221 | s.gid=function(x){
|
222 | if(!x){x=10};var t = "";var p = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
223 | for( var i=0; i < x; i++ )
|
224 | t += p.charAt(Math.floor(Math.random() * p.length));
|
225 | return t;
|
226 | };
|
227 | s.nid=function(x){
|
228 | if(!x){x=6};var t = "";var p = "0123456789";
|
229 | for( var i=0; i < x; i++ )
|
230 | t += p.charAt(Math.floor(Math.random() * p.length));
|
231 | return t;
|
232 | };
|
233 | s.moment_withOffset=function(e,x){
|
234 | if(!e){e=new Date};if(!x){x='YYYY-MM-DDTHH-mm-ss'};
|
235 | e=moment(e);if(config.utcOffset){e=e.utcOffset(config.utcOffset)}
|
236 | return e.format(x);
|
237 | }
|
238 | s.moment=function(e,x){
|
239 | if(!e){e=new Date};if(!x){x='YYYY-MM-DDTHH-mm-ss'};
|
240 | return moment(e).format(x);
|
241 | }
|
242 | s.ipRange=function(start_ip, end_ip) {
|
243 | var start_long = s.toLong(start_ip);
|
244 | var end_long = s.toLong(end_ip);
|
245 | if (start_long > end_long) {
|
246 | var tmp=start_long;
|
247 | start_long=end_long
|
248 | end_long=tmp;
|
249 | }
|
250 | var range_array = [];
|
251 | var i;
|
252 | for (i=start_long; i<=end_long;i++) {
|
253 | range_array.push(s.fromLong(i));
|
254 | }
|
255 | return range_array;
|
256 | }
|
257 | s.portRange=function(lowEnd,highEnd){
|
258 | var list = [];
|
259 | for (var i = lowEnd; i <= highEnd; i++) {
|
260 | list.push(i);
|
261 | }
|
262 | return list;
|
263 | }
|
264 |
|
265 | s.toLong=function(ip) {
|
266 | var ipl = 0;
|
267 | ip.split('.').forEach(function(octet) {
|
268 | ipl <<= 8;
|
269 | ipl += parseInt(octet);
|
270 | });
|
271 | return(ipl >>> 0);
|
272 | };
|
273 |
|
274 |
|
275 | s.fromLong=function(ipl) {
|
276 | return ((ipl >>> 24) + '.' +
|
277 | (ipl >> 16 & 255) + '.' +
|
278 | (ipl >> 8 & 255) + '.' +
|
279 | (ipl & 255) );
|
280 | };
|
281 | s.kill=function(x,e,p){
|
282 | if(s.group[e.ke]&&s.group[e.ke].mon[e.id]&&s.group[e.ke].mon[e.id].spawn !== undefined){
|
283 | if(s.group[e.ke].mon[e.id].spawn){
|
284 | try{
|
285 | s.group[e.ke].mon[e.id].spawn.removeListener('end',s.group[e.ke].mon[e.id].spawn_exit);
|
286 | s.group[e.ke].mon[e.id].spawn.removeListener('exit',s.group[e.ke].mon[e.id].spawn_exit);
|
287 | delete(s.group[e.ke].mon[e.id].spawn_exit);
|
288 | }catch(er){}
|
289 | }
|
290 | clearTimeout(s.group[e.ke].mon[e.id].checker);
|
291 | delete(s.group[e.ke].mon[e.id].checker);
|
292 | clearTimeout(s.group[e.ke].mon[e.id].checkStream);
|
293 | delete(s.group[e.ke].mon[e.id].checkStream);
|
294 | clearTimeout(s.group[e.ke].mon[e.id].watchdog_stop);
|
295 | delete(s.group[e.ke].mon[e.id].watchdog_stop);
|
296 | if(e&&s.group[e.ke].mon[e.id].record){
|
297 | clearTimeout(s.group[e.ke].mon[e.id].record.capturing);
|
298 |
|
299 | };
|
300 | if(s.group[e.ke].mon[e.id].child_node){
|
301 | s.cx({f:'kill',d:s.init('noReference',e)},s.group[e.ke].mon[e.id].child_node_id)
|
302 | }else{
|
303 | if(!x||x===1){return};
|
304 | p=x.pid;
|
305 | if(s.group[e.ke].mon_conf[e.id].type===('dashcam'||'socket'||'jpeg'||'pipe')){
|
306 | x.stdin.pause();setTimeout(function(){x.kill('SIGTERM');delete(x);},500)
|
307 | }else{
|
308 | try{
|
309 | x.stdin.setEncoding('utf8');x.stdin.write('q');
|
310 | }catch(er){}
|
311 | }
|
312 | setTimeout(function(){exec('kill -9 '+p,{detached: true})},1000)
|
313 | }
|
314 | }
|
315 | }
|
316 |
|
317 | s.log=function(e,x){
|
318 | if(!x||!e.mid){return}
|
319 | if((e.details&&e.details.sqllog==='1')||e.mid.indexOf('$')>-1){
|
320 | s.sqlQuery('INSERT INTO Logs (ke,mid,info) VALUES (?,?,?)',[e.ke,e.mid,s.s(x)]);
|
321 | }
|
322 | s.tx({f:'log',ke:e.ke,mid:e.mid,log:x,time:moment()},'GRPLOG_'+e.ke);
|
323 |
|
324 | }
|
325 |
|
326 | s.systemLog=function(q,w,e){
|
327 | if(!w){w=''}
|
328 | if(!e){e=''}
|
329 | if(config.systemLog===true){
|
330 | if(typeof q==='string'&&sql){
|
331 | s.sqlQuery('INSERT INTO Logs (ke,mid,info) VALUES (?,?,?)',['$','$SYSTEM',s.s({type:q,msg:w})]);
|
332 | s.tx({f:'log',log:{time:moment(),ke:'$',mid:'$SYSTEM',time:moment(),info:s.s({type:q,msg:w})}},'$');
|
333 | }
|
334 | return console.log(moment().format(),q,w,e)
|
335 | }
|
336 | }
|
337 |
|
338 | if(config.ssl&&config.ssl.key&&config.ssl.cert){
|
339 | config.ssl.key=fs.readFileSync(s.checkRelativePath(config.ssl.key),'utf8')
|
340 | config.ssl.cert=fs.readFileSync(s.checkRelativePath(config.ssl.cert),'utf8')
|
341 | if(config.ssl.port===undefined){
|
342 | config.ssl.port=443
|
343 | }
|
344 | if(config.ssl.bindip===undefined){
|
345 | config.ssl.bindip=config.bindip
|
346 | }
|
347 | if(config.ssl.ca&&config.ssl.ca instanceof Array){
|
348 | config.ssl.ca.forEach(function(v,n){
|
349 | config.ssl.ca[n]=fs.readFileSync(s.checkRelativePath(v),'utf8')
|
350 | })
|
351 | }
|
352 | var serverHTTPS = https.createServer(config.ssl,app);
|
353 | serverHTTPS.listen(config.ssl.port,config.bindip,function(){
|
354 | console.log('SSL '+lang.Shinobi+' - SSL PORT : '+config.ssl.port);
|
355 | });
|
356 | io.attach(serverHTTPS);
|
357 | }
|
358 |
|
359 | server.listen(config.port,config.bindip,function(){
|
360 | console.log(lang.Shinobi+' - PORT : '+config.port);
|
361 | });
|
362 | io.attach(server);
|
363 | console.log('NODE.JS version : '+execSync("node -v"))
|
364 |
|
365 | if(!config.ffmpegDir){
|
366 | if(s.isWin===true){
|
367 | config.ffmpegDir=__dirname+'/ffmpeg/ffmpeg.exe'
|
368 | }else{
|
369 | config.ffmpegDir='ffmpeg'
|
370 | }
|
371 | }
|
372 | s.ffmpegVersion=execSync(config.ffmpegDir+" -version").toString().split('Copyright')[0].replace('ffmpeg version','').trim()
|
373 | console.log('FFMPEG version : '+s.ffmpegVersion)
|
374 | if(s.ffmpegVersion.indexOf(': 2.')>-1){
|
375 | s.systemLog('FFMPEG is too old : '+s.ffmpegVersion+', Needed : 3.2+',err)
|
376 | return
|
377 | }
|
378 |
|
379 | s.group={};
|
380 | if(!config.windowsTempDir&&s.isWin===true){config.windowsTempDir='C:/Windows/Temp'}
|
381 | if(!config.defaultMjpeg){config.defaultMjpeg=__dirname+'/web/libs/img/bg.jpg'}
|
382 |
|
383 | if(!config.streamDir){
|
384 | if(s.isWin===false){
|
385 | config.streamDir='/dev/shm'
|
386 | }else{
|
387 | config.streamDir=config.windowsTempDir
|
388 | }
|
389 | if(!fs.existsSync(config.streamDir)){
|
390 | config.streamDir=__dirname+'/streams/'
|
391 | }else{
|
392 | config.streamDir+='/streams/'
|
393 | }
|
394 | }
|
395 | if(!config.videosDir){config.videosDir=__dirname+'/videos/'}
|
396 | if(!config.binDir){config.binDir=__dirname+'/fileBin/'}
|
397 | if(!config.addStorage){config.addStorage=[]}
|
398 | s.dir={
|
399 | videos:s.checkCorrectPathEnding(config.videosDir),
|
400 | streams:s.checkCorrectPathEnding(config.streamDir),
|
401 | fileBin:s.checkCorrectPathEnding(config.binDir),
|
402 | addStorage:config.addStorage,
|
403 | languages:location.languages+'/'
|
404 | };
|
405 |
|
406 | if(!fs.existsSync(s.dir.streams)){
|
407 | fs.mkdirSync(s.dir.streams);
|
408 | }
|
409 |
|
410 | if(!fs.existsSync(s.dir.videos)){
|
411 | fs.mkdirSync(s.dir.videos);
|
412 | }
|
413 |
|
414 | if(!fs.existsSync(s.dir.fileBin)){
|
415 | fs.mkdirSync(s.dir.fileBin);
|
416 | }
|
417 |
|
418 | s.dir.addStorage.forEach(function(v,n){
|
419 | v.path=s.checkCorrectPathEnding(v.path)
|
420 | if(!fs.existsSync(v.path)){
|
421 | fs.mkdirSync(v.path);
|
422 | }
|
423 | })
|
424 |
|
425 | s.init=function(x,e,k,fn){
|
426 | if(!e){e={}}
|
427 | if(!k){k={}}
|
428 | switch(x){
|
429 | case 0:
|
430 | if(!s.group[e.ke]){s.group[e.ke]={}};
|
431 | if(!s.group[e.ke].fileBin){s.group[e.ke].fileBin={}};
|
432 | if(!s.group[e.ke].mon){s.group[e.ke].mon={}}
|
433 | if(!s.group[e.ke].sizeChangeQueue){s.group[e.ke].sizeChangeQueue=[]}
|
434 | if(!s.group[e.ke].sizePurgeQueue){s.group[e.ke].sizePurgeQueue=[]}
|
435 | if(!s.group[e.ke].users){s.group[e.ke].users={}}
|
436 | if(!s.group[e.ke].mon[e.mid]){s.group[e.ke].mon[e.mid]={}}
|
437 | if(!s.group[e.ke].mon[e.mid].streamIn){s.group[e.ke].mon[e.mid].streamIn={}};
|
438 | if(!s.group[e.ke].mon[e.mid].watch){s.group[e.ke].mon[e.mid].watch={}};
|
439 | if(!s.group[e.ke].mon[e.mid].fixingVideos){s.group[e.ke].mon[e.mid].fixingVideos={}};
|
440 | if(!s.group[e.ke].mon[e.mid].record){s.group[e.ke].mon[e.mid].record={yes:e.record}};
|
441 | if(!s.group[e.ke].mon[e.mid].started){s.group[e.ke].mon[e.mid].started=0};
|
442 | if(s.group[e.ke].mon[e.mid].delete){clearTimeout(s.group[e.ke].mon[e.mid].delete)}
|
443 | if(!s.group[e.ke].mon_conf){s.group[e.ke].mon_conf={}}
|
444 | s.init('apps',e)
|
445 | break;
|
446 | case'apps':
|
447 | if(!s.group[e.ke].init){
|
448 | s.group[e.ke].init={};
|
449 | }
|
450 | if(!s.group[e.ke].webdav||!s.group[e.ke].sizeLimit){
|
451 | s.sqlQuery('SELECT * FROM Users WHERE ke=? AND details NOT LIKE ?',[e.ke,'%"sub"%'],function(ar,r){
|
452 | if(r&&r[0]){
|
453 | r=r[0];
|
454 | ar=JSON.parse(r.details);
|
455 |
|
456 | if(ar.webdav_user&&
|
457 | ar.webdav_user!==''&&
|
458 | ar.webdav_pass&&
|
459 | ar.webdav_pass!==''&&
|
460 | ar.webdav_url&&
|
461 | ar.webdav_url!==''
|
462 | ){
|
463 | if(!ar.webdav_dir||ar.webdav_dir===''){
|
464 | ar.webdav_dir='/';
|
465 | if(ar.webdav_dir.slice(-1)!=='/'){ar.webdav_dir+='/';}
|
466 | }
|
467 | s.group[e.ke].webdav = webdav(
|
468 | ar.webdav_url,
|
469 | ar.webdav_user,
|
470 | ar.webdav_pass
|
471 | );
|
472 | }
|
473 | Object.keys(ar).forEach(function(v){
|
474 | s.group[e.ke].init[v]=ar[v]
|
475 | })
|
476 | }
|
477 | });
|
478 | }
|
479 | break;
|
480 | case'sync':
|
481 | e.cn=Object.keys(s.child_nodes);
|
482 | e.cn.forEach(function(v){
|
483 | if(s.group[e.ke]){
|
484 | s.cx({f:'sync',sync:s.init('noReference',s.group[e.ke].mon[e.mid]),ke:e.ke,mid:e.mid},s.child_nodes[v].cnid);
|
485 | }
|
486 | });
|
487 | break;
|
488 | case'noReference':
|
489 | x={keys:Object.keys(e),ar:{}};
|
490 | x.keys.forEach(function(v){
|
491 | if(v!=='last_frame'&&v!=='record'&&v!=='spawn'&&v!=='running'&&(v!=='time'&&typeof e[v]!=='function')){x.ar[v]=e[v];}
|
492 | });
|
493 | return x.ar;
|
494 | break;
|
495 | case'url':
|
496 |
|
497 | e.authd='';
|
498 | if(e.details.muser&&e.details.muser!==''&&e.host.indexOf('@')===-1) {
|
499 | e.authd=e.details.muser+':'+e.details.mpass+'@';
|
500 | }
|
501 | if(e.port==80&&e.details.port_force!=='1'){e.porty=''}else{e.porty=':'+e.port}
|
502 | e.url=e.protocol+'://'+e.authd+e.host+e.porty+e.path;return e.url;
|
503 | break;
|
504 | case'url_no_path':
|
505 | e.authd='';
|
506 | if(!e.details.muser){e.details.muser=''}
|
507 | if(!e.details.mpass){e.details.mpass=''}
|
508 | if(e.details.muser!==''&&e.host.indexOf('@')===-1) {
|
509 | e.authd=e.details.muser+':'+e.details.mpass+'@';
|
510 | }
|
511 | if(e.port==80&&e.details.port_force!=='1'){e.porty=''}else{e.porty=':'+e.port}
|
512 | e.url=e.protocol+'://'+e.authd+e.host+e.porty;return e.url;
|
513 | break;
|
514 | case'diskUsedEmit':
|
515 |
|
516 | if(s.group[e.ke]&&s.group[e.ke].init){
|
517 | s.tx({f:'diskUsed',size:s.group[e.ke].usedSpace,limit:s.group[e.ke].sizeLimit},'GRP_'+e.ke);
|
518 | }
|
519 | break;
|
520 | case'diskUsedSet':
|
521 |
|
522 | s.group[e.ke].sizeChangeQueue.push(k)
|
523 | if(s.group[e.ke].sizeChanging!==true){
|
524 |
|
525 | s.group[e.ke].sizeChanging=true
|
526 |
|
527 | if(!s.group[e.ke].usedSpace){s.group[e.ke].usedSpace=0}else{s.group[e.ke].usedSpace=parseFloat(s.group[e.ke].usedSpace)}
|
528 | if(s.group[e.ke].usedSpace<0){s.group[e.ke].usedSpace=0}
|
529 |
|
530 | var checkQueue=function(){
|
531 |
|
532 | var currentChange = s.group[e.ke].sizeChangeQueue[0]
|
533 |
|
534 | s.group[e.ke].usedSpace=s.group[e.ke].usedSpace+currentChange
|
535 |
|
536 | s.group[e.ke].sizeChangeQueue = s.group[e.ke].sizeChangeQueue.splice(1,s.group[e.ke].sizeChangeQueue.length+10)
|
537 |
|
538 | if(s.group[e.ke].sizeChangeQueue.length>0){
|
539 | checkQueue()
|
540 | }else{
|
541 | s.group[e.ke].sizeChanging=false
|
542 | s.init('diskUsedEmit',e)
|
543 | }
|
544 | }
|
545 | checkQueue()
|
546 | }
|
547 | break;
|
548 | }
|
549 | if(typeof e.callback==='function'){setTimeout(function(){e.callback()},500);}
|
550 | }
|
551 | s.filter=function(x,d){
|
552 | switch(x){
|
553 | case'archive':
|
554 | d.videos.forEach(function(v,n){
|
555 | s.video('archive',v)
|
556 | })
|
557 | break;
|
558 | case'email':
|
559 | if(d.videos&&d.videos.length>0){
|
560 | d.videos.forEach(function(v,n){
|
561 |
|
562 | })
|
563 | d.mailOptions = {
|
564 | from: '"ShinobiCCTV" <no-reply@shinobi.video>',
|
565 | to: d.mail,
|
566 | subject: lang['Filter Matches']+' : '+d.name,
|
567 | html: lang.FilterMatchesText1+' '+d.videos.length+' '+lang.FilterMatchesText2,
|
568 | };
|
569 | if(d.execute&&d.execute!==''){
|
570 | d.mailOptions.html+='<div><b>'+lang.Executed+' :</b> '+d.execute+'</div>'
|
571 | }
|
572 | if(d.delete==='1'){
|
573 | d.mailOptions.html+='<div><b>'+lang.Deleted+' :</b> '+lang.Yes+'</div>'
|
574 | }
|
575 | d.mailOptions.html+='<div><b>'+lang.Query+' :</b> '+d.query+'</div>'
|
576 | d.mailOptions.html+='<div><b>'+lang['Filter ID']+' :</b> '+d.id+'</div>'
|
577 | nodemailer.sendMail(d.mailOptions, (error, info) => {
|
578 | if (error) {
|
579 | s.tx({f:'error',ff:'filter_mail',ke:d.ke,error:error},'GRP_'+d.ke);
|
580 | return ;
|
581 | }
|
582 | s.tx({f:'filter_mail',ke:d.ke,info:info},'GRP_'+d.ke);
|
583 | });
|
584 | }
|
585 | break;
|
586 | case'delete':
|
587 | d.videos.forEach(function(v,n){
|
588 | s.video('delete',v)
|
589 | })
|
590 | break;
|
591 | case'execute':
|
592 | exec(d.execute,{detached: true})
|
593 | break;
|
594 | }
|
595 | }
|
596 | s.video=function(x,e){
|
597 | if(!e){e={}};
|
598 | switch(x){
|
599 | case'getDir':
|
600 | if(e.mid&&!e.id){e.id=e.mid};
|
601 | if(e.details&&(e.details instanceof Object)===false){
|
602 | try{e.details=JSON.parse(e.details)}catch(err){}
|
603 | }
|
604 | if(e.details&&e.details.dir&&e.details.dir!==''){
|
605 | return s.checkCorrectPathEnding(e.details.dir)+e.ke+'/'+e.id+'/'
|
606 | }else{
|
607 | return s.dir.videos+e.ke+'/'+e.id+'/';
|
608 | }
|
609 | break;
|
610 | }
|
611 | var k={}
|
612 | if(x!=='getDir'){e.dir=s.video('getDir',e)}
|
613 | switch(x){
|
614 | case'fix':
|
615 | e.sdir=s.dir.streams+e.ke+'/'+e.id+'/';
|
616 | if(!e.filename&&e.time){e.filename=s.moment(e.time)}
|
617 | if(e.filename.indexOf('.')===-1){
|
618 | e.filename=e.filename+'.'+e.ext
|
619 | }
|
620 | s.tx({f:'video_fix_start',mid:e.mid,ke:e.ke,filename:e.filename},'GRP_'+e.ke)
|
621 | s.group[e.ke].mon[e.id].fixingVideos[e.filename]={}
|
622 | switch(e.ext){
|
623 | case'mp4':
|
624 | e.fixFlags='-vcodec libx264 -acodec aac -strict -2';
|
625 | break;
|
626 | case'webm':
|
627 | e.fixFlags='-vcodec libvpx -acodec libvorbis';
|
628 | break;
|
629 | }
|
630 | e.spawn=spawn(config.ffmpegDir,('-i '+e.dir+e.filename+' '+e.fixFlags+' '+e.sdir+e.filename).split(' '),{detached: true})
|
631 | e.spawn.stdout.on('data',function(data){
|
632 | s.tx({f:'video_fix_data',mid:e.mid,ke:e.ke,filename:e.filename},'GRP_'+e.ke)
|
633 | });
|
634 | e.spawn.on('close',function(data){
|
635 | exec('mv '+e.dir+e.filename+' '+e.sdir+e.filename,{detached: true}).on('exit',function(){
|
636 | s.tx({f:'video_fix_success',mid:e.mid,ke:e.ke,filename:e.filename},'GRP_'+e.ke)
|
637 | delete(s.group[e.ke].mon[e.id].fixingVideos[e.filename]);
|
638 | })
|
639 | });
|
640 | break;
|
641 | case'archive':
|
642 | if(!e.filename&&e.time){e.filename=s.moment(e.time)}
|
643 | if(!e.status){e.status=0}
|
644 | e.details.archived="1"
|
645 | e.save=[JSON.stringify(e.details),e.id,e.ke,s.nameToTime(e.filename)];
|
646 | s.sqlQuery('UPDATE Videos SET details=? WHERE `mid`=? AND `ke`=? AND `time`=?',e.save,function(err,r){
|
647 | s.tx({f:'video_edit',status:3,filename:e.filename+'.'+e.ext,mid:e.mid,ke:e.ke,time:s.nameToTime(e.filename)},'GRP_'+e.ke);
|
648 | });
|
649 | break;
|
650 | case'delete':
|
651 | if(!e.filename&&e.time){e.filename=s.moment(e.time)}
|
652 | if(!e.status){e.status=0}
|
653 | e.save=[e.id,e.ke,s.nameToTime(e.filename)];
|
654 | s.sqlQuery('SELECT * FROM Videos WHERE `mid`=? AND `ke`=? AND `time`=?',e.save,function(err,r){
|
655 | if(r&&r[0]){
|
656 | r=r[0]
|
657 | e.dir=s.video('getDir',r)
|
658 | s.sqlQuery('DELETE FROM Videos WHERE `mid`=? AND `ke`=? AND `time`=?',e.save,function(){
|
659 | fs.stat(e.dir+e.filename+'.'+e.ext,function(err,file){
|
660 | if(err){
|
661 | s.systemLog('File Delete Error : '+e.ke+' : '+' : '+e.mid,err)
|
662 | }
|
663 | s.init('diskUsedSet',e,-(r.size/1000000))
|
664 | })
|
665 | s.tx({f:'video_delete',filename:e.filename+'.'+e.ext,mid:e.mid,ke:e.ke,time:s.nameToTime(e.filename),end:s.moment(new Date,'YYYY-MM-DD HH:mm:ss')},'GRP_'+e.ke);
|
666 | s.file('delete',e.dir+e.filename+'.'+e.ext)
|
667 | })
|
668 | }
|
669 | })
|
670 | break;
|
671 | case'open':
|
672 |
|
673 | e.save=[e.id,e.ke,s.nameToTime(e.filename),e.ext];
|
674 | if(!e.status){e.save.push(0)}else{e.save.push(e.status)}
|
675 | k.details={}
|
676 | if(e.details&&e.details.dir&&e.details.dir!==''){
|
677 | k.details.dir=e.details.dir
|
678 | }
|
679 | e.save.push(s.s(k.details))
|
680 | s.sqlQuery('INSERT INTO Videos (mid,ke,time,ext,status,details) VALUES (?,?,?,?,?,?)',e.save)
|
681 | s.tx({f:'video_build_start',filename:e.filename+'.'+e.ext,mid:e.id,ke:e.ke,time:s.nameToTime(e.filename),end:s.moment(new Date,'YYYY-MM-DD HH:mm:ss')},'GRP_'+e.ke);
|
682 | break;
|
683 | case'close':
|
684 |
|
685 | if(s.group[e.ke]&&s.group[e.ke].mon[e.id]){
|
686 | if(s.group[e.ke].mon[e.id].open&&!e.filename){e.filename=s.group[e.ke].mon[e.id].open;e.ext=s.group[e.ke].mon[e.id].open_ext}
|
687 | if(s.group[e.ke].mon[e.id].child_node){
|
688 | s.cx({f:'close',d:s.init('noReference',e)},s.group[e.ke].mon[e.id].child_node_id);
|
689 | }else{
|
690 | k.file=e.filename+'.'+e.ext
|
691 | k.dir=e.dir.toString()
|
692 | k.fileExists=fs.existsSync(k.dir+k.file)
|
693 | if(k.fileExists!==true){
|
694 | k.dir=s.dir.videos+'/'+e.ke+'/'+e.id+'/'
|
695 | k.fileExists=fs.existsSync(k.dir+k.file)
|
696 | if(k.fileExists!==true){
|
697 | s.dir.addStorage.forEach(function(v){
|
698 | if(k.fileExists!==true){
|
699 | k.dir=s.checkCorrectPathEnding(v.path)+e.ke+'/'+e.id+'/'
|
700 | k.fileExists=fs.existsSync(k.dir+k.file)
|
701 | }
|
702 | })
|
703 | }
|
704 | }
|
705 | if(k.fileExists===true){
|
706 | k.stat=fs.statSync(k.dir+k.file);
|
707 | e.filesize=k.stat.size;
|
708 | e.filesizeMB=parseFloat((e.filesize/1000000).toFixed(2));
|
709 | e.end_time=s.moment(k.stat.mtime,'YYYY-MM-DD HH:mm:ss');
|
710 | e.save=[e.filesize,1,e.end_time,e.id,e.ke,s.nameToTime(e.filename)];
|
711 | if(!e.status){e.save.push(0)}else{e.save.push(e.status)}
|
712 | s.sqlQuery('UPDATE Videos SET `size`=?,`status`=?,`end`=? WHERE `mid`=? AND `ke`=? AND `time`=? AND `status`=?',e.save)
|
713 | s.txWithSubPermissions({f:'video_build_success',hrefNoAuth:'/videos/'+e.ke+'/'+e.mid+'/'+k.file,filename:k.file,mid:e.id,ke:e.ke,time:moment(s.nameToTime(e.filename)).format(),size:e.filesize,end:moment(e.end_time).format()},'GRP_'+e.ke,'video_view');
|
714 |
|
715 |
|
716 |
|
717 | if(s.group[e.ke].webdav&&s.group[e.ke].init.use_webdav!=='0'&&s.group[e.ke].init.webdav_save=="1"){
|
718 | fs.readFile(k.dir+k.file,function(err,data){
|
719 | s.group[e.ke].webdav.putFileContents(s.group[e.ke].init.webdav_dir+e.ke+'/'+e.mid+'/'+k.file,"binary",data)
|
720 | .catch(function(err) {
|
721 | s.log(e,{type:lang['Webdav Error'],msg:{msg:lang.WebdavErrorText+' <b>/'+e.ke+'/'+e.id+'</b>',info:err},ffmpeg:s.group[e.ke].mon[e.id].ffmpeg})
|
722 | console.error(err);
|
723 | });
|
724 | });
|
725 | }
|
726 | if(s.group[e.ke].init){
|
727 | s.init('diskUsedSet',e,e.filesizeMB)
|
728 | if(config.cron.deleteOverMax===true){
|
729 |
|
730 | s.group[e.ke].sizePurgeQueue.push(1)
|
731 | if(s.group[e.ke].sizePurging!==true){
|
732 |
|
733 | s.group[e.ke].sizePurging=true
|
734 |
|
735 | var finish=function(){
|
736 |
|
737 |
|
738 | s.group[e.ke].sizePurgeQueue = s.group[e.ke].sizePurgeQueue.splice(1,s.group[e.ke].sizePurgeQueue.length+10)
|
739 |
|
740 | if(s.group[e.ke].sizePurgeQueue.length>0){
|
741 | checkQueue()
|
742 | }else{
|
743 |
|
744 | s.group[e.ke].sizePurging=false
|
745 | s.init('diskUsedEmit',e)
|
746 | }
|
747 | }
|
748 | var checkQueue=function(){
|
749 |
|
750 |
|
751 | var currentPurge = s.group[e.ke].sizePurgeQueue[0]
|
752 | var deleteVideos = function(){
|
753 |
|
754 |
|
755 | if(s.group[e.ke].usedSpace>(s.group[e.ke].sizeLimit*config.cron.deleteOverMaxOffset)){
|
756 | s.sqlQuery('SELECT * FROM Videos WHERE status != 0 AND details NOT LIKE \'%"archived":"1"%\' AND ke=? ORDER BY `time` ASC LIMIT 2',[e.ke],function(err,evs){
|
757 | k.del=[];k.ar=[e.ke];
|
758 | evs.forEach(function(ev){
|
759 | ev.dir=s.video('getDir',ev)+s.moment(ev.time)+'.'+ev.ext;
|
760 | k.del.push('(mid=? AND time=?)');
|
761 | k.ar.push(ev.mid),k.ar.push(ev.time);
|
762 | s.file('delete',ev.dir);
|
763 | s.init('diskUsedSet',e,-(ev.size/1000000))
|
764 | s.tx({f:'video_delete',ff:'over_max',filename:s.moment(ev.time)+'.'+ev.ext,mid:ev.mid,ke:ev.ke,time:ev.time,end:s.moment(new Date,'YYYY-MM-DD HH:mm:ss')},'GRP_'+e.ke);
|
765 | });
|
766 | if(k.del.length>0){
|
767 | k.qu=k.del.join(' OR ');
|
768 | s.sqlQuery('DELETE FROM Videos WHERE ke =? AND ('+k.qu+')',k.ar,function(){
|
769 | deleteVideos()
|
770 | })
|
771 | }else{
|
772 | finish()
|
773 | }
|
774 | })
|
775 | }else{
|
776 | finish()
|
777 | }
|
778 | }
|
779 | deleteVideos()
|
780 | }
|
781 | checkQueue()
|
782 | }
|
783 | }else{
|
784 | s.init('diskUsedEmit',e)
|
785 | }
|
786 | }
|
787 | }else{
|
788 | s.video('delete',e);
|
789 | s.log(e,{type:lang['File Not Exist'],msg:lang.FileNotExistText,ffmpeg:s.group[e.ke].mon[e.id].ffmpeg})
|
790 | if(e.mode&&config.restart.onVideoNotExist===true&&e.fn){
|
791 | delete(s.group[e.ke].mon[e.id].open);
|
792 | s.log(e,{type:lang['Camera is not recording'],msg:{msg:lang.CameraNotRecordingText}});
|
793 | if(s.group[e.ke].mon[e.id].started===1){
|
794 | s.camera('restart',e)
|
795 | }
|
796 | }
|
797 | }
|
798 | }
|
799 | }
|
800 | delete(s.group[e.ke].mon[e.id].open);
|
801 | break;
|
802 | }
|
803 | }
|
804 | s.ffmpeg=function(e,x){
|
805 |
|
806 | if(!x){x={tmp:''}}
|
807 |
|
808 | x.record_string=''
|
809 | x.cust_input=''
|
810 | x.cust_detect=' '
|
811 | x.record_video_filters=[]
|
812 | x.stream_video_filters=[]
|
813 | x.hwaccel=''
|
814 |
|
815 | if(e.details.aduration&&e.details.aduration!==''){x.cust_input+=' -analyzeduration '+e.details.aduration};
|
816 |
|
817 | if(e.details.probesize&&e.details.probesize!==''){x.cust_input+=' -probesize '+e.details.probesize};
|
818 |
|
819 |
|
820 | switch(e.type){
|
821 | case'h264':
|
822 | switch(e.protocol){
|
823 | case'rtsp':
|
824 | if(e.details.rtsp_transport&&e.details.rtsp_transport!==''&&e.details.rtsp_transport!=='no'){x.cust_input+=' -rtsp_transport '+e.details.rtsp_transport;}
|
825 | break;
|
826 | }
|
827 | break;
|
828 | }
|
829 |
|
830 | switch(s.ratio(e.width,e.height)){
|
831 | case'16:9':
|
832 | x.ratio='640x360';
|
833 | break;
|
834 | default:
|
835 | x.ratio='640x480';
|
836 | break;
|
837 | }
|
838 | if(e.width!==''&&e.height!==''&&!isNaN(e.width)&&!isNaN(e.height)){
|
839 | x.record_dimensions=' -s '+e.width+'x'+e.height
|
840 | }else{
|
841 | x.record_dimensions=''
|
842 | }
|
843 | if(e.details.stream_scale_x&&e.details.stream_scale_x!==''&&e.details.stream_scale_y&&e.details.stream_scale_y!==''){
|
844 | x.ratio=e.details.stream_scale_x+'x'+e.details.stream_scale_y;
|
845 | }
|
846 |
|
847 | x.segment=' -f segment -segment_atclocktime 1 -reset_timestamps 1 -strftime 1 -segment_list pipe:2 -segment_time '+(60*e.cutoff)+' ';
|
848 |
|
849 | if(e.details.dqf=='1'){
|
850 | x.segment+='"'+e.dir+'%Y-%m-%dT%H-%M-%S.'+e.ext+'"';
|
851 | }else{
|
852 | x.segment+=e.dir+'%Y-%m-%dT%H-%M-%S.'+e.ext;
|
853 | }
|
854 |
|
855 | switch(e.ext){
|
856 | case'mp4':
|
857 | x.vcodec='libx264';x.acodec='aac';
|
858 | if(e.details.crf&&e.details.crf!==''){x.vcodec+=' -crf '+e.details.crf}
|
859 | break;
|
860 | case'webm':
|
861 | x.acodec='libvorbis',x.vcodec='libvpx';
|
862 | if(e.details.crf&&e.details.crf!==''){x.vcodec+=' -q:v '+e.details.crf}else{x.vcodec+=' -q:v 1';}
|
863 | break;
|
864 | }
|
865 |
|
866 | if(e.details.vcodec&&e.details.vcodec!==''&&e.details.vcodec!=='default'){x.vcodec=e.details.vcodec}
|
867 |
|
868 | if(e.details.acodec&&e.details.acodec!==''&&e.details.acodec!=='default'){x.acodec=e.details.acodec}
|
869 | if(e.details.cust_record){
|
870 | if(x.acodec=='aac'&&e.details.cust_record.indexOf('-strict -2')===-1){e.details.cust_record+=' -strict -2';}
|
871 | if(e.details.cust_record.indexOf('-threads')===-1){e.details.cust_record+=' -threads 1';}
|
872 | }
|
873 |
|
874 |
|
875 | if(x.acodec!=='no'){
|
876 | if(x.acodec.indexOf('none')>-1){x.acodec=''}else{x.acodec=' -acodec '+x.acodec}
|
877 | }else{
|
878 | x.acodec=' -an'
|
879 | }
|
880 | if(x.vcodec.indexOf('none')>-1){x.vcodec=''}else{x.vcodec=' -vcodec '+x.vcodec}
|
881 |
|
882 | if(!e.details.sfps||e.details.sfps===''){
|
883 | e.details.sfps=parseFloat(e.details.sfps);
|
884 | if(isNaN(e.details.sfps)){e.details.sfps=1}
|
885 | }
|
886 | if(e.fps&&e.fps!==''){x.framerate=' -r '+e.fps}else{x.framerate=''}
|
887 | if(e.details.stream_fps&&e.details.stream_fps!==''){x.stream_fps=' -r '+e.details.stream_fps}else{x.stream_fps=''}
|
888 |
|
889 | if(e.details.timestamp&&e.details.timestamp=="1"&&e.details.vcodec!=='copy'){
|
890 |
|
891 | if(e.details.timestamp_font&&e.details.timestamp_font!==''){x.time_font=e.details.timestamp_font}else{x.time_font='/usr/share/fonts/truetype/freefont/FreeSans.ttf'}
|
892 |
|
893 | if(e.details.timestamp_x&&e.details.timestamp_x!==''){x.timex=e.details.timestamp_x}else{x.timex='(w-tw)/2'}
|
894 |
|
895 | if(e.details.timestamp_y&&e.details.timestamp_y!==''){x.timey=e.details.timestamp_y}else{x.timey='0'}
|
896 |
|
897 | if(e.details.timestamp_color&&e.details.timestamp_color!==''){x.time_color=e.details.timestamp_color}else{x.time_color='white'}
|
898 |
|
899 | if(e.details.timestamp_box_color&&e.details.timestamp_box_color!==''){x.time_box_color=e.details.timestamp_box_color}else{x.time_box_color='0x00000000@1'}
|
900 |
|
901 | if(e.details.timestamp_font_size&&e.details.timestamp_font_size!==''){x.time_font_size=e.details.timestamp_font_size}else{x.time_font_size='10'}
|
902 |
|
903 | x.record_video_filters.push('drawtext=fontfile='+x.time_font+':text=\'%{localtime}\':x='+x.timex+':y='+x.timey+':fontcolor='+x.time_color+':box=1:boxcolor='+x.time_box_color+':fontsize='+x.time_font_size);
|
904 | }
|
905 |
|
906 | if(e.details.watermark&&e.details.watermark=="1"&&e.details.watermark_location&&e.details.watermark_location!==''){
|
907 | switch(e.details.watermark_position){
|
908 | case'tl':
|
909 | x.watermark_position='10:10'
|
910 | break;
|
911 | case'tr':
|
912 | x.watermark_position='main_w-overlay_w-10:10'
|
913 | break;
|
914 | case'bl':
|
915 | x.watermark_position='10:main_h-overlay_h-10'
|
916 | break;
|
917 | default:
|
918 | x.watermark_position='(main_w-overlay_w-10)/2:(main_h-overlay_h-10)/2'
|
919 | break;
|
920 | }
|
921 | x.record_video_filters.push('movie='+e.details.watermark_location+'[watermark],[in][watermark]overlay='+x.watermark_position+'[out]');
|
922 | }
|
923 |
|
924 | if(e.details.rotate_record&&e.details.rotate_record!==""&&e.details.rotate_record!=="no"&&e.details.stream_vcodec!=="copy"){
|
925 | x.record_video_filters.push('transpose='+e.details.rotate_record);
|
926 | }
|
927 |
|
928 | if(e.details.vf&&e.details.vf!==''){
|
929 | x.record_video_filters.push(e.details.vf)
|
930 | }
|
931 |
|
932 | if(x.record_video_filters.length>0){
|
933 | x.record_video_filters=' -vf '+x.record_video_filters.join(',')
|
934 | }else{
|
935 | x.record_video_filters=''
|
936 | }
|
937 |
|
938 | if(e.details.stream_timestamp&&e.details.stream_timestamp=="1"&&e.details.vcodec!=='copy'){
|
939 |
|
940 | if(e.details.stream_timestamp_font&&e.details.stream_timestamp_font!==''){x.stream_timestamp_font=e.details.stream_timestamp_font}else{x.stream_timestamp_font='/usr/share/fonts/truetype/freefont/FreeSans.ttf'}
|
941 |
|
942 | if(e.details.stream_timestamp_x&&e.details.stream_timestamp_x!==''){x.stream_timestamp_x=e.details.stream_timestamp_x}else{x.stream_timestamp_x='(w-tw)/2'}
|
943 |
|
944 | if(e.details.stream_timestamp_y&&e.details.stream_timestamp_y!==''){x.stream_timestamp_y=e.details.stream_timestamp_y}else{x.stream_timestamp_y='0'}
|
945 |
|
946 | if(e.details.stream_timestamp_color&&e.details.stream_timestamp_color!==''){x.stream_timestamp_color=e.details.stream_timestamp_color}else{x.stream_timestamp_color='white'}
|
947 |
|
948 | if(e.details.stream_timestamp_box_color&&e.details.stream_timestamp_box_color!==''){x.stream_timestamp_box_color=e.details.stream_timestamp_box_color}else{x.stream_timestamp_box_color='0x00000000@1'}
|
949 |
|
950 | if(e.details.stream_timestamp_font_size&&e.details.stream_timestamp_font_size!==''){x.stream_timestamp_font_size=e.details.stream_timestamp_font_size}else{x.stream_timestamp_font_size='10'}
|
951 |
|
952 | x.stream_video_filters.push('drawtext=fontfile='+x.stream_timestamp_font+':text=\'%{localtime}\':x='+x.stream_timestamp_x+':y='+x.stream_timestamp_y+':fontcolor='+x.stream_timestamp_color+':box=1:boxcolor='+x.stream_timestamp_box_color+':fontsize='+x.stream_timestamp_font_size);
|
953 | }
|
954 |
|
955 | if(e.details.stream_watermark&&e.details.stream_watermark=="1"&&e.details.stream_watermark_location&&e.details.stream_watermark_location!==''){
|
956 | switch(e.details.stream_watermark_position){
|
957 | case'tl':
|
958 | x.stream_watermark_position='10:10'
|
959 | break;
|
960 | case'tr':
|
961 | x.stream_watermark_position='main_w-overlay_w-10:10'
|
962 | break;
|
963 | case'bl':
|
964 | x.stream_watermark_position='10:main_h-overlay_h-10'
|
965 | break;
|
966 | default:
|
967 | x.stream_watermark_position='(main_w-overlay_w-10)/2:(main_h-overlay_h-10)/2'
|
968 | break;
|
969 | }
|
970 | x.stream_video_filters.push('movie='+e.details.stream_watermark_location+'[watermark],[in][watermark]overlay='+x.stream_watermark_position+'[out]');
|
971 | }
|
972 |
|
973 | if(e.details.rotate_stream&&e.details.rotate_stream!==""&&e.details.rotate_stream!=="no"){
|
974 | x.stream_video_filters.push('transpose='+e.details.rotate_stream);
|
975 | }
|
976 |
|
977 | if(e.details.stream_vcodec&&e.details.stream_vcodec!=='no'){
|
978 | if(e.details.stream_vcodec!==''){x.stream_vcodec=' -c:v '+e.details.stream_vcodec}else{x.stream_vcodec=' -c:v libx264'}
|
979 | }else{
|
980 | x.stream_vcodec='';
|
981 | }
|
982 |
|
983 | if(e.details.stream_acodec!=='no'){
|
984 | if(e.details.stream_acodec&&e.details.stream_acodec!==''){x.stream_acodec=' -c:a '+e.details.stream_acodec}else{x.stream_acodec=''}
|
985 | }else{
|
986 | x.stream_acodec=' -an';
|
987 | }
|
988 |
|
989 | if(e.details.hls_time&&e.details.hls_time!==''){x.hls_time=e.details.hls_time}else{x.hls_time="2"}
|
990 | if(e.details.hls_list_size&&e.details.hls_list_size!==''){x.hls_list_size=e.details.hls_list_size}else{x.hls_list_size=2}
|
991 |
|
992 | if(e.details.cust_stream&&e.details.cust_stream!==''){x.cust_stream=' '+e.details.cust_stream}else{x.cust_stream=''}
|
993 |
|
994 | if(e.details.preset_stream&&e.details.preset_stream!==''){x.preset_stream=' -preset '+e.details.preset_stream;}else{x.preset_stream=''}
|
995 |
|
996 | if(e.details.stream_quality&&e.details.stream_quality!==''){x.stream_quality=e.details.stream_quality}else{x.stream_quality=''}
|
997 |
|
998 | if(e.details.accelerator&&e.details.accelerator==='1'){
|
999 | if(e.details.hwaccel&&e.details.hwaccel!==''){
|
1000 | x.hwaccel+=' -hwaccel '+e.details.hwaccel;
|
1001 | }
|
1002 | if(e.details.hwaccel_vcodec&&e.details.hwaccel_vcodec!==''){
|
1003 | x.hwaccel+=' -c:v '+e.details.hwaccel_vcodec;
|
1004 | }
|
1005 | if(e.details.hwaccel_device&&e.details.hwaccel_device!==''){
|
1006 | switch(e.details.hwaccel){
|
1007 | case'vaapi':
|
1008 | x.hwaccel+=' -vaapi_device '+e.details.hwaccel_device;
|
1009 | break;
|
1010 | default:
|
1011 | x.hwaccel+=' -hwaccel_device '+e.details.hwaccel_device;
|
1012 | break;
|
1013 | }
|
1014 | }
|
1015 |
|
1016 |
|
1017 |
|
1018 |
|
1019 |
|
1020 | }
|
1021 | if(e.details.stream_vcodec==='h264_vaapi'){
|
1022 | x.stream_video_filters=[]
|
1023 | x.stream_video_filters.push('format=nv12|vaapi');
|
1024 | if(e.details.stream_scale_x&&e.details.stream_scale_x!==''&&e.details.stream_scale_y&&e.details.stream_scale_y!==''){
|
1025 | x.stream_video_filters.push('scale_vaapi=w='+e.details.stream_scale_x+':h='+e.details.stream_scale_y)
|
1026 | }
|
1027 | }
|
1028 |
|
1029 | if(e.details.svf&&e.details.svf!==''){
|
1030 | x.stream_video_filters.push(e.details.svf)
|
1031 | }
|
1032 | if(x.stream_video_filters.length>0){
|
1033 | x.stream_video_filters=' -vf '+x.stream_video_filters.join(',')
|
1034 | }else{
|
1035 | x.stream_video_filters=''
|
1036 | }
|
1037 |
|
1038 | switch(e.details.stream_type){
|
1039 | case'flv':
|
1040 | if(e.details.stream_vcodec!=='copy'){
|
1041 | if(x.cust_stream.indexOf('-s ')===-1){x.cust_stream+=' -s '+x.ratio}
|
1042 | x.cust_stream+=x.stream_fps
|
1043 | if(x.stream_quality)x.stream_quality=' -crf '+x.stream_quality;
|
1044 | x.cust_stream+=x.stream_quality
|
1045 | x.cust_stream+=x.preset_stream
|
1046 | }
|
1047 | x.pipe=' -f flv'+x.stream_acodec+x.stream_vcodec+x.stream_video_filters+x.cust_stream+' pipe:1';
|
1048 | break;
|
1049 | case'hls':
|
1050 | if(e.details.stream_vcodec!=='h264_vaapi'){
|
1051 | if(x.stream_quality)x.stream_quality=' -crf '+x.stream_quality;
|
1052 | if(x.cust_stream.indexOf('-tune')===-1){x.cust_stream+=' -tune zerolatency'}
|
1053 | if(x.cust_stream.indexOf('-g ')===-1){x.cust_stream+=' -g 1'}
|
1054 | }
|
1055 | x.pipe=x.preset_stream+x.stream_quality+x.stream_acodec+x.stream_vcodec+x.stream_fps+' -f hls -s '+x.ratio+x.stream_video_filters+x.cust_stream+' -hls_time '+x.hls_time+' -hls_list_size '+x.hls_list_size+' -start_number 0 -hls_allow_cache 0 -hls_flags +delete_segments+omit_endlist '+e.sdir+'s.m3u8';
|
1056 | break;
|
1057 | case'mjpeg':
|
1058 | if(x.stream_quality)x.stream_quality=' -q:v '+x.stream_quality;
|
1059 | x.pipe=' -c:v mjpeg -f mpjpeg -boundary_tag shinobi'+x.cust_stream+x.stream_video_filters+x.stream_quality+x.stream_fps+' -s '+x.ratio+' pipe:1';
|
1060 | break;
|
1061 | case'b64':case'':case undefined:case null:
|
1062 | if(x.stream_quality)x.stream_quality=' -q:v '+x.stream_quality;
|
1063 | x.pipe=' -c:v mjpeg -f image2pipe'+x.cust_stream+x.stream_video_filters+x.stream_quality+x.stream_fps+' -s '+x.ratio+' pipe:1';
|
1064 | break;
|
1065 | default:
|
1066 | x.pipe=''
|
1067 | break;
|
1068 | }
|
1069 |
|
1070 | if(e.details.detector==='1'&&e.details.detector_send_frames==='1'){
|
1071 | if(!e.details.detector_fps||e.details.detector_fps===''){e.details.detector_fps=2}
|
1072 | if(e.details.detector_scale_x&&e.details.detector_scale_x!==''&&e.details.detector_scale_y&&e.details.detector_scale_y!==''){x.dratio=' -s '+e.details.detector_scale_x+'x'+e.details.detector_scale_y}else{x.dratio=' -s 320x240'}
|
1073 | if(e.details.cust_detect&&e.details.cust_detect!==''){x.cust_detect+=e.details.cust_detect;}
|
1074 | x.pipe+=' -f singlejpeg -vf fps='+e.details.detector_fps+x.cust_detect+x.dratio+' pipe:0';
|
1075 | }
|
1076 |
|
1077 | if(e.details.snap==='1'||e.details.stream_type==='jpeg'){
|
1078 | if(!e.details.snap_fps||e.details.snap_fps===''){e.details.snap_fps=1}
|
1079 | if(e.details.snap_vf&&e.details.snap_vf!==''){x.snap_vf=' -vf '+e.details.snap_vf}else{x.snap_vf=''}
|
1080 | if(e.details.snap_scale_x&&e.details.snap_scale_x!==''&&e.details.snap_scale_y&&e.details.snap_scale_y!==''){x.sratio=' -s '+e.details.snap_scale_x+'x'+e.details.snap_scale_y}else{x.sratio=''}
|
1081 | if(e.details.cust_snap&&e.details.cust_snap!==''){x.cust_snap=' '+e.details.cust_snap;}else{x.cust_snap=''}
|
1082 | x.pipe+=' -update 1 -r '+e.details.snap_fps+x.cust_snap+x.sratio+x.snap_vf+' '+e.sdir+'s.jpg -y';
|
1083 | }
|
1084 |
|
1085 | if(e.details.rawh264==='1'){
|
1086 | if(e.details.rawh264_vcodec&&e.details.rawh264_vcodec!==''){x.rawh264_vcodec=' -c:v '+e.details.rawh264_vcodec}else{x.rawh264_vcodec=' -c:v copy'}
|
1087 | if(e.details.rawh264_acodec==='no'){
|
1088 | x.rawh264_acodec=''
|
1089 | }else{
|
1090 | if(e.details.rawh264_acodec&&e.details.rawh264_acodec!==''){x.rawh264_acodec=' -c:a '+e.details.rawh264_acodec}else{x.rawh264_acodec=' -c:a aac'}
|
1091 | }
|
1092 | x.rawh264_fps=''
|
1093 | x.cust_rawh264=''
|
1094 | x.rawh264_ratio=''
|
1095 | x.rawh264_vf=''
|
1096 | x.rawh264_crf=''
|
1097 | if(x.rawh264_vcodec!=='copy'){
|
1098 | if(e.details.rawh264_crf&&e.details.rawh264_crf!==''){x.rawh264_crf=' -crf '+e.details.rawh264_crf}else{x.rawh264_crf=''}
|
1099 | if(e.details.rawh264_fps&&e.details.rawh264_fps!==''){x.rawh264_fps=e.details.rawh264_fps}else{x.rawh264_fps=''}
|
1100 | if(e.details.rawh264_vf&&e.details.rawh264_vf!==''){x.rawh264_vf=' -vf '+e.details.rawh264_vf}else{x.rawh264_vf=''}
|
1101 | if(e.details.rawh264_scale_x&&e.details.rawh264_scale_x!==''&&e.details.rawh264_scale_y&&e.details.rawh264_scale_y!==''){x.rawh264_ratio=' -s '+e.details.rawh264_scale_x+'x'+e.details.rawh264_scale_y}else{x.rawh264_ratio=''}
|
1102 | }
|
1103 | if(e.details.cust_rawh264&&e.details.cust_rawh264!==''){x.cust_rawh264=' '+e.details.cust_rawh264;}else{x.cust_rawh264=''}
|
1104 | x.pipe+=' -f mpegts '+x.rawh264_vcodec+x.rawh264_acodec+x.rawh264_fps+x.cust_rawh264+x.rawh264_ratio+x.rawh264_vf+' http://127.0.0.1:'+config.port+'/streamIn/'+e.ke+'/'+e.mid+'/1';
|
1105 | }
|
1106 |
|
1107 |
|
1108 |
|
1109 |
|
1110 |
|
1111 |
|
1112 |
|
1113 |
|
1114 |
|
1115 |
|
1116 |
|
1117 |
|
1118 |
|
1119 |
|
1120 |
|
1121 |
|
1122 |
|
1123 | if(e.details.custom_output&&e.details.custom_output!==''){x.pipe+=' '+e.details.custom_output;}
|
1124 |
|
1125 | if(e.details.cust_input&&e.details.cust_input!==''){x.cust_input+=' '+e.details.cust_input;}
|
1126 |
|
1127 | if(e.details.loglevel&&e.details.loglevel!==''){x.loglevel='-loglevel '+e.details.loglevel;}else{x.loglevel='-loglevel error'}
|
1128 | if(e.mode=='record'){
|
1129 |
|
1130 | if(e.details.cust_record&&e.details.cust_record!==''){x.record_string+=' '+e.details.cust_record;}
|
1131 |
|
1132 | if(e.details.preset_record&&e.details.preset_record!==''){x.record_string+=' -preset '+e.details.preset_record;}
|
1133 | }
|
1134 |
|
1135 | switch(e.type){
|
1136 | case'dashcam':
|
1137 | if(e.mode==='record'){x.record_string+=x.vcodec+x.framerate+x.record_video_filters+x.record_dimensions+x.segment;}
|
1138 | x.tmp=x.loglevel+' -i -'+x.record_string+x.pipe;
|
1139 | break;
|
1140 | case'socket':case'jpeg':case'pipe':
|
1141 | if(e.mode==='record'){x.record_string+=x.vcodec+x.framerate+x.record_video_filters+x.record_dimensions+x.segment;}
|
1142 | x.tmp=x.loglevel+' -pattern_type glob -f image2pipe'+x.framerate+' -vcodec mjpeg'+x.cust_input+' -i -'+x.record_string+x.pipe;
|
1143 | break;
|
1144 | case'mjpeg':
|
1145 | if(e.mode=='record'){
|
1146 | x.record_string+=x.vcodec+x.record_video_filters+x.framerate+x.record_dimensions+x.segment;
|
1147 | }
|
1148 | x.tmp=x.loglevel+' -reconnect 1 -r '+e.details.sfps+' -f mjpeg'+x.cust_input+' -i '+e.url+''+x.record_string+x.pipe;
|
1149 | break;
|
1150 | case'h264':case'hls':case'mp4':
|
1151 | if(e.mode=='record'){
|
1152 | x.record_string+=x.vcodec+x.framerate+x.acodec+x.record_dimensions+x.record_video_filters+' '+x.segment;
|
1153 | }
|
1154 | x.tmp=x.loglevel+x.cust_input+x.hwaccel+' -i '+e.url+x.record_string+x.pipe;
|
1155 | break;
|
1156 | case'local':
|
1157 | if(e.mode=='record'){
|
1158 | x.record_string+=x.vcodec+x.framerate+x.acodec+x.record_dimensions+x.record_video_filters+' '+x.segment;
|
1159 | }
|
1160 | x.tmp=x.loglevel+x.cust_input+' -i '+e.path+''+x.record_string+x.pipe;
|
1161 | break;
|
1162 | }
|
1163 | s.group[e.ke].mon[e.mid].ffmpeg=x.tmp;
|
1164 | return spawn(config.ffmpegDir,x.tmp.replace(/\s+/g,' ').trim().split(' '),{detached: true});
|
1165 | }
|
1166 | s.file=function(x,e){
|
1167 | if(!e){e={}};
|
1168 | switch(x){
|
1169 | case'size':
|
1170 | return fs.statSync(e.filename)["size"];
|
1171 | break;
|
1172 | case'delete':
|
1173 | if(!e){return false;}
|
1174 | return exec('rm -f '+e,{detached: true});
|
1175 | break;
|
1176 | case'delete_files':
|
1177 | if(!e.age_type){e.age_type='min'};if(!e.age){e.age='1'};
|
1178 | exec('find '+e.path+' -type f -c'+e.age_type+' +'+e.age+' -exec rm -f {} +',{detached: true});
|
1179 | break;
|
1180 | }
|
1181 | }
|
1182 | s.camera=function(x,e,cn,tx){
|
1183 | if(x!=='motion'){
|
1184 | var ee=s.init('noReference',e);
|
1185 | if(!e){e={}};if(cn&&cn.ke&&!e.ke){e.ke=cn.ke};
|
1186 | if(!e.mode){e.mode=x;}
|
1187 | if(!e.id&&e.mid){e.id=e.mid}
|
1188 | }
|
1189 | if(e.details&&(e.details instanceof Object)===false){
|
1190 | try{e.details=JSON.parse(e.details)}catch(err){}
|
1191 | }
|
1192 | ['detector_cascades','cords'].forEach(function(v){
|
1193 | if(e.details&&e.details[v]&&(e.details[v] instanceof Object)===false){
|
1194 | try{
|
1195 | e.details[v]=JSON.parse(e.details[v]);
|
1196 | if(!e.details[v])e.details[v]={};
|
1197 | }catch(err){
|
1198 | e.details[v]={};
|
1199 | }
|
1200 | }
|
1201 | })
|
1202 | switch(x){
|
1203 | case'snapshot':
|
1204 | if(config.doSnapshot===true){
|
1205 | if(e.mon.mode!=='stop'){
|
1206 | try{e.mon.details=JSON.parse(e.mon.details)}catch(er){}
|
1207 | if(e.mon.details.snap==='1'){
|
1208 | fs.readFile(s.dir.streams+e.ke+'/'+e.mid+'/s.jpg',function(err,data){
|
1209 | if(err){s.tx({f:'monitor_snapshot',snapshot:e.mon.name,snapshot_format:'plc',mid:e.mid,ke:e.ke},'GRP_'+e.ke);return};
|
1210 | s.tx({f:'monitor_snapshot',snapshot:data,snapshot_format:'ab',mid:e.mid,ke:e.ke},'GRP_'+e.ke)
|
1211 | })
|
1212 | }else{
|
1213 | e.url=s.init('url',e.mon);
|
1214 | switch(e.mon.type){
|
1215 | case'mjpeg':case'h264':case'local':
|
1216 | if(e.mon.type==='local'){e.url=e.mon.path;}
|
1217 | e.spawn=spawn(config.ffmpegDir,('-loglevel quiet -i '+e.url+' -s 400x400 -r 25 -ss 1.8 -frames:v 1 -f singlejpeg pipe:1').split(' '),{detached: true})
|
1218 | e.spawn.stdout.on('data',function(data){
|
1219 | e.snapshot_sent=true; s.tx({f:'monitor_snapshot',snapshot:data.toString('base64'),snapshot_format:'b64',mid:e.mid,ke:e.ke},'GRP_'+e.ke)
|
1220 | e.spawn.kill();
|
1221 | });
|
1222 | e.spawn.on('close',function(data){
|
1223 | if(!e.snapshot_sent){
|
1224 | s.tx({f:'monitor_snapshot',snapshot:e.mon.name,snapshot_format:'plc',mid:e.mid,ke:e.ke},'GRP_'+e.ke)
|
1225 | }
|
1226 | delete(e.snapshot_sent);
|
1227 | });
|
1228 | break;
|
1229 | case'jpeg':
|
1230 | request({url:e.url,method:'GET',encoding:null},function(err,data){
|
1231 | if(err){s.tx({f:'monitor_snapshot',snapshot:e.mon.name,snapshot_format:'plc',mid:e.mid,ke:e.ke},'GRP_'+e.ke);return};
|
1232 | s.tx({f:'monitor_snapshot',snapshot:data.body,snapshot_format:'ab',mid:e.mid,ke:e.ke},'GRP_'+e.ke)
|
1233 | })
|
1234 | break;
|
1235 | default:
|
1236 | s.tx({f:'monitor_snapshot',snapshot:'...',snapshot_format:'plc',mid:e.mid,ke:e.ke},'GRP_'+e.ke)
|
1237 | break;
|
1238 | }
|
1239 | }
|
1240 | }else{
|
1241 | s.tx({f:'monitor_snapshot',snapshot:'Disabled',snapshot_format:'plc',mid:e.mid,ke:e.ke},'GRP_'+e.ke)
|
1242 | }
|
1243 | }else{
|
1244 | s.tx({f:'monitor_snapshot',snapshot:e.mon.name,snapshot_format:'plc',mid:e.mid,ke:e.ke},'GRP_'+e.ke)
|
1245 | }
|
1246 | break;
|
1247 | case'record_off':
|
1248 | if(!s.group[e.ke].mon[e.id].record){s.group[e.ke].mon[e.id].record={}}
|
1249 | s.group[e.ke].mon[e.id].record.yes=0;
|
1250 | s.camera('start',e);
|
1251 | break;
|
1252 | case'watch_on':
|
1253 |
|
1254 | s.init(0,{ke:e.ke,mid:e.id})
|
1255 | if(!cn.monitor_watching){cn.monitor_watching={}}
|
1256 | if(!cn.monitor_watching[e.id]){cn.monitor_watching[e.id]={ke:e.ke}}
|
1257 | s.group[e.ke].mon[e.id].watch[cn.id]={};
|
1258 |
|
1259 |
|
1260 |
|
1261 |
|
1262 |
|
1263 |
|
1264 |
|
1265 |
|
1266 |
|
1267 | break;
|
1268 | case'watch_off':
|
1269 | if(cn.monitor_watching){delete(cn.monitor_watching[e.id])}
|
1270 | if(s.group[e.ke].mon[e.id]&&s.group[e.ke].mon[e.id].watch){
|
1271 | delete(s.group[e.ke].mon[e.id].watch[cn.id]),e.ob=Object.keys(s.group[e.ke].mon[e.id].watch).length
|
1272 | if(e.ob===0){
|
1273 | delete(s.group[e.ke].mon[e.id].watch)
|
1274 | }
|
1275 | }else{
|
1276 | e.ob=0;
|
1277 | }
|
1278 | if(tx){tx({f:'monitor_watch_off',ke:e.ke,id:e.id,cnid:cn.id})};
|
1279 | s.tx({viewers:e.ob,ke:e.ke,id:e.id},'MON_'+e.id);
|
1280 | break;
|
1281 | case'restart':
|
1282 | s.camera('stop',e)
|
1283 | setTimeout(function(){
|
1284 | s.camera(e.mode,e)
|
1285 | },1300)
|
1286 | break;
|
1287 | case'idle':case'stop':
|
1288 | if(!s.group[e.ke]||!s.group[e.ke].mon[e.id]){return}
|
1289 | if(s.group[e.ke].mon[e.id].fswatch){s.group[e.ke].mon[e.id].fswatch.close();delete(s.group[e.ke].mon[e.id].fswatch)}
|
1290 | if(s.group[e.ke].mon[e.id].fswatchStream){s.group[e.ke].mon[e.id].fswatchStream.close();delete(s.group[e.ke].mon[e.id].fswatchStream)}
|
1291 | if(s.group[e.ke].mon[e.id].open){ee.filename=s.group[e.ke].mon[e.id].open,ee.ext=s.group[e.ke].mon[e.id].open_ext;s.video('close',ee)}
|
1292 | if(s.group[e.ke].mon[e.id].last_frame){delete(s.group[e.ke].mon[e.id].last_frame)}
|
1293 | if(s.group[e.ke].mon[e.id].started!==1){return}
|
1294 | s.kill(s.group[e.ke].mon[e.id].spawn,e);
|
1295 | if(e.neglectTriggerTimer===1){
|
1296 | delete(e.neglectTriggerTimer);
|
1297 | }else{
|
1298 | clearTimeout(s.group[e.ke].mon[e.id].trigger_timer)
|
1299 | delete(s.group[e.ke].mon[e.id].trigger_timer)
|
1300 | }
|
1301 | clearInterval(s.group[e.ke].mon[e.id].running);
|
1302 | clearInterval(s.group[e.ke].mon[e.id].detector_notrigger_timeout)
|
1303 | clearTimeout(s.group[e.ke].mon[e.id].err_fatal_timeout);
|
1304 | s.group[e.ke].mon[e.id].started=0;
|
1305 | if(s.group[e.ke].mon[e.id].record){s.group[e.ke].mon[e.id].record.yes=0}
|
1306 | s.tx({f:'monitor_stopping',mid:e.id,ke:e.ke,time:s.moment()},'GRP_'+e.ke);
|
1307 | s.camera('snapshot',{mid:e.id,ke:e.ke,mon:e})
|
1308 | if(x==='stop'){
|
1309 | s.log(e,{type:lang['Monitor Stopped'],msg:lang.MonitorStoppedText});
|
1310 | clearTimeout(s.group[e.ke].mon[e.id].delete)
|
1311 | if(e.delete===1){
|
1312 | s.group[e.ke].mon[e.id].delete=setTimeout(function(){
|
1313 | delete(s.group[e.ke].mon[e.id]);
|
1314 | delete(s.group[e.ke].mon_conf[e.id]);
|
1315 | },1000*60);
|
1316 | }
|
1317 | }else{
|
1318 | s.tx({f:'monitor_idle',mid:e.id,ke:e.ke,time:s.moment()},'GRP_'+e.ke);
|
1319 | s.log(e,{type:lang['Monitor Idling'],msg:lang.MonitorIdlingText});
|
1320 | }
|
1321 | break;
|
1322 | case'start':case'record':
|
1323 | s.init(0,{ke:e.ke,mid:e.id})
|
1324 | if(!s.group[e.ke].mon_conf[e.id]){s.group[e.ke].mon_conf[e.id]=s.init('noReference',e);}
|
1325 | e.url=s.init('url',e);
|
1326 | if(s.group[e.ke].mon[e.id].started===1){return}
|
1327 | if(x==='start'&&e.details.detector_trigger=='1'){
|
1328 | s.group[e.ke].mon[e.id].motion_lock=setTimeout(function(){
|
1329 | clearTimeout(s.group[e.ke].mon[e.id].motion_lock);
|
1330 | delete(s.group[e.ke].mon[e.id].motion_lock);
|
1331 | },30000)
|
1332 | }
|
1333 | s.group[e.ke].mon[e.id].started=1;
|
1334 | if(x==='record'){
|
1335 | s.group[e.ke].mon[e.id].record.yes=1;
|
1336 | }else{
|
1337 | s.group[e.ke].mon[e.mid].record.yes=0;
|
1338 | }
|
1339 | if(e.details&&e.details.dir&&e.details.dir!==''){
|
1340 |
|
1341 | e.dir=s.checkCorrectPathEnding(e.details.dir)+e.ke+'/';
|
1342 | if (!fs.existsSync(e.dir)){
|
1343 | fs.mkdirSync(e.dir);
|
1344 | }
|
1345 | e.dir=e.dir+e.id+'/';
|
1346 | if (!fs.existsSync(e.dir)){
|
1347 | fs.mkdirSync(e.dir);
|
1348 | }
|
1349 | }else{
|
1350 |
|
1351 | e.dir=s.dir.videos+e.ke+'/';
|
1352 | if (!fs.existsSync(e.dir)){
|
1353 | fs.mkdirSync(e.dir);
|
1354 | }
|
1355 | e.dir=s.dir.videos+e.ke+'/'+e.id+'/';
|
1356 | if (!fs.existsSync(e.dir)){
|
1357 | fs.mkdirSync(e.dir);
|
1358 | }
|
1359 | }
|
1360 |
|
1361 | e.sdir=s.dir.streams+e.ke+'/';
|
1362 | if (!fs.existsSync(e.sdir)){
|
1363 | fs.mkdirSync(e.sdir);
|
1364 | }
|
1365 | e.sdir=s.dir.streams+e.ke+'/'+e.id+'/';
|
1366 | if (!fs.existsSync(e.sdir)){
|
1367 | fs.mkdirSync(e.sdir);
|
1368 | }else{
|
1369 | s.file('delete',e.sdir+'*')
|
1370 | }
|
1371 |
|
1372 | if(e.details.detector=='1'&&e.details.detector_notrigger=='1'){
|
1373 | if(!e.details.detector_notrigger_timeout||e.details.detector_notrigger_timeout===''){
|
1374 | e.details.detector_notrigger_timeout=10
|
1375 | }
|
1376 | e.detector_notrigger_timeout=parseFloat(e.details.detector_notrigger_timeout)*1000*60;
|
1377 | s.sqlQuery('SELECT mail FROM Users WHERE ke=? AND details NOT LIKE ?',[e.ke,'%"sub"%'],function(err,r){
|
1378 | r=r[0];
|
1379 | s.group[e.ke].mon[e.id].detector_notrigger_timeout_function=function(){
|
1380 | if(config.mail&&e.details.detector_notrigger_mail=='1'){
|
1381 | e.mailOptions = {
|
1382 | from: '"ShinobiCCTV" <no-reply@shinobi.video>',
|
1383 | to: r.mail,
|
1384 | subject: lang.NoMotionEmailText1+' '+e.name+' ('+e.id+')',
|
1385 | html: '<i>'+lang.NoMotionEmailText2+' '+e.details.detector_notrigger_timeout+' '+lang.minutes+'.</i>',
|
1386 | };
|
1387 | e.mailOptions.html+='<div><b>'+lang['Monitor Name']+' </b> : '+e.name+'</div>'
|
1388 | e.mailOptions.html+='<div><b>'+lang['Monitor ID']+' </b> : '+e.id+'</div>'
|
1389 | nodemailer.sendMail(e.mailOptions, (error, info) => {
|
1390 | if (error) {
|
1391 | s.systemLog('detector:notrigger:sendMail',error)
|
1392 | s.tx({f:'error',ff:'detector_notrigger_mail',id:e.id,ke:e.ke,error:error},'GRP_'+e.ke);
|
1393 | return ;
|
1394 | }
|
1395 | s.tx({f:'detector_notrigger_mail',id:e.id,ke:e.ke,info:info},'GRP_'+e.ke);
|
1396 | });
|
1397 | }
|
1398 | }
|
1399 | clearInterval(s.group[e.ke].mon[e.id].detector_notrigger_timeout)
|
1400 | s.group[e.ke].mon[e.id].detector_notrigger_timeout=setInterval(s.group[e.ke].mon[e.id].detector_notrigger_timeout_function,e.detector_notrigger_timeout)
|
1401 | })
|
1402 | }
|
1403 |
|
1404 | if(!e.details.cutoff||e.details.cutoff===''){e.cutoff=15}else{e.cutoff=parseFloat(e.details.cutoff)};
|
1405 | if(isNaN(e.cutoff)===true){e.cutoff=15}
|
1406 | e.resetStreamCheck=function(){
|
1407 | clearTimeout(s.group[e.ke].mon[e.id].checkStream)
|
1408 | s.group[e.ke].mon[e.id].checkStream=setTimeout(function(){
|
1409 | if(s.group[e.ke].mon[e.id].started===1){
|
1410 | e.fn();
|
1411 | s.log(e,{type:lang['Camera is not streaming'],msg:{msg:lang['Restarting Process']}});
|
1412 | }
|
1413 | },60000*1);
|
1414 | }
|
1415 | switch(x){
|
1416 | case'record':
|
1417 | s.group[e.ke].mon[e.id].fswatch=fs.watch(e.dir,{encoding:'utf8'},function(eventType,filename){
|
1418 | if(s.group[e.ke].mon[e.id].fixingVideos[filename]){return}
|
1419 | switch(eventType){
|
1420 | case'change':
|
1421 | clearTimeout(s.group[e.ke].mon[e.id].checker)
|
1422 | clearTimeout(s.group[e.ke].mon[e.id].checkStream)
|
1423 | s.group[e.ke].mon[e.id].checker=setTimeout(function(){
|
1424 | if(s.group[e.ke].mon[e.id].started===1){
|
1425 | e.fn();
|
1426 | s.log(e,{type:lang['Camera is not recording'],msg:{msg:lang['Restarting Process']}});
|
1427 | }
|
1428 | },60000*2);
|
1429 | break;
|
1430 | case'rename':
|
1431 | fs.exists(e.dir+filename,function(exists){
|
1432 | if(exists){
|
1433 | if(s.group[e.ke].mon[e.id].open){
|
1434 | s.video('close',e);
|
1435 | if(e.details.detector==='1'&&s.ocv&&s.group[e.ke].mon[e.id].started===1&&e.details&&e.details.detector_record_method==='del'&&e.details.detector_delete_motionless_videos==='1'&&s.group[e.ke].mon[e.id].detector_motion_count===0){
|
1436 | if(e.details.loglevel!=='quiet'){
|
1437 | s.log(e,{type:lang['Delete Motionless Video'],msg:e.filename+'.'+e.ext});
|
1438 | }
|
1439 | s.video('delete',s.init('noReference',e))
|
1440 | }
|
1441 | }
|
1442 | setTimeout(function(){
|
1443 | e.filename=filename.split('.')[0];
|
1444 | s.video('open',e);
|
1445 | s.group[e.ke].mon[e.id].open=e.filename;
|
1446 | s.group[e.ke].mon[e.id].open_ext=e.ext;
|
1447 | s.group[e.ke].mon[e.id].detector_motion_count=0;
|
1448 | },2000)
|
1449 | }
|
1450 | });
|
1451 | break;
|
1452 | }
|
1453 | })
|
1454 | break;
|
1455 | case'start':
|
1456 | switch(e.details.stream_type){
|
1457 | case'jpeg':case'hls':
|
1458 | s.group[e.ke].mon[e.id].fswatchStream=fs.watch(e.sdir,{encoding:'utf8'},function(eventType,filename){
|
1459 | switch(eventType){
|
1460 | case'change':
|
1461 | e.resetStreamCheck()
|
1462 | break;
|
1463 | }
|
1464 | })
|
1465 | break;
|
1466 | }
|
1467 | break;
|
1468 | }
|
1469 | s.camera('snapshot',{mid:e.id,ke:e.ke,mon:e})
|
1470 |
|
1471 | e.hosty=e.host.split('@');if(e.hosty[1]){e.hosty=e.hosty[1];}else{e.hosty=e.hosty[0];};
|
1472 |
|
1473 | e.error_fatal=function(x){
|
1474 | clearTimeout(s.group[e.ke].mon[e.id].err_fatal_timeout);
|
1475 | ++e.error_fatal_count;
|
1476 | if(s.group[e.ke].mon[e.id].started===1){
|
1477 | s.group[e.ke].mon[e.id].err_fatal_timeout=setTimeout(function(){
|
1478 | if(e.details.fatal_max!==0&&e.error_fatal_count>e.details.fatal_max){
|
1479 | s.camera('stop',{id:e.id,ke:e.ke})
|
1480 | }else{
|
1481 | e.fn()
|
1482 | };
|
1483 | },5000);
|
1484 | }else{
|
1485 | s.kill(s.group[e.ke].mon[e.id].spawn,e);
|
1486 | }
|
1487 | }
|
1488 | e.error_fatal_count=0;
|
1489 | e.fn=function(){
|
1490 | clearTimeout(s.group[e.ke].mon[e.id].checker)
|
1491 | if(s.group[e.ke].mon[e.id].started===1){
|
1492 | e.error_count=0;
|
1493 | s.group[e.ke].mon[e.id].error_socket_timeout_count=0;
|
1494 | if(e.details.fatal_max===''){e.details.fatal_max=10}else{e.details.fatal_max=parseFloat(e.details.fatal_max)}
|
1495 | s.kill(s.group[e.ke].mon[e.id].spawn,e);
|
1496 | e.draw=function(err,o){
|
1497 | if(o.success===true){
|
1498 | e.frames=0;
|
1499 | if(!s.group[e.ke].mon[e.id].record){s.group[e.ke].mon[e.id].record={yes:1}};
|
1500 |
|
1501 | s.group[e.ke].mon[e.id].spawn = s.ffmpeg(e);
|
1502 |
|
1503 | s.group[e.ke].mon[e.id].spawn_exit=function(){
|
1504 | if(s.group[e.ke].mon[e.id].started===1){
|
1505 | if(e.details.loglevel!=='quiet'){
|
1506 | s.log(e,{type:lang['Process Unexpected Exit'],msg:{msg:lang['Process Crashed for Monitor']+' : '+e.id,cmd:s.group[e.ke].mon[e.id].ffmpeg}});
|
1507 | }
|
1508 | e.error_fatal();
|
1509 | }
|
1510 | }
|
1511 | s.group[e.ke].mon[e.id].spawn.on('end',s.group[e.ke].mon[e.id].spawn_exit)
|
1512 | s.group[e.ke].mon[e.id].spawn.on('exit',s.group[e.ke].mon[e.id].spawn_exit)
|
1513 |
|
1514 | if(!e.details.stream_mjpeg_clients||e.details.stream_mjpeg_clients===''||isNaN(e.details.stream_mjpeg_clients)===false){e.details.stream_mjpeg_clients=20;}else{e.details.stream_mjpeg_clients=parseInt(e.details.stream_mjpeg_clients)}
|
1515 | s.group[e.ke].mon[e.id].emitter = new events.EventEmitter().setMaxListeners(e.details.stream_mjpeg_clients);
|
1516 | s.log(e,{type:'FFMPEG Process Started',msg:{cmd:s.group[e.ke].mon[e.id].ffmpeg}});
|
1517 | s.tx({f:'monitor_starting',mode:x,mid:e.id,time:s.moment()},'GRP_'+e.ke);
|
1518 |
|
1519 | if(e.type==='jpeg'){
|
1520 | if(!e.details.sfps||e.details.sfps===''){
|
1521 | e.details.sfps=parseFloat(e.details.sfps);
|
1522 | if(isNaN(e.details.sfps)){e.details.sfps=1}
|
1523 | }
|
1524 | if(s.group[e.ke].mon[e.id].spawn){
|
1525 | s.group[e.ke].mon[e.id].spawn.stdin.on('error',function(err){
|
1526 | if(err&&e.details.loglevel!=='quiet'){
|
1527 | s.log(e,{type:'STDIN ERROR',msg:err});
|
1528 | }
|
1529 | })
|
1530 | }else{
|
1531 | if(x==='record'){
|
1532 | s.log(e,{type:lang.FFmpegCantStart,msg:lang.FFmpegCantStartText});
|
1533 | return
|
1534 | }
|
1535 | }
|
1536 | e.captureOne=function(f){
|
1537 | s.group[e.ke].mon[e.id].record.request=request({url:e.url,method:'GET',encoding: null,timeout:15000},function(err,data){
|
1538 | if(err){
|
1539 | return;
|
1540 | }
|
1541 | }).on('data',function(d){
|
1542 | if(!e.buffer0){
|
1543 | e.buffer0=[d]
|
1544 | }else{
|
1545 | e.buffer0.push(d);
|
1546 | }
|
1547 | if((d[d.length-2] === 0xFF && d[d.length-1] === 0xD9)){
|
1548 | e.buffer0=Buffer.concat(e.buffer0);
|
1549 | ++e.frames;
|
1550 | if(s.group[e.ke].mon[e.id].spawn&&s.group[e.ke].mon[e.id].spawn.stdin){
|
1551 | s.group[e.ke].mon[e.id].spawn.stdin.write(e.buffer0);
|
1552 | }
|
1553 | if(s.group[e.ke].mon[e.id].started===1){
|
1554 | s.group[e.ke].mon[e.id].record.capturing=setTimeout(function(){
|
1555 | e.captureOne()
|
1556 | },1000/e.details.sfps);
|
1557 | }
|
1558 | e.buffer0=null;
|
1559 | }
|
1560 | if(!e.timeOut){
|
1561 | e.timeOut=setTimeout(function(){e.error_count=0;delete(e.timeOut);},3000);
|
1562 | }
|
1563 |
|
1564 | }).on('error', function(err){
|
1565 | ++e.error_count;
|
1566 | clearTimeout(e.timeOut);delete(e.timeOut);
|
1567 | if(e.details.loglevel!=='quiet'){
|
1568 | s.log(e,{type:lang['JPEG Error'],msg:{msg:lang.JPEGErrorText,info:err}});
|
1569 | switch(err.code){
|
1570 | case'ESOCKETTIMEDOUT':
|
1571 | case'ETIMEDOUT':
|
1572 | ++s.group[e.ke].mon[e.id].error_socket_timeout_count
|
1573 | if(e.details.fatal_max!==0&&s.group[e.ke].mon[e.id].error_socket_timeout_count>e.details.fatal_max){
|
1574 | s.log(e,{type:lang['Fatal Maximum Reached'],msg:{code:'ESOCKETTIMEDOUT',msg:lang.FatalMaximumReachedText}});
|
1575 | s.camera('stop',e)
|
1576 | }else{
|
1577 | s.log(e,{type:lang['Restarting Process'],msg:{code:'ESOCKETTIMEDOUT',msg:lang.FatalMaximumReachedText}});
|
1578 | s.camera('restart',e)
|
1579 | }
|
1580 | return;
|
1581 | break;
|
1582 | }
|
1583 | }
|
1584 | if(e.details.fatal_max!==0&&e.error_count>e.details.fatal_max){
|
1585 | clearTimeout(s.group[e.ke].mon[e.id].record.capturing);
|
1586 | e.fn();
|
1587 | }
|
1588 | });
|
1589 | }
|
1590 | e.captureOne()
|
1591 | }
|
1592 | if(!s.group[e.ke]||!s.group[e.ke].mon[e.id]){s.init(0,e)}
|
1593 | s.group[e.ke].mon[e.id].spawn.on('error',function(er){
|
1594 | s.log(e,{type:'Spawn Error',msg:er});e.error_fatal()
|
1595 | });
|
1596 | if(s.ocv&&e.details.detector==='1'){
|
1597 | s.tx({f:'init_monitor',id:e.id,ke:e.ke},s.ocv.id)
|
1598 | }
|
1599 |
|
1600 | s.group[e.ke].mon[e.id].spawn.stdin.on('data',function(d){
|
1601 | if(s.ocv&&e.details.detector==='1'&&e.details.detector_send_frames==='1'){
|
1602 | s.tx({f:'frame',mon:s.group[e.ke].mon_conf[e.id].details,ke:e.ke,id:e.id,time:s.moment(),frame:d},s.ocv.id);
|
1603 | };
|
1604 | })
|
1605 |
|
1606 | ++e.frames;
|
1607 | switch(e.details.stream_type){
|
1608 | case'flv':
|
1609 | e.frame_to_stream=function(d){
|
1610 | if(!s.group[e.ke].mon[e.id].firstFLVchunk)s.group[e.ke].mon[e.id].firstFLVchunk = d;
|
1611 | e.resetStreamCheck()
|
1612 | s.group[e.ke].mon[e.id].emitter.emit('data',d);
|
1613 | }
|
1614 | break;
|
1615 | case'mjpeg':
|
1616 | e.frame_to_stream=function(d){
|
1617 | e.resetStreamCheck()
|
1618 | s.group[e.ke].mon[e.id].emitter.emit('data',d);
|
1619 | }
|
1620 | break;
|
1621 | case'b64':case undefined:case null:
|
1622 | e.frame_to_stream=function(d){
|
1623 | e.resetStreamCheck()
|
1624 | if(s.group[e.ke]&&s.group[e.ke].mon[e.id]&&s.group[e.ke].mon[e.id].watch&&Object.keys(s.group[e.ke].mon[e.id].watch).length>0){
|
1625 | if(!e.buffer){
|
1626 | e.buffer=[d]
|
1627 | }else{
|
1628 | e.buffer.push(d);
|
1629 | }
|
1630 | if((d[d.length-2] === 0xFF && d[d.length-1] === 0xD9)){
|
1631 | e.buffer=Buffer.concat(e.buffer);
|
1632 | s.tx({f:'monitor_frame',ke:e.ke,id:e.id,time:s.moment(),frame:e.buffer.toString('base64'),frame_format:'b64'},'MON_STREAM_'+e.id);
|
1633 | e.buffer=null;
|
1634 | }
|
1635 | }
|
1636 | }
|
1637 | break;
|
1638 | }
|
1639 | if(e.frame_to_stream){
|
1640 | s.group[e.ke].mon[e.id].spawn.stdout.on('data',e.frame_to_stream);
|
1641 | }
|
1642 | if(x==='record'||e.type==='mjpeg'||e.type==='h264'||e.type==='local'){
|
1643 | s.group[e.ke].mon[e.id].spawn.stderr.on('data',function(d){
|
1644 | d=d.toString();
|
1645 | e.chk=function(x){return d.indexOf(x)>-1;}
|
1646 | switch(true){
|
1647 |
|
1648 | case e.chk('Could not find tag for vp8'):
|
1649 | case e.chk('Only VP8 or VP9 Video'):
|
1650 | case e.chk('Could not write header'):
|
1651 |
|
1652 |
|
1653 |
|
1654 |
|
1655 |
|
1656 |
|
1657 |
|
1658 |
|
1659 |
|
1660 |
|
1661 |
|
1662 |
|
1663 |
|
1664 |
|
1665 |
|
1666 | return s.log(e,{type:lang['Incorrect Settings Chosen'],msg:{msg:d}})
|
1667 | break;
|
1668 | case e.chk('NULL @'):
|
1669 | case e.chk('RTP: missed'):
|
1670 | case e.chk('deprecated pixel format used, make sure you did set range correctly'):
|
1671 | return
|
1672 | break;
|
1673 |
|
1674 | case e.chk('Connection refused'):
|
1675 | case e.chk('Connection timed out'):
|
1676 |
|
1677 | setTimeout(function(){s.log(e,{type:lang["Can't Connect"],msg:lang['Retrying...']});e.error_fatal();},1000)
|
1678 | break;
|
1679 |
|
1680 |
|
1681 |
|
1682 |
|
1683 |
|
1684 |
|
1685 |
|
1686 |
|
1687 |
|
1688 |
|
1689 |
|
1690 | case e.chk('mjpeg_decode_dc'):
|
1691 | case e.chk('bad vlc'):
|
1692 | case e.chk('error dc'):
|
1693 | e.fn()
|
1694 | break;
|
1695 | case /T[0-9][0-9]-[0-9][0-9]-[0-9][0-9]./.test(d):
|
1696 | return s.log(e,{type:lang['Video Finished'],msg:{filename:d}})
|
1697 | break;
|
1698 | }
|
1699 | s.log(e,{type:"FFMPEG STDERR",msg:d})
|
1700 | });
|
1701 | }
|
1702 | }else{
|
1703 | s.log(e,{type:lang["Can't Connect"],msg:lang['Retrying...']});e.error_fatal();return;
|
1704 | }
|
1705 | }
|
1706 | if(e.type!=='socket'&&e.type!=='dashcam'&&e.protocol!=='udp'&&e.type!=='local'){
|
1707 | connectionTester.test(e.hosty,e.port,2000,e.draw);
|
1708 | }else{
|
1709 | e.draw(null,{success:true})
|
1710 | }
|
1711 | }else{
|
1712 | s.kill(s.group[e.ke].mon[e.id].spawn,e);
|
1713 | }
|
1714 | }
|
1715 |
|
1716 | if(s.child_help===true){
|
1717 | e.ch=Object.keys(s.child_nodes);
|
1718 | if(e.ch.length>0){
|
1719 | e.ch_stop=0;
|
1720 | e.fn=function(n){
|
1721 | connectionTester.test(e.hosty,e.port,2000,function(err,o){
|
1722 | if(o.success===true){
|
1723 | s.video('open',e);
|
1724 | e.frames=0;
|
1725 | s.group[e.ke].mon[e.id].spawn={};
|
1726 | s.group[e.ke].mon[e.id].child_node=n;
|
1727 | s.cx({f:'spawn',d:s.init('noReference',e),mon:s.init('noReference',s.group[e.ke].mon[e.mid])},s.group[e.ke].mon[e.mid].child_node_id)
|
1728 | }else{
|
1729 |
|
1730 | e.error_fatal();return;
|
1731 | }
|
1732 | })
|
1733 | }
|
1734 | e.ch.forEach(function(n){
|
1735 | if(e.ch_stop===0&&s.child_nodes[n].cpu<80){
|
1736 | e.ch_stop=1;
|
1737 | s.group[e.ke].mon[e.mid].child_node=n;
|
1738 | s.group[e.ke].mon[e.mid].child_node_id=s.child_nodes[n].cnid;
|
1739 | e.fn(n);
|
1740 | }
|
1741 | })
|
1742 | }else{
|
1743 | e.fn();
|
1744 | }
|
1745 | }else{
|
1746 | e.fn();
|
1747 | }
|
1748 | break;
|
1749 | case'motion':
|
1750 | var d=e;
|
1751 | if(!s.group[d.ke]||!s.group[d.ke].mon[d.id]){
|
1752 | return s.systemLog(lang['No Monitor Found, Ignoring Request'])
|
1753 | }
|
1754 | d.mon=s.group[d.ke].mon_conf[d.id];
|
1755 | if(!s.group[d.ke].mon[d.id].detector_motion_count){
|
1756 | s.group[d.ke].mon[d.id].detector_motion_count=0
|
1757 | }
|
1758 | s.group[d.ke].mon[d.id].detector_motion_count+=1
|
1759 | if(s.group[d.ke].mon[d.id].motion_lock){
|
1760 | return
|
1761 | }
|
1762 | if(!d.mon.details.detector_lock_timeout||d.mon.details.detector_lock_timeout===''){
|
1763 | d.mon.details.detector_lock_timeout=2000
|
1764 | }
|
1765 | d.mon.details.detector_lock_timeout=parseFloat(d.mon.details.detector_lock_timeout);
|
1766 | if(!s.group[d.ke].mon[d.id].detector_lock_timeout){
|
1767 | s.group[d.ke].mon[d.id].detector_lock_timeout=setTimeout(function(){
|
1768 | clearTimeout(s.group[d.ke].mon[d.id].detector_lock_timeout)
|
1769 | delete(s.group[d.ke].mon[d.id].detector_lock_timeout)
|
1770 | },d.mon.details.detector_lock_timeout)
|
1771 | }else{
|
1772 | return
|
1773 | }
|
1774 | d.cx={f:'detector_trigger',id:d.id,ke:d.ke,details:d.details};
|
1775 | s.tx(d.cx,'GRP_'+d.ke);
|
1776 | if(d.mon.details.detector_notrigger=='1'){
|
1777 | if(!d.mon.details.detector_notrigger_timeout||d.mon.details.detector_notrigger_timeout===''){
|
1778 | d.mon.details.detector_notrigger_timeout=10
|
1779 | }
|
1780 | d.mon.detector_notrigger_timeout=parseFloat(d.mon.details.detector_notrigger_timeout)*1000*60;
|
1781 | clearInterval(s.group[d.ke].mon[d.id].detector_notrigger_timeout)
|
1782 | s.group[d.ke].mon[d.id].detector_notrigger_timeout=setInterval(s.group[d.ke].mon[d.id].detector_notrigger_timeout_function,d.mon.detector_notrigger_timeout)
|
1783 | }
|
1784 | if(d.mon.details.detector_webhook=='1'){
|
1785 | d.mon.details.detector_webhook_url=d.mon.details.detector_webhook_url
|
1786 | .replace(/{{TIME}}/g,moment(new Date).format())
|
1787 | .replace(/{{MONITOR_ID}}/g,d.id)
|
1788 | .replace(/{{GROUP_KEY}}/g,d.ke);
|
1789 | http.get(d.mon.details.detector_webhook_url, function(data) {
|
1790 | data.setEncoding('utf8');
|
1791 | var chunks='';
|
1792 | data.on('data', (chunk) => {
|
1793 | chunks+=chunk;
|
1794 | });
|
1795 | data.on('end', () => {
|
1796 |
|
1797 | });
|
1798 |
|
1799 | }).on('error', function(e) {
|
1800 |
|
1801 | }).end();
|
1802 | }
|
1803 | if(d.mon.mode!=='stop'&&d.mon.details.detector_trigger=='1'&&d.mon.details.detector_record_method==='hot'){
|
1804 | if(!d.mon.details.detector_timeout||d.mon.details.detector_timeout===''){
|
1805 | d.mon.details.detector_timeout=10
|
1806 | }else{
|
1807 | d.mon.details.detector_timeout=parseFloat(d.mon.details.detector_timeout)
|
1808 | }
|
1809 | if(!d.auth){
|
1810 | d.auth=s.gid();
|
1811 | }
|
1812 | if(!s.group[d.ke].users[d.auth]){
|
1813 | s.group[d.ke].users[d.auth]={system:1,details:{},lang:lang}
|
1814 | }
|
1815 | d.urlQuery=[]
|
1816 | d.url='http://'+config.ip+':'+config.port+'/'+d.auth+'/monitor/'+d.ke+'/'+d.id+'/record/'+d.mon.details.detector_timeout+'/min';
|
1817 | if(d.mon.details.watchdog_reset!=='0'){
|
1818 | d.urlQuery.push('reset=1')
|
1819 | }
|
1820 | if(d.mon.details.detector_trigger_record_fps&&d.mon.details.detector_trigger_record_fps!==''&&d.mon.details.detector_trigger_record_fps!=='0'){
|
1821 | d.urlQuery.push('fps='+d.mon.details.detector_trigger_record_fps)
|
1822 | }
|
1823 | if(d.urlQuery.length>0){
|
1824 | d.url+='?'+d.urlQuery.join('&')
|
1825 | }
|
1826 | http.get(d.url, function(data) {
|
1827 | data.setEncoding('utf8');
|
1828 | var chunks='';
|
1829 | data.on('data', (chunk) => {
|
1830 | chunks+=chunk;
|
1831 | });
|
1832 | data.on('end', () => {
|
1833 | delete(s.group[d.ke].users[d.auth])
|
1834 | d.cx.f='detector_record_engaged';
|
1835 | d.cx.msg=JSON.parse(chunks);
|
1836 | s.tx(d.cx,'GRP_'+d.ke);
|
1837 | });
|
1838 |
|
1839 | }).on('error', function(e) {
|
1840 |
|
1841 | }).end();
|
1842 | }
|
1843 |
|
1844 | if(config.mail&&!s.group[d.ke].mon[d.id].detector_mail&&d.mon.details.detector_mail==='1'){
|
1845 | s.sqlQuery('SELECT mail FROM Users WHERE ke=? AND details NOT LIKE ?',[d.ke,'%"sub"%'],function(err,r){
|
1846 | r=r[0];
|
1847 | if(!d.mon.details.detector_mail_timeout||d.mon.details.detector_mail_timeout===''){
|
1848 | d.mon.details.detector_mail_timeout=1000*60*10;
|
1849 | }else{
|
1850 | d.mon.details.detector_mail_timeout=parseFloat(d.mon.details.detector_mail_timeout)*1000*60;
|
1851 | }
|
1852 |
|
1853 | s.group[d.ke].mon[d.id].detector_mail=setTimeout(function(){
|
1854 |
|
1855 | clearTimeout(s.group[d.ke].mon[d.id].detector_mail);
|
1856 | delete(s.group[d.ke].mon[d.id].detector_mail);
|
1857 | },d.mon.details.detector_mail_timeout);
|
1858 | d.frame_filename='Motion_'+(d.mon.name.replace(/[^\w\s]/gi, ''))+'_'+d.id+'_'+d.ke+'_'+s.moment()+'.jpg';
|
1859 | fs.readFile(s.dir.streams+'/'+d.ke+'/'+d.id+'/s.jpg',function(err, frame){
|
1860 | d.mailOptions = {
|
1861 | from: '"ShinobiCCTV" <no-reply@shinobi.video>',
|
1862 | to: r.mail,
|
1863 | subject: lang.Event+' - '+d.frame_filename,
|
1864 | html: '<i>'+lang.EventText1+' '+moment(new Date).format()+'.</i>',
|
1865 | };
|
1866 | if(err){
|
1867 | s.systemLog(lang.EventText2+' '+d.ke+' '+d.id,err)
|
1868 | }else{
|
1869 | d.mailOptions.attachments=[
|
1870 | {
|
1871 | filename: d.frame_filename,
|
1872 | content: frame
|
1873 | }
|
1874 | ]
|
1875 | d.mailOptions.html='<i>'+lang.EventText3+'</i>'
|
1876 | }
|
1877 | Object.keys(d.details).forEach(function(v,n){
|
1878 | d.mailOptions.html+='<div><b>'+v+'</b> : '+d.details[v]+'</div>'
|
1879 | })
|
1880 | nodemailer.sendMail(d.mailOptions, (error, info) => {
|
1881 | if (error) {
|
1882 | s.systemLog(lang.MailError,error)
|
1883 | return ;
|
1884 | }
|
1885 | });
|
1886 | })
|
1887 | });
|
1888 | }
|
1889 |
|
1890 | if(d.mon.details.detector_save==='1'){
|
1891 | s.sqlQuery('INSERT INTO Events (ke,mid,details) VALUES (?,?,?)',[d.ke,d.id,JSON.stringify(d.details)])
|
1892 | }
|
1893 | if(d.mon.details.detector_command_enable==='1'&&!s.group[d.ke].mon[d.id].detector_command){
|
1894 | if(!d.mon.details.detector_command_timeout||d.mon.details.detector_command_timeout===''){
|
1895 | d.mon.details.detector_command_timeout=1000*60*10;
|
1896 | }else{
|
1897 | d.mon.details.detector_command_timeout=parseFloat(d.mon.details.detector_command_timeout)*1000*60;
|
1898 | }
|
1899 | s.group[d.ke].mon[d.id].detector_command=setTimeout(function(){
|
1900 | clearTimeout(s.group[d.ke].mon[d.id].detector_command);
|
1901 | delete(s.group[d.ke].mon[d.id].detector_command);
|
1902 |
|
1903 | },d.mon.details.detector_command_timeout);
|
1904 | d.mon.details.detector_command=d.mon.details.detector_command
|
1905 | .replace(/{{TIME}}/g,moment(new Date).format())
|
1906 | .replace(/{{MONITOR_ID}}/g,d.id)
|
1907 | .replace(/{{GROUP_KEY}}/g,d.ke)
|
1908 | if(d.details.confidence){
|
1909 | d.mon.details.detector_command=d.mon.details.detector_command
|
1910 | .replace(/{{CONFIDENCE}}/g,d.details.confidence)
|
1911 | }
|
1912 | exec(d.mon.details.detector_command,{detached: true})
|
1913 | }
|
1914 | break;
|
1915 | }
|
1916 | if(typeof cn==='function'){setTimeout(function(){cn()},1000);}
|
1917 | }
|
1918 |
|
1919 |
|
1920 | s.cn=function(cn){return{id:cn.id,ke:cn.ke,uid:cn.uid}}
|
1921 | io.on('connection', function (cn) {
|
1922 | var tx;
|
1923 | cn.on('f',function(d){
|
1924 | if(!cn.ke&&d.f==='init'){
|
1925 | cn.ip=cn.request.connection.remoteAddress;
|
1926 | tx=function(z){if(!z.ke){z.ke=cn.ke;};cn.emit('f',z);}
|
1927 | d.failed=function(){tx({ok:false,msg:'Not Authorized',token_used:d.auth,ke:d.ke});cn.disconnect();}
|
1928 | d.success=function(r){
|
1929 | r=r[0];cn.join('GRP_'+d.ke);cn.join('CPU');
|
1930 | cn.ke=d.ke,
|
1931 | cn.uid=d.uid,
|
1932 | cn.auth=d.auth;
|
1933 | if(!s.group[d.ke])s.group[d.ke]={};
|
1934 |
|
1935 | if(!s.group[d.ke].users)s.group[d.ke].users={};
|
1936 |
|
1937 | s.group[d.ke].users[d.auth]={cnid:cn.id,uid:r.uid,mail:r.mail,details:JSON.parse(r.details),logged_in_at:moment(new Date).format(),login_type:'Dashboard'}
|
1938 | try{s.group[d.ke].users[d.auth].details=JSON.parse(r.details)}catch(er){}
|
1939 | if(s.group[d.ke].users[d.auth].details.get_server_log!=='0'){
|
1940 | cn.join('GRPLOG_'+d.ke)
|
1941 | }
|
1942 | s.group[d.ke].users[d.auth].lang=s.getLanguageFile(s.group[d.ke].users[d.auth].details.lang)
|
1943 | s.log({ke:d.ke,mid:'$USER'},{type:s.group[d.ke].users[d.auth].lang['Websocket Connected'],msg:{mail:r.mail,id:d.uid,ip:cn.ip}})
|
1944 | if(!s.group[d.ke].mon){
|
1945 | s.group[d.ke].mon={}
|
1946 | if(!s.group[d.ke].mon){s.group[d.ke].mon={}}
|
1947 | }
|
1948 | if(s.ocv){
|
1949 | tx({f:'detector_plugged',plug:s.ocv.plug,notice:s.ocv.notice})
|
1950 | s.tx({f:'readPlugins',ke:d.ke},s.ocv.id)
|
1951 | }
|
1952 | tx({f:'users_online',users:s.group[d.ke].users})
|
1953 | s.tx({f:'user_status_change',ke:d.ke,uid:cn.uid,status:1,user:s.group[d.ke].users[d.auth]},'GRP_'+d.ke)
|
1954 | s.init('diskUsedEmit',d)
|
1955 | s.init('apps',d)
|
1956 | s.sqlQuery('SELECT * FROM API WHERE ke=? && uid=?',[d.ke,d.uid],function(err,rrr) {
|
1957 | tx({
|
1958 | f:'init_success',
|
1959 | users:s.group[d.ke].vid,
|
1960 | apis:rrr,
|
1961 | os:{
|
1962 | platform:s.platform,
|
1963 | cpuCount:os.cpus().length,
|
1964 | totalmem:s.totalmem
|
1965 | }
|
1966 | })
|
1967 | http.get('http://'+config.ip+':'+config.port+'/'+cn.auth+'/monitor/'+cn.ke, function(res){
|
1968 | var body = '';
|
1969 | res.on('data', function(chunk){
|
1970 | body += chunk;
|
1971 | });
|
1972 | res.on('end', function(){
|
1973 | var rr = JSON.parse(body);
|
1974 | setTimeout(function(g){
|
1975 | g=function(t){
|
1976 | s.camera('snapshot',{mid:t.mid,ke:t.ke,mon:t})
|
1977 | }
|
1978 | if(rr.mid){
|
1979 | g(rr)
|
1980 | }else{
|
1981 | rr.forEach(g)
|
1982 | }
|
1983 | },2000)
|
1984 | });
|
1985 | }).on('error', function(e){
|
1986 |
|
1987 | });
|
1988 | })
|
1989 | }
|
1990 | s.sqlQuery('SELECT ke,uid,auth,mail,details FROM Users WHERE ke=? AND auth=? AND uid=?',[d.ke,d.auth,d.uid],function(err,r) {
|
1991 | if(r&&r[0]){
|
1992 | d.success(r)
|
1993 | }else{
|
1994 | s.sqlQuery('SELECT * FROM API WHERE ke=? AND code=? AND uid=?',[d.ke,d.auth,d.uid],function(err,r) {
|
1995 | if(r&&r[0]){
|
1996 | r=r[0]
|
1997 | r.details=JSON.parse(r.details)
|
1998 | if(r.details.auth_socket==='1'){
|
1999 | s.sqlQuery('SELECT ke,uid,auth,mail,details FROM Users WHERE ke=? AND uid=?',[r.ke,r.uid],function(err,r) {
|
2000 | if(r&&r[0]){
|
2001 | d.success(r)
|
2002 | }else{
|
2003 | d.failed()
|
2004 | }
|
2005 | })
|
2006 | }else{
|
2007 | d.failed()
|
2008 | }
|
2009 | }else{
|
2010 | d.failed()
|
2011 | }
|
2012 | })
|
2013 | }
|
2014 | })
|
2015 | return;
|
2016 | }
|
2017 | if((d.id||d.uid||d.mid)&&cn.ke){
|
2018 | try{
|
2019 | switch(d.f){
|
2020 | case'ocv_in':
|
2021 | if(s.ocv){
|
2022 | s.tx(d.data,s.ocv.id)
|
2023 | }
|
2024 | break;
|
2025 | case'monitorOrder':
|
2026 | if(d.monitorOrder&&d.monitorOrder instanceof Array){
|
2027 | s.sqlQuery('SELECT details FROM Users WHERE uid=? AND ke=?',[cn.uid,cn.ke],function(err,r){
|
2028 | if(r&&r[0]){
|
2029 | r=JSON.parse(r[0].details);
|
2030 | r.monitorOrder=d.monitorOrder;
|
2031 | s.sqlQuery('UPDATE Users SET details=? WHERE uid=? AND ke=?',[JSON.stringify(r),cn.uid,cn.ke])
|
2032 | }
|
2033 | })
|
2034 | }
|
2035 | break;
|
2036 | case'update':
|
2037 | if(!config.updateKey){
|
2038 | tx({error:lang.updateKeyText1});
|
2039 | return;
|
2040 | }
|
2041 | if(d.key===config.updateKey){
|
2042 | exec('chmod +x '+__dirname+'/UPDATE.sh&&'+__dirname+'/./UPDATE.sh',{detached: true})
|
2043 | }else{
|
2044 | tx({error:lang.updateKeyText2});
|
2045 | }
|
2046 | break;
|
2047 | case'cron':
|
2048 | if(s.group[cn.ke]&&s.group[cn.ke].users[cn.auth].details&&!s.group[cn.ke].users[cn.auth].details.sub){
|
2049 | s.tx({f:d.ff},s.cron.id)
|
2050 | }
|
2051 | break;
|
2052 | case'api':
|
2053 | switch(d.ff){
|
2054 | case'delete':
|
2055 | d.set=[],d.ar=[];
|
2056 | d.form.ke=cn.ke;d.form.uid=cn.uid;delete(d.form.ip);
|
2057 | if(!d.form.code){tx({f:'form_incomplete',form:'APIs'});return}
|
2058 | d.for=Object.keys(d.form);
|
2059 | d.for.forEach(function(v){
|
2060 | d.set.push(v+'=?'),d.ar.push(d.form[v]);
|
2061 | });
|
2062 | s.sqlQuery('DELETE FROM API WHERE '+d.set.join(' AND '),d.ar,function(err,r){
|
2063 | if(!err){
|
2064 | tx({f:'api_key_deleted',form:d.form});
|
2065 | delete(s.api[d.form.code]);
|
2066 | }else{
|
2067 | s.systemLog('API Delete Error : '+e.ke+' : '+' : '+e.mid,err)
|
2068 | }
|
2069 | })
|
2070 | break;
|
2071 | case'add':
|
2072 | d.set=[],d.qu=[],d.ar=[];
|
2073 | d.form.ke=cn.ke,d.form.uid=cn.uid,d.form.code=s.gid(30);
|
2074 | d.for=Object.keys(d.form);
|
2075 | d.for.forEach(function(v){
|
2076 | d.set.push(v),d.qu.push('?'),d.ar.push(d.form[v]);
|
2077 | });
|
2078 | d.ar.push(cn.ke);
|
2079 | s.sqlQuery('INSERT INTO API ('+d.set.join(',')+') VALUES ('+d.qu.join(',')+')',d.ar,function(err,r){
|
2080 | d.form.time=s.moment(new Date,'YYYY-DD-MM HH:mm:ss');
|
2081 | if(!err){tx({f:'api_key_added',form:d.form});}else{s.systemLog(err)}
|
2082 | });
|
2083 | break;
|
2084 | }
|
2085 | break;
|
2086 | case'settings':
|
2087 | switch(d.ff){
|
2088 | case'filters':
|
2089 | switch(d.fff){
|
2090 | case'save':case'delete':
|
2091 | s.sqlQuery('SELECT details FROM Users WHERE ke=? AND uid=?',[d.ke,d.uid],function(err,r){
|
2092 | if(r&&r[0]){
|
2093 | r=r[0];
|
2094 | d.d=JSON.parse(r.details);
|
2095 | if(d.form.id===''){d.form.id=s.gid(5)}
|
2096 | if(!d.d.filters)d.d.filters={};
|
2097 |
|
2098 | if(d.fff==='save'){
|
2099 | d.d.filters[d.form.id]=d.form;
|
2100 | }else{
|
2101 | delete(d.d.filters[d.form.id]);
|
2102 | }
|
2103 | s.sqlQuery('UPDATE Users SET details=? WHERE ke=? AND uid=?',[JSON.stringify(d.d),d.ke,d.uid],function(err,r){
|
2104 | tx({f:'filters_change',uid:d.uid,ke:d.ke,filters:d.d.filters});
|
2105 | });
|
2106 | }
|
2107 | })
|
2108 | break;
|
2109 | }
|
2110 | break;
|
2111 | case'edit':
|
2112 | s.sqlQuery('SELECT details FROM Users WHERE ke=? AND uid=?',[d.ke,d.uid],function(err,r){
|
2113 | if(r&&r[0]){
|
2114 | r=r[0];
|
2115 | d.d=JSON.parse(r.details);
|
2116 | if(d.d.get_server_log==='1'){
|
2117 | cn.join('GRPLOG_'+d.ke)
|
2118 | }else{
|
2119 | cn.leave('GRPLOG_'+d.ke)
|
2120 | }
|
2121 |
|
2122 | d.form.details=JSON.parse(d.form.details)
|
2123 |
|
2124 | d.form.details.permissions=d.d.permissions
|
2125 | d.form.details.edit_size=d.d.edit_size
|
2126 | d.form.details.edit_days=d.d.edit_days
|
2127 | d.form.details.use_admin=d.d.use_admin
|
2128 | d.form.details.use_webdav=d.d.use_webdav
|
2129 | d.form.details.use_ldap=d.d.use_ldap
|
2130 |
|
2131 | if(d.d.edit_days=="0"){
|
2132 | d.form.details.days=d.d.days;
|
2133 | }
|
2134 | if(d.d.edit_size=="0"){
|
2135 | d.form.details.size=d.d.size;
|
2136 | }
|
2137 | if(d.d.sub){
|
2138 | d.form.details.sub=d.d.sub;
|
2139 | if(d.d.monitors){d.form.details.monitors=d.d.monitors;}
|
2140 | if(d.d.allmonitors){d.form.details.allmonitors=d.d.allmonitors;}
|
2141 | if(d.d.video_delete){d.form.details.video_delete=d.d.video_delete;}
|
2142 | if(d.d.video_view){d.form.details.video_view=d.d.video_view;}
|
2143 | if(d.d.monitor_edit){d.form.details.monitor_edit=d.d.monitor_edit;}
|
2144 | if(d.d.size){d.form.details.size=d.d.size;}
|
2145 | if(d.d.days){d.form.details.days=d.d.days;}
|
2146 | delete(d.form.details.mon_groups)
|
2147 | }
|
2148 | var newSize = d.form.details.size
|
2149 | d.form.details=JSON.stringify(d.form.details)
|
2150 |
|
2151 | d.set=[],d.ar=[];
|
2152 | if(d.form.pass&&d.form.pass!==''){d.form.pass=s.md5(d.form.pass);}else{delete(d.form.pass)};
|
2153 | delete(d.form.password_again);
|
2154 | d.for=Object.keys(d.form);
|
2155 | d.for.forEach(function(v){
|
2156 | d.set.push(v+'=?'),d.ar.push(d.form[v]);
|
2157 | });
|
2158 | d.ar.push(d.ke),d.ar.push(d.uid);
|
2159 | s.sqlQuery('UPDATE Users SET '+d.set.join(',')+' WHERE ke=? AND uid=?',d.ar,function(err,r){
|
2160 | if(!d.d.sub){
|
2161 | s.group[d.ke].sizeLimit = parseFloat(newSize)
|
2162 | delete(s.group[d.ke].webdav)
|
2163 | s.init('apps',d)
|
2164 | }
|
2165 | tx({f:'user_settings_change',uid:d.uid,ke:d.ke,form:d.form});
|
2166 | });
|
2167 | }
|
2168 | })
|
2169 | break;
|
2170 | }
|
2171 | break;
|
2172 | case'monitor':
|
2173 | switch(d.ff){
|
2174 | case'control':
|
2175 | if(!s.group[d.ke]||!s.group[d.ke].mon[d.mid]){return}
|
2176 | d.m=s.group[d.ke].mon_conf[d.mid];
|
2177 | if(d.m.details.control!=="1"){s.log(d,{type:lang['Control Error'],msg:lang.ControlErrorText1});return}
|
2178 | if(!d.m.details.control_base_url||d.m.details.control_base_url===''){
|
2179 | d.base=s.init('url_no_path',d.m);
|
2180 | }else{
|
2181 | d.base=d.m.details.control_base_url;
|
2182 | }
|
2183 | if(!d.m.details.control_url_stop_timeout||d.m.details.control_url_stop_timeout===''){d.m.details.control_url_stop_timeout=1000}
|
2184 | d.setURL=function(url){
|
2185 | d.URLobject=URL.parse(url)
|
2186 | if(!d.URLobject.port){d.URLobject.port=80}
|
2187 | d.options = {
|
2188 | host: d.URLobject.hostname,
|
2189 | port: d.URLobject.port,
|
2190 | method: "GET",
|
2191 | path: d.URLobject.pathname,
|
2192 | };
|
2193 | if(d.URLobject.query){
|
2194 | d.options.path=d.options.path+'?'+d.URLobject.query
|
2195 | }
|
2196 | if(d.URLobject.username&&d.URLobject.password){
|
2197 | d.options.auth=d.URLobject.username+':'+d.URLobject.password
|
2198 | }
|
2199 | if(d.URLobject.auth){
|
2200 | d.options.auth=d.URLobject.auth
|
2201 | }
|
2202 | }
|
2203 | d.setURL(d.base+d.m.details['control_url_'+d.direction])
|
2204 | http.get(d.options, function(first) {
|
2205 | first.on('data', function(toss) {});
|
2206 | first.endCommand=function(){
|
2207 | clearTimeout(first.endCommandLastResort)
|
2208 | if(d.m.details.control_stop=='1'&&d.direction!=='center'){
|
2209 | d.setURL(d.base+d.m.details['control_url_'+d.direction+'_stop'])
|
2210 | setTimeout(function(){
|
2211 | http.get(d.options, function(data) {
|
2212 | data.on('end', function(){
|
2213 | if(err){s.log(d,{type:'Control Error',msg:err});return false}
|
2214 | s.tx({f:'control',mid:d.mid,ke:d.ke,direction:d.direction,url_stop:true});
|
2215 | });
|
2216 | }).on('error', function(err) {
|
2217 | s.log(d,{type:'Control Error',msg:err});
|
2218 | }).end();
|
2219 | },d.m.details.control_url_stop_timeout)
|
2220 | }else{
|
2221 | tx({f:'control',mid:d.mid,ke:d.ke,direction:d.direction,url_stop:false});
|
2222 | }
|
2223 | }
|
2224 | first.on('end',first.endCommand);
|
2225 | first.endCommandLastResort=setTimeout(first.endCommand,3000)
|
2226 | }).on('error', function(err) {
|
2227 | s.log(d,{type:'Control Error',msg:err});
|
2228 | }).end();
|
2229 | break;
|
2230 | case'jpeg_off':
|
2231 | delete(cn.jpeg_on);
|
2232 | if(cn.monitor_watching){
|
2233 | Object.keys(cn.monitor_watching).forEach(function(n,v){
|
2234 | v=cn.monitor_watching[n];
|
2235 | cn.join('MON_STREAM_'+n);
|
2236 | });
|
2237 | }
|
2238 | tx({f:'mode_jpeg_off'})
|
2239 | break;
|
2240 | case'jpeg_on':
|
2241 | cn.jpeg_on=true;
|
2242 | if(cn.monitor_watching){
|
2243 | Object.keys(cn.monitor_watching).forEach(function(n,v){
|
2244 | v=cn.monitor_watching[n];
|
2245 | cn.leave('MON_STREAM_'+n);
|
2246 | });
|
2247 | }
|
2248 | tx({f:'mode_jpeg_on'})
|
2249 | break;
|
2250 | case'watch_on':
|
2251 | if(!d.ke){d.ke=cn.ke}
|
2252 | s.init(0,{mid:d.id,ke:d.ke});
|
2253 | if(!s.group[d.ke]||!s.group[d.ke].mon[d.id]||s.group[d.ke].mon[d.id].started===0){return false}
|
2254 | s.camera(d.ff,d,cn,tx)
|
2255 | cn.join('MON_'+d.id);
|
2256 | if(cn.jpeg_on!==true){
|
2257 | cn.join('MON_STREAM_'+d.id);
|
2258 | } if(s.group[d.ke]&&s.group[d.ke].mon&&s.group[d.ke].mon[d.id]&&s.group[d.ke].mon[d.id].watch){
|
2259 |
|
2260 | tx({f:'monitor_watch_on',id:d.id,ke:d.ke})
|
2261 | s.tx({viewers:Object.keys(s.group[d.ke].mon[d.id].watch).length,ke:d.ke,id:d.id},'MON_'+d.id)
|
2262 | }
|
2263 | break;
|
2264 | case'watch_off':
|
2265 | if(!d.ke){d.ke=cn.ke;};cn.leave('MON_'+d.id);s.camera(d.ff,d,cn,tx);
|
2266 | s.tx({viewers:d.ob,ke:d.ke,id:d.id},'MON_'+d.id)
|
2267 | break;
|
2268 | case'start':case'stop':
|
2269 | s.sqlQuery('SELECT * FROM Monitors WHERE ke=? AND mid=?',[cn.ke,d.id],function(err,r) {
|
2270 | if(r&&r[0]){r=r[0]
|
2271 | s.camera(d.ff,{type:r.type,url:s.init('url',r),id:d.id,mode:d.ff,ke:cn.ke});
|
2272 | }
|
2273 | })
|
2274 | break;
|
2275 | }
|
2276 | break;
|
2277 | case'video':
|
2278 | switch(d.ff){
|
2279 | case'fix':
|
2280 | s.video('fix',d)
|
2281 | break;
|
2282 | case'delete':
|
2283 | s.video('delete',d)
|
2284 | break;
|
2285 | }
|
2286 | break;
|
2287 | case'ffprobe':
|
2288 | if(s.group[cn.ke].users[cn.auth]){
|
2289 | switch(d.ff){
|
2290 | case'stop':
|
2291 | exec('kill -9 '+s.group[cn.ke].users[cn.auth].ffprobe.pid,{detatched: true})
|
2292 | break;
|
2293 | default:
|
2294 | if(s.group[cn.ke].users[cn.auth].ffprobe){
|
2295 | return
|
2296 | }
|
2297 | s.group[cn.ke].users[cn.auth].ffprobe=1;
|
2298 | tx({f:'ffprobe_start'})
|
2299 | exec('ffprobe '+('-v quiet -print_format json -show_format -show_streams '+d.query),function(err,data){
|
2300 | tx({f:'ffprobe_data',data:data.toString('utf8')})
|
2301 | delete(s.group[cn.ke].users[cn.auth].ffprobe)
|
2302 | tx({f:'ffprobe_stop'})
|
2303 | })
|
2304 |
|
2305 | setTimeout(function(){
|
2306 | exec('kill -9 '+d.pid,{detached: true})
|
2307 | },30000)
|
2308 | break;
|
2309 | }
|
2310 | }
|
2311 | break;
|
2312 | case'onvif':
|
2313 | d.ip=d.ip.replace(/ /g,'');
|
2314 | d.port=d.port.replace(/ /g,'');
|
2315 | if(d.ip===''){
|
2316 | var interfaces = os.networkInterfaces();
|
2317 | var addresses = [];
|
2318 | for (var k in interfaces) {
|
2319 | for (var k2 in interfaces[k]) {
|
2320 | var address = interfaces[k][k2];
|
2321 | if (address.family === 'IPv4' && !address.internal) {
|
2322 | addresses.push(address.address);
|
2323 | }
|
2324 | }
|
2325 | }
|
2326 | d.arr=[]
|
2327 | addresses.forEach(function(v){
|
2328 | if(v.indexOf('0.0.0')>-1){return false}
|
2329 | v=v.split('.');
|
2330 | delete(v[3]);
|
2331 | v=v.join('.');
|
2332 | d.arr.push(v+'1-'+v+'254')
|
2333 | })
|
2334 | d.ip=d.arr.join(',')
|
2335 | }
|
2336 | if(d.port===''){
|
2337 | d.port='80,8080,554'
|
2338 | }
|
2339 | d.ip.split(',').forEach(function(v){
|
2340 | if(v.indexOf('-')>-1){
|
2341 | v=v.split('-');
|
2342 | d.IP_RANGE_START = v[0],
|
2343 | d.IP_RANGE_END = v[1];
|
2344 | }else{
|
2345 | d.IP_RANGE_START = v;
|
2346 | d.IP_RANGE_END = v;
|
2347 | }
|
2348 | if(!d.IP_LIST){
|
2349 | d.IP_LIST = s.ipRange(d.IP_RANGE_START,d.IP_RANGE_END);
|
2350 | }else{
|
2351 | d.IP_LIST=d.IP_LIST.concat(s.ipRange(d.IP_RANGE_START,d.IP_RANGE_END))
|
2352 | }
|
2353 |
|
2354 | if(d.port.indexOf('-')>-1){
|
2355 | d.port=d.port.split('-');
|
2356 | d.PORT_RANGE_START = d.port[0];
|
2357 | d.PORT_RANGE_END = d.port[1];
|
2358 | d.PORT_LIST = s.portRange(d.PORT_RANGE_START,d.PORT_RANGE_END);
|
2359 | }else{
|
2360 | d.PORT_LIST=d.port.split(',')
|
2361 | }
|
2362 |
|
2363 | d.USERNAME='';
|
2364 | if(d.user){
|
2365 | d.USERNAME = d.user
|
2366 | }
|
2367 | d.PASSWORD='';
|
2368 | if(d.pass){
|
2369 | d.PASSWORD = d.pass
|
2370 | }
|
2371 | })
|
2372 | d.cams=[]
|
2373 | d.IP_LIST.forEach(function(ip_entry,n) {
|
2374 | d.PORT_LIST.forEach(function(port_entry,nn) {
|
2375 | return new Cam({
|
2376 | hostname: ip_entry,
|
2377 | username: d.USERNAME,
|
2378 | password: d.PASSWORD,
|
2379 | port: port_entry,
|
2380 | timeout : 5000
|
2381 | }, function CamFunc(err,data) {
|
2382 | if (err) return;
|
2383 | data={f:'onvif',ip:ip_entry,port:port_entry}
|
2384 | var cam_obj = this;
|
2385 | cam_obj.getSystemDateAndTime(function(er, date, xml) {
|
2386 | if (!er) data.date = date;
|
2387 | cam_obj.getDeviceInformation(function(er, info, xml) {
|
2388 | if (!er) data.info = info;
|
2389 | try {
|
2390 | cam_obj.getStreamUri({
|
2391 | protocol: 'RTSP'
|
2392 | },function(er, stream, xml) {
|
2393 | if (!er) data.url = stream;
|
2394 | tx(data)
|
2395 | });
|
2396 | }catch(err){
|
2397 | tx(data);
|
2398 | }
|
2399 | });
|
2400 | });
|
2401 | });
|
2402 | });
|
2403 | });
|
2404 | break;
|
2405 | }
|
2406 | }catch(er){
|
2407 | s.systemLog('ERROR CATCH 1',er)
|
2408 | }
|
2409 | }else{
|
2410 | tx({ok:false,msg:lang.NotAuthorizedText1});
|
2411 | }
|
2412 | });
|
2413 |
|
2414 | cn.on('ocv',function(d){
|
2415 | if(!cn.ocv&&d.f==='init'){
|
2416 | if(config.pluginKeys[d.plug]===d.pluginKey){
|
2417 | s.api[cn.id]={ocvID:cn.id,permissions:{},details:{},ip:'0.0.0.0'};
|
2418 | s.ocv={started:moment(),id:cn.id,plug:d.plug,notice:d.notice};
|
2419 | cn.ocv=1;
|
2420 | s.tx({f:'api_key',key:cn.id},cn.id)
|
2421 | s.tx({f:'detector_plugged',plug:d.plug,notice:d.notice},'CPU')
|
2422 | s.tx({f:'readPlugins',ke:d.ke},'CPU')
|
2423 | s.systemLog('Connected to plugin : Detector - '+d.plug)
|
2424 | }else{
|
2425 | cn.disconnect()
|
2426 | }
|
2427 | }else{
|
2428 | if(config.pluginKeys[d.plug]===d.pluginKey){
|
2429 | switch(d.f){
|
2430 | case'trigger':
|
2431 | s.camera('motion',d)
|
2432 | break;
|
2433 | case's.tx':
|
2434 | s.tx(d.data,d.to)
|
2435 | break;
|
2436 | case'sql':
|
2437 | s.sqlQuery(d.query,d.values);
|
2438 | break;
|
2439 | case'log':
|
2440 | s.systemLog('PLUGIN : '+d.plug+' : ',d)
|
2441 | break;
|
2442 | }
|
2443 | }else{
|
2444 | cn.disconnect()
|
2445 | }
|
2446 | }
|
2447 | })
|
2448 |
|
2449 | cn.on('cron',function(d){
|
2450 | if(d.f==='init'){
|
2451 | if(config.cron.key){
|
2452 | if(config.cron.key===d.cronKey){
|
2453 | s.cron={started:moment(),last_run:moment(),id:cn.id};
|
2454 | }else{
|
2455 | cn.disconnect()
|
2456 | }
|
2457 | }else{
|
2458 | s.cron={started:moment(),last_run:moment(),id:cn.id};
|
2459 | }
|
2460 | }else{
|
2461 | if(s.cron&&cn.id===s.cron.id){
|
2462 | delete(d.cronKey)
|
2463 | switch(d.f){
|
2464 | case'filters':
|
2465 | s.filter(d.ff,d);
|
2466 | break;
|
2467 | case's.tx':
|
2468 | s.tx(d.data,d.to)
|
2469 | break;
|
2470 | case's.video':
|
2471 | s.video(d.data,d.file)
|
2472 | break;
|
2473 | case'start':case'end':
|
2474 | d.mid='_cron';s.log(d,{type:'cron',msg:d.msg})
|
2475 | break;
|
2476 | default:
|
2477 | s.systemLog('CRON : ',d)
|
2478 | break;
|
2479 | }
|
2480 | }else{
|
2481 | cn.disconnect()
|
2482 | }
|
2483 | }
|
2484 | })
|
2485 |
|
2486 | cn.on('super',function(d){
|
2487 | if(!cn.init&&d.f=='init'){
|
2488 | d.ok=s.superAuth({mail:d.mail,pass:d.pass},function(data){
|
2489 | cn.uid=d.mail
|
2490 | cn.join('$');
|
2491 | cn.ip=cn.request.connection.remoteAddress
|
2492 | s.log({ke:'$',mid:'$USER'},{type:lang['Websocket Connected'],msg:{for:lang['Superuser'],id:cn.uid,ip:cn.ip}})
|
2493 | cn.init='super';
|
2494 | cn.mail=d.mail;
|
2495 | s.tx({f:'init_success',mail:d.mail},cn.id);
|
2496 | })
|
2497 | if(d.ok===false){
|
2498 | cn.disconnect();
|
2499 | }
|
2500 | }else{
|
2501 | if(cn.mail&&cn.init=='super'){
|
2502 | switch(d.f){
|
2503 | case'logs':
|
2504 | switch(d.ff){
|
2505 | case'delete':
|
2506 | s.sqlQuery('DELETE FROM Logs WHERE ke=?',[d.ke])
|
2507 | break;
|
2508 | }
|
2509 | break;
|
2510 | case'system':
|
2511 | switch(d.ff){
|
2512 | case'update':
|
2513 | s.ffmpegKill()
|
2514 | s.systemLog('Shinobi ordered to update',{by:cn.mail,ip:cn.ip,distro:d.distro})
|
2515 | exec('chmod +x '+__dirname+'/UPDATE.sh&&'+__dirname+'/./UPDATE.sh '+d.distro,{detached: true})
|
2516 | break;
|
2517 | case'restart':
|
2518 | d.check=function(x){return d.target.indexOf(x)>-1}
|
2519 | if(d.check('system')){
|
2520 | s.systemLog('Shinobi ordered to restart',{by:cn.mail,ip:cn.ip})
|
2521 | s.ffmpegKill()
|
2522 | exec('pm2 restart '+__dirname+'/camera.js')
|
2523 | }
|
2524 | if(d.check('cron')){
|
2525 | s.systemLog('Shinobi CRON ordered to restart',{by:cn.mail,ip:cn.ip})
|
2526 | exec('pm2 restart '+__dirname+'/cron.js')
|
2527 | }
|
2528 | if(d.check('logs')){
|
2529 | s.systemLog('Flush PM2 Logs',{by:cn.mail,ip:cn.ip})
|
2530 | exec('pm2 flush')
|
2531 | }
|
2532 | break;
|
2533 | case'configure':
|
2534 | s.systemLog('conf.json Modified',{by:cn.mail,ip:cn.ip,old:jsonfile.readFileSync(location.config)})
|
2535 | jsonfile.writeFile(location.config,d.data,{spaces: 2},function(){
|
2536 | s.tx({f:'save_configuration'},cn.id)
|
2537 | })
|
2538 | break;
|
2539 | }
|
2540 | break;
|
2541 | case'accounts':
|
2542 | switch(d.ff){
|
2543 | case'register':
|
2544 | if(d.form.mail!==''&&d.form.pass!==''){
|
2545 | if(d.form.pass===d.form.password_again){
|
2546 | s.sqlQuery('SELECT * FROM Users WHERE mail=?',[d.form.mail],function(err,r) {
|
2547 | if(r&&r[0]){
|
2548 | d.msg='Email address is in use.';
|
2549 | s.tx({f:'error',ff:'account_register',msg:d.msg},cn.id)
|
2550 | }else{
|
2551 |
|
2552 | d.form.uid=s.gid();
|
2553 |
|
2554 | if(!d.form.ke||d.form.ke===''){
|
2555 | d.form.ke=s.gid()
|
2556 | }
|
2557 | s.sqlQuery('INSERT INTO Users (ke,uid,mail,pass,details) VALUES (?,?,?,?,?)',[d.form.ke,d.form.uid,d.form.mail,s.md5(d.form.pass),d.form.details])
|
2558 | s.tx({f:'add_account',details:d.form.details,ke:d.form.ke,uid:d.form.uid,mail:d.form.mail},'$');
|
2559 | }
|
2560 | })
|
2561 | }else{
|
2562 | d.msg=lang["Passwords Don't Match"];
|
2563 | }
|
2564 | }else{
|
2565 | d.msg=lang['Fields cannot be empty'];
|
2566 | }
|
2567 | if(d.msg){
|
2568 | s.tx({f:'error',ff:'account_register',msg:d.msg},cn.id)
|
2569 | }
|
2570 | break;
|
2571 | case'edit':
|
2572 | if(d.form.pass&&d.form.pass!==''){
|
2573 | if(d.form.pass===d.form.password_again){
|
2574 | d.form.pass=s.md5(d.form.pass);
|
2575 | }else{
|
2576 | s.tx({f:'error',ff:'account_edit',msg:lang["Passwords Don't Match"]},cn.id)
|
2577 | return
|
2578 | }
|
2579 | }else{
|
2580 | delete(d.form.pass);
|
2581 | }
|
2582 | delete(d.form.password_again);
|
2583 | d.keys=Object.keys(d.form);
|
2584 | d.set=[];
|
2585 | d.values=[];
|
2586 | d.keys.forEach(function(v,n){
|
2587 | if(d.set==='ke'||d.set==='password_again'||!d.form[v]){return}
|
2588 | d.set.push(v+'=?')
|
2589 | d.values.push(d.form[v])
|
2590 | })
|
2591 | d.values.push(d.account.mail)
|
2592 | s.sqlQuery('UPDATE Users SET '+d.set.join(',')+' WHERE mail=?',d.values,function(err,r) {
|
2593 | if(err){
|
2594 | s.tx({f:'error',ff:'account_edit',msg:lang.AccountEditText1},cn.id)
|
2595 | return
|
2596 | }
|
2597 | s.tx({f:'edit_account',form:d.form,ke:d.account.ke,uid:d.account.uid},'$');
|
2598 | delete(s.group[d.account.ke].init);
|
2599 | s.init('apps',d.account)
|
2600 | })
|
2601 | break;
|
2602 | case'delete':
|
2603 | s.sqlQuery('DELETE FROM Users WHERE uid=? AND ke=? AND mail=?',[d.account.uid,d.account.ke,d.account.mail])
|
2604 | s.sqlQuery('DELETE FROM API WHERE uid=? AND ke=?',[d.account.uid,d.account.ke])
|
2605 | s.tx({f:'delete_account',ke:d.account.ke,uid:d.account.uid,mail:d.account.mail},'$');
|
2606 | break;
|
2607 | }
|
2608 | break;
|
2609 | }
|
2610 | }
|
2611 | }
|
2612 | })
|
2613 |
|
2614 | cn.on('a',function(d){
|
2615 | if(!cn.init&&d.f=='init'){
|
2616 | s.sqlQuery('SELECT * FROM Users WHERE auth=? && uid=?',[d.auth,d.uid],function(err,r){
|
2617 | if(r&&r[0]){
|
2618 | r=r[0];
|
2619 | if(!s.group[d.ke]){s.group[d.ke]={users:{}}}
|
2620 | if(!s.group[d.ke].users[d.auth]){s.group[d.ke].users[d.auth]={cnid:cn.id}}
|
2621 | try{s.group[d.ke].users[d.auth].details=JSON.parse(r.details)}catch(er){}
|
2622 | cn.join('ADM_'+d.ke);
|
2623 | cn.ke=d.ke;
|
2624 | cn.uid=d.uid;
|
2625 | cn.auth=d.auth;
|
2626 | cn.init='admin';
|
2627 | }else{
|
2628 | cn.disconnect();
|
2629 | }
|
2630 | })
|
2631 | }else{
|
2632 | s.auth({auth:d.auth,ke:d.ke,id:d.id,ip:cn.request.connection.remoteAddress},function(user){
|
2633 | if(!user.details.sub){
|
2634 | switch(d.f){
|
2635 | case'accounts':
|
2636 | switch(d.ff){
|
2637 | case'edit':
|
2638 | d.keys=Object.keys(d.form);
|
2639 | d.condition=[];
|
2640 | d.value=[];
|
2641 | d.keys.forEach(function(v){
|
2642 | d.condition.push(v+'=?')
|
2643 | d.value.push(d.form[v])
|
2644 | })
|
2645 | d.value=d.value.concat([cn.ke,d.$uid])
|
2646 | s.sqlQuery("UPDATE Users SET "+d.condition.join(',')+" WHERE ke=? AND uid=?",d.value)
|
2647 | s.tx({f:'edit_sub_account',ke:cn.ke,uid:d.$uid,mail:d.mail,form:d.form},'ADM_'+d.ke);
|
2648 | break;
|
2649 | case'delete':
|
2650 | s.sqlQuery('DELETE FROM Users WHERE uid=? AND ke=? AND mail=?',[d.$uid,cn.ke,d.mail])
|
2651 | s.sqlQuery('DELETE FROM API WHERE uid=? AND ke=?',[d.$uid,cn.ke])
|
2652 | s.tx({f:'delete_sub_account',ke:cn.ke,uid:d.$uid,mail:d.mail},'ADM_'+d.ke);
|
2653 | break;
|
2654 | }
|
2655 | break;
|
2656 | }
|
2657 | }
|
2658 | })
|
2659 | }
|
2660 | })
|
2661 |
|
2662 | cn.on('r',function(d){
|
2663 | if(!cn.ke&&d.f==='init'){
|
2664 | s.sqlQuery('SELECT ke,uid,auth,mail,details FROM Users WHERE ke=? AND auth=? AND uid=?',[d.ke,d.auth,d.uid],function(err,r) {
|
2665 | if(r&&r[0]){
|
2666 | r=r[0]
|
2667 | cn.ke=d.ke,cn.uid=d.uid,cn.auth=d.auth;
|
2668 | if(!s.group[d.ke])s.group[d.ke]={};
|
2669 | if(!s.group[d.ke].users)s.group[d.ke].users={};
|
2670 | s.group[d.ke].users[d.auth]={cnid:cn.id,uid:r.uid,mail:r.mail,details:JSON.parse(r.details),logged_in_at:moment(new Date).format(),login_type:'Streamer'}
|
2671 | }
|
2672 | })
|
2673 | }else{
|
2674 | switch(d.f){
|
2675 | case'monitor_chunk':
|
2676 | if(!s.group[d.ke]||!s.group[d.ke].mon[d.mid]){return}
|
2677 | if(s.group[d.ke].mon[d.mid].started!==1){s.tx({error:'Not Started'},cn.id);return false};
|
2678 | s.group[d.ke].mon[d.mid].spawn.stdin.write(new Buffer(d.chunk, "binary"));
|
2679 | break;
|
2680 | case'monitor_frame':
|
2681 | if(!s.group[d.ke]||!s.group[d.ke].mon[d.mid]){return}
|
2682 | if(s.group[d.ke].mon[d.mid].started!==1){s.tx({error:'Not Started'},cn.id);return false};
|
2683 | s.group[d.ke].mon[d.mid].spawn.stdin.write(d.frame);
|
2684 | break;
|
2685 | }
|
2686 | }
|
2687 | })
|
2688 |
|
2689 | cn.on('c',function(d){
|
2690 |
|
2691 | if(!cn.shinobi_child&&d.f=='init'){
|
2692 | cn.ip=cn.request.connection.remoteAddress;
|
2693 | cn.name=d.u.name;
|
2694 | cn.shinobi_child=1;
|
2695 | tx=function(z){cn.emit('c',z);}
|
2696 | if(!s.child_nodes[cn.ip]){s.child_nodes[cn.ip]=d.u;};
|
2697 | s.child_nodes[cn.ip].cnid=cn.id;
|
2698 | s.child_nodes[cn.ip].cpu=0;
|
2699 | tx({f:'init_success',child_nodes:s.child_nodes});
|
2700 | }else{
|
2701 | if(d.f!=='s.tx'){s.systemLog('CRON',d)};
|
2702 | switch(d.f){
|
2703 | case'cpu':
|
2704 | s.child_nodes[cn.ip].cpu=d.cpu;
|
2705 | break;
|
2706 | case'sql':
|
2707 | s.sqlQuery(d.query,d.values);
|
2708 | break;
|
2709 | case'camera':
|
2710 | s.camera(d.mode,d.data)
|
2711 | break;
|
2712 | case's.tx':
|
2713 | s.tx(d.data,d.to)
|
2714 | break;
|
2715 | case's.log':
|
2716 | s.log(d.data,d.to)
|
2717 | break;
|
2718 | case'created_file':
|
2719 | if(d.details&&d.details.dir&&d.details.dir!==''){
|
2720 | d.dir=s.checkCorrectPathEnding(d.details.dir)+d.ke+'/'+d.id+'/'
|
2721 | }else{
|
2722 | d.dir=s.dir.videos+d.ke+'/'+d.id+'/';
|
2723 | }
|
2724 | fs.writeFile(d.dir+d.filename,d.created_file,'binary',function (err,data) {
|
2725 | if (err) {
|
2726 | return console.error('created_file'+d.d.mid,err);
|
2727 | }
|
2728 | tx({f:'delete_file',file:d.filename,ke:d.d.ke,mid:d.d.mid}); s.tx({f:'video_build_success',filename:s.group[d.d.ke].mon[d.d.mid].open+'.'+s.group[d.d.ke].mon[d.d.mid].open_ext,mid:d.d.mid,ke:d.d.ke,time:s.nameToTime(s.group[d.d.ke].mon[d.d.mid].open),end:s.moment(new Date,'YYYY-MM-DD HH:mm:ss')},'GRP_'+d.d.ke);
|
2729 | });
|
2730 | break;
|
2731 | }
|
2732 | }
|
2733 |
|
2734 | })
|
2735 |
|
2736 | cn.on('e', function (d) {
|
2737 | tx=function(z){if(!z.ke){z.ke=cn.ke;};cn.emit('f',z);}
|
2738 | switch(d.f){
|
2739 | case'init':
|
2740 | if(!s.group[d.ke]||!s.group[d.ke].mon[d.id]||s.group[d.ke].mon[d.id].started===0){return false}
|
2741 | s.auth({auth:d.auth,ke:d.ke,id:d.id,ip:cn.request.connection.remoteAddress},function(user){
|
2742 | cn.embedded=1;
|
2743 | cn.ke=d.ke;
|
2744 | if(!cn.mid){cn.mid={}}
|
2745 | cn.mid[d.id]={};
|
2746 |
|
2747 |
|
2748 |
|
2749 |
|
2750 | s.camera('watch_on',d,cn,tx)
|
2751 | cn.join('MON_'+d.id);
|
2752 | cn.join('MON_STREAM_'+d.id);
|
2753 | cn.join('STR_'+d.ke);
|
2754 | if(s.group[d.ke]&&s.group[d.ke].mon[d.id]&&s.group[d.ke].mon[d.id].watch){
|
2755 |
|
2756 | tx({f:'monitor_watch_on',id:d.id,ke:d.ke},'MON_'+d.id)
|
2757 | s.tx({viewers:Object.keys(s.group[d.ke].mon[d.id].watch).length,ke:d.ke,id:d.id},'MON_'+d.id)
|
2758 | }
|
2759 | });
|
2760 | break;
|
2761 | }
|
2762 | })
|
2763 | cn.on('disconnect', function () {
|
2764 | if(cn.ke){
|
2765 | if(cn.monitor_watching){
|
2766 | cn.monitor_count=Object.keys(cn.monitor_watching)
|
2767 | if(cn.monitor_count.length>0){
|
2768 | cn.monitor_count.forEach(function(v){
|
2769 | s.camera('watch_off',{id:v,ke:cn.monitor_watching[v].ke},s.cn(cn))
|
2770 | })
|
2771 | }
|
2772 | }
|
2773 | if(!cn.embedded){
|
2774 | if(s.group[cn.ke].users[cn.auth].login_type==='Dashboard'){
|
2775 | s.tx({f:'user_status_change',ke:cn.ke,uid:cn.uid,status:0})
|
2776 | }
|
2777 | s.log({ke:cn.ke,mid:'$USER'},{type:lang['Websocket Disconnected'],msg:{mail:s.group[cn.ke].users[cn.auth].mail,id:cn.uid,ip:cn.ip}})
|
2778 | delete(s.group[cn.ke].users[cn.auth]);
|
2779 | }
|
2780 | }
|
2781 | if(cn.ocv){
|
2782 | s.tx({f:'detector_unplugged',plug:s.ocv.plug},'CPU')
|
2783 | delete(s.ocv);
|
2784 | delete(s.api[cn.id])
|
2785 | }
|
2786 | if(cn.cron){
|
2787 | delete(s.cron);
|
2788 | }
|
2789 | if(cn.shinobi_child){
|
2790 | delete(s.child_nodes[cn.ip]);
|
2791 | }
|
2792 | })
|
2793 | });
|
2794 |
|
2795 | s.api={};
|
2796 |
|
2797 |
|
2798 |
|
2799 |
|
2800 |
|
2801 | s.auth=function(params,cb,res,req){
|
2802 | if(req){
|
2803 |
|
2804 | params.ip=req.headers['cf-connecting-ip'] || req.headers['x-forwarded-for'] || req.connection.remoteAddress;
|
2805 | var failed=function(){
|
2806 | if(!req.ret){req.ret={ok:false}}
|
2807 | req.ret.msg=lang['Not Authorized'];
|
2808 | res.end(s.s(req.ret, null, 3));
|
2809 | }
|
2810 | }else{
|
2811 |
|
2812 | var failed=function(){
|
2813 |
|
2814 | }
|
2815 | }
|
2816 | if(!params.auth||params.auth===''||params.auth===null||params.auth===undefined){
|
2817 | return failed()
|
2818 | }
|
2819 | var clearAfterTime=function(){
|
2820 |
|
2821 | clearTimeout(s.api[params.auth].timeout)
|
2822 | s.api[params.auth].timeout=setTimeout(function(){
|
2823 | delete(s.api[params.auth])
|
2824 | },1000*60*5)
|
2825 | }
|
2826 |
|
2827 | var finish=function(user){
|
2828 | if(s.api[params.auth].ip.indexOf('0.0.0.0')>-1||s.api[params.auth].ip.indexOf(params.ip)>-1){
|
2829 | cb(user);
|
2830 | }else{
|
2831 | failed();
|
2832 | }
|
2833 | }
|
2834 |
|
2835 | if(s.group[params.ke]&&s.group[params.ke].users&&s.group[params.ke].users[params.auth]){
|
2836 | s.group[params.ke].users[params.auth].permissions={};
|
2837 | cb(s.group[params.ke].users[params.auth]);
|
2838 | }else{
|
2839 |
|
2840 | if(s.api[params.auth]&&s.api[params.auth].details){
|
2841 | finish(s.api[params.auth]);
|
2842 | if(s.api[params.auth].timeout){
|
2843 | clearAfterTime()
|
2844 | }
|
2845 | }else{
|
2846 |
|
2847 | s.sqlQuery('SELECT * FROM API WHERE code=? AND ke=?',[params.auth,params.ke],function(err,r){
|
2848 | if(r&&r[0]){
|
2849 | r=r[0];
|
2850 | s.api[params.auth]={ip:r.ip,uid:r.uid,ke:r.ke,permissions:JSON.parse(r.details),details:{}};
|
2851 | s.sqlQuery('SELECT details FROM Users WHERE uid=? AND ke=?',[r.uid,r.ke],function(err,rr){
|
2852 | if(rr&&rr[0]){
|
2853 | rr=rr[0];
|
2854 | try{
|
2855 | s.api[params.auth].mail=rr.mail
|
2856 | s.api[params.auth].details=JSON.parse(rr.details)
|
2857 | s.api[params.auth].lang=s.getLanguageFile(s.api[params.auth].details.lang)
|
2858 | }catch(er){}
|
2859 | }
|
2860 | finish(s.api[params.auth]);
|
2861 | })
|
2862 | }else{
|
2863 | s.sqlQuery('SELECT * FROM Users WHERE auth=? AND ke=?',[params.auth,params.ke],function(err,r){
|
2864 | if(r&&r[0]){
|
2865 | r=r[0];
|
2866 | r.ip='0.0.0.0'
|
2867 | s.api[params.auth]=r
|
2868 | clearAfterTime()
|
2869 | finish(r)
|
2870 | }else{
|
2871 | failed();
|
2872 | }
|
2873 | })
|
2874 | }
|
2875 | })
|
2876 | }
|
2877 | }
|
2878 | }
|
2879 |
|
2880 | s.superAuth=function(x,callback){
|
2881 | req={};
|
2882 | req.super=require(location.super);
|
2883 | req.super.forEach(function(v,n){
|
2884 | if(x.md5===true){
|
2885 | x.pass=s.md5(x.pass);
|
2886 | }
|
2887 | if(x.mail.toLowerCase()===v.mail.toLowerCase()&&x.pass===v.pass){
|
2888 | req.found=1;
|
2889 | if(x.users===true){
|
2890 | s.sqlQuery('SELECT * FROM Users WHERE details NOT LIKE ?',['%"sub"%'],function(err,r) {
|
2891 | callback({$user:v,users:r,config:config,lang:lang})
|
2892 | })
|
2893 | }else{
|
2894 | callback({$user:v,config:config,lang:lang})
|
2895 | }
|
2896 | }
|
2897 | })
|
2898 | if(req.found!==1){
|
2899 | return false;
|
2900 | }else{
|
2901 | return true;
|
2902 | }
|
2903 | }
|
2904 |
|
2905 | app.enable('trust proxy');
|
2906 | app.use('/libs',express.static(__dirname + '/web/libs'));
|
2907 | app.use(bodyParser.json());
|
2908 | app.use(bodyParser.urlencoded({extended: true}));
|
2909 | app.set('views', __dirname + '/web/pages');
|
2910 | app.set('view engine','ejs');
|
2911 |
|
2912 | app.get('/:auth/logout/:ke/:id', function (req,res){
|
2913 | if(s.group[req.params.ke]&&s.group[req.params.ke].users[req.params.auth]){
|
2914 | delete(s.api[req.params.auth]);
|
2915 | delete(s.group[req.params.ke].users[req.params.auth]);
|
2916 | s.sqlQuery("UPDATE Users SET auth=? WHERE auth=? AND ke=? AND uid=?",['',req.params.auth,req.params.ke,req.params.id])
|
2917 | res.end(s.s({ok:true,msg:'You have been logged out, session key is now inactive.'}, null, 3))
|
2918 | }else{
|
2919 | res.end(s.s({ok:false,msg:'This group key does not exist or this user is not logged in.'}, null, 3))
|
2920 | }
|
2921 | });
|
2922 |
|
2923 | app.get('/info', function (req,res){
|
2924 | res.sendFile(__dirname+'/index.html');
|
2925 | });
|
2926 |
|
2927 | app.get(['/','/:screen'], function (req,res){
|
2928 | res.render('index',{lang:lang,config:config,screen:req.params.screen},function(err,html){
|
2929 | if(err){
|
2930 | s.systemLog(err)
|
2931 | }
|
2932 | res.end(html)
|
2933 | })
|
2934 | });
|
2935 |
|
2936 | app.get('/:auth/update/:key', function (req,res){
|
2937 | req.ret={ok:false};
|
2938 | res.setHeader('Content-Type', 'application/json');
|
2939 | req.fn=function(user){
|
2940 | if(!config.updateKey){
|
2941 | req.ret.msg=user.lang.updateKeyText1;
|
2942 | return;
|
2943 | }
|
2944 | if(req.params.key===config.updateKey){
|
2945 | req.ret.ok=true;
|
2946 | exec('chmod +x '+__dirname+'/UPDATE.sh&&'+__dirname+'/./UPDATE.sh',{detached: true})
|
2947 | }else{
|
2948 | req.ret.msg=user.lang.updateKeyText2;
|
2949 | }
|
2950 | res.end(s.s(req.ret, null, 3));
|
2951 | }
|
2952 | s.auth(req.params,req.fn,res,req);
|
2953 | });
|
2954 |
|
2955 | app.get('/:auth/userInfo/:ke',function (req,res){
|
2956 | req.ret={ok:false};
|
2957 | res.setHeader('Content-Type', 'application/json');
|
2958 | res.header("Access-Control-Allow-Origin",req.headers.origin);
|
2959 | s.auth(req.params,function(user){
|
2960 | req.ret.ok=true
|
2961 | req.ret.user=user
|
2962 | res.end(s.s(req.ret, null, 3));
|
2963 | },res,req);
|
2964 | })
|
2965 |
|
2966 | app.post('/:auth/register/:ke/:uid',function (req,res){
|
2967 | req.resp={ok:false};
|
2968 | res.setHeader('Content-Type', 'application/json');
|
2969 | s.auth(req.params,function(user){
|
2970 | s.sqlQuery('SELECT * FROM Users WHERE uid=? AND ke=? AND details NOT LIKE ? LIMIT 1',[req.params.uid,req.params.ke,'%"sub"%'],function(err,u) {
|
2971 | if(u&&u[0]){
|
2972 | if(req.body.mail!==''&&req.body.pass!==''){
|
2973 | if(req.body.pass===req.body.password_again){
|
2974 | s.sqlQuery('SELECT * FROM Users WHERE mail=?',[req.body.mail],function(err,r) {
|
2975 | if(r&&r[0]){
|
2976 | req.resp.msg='Email address is in use.';
|
2977 | }else{
|
2978 | req.resp.msg='New Account Created';req.resp.ok=true;
|
2979 | req.gid=s.gid();
|
2980 | req.body.details='{"sub":"1","allmonitors":"1"}';
|
2981 | s.sqlQuery('INSERT INTO Users (ke,uid,mail,pass,details) VALUES (?,?,?,?,?)',[req.params.ke,req.gid,req.body.mail,s.md5(req.body.pass),req.body.details])
|
2982 | s.tx({f:'add_sub_account',details:req.body.details,ke:req.params.ke,uid:req.gid,mail:req.body.mail},'ADM_'+req.params.ke);
|
2983 | }
|
2984 | res.end(s.s(req.resp,null,3));
|
2985 | })
|
2986 | }else{
|
2987 | req.resp.msg=user.lang['Passwords Don\'t Match'];
|
2988 | }
|
2989 | }else{
|
2990 | req.resp.msg=user.lang['Fields cannot be empty'];
|
2991 | }
|
2992 | }else{
|
2993 | req.resp.msg=user.lang['Not an Administrator Account'];
|
2994 | }
|
2995 | if(req.resp.msg){
|
2996 | res.end(s.s(req.resp,null,3));
|
2997 | }
|
2998 | })
|
2999 | },res,req);
|
3000 | })
|
3001 |
|
3002 | s.deleteFactorAuth=function(r){
|
3003 | delete(s.factorAuth[r.ke][r.uid])
|
3004 | if(Object.keys(s.factorAuth[r.ke]).length===0){
|
3005 | delete(s.factorAuth[r.ke])
|
3006 | }
|
3007 | }
|
3008 | app.post(['/','/:screen'],function (req,res){
|
3009 | req.ip=req.headers['cf-connecting-ip']||req.headers["CF-Connecting-IP"]||req.headers["'x-forwarded-for"]||req.connection.remoteAddress;
|
3010 | if(req.query.json=='true'){
|
3011 | res.header("Access-Control-Allow-Origin",req.headers.origin);
|
3012 | }
|
3013 | req.renderFunction=function(focus,data){
|
3014 | if(req.query.json=='true'){
|
3015 | delete(data.config)
|
3016 | data.ok=true;
|
3017 | res.setHeader('Content-Type', 'application/json');
|
3018 | res.end(s.s(data, null, 3))
|
3019 | }else{
|
3020 | data.screen=req.params.screen
|
3021 | res.render(focus,data,function(err,html){
|
3022 | if(err){
|
3023 | s.systemLog(err)
|
3024 | }
|
3025 | res.end(html)
|
3026 | });
|
3027 | }
|
3028 | }
|
3029 | req.failed=function(board){
|
3030 | if(req.query.json=='true'){
|
3031 | res.setHeader('Content-Type', 'application/json');
|
3032 | res.end(s.s({ok:false}, null, 3))
|
3033 | }else{
|
3034 | res.render('index',{failedLogin:true,lang:lang,config:config,screen:req.params.screen},function(err,html){
|
3035 | if(err){
|
3036 | s.systemLog(err)
|
3037 | }
|
3038 | res.end(html);
|
3039 | });
|
3040 | }
|
3041 | req.logTo={ke:'$',mid:'$USER'}
|
3042 | req.logData={type:lang['Authentication Failed'],msg:{for:board,mail:req.body.mail,ip:req.ip}}
|
3043 | if(board==='super'){
|
3044 | s.log(req.logTo,req.logData)
|
3045 | }else{
|
3046 | s.sqlQuery('SELECT ke,uid,details FROM Users WHERE mail=?',[req.body.mail],function(err,r) {
|
3047 | if(r&&r[0]){
|
3048 | r=r[0]
|
3049 | r.details=JSON.parse(r.details);
|
3050 | r.lang=s.getLanguageFile(r.details.lang)
|
3051 | req.logData.id=r.uid
|
3052 | req.logData.type=r.lang['Authentication Failed']
|
3053 | req.logTo.ke=r.ke
|
3054 | }
|
3055 | s.log(req.logTo,req.logData)
|
3056 | })
|
3057 | }
|
3058 | }
|
3059 | req.fn=function(r){
|
3060 | switch(req.body.function){
|
3061 | case'cam':
|
3062 | s.sqlQuery('SELECT * FROM Monitors WHERE ke=? AND type=?',[r.ke,"dashcam"],function(err,rr){
|
3063 | req.resp.mons=rr;
|
3064 | req.renderFunction("dashcam",{$user:req.resp,lang:r.lang,define:s.getDefinitonFile(r.details.lang)});
|
3065 | })
|
3066 | break;
|
3067 | case'streamer':
|
3068 | s.sqlQuery('SELECT * FROM Monitors WHERE ke=? AND type=?',[r.ke,"socket"],function(err,rr){
|
3069 | req.resp.mons=rr;
|
3070 | req.renderFunction("streamer",{$user:req.resp,lang:r.lang,define:s.getDefinitonFile(r.details.lang)});
|
3071 | })
|
3072 | break;
|
3073 | case'admin':
|
3074 | if(!r.details.sub){
|
3075 | s.sqlQuery('SELECT uid,mail,details FROM Users WHERE ke=? AND details LIKE \'%"sub"%\'',[r.ke],function(err,rr) {
|
3076 | s.sqlQuery('SELECT * FROM Monitors WHERE ke=?',[r.ke],function(err,rrr) {
|
3077 | req.renderFunction("admin",{$user:req.resp,$subs:rr,$mons:rrr,lang:r.lang,define:s.getDefinitonFile(r.details.lang)});
|
3078 | })
|
3079 | })
|
3080 | }else{
|
3081 |
|
3082 | req.renderFunction("home",{$user:req.resp,config:config,lang:r.lang,define:s.getDefinitonFile(r.details.lang),addStorage:s.dir.addStorage,fs:fs});
|
3083 | }
|
3084 | break;
|
3085 | default:
|
3086 | req.renderFunction("home",{$user:req.resp,config:config,lang:r.lang,define:s.getDefinitonFile(r.details.lang),addStorage:s.dir.addStorage,fs:fs});
|
3087 | break;
|
3088 | }
|
3089 | s.log({ke:r.ke,mid:'$USER'},{type:r.lang['New Authentication Token'],msg:{for:req.body.function,mail:r.mail,id:r.uid,ip:req.ip}})
|
3090 |
|
3091 | }
|
3092 | if(req.body.mail&&req.body.pass){
|
3093 | req.default=function(){
|
3094 | s.sqlQuery('SELECT * FROM Users WHERE mail=? AND pass=?',[req.body.mail,s.md5(req.body.pass)],function(err,r) {
|
3095 | req.resp={ok:false};
|
3096 | if(!err&&r&&r[0]){
|
3097 | r=r[0];r.auth=s.md5(s.gid());
|
3098 | s.sqlQuery("UPDATE Users SET auth=? WHERE ke=? AND uid=?",[r.auth,r.ke,r.uid])
|
3099 | req.resp={ok:true,auth_token:r.auth,ke:r.ke,uid:r.uid,mail:r.mail,details:r.details};
|
3100 | r.details=JSON.parse(r.details);
|
3101 | r.lang=s.getLanguageFile(r.details.lang)
|
3102 | req.factorAuth=function(cb){
|
3103 | if(r.details.factorAuth==="1"){
|
3104 | if(!r.details.acceptedMachines||!(r.details.acceptedMachines instanceof Object)){
|
3105 | r.details.acceptedMachines={}
|
3106 | }
|
3107 | if(!r.details.acceptedMachines[req.body.machineID]){
|
3108 | req.complete=function(){
|
3109 | s.factorAuth[r.ke][r.uid].info=req.resp;
|
3110 | clearTimeout(s.factorAuth[r.ke][r.uid].expireAuth)
|
3111 | s.factorAuth[r.ke][r.uid].expireAuth=setTimeout(function(){
|
3112 | s.deleteFactorAuth(r)
|
3113 | },1000*60*15)
|
3114 | req.renderFunction("factor",{$user:req.resp,lang:r.lang})
|
3115 | }
|
3116 | if(!s.factorAuth[r.ke]){s.factorAuth[r.ke]={}}
|
3117 | if(!s.factorAuth[r.ke][r.uid]){
|
3118 | s.factorAuth[r.ke][r.uid]={key:s.nid(),user:r}
|
3119 | r.mailOptions = {
|
3120 | from: '"ShinobiCCTV" <no-reply@shinobi.video>',
|
3121 | to: r.mail,
|
3122 | subject: r.lang['2-Factor Authentication'],
|
3123 | html: r.lang['Enter this code to proceed']+' <b>'+s.factorAuth[r.ke][r.uid].key+'</b>. '+r.lang.FactorAuthText1,
|
3124 | };
|
3125 | nodemailer.sendMail(r.mailOptions, (error, info) => {
|
3126 | if (error) {
|
3127 | s.systemLog(r.lang.MailError,error)
|
3128 | req.fn(r)
|
3129 | return
|
3130 | }
|
3131 | req.complete()
|
3132 | });
|
3133 | }else{
|
3134 | req.complete()
|
3135 | }
|
3136 | }else{
|
3137 | req.fn(r)
|
3138 | }
|
3139 | }else{
|
3140 | req.fn(r)
|
3141 | }
|
3142 | }
|
3143 | if(r.details.sub){
|
3144 | s.sqlQuery('SELECT details FROM Users WHERE ke=? AND details NOT LIKE ?',[r.ke,'%"sub"%'],function(err,rr) {
|
3145 | rr=rr[0];
|
3146 | rr.details=JSON.parse(rr.details);
|
3147 | r.details.mon_groups=rr.details.mon_groups;
|
3148 | req.resp.details=JSON.stringify(r.details);
|
3149 | req.factorAuth()
|
3150 | })
|
3151 | }else{
|
3152 | req.factorAuth()
|
3153 | }
|
3154 | }else{
|
3155 | req.failed(req.body.function)
|
3156 | }
|
3157 | })
|
3158 | }
|
3159 | if(LdapAuth&&req.body.function==='ldap'&&req.body.key!==''){
|
3160 | s.sqlQuery('SELECT * FROM Users WHERE ke=? AND details NOT LIKE ?',[req.body.key,'%"sub"%'],function(err,r) {
|
3161 | if(r&&r[0]){
|
3162 | r=r[0]
|
3163 | r.details=JSON.parse(r.details)
|
3164 | r.lang=s.getLanguageFile(r.details.lang)
|
3165 | if(r.details.use_ldap!=='0'&&r.details.ldap_enable==='1'&&r.details.ldap_url&&r.details.ldap_url!==''){
|
3166 | req.mailArray={}
|
3167 | req.body.mail.split(',').forEach(function(v){
|
3168 | v=v.split('=')
|
3169 | req.mailArray[v[0]]=v[1]
|
3170 | })
|
3171 | if(!r.details.ldap_bindDN||r.details.ldap_bindDN===''){
|
3172 | r.details.ldap_bindDN=req.body.mail
|
3173 | }
|
3174 | if(!r.details.ldap_bindCredentials||r.details.ldap_bindCredentials===''){
|
3175 | r.details.ldap_bindCredentials=req.body.pass
|
3176 | }
|
3177 | if(!r.details.ldap_searchFilter||r.details.ldap_searchFilter===''){
|
3178 | r.details.ldap_searchFilter=req.body.mail
|
3179 | if(req.mailArray.cn){
|
3180 | r.details.ldap_searchFilter='cn='+req.mailArray.cn
|
3181 | }
|
3182 | if(req.mailArray.uid){
|
3183 | r.details.ldap_searchFilter='uid='+req.mailArray.uid
|
3184 | }
|
3185 | }else{
|
3186 | r.details.ldap_searchFilter=r.details.ldap_searchFilter.replace('{{username}}',req.body.mail)
|
3187 | }
|
3188 | if(!r.details.ldap_searchBase||r.details.ldap_searchBase===''){
|
3189 | r.details.ldap_searchBase='dc=test,dc=com'
|
3190 | }
|
3191 | req.auth = new LdapAuth({
|
3192 | url:r.details.ldap_url,
|
3193 | bindDN:r.details.ldap_bindDN,
|
3194 | bindCredentials:r.details.ldap_bindCredentials,
|
3195 | searchBase:r.details.ldap_searchBase,
|
3196 | searchFilter:'('+r.details.ldap_searchFilter+')',
|
3197 | reconnect:true
|
3198 | });
|
3199 | req.auth.on('error', function (err) {
|
3200 | console.error('LdapAuth: ', err);
|
3201 | });
|
3202 |
|
3203 | req.auth.authenticate(req.body.mail, req.body.pass, function(err, user) {
|
3204 | if(user){
|
3205 |
|
3206 | if(!user.uid){
|
3207 | user.uid=s.gid()
|
3208 | }
|
3209 | req.resp={
|
3210 | ke:req.body.key,
|
3211 | uid:user.uid,
|
3212 | auth:s.md5(s.gid()),
|
3213 | mail:user.mail,
|
3214 | pass:s.md5(req.body.pass),
|
3215 | details:JSON.stringify({
|
3216 | sub:'1',
|
3217 | ldap:'1',
|
3218 | allmonitors:'1',
|
3219 | filter: {}
|
3220 | })
|
3221 | }
|
3222 | user.post=[]
|
3223 | Object.keys(req.resp).forEach(function(v){
|
3224 | user.post.push(req.resp[v])
|
3225 | })
|
3226 | s.log({ke:req.body.key,mid:'$USER'},{type:r.lang['LDAP Success'],msg:{user:user}})
|
3227 | s.sqlQuery('SELECT * FROM Users WHERE ke=? AND mail=?',[req.body.key,user.cn],function(err,rr){
|
3228 | if(rr&&rr[0]){
|
3229 |
|
3230 | rr=rr[0]
|
3231 | req.resp=rr;
|
3232 | rr.details=JSON.parse(rr.details)
|
3233 | req.resp.lang=s.getLanguageFile(rr.details.lang)
|
3234 | s.log({ke:req.body.key,mid:'$USER'},{type:r.lang['LDAP User Authenticated'],msg:{user:user,shinobiUID:rr.uid}})
|
3235 | s.sqlQuery("UPDATE Users SET auth=? WHERE ke=? AND uid=?",[req.resp.auth,req.resp.ke,rr.uid])
|
3236 | }else{
|
3237 |
|
3238 | s.log({ke:req.body.key,mid:'$USER'},{type:r.lang['LDAP User is New'],msg:{info:r.lang['Creating New Account'],user:user}})
|
3239 | req.resp.lang=r.lang
|
3240 | s.sqlQuery('INSERT INTO Users (ke,uid,auth,mail,pass,details) VALUES (?,?,?,?,?,?)',user.post)
|
3241 | }
|
3242 | req.resp.details=JSON.stringify(req.resp.details)
|
3243 | req.resp.auth_token=req.resp.auth
|
3244 | req.resp.ok=true
|
3245 | req.fn(req.resp)
|
3246 | })
|
3247 | return
|
3248 | }
|
3249 | s.log({ke:req.body.key,mid:'$USER'},{type:r.lang['LDAP Failed'],msg:{err:err}})
|
3250 |
|
3251 | req.default()
|
3252 | });
|
3253 |
|
3254 | req.auth.close(function(err) {
|
3255 |
|
3256 | })
|
3257 | }else{
|
3258 | req.default()
|
3259 | }
|
3260 | }else{
|
3261 | req.default()
|
3262 | }
|
3263 | })
|
3264 | }else{
|
3265 | if(req.body.function==='super'){
|
3266 | if(!fs.existsSync(location.super)){
|
3267 | res.end(lang.superAdminText)
|
3268 | return
|
3269 | }
|
3270 | req.ok=s.superAuth({mail:req.body.mail,pass:req.body.pass,users:true,md5:true},function(data){
|
3271 | s.sqlQuery('SELECT * FROM Logs WHERE ke=? ORDER BY `time` DESC LIMIT 30',['$'],function(err,r) {
|
3272 | if(!r){
|
3273 | r=[]
|
3274 | }
|
3275 | data.Logs=r;
|
3276 | fs.readFile(location.config,'utf8',function(err,file){
|
3277 | data.plainConfig=JSON.parse(file)
|
3278 | req.renderFunction("super",data);
|
3279 | })
|
3280 | })
|
3281 | })
|
3282 | if(req.ok===false){
|
3283 | req.failed(req.body.function)
|
3284 | }
|
3285 | }else{
|
3286 | req.default()
|
3287 | }
|
3288 | }
|
3289 | }else{
|
3290 | if(req.body.machineID&&req.body.factorAuthKey){
|
3291 | if(s.factorAuth[req.body.ke]&&s.factorAuth[req.body.ke][req.body.id]&&s.factorAuth[req.body.ke][req.body.id].key===req.body.factorAuthKey){
|
3292 | if(s.factorAuth[req.body.ke][req.body.id].key===req.body.factorAuthKey){
|
3293 | if(req.body.remember==="1"){
|
3294 | req.details=JSON.parse(s.factorAuth[req.body.ke][req.body.id].info.details)
|
3295 | req.lang=s.getLanguageFile(req.details.lang)
|
3296 | if(!req.details.acceptedMachines||!(req.details.acceptedMachines instanceof Object)){
|
3297 | req.details.acceptedMachines={}
|
3298 | }
|
3299 | if(!req.details.acceptedMachines[req.body.machineID]){
|
3300 | req.details.acceptedMachines[req.body.machineID]={}
|
3301 | s.sqlQuery("UPDATE Users SET details=? WHERE ke=? AND uid=?",[s.s(req.details),req.body.ke,req.body.id])
|
3302 | }
|
3303 | }
|
3304 | req.resp=s.factorAuth[req.body.ke][req.body.id].info
|
3305 | req.fn(s.factorAuth[req.body.ke][req.body.id].user)
|
3306 | }else{
|
3307 | req.renderFunction("factor",{$user:s.factorAuth[req.body.ke][req.body.id].info,lang:req.lang});
|
3308 | res.end();
|
3309 | }
|
3310 | }else{
|
3311 | req.failed(lang['2-Factor Authentication'])
|
3312 | }
|
3313 | }else{
|
3314 | req.failed(lang['2-Factor Authentication'])
|
3315 | }
|
3316 | }
|
3317 | });
|
3318 |
|
3319 | app.get('/:auth/mpd/:ke/:id/:file', function (req,res){
|
3320 | res.header("Access-Control-Allow-Origin",req.headers.origin);
|
3321 | req.fn=function(user){
|
3322 | req.extension=req.params.file.split('.')
|
3323 | req.extension=req.extension[req.extension.length-1]
|
3324 | switch(req.extension){
|
3325 | case'mpd':
|
3326 | res.header("Content-Type","application/dash+xml");
|
3327 | break;
|
3328 | }
|
3329 | req.dir=s.dir.streams+req.params.ke+'/'+req.params.id+'/'+req.params.file;
|
3330 | res.on('finish',function(){res.end();});
|
3331 | if (fs.existsSync(req.dir)){
|
3332 | fs.createReadStream(req.dir).pipe(res);
|
3333 | }else{
|
3334 | res.end(user.lang['File Not Found'])
|
3335 | }
|
3336 | }
|
3337 | s.auth(req.params,req.fn,res,req);
|
3338 | });
|
3339 |
|
3340 | app.get('/:auth/hls/:ke/:id/:file', function (req,res){
|
3341 | res.header("Access-Control-Allow-Origin",req.headers.origin);
|
3342 | req.fn=function(user){
|
3343 | req.dir=s.dir.streams+req.params.ke+'/'+req.params.id+'/'+req.params.file;
|
3344 | res.on('finish',function(){res.end();});
|
3345 | if (fs.existsSync(req.dir)){
|
3346 | fs.createReadStream(req.dir).pipe(res);
|
3347 | }else{
|
3348 | res.end(user.lang['File Not Found'])
|
3349 | }
|
3350 | }
|
3351 | s.auth(req.params,req.fn,res,req);
|
3352 | });
|
3353 |
|
3354 | app.get('/:auth/jpeg/:ke/:id/s.jpg', function(req,res){
|
3355 | res.header("Access-Control-Allow-Origin",req.headers.origin);
|
3356 | s.auth(req.params,function(user){
|
3357 | if(user.details.sub&&user.details.allmonitors!=='1'&&user.details.monitors.indexOf(req.params.id)===-1){
|
3358 | res.end(user.lang['Not Permitted'])
|
3359 | return
|
3360 | }
|
3361 | req.dir=s.dir.streams+req.params.ke+'/'+req.params.id+'/s.jpg';
|
3362 | res.writeHead(200, {
|
3363 | 'Content-Type': 'image/jpeg',
|
3364 | 'Cache-Control': 'no-cache',
|
3365 | 'Pragma': 'no-cache'
|
3366 | });
|
3367 | res.on('finish',function(){res.end();delete(res)});
|
3368 | if (fs.existsSync(req.dir)){
|
3369 | fs.createReadStream(req.dir).pipe(res);
|
3370 | }else{
|
3371 | fs.createReadStream(config.defaultMjpeg).pipe(res);
|
3372 | }
|
3373 | },res,req);
|
3374 | });
|
3375 |
|
3376 | app.get('/:auth/flv/:ke/:id/s.flv', function(req,res) {
|
3377 | res.header("Access-Control-Allow-Origin",req.headers.origin);
|
3378 | s.auth(req.params,function(user){
|
3379 | if(s.group[req.params.ke].mon[req.params.id].firstFLVchunk){
|
3380 | if(!req.params.feed){req.params.feed='1'}
|
3381 |
|
3382 | var contentWriter
|
3383 |
|
3384 | res.setHeader('Content-Type', 'video/x-flv');
|
3385 | res.setHeader('Access-Control-Allow-Origin','*');
|
3386 |
|
3387 | res.write(s.group[req.params.ke].mon[req.params.id].firstFLVchunk)
|
3388 |
|
3389 | s.group[req.params.ke].mon[req.params.id].emitter.on('data',contentWriter=function(buffer){
|
3390 | res.write(buffer)
|
3391 | })
|
3392 |
|
3393 | res.on('close', function () {
|
3394 | s.group[req.params.ke].mon[req.params.id].emitter.removeListener('data',contentWriter)
|
3395 | })
|
3396 | }else{
|
3397 | res.setHeader('Content-Type', 'application/json');
|
3398 | res.end(s.s({ok:false,msg:'FLV not started or not ready'},null,3))
|
3399 | }
|
3400 | })
|
3401 | })
|
3402 |
|
3403 | app.get(['/:auth/mjpeg/:ke/:id','/:auth/mjpeg/:ke/:id/:addon'], function(req,res) {
|
3404 | res.header("Access-Control-Allow-Origin",req.headers.origin);
|
3405 | if(req.params.addon=='full'){
|
3406 | res.render('mjpeg',{url:'/'+req.params.auth+'/mjpeg/'+req.params.ke+'/'+req.params.id});
|
3407 | res.end()
|
3408 | }else{
|
3409 | s.auth(req.params,function(user){
|
3410 | if(user.permissions.watch_stream==="0"||user.details.sub&&user.details.allmonitors!=='1'&&user.details.monitors.indexOf(req.params.id)===-1){
|
3411 | res.end(user.lang['Not Permitted'])
|
3412 | return
|
3413 | }
|
3414 | res.writeHead(200, {
|
3415 | 'Content-Type': 'multipart/x-mixed-replace; boundary=shinobi',
|
3416 | 'Cache-Control': 'no-cache',
|
3417 | 'Connection': 'keep-alive',
|
3418 | 'Pragma': 'no-cache'
|
3419 | });
|
3420 | var contentWriter,content = fs.readFileSync(config.defaultMjpeg,'binary');
|
3421 | res.write("--shinobi\r\n");
|
3422 | res.write("Content-Type: image/jpeg\r\n");
|
3423 | res.write("Content-Length: " + content.length + "\r\n");
|
3424 | res.write("\r\n");
|
3425 | res.write(content,'binary');
|
3426 | res.write("\r\n");
|
3427 | if(s.group[req.params.ke]&&s.group[req.params.ke].mon[req.params.id]&&s.group[req.params.ke].mon[req.params.id].emitter){
|
3428 | s.group[req.params.ke].mon[req.params.id].emitter.on('data',contentWriter=function(d){
|
3429 | content = d;
|
3430 | res.write(content,'binary');
|
3431 | })
|
3432 | res.on('close', function () {
|
3433 | s.group[req.params.ke].mon[req.params.id].emitter.removeListener('data',contentWriter)
|
3434 | });
|
3435 | }else{
|
3436 | res.end();
|
3437 | }
|
3438 | },res,req);
|
3439 | }
|
3440 | });
|
3441 |
|
3442 | app.get(['/:auth/embed/:ke/:id','/:auth/embed/:ke/:id/:addon'], function (req,res){
|
3443 | res.header("Access-Control-Allow-Origin",req.headers.origin);
|
3444 | req.params.protocol=req.protocol;
|
3445 | s.auth(req.params,function(user){
|
3446 | if(user.permissions.watch_stream==="0"||user.details.sub&&user.details.allmonitors!=='1'&&user.details.monitors.indexOf(req.params.id)===-1){
|
3447 | res.end(user.lang['Not Permitted'])
|
3448 | return
|
3449 | }
|
3450 | if(s.group[req.params.ke]&&s.group[req.params.ke].mon[req.params.id]){
|
3451 | if(s.group[req.params.ke].mon[req.params.id].started===1){
|
3452 | res.render("embed",{data:req.params,baseUrl:req.protocol+'://'+req.hostname,config:config,lang:user.lang,mon:CircularJSON.parse(CircularJSON.stringify(s.group[req.params.ke].mon_conf[req.params.id]))});
|
3453 | res.end()
|
3454 | }else{
|
3455 | res.end(user.lang['Cannot watch a monitor that isn\'t running.'])
|
3456 | }
|
3457 | }else{
|
3458 | res.end(user.lang['No Monitor Exists with this ID.'])
|
3459 | }
|
3460 | },res,req);
|
3461 | });
|
3462 |
|
3463 | app.get(['/:auth/monitor/:ke','/:auth/monitor/:ke/:id'], function (req,res){
|
3464 | req.ret={ok:false};
|
3465 | res.setHeader('Content-Type', 'application/json');
|
3466 | res.header("Access-Control-Allow-Origin",req.headers.origin);
|
3467 | req.fn=function(user){
|
3468 | if(user.permissions.get_monitors==="0"){
|
3469 | res.end(s.s([]))
|
3470 | return
|
3471 | }
|
3472 | req.sql='SELECT * FROM Monitors WHERE ke=?';req.ar=[req.params.ke];
|
3473 | if(!req.params.id){
|
3474 | if(user.details.sub&&user.details.monitors&&user.details.allmonitors!=='1'){
|
3475 | try{user.details.monitors=JSON.parse(user.details.monitors);}catch(er){}
|
3476 | req.or=[];
|
3477 | user.details.monitors.forEach(function(v,n){
|
3478 | req.or.push('mid=?');req.ar.push(v)
|
3479 | })
|
3480 | req.sql+=' AND ('+req.or.join(' OR ')+')'
|
3481 | }
|
3482 | }else{
|
3483 | if(!user.details.sub||user.details.allmonitors!=='0'||user.details.monitors.indexOf(req.params.id)>-1){
|
3484 | req.sql+=' and mid=?';req.ar.push(req.params.id)
|
3485 | }else{
|
3486 | res.end('[]');
|
3487 | return;
|
3488 | }
|
3489 | }
|
3490 | s.sqlQuery(req.sql,req.ar,function(err,r){
|
3491 |
|
3492 |
|
3493 |
|
3494 |
|
3495 |
|
3496 |
|
3497 |
|
3498 |
|
3499 |
|
3500 |
|
3501 | if(r.length===1){r=r[0];}
|
3502 | res.end(s.s(r, null, 3));
|
3503 | })
|
3504 | }
|
3505 | s.auth(req.params,req.fn,res,req);
|
3506 | });
|
3507 |
|
3508 | app.get(['/:auth/videos/:ke','/:auth/videos/:ke/:id'], function (req,res){
|
3509 | res.setHeader('Content-Type', 'application/json');
|
3510 | res.header("Access-Control-Allow-Origin",req.headers.origin);
|
3511 | s.auth(req.params,function(user){
|
3512 | if(user.permissions.watch_videos==="0"||user.details.sub&&user.details.allmonitors!=='1'&&user.details.video_view.indexOf(req.params.id)===-1){
|
3513 | res.end(s.s([]))
|
3514 | return
|
3515 | }
|
3516 | req.sql='SELECT * FROM Videos WHERE ke=?';req.ar=[req.params.ke];
|
3517 | req.count_sql='SELECT COUNT(*) FROM Videos WHERE ke=?';req.count_ar=[req.params.ke];
|
3518 | if(req.query.archived=='1'){
|
3519 | req.sql+=' AND details LIKE \'%"archived":"1"\''
|
3520 | req.count_sql+=' AND details LIKE \'%"archived":"1"\''
|
3521 | }
|
3522 | if(!req.params.id){
|
3523 | if(user.details.sub&&user.details.monitors&&user.details.allmonitors!=='1'){
|
3524 | try{user.details.monitors=JSON.parse(user.details.monitors);}catch(er){}
|
3525 | req.or=[];
|
3526 | user.details.monitors.forEach(function(v,n){
|
3527 | req.or.push('mid=?');req.ar.push(v)
|
3528 | })
|
3529 | req.sql+=' AND ('+req.or.join(' OR ')+')'
|
3530 | req.count_sql+=' AND ('+req.or.join(' OR ')+')'
|
3531 | }
|
3532 | }else{
|
3533 | if(!user.details.sub||user.details.allmonitors!=='0'||user.details.monitors.indexOf(req.params.id)>-1){
|
3534 | req.sql+=' and mid=?';req.ar.push(req.params.id)
|
3535 | req.count_sql+=' and mid=?';req.count_ar.push(req.params.id)
|
3536 | }else{
|
3537 | res.end('[]');
|
3538 | return;
|
3539 | }
|
3540 | }
|
3541 | if(req.query.start||req.query.end){
|
3542 | if(!req.query.startOperator||req.query.startOperator==''){
|
3543 | req.query.startOperator='>='
|
3544 | }
|
3545 | if(!req.query.endOperator||req.query.endOperator==''){
|
3546 | req.query.endOperator='<='
|
3547 | }
|
3548 | switch(true){
|
3549 | case(req.query.start&&req.query.start!==''&&req.query.end&&req.query.end!==''):
|
3550 | req.query.start=req.query.start.replace('T',' ')
|
3551 | req.query.end=req.query.end.replace('T',' ')
|
3552 | req.sql+=' AND `time` '+req.query.startOperator+' ? AND `end` '+req.query.endOperator+' ?';
|
3553 | req.count_sql+=' AND `time` '+req.query.startOperator+' ? AND `end` '+req.query.endOperator+' ?';
|
3554 | req.ar.push(req.query.start)
|
3555 | req.ar.push(req.query.end)
|
3556 | req.count_ar.push(req.query.start)
|
3557 | req.count_ar.push(req.query.end)
|
3558 | break;
|
3559 | case(req.query.start&&req.query.start!==''):
|
3560 | req.query.start=req.query.start.replace('T',' ')
|
3561 | req.sql+=' AND `time` '+req.query.startOperator+' ?';
|
3562 | req.count_sql+=' AND `time` '+req.query.startOperator+' ?';
|
3563 | req.ar.push(req.query.start)
|
3564 | req.count_ar.push(req.query.start)
|
3565 | break;
|
3566 | case(req.query.end&&req.query.end!==''):
|
3567 | req.query.end=req.query.end.replace('T',' ')
|
3568 | req.sql+=' AND `end` '+req.query.endOperator+' ?';
|
3569 | req.count_sql+=' AND `end` '+req.query.endOperator+' ?';
|
3570 | req.ar.push(req.query.end)
|
3571 | req.count_ar.push(req.query.end)
|
3572 | break;
|
3573 | }
|
3574 | }
|
3575 | req.sql+=' ORDER BY `time` DESC';
|
3576 | if(!req.query.limit||req.query.limit==''){
|
3577 | req.query.limit='100'
|
3578 | }
|
3579 | if(req.query.limit!=='0'){
|
3580 | req.sql+=' LIMIT '+req.query.limit
|
3581 | }
|
3582 | s.sqlQuery(req.sql,req.ar,function(err,r){
|
3583 | if(!r){
|
3584 | res.end(s.s({total:0,limit:req.query.limit,skip:0,videos:[]}, null, 3));
|
3585 | return
|
3586 | }
|
3587 | s.sqlQuery(req.count_sql,req.count_ar,function(err,count){
|
3588 | r.forEach(function(v){
|
3589 | v.href='/'+req.params.auth+'/videos/'+v.ke+'/'+v.mid+'/'+s.moment(v.time)+'.'+v.ext;
|
3590 | })
|
3591 | if(req.query.limit.indexOf(',')>-1){
|
3592 | req.skip=parseInt(req.query.limit.split(',')[0])
|
3593 | req.query.limit=parseInt(req.query.limit.split(',')[0])
|
3594 | }else{
|
3595 | req.skip=0
|
3596 | req.query.limit=parseInt(req.query.limit)
|
3597 | }
|
3598 | res.end(s.s({total:count[0]['COUNT(*)'],limit:req.query.limit,skip:req.skip,videos:r}, null, 3));
|
3599 | })
|
3600 | })
|
3601 | },res,req);
|
3602 | });
|
3603 |
|
3604 | app.get(['/:auth/events/:ke','/:auth/events/:ke/:id','/:auth/events/:ke/:id/:limit','/:auth/events/:ke/:id/:limit/:start','/:auth/events/:ke/:id/:limit/:start/:end'], function (req,res){
|
3605 | req.ret={ok:false};
|
3606 | res.setHeader('Content-Type', 'application/json');
|
3607 | res.header("Access-Control-Allow-Origin",req.headers.origin);
|
3608 | s.auth(req.params,function(user){
|
3609 | if(user.permissions.watch_videos==="0"||user.details.sub&&user.details.allmonitors!=='1'&&user.details.video_view.indexOf(req.params.id)===-1){
|
3610 | res.end(s.s([]))
|
3611 | return
|
3612 | }
|
3613 | req.sql='SELECT * FROM Events WHERE ke=?';req.ar=[req.params.ke];
|
3614 | if(!req.params.id){
|
3615 | if(user.details.sub&&user.details.monitors&&user.details.allmonitors!=='1'){
|
3616 | try{user.details.monitors=JSON.parse(user.details.monitors);}catch(er){}
|
3617 | req.or=[];
|
3618 | user.details.monitors.forEach(function(v,n){
|
3619 | req.or.push('mid=?');req.ar.push(v)
|
3620 | })
|
3621 | req.sql+=' AND ('+req.or.join(' OR ')+')'
|
3622 | }
|
3623 | }else{
|
3624 | if(!user.details.sub||user.details.allmonitors!=='0'||user.details.monitors.indexOf(req.params.id)>-1){
|
3625 | req.sql+=' and mid=?';req.ar.push(req.params.id)
|
3626 | }else{
|
3627 | res.end('[]');
|
3628 | return;
|
3629 | }
|
3630 | }
|
3631 | if(req.params.start&&req.params.start!==''){
|
3632 | req.params.start=req.params.start.replace('T',' ')
|
3633 | if(req.params.end&&req.params.end!==''){
|
3634 | req.params.end=req.params.end.replace('T',' ')
|
3635 | req.sql+=' AND `time` >= ? AND `time` <= ?';
|
3636 | req.ar.push(decodeURIComponent(req.params.start))
|
3637 | req.ar.push(decodeURIComponent(req.params.end))
|
3638 | }else{
|
3639 | req.sql+=' AND `time` >= ?';
|
3640 | req.ar.push(decodeURIComponent(req.params.start))
|
3641 | }
|
3642 | }
|
3643 | if(!req.params.limit||req.params.limit==''){req.params.limit=100}
|
3644 | req.sql+=' ORDER BY `time` DESC LIMIT '+req.params.limit+'';
|
3645 | s.sqlQuery(req.sql,req.ar,function(err,r){
|
3646 | if(err){
|
3647 | err.sql=req.sql;
|
3648 | res.end(s.s(err, null, 3));
|
3649 | return
|
3650 | }
|
3651 | if(!r){r=[]}
|
3652 | r.forEach(function(v,n){
|
3653 | r[n].details=JSON.parse(v.details);
|
3654 | })
|
3655 | res.end(s.s(r, null, 3));
|
3656 | })
|
3657 | },res,req);
|
3658 | });
|
3659 |
|
3660 | app.get(['/:auth/logs/:ke','/:auth/logs/:ke/:id','/:auth/logs/:ke/:limit','/:auth/logs/:ke/:id/:limit'], function (req,res){
|
3661 | req.ret={ok:false};
|
3662 | res.setHeader('Content-Type', 'application/json');
|
3663 | res.header("Access-Control-Allow-Origin",req.headers.origin);
|
3664 | s.auth(req.params,function(user){
|
3665 | if(user.permissions.get_logs==="0"){
|
3666 | res.end(s.s([]))
|
3667 | return
|
3668 | }
|
3669 | req.sql='SELECT * FROM Logs WHERE ke=?';req.ar=[req.params.ke];
|
3670 | if(!req.params.id){
|
3671 | if(user.details.sub&&user.details.monitors&&user.details.allmonitors!=='1'){
|
3672 | try{user.details.monitors=JSON.parse(user.details.monitors);}catch(er){}
|
3673 | req.or=[];
|
3674 | user.details.monitors.forEach(function(v,n){
|
3675 | req.or.push('mid=?');req.ar.push(v)
|
3676 | })
|
3677 | req.sql+=' AND ('+req.or.join(' OR ')+')'
|
3678 | }
|
3679 | }else{
|
3680 | if(!user.details.sub||user.details.allmonitors!=='0'||user.details.monitors.indexOf(req.params.id)>-1||req.params.id.indexOf('$')>-1){
|
3681 | req.sql+=' and mid=?';req.ar.push(req.params.id)
|
3682 | }else{
|
3683 | res.end('[]');
|
3684 | return;
|
3685 | }
|
3686 | }
|
3687 | if(!req.params.limit||req.params.limit==''){req.params.limit=100}
|
3688 | req.sql+=' ORDER BY `time` DESC LIMIT '+req.params.limit+'';
|
3689 | s.sqlQuery(req.sql,req.ar,function(err,r){
|
3690 | if(err){
|
3691 | err.sql=req.sql;
|
3692 | res.end(s.s(err, null, 3));
|
3693 | return
|
3694 | }
|
3695 | if(!r){r=[]}
|
3696 | r.forEach(function(v,n){
|
3697 | r[n].info=JSON.parse(v.info)
|
3698 | })
|
3699 | res.end(s.s(r, null, 3));
|
3700 | })
|
3701 | },res,req);
|
3702 | });
|
3703 |
|
3704 | app.get('/:auth/smonitor/:ke', function (req,res){
|
3705 | req.ret={ok:false};
|
3706 | res.setHeader('Content-Type', 'application/json');
|
3707 | res.header("Access-Control-Allow-Origin",req.headers.origin);
|
3708 | req.fn=function(user){
|
3709 | if(user.permissions.get_monitors==="0"){
|
3710 | res.end(s.s([]))
|
3711 | return
|
3712 | }
|
3713 | req.sql='SELECT * FROM Monitors WHERE ke=?';req.ar=[req.params.ke];
|
3714 | if(user.details.sub&&user.details.monitors&&user.details.allmonitors!=='1'){
|
3715 | try{user.details.monitors=JSON.parse(user.details.monitors);}catch(er){}
|
3716 | req.or=[];
|
3717 | user.details.monitors.forEach(function(v,n){
|
3718 | req.or.push('mid=?');req.ar.push(v)
|
3719 | })
|
3720 | req.sql+=' AND ('+req.or.join(' OR ')+')'
|
3721 | }
|
3722 | s.sqlQuery(req.sql,req.ar,function(err,r){
|
3723 | if(r&&r[0]){
|
3724 | req.ar=[];
|
3725 | r.forEach(function(v){
|
3726 | if(s.group[req.params.ke]&&s.group[req.params.ke].mon[v.mid]&&s.group[req.params.ke].mon[v.mid].started===1){
|
3727 | req.ar.push(v)
|
3728 | }
|
3729 | })
|
3730 | }else{
|
3731 | req.ar=[];
|
3732 | }
|
3733 | res.end(s.s(req.ar, null, 3));
|
3734 | })
|
3735 | }
|
3736 | s.auth(req.params,req.fn,res,req);
|
3737 | });
|
3738 |
|
3739 | app.all(['/:auth/configureMonitor/:ke/:id','/:auth/configureMonitor/:ke/:id/:f'], function (req,res){
|
3740 | req.ret={ok:false};
|
3741 | res.setHeader('Content-Type', 'application/json');
|
3742 | res.header("Access-Control-Allow-Origin",req.headers.origin);
|
3743 | s.auth(req.params,function(user){
|
3744 | if(req.params.f!=='delete'){
|
3745 | if(!req.body.data&&!req.query.data){
|
3746 | req.ret.msg='No Monitor Data found.'
|
3747 | res.end(s.s(req.ret, null, 3))
|
3748 | return
|
3749 | }
|
3750 | try{
|
3751 | if(req.query.data){
|
3752 | req.monitor=JSON.parse(req.query.data)
|
3753 | }else{
|
3754 | req.monitor=JSON.parse(req.body.data)
|
3755 | }
|
3756 | }catch(er){
|
3757 | if(!req.monitor){
|
3758 | req.ret.msg=user.lang.monitorEditText1;
|
3759 | res.end(s.s(req.ret, null, 3))
|
3760 | }
|
3761 | return
|
3762 | }
|
3763 | if(!user.details.sub||user.details.allmonitors==='1'||user.details.monitor_edit.indexOf(req.monitor.mid)>-1){
|
3764 | if(req.monitor&&req.monitor.mid&&req.monitor.name){
|
3765 | req.set=[],req.ar=[];
|
3766 | req.monitor.mid=req.monitor.mid.replace(/[^\w\s]/gi,'').replace(/ /g,'');
|
3767 | try{
|
3768 | JSON.parse(req.monitor.details)
|
3769 | }catch(er){
|
3770 | if(!req.monitor.details||!req.monitor.details.stream_type){
|
3771 | req.ret.msg=user.lang.monitorEditText2;
|
3772 | res.end(s.s(req.ret, null, 3))
|
3773 | return
|
3774 | }else{
|
3775 | req.monitor.details=JSON.stringify(req.monitor.details)
|
3776 | }
|
3777 | }
|
3778 | req.monitor.ke=req.params.ke
|
3779 | req.logObject={details:JSON.parse(req.monitor.details),ke:req.params.ke,mid:req.params.id}
|
3780 | s.sqlQuery('SELECT * FROM Monitors WHERE ke=? AND mid=?',[req.monitor.ke,req.monitor.mid],function(er,r){
|
3781 | req.tx={f:'monitor_edit',mid:req.monitor.mid,ke:req.monitor.ke,mon:req.monitor};
|
3782 | if(r&&r[0]){
|
3783 | req.tx.new=false;
|
3784 | Object.keys(req.monitor).forEach(function(v){
|
3785 | if(req.monitor[v]&&req.monitor[v]!==''){
|
3786 | req.set.push(v+'=?'),req.ar.push(req.monitor[v]);
|
3787 | }
|
3788 | })
|
3789 | req.set=req.set.join(',');
|
3790 | req.ar.push(req.monitor.ke),req.ar.push(req.monitor.mid);
|
3791 | s.log(req.monitor,{type:'Monitor Updated',msg:'by user : '+user.uid});
|
3792 | req.ret.msg=user.lang['Monitor Updated by user']+' : '+user.uid;
|
3793 | s.sqlQuery('UPDATE Monitors SET '+req.set+' WHERE ke=? AND mid=?',req.ar)
|
3794 | req.finish=1;
|
3795 | }else{
|
3796 | if(!s.group[req.monitor.ke].init.max_camera||s.group[req.monitor.ke].init.max_camera==''||Object.keys(s.group[req.monitor.ke].mon).length <= parseInt(s.group[req.monitor.ke].init.max_camera)){
|
3797 | req.tx.new=true;
|
3798 | req.st=[];
|
3799 | Object.keys(req.monitor).forEach(function(v){
|
3800 | if(req.monitor[v]&&req.monitor[v]!==''){
|
3801 | req.set.push(v),req.st.push('?'),req.ar.push(req.monitor[v]);
|
3802 | }
|
3803 | })
|
3804 |
|
3805 | req.set=req.set.join(','),req.st=req.st.join(',');
|
3806 | s.log(req.monitor,{type:'Monitor Added',msg:'by user : '+user.uid});
|
3807 | req.ret.msg=user.lang['Monitor Added by user']+' : '+user.uid;
|
3808 | s.sqlQuery('INSERT INTO Monitors ('+req.set+') VALUES ('+req.st+')',req.ar)
|
3809 | req.finish=1;
|
3810 | }else{
|
3811 | req.tx.f='monitor_edit_failed';
|
3812 | req.tx.ff='max_reached';
|
3813 | req.ret.msg=user.lang.monitorEditFailedMaxReached;
|
3814 | }
|
3815 | }
|
3816 | if(req.finish===1){
|
3817 | req.monitor.details=JSON.parse(req.monitor.details)
|
3818 | req.ret.ok=true;
|
3819 | s.init(0,{mid:req.monitor.mid,ke:req.monitor.ke});
|
3820 | s.group[req.monitor.ke].mon_conf[req.monitor.mid]=s.init('noReference',req.monitor);
|
3821 | if(req.monitor.mode==='stop'){
|
3822 | s.camera('stop',req.monitor);
|
3823 | }else{
|
3824 | s.camera('stop',req.monitor);setTimeout(function(){s.camera(req.monitor.mode,req.monitor);},5000)
|
3825 | };
|
3826 | s.tx(req.tx,'STR_'+req.monitor.ke);
|
3827 | };
|
3828 | s.tx(req.tx,'GRP_'+req.monitor.ke);
|
3829 | res.end(s.s(req.ret, null, 3))
|
3830 | })
|
3831 | }else{
|
3832 | req.ret.msg=user.lang.monitorEditText1;
|
3833 | res.end(s.s(req.ret, null, 3))
|
3834 | }
|
3835 | }else{
|
3836 | req.ret.msg=user.lang['Not Permitted'];
|
3837 | res.end(s.s(req.ret, null, 3))
|
3838 | }
|
3839 | }else{
|
3840 | if(!user.details.sub||user.details.allmonitors==='1'||user.details.monitor_edit.indexOf(req.params.id)>-1){
|
3841 | s.log(s.group[req.params.ke].mon_conf[req.params.id],{type:'Monitor Deleted',msg:'by user : '+user.uid});
|
3842 | req.params.delete=1;s.camera('stop',req.params);
|
3843 | s.tx({f:'monitor_delete',uid:user.uid,mid:req.params.id,ke:req.params.ke},'GRP_'+req.params.ke);
|
3844 | s.sqlQuery('DELETE FROM Monitors WHERE ke=? AND mid=?',[req.params.ke,req.params.id])
|
3845 | req.ret.ok=true;
|
3846 | req.ret.msg='Monitor Deleted by user : '+user.uid
|
3847 | res.end(s.s(req.ret, null, 3))
|
3848 | }
|
3849 | }
|
3850 | })
|
3851 | })
|
3852 | app.get(['/:auth/monitor/:ke/:id/:f','/:auth/monitor/:ke/:id/:f/:ff','/:auth/monitor/:ke/:id/:f/:ff/:fff'], function (req,res){
|
3853 | req.ret={ok:false};
|
3854 | res.setHeader('Content-Type', 'application/json');
|
3855 | res.header("Access-Control-Allow-Origin",req.headers.origin);
|
3856 | s.auth(req.params,function(user){
|
3857 | if(user.permissions.control_monitors==="0"||user.details.sub&&user.details.allmonitors!=='1'&&user.details.monitor_edit.indexOf(req.params.id)===-1){
|
3858 | res.end(user.lang['Not Permitted'])
|
3859 | return
|
3860 | }
|
3861 | if(req.params.f===''){req.ret.msg=user.lang.monitorGetText1;res.end(s.s(req.ret, null, 3));return}
|
3862 | if(req.params.f!=='stop'&&req.params.f!=='start'&&req.params.f!=='record'){
|
3863 | req.ret.msg='Mode not recognized.';
|
3864 | res.end(s.s(req.ret, null, 3));
|
3865 | return;
|
3866 | }
|
3867 | s.sqlQuery('SELECT * FROM Monitors WHERE ke=? AND mid=?',[req.params.ke,req.params.id],function(err,r){
|
3868 | if(r&&r[0]){
|
3869 | r=r[0];
|
3870 | if(req.query.reset==='1'||(s.group[r.ke]&&s.group[r.ke].mon_conf[r.mid].mode!==req.params.f)||req.query.fps&&(!s.group[r.ke].mon[r.mid].currentState||!s.group[r.ke].mon[r.mid].currentState.trigger_on)){
|
3871 | if(req.query.reset!=='1'||!s.group[r.ke].mon[r.mid].trigger_timer){
|
3872 | if(!s.group[r.ke].mon[r.mid].currentState)s.group[r.ke].mon[r.mid].currentState={}
|
3873 | s.group[r.ke].mon[r.mid].currentState.mode=r.mode.toString()
|
3874 | s.group[r.ke].mon[r.mid].currentState.fps=r.fps.toString()
|
3875 | if(!s.group[r.ke].mon[r.mid].currentState.trigger_on){
|
3876 | s.group[r.ke].mon[r.mid].currentState.trigger_on=true
|
3877 | }else{
|
3878 | s.group[r.ke].mon[r.mid].currentState.trigger_on=false
|
3879 | }
|
3880 | r.mode=req.params.f;
|
3881 | try{r.details=JSON.parse(r.details);}catch(er){}
|
3882 | if(req.query.fps){
|
3883 | r.fps=parseFloat(r.details.detector_trigger_record_fps)
|
3884 | s.group[r.ke].mon[r.mid].currentState.detector_trigger_record_fps=r.fps
|
3885 | }
|
3886 | r.id=r.mid;
|
3887 | s.sqlQuery('UPDATE Monitors SET mode=? WHERE ke=? AND mid=?',[r.mode,r.ke,r.mid]);
|
3888 | s.group[r.ke].mon_conf[r.mid]=r;
|
3889 | s.tx({f:'monitor_edit',mid:r.mid,ke:r.ke,mon:r},'GRP_'+r.ke);
|
3890 | s.tx({f:'monitor_edit',mid:r.mid,ke:r.ke,mon:r},'STR_'+r.ke);
|
3891 | s.camera('stop',s.init('noReference',r));
|
3892 | if(req.params.f!=='stop'){
|
3893 | s.camera(req.params.f,s.init('noReference',r));
|
3894 | }
|
3895 | req.ret.msg=user.lang['Monitor mode changed']+' : '+req.params.f;
|
3896 | }else{
|
3897 | req.ret.msg=user.lang['Reset Timer'];
|
3898 | }
|
3899 | req.ret.cmd_at=s.moment(new Date,'YYYY-MM-DD HH:mm:ss');
|
3900 | req.ret.ok=true;
|
3901 | if(req.params.ff&&req.params.f!=='stop'){
|
3902 | req.params.ff=parseFloat(req.params.ff);
|
3903 | clearTimeout(s.group[r.ke].mon[r.mid].trigger_timer)
|
3904 | switch(req.params.fff){
|
3905 | case'day':case'days':
|
3906 | req.timeout=req.params.ff*1000*60*60*24
|
3907 | break;
|
3908 | case'hr':case'hour':case'hours':
|
3909 | req.timeout=req.params.ff*1000*60*60
|
3910 | break;
|
3911 | case'min':case'minute':case'minutes':
|
3912 | req.timeout=req.params.ff*1000*60
|
3913 | break;
|
3914 | default:
|
3915 | req.timeout=req.params.ff*1000
|
3916 | break;
|
3917 | }
|
3918 | s.group[r.ke].mon[r.mid].trigger_timer=setTimeout(function(){
|
3919 | delete(s.group[r.ke].mon[r.mid].trigger_timer)
|
3920 | s.sqlQuery('UPDATE Monitors SET mode=? WHERE ke=? AND mid=?',[s.group[r.ke].mon[r.mid].currentState.mode,r.ke,r.mid]);
|
3921 | r.neglectTriggerTimer=1;
|
3922 | r.mode=s.group[r.ke].mon[r.mid].currentState.mode;
|
3923 | r.fps=s.group[r.ke].mon[r.mid].currentState.fps;
|
3924 | s.camera('stop',s.init('noReference',r),function(){
|
3925 | if(s.group[r.ke].mon[r.mid].currentState.mode!=='stop'){
|
3926 | s.camera(s.group[r.ke].mon[r.mid].currentState.mode,s.init('noReference',r));
|
3927 | }
|
3928 | s.group[r.ke].mon_conf[r.mid]=r;
|
3929 | });
|
3930 | s.tx({f:'monitor_edit',mid:r.mid,ke:r.ke,mon:r},'GRP_'+r.ke);
|
3931 | s.tx({f:'monitor_edit',mid:r.mid,ke:r.ke,mon:r},'STR_'+r.ke);
|
3932 | },req.timeout);
|
3933 |
|
3934 | }
|
3935 | }else{
|
3936 | req.ret.msg=user.lang['Monitor mode is already']+' : '+req.params.f;
|
3937 | }
|
3938 | }else{
|
3939 | req.ret.msg=user.lang['Monitor or Key does not exist.'];
|
3940 | }
|
3941 | res.end(s.s(req.ret, null, 3));
|
3942 | })
|
3943 | },res,req);
|
3944 | })
|
3945 |
|
3946 | app.get(['/:auth/fileBin/:ke','/:auth/fileBin/:ke/:id'],function (req,res){
|
3947 | res.setHeader('Content-Type', 'application/json');
|
3948 | res.header("Access-Control-Allow-Origin",req.headers.origin);
|
3949 | req.fn=function(user){
|
3950 | req.sql='SELECT * FROM Files WHERE ke=?';req.ar=[req.params.ke];
|
3951 | if(user.details.sub&&user.details.monitors&&user.details.allmonitors!=='1'){
|
3952 | try{user.details.monitors=JSON.parse(user.details.monitors);}catch(er){}
|
3953 | req.or=[];
|
3954 | user.details.monitors.forEach(function(v,n){
|
3955 | req.or.push('mid=?');req.ar.push(v)
|
3956 | })
|
3957 | req.sql+=' AND ('+req.or.join(' OR ')+')'
|
3958 | }else{
|
3959 | if(req.params.id&&(!user.details.sub||user.details.allmonitors!=='0'||user.details.monitors.indexOf(req.params.id)>-1)){
|
3960 | req.sql+=' and mid=?';req.ar.push(req.params.id)
|
3961 | }
|
3962 | }
|
3963 | s.sqlQuery(req.sql,req.ar,function(err,r){
|
3964 | if(!r){
|
3965 | r=[]
|
3966 | }else{
|
3967 | r.forEach(function(v){
|
3968 | v.details=JSON.parse(v.details)
|
3969 | v.href='/'+req.params.auth+'/fileBin/'+req.params.ke+'/'+req.params.id+'/'+v.details.year+'/'+v.details.month+'/'+v.details.day+'/'+v.name;
|
3970 | })
|
3971 | }
|
3972 | res.end(s.s(r, null, 3));
|
3973 | })
|
3974 | }
|
3975 | s.auth(req.params,req.fn,res,req);
|
3976 | });
|
3977 |
|
3978 | app.get('/:auth/fileBin/:ke/:id/:year/:month/:day/:file', function (req,res){
|
3979 | res.header("Access-Control-Allow-Origin",req.headers.origin);
|
3980 | req.fn=function(user){
|
3981 | req.failed=function(){
|
3982 | res.end(user.lang['File Not Found'])
|
3983 | }
|
3984 | if (!s.group[req.params.ke].fileBin[req.params.id+'/'+req.params.file]){
|
3985 | s.sqlQuery('SELECT * FROM Files WHERE ke=? AND mid=? AND name=?',[req.params.ke,req.params.id,req.params.file],function(err,r){
|
3986 | if(r&&r[0]){
|
3987 | r=r[0]
|
3988 | r.details=JSON.parse(r.details)
|
3989 | req.dir=s.dir.fileBin+req.params.ke+'/'+req.params.id+'/'+r.details.year+'/'+r.details.month+'/'+r.details.day+'/'+req.params.file;
|
3990 | if(fs.existsSync(req.dir)){
|
3991 | res.on('finish',function(){res.end();});
|
3992 | fs.createReadStream(req.dir).pipe(res);
|
3993 | }else{
|
3994 | req.failed()
|
3995 | }
|
3996 | }else{
|
3997 | req.failed()
|
3998 | }
|
3999 | })
|
4000 | }else{
|
4001 | res.end(user.lang['Please Wait for Completion'])
|
4002 | }
|
4003 | }
|
4004 | s.auth(req.params,req.fn,res,req);
|
4005 | });
|
4006 |
|
4007 | app.get('/:auth/videos/:ke/:id/:file', function (req,res){
|
4008 | s.auth(req.params,function(user){
|
4009 | if(user.permissions.watch_videos==="0"||user.details.sub&&user.details.allmonitors!=='1'&&user.details.monitors.indexOf(req.params.id)===-1){
|
4010 | res.end(user.lang['Not Permitted'])
|
4011 | return
|
4012 | }
|
4013 | s.sqlQuery('SELECT * FROM Videos WHERE ke=? AND mid=? AND time=?',[req.params.ke,req.params.id,s.nameToTime(req.params.file)],function(err,r){
|
4014 | if(r&&r[0]){
|
4015 | req.dir=s.video('getDir',r[0])+req.params.file
|
4016 | if (fs.existsSync(req.dir)){
|
4017 | req.ext=req.params.file.split('.')[1];
|
4018 | var total = fs.statSync(req.dir).size;
|
4019 | if (req.headers['range']) {
|
4020 | var range = req.headers.range;
|
4021 | var parts = range.replace(/bytes=/, "").split("-");
|
4022 | var partialstart = parts[0];
|
4023 | var partialend = parts[1];
|
4024 |
|
4025 | var start = parseInt(partialstart, 10);
|
4026 | var end = partialend ? parseInt(partialend, 10) : total-1;
|
4027 | var chunksize = (end-start)+1;
|
4028 | var file = fs.createReadStream(req.dir, {start: start, end: end});
|
4029 | req.headerWrite={ 'Content-Range': 'bytes ' + start + '-' + end + '/' + total, 'Accept-Ranges': 'bytes', 'Content-Length': chunksize, 'Content-Type': 'video/'+req.ext }
|
4030 | req.writeCode=206
|
4031 | } else {
|
4032 | req.headerWrite={ 'Content-Length': total, 'Content-Type': 'video/'+req.ext};
|
4033 | var file=fs.createReadStream(req.dir)
|
4034 | req.writeCode=200
|
4035 | }
|
4036 | if(req.query.downloadName){
|
4037 | req.headerWrite['content-disposition']='attachment; filename="'+req.query.downloadName+'"';
|
4038 | }
|
4039 | res.writeHead(req.writeCode,req.headerWrite);
|
4040 | file.on('close',function(){
|
4041 | res.end();
|
4042 | })
|
4043 | file.pipe(res);
|
4044 | }else{
|
4045 | res.end(user.lang['File Not Found'])
|
4046 | }
|
4047 | }else{
|
4048 | res.end(user.lang['File Not Found'])
|
4049 | }
|
4050 | })
|
4051 | },res,req);
|
4052 | });
|
4053 |
|
4054 | app.get('/:auth/motion/:ke/:id', function (req,res){
|
4055 | s.auth(req.params,function(user){
|
4056 | if(req.query.data){
|
4057 | try{
|
4058 | var d={id:req.params.id,ke:req.params.ke,details:JSON.parse(req.query.data)};
|
4059 | }catch(err){
|
4060 | res.end('Data Broken',err);
|
4061 | return;
|
4062 | }
|
4063 | }else{
|
4064 | res.end('No Data');
|
4065 | return;
|
4066 | }
|
4067 | if(!d.ke||!d.id||!s.group[d.ke]){
|
4068 | res.end(user.lang['No Group with this key exists']);
|
4069 | return;
|
4070 | }
|
4071 | s.camera('motion',d,function(){
|
4072 | res.end(user.lang['Trigger Successful'])
|
4073 | });
|
4074 | },res,req);
|
4075 | })
|
4076 |
|
4077 | app.get(['/:auth/videos/:ke/:id/:file/:mode','/:auth/videos/:ke/:id/:file/:mode/:f'], function (req,res){
|
4078 | req.ret={ok:false};
|
4079 | res.setHeader('Content-Type', 'application/json');
|
4080 | res.header("Access-Control-Allow-Origin",req.headers.origin);
|
4081 | s.auth(req.params,function(user){
|
4082 | if(user.permissions.watch_videos==="0"||user.details.sub&&user.details.allmonitors!=='1'&&user.details.video_delete.indexOf(req.params.id)===-1){
|
4083 | res.end(user.lang['Not Permitted'])
|
4084 | return
|
4085 | }
|
4086 | req.sql='SELECT * FROM Videos WHERE ke=? AND mid=? AND time=?';
|
4087 | req.ar=[req.params.ke,req.params.id,s.nameToTime(req.params.file)];
|
4088 | s.sqlQuery(req.sql,req.ar,function(err,r){
|
4089 | if(r&&r[0]){
|
4090 | r=r[0];r.filename=s.moment(r.time)+'.'+r.ext;
|
4091 | switch(req.params.mode){
|
4092 | case'fix':
|
4093 | req.ret.ok=true;
|
4094 | s.video('fix',r)
|
4095 | break;
|
4096 | case'status':
|
4097 | req.params.f=parseInt(req.params.f)
|
4098 | if(isNaN(req.params.f)||req.params.f===0){
|
4099 | req.ret.msg='Not a valid value.';
|
4100 | }else{
|
4101 | req.ret.ok=true;
|
4102 | s.sqlQuery('UPDATE Videos SET status=? WHERE ke=? AND mid=? AND time=?',[req.params.f,req.params.ke,req.params.id,s.nameToTime(req.params.file)])
|
4103 | s.tx({f:'video_edit',status:req.params.f,filename:r.filename,mid:r.mid,ke:r.ke,time:s.nameToTime(r.filename),end:s.moment(new Date,'YYYY-MM-DD HH:mm:ss')},'GRP_'+r.ke);
|
4104 | }
|
4105 | break;
|
4106 | case'delete':
|
4107 | req.ret.ok=true;
|
4108 | s.video('delete',r)
|
4109 | break;
|
4110 | default:
|
4111 | req.ret.msg=user.lang.modifyVideoText1;
|
4112 | break;
|
4113 | }
|
4114 | }else{
|
4115 | req.ret.msg=user.lang['No such file'];
|
4116 | }
|
4117 | res.end(s.s(req.ret, null, 3));
|
4118 | })
|
4119 | },res,req);
|
4120 | })
|
4121 |
|
4122 | app.all(['/streamIn/:ke/:id','/streamIn/:ke/:id/:feed'], function (req, res) {
|
4123 | var checkOrigin = function(search){return req.headers.host.indexOf(search)>-1}
|
4124 | if(checkOrigin('127.0.0.1')){
|
4125 | if(!req.params.feed){req.params.feed='1'}
|
4126 | if(!s.group[req.params.ke].mon[req.params.id].streamIn[req.params.feed]){
|
4127 | s.group[req.params.ke].mon[req.params.id].streamIn[req.params.feed] = new events.EventEmitter().setMaxListeners(0)
|
4128 | }
|
4129 |
|
4130 | res.connection.setTimeout(0);
|
4131 | req.on('data', function(buffer){
|
4132 | s.group[req.params.ke].mon[req.params.id].streamIn[req.params.feed].emit('data',buffer)
|
4133 | });
|
4134 | req.on('end',function(){
|
4135 |
|
4136 | });
|
4137 | }else{
|
4138 | res.end('Local connection is only allowed.')
|
4139 | }
|
4140 | })
|
4141 |
|
4142 | app.get(['/:auth/h264/:ke/:id/:feed','/:auth/h264/:ke/:id'], function (req, res) {
|
4143 | res.header("Access-Control-Allow-Origin",req.headers.origin);
|
4144 | s.auth(req.params,function(user){
|
4145 | if(!req.params.feed){req.params.feed='1'}
|
4146 | if(!s.group[req.params.ke].mon[req.params.id].streamIn[req.params.feed]){
|
4147 | s.group[req.params.ke].mon[req.params.id].streamIn[req.params.feed] = new events.EventEmitter().setMaxListeners(0)
|
4148 | }
|
4149 | var contentWriter
|
4150 | var date = new Date();
|
4151 | res.writeHead(200, {
|
4152 | 'Date': date.toUTCString(),
|
4153 | 'Connection': 'keep-alive',
|
4154 | 'Cache-Control': 'no-cache',
|
4155 | 'Pragma': 'no-cache',
|
4156 | 'Content-Type': 'video/mp4',
|
4157 | 'Server': 'Shinobi H.264 Test Stream',
|
4158 | });
|
4159 | s.group[req.params.ke].mon[req.params.id].streamIn[req.params.feed].on('data',contentWriter=function(buffer){
|
4160 | res.write(buffer)
|
4161 | })
|
4162 | res.on('close', function () {
|
4163 | s.group[req.params.ke].mon[req.params.id].streamIn[req.params.feed].removeListener('data',contentWriter)
|
4164 | })
|
4165 | })
|
4166 | });
|
4167 | try{
|
4168 | s.cpuUsage=function(e){
|
4169 | k={}
|
4170 | switch(s.platform){
|
4171 | case'win32':
|
4172 | k.cmd="@for /f \"skip=1\" %p in ('wmic cpu get loadpercentage') do @echo %p%"
|
4173 | break;
|
4174 | case'darwin':
|
4175 | k.cmd="ps -A -o %cpu | awk '{s+=$1} END {print s}'";
|
4176 | break;
|
4177 | case'linux':
|
4178 | k.cmd='LANG=C top -b -n 2 | grep "^'+config.cpuUsageMarker+'" | awk \'{print $2}\' | tail -n1';
|
4179 | break;
|
4180 | }
|
4181 | if(k.cmd){
|
4182 | exec(k.cmd,{encoding:'utf8',detached: true},function(err,d){
|
4183 | if(s.isWin===true){
|
4184 | d=d.replace(/(\r\n|\n|\r)/gm,"").replace(/%/g,"")
|
4185 | }
|
4186 | e(d)
|
4187 | });
|
4188 | }else{
|
4189 | e(0)
|
4190 | }
|
4191 | }
|
4192 | s.ramUsage=function(e){
|
4193 | k={}
|
4194 | switch(s.platform){
|
4195 | case'win32':
|
4196 | k.cmd = "wmic OS get FreePhysicalMemory /Value"
|
4197 | break;
|
4198 | case'darwin':
|
4199 | k.cmd = "vm_stat | awk '/^Pages free: /{f=substr($3,1,length($3)-1)} /^Pages active: /{a=substr($3,1,length($3-1))} /^Pages inactive: /{i=substr($3,1,length($3-1))} /^Pages speculative: /{s=substr($3,1,length($3-1))} /^Pages wired down: /{w=substr($4,1,length($4-1))} /^Pages occupied by compressor: /{c=substr($5,1,length($5-1)); print ((a+w)/(f+a+i+w+s+c))*100;}'"
|
4200 | break;
|
4201 | default:
|
4202 | k.cmd = "LANG=C free | grep Mem | awk '{print $4/$2 * 100.0}'";
|
4203 | break;
|
4204 | }
|
4205 | if(k.cmd){
|
4206 | exec(k.cmd,{encoding:'utf8',detached: true},function(err,d){
|
4207 | if(s.isWin===true){
|
4208 | d=(parseInt(d.split('=')[1])/(s.totalmem/1000))*100
|
4209 | }
|
4210 | e(d)
|
4211 | });
|
4212 | }else{
|
4213 | e(0)
|
4214 | }
|
4215 | }
|
4216 | setInterval(function(){
|
4217 | s.cpuUsage(function(cpu){
|
4218 | s.ramUsage(function(ram){
|
4219 | s.tx({f:'os',cpu:cpu,ram:ram},'CPU');
|
4220 | })
|
4221 | })
|
4222 | },10000);
|
4223 | }catch(err){s.systemLog(lang['CPU indicator will not work. Continuing...'])}
|
4224 |
|
4225 | if(config.autoDropCache===true){
|
4226 | setInterval(function(){
|
4227 | exec('echo 3 > /proc/sys/vm/drop_caches',{detached: true})
|
4228 | },60000*20);
|
4229 | }
|
4230 | s.beat=function(){
|
4231 | setTimeout(s.beat, 8000);
|
4232 | io.sockets.emit('ping',{beat:1});
|
4233 | }
|
4234 | s.beat();
|
4235 | setTimeout(function(){
|
4236 |
|
4237 | s.sqlQuery('SELECT * FROM Users WHERE details NOT LIKE ?',['%"sub"%'],function(err,r){
|
4238 | if(r&&r[0]){
|
4239 | var count = r.length
|
4240 | var countFinished = 0
|
4241 | r.forEach(function(v,n){
|
4242 | v.size=0;
|
4243 | v.limit=JSON.parse(v.details).size
|
4244 | s.sqlQuery('SELECT * FROM Videos WHERE ke=? AND status!=?',[v.ke,0],function(err,rr){
|
4245 | ++countFinished
|
4246 | if(r&&r[0]){
|
4247 | rr.forEach(function(b){
|
4248 | v.size+=b.size
|
4249 | })
|
4250 | }
|
4251 | s.systemLog(v.mail+' : '+lang.startUpText0+' : '+rr.length,v.size)
|
4252 | if(!s.group[v.ke]){
|
4253 | s.group[v.ke]={}
|
4254 | }
|
4255 | if(!s.group[v.ke].init){
|
4256 | s.group[v.ke].init={}
|
4257 | }
|
4258 | if(!v.limit||v.limit===''){v.limit=10000}else{v.limit=parseFloat(v.limit)}
|
4259 |
|
4260 | s.group[v.ke].sizeLimit=v.limit;
|
4261 |
|
4262 | s.group[v.ke].usedSpace=v.size/1000000;
|
4263 |
|
4264 | s.init('diskUsedEmit',v)
|
4265 | s.systemLog(v.mail+' : '+lang.startUpText1,countFinished+'/'+count)
|
4266 | if(countFinished===count){
|
4267 | s.systemLog(lang.startUpText2)
|
4268 |
|
4269 | s.sqlQuery('SELECT * FROM Videos WHERE status=?',[0],function(err,r){
|
4270 | if(r&&r[0]){
|
4271 | r.forEach(function(v){
|
4272 | s.init(0,v)
|
4273 | v.filename=s.moment(v.time);
|
4274 | s.video('close',v);
|
4275 | })
|
4276 | }
|
4277 | s.systemLog(lang.startUpText3)
|
4278 | setTimeout(function(){
|
4279 | s.systemLog(lang.startUpText4)
|
4280 |
|
4281 | s.sqlQuery('SELECT * FROM Monitors', function(err,r) {
|
4282 | if(err){s.systemLog(err)}
|
4283 | if(r&&r[0]){
|
4284 | r.forEach(function(v){
|
4285 | s.init(0,v);
|
4286 | r.ar={};
|
4287 | r.ar.id=v.mid;
|
4288 | Object.keys(v).forEach(function(b){
|
4289 | r.ar[b]=v[b];
|
4290 | })
|
4291 | if(!s.group[v.ke]){
|
4292 | s.group[v.ke]={}
|
4293 | s.group[v.ke].mon_conf={}
|
4294 | }
|
4295 | v.details=JSON.parse(v.details);
|
4296 | s.group[v.ke].mon_conf[v.mid]=v;
|
4297 | s.camera(v.mode,r.ar);
|
4298 | });
|
4299 | }
|
4300 | s.systemLog(lang.startUpText5)
|
4301 | process.send('ready')
|
4302 | });
|
4303 | },3000)
|
4304 | })
|
4305 | }
|
4306 | })
|
4307 | })
|
4308 | }
|
4309 | })
|
4310 | },1500)
|