mirror of
https://gitlab.com/Shinobi-Systems/ShinobiCE.git
synced 2025-03-09 15:40:15 +00:00
Coy Cobra
This commit is contained in:
parent
157bf6feb0
commit
c8b67c57b4
45 changed files with 3076 additions and 144 deletions
3
plugins/python-dlib/.gitignore
vendored
Normal file
3
plugins/python-dlib/.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
conf.json
|
||||
faces
|
||||
data
|
66
plugins/python-dlib/INSTALL.sh
Normal file
66
plugins/python-dlib/INSTALL.sh
Normal file
|
@ -0,0 +1,66 @@
|
|||
#!/bin/bash
|
||||
echo "-----------------------------------------------"
|
||||
echo "-- Installing Python Dlib Plugin for Shinobi --"
|
||||
echo "-----------------------------------------------"
|
||||
echo "-----------------------------------"
|
||||
if [ ! -e "./conf.json" ]; then
|
||||
echo "Creating conf.json"
|
||||
sudo cp conf.sample.json conf.json
|
||||
else
|
||||
echo "conf.json already exists..."
|
||||
fi
|
||||
echo "-----------------------------------"
|
||||
sudo apt update -y
|
||||
echo "Installing python3"
|
||||
sudo apt install python3 python3-dev python3-pip -y
|
||||
echo "-----------------------------------"
|
||||
sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y
|
||||
sudo apt update
|
||||
sudo apt-get install gcc-6 g++-6 -y && sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-6 60 --slave /usr/bin/g++ g++ /usr/bin/g++-6
|
||||
echo "-----------------------------------"
|
||||
if ! [ -x "$(command -v nvidia-smi)" ]; then
|
||||
echo "You need to install NVIDIA Drivers to use this."
|
||||
echo "inside the Shinobi directory run the following :"
|
||||
echo "sh INSTALL/cuda9-part1.sh"
|
||||
exit 1
|
||||
else
|
||||
echo "NVIDIA Drivers found..."
|
||||
echo "$(nvidia-smi |grep 'Driver Version')"
|
||||
fi
|
||||
echo "-----------------------------------"
|
||||
if [ ! -d "/usr/local/cuda" ]; then
|
||||
echo "You need to install CUDA Toolkit to use this."
|
||||
echo "inside the Shinobi directory run the following :"
|
||||
echo "sh INSTALL/cuda9-part2-after-reboot.sh"
|
||||
exit 1
|
||||
else
|
||||
echo "CUDA Toolkit found..."
|
||||
fi
|
||||
echo "-----------------------------------"
|
||||
if ! [ -x "$(command -v opencv_version)" ]; then
|
||||
echo "You need to install OpenCV with CUDA first."
|
||||
echo "inside the Shinobi directory run the following :"
|
||||
echo "sh INSTALL/opencv-cuda.sh"
|
||||
exit 1
|
||||
else
|
||||
echo "OpenCV found... : $(opencv_version)"
|
||||
fi
|
||||
echo "-----------------------------------"
|
||||
echo "Getting new pip..."
|
||||
pip3 install --upgrade pip
|
||||
pip install --user --upgrade pip
|
||||
echo "Smoking pips..."
|
||||
pip3 install flask_socketio
|
||||
pip3 install flask
|
||||
pip3 install numpy
|
||||
pip3 install gevent gevent-websocket
|
||||
export PATH=/usr/local/cuda/bin:$PATH
|
||||
echo "Installing Dlib..."
|
||||
cd /opt
|
||||
git clone https://github.com/davisking/dlib.git dlib
|
||||
cd dlib
|
||||
cmake -DCUDA_CUDART_LIBRARY=/usr/local/cuda/lib64/libcudart.so
|
||||
make install
|
||||
pip3 install dlib
|
||||
echo "Start the plugin with pm2 like so :"
|
||||
echo "pm2 start shinobi-python-dlib.js"
|
72
plugins/python-dlib/README.md
Normal file
72
plugins/python-dlib/README.md
Normal file
|
@ -0,0 +1,72 @@
|
|||
# Python DLIB
|
||||
|
||||
> This plugin requires the use of port `7990` by default. You can specify a different port by adding `pythonPort` to your plugin's conf.json.
|
||||
|
||||
**Ubuntu and Debian only**
|
||||
|
||||
Go to the Shinobi directory. **/home/Shinobi** is the default directory.
|
||||
|
||||
```
|
||||
cd /home/Shinobi/plugins/python-dlib
|
||||
```
|
||||
|
||||
Copy the config file.
|
||||
|
||||
```
|
||||
sh INSTALL.sh
|
||||
```
|
||||
|
||||
Start the plugin.
|
||||
|
||||
```
|
||||
pm2 start shinobi-python-dlib.js
|
||||
```
|
||||
|
||||
Doing this will reveal options in the monitor configuration. Shinobi does not need to be restarted when a plugin is initiated or stopped.
|
||||
|
||||
## Run the plugin as a Host
|
||||
> The main app (Shinobi) will be the client and the plugin will be the host. The purpose of allowing this method is so that you can use one plugin for multiple Shinobi instances. Allowing you to easily manage connections without starting multiple processes.
|
||||
|
||||
Edit your plugins configuration file. Set the `hostPort` **to be different** than the `listening port for camera.js`.
|
||||
|
||||
```
|
||||
nano conf.json
|
||||
```
|
||||
|
||||
Here is a sample of a Host configuration for the plugin.
|
||||
- `plug` is the name of the plugin corresponding in the main configuration file.
|
||||
- `https` choose if you want to use SSL or not. Default is `false`.
|
||||
- `hostPort` can be any available port number. **Don't make this the same port number as Shinobi.** Default is `8082`.
|
||||
- `type` tells the main application (Shinobi) what kind of plugin it is. In this case it is a detector.
|
||||
|
||||
```
|
||||
{
|
||||
"plug":"PythonDlib",
|
||||
"hostPort":8082,
|
||||
"key":"SomeOpenALPRkeySoPeopleDontMessWithYourShinobi",
|
||||
"mode":"host",
|
||||
"type":"detector"
|
||||
}
|
||||
```
|
||||
|
||||
Now modify the **main configuration file** located in the main directory of Shinobi. *Where you currently should be.*
|
||||
|
||||
```
|
||||
nano conf.json
|
||||
```
|
||||
|
||||
Add the `plugins` array if you don't already have it. Add the following *object inside the array*.
|
||||
|
||||
```
|
||||
"plugins":[
|
||||
{
|
||||
"id" : "PythonDlib",
|
||||
"https" : false,
|
||||
"host" : "localhost",
|
||||
"port" : 8082,
|
||||
"key" : "SomeOpenALPRkeySoPeopleDontMessWithYourShinobi",
|
||||
"mode" : "host",
|
||||
"type" : "detector"
|
||||
}
|
||||
],
|
||||
```
|
1
plugins/python-dlib/bootPy.sh
Normal file
1
plugins/python-dlib/bootPy.sh
Normal file
|
@ -0,0 +1 @@
|
|||
python3 -u $@
|
10
plugins/python-dlib/conf.sample.json
Normal file
10
plugins/python-dlib/conf.sample.json
Normal file
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"plug":"PythonDlib",
|
||||
"host":"localhost",
|
||||
"port":8080,
|
||||
"pythonPort":7990,
|
||||
"hostPort":8082,
|
||||
"key":"SomeOpenALPRkeySoPeopleDontMessWithYourShinobi",
|
||||
"mode":"client",
|
||||
"type":"detector"
|
||||
}
|
18
plugins/python-dlib/package.json
Normal file
18
plugins/python-dlib/package.json
Normal file
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"name": "shinobi-python-dlib",
|
||||
"version": "1.0.0",
|
||||
"description": "DLIB plugin for Shinobi that uses Python functions for detection.",
|
||||
"main": "shinobi-python-dlib.js",
|
||||
"dependencies": {
|
||||
"socket.io-client": "^1.7.4",
|
||||
"express": "^4.16.2",
|
||||
"moment": "^2.19.2",
|
||||
"socket.io": "^2.0.4"
|
||||
},
|
||||
"devDependencies": {},
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "Moe Alam",
|
||||
"license": "ISC"
|
||||
}
|
113
plugins/python-dlib/pumpkin.py
Normal file
113
plugins/python-dlib/pumpkin.py
Normal file
|
@ -0,0 +1,113 @@
|
|||
from flask import Flask, request, jsonify, render_template
|
||||
from flask_socketio import SocketIO, emit
|
||||
from PIL import Image
|
||||
import face_recognition
|
||||
import cv2
|
||||
import os
|
||||
import json
|
||||
import numpy as np
|
||||
import sys
|
||||
|
||||
dirname = sys.argv[1]
|
||||
|
||||
try:
|
||||
with open("{}/conf.json".format(dirname)) as json_file:
|
||||
config = json.load(json_file)
|
||||
httpPort = config['pythonPort']
|
||||
try:
|
||||
httpPort
|
||||
except NameError:
|
||||
httpPort = 7990
|
||||
except Exception as e:
|
||||
print("conf.json not found.")
|
||||
httpPort = 7990
|
||||
|
||||
# Load Flask
|
||||
app = Flask("DLIB for Shinobi (Pumpkin Pie)")
|
||||
socketio = SocketIO(app)
|
||||
# Silence Flask
|
||||
# import logging
|
||||
# log = logging.getLogger('werkzeug')
|
||||
# log.setLevel(logging.ERROR)
|
||||
|
||||
#check for faces dir
|
||||
facesDir = "{}/faces/".format(dirname)
|
||||
if not os.path.exists(facesDir):
|
||||
os.makedirs(facesDir)
|
||||
|
||||
# load faces
|
||||
included_extensions = ['jpg','jpeg', 'bmp', 'png', 'gif']
|
||||
file_names = [fn for fn in os.listdir(facesDir)
|
||||
if any(fn.endswith(ext) for ext in included_extensions)]
|
||||
known_faces = []
|
||||
face_locations = []
|
||||
face_encodings = []
|
||||
face_names = []
|
||||
|
||||
for faceFile in file_names:
|
||||
face = face_recognition.load_image_file(facesDir+faceFile)
|
||||
face_encoding = face_recognition.face_encodings(face)[0]
|
||||
known_faces.append(face_encoding)
|
||||
|
||||
# detection function
|
||||
def spark(filepath):
|
||||
try:
|
||||
filepath
|
||||
except NameError:
|
||||
return "File path not found."
|
||||
img = cv2.imread(filepath)
|
||||
returnData = []
|
||||
frame = img[:, :, ::-1]
|
||||
|
||||
# Find all the faces and face encodings in the current frame of video
|
||||
face_locations = face_recognition.face_locations(frame)
|
||||
face_encodings = face_recognition.face_encodings(frame, face_locations)
|
||||
face_names = []
|
||||
for (top, right, bottom, left), face_encoding in zip(face_locations, face_encodings):
|
||||
# See if the face is a match for the known face(s)
|
||||
matrix = {}
|
||||
matrix["coordinates"] = [
|
||||
{"x" : left, "y" : top},
|
||||
{"x" : right, "y" : top},
|
||||
{"x" : right, "y" : bottom},
|
||||
{"x" : left, "y" : bottom}
|
||||
]
|
||||
(left, top), (right, bottom)
|
||||
match = face_recognition.compare_faces(known_faces, face_encoding, tolerance=0.50)
|
||||
if True in match:
|
||||
first_match_index = match.index(True)
|
||||
name = file_names[first_match_index]
|
||||
matrix["tag"] = name
|
||||
returnData.append(matrix)
|
||||
return returnData
|
||||
|
||||
# bake the image data by a file path
|
||||
# POST body contains the "img" variable. The value should be to a local image path.
|
||||
# Example : /dev/shm/streams/[GROUP_KEY]/[MONITOR_ID]/s.jpg
|
||||
@app.route('/', methods=['GET'])
|
||||
def index():
|
||||
return "Pumpkin.py is running. This web interface should NEVER be accessible remotely. The Node.js plugin that runs this script should only be allowed accessible remotely."
|
||||
|
||||
# bake the image data by a file path
|
||||
# POST body contains the "img" variable. The value should be to a local image path.
|
||||
# Example : /dev/shm/streams/[GROUP_KEY]/[MONITOR_ID]/s.jpg
|
||||
@app.route('/post', methods=['POST'])
|
||||
def post():
|
||||
filepath = request.form['img']
|
||||
return jsonify(spark(filepath))
|
||||
|
||||
# bake the image data by a file path
|
||||
# GET string contains the "img" variable. The value should be to a local image path.
|
||||
# Example : /dev/shm/streams/[GROUP_KEY]/[MONITOR_ID]/s.jpg
|
||||
@app.route('/get', methods=['GET'])
|
||||
def get():
|
||||
filepath = request.args.get('img')
|
||||
return jsonify(spark(filepath))
|
||||
|
||||
@socketio.on('f')
|
||||
def receiveMessage(message):
|
||||
emit('f',{'id':message.get("id"),'data':spark(message.get("path"))})
|
||||
|
||||
# quick-and-dirty start
|
||||
if __name__ == '__main__':
|
||||
socketio.run(app, port=httpPort)
|
292
plugins/python-dlib/shinobi-python-dlib.js
Normal file
292
plugins/python-dlib/shinobi-python-dlib.js
Normal file
|
@ -0,0 +1,292 @@
|
|||
//
|
||||
// Shinobi - Python DLIB Plugin
|
||||
// Copyright (C) 2016-2025 Moe Alam, moeiscool
|
||||
//
|
||||
// # Donate
|
||||
//
|
||||
// If you like what I am doing here and want me to continue please consider donating :)
|
||||
// PayPal : paypal@m03.ca
|
||||
//
|
||||
process.on('uncaughtException', function (err) {
|
||||
console.error('uncaughtException',err);
|
||||
});
|
||||
//main vars
|
||||
var fs=require('fs');
|
||||
var exec = require('child_process').exec;
|
||||
var spawn = require('child_process').spawn;
|
||||
var moment = require('moment');
|
||||
var http = require('http');
|
||||
var express = require('express');
|
||||
var socketIoClient = require('socket.io-client');
|
||||
var config = require('./conf.json');
|
||||
var http = require('http'),
|
||||
app = express(),
|
||||
server = http.createServer(app);
|
||||
s={
|
||||
group:{},
|
||||
dir:{},
|
||||
isWin:(process.platform==='win32'),
|
||||
s:function(json){return JSON.stringify(json,null,3)}
|
||||
}
|
||||
s.checkCorrectPathEnding=function(x){
|
||||
var length=x.length
|
||||
if(x.charAt(length-1)!=='/'){
|
||||
x=x+'/'
|
||||
}
|
||||
return x.replace('__DIR__',__dirname)
|
||||
}
|
||||
s.debugLog = function(){
|
||||
if(config.debugLog === true){
|
||||
console.log(new Date(),arguments)
|
||||
if(config.debugLogVerbose === true){
|
||||
console.log(new Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!config.port){config.port=8080}
|
||||
if(!config.pythonScript){config.pythonScript=__dirname+'/pumpkin.py'}
|
||||
if(!config.pythonPort){config.pythonPort=7990}
|
||||
if(!config.hostPort){config.hostPort=8082}
|
||||
if(config.systemLog===undefined){config.systemLog=true}
|
||||
//default stream folder check
|
||||
if(!config.streamDir){
|
||||
if(s.isWin===false){
|
||||
config.streamDir='/dev/shm'
|
||||
}else{
|
||||
config.streamDir=config.windowsTempDir
|
||||
}
|
||||
if(!fs.existsSync(config.streamDir)){
|
||||
config.streamDir=__dirname+'/streams/'
|
||||
}else{
|
||||
config.streamDir+='/streams/'
|
||||
}
|
||||
}
|
||||
s.dir.streams=config.streamDir;
|
||||
//streams dir
|
||||
if(!fs.existsSync(s.dir.streams)){
|
||||
fs.mkdirSync(s.dir.streams);
|
||||
}
|
||||
s.gid=function(x){
|
||||
if(!x){x=10};var t = "";var p = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||
for( var i=0; i < x; i++ )
|
||||
t += p.charAt(Math.floor(Math.random() * p.length));
|
||||
return t;
|
||||
};
|
||||
s.getRequest = function(url,callback){
|
||||
return http.get(url, function(res){
|
||||
var body = '';
|
||||
res.on('data', function(chunk){
|
||||
body += chunk;
|
||||
});
|
||||
res.on('end',function(){
|
||||
try{body = JSON.parse(body)}catch(err){}
|
||||
callback(body)
|
||||
});
|
||||
}).on('error', function(e){
|
||||
// s.systemLog("Get Snapshot Error", e);
|
||||
});
|
||||
}
|
||||
s.multiplerHeight = 1
|
||||
s.multiplerWidth = 1
|
||||
s.detectObject=function(buffer,d,tx){
|
||||
d.tmpFile=s.gid(5)+'.jpg'
|
||||
if(!fs.existsSync(s.dir.streams)){
|
||||
fs.mkdirSync(s.dir.streams);
|
||||
}
|
||||
d.dir=s.dir.streams+d.ke+'/'
|
||||
if(!fs.existsSync(d.dir)){
|
||||
fs.mkdirSync(d.dir);
|
||||
}
|
||||
d.dir=s.dir.streams+d.ke+'/'+d.id+'/'
|
||||
if(!fs.existsSync(d.dir)){
|
||||
fs.mkdirSync(d.dir);
|
||||
}
|
||||
fs.writeFile(d.dir+d.tmpFile,buffer,function(err){
|
||||
if(err) return s.systemLog(err);
|
||||
if(s.isPythonRunning === false){
|
||||
return console.log('Python Script is not Running.')
|
||||
}
|
||||
var callbackId = s.gid(10)
|
||||
s.group[d.ke][d.id].sendToPython({path:d.dir+d.tmpFile,id:callbackId},function(data){
|
||||
console.log('returned',data)
|
||||
if(data.length > 0){
|
||||
var mats=[]
|
||||
data.forEach(function(v){
|
||||
var width = Math.sqrt( Math.pow(v.coordinates[1].x - v.coordinates[0].x, 2) + Math.pow(v.coordinates[1].y - v.coordinates[0].y, 2));
|
||||
var height = Math.sqrt( Math.pow(v.coordinates[2].x - v.coordinates[1].x, 2) + Math.pow(v.coordinates[2].y - v.coordinates[1].y, 2))
|
||||
mats.push({
|
||||
x:v.coordinates[0].x,
|
||||
y:v.coordinates[0].y,
|
||||
width: width,
|
||||
height: height,
|
||||
confidence:v.confidence,
|
||||
tag:v.tag
|
||||
})
|
||||
})
|
||||
tx({
|
||||
f:'trigger',
|
||||
id:d.id,
|
||||
ke:d.ke,
|
||||
details:{
|
||||
plug:config.plug,
|
||||
name:'dlib',
|
||||
reason:'object',
|
||||
matrices:mats,
|
||||
imgHeight:d.mon.detector_scale_y,
|
||||
imgWidth:d.mon.detector_scale_x
|
||||
}
|
||||
})
|
||||
}
|
||||
delete(s.callbacks[callbackId])
|
||||
exec('rm -rf '+d.dir+d.tmpFile,{encoding:'utf8'})
|
||||
})
|
||||
})
|
||||
}
|
||||
s.systemLog=function(q,w,e){
|
||||
if(w===undefined){return}
|
||||
if(!w){w=''}
|
||||
if(!e){e=''}
|
||||
if(config.systemLog===true){
|
||||
return console.log(moment().format(),q,w,e)
|
||||
}
|
||||
}
|
||||
s.MainEventController=function(d,cn,tx){
|
||||
switch(d.f){
|
||||
case'init_plugin_as_host':
|
||||
if(!cn){
|
||||
console.log('No CN',d)
|
||||
return
|
||||
}
|
||||
if(d.key!==config.key){
|
||||
console.log(new Date(),'Plugin Key Mismatch',cn.request.connection.remoteAddress,d)
|
||||
cn.emit('init',{ok:false})
|
||||
cn.disconnect()
|
||||
}else{
|
||||
console.log(new Date(),'Plugin Connected to Client',cn.request.connection.remoteAddress)
|
||||
cn.emit('init',{ok:true,plug:config.plug,notice:config.notice,type:config.type})
|
||||
}
|
||||
break;
|
||||
case'init_monitor':
|
||||
if(s.group[d.ke]&&s.group[d.ke][d.id]){
|
||||
delete(s.group[d.ke][d.id].buffer)
|
||||
}
|
||||
break;
|
||||
case'frame':
|
||||
try{
|
||||
if(!s.group[d.ke]){
|
||||
s.group[d.ke]={}
|
||||
}
|
||||
if(!s.group[d.ke][d.id]){
|
||||
s.group[d.ke][d.id]={
|
||||
sendToPython : s.createCameraBridgeToPython(d.ke+d.id)
|
||||
}
|
||||
}
|
||||
if(!s.group[d.ke][d.id].buffer){
|
||||
s.group[d.ke][d.id].buffer=[d.frame];
|
||||
}else{
|
||||
s.group[d.ke][d.id].buffer.push(d.frame)
|
||||
}
|
||||
if(d.frame[d.frame.length-2] === 0xFF && d.frame[d.frame.length-1] === 0xD9){
|
||||
s.detectObject(Buffer.concat(s.group[d.ke][d.id].buffer),d,tx)
|
||||
s.group[d.ke][d.id].buffer=null;
|
||||
}
|
||||
}catch(err){
|
||||
if(err){
|
||||
s.systemLog(err)
|
||||
delete(s.group[d.ke][d.id].buffer)
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
server.listen(config.hostPort);
|
||||
//web pages and plugin api
|
||||
app.get('/', function (req, res) {
|
||||
res.end('<b>'+config.plug+'</b> for Shinobi is running')
|
||||
});
|
||||
//Conector to Shinobi
|
||||
if(config.mode==='host'){
|
||||
//start plugin as host
|
||||
var io = require('socket.io')(server);
|
||||
io.attach(server);
|
||||
s.connectedClients={};
|
||||
io.on('connection', function (cn) {
|
||||
s.connectedClients[cn.id]={id:cn.id}
|
||||
s.connectedClients[cn.id].tx = function(data){
|
||||
data.pluginKey=config.key;data.plug=config.plug;
|
||||
return io.to(cn.id).emit('ocv',data);
|
||||
}
|
||||
cn.on('f',function(d){
|
||||
s.MainEventController(d,cn,s.connectedClients[cn.id].tx)
|
||||
});
|
||||
cn.on('disconnect',function(d){
|
||||
delete(s.connectedClients[cn.id])
|
||||
})
|
||||
});
|
||||
}else{
|
||||
//start plugin as client
|
||||
if(!config.host){config.host='localhost'}
|
||||
var io = socketIoClient('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)}
|
||||
io.on('connect',function(d){
|
||||
s.cx({f:'init',plug:config.plug,notice:config.notice,type:config.type});
|
||||
})
|
||||
io.on('disconnect',function(d){
|
||||
io.connect();
|
||||
})
|
||||
io.on('f',function(d){
|
||||
s.MainEventController(d,null,s.cx)
|
||||
})
|
||||
}
|
||||
|
||||
//Start Python Controller
|
||||
s.callbacks = {}
|
||||
s.createCameraBridgeToPython = function(uniqueId){
|
||||
var pythonIo = socketIoClient('ws://localhost:'+config.pythonPort,{transports : ['websocket']});
|
||||
var sendToPython = function(data,callback){
|
||||
s.callbacks[data.id] = callback
|
||||
pythonIo.emit('f',data)
|
||||
}
|
||||
pythonIo.on('connect',function(d){
|
||||
s.debugLog(uniqueId+' is Connected from Python')
|
||||
})
|
||||
pythonIo.on('disconnect',function(d){
|
||||
s.debugLog(uniqueId+' is Disconnected from Python')
|
||||
setTimeout(function(){
|
||||
pythonIo.connect();
|
||||
s.debugLog(uniqueId+' is Attempting to Reconect to Python')
|
||||
},3000)
|
||||
})
|
||||
pythonIo.on('f',function(d){
|
||||
if(s.callbacks[d.id]){
|
||||
s.callbacks[d.id](d.data)
|
||||
delete(s.callbacks[d.id])
|
||||
}
|
||||
})
|
||||
return sendToPython
|
||||
}
|
||||
|
||||
|
||||
//Start Python Daemon
|
||||
process.env.PYTHONUNBUFFERED = 1;
|
||||
s.createPythonProcess = function(){
|
||||
s.isPythonRunning = false
|
||||
s.pythonScript = spawn('sh',[__dirname+'/bootPy.sh',config.pythonScript,__dirname]);
|
||||
var onStdErr = function(data){
|
||||
s.debugLog(data.toString())
|
||||
}
|
||||
var onStdOut = function(data){
|
||||
s.debugLog(data.toString())
|
||||
}
|
||||
setTimeout(function(){
|
||||
s.isPythonRunning = true
|
||||
},5000)
|
||||
s.pythonScript.stderr.on('data',onStdErr);
|
||||
|
||||
s.pythonScript.stdout.on('data',onStdOut);
|
||||
|
||||
s.pythonScript.on('close', function () {
|
||||
s.debugLog('Python CLOSED')
|
||||
});
|
||||
}
|
||||
s.createPythonProcess()
|
Loading…
Add table
Add a link
Reference in a new issue