Merge branch 'dev' into 'master'
PTZ Improvement, P2P, and Some Critical Fixes See merge request Shinobi-Systems/Shinobi!240merge-requests/256/head ocean-1
commit
cd9c013916
|
@ -12,3 +12,4 @@ npm-debug.log
|
|||
shinobi.sqlite
|
||||
package-lock.json
|
||||
dist
|
||||
._*
|
||||
|
|
|
@ -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)
|
||||
})
|
||||
|
|
11
cron.js
11
cron.js
|
@ -135,6 +135,16 @@ s.sqlQuery = function(query,values,onMoveOn){
|
|||
}
|
||||
})
|
||||
}
|
||||
const cleanSqlWhereObject = (where) => {
|
||||
const newWhere = {}
|
||||
Object.keys(where).forEach((key) => {
|
||||
if(key !== '__separator'){
|
||||
const value = where[key]
|
||||
newWhere[key] = value
|
||||
}
|
||||
})
|
||||
return newWhere
|
||||
}
|
||||
const processSimpleWhereCondition = (dbQuery,where,didOne) => {
|
||||
var whereIsArray = where instanceof Array;
|
||||
if(where[0] === 'or' || where.__separator === 'or'){
|
||||
|
@ -261,7 +271,6 @@ const knexQuery = (options,callback) => {
|
|||
knexError(dbQuery,options,err)
|
||||
}
|
||||
}
|
||||
|
||||
s.debugLog = function(arg1,arg2){
|
||||
if(config.debugLog === true){
|
||||
if(!arg2)arg2 = ''
|
||||
|
|
|
@ -420,6 +420,25 @@ module.exports = function(s,config,lang){
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "detail=onvif_non_standard",
|
||||
"field": lang['Non-Standard ONVIF'],
|
||||
"description": "Is this a Non-Standard ONVIF camera?",
|
||||
"default": "0",
|
||||
"example": "",
|
||||
"form-group-class": "h_onvif_input h_onvif_1",
|
||||
"fieldType": "select",
|
||||
"possible": [
|
||||
{
|
||||
"name": lang.No,
|
||||
"value": "0"
|
||||
},
|
||||
{
|
||||
"name": lang.Yes,
|
||||
"value": "1"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
hidden: true,
|
||||
"name": "detail=onvif_port",
|
||||
|
@ -3608,6 +3627,24 @@ module.exports = function(s,config,lang){
|
|||
"form-group-class": "h_control_call_input h_control_call_GET h_control_call_PUT h_control_call_POST",
|
||||
"possible": ""
|
||||
},
|
||||
{
|
||||
"name": "detail=control_invert_y",
|
||||
"field": lang["Invert Y-Axis"],
|
||||
"description": "For When your camera is mounted upside down or uses inverted vertical controls.",
|
||||
"default": "0",
|
||||
"example": "",
|
||||
"fieldType": "select",
|
||||
"possible": [
|
||||
{
|
||||
"name": lang.No,
|
||||
"value": "0"
|
||||
},
|
||||
{
|
||||
"name": lang.Yes,
|
||||
"value": "1"
|
||||
}
|
||||
]
|
||||
},
|
||||
]
|
||||
},
|
||||
"Grouping": {
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
"Token": "Token",
|
||||
"OAuth Code": "OAuth Code",
|
||||
"Google Drive": "Google Drive",
|
||||
"Invert Y-Axis": "Invert Y-Axis",
|
||||
"Get Code": "Get Code",
|
||||
"PTZ Tracking": "PTZ Tracking",
|
||||
"PTZ Tracking Target": "PTZ Tracking Target",
|
||||
|
@ -88,6 +89,9 @@
|
|||
"Never": "Never",
|
||||
"API": "API",
|
||||
"ONVIF": "ONVIF",
|
||||
"Set Home": "Set Home",
|
||||
"Set Home Position (ONVIF-only)": "Set Home Position (ONVIF-only)",
|
||||
"Non-Standard ONVIF": "Non-Standard ONVIF",
|
||||
"FFprobe": "Probe",
|
||||
"Monitor States": "Monitor States",
|
||||
"Schedule": "Schedule",
|
||||
|
|
|
@ -175,7 +175,7 @@ module.exports = function(s,config,lang){
|
|||
){
|
||||
if(!user.lang){
|
||||
var details = s.parseJSON(user.details).lang
|
||||
user.lang = s.getDefinitonFile(user.details.lang) || s.copySystemDefaultLanguage()
|
||||
user.lang = s.getLanguageFile(user.details.lang) || s.copySystemDefaultLanguage()
|
||||
}
|
||||
onSuccessComplete(user)
|
||||
}else{
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
module.exports = function(s,config,lang){
|
||||
if(config.p2pEnabled){
|
||||
const { Worker, isMainThread } = require('worker_threads');
|
||||
const startWorker = () => {
|
||||
// set the first parameter as a string.
|
||||
const pathToWorkerScript = __dirname + '/commander/worker.js'
|
||||
const workerProcess = new Worker(pathToWorkerScript)
|
||||
workerProcess.on('message',function(data){
|
||||
switch(data.f){
|
||||
case'debugLog':
|
||||
s.debugLog(...data.data)
|
||||
break;
|
||||
case'systemLog':
|
||||
s.systemLog(...data.data)
|
||||
break;
|
||||
}
|
||||
})
|
||||
setTimeout(() => {
|
||||
workerProcess.postMessage({
|
||||
f: 'init',
|
||||
config: config,
|
||||
lang: lang
|
||||
})
|
||||
},2000)
|
||||
// workerProcess is an Emitter.
|
||||
// it also contains a direct handle to the `spawn` at `workerProcess.spawnProcess`
|
||||
return workerProcess
|
||||
}
|
||||
config.machineId = config.p2pApiKey + '' + config.p2pGroupId
|
||||
config.p2pTargetAuth = config.p2pTargetAuth || s.gid(30)
|
||||
if(config.p2pTargetGroupId && config.p2pTargetUserId){
|
||||
startWorker()
|
||||
}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
|
||||
startWorker()
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,230 @@
|
|||
const { parentPort } = require('worker_threads');
|
||||
const request = require('request');
|
||||
const socketIOClient = require('socket.io-client');
|
||||
const p2pClientConnectionStaticName = 'Commander'
|
||||
const p2pClientConnections = {}
|
||||
const runningRequests = {}
|
||||
const connectedUserWebSockets = {}
|
||||
const s = {
|
||||
debugLog: (...args) => {
|
||||
parentPort.postMessage({
|
||||
f: 'debugLog',
|
||||
data: args
|
||||
})
|
||||
},
|
||||
systemLog: (...args) => {
|
||||
parentPort.postMessage({
|
||||
f: 'systemLog',
|
||||
data: args
|
||||
})
|
||||
},
|
||||
}
|
||||
parentPort.on('message',(data) => {
|
||||
switch(data.f){
|
||||
case'init':
|
||||
initialize(data.config,data.lang)
|
||||
break;
|
||||
}
|
||||
})
|
||||
|
||||
const initialize = (config,lang) => {
|
||||
if(!config.p2pHost)config.p2pHost = 'ws://163.172.180.205:8084'
|
||||
const parseJSON = function(string){
|
||||
var parsed = string
|
||||
try{
|
||||
parsed = JSON.parse(string)
|
||||
}catch(err){
|
||||
|
||||
}
|
||||
return parsed
|
||||
}
|
||||
const createQueryStringFromObject = function(obj){
|
||||
var queryString = ''
|
||||
var keys = Object.keys(obj)
|
||||
keys.forEach(function(key){
|
||||
var value = obj[key]
|
||||
queryString += `&${key}=${value}`
|
||||
})
|
||||
return queryString
|
||||
}
|
||||
const doRequest = function(url,method,data,callback,onDataReceived){
|
||||
var requestEndpoint = `${config.sslEnabled ? `https` : 'http'}://localhost:${config.sslEnabled ? config.ssl.port : config.port}` + 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)
|
||||
})
|
||||
}
|
||||
const createShinobiSocketConnection = (connectionId) => {
|
||||
const masterConnectionToMachine = socketIOClient(`ws://localhost:${config.port}`, {transports:['websocket']})
|
||||
p2pClientConnections[connectionId || p2pClientConnectionStaticName] = masterConnectionToMachine
|
||||
return masterConnectionToMachine
|
||||
}
|
||||
//
|
||||
s.debugLog('p2p',`Connecting to ${config.p2pHost}...`)
|
||||
const connectionToP2PServer = socketIOClient(config.p2pHost, {transports:['websocket']});
|
||||
if(!config.p2pApiKey){
|
||||
s.systemLog('p2p',`Please fill 'p2pApiKey' in your conf.json.`)
|
||||
}
|
||||
if(!config.p2pGroupId){
|
||||
s.systemLog('p2p',`Please fill 'p2pGroupId' in your conf.json.`)
|
||||
}
|
||||
connectionToP2PServer.on('connect', () => {
|
||||
s.systemLog('p2p',`Connected ${config.p2pHost}!`)
|
||||
connectionToP2PServer.emit('initMachine',{
|
||||
port: config.port,
|
||||
apiKey: config.p2pApiKey,
|
||||
groupId: config.p2pGroupId,
|
||||
targetUserId: config.p2pTargetUserId,
|
||||
targetGroupId: config.p2pTargetGroupId,
|
||||
subscriptionId: config.subscriptionId || 'notActivated'
|
||||
})
|
||||
})
|
||||
connectionToP2PServer.on('httpClose',(requestId) => {
|
||||
if(runningRequests[requestId] && runningRequests[requestId].abort){
|
||||
runningRequests[requestId].abort()
|
||||
delete(runningRequests[requestId])
|
||||
}
|
||||
})
|
||||
connectionToP2PServer.on('http',(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
|
||||
})
|
||||
},
|
||||
(data) => {
|
||||
if(!rawRequest.bodyOnEnd)connectionToP2PServer.emit('httpResponseChunk',{
|
||||
data: data,
|
||||
rid: rawRequest.rid
|
||||
})
|
||||
})
|
||||
})
|
||||
const masterConnectionToMachine = createShinobiSocketConnection()
|
||||
masterConnectionToMachine.on('connect', () => {
|
||||
masterConnectionToMachine.emit('f',{
|
||||
f: 'init',
|
||||
auth: config.p2pTargetAuth,
|
||||
ke: config.p2pTargetGroupId,
|
||||
uid: config.p2pTargetUserId
|
||||
})
|
||||
})
|
||||
masterConnectionToMachine.on('f',(data) => {
|
||||
connectionToP2PServer.emit('f',data)
|
||||
})
|
||||
|
||||
connectionToP2PServer.on('wsInit',(rawRequest) => {
|
||||
s.debugLog('p2pWsInit',rawRequest)
|
||||
const user = rawRequest.user
|
||||
const clientConnectionToMachine = createShinobiSocketConnection(rawRequest.cnid)
|
||||
connectedUserWebSockets[user.auth_token] = user;
|
||||
clientConnectionToMachine.on('connect', () => {
|
||||
s.debugLog('init',user.auth_token)
|
||||
clientConnectionToMachine.emit('f',{
|
||||
f: 'init',
|
||||
auth: user.auth_token,
|
||||
ke: user.ke,
|
||||
uid: user.uid,
|
||||
})
|
||||
});
|
||||
([
|
||||
'f',
|
||||
]).forEach((target) => {
|
||||
connectionToP2PServer.on(target,(data) => {
|
||||
clientConnectionToMachine.emit(target,data)
|
||||
})
|
||||
clientConnectionToMachine.on(target,(data) => {
|
||||
connectionToP2PServer.emit(target,{data: data, cnid: rawRequest.cnid})
|
||||
})
|
||||
})
|
||||
});
|
||||
([
|
||||
'a',
|
||||
'r',
|
||||
'gps',
|
||||
'e',
|
||||
'super',
|
||||
]).forEach((target) => {
|
||||
connectionToP2PServer.on(target,(data) => {
|
||||
var clientConnectionToMachine
|
||||
if(data.f === 'init'){
|
||||
clientConnectionToMachine = createShinobiSocketConnection(data.cnid)
|
||||
clientConnectionToMachine.on('connect', () => {
|
||||
clientConnectionToMachine.on(target,(fromData) => {
|
||||
connectionToP2PServer.emit(target,{data: fromData, cnid: data.cnid})
|
||||
})
|
||||
clientConnectionToMachine.on('f',(fromData) => {
|
||||
connectionToP2PServer.emit('f',{data: fromData, cnid: data.cnid})
|
||||
})
|
||||
clientConnectionToMachine.emit(target,data)
|
||||
});
|
||||
}else{
|
||||
clientConnectionToMachine = p2pClientConnections[data.cnid]
|
||||
clientConnectionToMachine.emit(target,data)
|
||||
}
|
||||
})
|
||||
|
||||
});
|
||||
([
|
||||
'h265',
|
||||
'Base64',
|
||||
'FLV',
|
||||
'MP4',
|
||||
]).forEach((target) => {
|
||||
connectionToP2PServer.on(target,(initData) => {
|
||||
if(connectedUserWebSockets[initData.auth]){
|
||||
const clientConnectionToMachine = createShinobiSocketConnection(initData.auth + initData.ke + initData.id)
|
||||
clientConnectionToMachine.on('connect', () => {
|
||||
clientConnectionToMachine.emit(target,initData)
|
||||
});
|
||||
clientConnectionToMachine.on('data',(data) => {
|
||||
connectionToP2PServer.emit('data',{data: data, cnid: initData.cnid})
|
||||
});
|
||||
}else{
|
||||
s.debugLog('disconnect now!')
|
||||
}
|
||||
})
|
||||
});
|
||||
connectionToP2PServer.on('wsDestroyStream',(clientKey) => {
|
||||
if(p2pClientConnections[clientKey]){
|
||||
p2pClientConnections[clientKey].disconnect();
|
||||
}
|
||||
delete(p2pClientConnections[clientKey])
|
||||
});
|
||||
connectionToP2PServer.on('wsDestroy',(rawRequest) => {
|
||||
if(p2pClientConnections[rawRequest.cnid]){
|
||||
p2pClientConnections[rawRequest.cnid].disconnect();
|
||||
}
|
||||
delete(p2pClientConnections[rawRequest.cnid])
|
||||
});
|
||||
|
||||
connectionToP2PServer.on('allowDisconnect',(bool) => {
|
||||
connectionToP2PServer.allowDisconnect = true;
|
||||
connectionToP2PServer.disconnect()
|
||||
s.debugLog('p2p','Server Forced Disconnection')
|
||||
});
|
||||
const onDisconnect = () => {
|
||||
s.systemLog('p2p','Disconnected')
|
||||
if(!connectionToP2PServer.allowDisconnect){
|
||||
s.systemLog('p2p','Attempting Reconnection...')
|
||||
setTimeout(() => {
|
||||
connectionToP2PServer.connect()
|
||||
},3000)
|
||||
}
|
||||
}
|
||||
connectionToP2PServer.on('error',onDisconnect)
|
||||
connectionToP2PServer.on('disconnect',onDisconnect)
|
||||
}
|
|
@ -2,5 +2,5 @@ var os = require('os');
|
|||
var exec = require('child_process').exec;
|
||||
module.exports = function(s,config,lang,app,io){
|
||||
require('./control/onvif.js')(s,config,lang,app,io)
|
||||
const ptz = require('./control/ptz.js')(s,config,lang,app,io)
|
||||
// const ptz = require('./control/ptz.js')(s,config,lang,app,io)
|
||||
}
|
||||
|
|
|
@ -17,13 +17,26 @@ module.exports = function(s,config,lang,app,io){
|
|||
try{
|
||||
const info = await device.init()
|
||||
response.ok = true
|
||||
response.device = device
|
||||
}catch(err){
|
||||
response.msg = 'Device responded with an error'
|
||||
response.error = error
|
||||
response.error = err
|
||||
}
|
||||
return response
|
||||
}
|
||||
const runOnvifMethod = (onvifOptions,callback) => {
|
||||
const replaceDynamicInOptions = (Camera,options) => {
|
||||
const newOptions = {}
|
||||
Object.keys(options).forEach((key) => {
|
||||
const value = options[key]
|
||||
if(typeof value === 'string'){
|
||||
newOptions[key] = value.replace(/__CURRENT_TOKEN/g,Camera.current_profile.token)
|
||||
}else if(value !== undefined && value !== null){
|
||||
newOptions[key] = value
|
||||
}
|
||||
})
|
||||
return newOptions
|
||||
}
|
||||
const runOnvifMethod = async (onvifOptions,callback) => {
|
||||
var onvifAuth = onvifOptions.auth
|
||||
var response = {ok: false}
|
||||
var errorMessage = function(msg,error){
|
||||
|
@ -83,7 +96,8 @@ module.exports = function(s,config,lang,app,io){
|
|||
var options
|
||||
var command
|
||||
if(argNames[0] === 'options' || argNames[0] === 'params'){
|
||||
options = onvifOptions.options || {}
|
||||
options = replaceDynamicInOptions(Camera,onvifOptions.options || {})
|
||||
response.options = options
|
||||
}
|
||||
if(onvifAuth.service){
|
||||
command = Camera.services[onvifAuth.service][onvifAuth.action](options)
|
||||
|
@ -94,7 +108,7 @@ module.exports = function(s,config,lang,app,io){
|
|||
}
|
||||
}
|
||||
if(!s.group[onvifAuth.ke].activeMonitors[onvifAuth.id].onvifConnection){
|
||||
const response = createOnvifDevice(onvifAuth)
|
||||
const response = await createOnvifDevice(onvifAuth)
|
||||
if(response.ok){
|
||||
doAction(response.device)
|
||||
}else{
|
||||
|
@ -112,15 +126,15 @@ module.exports = function(s,config,lang,app,io){
|
|||
config.webPaths.apiPrefix+':auth/onvif/:ke/:id/:service/:action'
|
||||
],function (req,res){
|
||||
s.auth(req.params,function(user){
|
||||
const options = s.getPostData(req,'options',true) || s.getPostData(req,'params',true)
|
||||
runOnvifMethod({
|
||||
auth: {
|
||||
ke: req.params.ke,
|
||||
id: req.params.id,
|
||||
auth: req.params.auth,
|
||||
action: req.params.action,
|
||||
service: req.params.service,
|
||||
},
|
||||
options: s.getPostData(req,'options',true) || s.getPostData(req,'params',true),
|
||||
options: options,
|
||||
},(endData) => {
|
||||
s.closeJsonResponse(res,endData)
|
||||
})
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
var os = require('os');
|
||||
var exec = require('child_process').exec;
|
||||
var request = require('request')
|
||||
module.exports = function(s,config,lang,app,io){
|
||||
module.exports = function(s,config,lang){
|
||||
const moveLock = {}
|
||||
const ptzTimeoutsUntilResetToHome = {}
|
||||
const startMove = async function(options,callback){
|
||||
const device = s.group[options.ke].activeMonitors[options.id].onvifConnection
|
||||
if(!device){
|
||||
|
@ -41,6 +42,7 @@ module.exports = function(s,config,lang,app,io){
|
|||
}
|
||||
const moveOnvifCamera = function(options,callback){
|
||||
const monitorConfig = s.group[options.ke].rawMonitorConfigurations[options.id]
|
||||
const invertedVerticalAxis = monitorConfig.details.control_invert_y === '1'
|
||||
const controlUrlStopTimeout = parseInt(monitorConfig.details.control_url_stop_timeout) || 1000
|
||||
switch(options.direction){
|
||||
case'center':
|
||||
|
@ -68,8 +70,8 @@ module.exports = function(s,config,lang,app,io){
|
|||
var onvifDirections = {
|
||||
"left": [-1.0,'x'],
|
||||
"right": [1.0,'x'],
|
||||
"down": [-1.0,'y'],
|
||||
"up": [1.0,'y'],
|
||||
"down": [invertedVerticalAxis ? 1.0 : -1.0,'y'],
|
||||
"up": [invertedVerticalAxis ? -1.0 : 1.0,'y'],
|
||||
"zoom_in": [1.0,'z'],
|
||||
"zoom_out": [-1.0,'z']
|
||||
}
|
||||
|
@ -258,10 +260,123 @@ module.exports = function(s,config,lang,app,io){
|
|||
}
|
||||
}
|
||||
}
|
||||
s.cameraControl = ptzControl
|
||||
const getPresetPositions = (options,callback) => {
|
||||
const profileToken = options.ProfileToken || "__CURRENT_TOKEN"
|
||||
return s.runOnvifMethod({
|
||||
auth: {
|
||||
ke: options.ke,
|
||||
id: options.id,
|
||||
service: 'ptz',
|
||||
action: 'getPresets',
|
||||
},
|
||||
options: {
|
||||
ProfileToken: profileToken
|
||||
},
|
||||
},callback)
|
||||
}
|
||||
const setPresetForCurrentPosition = (options,callback) => {
|
||||
const nonStandardOnvif = s.group[options.ke].rawMonitorConfigurations[options.id].details.onvif_non_standard === '1'
|
||||
const profileToken = options.ProfileToken || "__CURRENT_TOKEN"
|
||||
s.runOnvifMethod({
|
||||
auth: {
|
||||
ke: options.ke,
|
||||
id: options.id,
|
||||
service: 'ptz',
|
||||
action: 'setPreset',
|
||||
},
|
||||
options: {
|
||||
ProfileToken: profileToken,
|
||||
PresetToken: nonStandardOnvif ? null : options.PresetToken || profileToken,
|
||||
PresetName: options.PresetName || nonStandardOnvif ? '1' : profileToken
|
||||
},
|
||||
},(endData) => {
|
||||
callback(endData)
|
||||
})
|
||||
}
|
||||
const moveToPresetPosition = (options,callback) => {
|
||||
const nonStandardOnvif = s.group[options.ke].rawMonitorConfigurations[options.id].details.onvif_non_standard === '1'
|
||||
const profileToken = options.ProfileToken || "__CURRENT_TOKEN"
|
||||
return s.runOnvifMethod({
|
||||
auth: {
|
||||
ke: options.ke,
|
||||
id: options.id,
|
||||
service: 'ptz',
|
||||
action: 'gotoPreset',
|
||||
},
|
||||
options: {
|
||||
ProfileToken: profileToken,
|
||||
PresetToken: options.PresetToken || nonStandardOnvif ? '1' : profileToken,
|
||||
Speed: {
|
||||
"x": 1,
|
||||
"y": 1,
|
||||
"z": 1
|
||||
},
|
||||
},
|
||||
},callback)
|
||||
}
|
||||
const getLargestMatrix = (matrices) => {
|
||||
var largestMatrix = {width: 0, height: 0}
|
||||
matrices.forEach((matrix) => {
|
||||
if(matrix.width > largestMatrix.width && matrix.height > largestMatrix.height)largestMatrix = matrix
|
||||
})
|
||||
return largestMatrix.x ? largestMatrix : null
|
||||
}
|
||||
const moveCameraPtzToMatrix = function(event,trackingTarget){
|
||||
if(moveLock[event.ke + event.id])return;
|
||||
clearTimeout(moveLock[event.ke + event.id])
|
||||
moveLock[event.ke + event.id] = setTimeout(() => {
|
||||
delete(moveLock[event.ke + event.id])
|
||||
},1000)
|
||||
const imgHeight = event.details.imgHeight
|
||||
const imgWidth = event.details.imgWidth
|
||||
const thresholdX = imgWidth * 0.125
|
||||
const thresholdY = imgHeight * 0.125
|
||||
const imageCenterX = imgWidth / 2
|
||||
const imageCenterY = imgHeight / 2
|
||||
const matrices = event.details.matrices
|
||||
const largestMatrix = getLargestMatrix(matrices.filter(matrix => matrix.tag === (trackingTarget || 'person')))
|
||||
// console.log(matrices.find(matrix => matrix.tag === 'person'))
|
||||
if(!largestMatrix)return;
|
||||
const matrixCenterX = largestMatrix.x + (largestMatrix.width / 2)
|
||||
const matrixCenterY = largestMatrix.y + (largestMatrix.height / 2)
|
||||
const rawDistanceX = (matrixCenterX - imageCenterX)
|
||||
const rawDistanceY = (matrixCenterY - imageCenterY)
|
||||
const distanceX = imgWidth / rawDistanceX
|
||||
const distanceY = imgHeight / rawDistanceY
|
||||
const axisX = rawDistanceX > thresholdX || rawDistanceX < -thresholdX ? distanceX : 0
|
||||
const axisY = largestMatrix.y < 30 && largestMatrix.height > imgHeight * 0.8 ? 0.5 : rawDistanceY > thresholdY || rawDistanceY < -thresholdY ? -distanceY : 0
|
||||
if(axisX !== 0 || axisY !== 0){
|
||||
ptzControl({
|
||||
axis: [
|
||||
{direction: 'x', amount: axisX === 0 ? 0 : axisX > 0 ? 0.01 : -0.01},
|
||||
{direction: 'y', amount: axisY === 0 ? 0 : axisY > 0 ? 0.01 : -0.01},
|
||||
{direction: 'z', amount: 0},
|
||||
],
|
||||
// axis: [{direction: 'x', amount: 1.0}],
|
||||
id: event.id,
|
||||
ke: event.ke
|
||||
},(msg) => {
|
||||
s.userLog(event,msg)
|
||||
// console.log(msg)
|
||||
clearTimeout(ptzTimeoutsUntilResetToHome[event.ke + event.id])
|
||||
ptzTimeoutsUntilResetToHome[event.ke + event.id] = setTimeout(() => {
|
||||
moveToPresetPosition({
|
||||
ke: event.ke,
|
||||
id: event.id,
|
||||
},(endData) => {
|
||||
console.log(endData)
|
||||
})
|
||||
},7000)
|
||||
})
|
||||
}
|
||||
}
|
||||
return {
|
||||
control: ptzControl,
|
||||
ptzControl: ptzControl,
|
||||
startMove: startMove,
|
||||
stopMove: stopMove,
|
||||
getPresetPositions: getPresetPositions,
|
||||
setPresetForCurrentPosition: setPresetForCurrentPosition,
|
||||
moveToPresetPosition: moveToPresetPosition,
|
||||
moveCameraPtzToMatrix: moveCameraPtzToMatrix
|
||||
}
|
||||
}
|
||||
|
|
|
@ -383,6 +383,35 @@ module.exports = async (s,config,lang,app,io) => {
|
|||
}
|
||||
},res,req)
|
||||
})
|
||||
// /**
|
||||
// * API : Superuser : Custom Auto Load Package Update.
|
||||
// */
|
||||
// app.post(config.webPaths.superApiPrefix+':auth/package/update', async (req,res) => {
|
||||
// s.superAuth(req.params, async (resp) => {
|
||||
// try{
|
||||
// const url = req.body.downloadUrl
|
||||
// const packageRoot = req.body.packageRoot || ''
|
||||
// const packageName = req.body.packageName || extractNameFromPackage(url)
|
||||
// const modulePath = getModulePath(packageName)
|
||||
// await downloadModule(url,packageName)
|
||||
// const properties = getModuleProperties(packageName)
|
||||
// const newName = await moveModuleToNameInProperties(modulePath,packageRoot,properties)
|
||||
// const chosenName = newName ? newName : packageName
|
||||
//
|
||||
// disableModule(chosenName,true)
|
||||
// s.closeJsonResponse(res,{
|
||||
// ok: true,
|
||||
// moduleName: chosenName,
|
||||
// newModule: getModule(chosenName)
|
||||
// })
|
||||
// }catch(err){
|
||||
// s.closeJsonResponse(res,{
|
||||
// ok: false,
|
||||
// error: err
|
||||
// })
|
||||
// }
|
||||
// },res,req)
|
||||
// })
|
||||
/**
|
||||
* API : Superuser : Custom Auto Load Package Install.
|
||||
*/
|
||||
|
|
|
@ -10,7 +10,9 @@ var P = SAT.Polygon;
|
|||
var B = SAT.Box;
|
||||
// Matrix In Region Libs />
|
||||
module.exports = function(s,config,lang){
|
||||
const ptz = require('./control/ptz.js')(s,config,lang)
|
||||
const {
|
||||
moveCameraPtzToMatrix,
|
||||
} = require('./control/ptz.js')(s,config,lang)
|
||||
const countObjects = async (event) => {
|
||||
const matrices = event.details.matrices
|
||||
const eventsCounted = s.group[event.ke].activeMonitors[event.id].eventsCounted || {}
|
||||
|
@ -78,54 +80,6 @@ module.exports = function(s,config,lang){
|
|||
return collisions
|
||||
}
|
||||
const nonEmpty = (element) => element.length !== 0;
|
||||
const moveLock = {}
|
||||
const getLargestMatrix = (matrices) => {
|
||||
var largestMatrix = {width: 0, height: 0}
|
||||
matrices.forEach((matrix) => {
|
||||
if(matrix.width > largestMatrix.width && matrix.height > largestMatrix.height)largestMatrix = matrix
|
||||
})
|
||||
return largestMatrix.x ? largestMatrix : null
|
||||
}
|
||||
const moveCameraPtzToMatrix = function(event,trackingTarget){
|
||||
if(moveLock[event.ke + event.id])return;
|
||||
clearTimeout(moveLock[event.ke + event.id])
|
||||
moveLock[event.ke + event.id] = setTimeout(() => {
|
||||
delete(moveLock[event.ke + event.id])
|
||||
},1000)
|
||||
const imgHeight = event.details.imgHeight
|
||||
const imgWidth = event.details.imgWidth
|
||||
const thresholdX = imgWidth * 0.125
|
||||
const thresholdY = imgHeight * 0.125
|
||||
const imageCenterX = imgWidth / 2
|
||||
const imageCenterY = imgHeight / 2
|
||||
const matrices = event.details.matrices
|
||||
const largestMatrix = getLargestMatrix(matrices.filter(matrix => matrix.tag === (trackingTarget || 'person')))
|
||||
// console.log(matrices.find(matrix => matrix.tag === 'person'))
|
||||
if(!largestMatrix)return;
|
||||
const matrixCenterX = largestMatrix.x + (largestMatrix.width / 2)
|
||||
const matrixCenterY = largestMatrix.y + (largestMatrix.height / 2)
|
||||
const rawDistanceX = (matrixCenterX - imageCenterX)
|
||||
const rawDistanceY = (matrixCenterY - imageCenterY)
|
||||
const distanceX = imgWidth / rawDistanceX
|
||||
const distanceY = imgHeight / rawDistanceY
|
||||
const axisX = rawDistanceX > thresholdX || rawDistanceX < -thresholdX ? distanceX : 0
|
||||
const axisY = largestMatrix.y < 30 && largestMatrix.height > imgHeight * 0.8 ? 0.5 : rawDistanceY > thresholdY || rawDistanceY < -thresholdY ? -distanceY : 0
|
||||
if(axisX !== 0 || axisY !== 0){
|
||||
ptz.control({
|
||||
axis: [
|
||||
{direction: 'x', amount: axisX === 0 ? 0 : axisX > 0 ? 0.01 : -0.01},
|
||||
{direction: 'y', amount: axisY === 0 ? 0 : axisY > 0 ? 0.01 : -0.01},
|
||||
{direction: 'z', amount: 0},
|
||||
],
|
||||
// axis: [{direction: 'x', amount: 1.0}],
|
||||
id: event.id,
|
||||
ke: event.ke
|
||||
},(msg) => {
|
||||
s.userLog(event,msg)
|
||||
// console.log(msg)
|
||||
})
|
||||
}
|
||||
}
|
||||
s.addEventDetailsToString = function(eventData,string,addOps){
|
||||
//d = event data
|
||||
if(!addOps)addOps = {}
|
||||
|
|
|
@ -13,6 +13,9 @@ const URL = require('url')
|
|||
const { copyObject, createQueue } = require('./common.js')
|
||||
module.exports = function(s,config,lang){
|
||||
const { cameraDestroy } = require('./monitor/utils.js')(s,config,lang)
|
||||
const {
|
||||
setPresetForCurrentPosition
|
||||
} = require('./control/ptz.js')(s,config,lang)
|
||||
const startMonitorInQueue = createQueue(1, 3)
|
||||
s.initiateMonitorObject = function(e){
|
||||
if(!s.group[e.ke]){s.group[e.ke]={}};
|
||||
|
@ -455,7 +458,7 @@ module.exports = function(s,config,lang){
|
|||
ke: e.ke
|
||||
},'GRP_'+e.ke)
|
||||
}else{
|
||||
console.log('not image')
|
||||
s.debugLog('Damaged Snapshot Data')
|
||||
s.tx({f:'monitor_snapshot',snapshot:e.mon.name,snapshot_format:'plc',mid:e.mid,ke:e.ke},'GRP_'+e.ke)
|
||||
}
|
||||
}else{
|
||||
|
@ -634,21 +637,25 @@ module.exports = function(s,config,lang){
|
|||
},60000*1);
|
||||
}
|
||||
const onDetectorJpegOutputAlone = (e,d) => {
|
||||
s.ocvTx({
|
||||
f: 'frame',
|
||||
mon: s.group[e.ke].rawMonitorConfigurations[e.id].details,
|
||||
ke: e.ke,
|
||||
id: e.id,
|
||||
time: s.formattedTime(),
|
||||
frame: d
|
||||
})
|
||||
if(s.isAtleatOneDetectorPluginConnected){
|
||||
s.ocvTx({
|
||||
f: 'frame',
|
||||
mon: s.group[e.ke].rawMonitorConfigurations[e.id].details,
|
||||
ke: e.ke,
|
||||
id: e.id,
|
||||
time: s.formattedTime(),
|
||||
frame: d
|
||||
})
|
||||
}
|
||||
}
|
||||
const onDetectorJpegOutputSecondary = (e,buffer) => {
|
||||
const theArray = s.group[e.ke].activeMonitors[e.id].pipe4BufferPieces
|
||||
theArray.push(buffer)
|
||||
if(buffer[buffer.length-2] === 0xFF && buffer[buffer.length-1] === 0xD9){
|
||||
s.group[e.ke].activeMonitors[e.id].lastJpegDetectorFrame = Buffer.concat(theArray)
|
||||
s.group[e.ke].activeMonitors[e.id].pipe4BufferPieces = []
|
||||
if(s.isAtleatOneDetectorPluginConnected){
|
||||
const theArray = s.group[e.ke].activeMonitors[e.id].pipe4BufferPieces
|
||||
theArray.push(buffer)
|
||||
if(buffer[buffer.length-2] === 0xFF && buffer[buffer.length-1] === 0xD9){
|
||||
s.group[e.ke].activeMonitors[e.id].lastJpegDetectorFrame = Buffer.concat(theArray)
|
||||
s.group[e.ke].activeMonitors[e.id].pipe4BufferPieces = []
|
||||
}
|
||||
}
|
||||
}
|
||||
const createCameraFfmpegProcess = (e) => {
|
||||
|
@ -856,19 +863,13 @@ module.exports = function(s,config,lang){
|
|||
onDetectorJpegOutputSecondary(e,data)
|
||||
})
|
||||
}
|
||||
}else if(s.isAtleatOneDetectorPluginConnected){
|
||||
if(e.details.detector_use_detect_object === '1' && e.details.detector_send_frames !== '1'){
|
||||
s.group[e.ke].activeMonitors[e.id].spawn.stdio[4].on('data',function(data){
|
||||
onDetectorJpegOutputSecondary(e,data)
|
||||
})
|
||||
}else{
|
||||
s.group[e.ke].activeMonitors[e.id].spawn.stdio[4].on('data',function(data){
|
||||
onDetectorJpegOutputAlone(e,data)
|
||||
})
|
||||
}
|
||||
}else if(e.details.detector_use_detect_object === '1' && e.details.detector_send_frames !== '1'){
|
||||
s.group[e.ke].activeMonitors[e.id].spawn.stdio[4].on('data',function(data){
|
||||
onDetectorJpegOutputSecondary(e,data)
|
||||
})
|
||||
}else{
|
||||
s.group[e.ke].activeMonitors[e.id].spawn.stdio[4].on('data',function(data){
|
||||
// set so ffmpeg doesnt hang
|
||||
onDetectorJpegOutputAlone(e,data)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -1609,6 +1610,34 @@ module.exports = function(s,config,lang){
|
|||
break;
|
||||
}
|
||||
}
|
||||
if(e.details.detector_ptz_follow === '1'){
|
||||
setTimeout(() => {
|
||||
setPresetForCurrentPosition({
|
||||
ke: e.ke,
|
||||
id: e.id
|
||||
},(endData) => {
|
||||
if(endData.ok === false){
|
||||
setTimeout(() => {
|
||||
setPresetForCurrentPosition({
|
||||
ke: e.ke,
|
||||
id: e.id
|
||||
},(endData) => {
|
||||
if(endData.ok === false){
|
||||
setTimeout(() => {
|
||||
setPresetForCurrentPosition({
|
||||
ke: e.ke,
|
||||
id: e.id
|
||||
},(endData) => {
|
||||
console.log(endData)
|
||||
})
|
||||
},5000)
|
||||
}
|
||||
})
|
||||
},5000)
|
||||
}
|
||||
})
|
||||
},5000)
|
||||
}
|
||||
launchMonitorProcesses(e)
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -54,7 +54,7 @@ module.exports = function(s,config,lang,app,io){
|
|||
ip = addressRange.join(',')
|
||||
}
|
||||
if(ports === ''){
|
||||
ports = '80,8080,8000,7575,8081,9080,8090,8999'
|
||||
ports = '80,8080,8000,7575,8081,9080,8090,8999,8899'
|
||||
}
|
||||
if(ports.indexOf('-') > -1){
|
||||
ports = ports.split('-')
|
||||
|
|
|
@ -118,10 +118,11 @@ module.exports = function(s,config,lang,app,io){
|
|||
var scheduleNames = Object.keys(s.schedules[key])
|
||||
scheduleNames.forEach(function(name){
|
||||
var schedule = s.schedules[key][name]
|
||||
if(!schedule.active && schedule.enabled === 1 && schedule.start && schedule.details.monitorStates){
|
||||
if(schedule.enabled === 1 && schedule.start && schedule.details.monitorStates){
|
||||
var timePasses = checkTimeAgainstSchedule(schedule)
|
||||
var daysPasses = checkDaysAgainstSchedule(schedule)
|
||||
if(timePasses && daysPasses){
|
||||
var passed = timePasses && daysPasses
|
||||
if(passed && !schedule.active){
|
||||
schedule.active = true
|
||||
var monitorStates = schedule.details.monitorStates
|
||||
monitorStates.forEach(function(stateName){
|
||||
|
@ -135,7 +136,7 @@ module.exports = function(s,config,lang,app,io){
|
|||
// console.log(endData)
|
||||
})
|
||||
})
|
||||
}else{
|
||||
}else if(!passed && schedule.active){
|
||||
schedule.active = false
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,9 @@ var exec = require('child_process').exec;
|
|||
var spawn = require('child_process').spawn;
|
||||
var jsonfile = require("jsonfile");
|
||||
module.exports = function(s,config,lang,io){
|
||||
const {
|
||||
ptzControl
|
||||
} = require('./control/ptz.js')(s,config,lang)
|
||||
s.clientSocketConnection = {}
|
||||
//send data to socket client function
|
||||
s.tx = function(z,y,x){
|
||||
|
@ -51,17 +54,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 +77,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 +168,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 +201,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 +234,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 +315,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 +396,7 @@ module.exports = function(s,config,lang,io){
|
|||
extender(r,cn,d,tx)
|
||||
})
|
||||
}
|
||||
streamConnectionAuthentication(d).then(onSuccess).catch(onFail)
|
||||
streamConnectionAuthentication(d,cn.ip).then(onSuccess).catch(onFail)
|
||||
return;
|
||||
}
|
||||
if((d.id||d.uid||d.mid)&&cn.ke){
|
||||
|
@ -649,7 +652,7 @@ module.exports = function(s,config,lang,io){
|
|||
}
|
||||
break;
|
||||
case'control':
|
||||
s.cameraControl(d,function(msg){
|
||||
ptzControl(d,function(msg){
|
||||
s.userLog(d,msg)
|
||||
tx({f:'control',response:msg})
|
||||
})
|
||||
|
|
|
@ -172,7 +172,7 @@ module.exports = function(s,config){
|
|||
dbQuery.limit(options.limit)
|
||||
}else{
|
||||
const limitParts = `${options.limit}`.split(',')
|
||||
dbQuery.limit(limitParts[0]).offset(limitParts[1])
|
||||
dbQuery.limit(limitParts[1]).offset(limitParts[0])
|
||||
}
|
||||
}
|
||||
if(config.debugLog === true){
|
||||
|
@ -203,7 +203,7 @@ module.exports = function(s,config){
|
|||
['ke','=',options.groupKey],
|
||||
]
|
||||
const monitorRestrictions = options.monitorRestrictions
|
||||
var frameLimit = parseInt(options.limit) || 500
|
||||
var frameLimit = options.limit
|
||||
const endIsStartTo = options.endIsStartTo
|
||||
const chosenDate = options.date
|
||||
const startDate = options.startDate ? s.stringToSqlTime(options.startDate) : null
|
||||
|
@ -511,8 +511,6 @@ module.exports = function(s,config){
|
|||
type: 'count',
|
||||
endIsStartTo: endIsStartTo
|
||||
},(response) => {
|
||||
console.log('count')
|
||||
console.log(response)
|
||||
const count = response.count
|
||||
var skipOver = 0
|
||||
if(limitString.indexOf(',') > -1){
|
||||
|
|
803
libs/startup.js
803
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)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -57,7 +57,9 @@ module.exports = function(s,config,lang,io){
|
|||
//SSL options
|
||||
var wellKnownDirectory = s.mainDirectory + '/web/.well-known'
|
||||
if(fs.existsSync(wellKnownDirectory))app.use('/.well-known',express.static(wellKnownDirectory))
|
||||
config.sslEnabled = false
|
||||
if(config.ssl&&config.ssl.key&&config.ssl.cert){
|
||||
config.sslEnabled = true
|
||||
config.ssl.key=fs.readFileSync(s.checkRelativePath(config.ssl.key),'utf8')
|
||||
config.ssl.cert=fs.readFileSync(s.checkRelativePath(config.ssl.cert),'utf8')
|
||||
if(config.ssl.port === undefined){
|
||||
|
|
|
@ -12,6 +12,10 @@ var proxy = httpProxy.createProxyServer({})
|
|||
var ejs = require('ejs');
|
||||
var fileupload = require("express-fileupload");
|
||||
module.exports = function(s,config,lang,app,io){
|
||||
const {
|
||||
ptzControl,
|
||||
setPresetForCurrentPosition
|
||||
} = require('./control/ptz.js')(s,config,lang,app,io)
|
||||
if(config.productType === 'Pro'){
|
||||
var LdapAuth = require('ldapauth-fork');
|
||||
}
|
||||
|
@ -1453,7 +1457,6 @@ module.exports = function(s,config,lang,app,io){
|
|||
videoRowCaches[cacheName] = videoRow
|
||||
clearTimeout(videoRowCacheTimeouts[cacheName])
|
||||
videoRowCacheTimeouts[cacheName] = setTimeout(() => {
|
||||
console.log('clear cache',cacheName)
|
||||
delete(videoRowCaches[cacheName])
|
||||
},60000)
|
||||
}
|
||||
|
@ -1656,16 +1659,25 @@ module.exports = function(s,config,lang,app,io){
|
|||
app.get(config.webPaths.apiPrefix+':auth/control/:ke/:id/:direction', function (req,res){
|
||||
res.setHeader('Content-Type', 'application/json');
|
||||
s.auth(req.params,function(user){
|
||||
s.cameraControl(req.params,function(msg){
|
||||
s.userLog({
|
||||
if(req.params.direction === 'setHome'){
|
||||
setPresetForCurrentPosition({
|
||||
id: req.params.id,
|
||||
ke: req.params.ke,
|
||||
},{
|
||||
msg: msg,
|
||||
direction: req.params.direction,
|
||||
},(response) => {
|
||||
res.end(s.prettyPrint(response))
|
||||
})
|
||||
res.end(s.prettyPrint(msg))
|
||||
});
|
||||
}else{
|
||||
ptzControl(req.params,function(msg){
|
||||
s.userLog({
|
||||
id: req.params.id,
|
||||
ke: req.params.ke,
|
||||
},{
|
||||
msg: msg,
|
||||
direction: req.params.direction,
|
||||
})
|
||||
res.end(s.prettyPrint(msg))
|
||||
})
|
||||
}
|
||||
},res,req);
|
||||
})
|
||||
/**
|
||||
|
|
|
@ -13,9 +13,6 @@
|
|||
position: relative;
|
||||
height: 120px;
|
||||
width: 120px;
|
||||
background: #b7b7b7;
|
||||
border-radius: 50%;
|
||||
box-shadow: inset 0 0 1px rgba(120, 120, 120, 0.6), inset 0 2px 2px rgba(0, 0, 0, 0.1), 0 2px 2px rgba(240, 240, 240, 0.4);
|
||||
}
|
||||
.PTZ_controls .control {
|
||||
position: absolute;
|
||||
|
@ -23,9 +20,10 @@
|
|||
.PTZ_controls .pad .control {
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
background: #636363;
|
||||
box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.6), 0 0 0 3px rgba(60, 60, 60, 0.2), 0 0 0 4px rgba(60, 60, 60, 0.2);
|
||||
background: #101f54;
|
||||
box-shadow: 0 0 15px rgba(0,0,0,0.4);
|
||||
border-radius: 2px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.PTZ_controls .zoom_in{
|
||||
top: 0;
|
||||
|
@ -44,25 +42,29 @@
|
|||
right: 0;
|
||||
}
|
||||
.PTZ_controls .pad .top {
|
||||
top: 15px;
|
||||
left: 50%;
|
||||
margin: 0 0 0 -15px;
|
||||
top: 10px;
|
||||
border-radius: 10px 10px 50px 50px;
|
||||
}
|
||||
.PTZ_controls .pad .left {
|
||||
top: 45px;
|
||||
left: 15px;
|
||||
left: 10px;
|
||||
border-radius: 10px 50px 50px 10px;
|
||||
}
|
||||
.PTZ_controls .pad .right {
|
||||
top: 45px;
|
||||
right: 15px;
|
||||
right: 10px;
|
||||
border-radius: 50px 10px 10px 50px;
|
||||
}
|
||||
.PTZ_controls .pad .control.right:before {
|
||||
transform: rotate(90deg) translate(-3px, -5px);
|
||||
}
|
||||
.PTZ_controls .pad .bottom {
|
||||
bottom: 15px;
|
||||
left: 50%;
|
||||
margin: 0 0 0 -15px;
|
||||
bottom: 10px;
|
||||
border-radius: 50px 50px 10px 10px;
|
||||
}
|
||||
/* Overlap the other controls to hide box-shadow */
|
||||
.PTZ_controls .pad .middle {
|
||||
|
@ -72,18 +74,6 @@
|
|||
top: 43px;
|
||||
left: 50%;
|
||||
margin: 0 0 0 -17px;
|
||||
box-shadow: none;
|
||||
border-radius: 3px;
|
||||
}
|
||||
.PTZ_controls .pad .middle:after {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
margin: -35% 0 0 -35%;
|
||||
content: '';
|
||||
background: #636363;
|
||||
height: 70%;
|
||||
width: 70%;
|
||||
border-radius: 100%;
|
||||
box-shadow: inset 0 0 2px rgba(120, 120, 120, 0.6), inset 0 2px 8px rgba(0, 0, 0, 0.1), 0 2px 2px rgba(240, 240, 240, 0.2);
|
||||
border-radius: 50%;
|
||||
background: #1f396c;
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ $.ccio={
|
|||
mon:{},
|
||||
useUTC: <%- config.useUTC || false %>,
|
||||
definitions: <%-JSON.stringify(define)%>,
|
||||
libURL: location.search === '?assemble=1' ? location.pathname + '/' : '<%-window.libURL%>',
|
||||
libURL: location.search === '?p2p=1' ? location.pathname + '/' : '<%-window.libURL%>',
|
||||
isAppleDevice: navigator.userAgent.match(/(iPod|iPhone|iPad)/)||(navigator.userAgent.match(/(Safari)/)&&!navigator.userAgent.match('Chrome'))
|
||||
};
|
||||
<% if(config.DropboxAppKey){ %>
|
||||
|
@ -154,6 +154,7 @@ $(document).ready(function(e){
|
|||
function onFullScreenChange() {
|
||||
var fullscreenElement = document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement;
|
||||
if(!fullscreenElement){
|
||||
$('.videoPlayer-detection-info').removeClass('hide')
|
||||
$('.fullscreen').removeClass('fullscreen')
|
||||
setTimeout(function(){
|
||||
$('canvas.stream-element').resize();
|
||||
|
|
|
@ -456,8 +456,23 @@ $(document).ready(function(e){
|
|||
});
|
||||
break;
|
||||
case'control':
|
||||
e.a=e.e.attr('control')
|
||||
$.ccio.cx({f:'monitor',ff:'control',direction:e.a,id:e.mid,ke:e.ke},user)
|
||||
var switchChosen = e.e.attr('control')
|
||||
switch(switchChosen){
|
||||
case'setHome':
|
||||
$.get(getApiPrefix() + '/control' + '/' + $user.ke + '/' + e.mid + '/setHome',function(data){
|
||||
console.log(data)
|
||||
})
|
||||
break;
|
||||
default:
|
||||
$.ccio.cx({
|
||||
f: 'monitor',
|
||||
ff: 'control',
|
||||
direction: switchChosen,
|
||||
id: e.mid,
|
||||
ke: e.ke
|
||||
},user)
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case'videos_table':case'calendar':case'video_grid'://call videos table or calendar or video grid
|
||||
$.vidview.launcher=$(this);
|
||||
|
@ -685,23 +700,27 @@ $(document).ready(function(e){
|
|||
if(e.e.length>0){
|
||||
e.e.remove()
|
||||
}else{
|
||||
var html = '<div class="PTZ_controls">'
|
||||
html += '<div class="pad">'
|
||||
html += '<div class="control top" monitor="control" control="up"></div>'
|
||||
html += '<div class="control left" monitor="control" control="left"></div>'
|
||||
html += '<div class="control right" monitor="control" control="right"></div>'
|
||||
html += '<div class="control bottom" monitor="control" control="down"></div>'
|
||||
html += '<div class="control middle" monitor="control" control="center"></div>'
|
||||
html += '</div>'
|
||||
html += '<div class="btn-group btn-group-sm btn-group-justified">'
|
||||
html += '<a title="'+lang['Zoom In']+'" class="zoom_in btn btn-default" monitor="control" control="zoom_in"><i class="fa fa-search-plus"></i></a>'
|
||||
html += '<a title="'+lang['Zoom Out']+'" class="zoom_out btn btn-default" monitor="control" control="zoom_out"><i class="fa fa-search-minus"></i></a>'
|
||||
html += '</div>'
|
||||
html += '<div class="btn-group btn-group-sm btn-group-justified">'
|
||||
html += '<a title="'+lang['Enable Nightvision']+'" class="nv_enable btn btn-default" monitor="control" control="enable_nv"><i class="fa fa-moon-o"></i></a>'
|
||||
html += '<a title="'+lang['Disable Nightvision']+'" class="nv_disable btn btn-default" monitor="control" control="disable_nv"><i class="fa fa-sun-o"></i></a>'
|
||||
html += '</div>'
|
||||
html += '</div>'
|
||||
var html = `<div class="PTZ_controls">
|
||||
<div class="pad">
|
||||
<div class="control top" monitor="control" control="up"></div>
|
||||
<div class="control left" monitor="control" control="left"></div>
|
||||
<div class="control right" monitor="control" control="right"></div>
|
||||
<div class="control bottom" monitor="control" control="down"></div>
|
||||
<div class="control middle" monitor="control" control="center"></div>
|
||||
</div>
|
||||
<div class="btn-group btn-group-sm btn-group-justified">
|
||||
<a title="${lang['Zoom In']}" class="zoom_in btn btn-default" monitor="control" control="zoom_in"><i class="fa fa-search-plus"></i></a>
|
||||
<a title="${lang['Zoom Out']}" class="zoom_out btn btn-default" monitor="control" control="zoom_out"><i class="fa fa-search-minus"></i></a>
|
||||
</div>
|
||||
<div class="btn-group btn-group-sm btn-group-justified">
|
||||
<a title="${lang['Enable Nightvision']}" class="nv_enable btn btn-default" monitor="control" control="enable_nv"><i class="fa fa-moon-o"></i></a>
|
||||
<a title="${lang['Disable Nightvision']}" class="nv_disable btn btn-default" monitor="control" control="disable_nv"><i class="fa fa-sun-o"></i></a>
|
||||
</div>
|
||||
${$.parseJSON($.ccio.mon[$user.ke + e.mid + $user.auth_token].details,{}).is_onvif === '1' ? `
|
||||
<div class="btn-group btn-group-sm btn-group-justified">
|
||||
<a title="${lang['Set Home Position (ONVIF-only)']}" class="btn btn-default" monitor="control" control="setHome"><i class="fa fa-h-square"></i> ${lang['Set Home']}</a>
|
||||
</div>` : ``}
|
||||
</div>`
|
||||
e.p.append(html)
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -611,6 +611,7 @@ $(document).ready(function(e){
|
|||
$('body')
|
||||
.on('dblclick','.videoPlayer',function(){
|
||||
var el = $(this)
|
||||
$('.videoPlayer-detection-info').addClass('hide')
|
||||
$.ccio.init('fullscreen',this)
|
||||
})
|
||||
.on('click','[data-monitor]',function(){
|
||||
|
|
|
@ -277,7 +277,7 @@ $.ccio.globalWebsocket=function(d,user){
|
|||
if($.ccio.op().jpeg_on===true){
|
||||
$.ccio.init('jpegMode',$.ccio.mon[d.ke+d.id+user.auth_token]);
|
||||
}else{
|
||||
if(location.search === '?assemble=1'){
|
||||
if(location.search === '?p2p=1'){
|
||||
var path = '/socket.io'
|
||||
}else{
|
||||
var path = tool.checkCorrectPathEnding(location.pathname)+'socket.io'
|
||||
|
@ -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){
|
||||
|
@ -690,7 +689,7 @@ $.ccio.globalWebsocket=function(d,user){
|
|||
break;
|
||||
}
|
||||
}
|
||||
if(location.search === '?assemble=1'){
|
||||
if(location.search === '?p2p=1'){
|
||||
$user.ws=io(location.origin,{
|
||||
path : '/socket.io'
|
||||
});
|
||||
|
@ -702,16 +701,16 @@ if(location.search === '?assemble=1'){
|
|||
$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,
|
||||
if(location.search === '?p2p=1'){
|
||||
$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})
|
||||
|
|
|
@ -86,7 +86,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<script>
|
||||
var adminApiPrefix = "<%=originalURL%><%=config.webPaths.adminApiPrefix%>"
|
||||
var adminApiPrefix = location.search === '?p2p=1' ? location.pathname + '/' : "<%=originalURL%><%=config.webPaths.adminApiPrefix%>"
|
||||
</script>
|
||||
<% include blocks/confirm.ejs %>
|
||||
<% include blocks/subpermissions.ejs %>
|
||||
|
@ -104,7 +104,7 @@
|
|||
<script><% include ../libs/js/bootstrap-table.min.js %></script>
|
||||
<script>
|
||||
$.ccio={subs:{}};$.ls=localStorage;
|
||||
if(location.search === '?assemble=1'){
|
||||
if(location.search === '?p2p=1'){
|
||||
$.ccio.ws=io(location.origin,{
|
||||
path : '/socket.io'
|
||||
});
|
||||
|
@ -115,7 +115,7 @@ if(location.search === '?assemble=1'){
|
|||
}
|
||||
$.ccio.cx=function(x){if(!x.ke){x.ke=$user.ke;};if(!x.uid){x.uid=$user.uid;};return $.ccio.ws.emit('a',x)}
|
||||
$.ccio.ws.on('connect',function(d){
|
||||
$.ccio.cx({f:'init',auth:$user.auth_token});
|
||||
$.ccio.cx({f:'init',auth:$user.auth_token,machineId: `<%- config.machineId %>`});
|
||||
})
|
||||
PNotify.prototype.options.styling = "fontawesome";
|
||||
$.ccio.ws.on('f',function(d){
|
||||
|
@ -179,7 +179,7 @@ $.aN.e.submit(function(e){
|
|||
e.preventDefault();
|
||||
e.s = $.aN.e.serializeObject()
|
||||
e.m = $('#msg').empty()
|
||||
$.post('<%=originalURL%><%=config.webPaths.adminApiPrefix%>'+$user.auth_token+'/accounts/'+$user.ke+'/register',{data:e.s},function(d){
|
||||
$.post(adminApiPrefix + $user.auth_token+'/accounts/'+$user.ke+'/register',{data:e.s},function(d){
|
||||
if(d.msg){
|
||||
e.m.text(d.msg)
|
||||
}
|
||||
|
@ -197,7 +197,7 @@ $.sU.e.on('click','.delete',function(e){
|
|||
var html = 'Do you want to delete <b>'+subAccountEmail+'</b>? You cannot recover this account.'
|
||||
$.confirm.body.html(html)
|
||||
$.confirm.click({title:'Delete',class:'btn-danger'},function(){
|
||||
$.post('<%=originalURL%><%=config.webPaths.adminApiPrefix%>'+$user.auth_token+'/accounts/'+$user.ke+'/delete',{
|
||||
$.post(adminApiPrefix + $user.auth_token+'/accounts/'+$user.ke+'/delete',{
|
||||
uid: subAccountUid,
|
||||
mail: subAccountEmail
|
||||
},function(data){})
|
||||
|
@ -269,7 +269,7 @@ $.pR.e.on('change','[monitor]',function(e){
|
|||
$.pR.f.submit(function(e){
|
||||
e.preventDefault()
|
||||
var form = $(this).serializeObject()
|
||||
$.post('<%=originalURL%><%=config.webPaths.adminApiPrefix%>'+$user.auth_token+'/accounts/'+$user.ke+'/edit',{
|
||||
$.post(adminApiPrefix + $user.auth_token+'/accounts/'+$user.ke+'/edit',{
|
||||
uid: $.pR.user,
|
||||
mail: $.ccio.subs[$.pR.user].mail,
|
||||
data: form
|
||||
|
|
|
@ -22,4 +22,4 @@
|
|||
if(!string){string=''}
|
||||
return string.replace(/'/g,"\\'")
|
||||
}%>
|
||||
<script>var subscriptionId = '<%- config.subscriptionId || 'notActivated' %>'</script>
|
||||
<script>var machineId = '<%- config.machineId || 'noMachineIdSet' %>'</script>
|
||||
|
|
|
@ -213,7 +213,7 @@ $.aN.f.submit(function(e){
|
|||
webPath = 'editAdmin'
|
||||
postData.account = $.aN.selected
|
||||
}
|
||||
$.post('<%=originalURL%><%=config.webPaths.superApiPrefix%>'+$user.sessionKey+'/accounts/'+webPath,postData,function(data){
|
||||
$.post(superApiPrefix + $user.sessionKey+'/accounts/'+webPath,postData,function(data){
|
||||
console.log(data)
|
||||
if(data.ok === true){
|
||||
$.aN.e.modal('hide')
|
||||
|
@ -295,7 +295,7 @@ $.aC.e.on('click','.delete',function(e){
|
|||
e.html='Do you want to delete <b>'+e.account.mail+'</b>? You cannot recover this account. Files will remain in the filesystem. If you choose to create an account with the same Group Key it will have the previous events activated in that account.'
|
||||
$.confirm.body.html(e.html)
|
||||
$.confirm.click({title:'Delete',class:'btn-danger'},function(){
|
||||
$.post('<%=originalURL%><%=config.webPaths.superApiPrefix%>'+$user.sessionKey+'/accounts/deleteAdmin',{
|
||||
$.post(superApiPrefix + $user.sessionKey+'/accounts/deleteAdmin',{
|
||||
account : e.account,
|
||||
// "deleteSubAccounts" : "1",
|
||||
// "deleteMonitors" : "1",
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
a {cursor:pointer}
|
||||
</style>
|
||||
<script>
|
||||
var superApiPrefix = "<%=originalURL%><%=config.webPaths.superApiPrefix%>"
|
||||
var superApiPrefix = location.search === '?p2p=1' ? location.pathname + '/' : "<%=originalURL%><%=config.webPaths.superApiPrefix%>"
|
||||
var shinobiConfig = <%- JSON.stringify(plainConfig) %>
|
||||
</script>
|
||||
<% customAutoLoad.superLibsCss.forEach(function(lib){ %>
|
||||
|
@ -173,7 +173,7 @@ switch($user.lang){
|
|||
})
|
||||
break;
|
||||
}
|
||||
if(location.search === '?assemble=1'){
|
||||
if(location.search === '?p2p=1'){
|
||||
$.ccio.ws=io(location.origin,{
|
||||
path : '/socket.io'
|
||||
});
|
||||
|
@ -184,7 +184,7 @@ if(location.search === '?assemble=1'){
|
|||
}
|
||||
$.ccio.cx=function(x){return $.ccio.ws.emit('super',x)}
|
||||
$.ccio.ws.on('connect',function(d){
|
||||
$.ccio.cx({f:'init',mail:$user.mail,pass:$user.pass})
|
||||
$.ccio.cx({f:'init',mail:$user.mail,pass:$user.pass,machineId: `<%- config.machineId %>`})
|
||||
})
|
||||
$.ccio.ws.on('f',function(d){
|
||||
switch(d.f){
|
||||
|
|
Loading…
Reference in New Issue