diff --git a/.gitignore b/.gitignore index c008a49d..cd1cef74 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ npm-debug.log shinobi.sqlite package-lock.json dist +._* diff --git a/camera.js b/camera.js index de6657fd..f200e22b 100644 --- a/camera.js +++ b/camera.js @@ -26,7 +26,7 @@ require('./libs/codeTester.js')(s,config,lang) //get version require('./libs/version.js')(s,config,lang) //video processing engine -require('./libs/ffmpeg.js')(s,config,lang,function(ffmpeg){ +require('./libs/ffmpeg.js')(s,config,lang,async function(ffmpeg){ //ffmpeg coProcessor require('./libs/ffmpegCoProcessor.js')(s,config,lang,ffmpeg) //database connection : mysql, sqlite3.. @@ -86,5 +86,7 @@ require('./libs/ffmpeg.js')(s,config,lang,function(ffmpeg){ //scheduling engine require('./libs/scheduler.js')(s,config,lang,app,io) //on-start actions, daemon(s) starter - require('./libs/startup.js')(s,config,lang) + await require('./libs/startup.js')(s,config,lang) + //p2p, commander + require('./libs/commander.js')(s,config,lang) }) diff --git a/libs/commander.js b/libs/commander.js new file mode 100644 index 00000000..b05d545d --- /dev/null +++ b/libs/commander.js @@ -0,0 +1,166 @@ +module.exports = function(s,config,lang,app,io){ + // Shinobi P2P Client Script + if(config.p2pEnabled){ + if(!config.p2pHost)config.p2pHost = 'ws://163.172.180.205:8084' + var p2pClientConnectionStaticName = 'Commander' + var p2pClientConnections = {} + var runningRequests = {} + var request = require('request'); + const socketIOClient = require('socket.io-client'); + var parseJSON = function(string){ + var parsed = string + try{ + parsed = JSON.parse(string) + }catch(err){ + + } + return parsed + } + var createQueryStringFromObject = function(obj){ + var queryString = '' + var keys = Object.keys(obj) + keys.forEach(function(key){ + var value = obj[key] + queryString += `&${key}=${value}` + }) + return queryString + } + var doRequest = function(url,method,data,callback,onDataReceived){ + var requestEndpoint = url + if(method === 'GET' && data){ + requestEndpoint += '?' + createQueryStringFromObject(data) + } + return request(requestEndpoint,{ + method: method, + json: method !== 'GET' ? (data ? data : null) : null + }, function(err,resp,body){ + // var json = parseJSON(body) + if(err)console.error(err,data) + callback(err,body,resp) + }).on('data', function(data) { + onDataReceived(data) + }) + } + var createShinobiSocketConnection = function(connectionId){ + var masterConnectionToMachine = socketIOClient(`ws://localhost:${config.port}`, {transports:['websocket']}) + p2pClientConnections[connectionId || p2pClientConnectionStaticName] = masterConnectionToMachine + return masterConnectionToMachine + } + // + const createSocketConnections = () => { + console.log(`Connecting to ${config.p2pHost}`) + const connectionToP2PServer = socketIOClient(config.p2pHost, {transports:['websocket']}); + if(!config.p2pApiKey){ + console.log(`Please fill 'p2pApiKey' in your conf.json.`) + } + if(!config.p2pGroupId){ + console.log(`Please fill 'p2pGroupId' in your conf.json.`) + } + config.machineId = config.machineId || s.gid(20) + connectionToP2PServer.on('connect',function(){ + console.log(`Connected ${config.p2pHost}`) + connectionToP2PServer.emit('initMachine',{ + port: config.port, + apiKey: config.p2pApiKey, + groupId: config.p2pGroupId, + targetUserId: config.p2pTargetUserId, + targetGroupId: config.p2pTargetGroupId, + machineId: config.machineId, + subscriptionId: config.subscriptionId || 'notActivated' + }) + }) + connectionToP2PServer.on('httpClose',function(requestId){ + if(runningRequests[requestId] && runningRequests[requestId].abort){ + runningRequests[requestId].abort() + } + }) + connectionToP2PServer.on('http',function(rawRequest){ + runningRequests[rawRequest.rid] = doRequest( + rawRequest.url, + rawRequest.method, + rawRequest.data, + function(err,json,resp){ + connectionToP2PServer.emit('httpResponse',{ + err: err, + json: rawRequest.bodyOnEnd ? json : null, + rid: rawRequest.rid + }) + }, + function(data){ + if(!rawRequest.bodyOnEnd)connectionToP2PServer.emit('httpResponseChunk',{ + data: data, + rid: rawRequest.rid + }) + }) + }) + const masterConnectionToMachine = createShinobiSocketConnection() + masterConnectionToMachine.on('connect',function(){ + masterConnectionToMachine.emit('f',{ + f: 'init', + ke: config.p2pTargetGroupId, + uid: config.p2pTargetUserId + }) + }) + masterConnectionToMachine.on('f',function(data){ + connectionToP2PServer.emit('f',data) + }) + + connectionToP2PServer.on('wsInit',function(rawRequest){ + console.log('wsInit') + var user = rawRequest.user + var clientConnectionToMachine = createShinobiSocketConnection(rawRequest.cnid) + connectionToP2PServer.on('f',function(rawRequest){ + clientConnectionToMachine.emit('f',rawRequest.data) + }) + clientConnectionToMachine.on('connect',function(){ + clientConnectionToMachine.emit('f',{ + f: 'init', + ke: user.ke, + uid: user.uid, + }) + }) + clientConnectionToMachine.on('f',function(data){ + connectionToP2PServer.emit('f',{data: data, cnid: rawRequest.cnid}) + }) + }); + connectionToP2PServer.on('wsDestroy',function(rawRequest){ + if(p2pClientConnections[rawRequest.cnid]){ + p2pClientConnections[rawRequest.cnid].disconnect(); + } + delete(p2pClientConnections[rawRequest.cnid]) + }); + + connectionToP2PServer.on('allowDisconnect',function(bool){ + connectionToP2PServer.allowDisconnect = true; + connectionToP2PServer.disconnect() + console.log('Server said to go away') + }); + const onDisconnect = () => { + console.log('disconnected p2p') + if(!connectionToP2PServer.allowDisconnect){ + setTimeout(function(){ + connectionToP2PServer.connect() + },3000) + } + } + connectionToP2PServer.on('error',onDisconnect) + connectionToP2PServer.on('disconnect',onDisconnect) + } + if(config.p2pTargetGroupId && config.p2pTargetUserId){ + createSocketConnections() + }else{ + s.knexQuery({ + action: "select", + columns: "ke,uid", + table: "Users", + where: [], + limit: 1 + },(err,r) => { + const firstUser = r[0] + config.p2pTargetUserId = firstUser.uid + config.p2pTargetGroupId = firstUser.ke + createSocketConnections() + }) + } + } +} diff --git a/libs/socketio.js b/libs/socketio.js index 34bddd9d..731e4c7a 100644 --- a/libs/socketio.js +++ b/libs/socketio.js @@ -51,17 +51,21 @@ module.exports = function(s,config,lang,io){ } } - const streamConnectionAuthentication = (options) => { + const streamConnectionAuthentication = (options,ipAddress) => { return new Promise( (resolve,reject) => { + var isInternal = false + if(ipAddress.indexOf('localhost') > -1 || ipAddress.indexOf('127.0.0.1') > -1){ + isInternal = true + } + const baseWheres = [ + ['ke','=',options.ke], + ['uid','=',options.uid], + ] s.knexQuery({ action: "select", columns: "ke,uid,auth,mail,details", table: "Users", - where: [ - ['ke','=',options.ke], - ['auth','=',options.auth], - ['uid','=',options.uid], - ] + where: baseWheres.concat(!isInternal ? [['auth','=',options.auth]] : []) },(err,r) => { if(r&&r[0]){ resolve(r) @@ -70,11 +74,7 @@ module.exports = function(s,config,lang,io){ action: "select", columns: "*", table: "API", - where: [ - ['ke','=',options.ke], - ['code','=',options.auth], - ['uid','=',options.uid], - ] + where: baseWheres.concat(!isInternal ? [['code','=',options.auth]] : []) },(err,r) => { if(r && r[0]){ r = r[0] @@ -165,7 +165,7 @@ module.exports = function(s,config,lang,io){ if(s.group[d.ke]&&s.group[d.ke].users&&s.group[d.ke].users[d.auth]){ onSuccess(s.group[d.ke].users[d.auth]); }else{ - streamConnectionAuthentication(d).then(onSuccess).catch(onFail) + streamConnectionAuthentication(d,cn.ip).then(onSuccess).catch(onFail) } }) //unique Base64 socket stream @@ -198,7 +198,7 @@ module.exports = function(s,config,lang,io){ if(s.group[d.ke]&&s.group[d.ke].users&&s.group[d.ke].users[d.auth]){ onSuccess(s.group[d.ke].users[d.auth]); }else{ - streamConnectionAuthentication(d).then(onSuccess).catch(onFail) + streamConnectionAuthentication(d,cn.ip).then(onSuccess).catch(onFail) } }) //unique FLV socket stream @@ -231,7 +231,7 @@ module.exports = function(s,config,lang,io){ if(s.group[d.ke] && s.group[d.ke].users && s.group[d.ke].users[d.auth]){ onSuccess(s.group[d.ke].users[d.auth]); }else{ - streamConnectionAuthentication(d).then(onSuccess).catch(onFail) + streamConnectionAuthentication(d,cn.ip).then(onSuccess).catch(onFail) } }) //unique MP4 socket stream @@ -312,7 +312,7 @@ module.exports = function(s,config,lang,io){ if(s.group[d.ke]&&s.group[d.ke].users&&s.group[d.ke].users[d.auth]){ onSuccess(s.group[d.ke].users[d.auth]); }else{ - streamConnectionAuthentication(d).then(onSuccess).catch(onFail) + streamConnectionAuthentication(d,cn.ip).then(onSuccess).catch(onFail) } }) //main socket control functions @@ -393,7 +393,8 @@ module.exports = function(s,config,lang,io){ extender(r,cn,d,tx) }) } - streamConnectionAuthentication(d).then(onSuccess).catch(onFail) + console.log(cn.ip) + streamConnectionAuthentication(d,cn.ip).then(onSuccess).catch(onFail) return; } if((d.id||d.uid||d.mid)&&cn.ke){ diff --git a/libs/startup.js b/libs/startup.js index cf4bcf5d..8cb64499 100644 --- a/libs/startup.js +++ b/libs/startup.js @@ -6,443 +6,446 @@ var crypto = require('crypto'); var exec = require('child_process').exec; var execSync = require('child_process').execSync; module.exports = function(s,config,lang,io){ - var checkedAdminUsers = {} - console.log('FFmpeg version : '+s.ffmpegVersion) - console.log('Node.js version : '+process.version) - s.processReady = function(){ - delete(checkedAdminUsers) - s.systemLog(lang.startUpText5) - s.onProcessReadyExtensions.forEach(function(extender){ - extender(true) - }) - process.send('ready') - } - var checkForTerminalCommands = function(callback){ - var next = function(){ - if(callback)callback() - } - if(!s.isWin && s.packageJson.mainDirectory !== '.'){ - var etcPath = '/etc/shinobisystems/cctv.txt' - fs.stat(etcPath,function(err,stat){ - if(err || !stat){ - exec('node '+ s.mainDirectory + '/INSTALL/terminalCommands.js',function(err){ - if(err)console.log(err) - }) - } - next() + return new Promise((resolve, reject) => { + var checkedAdminUsers = {} + console.log('FFmpeg version : '+s.ffmpegVersion) + console.log('Node.js version : '+process.version) + s.processReady = function(){ + delete(checkedAdminUsers) + resolve() + s.systemLog(lang.startUpText5) + s.onProcessReadyExtensions.forEach(function(extender){ + extender(true) }) - }else{ - next() + process.send('ready') } - } - var loadedAccounts = [] - var foundMonitors = [] - var loadMonitors = function(callback){ - s.beforeMonitorsLoadedOnStartupExtensions.forEach(function(extender){ - extender() - }) - s.systemLog(lang.startUpText4) - //preliminary monitor start - s.knexQuery({ - action: "select", - columns: "*", - table: "Monitors", - },function(err,monitors) { - foundMonitors = monitors - if(err){s.systemLog(err)} - if(monitors && monitors[0]){ - var didNotLoad = 0 - var loadCompleted = 0 - var orphanedVideosForMonitors = {} - var loadMonitor = function(monitor){ - const checkAnother = function(){ - ++loadCompleted - if(monitors[loadCompleted]){ - loadMonitor(monitors[loadCompleted]) + var checkForTerminalCommands = function(callback){ + var next = function(){ + if(callback)callback() + } + if(!s.isWin && s.packageJson.mainDirectory !== '.'){ + var etcPath = '/etc/shinobisystems/cctv.txt' + fs.stat(etcPath,function(err,stat){ + if(err || !stat){ + exec('node '+ s.mainDirectory + '/INSTALL/terminalCommands.js',function(err){ + if(err)console.log(err) + }) + } + next() + }) + }else{ + next() + } + } + var loadedAccounts = [] + var foundMonitors = [] + var loadMonitors = function(callback){ + s.beforeMonitorsLoadedOnStartupExtensions.forEach(function(extender){ + extender() + }) + s.systemLog(lang.startUpText4) + //preliminary monitor start + s.knexQuery({ + action: "select", + columns: "*", + table: "Monitors", + },function(err,monitors) { + foundMonitors = monitors + if(err){s.systemLog(err)} + if(monitors && monitors[0]){ + var didNotLoad = 0 + var loadCompleted = 0 + var orphanedVideosForMonitors = {} + var loadMonitor = function(monitor){ + const checkAnother = function(){ + ++loadCompleted + if(monitors[loadCompleted]){ + loadMonitor(monitors[loadCompleted]) + }else{ + if(didNotLoad > 0)console.log(`${didNotLoad} Monitor${didNotLoad === 1 ? '' : 's'} not loaded because Admin user does not exist for them. It may have been deleted.`); + callback() + } + } + if(checkedAdminUsers[monitor.ke]){ + setTimeout(function(){ + if(!orphanedVideosForMonitors[monitor.ke])orphanedVideosForMonitors[monitor.ke] = {} + if(!orphanedVideosForMonitors[monitor.ke][monitor.mid])orphanedVideosForMonitors[monitor.ke][monitor.mid] = 0 + s.initiateMonitorObject(monitor) + s.group[monitor.ke].rawMonitorConfigurations[monitor.mid] = monitor + s.sendMonitorStatus({id:monitor.mid,ke:monitor.ke,status:'Stopped'}); + var monObj = Object.assign(monitor,{id : monitor.mid}) + s.camera(monitor.mode,monObj) + checkAnother() + },1000) }else{ - if(didNotLoad > 0)console.log(`${didNotLoad} Monitor${didNotLoad === 1 ? '' : 's'} not loaded because Admin user does not exist for them. It may have been deleted.`); - callback() + ++didNotLoad + checkAnother() } } - if(checkedAdminUsers[monitor.ke]){ - setTimeout(function(){ - if(!orphanedVideosForMonitors[monitor.ke])orphanedVideosForMonitors[monitor.ke] = {} - if(!orphanedVideosForMonitors[monitor.ke][monitor.mid])orphanedVideosForMonitors[monitor.ke][monitor.mid] = 0 - s.initiateMonitorObject(monitor) - s.group[monitor.ke].rawMonitorConfigurations[monitor.mid] = monitor - s.sendMonitorStatus({id:monitor.mid,ke:monitor.ke,status:'Stopped'}); - var monObj = Object.assign(monitor,{id : monitor.mid}) - s.camera(monitor.mode,monObj) - checkAnother() - },1000) - }else{ - ++didNotLoad - checkAnother() - } + loadMonitor(monitors[loadCompleted]) + }else{ + callback() } - loadMonitor(monitors[loadCompleted]) + }) + } + var checkForOrphanedVideos = function(callback){ + var monitors = foundMonitors + if(monitors && monitors[0]){ + var loadCompleted = 0 + var orphanedVideosForMonitors = {} + var checkForOrphanedVideosForMonitor = function(monitor){ + if(!orphanedVideosForMonitors[monitor.ke])orphanedVideosForMonitors[monitor.ke] = {} + if(!orphanedVideosForMonitors[monitor.ke][monitor.mid])orphanedVideosForMonitors[monitor.ke][monitor.mid] = 0 + s.orphanedVideoCheck(monitor,null,function(orphanedFilesCount){ + if(orphanedFilesCount){ + orphanedVideosForMonitors[monitor.ke][monitor.mid] += orphanedFilesCount + } + ++loadCompleted + if(monitors[loadCompleted]){ + checkForOrphanedVideosForMonitor(monitors[loadCompleted]) + }else{ + s.systemLog(lang.startUpText6+' : '+s.s(orphanedVideosForMonitors)) + delete(foundMonitors) + callback() + } + }) + } + checkForOrphanedVideosForMonitor(monitors[loadCompleted]) }else{ callback() } - }) - } - var checkForOrphanedVideos = function(callback){ - var monitors = foundMonitors - if(monitors && monitors[0]){ - var loadCompleted = 0 - var orphanedVideosForMonitors = {} - var checkForOrphanedVideosForMonitor = function(monitor){ - if(!orphanedVideosForMonitors[monitor.ke])orphanedVideosForMonitors[monitor.ke] = {} - if(!orphanedVideosForMonitors[monitor.ke][monitor.mid])orphanedVideosForMonitors[monitor.ke][monitor.mid] = 0 - s.orphanedVideoCheck(monitor,null,function(orphanedFilesCount){ - if(orphanedFilesCount){ - orphanedVideosForMonitors[monitor.ke][monitor.mid] += orphanedFilesCount - } - ++loadCompleted - if(monitors[loadCompleted]){ - checkForOrphanedVideosForMonitor(monitors[loadCompleted]) - }else{ - s.systemLog(lang.startUpText6+' : '+s.s(orphanedVideosForMonitors)) - delete(foundMonitors) - callback() - } - }) - } - checkForOrphanedVideosForMonitor(monitors[loadCompleted]) - }else{ - callback() } - } - var loadDiskUseForUser = function(user,callback){ - s.systemLog(user.mail+' : '+lang.startUpText0) - var userDetails = JSON.parse(user.details) - s.group[user.ke].sizeLimit = parseFloat(userDetails.size) || 10000 - s.group[user.ke].sizeLimitVideoPercent = parseFloat(userDetails.size_video_percent) || 90 - s.group[user.ke].sizeLimitTimelapseFramesPercent = parseFloat(userDetails.size_timelapse_percent) || 10 - s.knexQuery({ - action: "select", - columns: "*", - table: "Videos", - where: [ - ['ke','=',user.ke], - ['status','!=',0], - ] - },function(err,videos) { + var loadDiskUseForUser = function(user,callback){ + s.systemLog(user.mail+' : '+lang.startUpText0) + var userDetails = JSON.parse(user.details) + s.group[user.ke].sizeLimit = parseFloat(userDetails.size) || 10000 + s.group[user.ke].sizeLimitVideoPercent = parseFloat(userDetails.size_video_percent) || 90 + s.group[user.ke].sizeLimitTimelapseFramesPercent = parseFloat(userDetails.size_timelapse_percent) || 10 s.knexQuery({ action: "select", columns: "*", - table: "Timelapse Frames", - where: [ - ['ke','=',user.ke], - ] - },function(err,timelapseFrames) { - s.knexQuery({ - action: "select", - columns: "*", - table: "Files", - where: [ - ['ke','=',user.ke], - ] - },function(err,files) { - var usedSpaceVideos = 0 - var usedSpaceTimelapseFrames = 0 - var usedSpaceFilebin = 0 - var addStorageData = { - files: [], - videos: [], - timelapeFrames: [], - } - if(videos && videos[0]){ - videos.forEach(function(video){ - video.details = s.parseJSON(video.details) - if(!video.details.dir){ - usedSpaceVideos += video.size - }else{ - addStorageData.videos.push(video) - } - }) - } - if(timelapseFrames && timelapseFrames[0]){ - timelapseFrames.forEach(function(frame){ - frame.details = s.parseJSON(frame.details) - if(!frame.details.dir){ - usedSpaceTimelapseFrames += frame.size - }else{ - addStorageData.timelapeFrames.push(frame) - } - }) - } - if(files && files[0]){ - files.forEach(function(file){ - file.details = s.parseJSON(file.details) - if(!file.details.dir){ - usedSpaceFilebin += file.size - }else{ - addStorageData.files.push(file) - } - }) - } - s.group[user.ke].usedSpace = (usedSpaceVideos + usedSpaceTimelapseFrames + usedSpaceFilebin) / 1048576 - s.group[user.ke].usedSpaceVideos = usedSpaceVideos / 1048576 - s.group[user.ke].usedSpaceFilebin = usedSpaceFilebin / 1048576 - s.group[user.ke].usedSpaceTimelapseFrames = usedSpaceTimelapseFrames / 1048576 - loadAddStorageDiskUseForUser(user,addStorageData,function(){ - callback() - }) - }) - }) - }) - } - var loadCloudDiskUseForUser = function(user,callback){ - var userDetails = JSON.parse(user.details) - user.cloudDiskUse = {} - user.size = 0 - user.limit = userDetails.size - s.cloudDisksLoaded.forEach(function(storageType){ - user.cloudDiskUse[storageType] = { - usedSpace : 0, - firstCount : 0 - } - if(s.cloudDiskUseStartupExtensions[storageType])s.cloudDiskUseStartupExtensions[storageType](user,userDetails) - }) - var loadCloudVideos = function(callback){ - s.knexQuery({ - action: "select", - columns: "*", - table: "Cloud Videos", + table: "Videos", where: [ ['ke','=',user.ke], ['status','!=',0], ] },function(err,videos) { - if(videos && videos[0]){ - videos.forEach(function(video){ - var storageType = JSON.parse(video.details).type - if(!storageType)storageType = 's3' - var videoSize = video.size / 1048576 - user.cloudDiskUse[storageType].usedSpace += videoSize - user.cloudDiskUse[storageType].usedSpaceVideos += videoSize - ++user.cloudDiskUse[storageType].firstCount + s.knexQuery({ + action: "select", + columns: "*", + table: "Timelapse Frames", + where: [ + ['ke','=',user.ke], + ] + },function(err,timelapseFrames) { + s.knexQuery({ + action: "select", + columns: "*", + table: "Files", + where: [ + ['ke','=',user.ke], + ] + },function(err,files) { + var usedSpaceVideos = 0 + var usedSpaceTimelapseFrames = 0 + var usedSpaceFilebin = 0 + var addStorageData = { + files: [], + videos: [], + timelapeFrames: [], + } + if(videos && videos[0]){ + videos.forEach(function(video){ + video.details = s.parseJSON(video.details) + if(!video.details.dir){ + usedSpaceVideos += video.size + }else{ + addStorageData.videos.push(video) + } + }) + } + if(timelapseFrames && timelapseFrames[0]){ + timelapseFrames.forEach(function(frame){ + frame.details = s.parseJSON(frame.details) + if(!frame.details.dir){ + usedSpaceTimelapseFrames += frame.size + }else{ + addStorageData.timelapeFrames.push(frame) + } + }) + } + if(files && files[0]){ + files.forEach(function(file){ + file.details = s.parseJSON(file.details) + if(!file.details.dir){ + usedSpaceFilebin += file.size + }else{ + addStorageData.files.push(file) + } + }) + } + s.group[user.ke].usedSpace = (usedSpaceVideos + usedSpaceTimelapseFrames + usedSpaceFilebin) / 1048576 + s.group[user.ke].usedSpaceVideos = usedSpaceVideos / 1048576 + s.group[user.ke].usedSpaceFilebin = usedSpaceFilebin / 1048576 + s.group[user.ke].usedSpaceTimelapseFrames = usedSpaceTimelapseFrames / 1048576 + loadAddStorageDiskUseForUser(user,addStorageData,function(){ + callback() + }) }) - s.cloudDisksLoaded.forEach(function(storageType){ - var firstCount = user.cloudDiskUse[storageType].firstCount - s.systemLog(user.mail+' : '+lang.startUpText1+' : '+firstCount,storageType,user.cloudDiskUse[storageType].usedSpace) - delete(user.cloudDiskUse[storageType].firstCount) - }) - } - callback() + }) }) } - var loadCloudTimelapseFrames = function(callback){ + var loadCloudDiskUseForUser = function(user,callback){ + var userDetails = JSON.parse(user.details) + user.cloudDiskUse = {} + user.size = 0 + user.limit = userDetails.size + s.cloudDisksLoaded.forEach(function(storageType){ + user.cloudDiskUse[storageType] = { + usedSpace : 0, + firstCount : 0 + } + if(s.cloudDiskUseStartupExtensions[storageType])s.cloudDiskUseStartupExtensions[storageType](user,userDetails) + }) + var loadCloudVideos = function(callback){ + s.knexQuery({ + action: "select", + columns: "*", + table: "Cloud Videos", + where: [ + ['ke','=',user.ke], + ['status','!=',0], + ] + },function(err,videos) { + if(videos && videos[0]){ + videos.forEach(function(video){ + var storageType = JSON.parse(video.details).type + if(!storageType)storageType = 's3' + var videoSize = video.size / 1048576 + user.cloudDiskUse[storageType].usedSpace += videoSize + user.cloudDiskUse[storageType].usedSpaceVideos += videoSize + ++user.cloudDiskUse[storageType].firstCount + }) + s.cloudDisksLoaded.forEach(function(storageType){ + var firstCount = user.cloudDiskUse[storageType].firstCount + s.systemLog(user.mail+' : '+lang.startUpText1+' : '+firstCount,storageType,user.cloudDiskUse[storageType].usedSpace) + delete(user.cloudDiskUse[storageType].firstCount) + }) + } + callback() + }) + } + var loadCloudTimelapseFrames = function(callback){ + s.knexQuery({ + action: "select", + columns: "*", + table: "Cloud Timelapse Frames", + where: [ + ['ke','=',user.ke], + ] + },function(err,frames) { + if(frames && frames[0]){ + frames.forEach(function(frame){ + var storageType = JSON.parse(frame.details).type + if(!storageType)storageType = 's3' + var frameSize = frame.size / 1048576 + user.cloudDiskUse[storageType].usedSpace += frameSize + user.cloudDiskUse[storageType].usedSpaceTimelapseFrames += frameSize + }) + } + callback() + }) + } + loadCloudVideos(function(){ + loadCloudTimelapseFrames(function(){ + s.group[user.ke].cloudDiskUse = user.cloudDiskUse + callback() + }) + }) + } + var loadAddStorageDiskUseForUser = function(user,data,callback){ + var videos = data.videos + var timelapseFrames = data.timelapseFrames + var files = data.files + var userDetails = JSON.parse(user.details) + var userAddStorageData = s.parseJSON(userDetails.addStorage) || {} + var currentStorageNumber = 0 + var readStorageArray = function(){ + var storage = s.listOfStorage[currentStorageNumber] + if(!storage){ + //done all checks, move on to next user + callback() + return + } + var path = storage.value + if(path === ''){ + ++currentStorageNumber + readStorageArray() + return + } + var storageId = path + var storageData = userAddStorageData[storageId] || {} + if(!s.group[user.ke].addStorageUse[storageId])s.group[user.ke].addStorageUse[storageId] = {} + var storageIndex = s.group[user.ke].addStorageUse[storageId] + storageIndex.name = storage.name + storageIndex.path = path + storageIndex.usedSpace = 0 + storageIndex.sizeLimit = parseFloat(storageData.limit) || parseFloat(userDetails.size) || 10000 + var usedSpaceVideos = 0 + var usedSpaceTimelapseFrames = 0 + var usedSpaceFilebin = 0 + if(videos && videos[0]){ + videos.forEach(function(video){ + if(video.details.dir === storage.value){ + usedSpaceVideos += video.size + } + }) + } + if(timelapseFrames && timelapseFrames[0]){ + timelapseFrames.forEach(function(frame){ + if(video.details.dir === storage.value){ + usedSpaceTimelapseFrames += frame.size + } + }) + } + if(files && files[0]){ + files.forEach(function(file){ + if(video.details.dir === storage.value){ + usedSpaceFilebin += file.size + } + }) + } + storageIndex.usedSpace = (usedSpaceVideos + usedSpaceTimelapseFrames + usedSpaceFilebin) / 1048576 + storageIndex.usedSpaceVideos = usedSpaceVideos / 1048576 + storageIndex.usedSpaceFilebin = usedSpaceFilebin / 1048576 + storageIndex.usedSpaceTimelapseFrames = usedSpaceTimelapseFrames / 1048576 + s.systemLog(user.mail+' : '+path+' : '+videos.length,storageIndex.usedSpace) + ++currentStorageNumber + readStorageArray() + } + readStorageArray() + } + var loadAdminUsers = function(callback){ + //get current disk used for each isolated account (admin user) on startup s.knexQuery({ action: "select", columns: "*", - table: "Cloud Timelapse Frames", + table: "Users", where: [ - ['ke','=',user.ke], + ['details','NOT LIKE','%"sub"%'] ] - },function(err,frames) { - if(frames && frames[0]){ - frames.forEach(function(frame){ - var storageType = JSON.parse(frame.details).type - if(!storageType)storageType = 's3' - var frameSize = frame.size / 1048576 - user.cloudDiskUse[storageType].usedSpace += frameSize - user.cloudDiskUse[storageType].usedSpaceTimelapseFrames += frameSize - }) - } - callback() - }) - } - loadCloudVideos(function(){ - loadCloudTimelapseFrames(function(){ - s.group[user.ke].cloudDiskUse = user.cloudDiskUse - callback() - }) - }) - } - var loadAddStorageDiskUseForUser = function(user,data,callback){ - var videos = data.videos - var timelapseFrames = data.timelapseFrames - var files = data.files - var userDetails = JSON.parse(user.details) - var userAddStorageData = s.parseJSON(userDetails.addStorage) || {} - var currentStorageNumber = 0 - var readStorageArray = function(){ - var storage = s.listOfStorage[currentStorageNumber] - if(!storage){ - //done all checks, move on to next user - callback() - return - } - var path = storage.value - if(path === ''){ - ++currentStorageNumber - readStorageArray() - return - } - var storageId = path - var storageData = userAddStorageData[storageId] || {} - if(!s.group[user.ke].addStorageUse[storageId])s.group[user.ke].addStorageUse[storageId] = {} - var storageIndex = s.group[user.ke].addStorageUse[storageId] - storageIndex.name = storage.name - storageIndex.path = path - storageIndex.usedSpace = 0 - storageIndex.sizeLimit = parseFloat(storageData.limit) || parseFloat(userDetails.size) || 10000 - var usedSpaceVideos = 0 - var usedSpaceTimelapseFrames = 0 - var usedSpaceFilebin = 0 - if(videos && videos[0]){ - videos.forEach(function(video){ - if(video.details.dir === storage.value){ - usedSpaceVideos += video.size - } - }) - } - if(timelapseFrames && timelapseFrames[0]){ - timelapseFrames.forEach(function(frame){ - if(video.details.dir === storage.value){ - usedSpaceTimelapseFrames += frame.size - } - }) - } - if(files && files[0]){ - files.forEach(function(file){ - if(video.details.dir === storage.value){ - usedSpaceFilebin += file.size - } - }) - } - storageIndex.usedSpace = (usedSpaceVideos + usedSpaceTimelapseFrames + usedSpaceFilebin) / 1048576 - storageIndex.usedSpaceVideos = usedSpaceVideos / 1048576 - storageIndex.usedSpaceFilebin = usedSpaceFilebin / 1048576 - storageIndex.usedSpaceTimelapseFrames = usedSpaceTimelapseFrames / 1048576 - s.systemLog(user.mail+' : '+path+' : '+videos.length,storageIndex.usedSpace) - ++currentStorageNumber - readStorageArray() - } - readStorageArray() - } - var loadAdminUsers = function(callback){ - //get current disk used for each isolated account (admin user) on startup - s.knexQuery({ - action: "select", - columns: "*", - table: "Users", - where: [ - ['details','NOT LIKE','%"sub"%'] - ] - },function(err,users) { - if(users && users[0]){ - users.forEach(function(user){ - checkedAdminUsers[user.ke] = user - }) - var loadLocalDiskUse = function(callback){ - var count = users.length - var countFinished = 0 + },function(err,users) { + if(users && users[0]){ users.forEach(function(user){ - s.loadGroup(user) - s.loadGroupApps(user) - loadedAccounts.push(user.ke) - loadDiskUseForUser(user,function(){ - ++countFinished - if(countFinished === count){ - callback() - } + checkedAdminUsers[user.ke] = user + }) + var loadLocalDiskUse = function(callback){ + var count = users.length + var countFinished = 0 + users.forEach(function(user){ + s.loadGroup(user) + s.loadGroupApps(user) + loadedAccounts.push(user.ke) + loadDiskUseForUser(user,function(){ + ++countFinished + if(countFinished === count){ + callback() + } + }) + }) + } + var loadCloudDiskUse = function(callback){ + var count = users.length + var countFinished = 0 + users.forEach(function(user){ + loadCloudDiskUseForUser(user,function(){ + ++countFinished + if(countFinished === count){ + callback() + } + }) + }) + } + loadLocalDiskUse(function(){ + loadCloudDiskUse(function(){ + callback() }) }) + }else{ + s.processReady() } - var loadCloudDiskUse = function(callback){ - var count = users.length - var countFinished = 0 - users.forEach(function(user){ - loadCloudDiskUseForUser(user,function(){ - ++countFinished - if(countFinished === count){ - callback() - } - }) - }) - } - loadLocalDiskUse(function(){ - loadCloudDiskUse(function(){ - callback() - }) + }) + } + config.userHasSubscribed = false + var checkSubscription = function(callback){ + var subscriptionFailed = function(){ + console.error('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!') + console.error('This Install of Shinobi is NOT Activated') + console.error('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!') + console.log('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!') + s.systemLog('This Install of Shinobi is NOT Activated') + console.log('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!') + console.log('https://licenses.shinobi.video/subscribe') + } + if(config.subscriptionId && config.subscriptionId !== 'sub_XXXXXXXXXXXX'){ + var url = 'https://licenses.shinobi.video/subscribe/check?subscriptionId=' + config.subscriptionId + request(url,{ + method: 'GET', + timeout: 30000 + }, function(err,resp,body){ + var json = s.parseJSON(body) + if(err)console.log(err,json) + var hasSubcribed = json && !!json.ok + config.userHasSubscribed = hasSubcribed + callback(hasSubcribed) + if(config.userHasSubscribed){ + s.systemLog('This Install of Shinobi is Activated') + if(!json.expired){ + s.systemLog(`This License expires on ${json.timeExpires}`) + } + }else{ + subscriptionFailed() + } }) }else{ - s.processReady() + subscriptionFailed() + callback(false) } - }) - } - config.userHasSubscribed = false - var checkSubscription = function(callback){ - var subscriptionFailed = function(){ - console.error('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!') - console.error('This Install of Shinobi is NOT Activated') - console.error('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!') - console.log('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!') - s.systemLog('This Install of Shinobi is NOT Activated') - console.log('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!') - console.log('https://licenses.shinobi.video/subscribe') } - if(config.subscriptionId && config.subscriptionId !== 'sub_XXXXXXXXXXXX'){ - var url = 'https://licenses.shinobi.video/subscribe/check?subscriptionId=' + config.subscriptionId - request(url,{ - method: 'GET', - timeout: 30000 - }, function(err,resp,body){ - var json = s.parseJSON(body) - if(err)console.log(err,json) - var hasSubcribed = json && !!json.ok - config.userHasSubscribed = hasSubcribed - callback(hasSubcribed) - if(config.userHasSubscribed){ - s.systemLog('This Install of Shinobi is Activated') - if(!json.expired){ - s.systemLog(`This License expires on ${json.timeExpires}`) - } - }else{ - subscriptionFailed() - } - }) - }else{ - subscriptionFailed() - callback(false) + //check disk space every 20 minutes + if(config.autoDropCache===true){ + setInterval(function(){ + exec('echo 3 > /proc/sys/vm/drop_caches',{detached: true}) + },60000*20) } - } - //check disk space every 20 minutes - if(config.autoDropCache===true){ - setInterval(function(){ - exec('echo 3 > /proc/sys/vm/drop_caches',{detached: true}) - },60000*20) - } - if(config.childNodes.mode !== 'child'){ - //master node - startup functions - //hourly check to see if sizePurge has failed to unlock - //checks to see if request count is the number of monitors + 10 - s.checkForStalePurgeLocks() - //run prerequsite queries, load users and monitors - //sql/database connection with knex - s.databaseEngine = require('knex')(s.databaseOptions) - //run prerequsite queries - s.preQueries() - setTimeout(() => { - //check for subscription - checkSubscription(function(){ - //check terminal commander - checkForTerminalCommands(function(){ - //load administrators (groups) - loadAdminUsers(function(){ - //load monitors (for groups) - loadMonitors(function(){ - //check for orphaned videos - checkForOrphanedVideos(async () => { - s.processReady() + if(config.childNodes.mode !== 'child'){ + //master node - startup functions + //hourly check to see if sizePurge has failed to unlock + //checks to see if request count is the number of monitors + 10 + s.checkForStalePurgeLocks() + //run prerequsite queries, load users and monitors + //sql/database connection with knex + s.databaseEngine = require('knex')(s.databaseOptions) + //run prerequsite queries + s.preQueries() + setTimeout(() => { + //check for subscription + checkSubscription(function(){ + //check terminal commander + checkForTerminalCommands(function(){ + //load administrators (groups) + loadAdminUsers(function(){ + //load monitors (for groups) + loadMonitors(function(){ + //check for orphaned videos + checkForOrphanedVideos(async () => { + s.processReady() + }) }) }) }) }) - }) - },1500) - } + },1500) + } + }) } diff --git a/web/libs/js/dash2.socketio.js b/web/libs/js/dash2.socketio.js index a1406e46..fcf809c9 100644 --- a/web/libs/js/dash2.socketio.js +++ b/web/libs/js/dash2.socketio.js @@ -302,7 +302,6 @@ $.ccio.globalWebsocket=function(d,user){ uid: user.uid, ke: d.ke, id: d.id, - subscriptionId: subscriptionId, // channel: channel }) if(!$.ccio.mon[d.ke+d.id+user.auth_token].ctx||$.ccio.mon[d.ke+d.id+user.auth_token].ctx.length===0){ @@ -703,15 +702,15 @@ $user.ws.on('connect',function (d){ $(document).ready(function(e){ $.ccio.init('id',$user); if(location.search === '?assemble=1'){ - $user.ws.emit('initUser',{ - subscriptionId: subscriptionId, + $user.ws.emit('p2pInitUser',{ user: { ke: $user.ke, mail: $user.mail, auth_token: $user.auth_token, details: $user.details, uid: $user.uid, - } + }, + machineId: machineId }) }else{ $.ccio.cx({f:'init',ke:$user.ke,auth:$user.auth_token,uid:$user.uid}) diff --git a/web/pages/blocks/header.ejs b/web/pages/blocks/header.ejs index 7273598e..d31563ce 100644 --- a/web/pages/blocks/header.ejs +++ b/web/pages/blocks/header.ejs @@ -22,4 +22,4 @@ if(!string){string=''} return string.replace(/'/g,"\\'") }%> - +