diff --git a/INSTALL/freenas.csh b/INSTALL/freenas.csh new file mode 100644 index 00000000..96415a60 --- /dev/null +++ b/INSTALL/freenas.csh @@ -0,0 +1,41 @@ +#!/bin/tcsh +echo "Installing updates..." +pkg update -f +pkg upgrade -y +echo "Installing packages..." +pkg install -y nano ffmpeg libav x264 x265 mysql56-server node npm +echo "Enabling mysql..." +sysrc mysql_enable=yes +service mysql-server start +echo "Cloning the official Shinobi Community Edition gitlab repo..." +git clone "https://gitlab.com/Shinobi-Systems/ShinobiCE" +cd ./ShinobiCE +echo "Adding Shinobi user to database..." +mysql -h localhost -u root -e "source sql/user.sql" +ehco "Shinobi database framework setup..." +mysql -h localhost -u root -e "source sql/framework.sql" +echo "Securing mysql..." +#/usr/local/bin/mysql_secure_installation +#mysql -h localhost -u root -e "source sql/secure_mysql.sq" +npm i npm -g +#There are some errors in here that I don't want you to see. Redirecting to dev null :D +npm install --unsafe-perm > & /dev/null +npm audit fix --force > & /dev/null +npm install pm2 -g +cp conf.sample.json conf.json +cp super.sample.json super.json +pm2 start camera.js +pm2 start cron.js +pm2 save +pm2 list +pm2 startup rcd +echo "=====================================" +echo "||===== Install Completed =====||" +echo "=====================================" +echo "|| Login with the Superuser and ||" +echo "|| create a new user at ||" +echo "|| http://THIS_JAIL_IP:8080/super ||" +echo "||===================================" +echo "|| Superuser : admin@shinobi.video ||" +echo "|| Default Password : admin ||" +echo "=====================================" diff --git a/INSTALL/ubuntu.sh b/INSTALL/ubuntu.sh index a9c5b865..b033daf1 100644 --- a/INSTALL/ubuntu.sh +++ b/INSTALL/ubuntu.sh @@ -25,55 +25,40 @@ fi #create super.json if [ ! -e "./super.json" ]; then echo "=============" - echo "Shinobi - Do you want to enable superuser access?" - echo "This may be useful if passwords are forgotten or" - echo "if you would like to limit accessibility of an" - echo "account for business scenarios." - echo "(y)es or (N)o" - read createSuperJson - if [ "$createSuperJson" = "y" ] || [ "$createSuperJson" = "Y" ]; then - echo "Default Superuser : admin@shinobi.video" - echo "Default Password : admin" - echo "* You can edit these settings in \"super.json\" located in the Shinobi directory." - sudo cp super.sample.json super.json - fi + echo "Default Superuser : admin@shinobi.video" + echo "Default Password : admin" + echo "* You can edit these settings in \"super.json\" located in the Shinobi directory." + sudo cp super.sample.json super.json fi -echo "=============" -echo "Shinobi - Do you want to Install Node.js?" -echo "(y)es or (N)o" -read nodejsinstall -if [ "$nodejsinstall" = "y" ] || [ "$nodejsinstall" = "Y" ]; then - wget https://deb.nodesource.com/setup_8.x - chmod +x setup_8.x - ./setup_8.x +if ! [ -x "$(command -v node)" ]; then + echo "=============" + echo "Shinobi - Installing Node.js" + wget https://deb.nodesource.com/setup_9.x + chmod +x setup_9.x + ./setup_9.x sudo apt install nodejs -y +else + echo "Node.js Found..." + echo "Version : $(node -v)" +fi +if ! [ -x "$(command -v npm)" ]; then + sudo apt install npm -y fi sudo apt install make -y -echo "=============" -echo "Shinobi - Do you want to Install FFMPEG?" -echo "(y)es or (N)o" -read ffmpeginstall -if [ "$ffmpeginstall" = "y" ] || [ "$ffmpeginstall" = "Y" ]; then - echo "Shinobi - Do you want to Install FFMPEG with apt or download a static version provided with npm?" - echo "(a)pt or (N)pm" - echo "Press [ENTER] for default (npm)" - read ffmpegstaticinstall - if [ "$ffmpegstaticinstall" = "a" ] || [ "$ffmpegstaticinstall" = "A" ]; then - if [ "$getubuntuversion" = "16" ] || [ "$getubuntuversion" < "16" ]; then - echo "=============" - echo "Shinobi - Get FFMPEG 3.x from ppa:jonathonf/ffmpeg-3" - sudo add-apt-repository ppa:jonathonf/ffmpeg-3 -y - sudo apt update -y && sudo apt install ffmpeg libav-tools x264 x265 -y - echo "=============" - else - echo "=============" - echo "Shinobi - Installing FFMPEG" - sudo apt install ffmpeg -y - echo "=============" - fi +if ! [ -x "$(command -v ffmpeg)" ]; then + if [ "$getubuntuversion" = "16" ] || [ "$getubuntuversion" < "16" ]; then + echo "=============" + echo "Shinobi - Get FFMPEG 3.x from ppa:jonathonf/ffmpeg-3" + sudo add-apt-repository ppa:jonathonf/ffmpeg-3 -y + sudo apt update -y && sudo apt install ffmpeg libav-tools x264 x265 -y else - sudo npm install ffbinaries + echo "=============" + echo "Shinobi - Installing FFMPEG" + sudo apt install ffmpeg -y fi +else + echo "FFmpeg Found..." + echo "Version : $(ffmpeg -version)" fi echo "=============" echo "Shinobi - Do you want to use MariaDB or SQLite3?" @@ -137,15 +122,6 @@ sudo chmod -R 755 . touch INSTALL/installed.txt dos2unix /home/Shinobi/INSTALL/shinobi ln -s /home/Shinobi/INSTALL/shinobi /usr/bin/shinobi -if [ "$mysqlDefaultData" = "y" ] || [ "$mysqlDefaultData" = "Y" ]; then - echo "=====================================" > INSTALL/installed.txt - echo "======= Login Credentials =======" >> INSTALL/installed.txt - echo "|| Username : $userEmail" >> INSTALL/installed.txt - echo "|| Password : $userPasswordPlain" >> INSTALL/installed.txt - echo "|| API Key : $apiKey" >> INSTALL/installed.txt - echo "=====================================" >> INSTALL/installed.txt - echo "=====================================" >> INSTALL/installed.txt -fi echo "Shinobi - Start Shinobi and set to start on boot?" echo "(y)es or (N)o" read startShinobi @@ -156,16 +132,6 @@ if [ "$startShinobi" = "y" ] || [ "$startShinobi" = "y" ]; then sudo pm2 save sudo pm2 list fi -if [ "$mysqlDefaultData" = "y" ] || [ "$mysqlDefaultData" = "Y" ]; then - echo "details written to INSTALL/installed.txt" - echo "=====================================" - echo "======= Login Credentials =======" - echo "|| Username : $userEmail" - echo "|| Password : $userPasswordPlain" - echo "|| API Key : $apiKey" - echo "=====================================" - echo "=====================================" -fi if [ ! "$sqliteormariadb" = "M" ] && [ ! "$sqliteormariadb" = "m" ]; then echo "=====================================" echo "||===== Install Completed =====||" diff --git a/languages/en_CA.json b/languages/en_CA.json index e72d9525..896b7793 100644 --- a/languages/en_CA.json +++ b/languages/en_CA.json @@ -649,6 +649,8 @@ "Thumbnail": "Thumbnail", "Host Type": "Host Type", "Edit": "Edit", + "Show Matrices": "Show Matrices", + "Show Matrix": "Show Matrix", "No Monitor ID Present in Form": "No Monitor ID Present in Form", "State Configuration has no monitors associated": "State Configuration has no monitors associated", "State Configuration Not Found": "State Configuration Not Found", diff --git a/libs/detector.js b/libs/detector.js index 2ea40344..eac722fa 100644 --- a/libs/detector.js +++ b/libs/detector.js @@ -53,7 +53,11 @@ module.exports = function(s,config){ var regions = s.createPamDiffRegionArray(regionJson,globalColorThreshold,globalSensitivity,fullFrame) - s.group[e.ke].mon[e.id].pamDiff = new PamDiff({grayscale: 'luminosity', regions : regions.forPam}); + s.group[e.ke].mon[e.id].pamDiff = new PamDiff({ + grayscale: 'luminosity', + regions : regions.forPam, + drawMatrix : e.details.detector_show_matrix + }); s.group[e.ke].mon[e.id].p2p = new P2P(); var sendTrigger = function(trigger){ var detectorObject = { diff --git a/libs/detectorPamDiff.js b/libs/detectorPamDiff.js index a24ef3b8..690adcc5 100644 --- a/libs/detectorPamDiff.js +++ b/libs/detectorPamDiff.js @@ -44,6 +44,7 @@ class PamDiff extends Transform { this.difference = PamDiff._parseOptions('difference', options);//global option, can be overridden per region this.percent = PamDiff._parseOptions('percent', options);//global option, can be overridden per region this.regions = PamDiff._parseOptions('regions', options);//can be no regions or a single region or multiple regions. if no regions, all pixels will be compared. + this.drawMatrix = PamDiff._parseOptions('drawMatrix', options);//can be no regions or a single region or multiple regions. if no regions, all pixels will be compared. this.callback = callback;//callback function to be called when pixel difference is detected this._parseChunk = this._parseFirstChunk;//first parsing will be reading settings and configuring internal pixel reading } @@ -331,7 +332,7 @@ class PamDiff extends Transform { * @param chunk * @private */ - _grayScalePixelDiff(chunk) { + _grayScalePixelDiffWithMatrices(chunk) { this._newPix = chunk.pixels; for (let j = 0; j < this._regionsLength; j++) { this._regions[j].topLeft = { @@ -430,6 +431,71 @@ class PamDiff extends Transform { this._oldPix = this._newPix; } + /** + * + * @param chunk + * @private + */ + _grayScalePixelDiff(chunk) { + this._newPix = chunk.pixels; + for (let y = 0, i = 0; y < this._height; y++) { + for (let x = 0; x < this._width; x++, i++) { + if (this._oldPix[i] !== this._newPix[i]) { + const diff = Math.abs(this._oldPix[i] - this._newPix[i]); + if (this._regions && diff >= this._minDiff) { + for (let j = 0; j < this._regionsLength; j++) { + if (this._pointsInPolygons[j][i] && diff >= this._regions[j].difference) { + this._regions[j].diffs++; + } + } + } else { + if (diff >= this._difference) { + this._diffs++; + } + } + } + } + } + if (this._regions) { + const regionDiffArray = []; + for (let i = 0; i < this._regionsLength; i++) { + const percent = Math.floor(100 * this._regions[i].diffs / this._regions[i].pointsLength); + if (percent >= this._regions[i].percent) { + regionDiffArray.push({name: this._regions[i].name, percent: percent}); + } + this._regions[i].diffs = 0; + } + if (regionDiffArray.length > 0) { + const data = {trigger: regionDiffArray, pam: chunk.pam}; + if (this._callback) { + this._callback(data); + } + if (this._readableState.pipesCount > 0) { + this.push(data); + } + if (this.listenerCount('diff') > 0) { + this.emit('diff', data); + } + } + } else { + const percent = Math.floor(100 * this._diffs / this._length); + if (percent >= this._percent) { + const data = {trigger: [{name: 'percent', percent: percent}], pam: chunk.pam}; + if (this._callback) { + this._callback(data); + } + if (this._readableState.pipesCount > 0) { + this.push(data); + } + if (this.listenerCount('diff') > 0) { + this.emit('diff', data); + } + } + this._diffs = 0; + } + this._oldPix = this._newPix; + } + /** * * @param chunk @@ -576,7 +642,11 @@ class PamDiff extends Transform { this._parseChunk = this._blackAndWhitePixelDiff; break; case 'grayscale' : - this._parseChunk = this._grayScalePixelDiff; + if(this.drawMatrix === "1"){ + this._parseChunk = this._grayScalePixelDiffWithMatrices; + }else{ + this._parseChunk = this._grayScalePixelDiff; + } break; case 'rgb' : this._parseChunk = this._rgbPixelDiff; diff --git a/libs/socketio.js b/libs/socketio.js index 50e8031b..c690f0ec 100644 --- a/libs/socketio.js +++ b/libs/socketio.js @@ -59,14 +59,14 @@ module.exports = function(s,config,lang,io){ var tx; //set "client" detector plugin event function cn.on('ocv',function(d){ - if(!cn.pluginEngine&&d.f==='init'){ - if(config.pluginKeys[d.plug]===d.pluginKey){ + if(!cn.pluginEngine && d.f === 'init'){ + if(config.pluginKeys[d.plug] === d.pluginKey){ s.pluginInitiatorSuccess("client",d,cn) }else{ s.pluginInitiatorFail("client",d,cn) } }else{ - if(config.pluginKeys[d.plug]===d.pluginKey){ + if(config.pluginKeys[d.plug] === d.pluginKey){ s.pluginEventController(d) }else{ cn.disconnect() diff --git a/libs/webServerAdminPaths.js b/libs/webServerAdminPaths.js index 7cebd975..7d4809ba 100644 --- a/libs/webServerAdminPaths.js +++ b/libs/webServerAdminPaths.js @@ -364,6 +364,36 @@ module.exports = function(s,config,lang,app){ },res,req) }) /** + * API : Administrator : Get Monitor State Presets List + */ + app.get([ + config.webPaths.apiPrefix+':auth/monitorStates/:ke', + config.webPaths.adminApiPrefix+':auth/monitorStates/:ke' + ],function (req,res){ + s.auth(req.params,function(user){ + var endData = { + ok : false + } + if(user.details.sub){ + endData.msg = user.lang['Not Permitted'] + s.closeJsonResponse(res,endData) + return + } + s.sqlQuery("SELECT * FROM Presets WHERE ke=? AND type=?",[req.params.ke,'monitorStates'],function(err,presets){ + if(presets && presets[0]){ + endData.ok = true + presets.forEach(function(preset){ + preset.details = JSON.parse(preset.details) + }) + endData.presets = presets + }else{ + endData.msg = user.lang['State Configuration Not Found'] + } + s.closeJsonResponse(res,endData) + }) + }) + }) + /** * API : Administrator : Change Group Preset. Currently affects Monitors only. */ app.all([ diff --git a/libs/webServerPaths.js b/libs/webServerPaths.js index c01f26fd..77b03000 100644 --- a/libs/webServerPaths.js +++ b/libs/webServerPaths.js @@ -18,6 +18,7 @@ module.exports = function(s,config,lang,app,io){ s.renderPage = function(req,res,paths,passables,callback){ passables.window = {} passables.originalURL = s.getOriginalUrl(req) + passables.config = config res.render(paths,passables,callback) } //child node proxy check diff --git a/plugins/pluginBase.js b/plugins/pluginBase.js index 5ac89ec4..a80ee5e7 100644 --- a/plugins/pluginBase.js +++ b/plugins/pluginBase.js @@ -217,11 +217,25 @@ module.exports = function(__dirname,config){ }else{ var retryConnection = 0 maxRetryConnection = config.maxRetryConnection || 5 - plugLog('Plugin starting as Client') + plugLog('Plugin starting as Client, Host Address : '+'ws://'+config.host+':'+config.port) //start plugin as client if(!config.host){config.host='localhost'} - var io = require('socket.io-client')('ws://'+config.host+':'+config.port);//connect to master - s.cx=function(x){x.pluginKey=config.key;x.plug=config.plug;return io.emit('ocv',x)} + var io = require('socket.io-client')('ws://'+config.host+':'+config.port,{ + transports: ['websocket'] + }); + //connect to master + s.cx = function(x){ + var sendData = Object.assign(x,{ + pluginKey : config.key, + plug : config.plug + }) + return io.emit('ocv',sendData) + } + io.on('connect_error', function(err){ + plugLog('ws://'+config.host+':'+config.port) + plugLog('Connection Failed') + plugLog(err) + }) io.on('connect',function(d){ s.cx({f:'init',plug:config.plug,notice:config.notice,type:config.type,connectionType:config.connectionType}); }) diff --git a/plugins/yolo/INSTALL.sh b/plugins/yolo/INSTALL.sh index e095c293..f2f50030 100644 --- a/plugins/yolo/INSTALL.sh +++ b/plugins/yolo/INSTALL.sh @@ -19,8 +19,15 @@ if [ ! -d "/usr/local/cuda" ]; then exit 1 else echo "CUDA Toolkit found..." - export PATH=/usr/local/cuda/bin:$PATH - export LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH + echo "=============" + echo "Shinobi - Do you want to install the plugin with CUDA support?" + echo "Do this if you installed NVIDIA Drivers, CUDA Toolkit, and CuDNN" + echo "(y)es or (N)o" + read usecuda + if [ "$usecuda" = "y" ] || [ "$usecuda" = "Y" ]; then + export PATH=/usr/local/cuda/bin:$PATH + export LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH + fi fi echo "-----------------------------------" if ! [ -x "$(command -v opencv_version)" ]; then @@ -73,7 +80,6 @@ else echo "conf.json already exists..." fi echo "-----------------------------------" -echo "Getting Imagemagick" if [ -f /etc/redhat-release ]; then yum update yum install imagemagick -y @@ -90,6 +96,7 @@ echo "-----------------------------------" echo "Getting C++ module : node-yolo-shinobi" echo "https://www.npmjs.com/package/node-yolo-shinobi is a fork of https://github.com/rcaceiro/node-yolo" npm install --unsafe-perm +npm install node-yolo-shinobi --unsafe-perm npm audit fix --force echo "-----------------------------------" echo "Start the plugin with pm2 like so :" diff --git a/plugins/yolo/package.json b/plugins/yolo/package.json index 056354d4..382d3e97 100644 --- a/plugins/yolo/package.json +++ b/plugins/yolo/package.json @@ -1,6 +1,6 @@ { "name": "shinobi-yolo", - "version": "1.0.0", + "version": "2.0.0", "description": "YoloV3 plugin for Shinobi that uses C++ functions for detection.", "main": "shinobi-yolo.js", "dependencies": { @@ -8,7 +8,8 @@ "express": "^4.16.2", "moment": "^2.19.2", "socket.io": "^2.0.4", - "node-yolo-shinobi": "1.2.4" + "imagickal": "^4.0.0", + "node-yolo-shinobi": "^2.0.3" }, "devDependencies": {}, "scripts": { diff --git a/web/pages/blocks/monitoredit.ejs b/web/pages/blocks/monitoredit.ejs index d112d56e..c83a5fda 100644 --- a/web/pages/blocks/monitoredit.ejs +++ b/web/pages/blocks/monitoredit.ejs @@ -1065,6 +1065,14 @@ +