UNPKG

11.5 kBJavaScriptView Raw
1process.on('uncaughtException', function (err) {
2 console.error('uncaughtException',err);
3});
4var fs = require('fs');
5var path = require('path');
6var mysql = require('mysql');
7var moment = require('moment');
8var exec = require('child_process').exec;
9var spawn = require('child_process').spawn;
10var config=require('./conf.json');
11var sql=mysql.createConnection(config.db);
12
13//set option defaults
14s={lock:{}};
15if(config.cron===undefined)config.cron={};
16if(config.cron.deleteOld===undefined)config.cron.deleteOld=true;
17if(config.cron.deleteOrphans===undefined)config.cron.deleteOrphans=false;
18if(config.cron.deleteNoVideo===undefined)config.cron.deleteNoVideo=true;
19if(config.cron.deleteOverMax===undefined)config.cron.deleteOverMax=true;
20if(config.cron.deleteLogs===undefined)config.cron.deleteLogs=true;
21if(config.cron.deleteEvents===undefined)config.cron.deleteEvents=true;
22if(config.cron.interval===undefined)config.cron.interval=1;
23
24if(!config.ip||config.ip===''||config.ip.indexOf('0.0.0.0')>-1)config.ip='localhost';
25if(!config.videosDir)config.videosDir=__dirname+'/videos/';
26if(!config.addStorage){config.addStorage=[]}
27s.checkCorrectPathEnding=function(x){
28 var length=x.length
29 if(x.charAt(length-1)!=='/'){
30 x=x+'/'
31 }
32 return x.replace('__DIR__',__dirname)
33}
34s.dir={
35 videos:s.checkCorrectPathEnding(config.videosDir),
36 addStorage:config.addStorage,
37};
38s.moment=function(e,x){
39 if(!e){e=new Date};if(!x){x='YYYY-MM-DDTHH-mm-ss'};
40 return moment(e).format(x);
41}
42s.nameToTime=function(x){x=x.replace('.webm','').replace('.mp4','').split('T'),x[1]=x[1].replace(/-/g,':');x=x.join(' ');return x;}
43io = require('socket.io-client')('ws://'+config.ip+':'+config.port);//connect to master
44s.cx=function(x){x.cronKey=config.cron.key;return io.emit('cron',x)}
45//emulate master socket emitter
46s.tx=function(x,y){s.cx({f:'s.tx',data:x,to:y})}
47s.video=function(x,y){s.cx({f:'s.video',data:x,file:y})}
48//Cron Job
49s.cx({f:'init',time:moment()})
50s.getVideoDirectory=function(e){
51 if(e.mid&&!e.id){e.id=e.mid};
52 if(e.details&&(e.details instanceof Object)===false){
53 try{e.details=JSON.parse(e.details)}catch(err){}
54 }
55 if(e.details.dir&&e.details.dir!==''){
56 return s.checkCorrectPathEnding(e.details.dir)+e.ke+'/'+e.id+'/'
57 }else{
58 return s.dir.videos+e.ke+'/'+e.id+'/';
59 }
60}
61s.checkFilterRules=function(v){
62 Object.keys(v.d.filters).forEach(function(m,b){
63 b=v.d.filters[m];
64 if(b.enabled==="1"){
65 b.ar=[v.ke];
66 b.sql=[];
67 b.where.forEach(function(j,k){
68 if(j.p1==='ke'){j.p3=v.ke}
69 switch(j.p3_type){
70 case'function':
71 b.sql.push(j.p1+' '+j.p2+' '+j.p3)
72 break;
73 default:
74 b.sql.push(j.p1+' '+j.p2+' ?')
75 b.ar.push(j.p3)
76 break;
77 }
78 })
79 b.sql='WHERE ke=? AND status != 0 AND details NOT LIKE \'%"archived":"1"%\' AND ('+b.sql.join(' AND ')+')';
80 if(b.sort_by&&b.sort_by!==''){
81 b.sql+=' ORDER BY `'+b.sort_by+'` '+b.sort_by_direction
82 }
83 if(b.limit&&b.limit!==''){
84 b.sql+=' LIMIT '+b.limit
85 }
86 sql.query('SELECT * FROM Videos '+b.sql,b.ar,function(err,r){
87 if(r&&r[0]){
88 b.cx={
89 f:'filters',
90 name:b.name,
91 videos:r,
92 time:moment(),
93 ke:v.ke,
94 id:b.id
95 };
96 if(b.archive==="1"){
97 s.cx({f:'filters',ff:'archive',videos:r,time:moment(),ke:v.ke,id:b.id});
98 }else{
99 if(b.delete==="1"){
100 s.cx({f:'filters',ff:'delete',videos:r,time:moment(),ke:v.ke,id:b.id});
101 }
102 }
103 if(b.email==="1"){
104 b.cx.ff='email';
105 b.cx.delete=b.delete;
106 b.cx.mail=v.mail;
107 b.cx.execute=b.execute;
108 b.cx.query=b.sql;
109 s.cx(b.cx);
110 }
111 if(b.execute&&b.execute!==""){
112 s.cx({f:'filters',ff:'execute',execute:b.execute,time:moment()});
113 }
114 }
115 })
116
117 }
118 })
119}
120s.checkForOrphanedFiles=function(v){
121 if(config.cron.deleteOrphans===true){
122 e={};
123 sql.query('SELECT * FROM Monitors WHERE ke=?',[v.ke],function(arr,b) {
124 b.forEach(function(mon,m){
125 mon.dir=s.
126 fs.readdir(s.getVideoDirectory(mon), function(err, items) {
127 e.query=[];
128 e.filesFound=[mon.ke,mon.mid];
129 if(items&&items.length>0){
130 items.forEach(function(v,n){
131 e.query.push('time=?')
132 e.filesFound.push(s.nameToTime(v))
133 })
134 sql.query('SELECT * FROM Videos WHERE ke=? AND mid=? AND ('+e.query.join(' OR ')+')',e.filesFound,function(arr,r) {
135 if(!r){r=[]};
136 e.foundSQLrows=[];
137 r.forEach(function(v,n){
138 v.index=e.filesFound.indexOf(s.moment(v.time,'YYYY-MM-DD HH:mm:ss'));
139 if(v.index>-1){
140 delete(items[v.index-2]);
141 }
142 });
143 items.forEach(function(v,n){
144 if(v&&v!==null){
145 exec('rm '+s.getVideoDirectory(mon)+v);
146 }
147 })
148 })
149 }
150 })
151 });
152 });
153 }
154}
155s.cron=function(){
156 x={};
157 s.cx({f:'start',time:moment()})
158 sql.query('SELECT ke,uid,details,mail FROM Users WHERE details NOT LIKE \'%"sub"%\'', function(arr,r) {
159 if(r&&r[0]){
160 arr={};
161 r.forEach(function(v){
162 if(!arr[v.ke]){arr[v.ke]=0;}else{return false;}
163 //set permissions
164 v.d=JSON.parse(v.details);
165 //size
166 if(!v.d.size||v.d.size==''){v.d.size=10000}else{v.d.size=parseFloat(v.d.size)};
167 //days to keep videos
168 if(!v.d.days||v.d.days==''){v.d.days=5}else{v.d.days=parseFloat(v.d.days)};
169 //purge logs
170 if(!v.d.log_days||v.d.log_days==''){v.d.log_days=10}else{v.d.log_days=parseFloat(v.d.log_days)};
171 if(config.cron.deleteLogs===true&&v.d.log_days!==0){
172 sql.query("DELETE FROM Logs WHERE ke=? AND `time` < DATE_SUB(NOW(), INTERVAL ? DAY)",[v.ke,v.d.log_days],function(err,rrr){
173 if(err)return console.log(err);
174 s.cx({f:'deleteLogs',msg:rrr.affectedRows+' SQL rows older than '+v.d.log_days+' days deleted',ke:v.ke,time:moment()})
175 })
176 }
177 //purge events
178 if(!v.d.event_days||v.d.event_days==''){v.d.event_days=10}else{v.d.event_days=parseFloat(v.d.event_days)};
179 if(config.cron.deleteEvents===true&&v.d.event_days!==0){
180 sql.query("DELETE FROM Events WHERE ke=? AND `time` < DATE_SUB(NOW(), INTERVAL ? DAY)",[v.ke,v.d.event_days],function(err,rrr){
181 if(err)return console.log(err);
182 s.cx({f:'deleteEvents',msg:rrr.affectedRows+' SQL rows older than '+v.d.event_days+' days deleted',ke:v.ke,time:moment()})
183 })
184 }
185 //filters
186 if(!v.d.filters||v.d.filters==''){
187 v.d.filters={};
188 }
189 //delete old videos with filter
190 if(config.cron.deleteOld===true){
191 v.d.filters.deleteOldByCron={
192 "id":"deleteOldByCron",
193 "name":"deleteOldByCron",
194 "sort_by":"time",
195 "sort_by_direction":"ASC",
196 "limit":"",
197 "enabled":"1",
198 "archive":"0",
199 "email":"0",
200 "delete":"1",
201 "execute":"",
202 "where":[{
203 "p1":"end",
204 "p2":"<",
205 "p3":"NOW() - INTERVAL "+(v.d.days*24)+" HOUR",
206 "p3_type":"function",
207 }]
208 };
209 }
210 s.checkFilterRules(v);
211 //purge SQL rows with no file
212 v.fn=function(){
213 if(s.lock[v.ke]!==1){
214 s.lock[v.ke]=1;
215 es={};
216 sql.query('SELECT * FROM Videos WHERE ke = ? AND status != 0 AND details NOT LIKE \'%"archived":"1"%\' AND time < (NOW() - INTERVAL 10 MINUTE)',[v.ke],function(err,evs){
217 if(evs&&evs[0]){
218 es.del=[];es.ar=[v.ke];
219 evs.forEach(function(ev){
220 ev.dir=s.getVideoDirectory(ev)+s.moment(ev.time)+'.'+ev.ext;
221 if(config.cron.deleteNoVideo===true&&fs.existsSync(ev.dir)!==true){
222 s.video('delete',ev)
223 es.del.push('(mid=? AND time=?)');
224 es.ar.push(ev.mid),es.ar.push(ev.time);
225 s.tx({f:'video_delete',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_'+ev.ke);
226 }
227 });
228 if(config.cron.deleteNoVideo===true){
229 s.cx({f:'deleteNoVideo',msg:es.del.length+' SQL rows with no file deleted',ke:v.ke,time:moment()})
230 }
231 }
232 //delete files when over specified maximum
233 s.lock[v.ke]=0;
234 setTimeout(function(){
235 s.checkForOrphanedFiles(v);
236 },3000)
237 })
238 }
239 };
240 v.fn();
241 })
242 }
243 })
244 s.timeout=setTimeout(function(){
245 s.cron();
246 },parseFloat(config.cron.interval)*60000*60)
247}
248s.cron();
249
250io.on('f',function(d){
251 switch(d.f){
252 case'start':case'restart':
253 clearTimeout(s.timeout);
254 s.cron();
255 break;
256 case'stop':
257 clearTimeout(s.timeout);
258 break;
259 }
260})
261
262
263console.log('Shinobi : cron.js started')
\No newline at end of file