Merge branch 'dev' into generic-face-manager
# Conflicts: # libs/system/utils.js # libs/webServerSuperPaths.js # tools/modifyConfiguration.jsface-manager-integrated
commit
95de2f6348
|
@ -33,6 +33,8 @@ docker-latest-build:
|
|||
- docker push "$CI_REGISTRY_IMAGE${tag}"
|
||||
# Run this job in a branch where a Dockerfile exists
|
||||
rules:
|
||||
- if: $CI_COMMIT_BRANCH != "master" && $CI_COMMIT_BRANCH != "main" && $CI_COMMIT_BRANCH != "dev"
|
||||
when: never
|
||||
- if: $CI_COMMIT_BRANCH
|
||||
exists:
|
||||
- Dockerfile
|
||||
|
@ -60,6 +62,8 @@ docker-arm32v7-build:
|
|||
- docker push "$CI_REGISTRY_IMAGE${tag}"
|
||||
# Run this job in a branch where a Dockerfile exists
|
||||
rules:
|
||||
- if: $CI_COMMIT_BRANCH != "master" && $CI_COMMIT_BRANCH != "main" && $CI_COMMIT_BRANCH != "dev"
|
||||
when: never
|
||||
- if: $CI_COMMIT_BRANCH
|
||||
exists:
|
||||
- Dockerfile.arm32v7
|
||||
|
@ -88,6 +92,8 @@ docker-nvidia-build:
|
|||
- docker push "$CI_REGISTRY_IMAGE${tag}"
|
||||
# Run this job in a branch where a Dockerfile exists
|
||||
rules:
|
||||
- if: $CI_COMMIT_BRANCH != "master" && $CI_COMMIT_BRANCH != "main" && $CI_COMMIT_BRANCH != "dev"
|
||||
when: never
|
||||
- if: $CI_COMMIT_BRANCH
|
||||
exists:
|
||||
- Dockerfile.nvidia
|
||||
|
|
|
@ -4,22 +4,22 @@ echo "-- Installing CUDA Toolkit and CUDA DNN --"
|
|||
echo "------------------------------------------"
|
||||
# Install CUDA Drivers and Toolkit
|
||||
if [ -x "$(command -v apt)" ]; then
|
||||
wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/cuda-ubuntu2004.pin
|
||||
sudo mv cuda-ubuntu2004.pin /etc/apt/preferences.d/cuda-repository-pin-600
|
||||
wget http://developer.download.nvidia.com/compute/cuda/11.0.2/local_installers/cuda-repo-ubuntu2004-11-0-local_11.0.2-450.51.05-1_amd64.deb
|
||||
sudo dpkg -i cuda-repo-ubuntu2004-11-0-local_11.0.2-450.51.05-1_amd64.deb
|
||||
sudo apt-key add /var/cuda-repo-ubuntu2004-11-0-local/7fa2af80.pub
|
||||
# CUDA Toolkit
|
||||
echo "Choose to Install CUDA Toolkit without Drivers!"
|
||||
wget https://developer.download.nvidia.com/compute/cuda/11.2.0/local_installers/cuda_11.2.0_460.27.04_linux.run
|
||||
sudo sh cuda_11.2.0_460.27.04_linux.run
|
||||
cudaLibPath="/usr/local/cuda-11.2/lib64"
|
||||
grep -qxF $cudaLibPath /etc/ld.so.conf || echo "$cudaLibPath" >> /etc/ld.so.conf
|
||||
sudo ldconfig
|
||||
|
||||
sudo apt-get update -y
|
||||
|
||||
sudo apt-get -o Dpkg::Options::="--force-overwrite" install cuda-toolkit-11-0 -y --no-install-recommends
|
||||
sudo apt-get -o Dpkg::Options::="--force-overwrite" install --fix-broken -y
|
||||
sudo apt install nvidia-utils-495 nvidia-headless-495 -y
|
||||
# Driver
|
||||
echo "Installing nvidia-driver-515-server"
|
||||
sudo apt install nvidia-driver-515-server
|
||||
|
||||
# Install CUDA DNN
|
||||
wget https://cdn.shinobi.video/installers/libcudnn8_8.2.1.32-1+cuda11.3_amd64.deb -O cuda-dnn.deb
|
||||
wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/libcudnn8_8.1.1.33-1+cuda11.2_amd64.deb -O cuda-dnn.deb
|
||||
sudo dpkg -i cuda-dnn.deb
|
||||
wget https://cdn.shinobi.video/installers/libcudnn8-dev_8.2.0.53-1+cuda11.3_amd64.deb -O cuda-dnn-dev.deb
|
||||
wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/libcudnn8-dev_8.1.1.33-1+cuda11.2_amd64.deb -O cuda-dnn-dev.deb
|
||||
sudo dpkg -i cuda-dnn-dev.deb
|
||||
echo "-- Cleaning Up --"
|
||||
# Cleanup
|
||||
|
|
|
@ -708,6 +708,7 @@
|
|||
"Height": "Height",
|
||||
"Rotate": "Rotate",
|
||||
"Trigger Event": "Trigger Event",
|
||||
"Test": "Test",
|
||||
"Test Object Event": "Test Object Event",
|
||||
"Test Motion Event": "Test Motion Event",
|
||||
"Primary Engine": "Primary Engine",
|
||||
|
|
|
@ -311,27 +311,27 @@ module.exports = function(jsonData,pamDiffResponder,alternatePamDiff){
|
|||
}
|
||||
function checkTriggerThreshold(triggerLabel){
|
||||
const threshold = regionTriggerThresholds[triggerLabel] || globalThreshold
|
||||
if (threshold <= 1) {
|
||||
if(threshold <= 1){
|
||||
return true
|
||||
} else {
|
||||
if (triggerTimer[triggerLabel] === undefined) {
|
||||
}else{
|
||||
if(triggerTimer[triggerLabel] === undefined){
|
||||
triggerTimer[triggerLabel] = {
|
||||
count : threshold,
|
||||
timeout : null
|
||||
}
|
||||
}
|
||||
const theTriggerTimerInfo = triggerTimer[triggerLabel]
|
||||
if (--theTriggerTimerInfo.count == 0) {
|
||||
if(--theTriggerTimerInfo.count == 0){
|
||||
clearTimeout(theTriggerTimerInfo.timeout)
|
||||
theTriggerTimerInfo = undefined
|
||||
return true
|
||||
} else {
|
||||
if (theTriggerTimerInfo.timeout !== null){
|
||||
}else{
|
||||
if(theTriggerTimerInfo.timeout !== null){
|
||||
clearTimeout(theTriggerTimerInfo.timeout)
|
||||
}
|
||||
theTriggerTimerInfo.timeout = setTimeout(function() {
|
||||
theTriggerTimerInfo.timeout = setTimeout(function(){
|
||||
triggerTimer[triggerLabel] = undefined
|
||||
}, ((threshold+0.5) * 1000) / detectorFrameRate)
|
||||
},((threshold+0.5) * 1000) / detectorFrameRate)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
|
|
@ -321,6 +321,7 @@ module.exports = (s,config,lang) => {
|
|||
const monitorCaptureRate = !isNaN(parseFloat(e.details.sfps)) && e.details.sfps !== '0' ? parseFloat(e.details.sfps) : null
|
||||
const logLevel = e.details.loglevel ? e.details.loglevel : 'warning'
|
||||
const casualDecodingRequired = e.type === 'mp4' || e.type === 'mjpeg'
|
||||
const inputMaps = s.parseJSON(e.details.input_maps) || []
|
||||
if(e.details.cust_input)inputFlags.push(e.details.cust_input)
|
||||
if(useWallclockTimestamp && inputTypeIsH264 && !arrayContains('-use_wallclock_as_timestamps',inputFlags)){
|
||||
inputFlags.push('-use_wallclock_as_timestamps 1')
|
||||
|
@ -368,8 +369,8 @@ module.exports = (s,config,lang) => {
|
|||
inputFlags.push(`-re`)
|
||||
}
|
||||
inputFlags.push(buildConnectionFlagsFromConfiguration(e))
|
||||
if(e.details.input_maps){
|
||||
e.details.input_maps.forEach(function(v,n){
|
||||
if(inputMaps){
|
||||
inputMaps.forEach(function(v,n){
|
||||
inputFlags.push(createInputMap(e,n+1,v))
|
||||
})
|
||||
}
|
||||
|
@ -392,6 +393,7 @@ module.exports = (s,config,lang) => {
|
|||
const outputCanHaveAudio = config.outputsWithAudio.indexOf(streamType) > -1;
|
||||
const outputRequiresEncoding = streamType === 'mjpeg' || streamType === 'b64'
|
||||
const outputIsPresetCapable = outputCanHaveAudio
|
||||
const streamChannels = s.parseJSON(e.details.stream_channels) || []
|
||||
const { videoWidth, videoHeight } = validateDimensions(e.details.stream_scale_x,e.details.stream_scale_y)
|
||||
if(inputMap)streamFlags.push(inputMap)
|
||||
if(e.details.cust_stream)streamFlags.push(e.details.cust_stream)
|
||||
|
@ -480,8 +482,8 @@ module.exports = (s,config,lang) => {
|
|||
if(e.details.custom_output){
|
||||
streamFlags.push(e.details.custom_output)
|
||||
}
|
||||
if(e.details.stream_channels){
|
||||
e.details.stream_channels.forEach(function(v,n){
|
||||
if(streamChannels){
|
||||
streamChannels.forEach(function(v,n){
|
||||
streamFlags.push(createStreamChannel(e,n + config.pipeAddition,v))
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1075,10 +1075,10 @@ module.exports = function(s,config,lang){
|
|||
},1000)
|
||||
break;
|
||||
case checkLog(d,'Immediate exit requested'):
|
||||
cameraDestroy(e)
|
||||
activeMonitor.timeoutToRestart = setTimeout(() => {
|
||||
launchMonitorProcesses(e)
|
||||
},15000)
|
||||
cameraDestroy(e)
|
||||
break;
|
||||
case checkLog(d,'mjpeg_decode_dc'):
|
||||
case checkLog(d,'bad vlc'):
|
||||
|
|
|
@ -236,7 +236,7 @@ module.exports = function(s,config,lang,app,io){
|
|||
plug: v.id,
|
||||
type: v.type
|
||||
}
|
||||
if(v.enabled===false){return}
|
||||
if(!v.enabled){return}
|
||||
if(v.mode==='host'){
|
||||
//is in host mode (camera.js is client)
|
||||
if(v.https===true){
|
||||
|
|
|
@ -2,6 +2,7 @@ const fs = require('fs-extra');
|
|||
const express = require('express')
|
||||
const unzipper = require('unzipper')
|
||||
const spawn = require('child_process').spawn
|
||||
const exec = require('child_process').execSync
|
||||
const {
|
||||
Worker
|
||||
} = require('worker_threads');
|
||||
|
@ -22,6 +23,7 @@ module.exports = async (s,config,lang,app,io,currentUse) => {
|
|||
} = require('../events/utils.js')(s,config,lang)
|
||||
const runningPluginWorkers = {}
|
||||
const runningInstallProcesses = {}
|
||||
const runningTestProcesses = {}
|
||||
const modulesBasePath = process.cwd() + '/plugins/'
|
||||
const extractNameFromPackage = (filePath) => {
|
||||
const filePathParts = filePath.split('/')
|
||||
|
@ -59,12 +61,16 @@ module.exports = async (s,config,lang,app,io,currentUse) => {
|
|||
size: stats.size,
|
||||
lastModified: stats.mtime,
|
||||
created: stats.ctime,
|
||||
hasTester: false,
|
||||
}
|
||||
var hasInstaller = false
|
||||
if(!fs.existsSync(modulePath + '/index.js')){
|
||||
hasInstaller = true
|
||||
newModule.noIndex = true
|
||||
}
|
||||
if(fs.existsSync(modulePath + '/test.js')){
|
||||
newModule.hasTester = true
|
||||
}
|
||||
//package.json
|
||||
if(fs.existsSync(modulePath + '/package.json')){
|
||||
hasInstaller = true
|
||||
|
@ -77,6 +83,7 @@ module.exports = async (s,config,lang,app,io,currentUse) => {
|
|||
//conf.json
|
||||
newModule.config = getModuleConfiguration(moduleName)
|
||||
newModule.hasInstaller = hasInstaller
|
||||
newModule.installerRunning = !!runningInstallProcesses[moduleName]
|
||||
}
|
||||
return newModule
|
||||
}
|
||||
|
@ -89,7 +96,11 @@ module.exports = async (s,config,lang,app,io,currentUse) => {
|
|||
}
|
||||
const downloadModule = (downloadUrl,packageName) => {
|
||||
const downloadPath = modulesBasePath + packageName
|
||||
fs.mkdirSync(downloadPath)
|
||||
try{
|
||||
fs.mkdirSync(downloadPath)
|
||||
}catch(err){
|
||||
s.debugLog(err)
|
||||
}
|
||||
return new Promise(async (resolve, reject) => {
|
||||
fs.mkdir(downloadPath, () => {
|
||||
fetchDownloadAndWrite(downloadUrl,downloadPath + '.zip', 1)
|
||||
|
@ -114,6 +125,7 @@ module.exports = async (s,config,lang,app,io,currentUse) => {
|
|||
fs.remove(downloadPath + '.zip', () => {})
|
||||
resolve()
|
||||
})
|
||||
.catch(reject)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -135,31 +147,37 @@ module.exports = async (s,config,lang,app,io,currentUse) => {
|
|||
const installerPath = modulePath + `INSTALL.sh`
|
||||
const propertiesPath = modulePath + 'package.json'
|
||||
var installProcess
|
||||
// check for INSTALL.sh (ubuntu only)
|
||||
const tempRunPath = `${process.cwd()}/plugin-install-${name}.sh`
|
||||
if(fs.existsSync(installerPath)){
|
||||
installProcess = spawn(`sh`,[installerPath])
|
||||
// check for INSTALL.sh (ubuntu only)
|
||||
fs.writeFileSync(tempRunPath,`cd "${modulePath}" && sh INSTALL.sh && echo "Done!"`)
|
||||
}else if(fs.existsSync(propertiesPath)){
|
||||
// no INSTALL.sh found, check for package.json and do `npm install --unsafe-perm`
|
||||
installProcess = spawn(`npm`,['install','--unsafe-perm','--prefix',modulePath])
|
||||
fs.writeFileSync(tempRunPath,`cd "${modulePath}" && npm install && echo "Done!"`)
|
||||
}else{
|
||||
fs.writeFileSync(tempRunPath,`echo "No Installer Found"`)
|
||||
}
|
||||
installProcess = spawn(`sh`,[tempRunPath])
|
||||
fs.rm(tempRunPath,function(err){s.debugLog(err)})
|
||||
if(installProcess){
|
||||
const sendData = (data,channel) => {
|
||||
const clientData = {
|
||||
f: 'plugin-info',
|
||||
module: name,
|
||||
process: 'install-' + channel,
|
||||
data: data.toString(),
|
||||
data: data,
|
||||
}
|
||||
s.tx(clientData,'$')
|
||||
s.debugLog(clientData)
|
||||
}
|
||||
installProcess.stderr.on('data',(data) => {
|
||||
sendData(data,'stderr')
|
||||
sendData(data.toString(),'stderr')
|
||||
})
|
||||
installProcess.stdout.on('data',(data) => {
|
||||
sendData(data,'stdout')
|
||||
sendData(data.toString(),'stdout')
|
||||
})
|
||||
installProcess.on('exit',(data) => {
|
||||
sendData('#END_PROCESS','stdout')
|
||||
runningInstallProcesses[name] = null;
|
||||
})
|
||||
runningInstallProcesses[name] = installProcess
|
||||
|
@ -170,7 +188,49 @@ module.exports = async (s,config,lang,app,io,currentUse) => {
|
|||
}
|
||||
})
|
||||
}
|
||||
const disableModule = (name,status) => {
|
||||
const testModule = (name) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
if(!runningTestProcesses[name]){
|
||||
//depending on module this may only work for Ubuntu
|
||||
const modulePath = getModulePath(name)
|
||||
const testScriptPath = modulePath + `test.js`
|
||||
var testProcess
|
||||
const tempRunPath = `${process.cwd()}/plugin-test-${name}.sh`
|
||||
if(fs.existsSync(testScriptPath)){
|
||||
fs.writeFileSync(tempRunPath,`cd "${modulePath}" && node test.js && echo "Done!"`)
|
||||
testProcess = spawn(`sh`,[tempRunPath])
|
||||
fs.rm(tempRunPath,function(err){s.debugLog(err)})
|
||||
if(testProcess){
|
||||
const sendData = (data,channel) => {
|
||||
const clientData = {
|
||||
f: 'plugin-info',
|
||||
module: name,
|
||||
process: 'test-' + channel,
|
||||
data: data,
|
||||
}
|
||||
s.tx(clientData,'$')
|
||||
s.debugLog(clientData)
|
||||
}
|
||||
testProcess.stderr.on('data',(data) => {
|
||||
sendData(data.toString(),'stderr')
|
||||
})
|
||||
testProcess.stdout.on('data',(data) => {
|
||||
sendData(data.toString(),'stdout')
|
||||
})
|
||||
testProcess.on('exit',(data) => {
|
||||
sendData('#END_PROCESS','stdout')
|
||||
runningTestProcesses[name] = null;
|
||||
})
|
||||
runningTestProcesses[name] = testProcess
|
||||
}
|
||||
}
|
||||
resolve()
|
||||
}else{
|
||||
resolve('Already Testing...')
|
||||
}
|
||||
})
|
||||
}
|
||||
const enableModule = (name,status) => {
|
||||
// set status to `false` to enable
|
||||
const modulePath = getModulePath(name)
|
||||
const confJson = getModuleConfiguration(name)
|
||||
|
@ -183,7 +243,7 @@ module.exports = async (s,config,lang,app,io,currentUse) => {
|
|||
try{
|
||||
const modulePath = modulesBasePath + name
|
||||
fs.remove(modulePath, (err) => {
|
||||
console.log(err)
|
||||
if(err)console.log(err)
|
||||
})
|
||||
return true
|
||||
}catch(err){
|
||||
|
@ -256,10 +316,10 @@ module.exports = async (s,config,lang,app,io,currentUse) => {
|
|||
});
|
||||
runningPluginWorkers[moduleName] = worker
|
||||
}
|
||||
const moveModuleToNameInProperties = (modulePath,packageRoot,properties) => {
|
||||
const moveModuleToNameInProperties = (modulePath,packageRoot) => {
|
||||
return new Promise((resolve,reject) => {
|
||||
const packageRootParts = packageRoot.split('/')
|
||||
const filename = packageRootParts[packageRootParts.length - 1]
|
||||
const filename = `dl_${packageRootParts[packageRootParts.length - 1]}`
|
||||
fs.move(modulePath + packageRoot,modulesBasePath + filename,(err) => {
|
||||
if(packageRoot){
|
||||
fs.remove(modulePath, (err) => {
|
||||
|
@ -309,16 +369,21 @@ module.exports = async (s,config,lang,app,io,currentUse) => {
|
|||
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)
|
||||
s.debugLog('Downloaded',packageName,url)
|
||||
const newName = await moveModuleToNameInProperties(modulePath,packageRoot)
|
||||
const properties = getModuleProperties(newName)
|
||||
s.debugLog('properties',properties)
|
||||
s.debugLog('moveModuleToNameInProperties',newName)
|
||||
const chosenName = newName ? newName : packageName
|
||||
disableModule(chosenName,true)
|
||||
enableModule(chosenName,false)
|
||||
s.debugLog('Plugin Ready to Use!',newName,url)
|
||||
s.closeJsonResponse(res,{
|
||||
ok: true,
|
||||
moduleName: chosenName,
|
||||
newModule: getModule(chosenName)
|
||||
})
|
||||
}catch(err){
|
||||
console.error(err)
|
||||
s.closeJsonResponse(res,{
|
||||
ok: false,
|
||||
error: err
|
||||
|
@ -341,7 +406,7 @@ module.exports = async (s,config,lang,app,io,currentUse) => {
|
|||
// const newName = await moveModuleToNameInProperties(modulePath,packageRoot,properties)
|
||||
// const chosenName = newName ? newName : packageName
|
||||
//
|
||||
// disableModule(chosenName,true)
|
||||
// enableModule(chosenName,true)
|
||||
// s.closeJsonResponse(res,{
|
||||
// ok: true,
|
||||
// moduleName: chosenName,
|
||||
|
@ -376,6 +441,26 @@ module.exports = async (s,config,lang,app,io,currentUse) => {
|
|||
},res,req)
|
||||
})
|
||||
/**
|
||||
* API : Superuser : Custom Auto Load Package Test (node test.js).
|
||||
*/
|
||||
app.post(config.webPaths.superApiPrefix+':auth/plugins/test', (req,res) => {
|
||||
s.superAuth(req.params, async (resp) => {
|
||||
const packageName = req.body.packageName
|
||||
const cancelInstall = req.body.cancelTest === 'true' ? true : false
|
||||
const response = {ok: true}
|
||||
if(runningTestProcesses[packageName] && cancelTest){
|
||||
runningTestProcesses[packageName].kill('SIGTERM')
|
||||
}else{
|
||||
const error = await testModule(packageName)
|
||||
if(error){
|
||||
response.ok = false
|
||||
response.msg = error
|
||||
}
|
||||
}
|
||||
s.closeJsonResponse(res,response)
|
||||
},res,req)
|
||||
})
|
||||
/**
|
||||
* API : Superuser : Interact with Installer
|
||||
*/
|
||||
app.post(config.webPaths.superApiPrefix+':auth/plugins/command', (req,res) => {
|
||||
|
@ -437,7 +522,7 @@ module.exports = async (s,config,lang,app,io,currentUse) => {
|
|||
const packageName = req.body.packageName
|
||||
const selection = status == 'true' ? true : false
|
||||
const theModule = getModule(packageName)
|
||||
disableModule(packageName,selection)
|
||||
enableModule(packageName,selection)
|
||||
if(theModule.config.hotLoadable === true){
|
||||
if(!selection){
|
||||
loadModule(theModule)
|
||||
|
|
|
@ -23,10 +23,10 @@ module.exports = (config) => {
|
|||
return response
|
||||
},
|
||||
getConfiguration: () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
return new Promise((resolve,reject) => {
|
||||
const configPath = config.thisIsDocker ? "/config/conf.json" : s.location.config;
|
||||
|
||||
fs.readFile(configPath, 'utf8', (err,data) => {
|
||||
fs.readFile(configPath, 'utf8', (err, data) => {
|
||||
resolve(JSON.parse(data))
|
||||
});
|
||||
});
|
||||
|
@ -37,7 +37,7 @@ module.exports = (config) => {
|
|||
|
||||
const configPath = config.thisIsDocker ? "/config/conf.json" : s.location.config;
|
||||
const configData = JSON.stringify(postBody,null,3);
|
||||
console.log(postBody)
|
||||
|
||||
fs.writeFile(configPath, configData, resolve);
|
||||
});
|
||||
},
|
||||
|
|
|
@ -252,8 +252,9 @@ module.exports = function(s,config,lang,app){
|
|||
//update master list in system
|
||||
const configPath = config.thisIsDocker ? "/config/super.json" : s.location.super;
|
||||
const configData = JSON.stringify(postBody,null,3);
|
||||
|
||||
fs.writeFile(configPath, configData, () => {
|
||||
s.tx({f:'save_preferences'},'$')
|
||||
s.tx({f: 'save_preferences'},'$')
|
||||
});
|
||||
|
||||
}else{
|
||||
|
|
|
@ -1,4 +1 @@
|
|||
opencv-python
|
||||
ccv
|
||||
stemkoski
|
||||
variantai
|
||||
dl_*
|
||||
|
|
|
@ -59,7 +59,7 @@ processArgv.forEach(function(val) {
|
|||
const configPath = config.thisIsDocker ? "/config/conf.json" : configLocation;
|
||||
const configData = JSON.stringify(config,null,3);
|
||||
|
||||
fs.writeFile(configPath, configData, () =>{
|
||||
console.log('Changes Complete. Here is what it is now.')
|
||||
console.log(JSON.stringify(config,null,2))
|
||||
});
|
||||
fs.writeFile(configPath, configData, () => {
|
||||
onsole.log('Changes Complete. Here is what it is now.');
|
||||
console.log(JSON.stringify(config, null, 2));
|
||||
});
|
|
@ -1,22 +1,24 @@
|
|||
$(document).ready(function(){
|
||||
var loadedModules = {}
|
||||
var listElement = $('#pluginManagerList')
|
||||
var quickSelect = $('#pluginQuickSelect')
|
||||
var pluginDownloadForm = $('#downloadNewPlugin')
|
||||
var getModules = function(callback) {
|
||||
$.get(superApiPrefix + $user.sessionKey + '/plugins/list',callback)
|
||||
}
|
||||
var loadedBlocks = {}
|
||||
var drawModuleBlock = function(module){
|
||||
var humanName = module.properties.name ? module.properties.name : module.name
|
||||
if(listElement.find('[package-name="${module.name}"]').length > 0){
|
||||
if(listElement.find(`[package-name="${module.name}"]`).length > 0){
|
||||
var existingElement = listElement.find('[package-name="${module.name}"]')
|
||||
existingElement.find('.title').text(humanName)
|
||||
existingElement.find('[plugin-manager-action="status"]').text(!module.config.enabled ? lang.Enable : lang.Disable)
|
||||
}else{
|
||||
listElement.append(`
|
||||
<div class="col-md-12">
|
||||
listElement.prepend(`
|
||||
<div class="card bg-dark text-white mb-3" package-name="${module.name}">
|
||||
<div class="card-body pb-3">
|
||||
<div><h4 class="title mt-0">${humanName}</h4></div>
|
||||
<div><h4 class="title my-0">${humanName}</h4></div>
|
||||
<div clas="mb-2"><small>${module.name}</small></div>
|
||||
<div class="pb-2"><b>${lang['Time Created']} :</b> ${module.created}</div>
|
||||
<div class="pb-2"><b>${lang['Last Modified']} :</b> ${module.lastModified}</div>
|
||||
<div class="mb-2">
|
||||
|
@ -24,6 +26,10 @@ $(document).ready(function(){
|
|||
<a class="btn btn-sm btn-info" plugin-manager-action="install">${lang['Run Installer']}</a>
|
||||
<a class="btn btn-sm btn-danger" style="display:none" plugin-manager-action="cancelInstall">${lang['Stop']}</a>
|
||||
` : ''}
|
||||
${module.hasTester ? `
|
||||
<a class="btn btn-sm btn-default" plugin-manager-action="test">${lang['Test']}</a>
|
||||
<a class="btn btn-sm btn-danger" style="display:none" plugin-manager-action="cancelTest">${lang['Stop']}</a>
|
||||
` : ''}
|
||||
<a class="btn btn-sm btn-default" plugin-manager-action="status">${!module.config.enabled ? lang.Enable : lang.Disable}</a>
|
||||
<a class="btn btn-sm btn-danger" plugin-manager-action="delete">${lang.Delete}</a>
|
||||
<a class="btn btn-sm btn-warning" plugin-manager-action="editConfig">${lang[`Edit Configuration`]}</a>
|
||||
|
@ -43,8 +49,7 @@ $(document).ready(function(){
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>`)
|
||||
</div>`)
|
||||
var newBlock = $(`.card[package-name="${module.name}"]`)
|
||||
loadedBlocks[module.name] = {
|
||||
block: newBlock,
|
||||
|
@ -56,7 +61,7 @@ $(document).ready(function(){
|
|||
var downloadModule = function(url,packageRoot,callback){
|
||||
$.confirm.create({
|
||||
title: 'Module Download',
|
||||
body: `Do you want to download the module from ${url}? `,
|
||||
body: `Do you want to download the module from <b>${url}</b>? `,
|
||||
clickOptions: {
|
||||
class: 'btn-success',
|
||||
title: lang.Download,
|
||||
|
@ -86,6 +91,23 @@ $(document).ready(function(){
|
|||
}
|
||||
})
|
||||
}
|
||||
var testModule = function(packageName,callback){
|
||||
$.confirm.create({
|
||||
title: 'Test Module',
|
||||
body: `Do you want to test the module ${packageName}?`,
|
||||
clickOptions: {
|
||||
class: 'btn-success',
|
||||
title: lang.Test,
|
||||
},
|
||||
clickCallback: function(){
|
||||
loadedBlocks[packageName].stdout.empty()
|
||||
loadedBlocks[packageName].stderr.empty()
|
||||
$.post(superApiPrefix + $user.sessionKey + '/plugins/test',{
|
||||
packageName: packageName,
|
||||
},callback)
|
||||
}
|
||||
})
|
||||
}
|
||||
var deleteModule = function(packageName,callback){
|
||||
$.confirm.create({
|
||||
title: 'Delete Module',
|
||||
|
@ -139,6 +161,10 @@ $(document).ready(function(){
|
|||
action: 'install',
|
||||
show: false,
|
||||
},
|
||||
{
|
||||
action: 'test',
|
||||
show: false,
|
||||
},
|
||||
{
|
||||
action: 'cancelInstall',
|
||||
show: true,
|
||||
|
@ -155,6 +181,38 @@ $(document).ready(function(){
|
|||
}
|
||||
})
|
||||
break;
|
||||
case'test':
|
||||
testModule(packageName,function(data){
|
||||
if(data.ok){
|
||||
toggleCardButtons(card,[
|
||||
{
|
||||
action: 'install',
|
||||
show: false,
|
||||
},
|
||||
{
|
||||
action: 'test',
|
||||
show: false,
|
||||
},
|
||||
{
|
||||
action: 'cancelInstall',
|
||||
show: false,
|
||||
},
|
||||
{
|
||||
action: 'cancelTest',
|
||||
show: true,
|
||||
},
|
||||
{
|
||||
action: 'delete',
|
||||
show: false,
|
||||
},
|
||||
{
|
||||
action: 'status',
|
||||
show: false,
|
||||
},
|
||||
])
|
||||
}
|
||||
})
|
||||
break;
|
||||
case'cancelInstall':
|
||||
$.post(superApiPrefix + $user.sessionKey + '/plugins/install',{
|
||||
packageName: packageName,
|
||||
|
@ -166,6 +224,10 @@ $(document).ready(function(){
|
|||
action: 'install',
|
||||
show: true,
|
||||
},
|
||||
{
|
||||
action: 'test',
|
||||
show: true,
|
||||
},
|
||||
{
|
||||
action: 'cancelInstall',
|
||||
show: false,
|
||||
|
@ -183,6 +245,42 @@ $(document).ready(function(){
|
|||
})
|
||||
toggleUsabilityOfYesAndNoButtons(packageName,false)
|
||||
break;
|
||||
case'cancelTest':
|
||||
$.post(superApiPrefix + $user.sessionKey + '/plugins/test',{
|
||||
packageName: packageName,
|
||||
cancelInstall: 'true'
|
||||
},function(data){
|
||||
if(data.ok){
|
||||
toggleCardButtons(card,[
|
||||
{
|
||||
action: 'install',
|
||||
show: true,
|
||||
},
|
||||
{
|
||||
action: 'test',
|
||||
show: true,
|
||||
},
|
||||
{
|
||||
action: 'cancelInstall',
|
||||
show: false,
|
||||
},
|
||||
{
|
||||
action: 'cancelTest',
|
||||
show: false,
|
||||
},
|
||||
{
|
||||
action: 'delete',
|
||||
show: true,
|
||||
},
|
||||
{
|
||||
action: 'status',
|
||||
show: true,
|
||||
},
|
||||
])
|
||||
}
|
||||
})
|
||||
toggleUsabilityOfYesAndNoButtons(packageName,false)
|
||||
break;
|
||||
case'status':
|
||||
var currentStatus = !!loadedModules[packageName].config.enabled
|
||||
var newStatus = !currentStatus
|
||||
|
@ -231,19 +329,49 @@ $(document).ready(function(){
|
|||
break;
|
||||
}
|
||||
})
|
||||
$('#downloadNewPlugin').submit(function(e){
|
||||
pluginDownloadForm.submit(function(e){
|
||||
e.preventDefault();
|
||||
var el = $(this)
|
||||
var form = el.serializeObject()
|
||||
downloadModule(form.downloadUrl,form.packageRoot,function(data){
|
||||
console.log(data)
|
||||
if(data.ok){
|
||||
data.newModule.config.enabled = false
|
||||
drawModuleBlock(data.newModule)
|
||||
var theModule = data.newModule
|
||||
theModule.config.enabled = false
|
||||
drawModuleBlock(theModule)
|
||||
if(theModule.installerRunning){
|
||||
toggleCardButtons(card,[
|
||||
{
|
||||
action: 'install',
|
||||
show: false,
|
||||
},
|
||||
{
|
||||
action: 'cancelInstall',
|
||||
show: true,
|
||||
},
|
||||
{
|
||||
action: 'delete',
|
||||
show: false,
|
||||
},
|
||||
{
|
||||
action: 'status',
|
||||
show: false,
|
||||
},
|
||||
])
|
||||
}
|
||||
}
|
||||
})
|
||||
return false
|
||||
})
|
||||
$('#pluginQuickSelectExec').click(function(){
|
||||
var currentVal = quickSelect.val()
|
||||
var valParts = currentVal.split('.zip,')
|
||||
var packageUrl = `${valParts[0]}.zip`
|
||||
var packageRoot = valParts[1]
|
||||
pluginDownloadForm.find(`[name="downloadUrl"]`).val(packageUrl)
|
||||
pluginDownloadForm.find(`[name="packageRoot"]`).val(packageRoot)
|
||||
pluginDownloadForm.submit()
|
||||
})
|
||||
setTimeout(function(){
|
||||
getModules(function(data){
|
||||
loadedModules = data.modules
|
||||
|
@ -258,6 +386,7 @@ $(document).ready(function(){
|
|||
case'plugin-info':
|
||||
var name = data.module
|
||||
switch(data.process){
|
||||
case'test-stdout':
|
||||
case'install-stdout':
|
||||
loadedBlocks[name].stdout.append(`<div class="line">${data.data}</div>`)
|
||||
// if(loadedBlocks[name].stdout.find('.line').length > 10){
|
||||
|
@ -265,8 +394,38 @@ $(document).ready(function(){
|
|||
// }
|
||||
if(data.data.indexOf('(y)es or (N)o') > -1){
|
||||
toggleUsabilityOfYesAndNoButtons(name,true)
|
||||
}else if(data.data === '#END_PROCESS'){
|
||||
var isTest = data.process === 'test-stdout'
|
||||
var card = $(`[package-name="${name}"]`)
|
||||
toggleCardButtons(card,[
|
||||
{
|
||||
action: 'install',
|
||||
show: true,
|
||||
},
|
||||
{
|
||||
action: 'test',
|
||||
show: true,
|
||||
},
|
||||
{
|
||||
action: 'cancelInstall',
|
||||
show: false,
|
||||
},
|
||||
{
|
||||
action: 'cancelTest',
|
||||
show: false,
|
||||
},
|
||||
{
|
||||
action: 'delete',
|
||||
show: true,
|
||||
},
|
||||
{
|
||||
action: 'status',
|
||||
show: true,
|
||||
},
|
||||
])
|
||||
}
|
||||
break;
|
||||
case'test-stderr':
|
||||
case'install-stderr':
|
||||
loadedBlocks[name].stderr.append(`<div class="line">${data.data}</div>`)
|
||||
// if(loadedBlocks[name].stderr.find('.line').length > 10){
|
||||
|
|
|
@ -1,15 +1,42 @@
|
|||
<form class="form-group-group card bg-dark grey mt-1" id="downloadNewPlugin">
|
||||
<div class="card-body">
|
||||
<div class="form-group">
|
||||
<input type="text" placeholder="Download URL for Module" class="form-control" name="downloadUrl" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input type="text" placeholder="Subdirectory for Module (Inside the downloaded package)" class="form-control" name="packageRoot" />
|
||||
</div>
|
||||
<div><button type="submit" class="btn btn-round btn-block btn-default mb-0"><i class="fa fa-download"></i> <%- lang.Download %></button></div>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<form class="card bg-dark grey mt-1" id="downloadNewPlugin">
|
||||
<div class="card-body">
|
||||
<div class="form-group">
|
||||
<input type="text" placeholder="Download URL for Module" class="form-control" name="downloadUrl" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input type="text" placeholder="Subdirectory for Module (Inside the downloaded package)" class="form-control" name="packageRoot" />
|
||||
</div>
|
||||
<div><button type="submit" class="btn btn-round btn-block btn-default mb-0"><i class="fa fa-download"></i> <%- lang.Download %></button></div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</form>
|
||||
<div class="form-group-group red pt-4 pb-0 m-0" id="pluginManagerList">
|
||||
<div class="col-md-6">
|
||||
<div class="card bg-dark grey mt-1">
|
||||
<div class="card-body">
|
||||
<div class="form-group">
|
||||
<select class="form-control" id="pluginQuickSelect">
|
||||
<% [
|
||||
{
|
||||
"label": "tensorflow-4-1-0",
|
||||
"value": "https://gitlab.com/Shinobi-Systems/shinobi-plugins/-/archive/master/shinobi-plugins-master.zip,plugins/tensorflow-4-1-0"
|
||||
},
|
||||
{
|
||||
"label": "tensorflow-2-3-0",
|
||||
"value": "https://gitlab.com/Shinobi-Systems/shinobi-plugins/-/archive/master/shinobi-plugins-master.zip,plugins/tensorflow-2-3-0"
|
||||
}
|
||||
].forEach((option) => { %>
|
||||
<option value="<%- option.value %>"><%- option.label %></option>
|
||||
<% }) %>
|
||||
</select>
|
||||
</div>
|
||||
<div><button id="pluginQuickSelectExec" class="btn btn-round btn-block btn-default mb-0"><i class="fa fa-download"></i> <%- lang.Download %></button></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pt-4 pb-0 m-0" id="pluginManagerList">
|
||||
|
||||
</div>
|
||||
<script src="<%-window.libURL%>assets/js/super.pluginManager.js" type="text/javascript"></script>
|
||||
|
|
Loading…
Reference in New Issue