diff --git a/languages/en_CA.json b/languages/en_CA.json index 99939555..a33bb8a7 100644 --- a/languages/en_CA.json +++ b/languages/en_CA.json @@ -199,6 +199,7 @@ "File Type": "File Type", "Filesize": "Filesize", "Video Status": "Video Status", + "Custom Auto Load": "Custom Auto Load", "Preferences": "Preferences", "Equal to": "Equal to", "Not Equal to": "Not Equal to", @@ -482,6 +483,10 @@ "DetectorText": "<p>When the Width and Height boxes are shown you should set them to 640x480 or below. This will optimize the read speed of frames.</p>", "RecordingText": "It is recommended that you set <b>Record File Type</b> to <b class=\"h_t_input h_t_jpeg h_t_socket\">WebM</b><b class=\"h_t_input h_t_mjpeg h_t_h264 h_t_hls h_t_mp4 h_t_local\">MP4</b> and <b>Video Codec</b> to <b class=\"h_t_input h_t_jpeg h_t_socket\">libvpx</b><b class=\"h_t_input h_t_h264 h_t_hls h_t_mp4\">copy or </b><b class=\"h_t_input h_t_mjpeg h_t_h264 h_t_hls h_t_mp4 h_t_local\">libx264</b> because your <b>Input Type</b> is set to <b class=\"h_t_text\"></b>.", "Mode": "Mode", + "Install": "Install", + "Enable": "Enable", + "Disable": "Disable", + "Delete": "Delete", "Name": "Name", "Skip Ping": "Skip Ping", "Retry Connection": "Retry Connection <small>Number of times allowed to fail</small>", diff --git a/libs/customAutoLoad.js b/libs/customAutoLoad.js index cf47d748..8946f6af 100644 --- a/libs/customAutoLoad.js +++ b/libs/customAutoLoad.js @@ -31,8 +31,12 @@ module.exports = async (s,config,lang,app,io) => { if(!fs.existsSync(modulePath + '/index.js')){ foundModules[moduleName].noIndex = true } - if(!fs.existsSync(modulePath + '/package.json')){ + if(fs.existsSync(modulePath + '/package.json')){ foundModules[moduleName].properties = getModuleProperties(moduleName) + }else{ + foundModules[moduleName].properties = { + name: moduleName + } } }else{ foundModules[moduleName].isIgnitor = (moduleName.indexOf('.js') > -1) @@ -104,6 +108,8 @@ module.exports = async (s,config,lang,app,io) => { installProcess.on('exit',(data) => { resolve() }) + }else{ + resolve() } }) } @@ -112,15 +118,28 @@ module.exports = async (s,config,lang,app,io) => { const modulePath = getModulePath(name) const properties = getModuleProperties(name); const propertiesPath = modulePath + 'package.json' - var packageJson = JSON.parse(fs.readFileSync(propertiesPath)) + var packageJson = { + name: name + } + try{ + packageJson = JSON.parse(fs.readFileSync(propertiesPath)) + }catch(err){ + + } packageJson.disabled = status; fs.writeFileSync(propertiesPath,s.prettyPrint(packageJson)) } const deleteModule = (name) => { // requires restart for changes to take effect - const modulePath = getModulePath(name) - fs.unlink(modulePath) - s.file('delete',modulePath) + try{ + const modulePath = modulesBasePath + name + fs.unlinkSync(modulePath) + s.file('delete',modulePath) + return true + }catch(err){ + console.log(err) + return false + } } const loadModule = (shinobiModule) => { const moduleName = shinobiModule.name @@ -248,6 +267,11 @@ module.exports = async (s,config,lang,app,io) => { } } } + const moveModuleToNameInProperties = (modulePath,packageRoot,properties) => { + fs.renameSync(modulePath + packageRoot,modulesBasePath + properties.name) + fs.unlinkSync(modulePath) + s.file('delete',modulePath) + } const initializeAllModules = async () => { s.customAutoLoadModules = {} s.customAutoLoadTree = { @@ -271,25 +295,45 @@ module.exports = async (s,config,lang,app,io) => { loadModule(shinobiModule) }) }else{ - fs.mkdirSync(modulesBasePath) + fs.mkdir(modulesBasePath,() => {}) } }) } /** * API : Superuser : Custom Auto Load Package Download. */ + app.get(config.webPaths.superApiPrefix+':auth/package/list', async (req,res) => { + s.superAuth(req.params, async (resp) => { + s.closeJsonResponse(res,{ + ok: true, + modules: getModules() + }) + },res,req) + }) + /** + * API : Superuser : Custom Auto Load Package Download. + */ app.post(config.webPaths.superApiPrefix+':auth/package/download', async (req,res) => { s.superAuth(req.params, async (resp) => { - 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) - fs.renameSync(modulePath + packageRoot,modulesBasePath + properties.name) - fs.unlinkSync(modulePath) - s.file('delete',modulePath) - s.closeJsonResponse(res,{ok: true}) + 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) + disableModule(newName,true) + s.closeJsonResponse(res,{ + ok: true, + moduleName: newName + }) + }catch(err){ + console.log(err) + s.closeJsonResponse(res,{ + ok: false + }) + } },res,req) }) /** @@ -309,7 +353,7 @@ module.exports = async (s,config,lang,app,io) => { s.superAuth(req.params, async (resp) => { const status = req.body.status const packageName = req.body.packageName - disableModule(packageName,status === 'true' ? true : false) + disableModule(packageName,status == 'true' ? true : false) s.closeJsonResponse(res,{ok: true}) },res,req) }) @@ -319,8 +363,8 @@ module.exports = async (s,config,lang,app,io) => { app.post(config.webPaths.superApiPrefix+':auth/package/delete', async (req,res) => { s.superAuth(req.params, async (resp) => { const packageName = req.body.packageName - deleteModule(packageName) - s.closeJsonResponse(res,{ok: true}) + const response = deleteModule(packageName) + s.closeJsonResponse(res,{ok: response}) },res,req) }) /** diff --git a/web/libs/js/super.customAutoLoad.js b/web/libs/js/super.customAutoLoad.js new file mode 100644 index 00000000..d54c18b2 --- /dev/null +++ b/web/libs/js/super.customAutoLoad.js @@ -0,0 +1,114 @@ +$(document).ready(function(){ + var loadedModules = {} + var listElement = $('#customAutoLoadList') + var getModules = function(callback) { + $.get(superApiPrefix + $user.sessionKey + '/package/list',callback) + } + var drawModuleBlock = function(module){ + listElement.append(`<div class="card" package-name="${module.name}"> + <div class="card-body"> + <div><h4>${module.properties.name ? module.properties.name : module.name}</h4></div> + <div> + ${!module.isIgnitor ? ` + <a class="btn btn-sm btn-success" calm-action="install">${lang.Install}</a> + <a class="btn btn-sm btn-default" calm-action="status">${module.disabled ? lang.Enable : lang.Disable}</a> + ` : ''} + <a class="btn btn-sm btn-danger" calm-action="delete">${lang.Delete}</a> + </div> + </div> + </div>`) + } + var downloadModule = function(url,packageRoot){ + $.confirm.create({ + title: 'Module Download', + body: `Do you want to download the module from ${url}? `, + clickOptions: { + class: 'btn-success', + title: lang.Download, + }, + clickCallback: function(){ + $.post(superApiPrefix + $user.sessionKey + '/package/download',{ + downloadUrl: url, + packageRoot: packageRoot, + },function(data){ + + }) + } + }) + } + var installModule = function(packageName,callback){ + $.confirm.create({ + title: 'Install Module', + body: `Do you want to install the module ${packageName}?`, + clickOptions: { + class: 'btn-success', + title: lang.Install, + }, + clickCallback: function(){ + $.post(superApiPrefix + $user.sessionKey + '/package/install',{ + packageName: packageName, + },callback) + } + }) + } + var deleteModule = function(packageName,callback){ + $.confirm.create({ + title: 'Delete Module', + body: `Do you want to delete the module ${packageName}?`, + clickOptions: { + class: 'btn-danger', + title: lang.Delete, + }, + clickCallback: function(){ + $.post(superApiPrefix + $user.sessionKey + '/package/delete',{ + packageName: packageName, + },callback) + } + }) + } + var setModuleStatus = function(packageName,status,callback){ + $.post(superApiPrefix + $user.sessionKey + '/package/status',{ + status: status, + packageName: packageName, + },callback) + } + $('body').on(`click`,`[calm-action]`,function(){ + var el = $(this) + var action = el.attr('calm-action') + var card = el.parent('[package-name]') + var packageName = card.attr('package-name') + switch(action){ + case'install': + installModule(packageName,function(data){ + if(data.ok){ + console.log(data) + } + }) + break; + case'status': + setModuleStatus(packageName,!!!loadedModules[packageName].disabled,function(data){ + if(data.ok){ + loadedModules[packageName].disabled = !!!loadedModules[packageName].disabled + el.text(loadedModules[packageName].disabled ? lang.Enable : lang.Disable) + } + }) + break; + case'delete': + deleteModule(packageName,function(data){ + if(data.ok){ + card.remove() + } + }) + break; + } + }) + setTimeout(function(){ + getModules(function(data){ + loadedModules = data.modules + console.log(loadedModules) + $.each(data.modules,function(n,module){ + drawModuleBlock(module) + }) + }) + },2000) +}) diff --git a/web/pages/blocks/superCustomAutoLoadManager.ejs b/web/pages/blocks/superCustomAutoLoadManager.ejs new file mode 100644 index 00000000..561f07bb --- /dev/null +++ b/web/pages/blocks/superCustomAutoLoadManager.ejs @@ -0,0 +1,4 @@ +<div class="form-group-group red" id="customAutoLoadList"> + +</div> +<script src="<%-window.libURL%>libs/js/super.customAutoLoad.js" type="text/javascript"></script> diff --git a/web/pages/super.ejs b/web/pages/super.ejs index 731c00e0..dddbc38f 100644 --- a/web/pages/super.ejs +++ b/web/pages/super.ejs @@ -40,6 +40,7 @@ <link rel="stylesheet" href="<%-window.libURL%>libs/css/<%-lib%>"> <% }) %> </head> +<script>$user=<%-JSON.stringify($user)%></script> <body class="index-page sidebar-collapse bg-hexagon"> <!-- Navbar --> @@ -87,6 +88,9 @@ <li class="nav-item"> <a class="nav-link" data-toggle="tab" href="#changeSuperPreferences" role="tab"><%-lang['Preferences']%></a> </li> + <li class="nav-item"> + <a class="nav-link" data-toggle="tab" href="#customAutoLoad" role="tab"><%-lang['Custom Auto Load']%></a> + </li> </ul> <div class="card-body"> <!-- Tab panes --> @@ -101,6 +105,9 @@ <div class="tab-pane text-left" id="system" role="tabpanel"> <% include blocks/superSystemTab.ejs %> </div> + <div class="tab-pane text-left" id="customAutoLoad" role="tabpanel"> + <% include blocks/superCustomAutoLoadManager.ejs %> + </div> <div class="tab-pane text-left" id="changeSuperPreferences" role="tabpanel"> <% include blocks/changeSuperPreferences.ejs %> </div> @@ -151,7 +158,6 @@ } </script> -<script>$user=<%-JSON.stringify($user)%></script> <script> $.ccio={accounts:{}};$.ls=localStorage; if(!$user.lang||$user.lang==''){