Finalize Configuration Editor, refactor some super panel js/ejs

build-default-monitor-config-from-definitions
Moe 2020-04-18 23:11:55 -07:00
parent 605f227897
commit fa96bd7043
8 changed files with 430 additions and 435 deletions

View File

@ -1,6 +1,14 @@
.better-json-editor h3 {
font-size: initial;
margin: 0 10px 10px 0;
margin: 10px 10px 20px 0;
}
.better-json-editor h3 > span{
color: #bd4147;
background-color: #f8f9fa;
padding: 7px 10px;
border-radius: .25rem;
font-family: Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
margin-bottom: 5px;
}
.better-json-editor .well .well {
margin-left:20px;
@ -24,6 +32,9 @@
.better-json-editor table {
width: 100%!important;
margin-bottom: 10px;
overflow: hidden;
border-radius: 5px;
background: #fbfbfb;
}
.better-json-editor .floating-json textarea.form-control {
padding: 20px;
@ -42,6 +53,9 @@
.better-json-editor .row {
margin: 0;
}
.better-json-editor .row p:visible:last-child{
margin: 0;
}
.better-json-editor .row > div {
border: 1px solid #eee;
border-radius: 5px;

View File

@ -1,284 +1,303 @@
var schema = {
"title": "Shinobi Configuration",
"type": "object",
"properties": {
"subscriptionId": {
"type": "string",
},
"port": {
"type": "integer",
"default": 8080
},
"passwordType": {
"type": "string",
"enum": [
"sha256",
"sha512",
"md5"
],
"default": "sha256"
},
"addStorage": {
"type": "array",
"format": "table",
"title": "Additional Storage",
"description": "Separate storage locations that can be set for different monitors.",
"uniqueItems": true,
"items": {
"type": "object",
"title": "Storage Array",
"properties": {
"name": {
"type": "string",
},
"path": {
"type": "string",
"default": "__DIR__/videos2"
}
}
},
"default": [
{
"name": "second",
"path": "__DIR__/videos2"
}
]
},
"plugins": {
"type": "array",
"format": "table",
"title": "Plugins",
"descripton": "Elaborate Plugin connection settings.",
"uniqueItems": true,
"items": {
"type": "object",
"title": "Plugin",
"properties": {
"plug": {
"type": "string",
"default": "pluginName"
},
"key": {
"type": "string"
},
"mode": {
"type": "string",
"enum": [
"host",
"client"
],
"default": "client"
},
"https": {
"type": "boolean",
"descripton": "Only for Host mode.",
"default": false
},
"host": {
"type": "string",
"descripton": "Only for Host mode.",
"default": "localhost"
},
"port": {
"type": "integer",
"descripton": "Only for Host mode.",
"default": 8082
},
"type": {
"type": "string",
"default": "detector"
}
}
},
"default": [
{
"name": "second",
"path": "__DIR__/videos2"
}
]
},
"pluginKeys": {
$(document).ready(function(){
var schema = {
"title": "Shinobi Configuration",
"type": "object",
"format": "table",
"title": "Plugin Keys",
"description": "Quick client connection setup for plugins. Just add the plugin key to make it ready for incoming connections.",
"uniqueItems": true,
"items": {
"type": "object",
"title": "Plugin Key",
"properties": {}
}
},
"db": {
"type": "object",
"format": "table",
"title": "Database Options",
"description": "Credentials to connect to where detailed information is stored.",
"properties": {
"host": {
"properties": {
"subscriptionId": {
"type": "string",
"default": "127.0.0.1"
},
"user": {
"type": "string",
"default": "majesticflame"
"port": {
"type": "integer",
"default": 8080
},
"passwordType": {
"type": "string",
"enum": [
"sha256",
"sha512",
"md5"
],
"default": "sha256"
},
"addStorage": {
"type": "array",
"format": "table",
"title": "Additional Storage",
"description": "Separate storage locations that can be set for different monitors.",
"uniqueItems": true,
"items": {
"type": "object",
"title": "Storage Array",
"properties": {
"name": {
"type": "string",
},
"path": {
"type": "string",
"default": "__DIR__/videos2"
}
}
},
"password": {
"type": "string",
"default": ""
"default": [
{
"name": "second",
"path": "__DIR__/videos2"
}
]
},
"plugins": {
"type": "array",
"format": "table",
"title": "Plugins",
"descripton": "Elaborate Plugin connection settings.",
"uniqueItems": true,
"items": {
"type": "object",
"title": "Plugin",
"properties": {
"plug": {
"type": "string",
"default": "pluginName"
},
"key": {
"type": "string"
},
"mode": {
"type": "string",
"enum": [
"host",
"client"
],
"default": "client"
},
"https": {
"type": "boolean",
"descripton": "Only for Host mode.",
"default": false
},
"host": {
"type": "string",
"descripton": "Only for Host mode.",
"default": "localhost"
},
"port": {
"type": "integer",
"descripton": "Only for Host mode.",
"default": 8082
},
"type": {
"type": "string",
"default": "detector"
}
}
},
"database": {
"type": "string",
"default": "ccio"
},
"port": {
"type": "integer",
"default": 3306
"default": [
{
"name": "second",
"path": "__DIR__/videos2"
}
]
},
"pluginKeys": {
"type": "object",
"format": "table",
"title": "Plugin Keys",
"description": "Quick client connection setup for plugins. Just add the plugin key to make it ready for incoming connections.",
"uniqueItems": true,
"items": {
"type": "object",
"title": "Plugin Key",
"properties": {}
}
},
"default": {
"host": "127.0.0.1",
"user": "majesticflame",
"password": "",
"database": "ccio",
"port":3306
}
},
"cron": {
"type": "object",
"format": "table",
"title": "CRON Options",
"properties": {
"key": {
"type": "string",
},
"deleteOld": {
"type": "boolean",
"description": "cron will delete videos older than Max Number of Days per account.",
"default": true
},
"deleteNoVideo": {
"type": "boolean",
"description": "cron will delete SQL rows that it thinks have no video files.",
"default": true
},
"deleteOverMax": {
"type": "boolean",
"description": "cron will delete files that are over the set maximum storage per account.",
"default": true
},
}
},
"mail": {
"type": "object",
"format": "table",
"title": "Email Options",
"properties": {
"service": {
"type": "string",
},
"host": {
"type": "string",
},
"auth": {
"db": {
"type": "object",
"format": "table",
"title": "Database Options",
"description": "Credentials to connect to where detailed information is stored.",
"properties": {
"user": {
"type": "string",
},
"pass": {
"type": "string",
},
"host": {
"type": "string",
"default": "127.0.0.1"
},
"user": {
"type": "string",
"default": "majesticflame"
},
"password": {
"type": "string",
"default": ""
},
"database": {
"type": "string",
"default": "ccio"
},
"port": {
"type": "integer",
"default": 3306
}
},
},
"secure": {
"type": "boolean",
"default": false
},
"ignoreTLS": {
"type": "boolean",
},
"requireTLS": {
"type": "boolean",
},
"port": {
"type": "integer",
}
"default": {
"host": "127.0.0.1",
"user": "majesticflame",
"password": "",
"database": "ccio",
"port":3306
}
},
"cron": {
"type": "object",
"format": "table",
"title": "CRON Options",
"properties": {
"key": {
"type": "string",
},
"deleteOld": {
"type": "boolean",
"description": "cron will delete videos older than Max Number of Days per account.",
"default": true
},
"deleteNoVideo": {
"type": "boolean",
"description": "cron will delete SQL rows that it thinks have no video files.",
"default": true
},
"deleteOverMax": {
"type": "boolean",
"description": "cron will delete files that are over the set maximum storage per account.",
"default": true
},
}
},
"mail": {
"type": "object",
"format": "table",
"title": "Email Options",
"properties": {
"service": {
"type": "string",
},
"host": {
"type": "string",
},
"auth": {
"type": "object",
"properties": {
"user": {
"type": "string",
},
"pass": {
"type": "string",
},
},
},
"secure": {
"type": "boolean",
"default": false
},
"ignoreTLS": {
"type": "boolean",
},
"requireTLS": {
"type": "boolean",
},
"port": {
"type": "integer",
}
}
},
"detectorMergePamRegionTriggers": {
"type": "boolean",
"default": true
},
"doSnapshot": {
"type": "boolean",
"default": true
},
"discordBot": {
"type": "boolean",
"default": false
},
"dropInEventServer": {
"type": "boolean",
"default": false
},
"ftpServer": {
"type": "boolean",
"default": false
},
"oldPowerVideo": {
"type": "boolean",
"default": false
},
"defaultMjpeg": {
"type": "string",
},
"streamDir": {
"type": "string",
},
"videosDir": {
"type": "string",
},
"windowsTempDir": {
"type": "string",
}
}
};
var configurationTab = $('#config')
var configurationForm = configurationTab.find('form')
// Set default options
JSONEditor.defaults.options.theme = 'bootstrap3';
JSONEditor.defaults.options.iconlib = 'fontawesome4';
// Initialize the editor
var configurationEditor = new JSONEditor(document.getElementById("configForHumans"),{
theme: 'bootstrap3',
schema: schema
});
configurationEditor.setValue(shinobiConfig);
// configurationEditor.on("change", function() {
// // Do something...
// });
var submitConfiguration = function(){
var errors = configurationEditor.validate();
console.log(errors.length)
console.log(errors)
if(errors.length === 0) {
var newConfiguration = JSON.stringify(configurationEditor.getValue(),null,3)
var html = '<p>This is a change being applied to the configuration file (conf.json). Are you sure you want to do this? You must restart Shinobi for these changes to take effect. <b>The JSON below is what you are about to save.</b></p>'
html += `<pre>${newConfiguration}</pre>`
$.confirm.create({
title: 'Save Configuration <small>conf.json</small>',
body: html,
clickOptions: {
class: 'btn-success',
title: lang.Save,
},
clickCallback: function(){
$.post('<%=originalURL%><%=config.webPaths.superApiPrefix%>'+$user.sessionKey+'/system/configure',{
data: newConfiguration
},function(data){
// console.log(data)
})
}
})
}else{
new PNotify({text:'Invalid JSON Syntax, Cannot Save.',type:'error'})
}
},
"detectorMergePamRegionTriggers": {
"type": "boolean",
"default": true
},
"doSnapshot": {
"type": "boolean",
"default": true
},
"discordBot": {
"type": "boolean",
"default": false
},
"dropInEventServer": {
"type": "boolean",
"default": false
},
"ftpServer": {
"type": "boolean",
"default": false
},
"oldPowerVideo": {
"type": "boolean",
"default": false
},
"defaultMjpeg": {
"type": "string",
},
"streamDir": {
"type": "string",
},
"videosDir": {
"type": "string",
},
"windowsTempDir": {
"type": "string",
}
}
};
// Set default options
JSONEditor.defaults.options.theme = 'bootstrap3';
JSONEditor.defaults.options.iconlib = 'fontawesome4';
// Initialize the editor
var editor = new JSONEditor(document.getElementById("configForHumans"),{
theme: 'bootstrap3',
schema: schema,
//schema: {
// type: "object",
// properties: {
// name: { "type": "string" }
// }
//}
});
// Set the value
editor.setValue(shinobiConfig);
//editor.setValue({
// name: "John Smith"
//});
// Get the value
var data = editor.getValue();
console.log(data); // "John Smith"
// Validate
var errors = editor.validate();
if(errors.length) {
// Not valid
}
// Listen for changes
editor.on("change", function() {
// Do something...
});
configurationTab.find('.submit').click(function(){
submitConfiguration()
})
configurationForm.submit(function(e){
e.preventDefault()
submitConfiguration()
return false;
})
window.configurationEditor = configurationEditor
})

View File

@ -0,0 +1,18 @@
$(document).ready(function(){
var changeSuperPreferencesTab = $('#changeSuperPreferences')
var changeSuperPreferencesForm = changeSuperPreferencesTab.find('form')
changeSuperPreferencesTab.find('.submit').click(function(){
changeSuperPreferencesForm.submit()
})
changeSuperPreferencesForm.submit(function(e){
e.preventDefault()
var formValues = $(this).serializeObject()
// $.ccio.cx({f:'accounts',ff:'saveSuper',form:formValues})
$.post(superApiPrefix + $user.sessionKey + '/accounts/saveSettings',{
data: JSON.stringify(formValues)
},function(data){
console.log(data)
})
return false
})
})

View File

@ -0,0 +1,70 @@
$(document).ready(function(){
var systemsControlsTab = $('#system')
systemsControlsTab.find('[system]').click(function(e){
switch($(this).attr('system')){
case'deleteLogs':
var html = 'Do you want to delete these logs? User logs will <b>not</b> be deleted.'
$.confirm.create({
title: `${lang['Delete Logs']} <small>${e.u}</small>`,
body: html,
clickOptions: {
class: 'btn-danger',
title: lang.Delete,
},
clickCallback: function(){
$.get(superApiPrefix + $user.sessionKey + '/logs/delete',function(data){
console.log(data)
})
$.logs.e.find('table').empty()
}
})
break;
case'update':
var html = 'Updating Shinobi means overwriting files. If you have modified any files yourself you should update Shinobi manually.'
$.confirm.create({
title: `${lang.Update} Shinobi?`,
body: html,
clickOptions: {
class: 'btn-danger',
title: lang.Update,
},
clickCallback: function(){
$.get(superApiPrefix + $user.sessionKey + '/system/update',function(data){
console.log(data)
})
}
})
break;
}
})
systemsControlsTab.find('[restart]').click(function(e){
var html = ''
var target = $(this).attr('restart').split(',')
target.forEach(function(v){
switch(v){
case'system':
html += '<p>Do you want to restart the core (camera.js)? plugins will not be restarted. They will reconnect when Shinobi is back online.</p>'
break;
case'cron':
html += '<p>Do you want to restart the CRON (cron.js)?</p>'
break;
case'logs':
html += '<p>Flush PM2 console logs? The logs saved in the database will <b>not</b> be deleted.</p>'
break;
}
})
$.confirm.create({
title: `${lang.Restart}?`,
body: html,
clickOptions: {
class: 'btn-danger',
title: lang.Restart,
},
clickCallback: function(){
$.get(superApiPrefix + $user.sessionKey + '/system/restart/'+encodeURIComponent(target),function(data){
console.log(data)
})
}
})
})
})

View File

@ -37,3 +37,4 @@
</label>
</div>
</form>
<script src="<%-window.libURL%>libs/js/super.preferences.js" type="text/javascript"></script>

View File

@ -15,12 +15,7 @@
</nav>
<form class="form-group-group red" id="conf_json">
<small class="pull-right msg"></small>
<div id="configForHumans" class="better-json-editor pt-3">
</div>
<div class="form-group">
<textarea name="json" style="height:300px;font-family: monospace;" class="form-control"></textarea>
</div>
<div id="configForHumans" class="better-json-editor pt-2"></div>
</form>
<script src="<%-window.libURL%>libs/js/jsonEditor.js" type="text/javascript"></script>
<script src="<%-window.libURL%>libs/js/super.configEditor.js" type="text/javascript"></script>

View File

@ -0,0 +1,33 @@
<nav class="navbar navbar-rounded navbar-expand-lg bg-primary">
<div class="container">
<div class="collapse navbar-collapse">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" system="deleteLogs">
<p><i class="fa fa-trash-o"></i> <%-lang['Delete']%> <%-lang['Logs']%></p>
</a>
</li>
<li class="nav-item">
<a class="nav-link" restart="system">
<p><i class="fa fa-retweet"></i> <%-lang['Restart Core']%></p>
</a>
</li>
<li class="nav-item">
<a class="nav-link" restart="cron">
<p><i class="fa fa-retweet"></i> <%-lang['Restart CRON']%></p>
</a>
</li>
<li class="nav-item">
<a class="nav-link" restart="logs">
<p><i class="fa fa-retweet"></i> <%-lang['Flush PM2 Logs']%></p>
</a>
</li>
</ul>
</div>
</div>
</nav>
<div id="logs" style="height:400px;overflow:auto">
<table class="table table-striped"></table>
</div>
<script src="<%-window.libURL%>libs/js/super.systemTab.js" type="text/javascript"></script>

View File

@ -111,38 +111,7 @@
<% include blocks/superConfigEditor.ejs %>
</div>
<div class="tab-pane text-left" id="system" role="tabpanel">
<nav class="navbar navbar-rounded navbar-expand-lg bg-primary">
<div class="container">
<div class="collapse navbar-collapse">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" system="deleteLogs">
<p><i class="fa fa-trash-o"></i> <%-lang['Delete']%> <%-lang['Logs']%></p>
</a>
</li>
<li class="nav-item">
<a class="nav-link" restart="system">
<p><i class="fa fa-retweet"></i> <%-lang['Restart Core']%></p>
</a>
</li>
<li class="nav-item">
<a class="nav-link" restart="cron">
<p><i class="fa fa-retweet"></i> <%-lang['Restart CRON']%></p>
</a>
</li>
<li class="nav-item">
<a class="nav-link" restart="logs">
<p><i class="fa fa-retweet"></i> <%-lang['Flush PM2 Logs']%></p>
</a>
</li>
</ul>
</div>
</div>
</nav>
<div id="logs" style="height:400px;overflow:auto">
<table class="table table-striped"></table>
</div>
<% include blocks/superSystemTab.ejs %>
</div>
<div class="tab-pane text-left" id="changeSuperPreferences" role="tabpanel">
<% include blocks/changeSuperPreferences.ejs %>
@ -314,130 +283,6 @@ $.ccio.init=function(x,d,z,k){
}
//logs
$.logs={e:$('#logs')}
//config editor
<%
var stringedConfig = JSON.stringify(plainConfig)
%>
var config = <%- JSON.stringify(plainConfig) || [] %>
$.conf={e:$('#config')};
$.conf.f = $.conf.e.find('form')
$.conf.draw=$.conf.e.find('[name="json"]')
$.conf.valid=1;
$.conf.draw.val(JSON.stringify(<%-stringedConfig%>,null,3))
$.conf.draw.keyup(function(){
var msg=''
var color=''
try{
config = $.parseJSON($.conf.draw.val())
msg = 'Valid JSON'
color = 'success'
$.conf.valid = 1
}catch(er){
msg = 'Not a valid JSON'
color = 'danger'
$.conf.valid = 0
}
new PNotify({text:msg,type:color})
})
$.conf.e.find('.submit').click(function(e){
$.conf.f.submit()
})
$.conf.f.submit(function(e){
e.preventDefault()
if($.conf.valid===1){
$.confirm.e.modal('show');
$.confirm.title.html('Save Configuration <small>conf.json</small>')
e.html='<p>This is a change being applied to the configuration file (conf.json). Are you sure you want to do this? You must restart Shinobi for these changes to take effect. <b>The JSON below is what you are about to save.</b></p>'
e.html+='<pre>'+JSON.stringify($.parseJSON($.conf.draw.val()),null,3)+'</pre>'
$.confirm.body.html(e.html)
$.confirm.click({title:lang.Save,class:'btn-success'},function(){
$.post('<%=originalURL%><%=config.webPaths.superApiPrefix%>'+$user.sessionKey+'/system/configure',{
data: $.conf.draw.val()
},function(data){
// console.log(data)
})
// $.ccio.cx({f:'system',ff:'configure',data:$.parseJSON($.conf.draw.val())})
});
}else{
new PNotify({text:'Invalid JSON Syntax, Cannot Save.',type:'error'})
}
return false;
})
//sys controls
$.system={e:$('#system')}
$.system.e.find('[system]').click(function(e){
switch($(this).attr('system')){
case'deleteLogs':
$.confirm.e.modal('show');
$.confirm.title.html('<%=lang['Delete Logs']%> <small>'+e.u+'</small>')
e.html='Do you want to delete these logs? User logs will <b>not</b> be deleted.'
$.confirm.body.html(e.html)
$.confirm.click({title:lang.Delete,class:'btn-danger'},function(){
// $.ccio.cx({f:'logs',ff:'delete',ke:'$'})
$.get('<%=originalURL%><%=config.webPaths.superApiPrefix%>'+$user.sessionKey+'/logs/delete',function(data){
console.log(data)
})
$.logs.e.find('table').empty()
});
break;
case'update':
$.confirm.e.modal('show')
$.confirm.title.html('<%=lang.Update%> Shinobi?')
$.confirm.body.html('Updating Shinobi means overwriting files. If you have modified any files yourself you should update Shinobi manually.')
$.confirm.click({title:lang.Update,class:'btn-danger'},function(){
// $.ccio.cx({f:'system',ff:'update'})
$.get('<%=originalURL%><%=config.webPaths.superApiPrefix%>'+$user.sessionKey+'/system/update',function(data){
console.log(data)
})
})
break;
}
})
$.system.e.find('[restart]').click(function(e){
$.confirm.e.modal('show');
e.html=''
e.title=''
e.target=$(this).attr('restart').split(',')
e.target.forEach(function(v){
switch(v){
case'system':
e.html+='<p>Do you want to restart the core (camera.js)? plugins will not be restarted. They will reconnect when Shinobi is back online.</p>'
break;
case'cron':
e.html+='<p>Do you want to restart the CRON (cron.js)?</p>'
break;
case'logs':
e.html+='<p>Flush PM2 console logs? The logs saved in the database will <b>not</b> be deleted.</p>'
break;
}
})
$.confirm.title.html('<%=lang.Restart%>?')
$.confirm.body.html(e.html)
$.confirm.click({title:lang.Restart,class:'btn-danger'},function(){
// $.ccio.cx({f:'system',ff:'restart',target:e.target})
$.get('<%=originalURL%><%=config.webPaths.superApiPrefix%>'+$user.sessionKey+'/system/restart/'+encodeURIComponent(e.target),function(data){
console.log(data)
})
});
})
$.changeSuperPreferences = {
window : $('#changeSuperPreferences')
}
$.changeSuperPreferences.form = $.changeSuperPreferences.window.find('form')
$.changeSuperPreferences.form.find('.submit').click(function(){
$.changeSuperPreferences.form.submit()
})
$.changeSuperPreferences.form.submit(function(e){
e.preventDefault()
var formValues = $(this).serializeObject()
// $.ccio.cx({f:'accounts',ff:'saveSuper',form:formValues})
$.post('<%=originalURL%><%=config.webPaths.superApiPrefix%>'+$user.sessionKey+'/accounts/saveSettings',{
data: JSON.stringify(formValues)
},function(data){
console.log(data)
})
return false
})
////
$(document).ready(function(){
<% if(!users || !(users instanceof Array)){ %>