2019-05-16 15:09:49 +00:00
2018-10-10 06:56:13 +00:00
var fs = require ( 'fs' ) ;
2018-09-29 01:38:14 +00:00
var moment = require ( 'moment' ) ;
var crypto = require ( 'crypto' ) ;
var exec = require ( 'child_process' ) . exec ;
var execSync = require ( 'child_process' ) . execSync ;
2019-01-28 20:25:53 +00:00
module . exports = function ( s , config , lang , io ) {
2021-01-20 04:51:39 +00:00
const {
scanForOrphanedVideos
} = require ( './video/utils.js' ) ( s , config , lang )
2021-05-21 02:09:33 +00:00
const {
checkSubscription
2021-06-09 19:52:34 +00:00
} = require ( './basic/utils.js' ) ( process . cwd ( ) , config )
2022-02-12 22:14:16 +00:00
const {
checkForStaticUsers
} = require ( './user/startup.js' ) ( s , config , lang , io )
2020-09-14 06:49:52 +00:00
return new Promise ( ( resolve , reject ) => {
var checkedAdminUsers = { }
console . log ( 'FFmpeg version : ' + s . ffmpegVersion )
console . log ( 'Node.js version : ' + process . version )
s . processReady = function ( ) {
2021-04-05 21:13:20 +00:00
s . timeReady = new Date ( )
2020-09-14 06:49:52 +00:00
delete ( checkedAdminUsers )
resolve ( )
s . systemLog ( lang . startUpText5 )
s . onProcessReadyExtensions . forEach ( function ( extender ) {
extender ( true )
} )
process . send ( 'ready' )
2019-01-13 21:42:11 +00:00
}
2020-09-14 06:49:52 +00:00
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 {
2019-01-13 21:42:11 +00:00
next ( )
2020-09-14 06:49:52 +00:00
}
}
var loadedAccounts = [ ]
var foundMonitors = [ ]
2023-07-15 05:31:33 +00:00
var loadMonitors = async function ( callback ) {
for ( let i = 0 ; i < s . beforeMonitorsLoadedOnStartupExtensions . length ; i ++ ) {
await s . beforeMonitorsLoadedOnStartupExtensions [ i ] ( )
}
2020-09-14 06:49:52 +00:00
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 ] ) {
2023-01-21 00:49:37 +00:00
setTimeout ( async function ( ) {
2020-09-14 06:49:52 +00:00
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
2021-05-04 23:24:08 +00:00
s . sendMonitorStatus ( {
id : monitor . mid ,
ke : monitor . ke ,
status : 'Stopped' ,
code : 5
} ) ;
2022-08-11 05:41:41 +00:00
const monObj = Object . assign ( { } , monitor , { id : monitor . mid } )
2023-01-21 00:49:37 +00:00
await s . camera ( 'stop' , monObj ) ;
await s . camera ( monitor . mode , monObj ) ;
2020-09-14 06:49:52 +00:00
checkAnother ( )
} , 1000 )
} else {
++ didNotLoad
checkAnother ( )
}
}
loadMonitor ( monitors [ loadCompleted ] )
} else {
callback ( )
}
2019-01-13 21:42:11 +00:00
} )
}
2021-01-20 04:51:39 +00:00
var checkForOrphanedVideos = async function ( callback ) {
2020-09-14 06:49:52 +00:00
var monitors = foundMonitors
2018-09-29 23:03:55 +00:00
if ( monitors && monitors [ 0 ] ) {
2018-10-10 23:10:59 +00:00
var loadCompleted = 0
var orphanedVideosForMonitors = { }
2021-01-20 04:51:39 +00:00
var checkForOrphanedVideosForMonitor = async function ( monitor ) {
2020-09-14 06:49:52 +00:00
if ( ! orphanedVideosForMonitors [ monitor . ke ] ) orphanedVideosForMonitors [ monitor . ke ] = { }
if ( ! orphanedVideosForMonitors [ monitor . ke ] [ monitor . mid ] ) orphanedVideosForMonitors [ monitor . ke ] [ monitor . mid ] = 0
2021-01-20 04:51:39 +00:00
try {
await fs . promises . mkdir ( s . getStreamsDirectory ( monitor ) , { recursive : true } )
} catch ( err ) {
s . debugLog ( err )
}
2021-01-26 02:55:59 +00:00
const { orphanedFilesCount } = await scanForOrphanedVideos ( monitor , { forceCheck : true } )
2021-01-20 04:51:39 +00:00
if ( orphanedFilesCount ) {
orphanedVideosForMonitors [ monitor . ke ] [ monitor . mid ] += orphanedFilesCount
}
++ loadCompleted
if ( monitors [ loadCompleted ] ) {
await checkForOrphanedVideosForMonitor ( monitors [ loadCompleted ] )
} else {
s . systemLog ( lang . startUpText6 + ' : ' + s . s ( orphanedVideosForMonitors ) )
delete ( foundMonitors )
callback ( )
}
2018-10-10 23:10:59 +00:00
}
2021-01-20 04:51:39 +00:00
await checkForOrphanedVideosForMonitor ( monitors [ loadCompleted ] )
2018-10-16 02:40:12 +00:00
} else {
callback ( )
2018-09-29 23:03:55 +00:00
}
2019-05-05 20:30:07 +00:00
}
2020-09-14 06:49:52 +00:00
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
2021-01-30 15:33:19 +00:00
s . group [ user . ke ] . sizeLimitTimelapseFramesPercent = parseFloat ( userDetails . size _timelapse _percent ) || 5
s . group [ user . ke ] . sizeLimitFileBinPercent = parseFloat ( userDetails . size _filebin _percent ) || 5
2020-07-09 04:34:12 +00:00
s . knexQuery ( {
action : "select" ,
columns : "*" ,
2020-09-14 06:49:52 +00:00
table : "Videos" ,
2020-07-09 04:34:12 +00:00
where : [
[ 'ke' , '=' , user . ke ] ,
2020-09-14 06:49:52 +00:00
[ 'status' , '!=' , 0 ] ,
2020-07-09 04:34:12 +00:00
]
2020-09-14 06:49:52 +00:00
} , function ( err , videos ) {
2020-07-09 04:34:12 +00:00
s . knexQuery ( {
action : "select" ,
columns : "*" ,
2020-09-14 06:49:52 +00:00
table : "Timelapse Frames" ,
2020-07-09 04:34:12 +00:00
where : [
[ 'ke' , '=' , user . ke ] ,
]
2020-09-14 06:49:52 +00:00
} , 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 : [ ] ,
2023-01-21 15:41:03 +00:00
timelapseFrames : [ ] ,
2020-09-14 06:49:52 +00:00
}
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 {
2023-01-21 15:41:03 +00:00
addStorageData . timelapseFrames . push ( frame )
2020-09-14 06:49:52 +00:00
}
} )
}
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" ,
where : [
[ 'ke' , '=' , user . ke ] ,
[ 'status' , '!=' , 0 ] ,
]
} , function ( err , videos ) {
2019-04-03 03:47:03 +00:00
if ( videos && videos [ 0 ] ) {
videos . forEach ( function ( video ) {
2020-09-14 06:49:52 +00:00
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
2019-04-03 03:47:03 +00:00
} )
2020-09-14 06:49:52 +00:00
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 )
2019-04-03 03:47:03 +00:00
} )
}
2020-09-14 06:49:52 +00:00
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 ) {
2022-08-17 15:45:21 +00:00
try {
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
} catch ( err ) {
s . debugLog ( err )
}
2019-04-03 03:47:03 +00:00
} )
}
2020-09-14 06:49:52 +00:00
callback ( )
2018-09-30 22:44:04 +00:00
} )
}
2020-09-14 06:49:52 +00:00
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
2023-01-21 15:41:03 +00:00
storageIndex . videoPercent = parseFloat ( storageData . videoPercent ) || parseFloat ( userDetails . size _video _percent ) || 95
storageIndex . timelapsePercent = parseFloat ( storageData . timelapsePercent ) || parseFloat ( userDetails . size _timelapse _percent ) || 5
2020-09-14 06:49:52 +00:00
var usedSpaceVideos = 0
var usedSpaceTimelapseFrames = 0
var usedSpaceFilebin = 0
2019-07-08 03:02:49 +00:00
if ( videos && videos [ 0 ] ) {
videos . forEach ( function ( video ) {
2020-09-14 06:49:52 +00:00
if ( video . details . dir === storage . value ) {
usedSpaceVideos += video . size
}
2019-07-08 03:02:49 +00:00
} )
2020-09-14 06:49:52 +00:00
}
if ( timelapseFrames && timelapseFrames [ 0 ] ) {
timelapseFrames . forEach ( function ( frame ) {
2023-01-21 15:41:03 +00:00
if ( frame . details . dir === storage . value ) {
2020-09-14 06:49:52 +00:00
usedSpaceTimelapseFrames += frame . size
}
2019-07-08 03:02:49 +00:00
} )
}
2020-09-14 06:49:52 +00:00
if ( files && files [ 0 ] ) {
files . forEach ( function ( file ) {
2022-09-14 22:35:10 +00:00
usedSpaceFilebin += file . size
2019-07-08 03:02:49 +00:00
} )
}
2020-09-14 06:49:52 +00:00
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 )
2019-04-19 00:54:07 +00:00
++ currentStorageNumber
readStorageArray ( )
2019-05-05 20:30:07 +00:00
}
2019-04-20 00:50:01 +00:00
readStorageArray ( )
2019-04-19 00:54:07 +00:00
}
2020-09-14 06:49:52 +00:00
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 ] ) {
2018-09-30 22:44:04 +00:00
users . forEach ( function ( user ) {
2020-09-14 06:49:52 +00:00
checkedAdminUsers [ user . ke ] = user
2018-09-30 22:44:04 +00:00
} )
2020-09-14 06:49:52 +00:00
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 ( )
2018-09-30 22:44:04 +00:00
} )
} )
2020-09-14 06:49:52 +00:00
} else {
s . processReady ( )
2018-09-30 22:44:04 +00:00
}
2020-09-14 06:49:52 +00:00
} )
}
config . userHasSubscribed = 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 )
2019-10-26 20:29:34 +00:00
}
2020-09-14 06:49:52 +00:00
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
2022-12-17 00:07:23 +00:00
s . preQueries ( ) . then ( ( ) => {
setTimeout ( async ( ) => {
await checkForStaticUsers ( )
//check for subscription
checkSubscription ( config . subscriptionId , function ( hasSubcribed ) {
config . userHasSubscribed = hasSubcribed
//check terminal commander
checkForTerminalCommands ( function ( ) {
//load administrators (groups)
loadAdminUsers ( function ( ) {
//load monitors (for groups)
loadMonitors ( function ( ) {
//check for orphaned videos
checkForOrphanedVideos ( ( ) => {
s . processReady ( )
} )
2020-09-14 06:49:52 +00:00
} )
2019-10-26 20:29:34 +00:00
} )
2019-05-05 20:30:07 +00:00
} )
2019-01-13 21:42:11 +00:00
} )
2022-12-17 00:07:23 +00:00
} , 1500 )
} )
2020-09-14 06:49:52 +00:00
}
} )
2018-09-29 01:38:14 +00:00
}