1
0
Fork 0
mirror of https://gitlab.com/Shinobi-Systems/ShinobiCE.git synced 2025-03-09 15:40:15 +00:00

Tickly Tiger

This commit is contained in:
Moe 2018-08-04 12:48:05 -07:00
parent 301337c140
commit a80c1e4e97
78 changed files with 28107 additions and 1402 deletions

View file

@ -14,14 +14,14 @@
}
nav{margin-top:20px}
</style>
<link rel="stylesheet" href="libs/css/pnotify.custom.min.css">
<link rel="stylesheet" href="libs/css/vbox.css">
<link rel="stylesheet" href="libs/css/circles.css">
<link rel="stylesheet" href="libs/css/bootstrap.min.css">
<link rel="stylesheet" href="libs/css/font-awesome.min.css">
<link rel="stylesheet" href="libs/css/fullcalendar.min.css">
<link rel="stylesheet" href="libs/css/bootstrap-table.min.css">
<link rel="stylesheet" href="libs/css/main.dash2.css">
<link rel="stylesheet" href="<%-originalURL%>libs/css/pnotify.custom.min.css">
<link rel="stylesheet" href="<%-originalURL%>libs/css/vbox.css">
<link rel="stylesheet" href="<%-originalURL%>libs/css/circles.css">
<link rel="stylesheet" href="<%-originalURL%>libs/css/bootstrap.min.css">
<link rel="stylesheet" href="<%-originalURL%>libs/css/font-awesome.min.css">
<link rel="stylesheet" href="<%-originalURL%>libs/css/fullcalendar.min.css">
<link rel="stylesheet" href="<%-originalURL%>libs/css/bootstrap-table.min.css">
<link rel="stylesheet" href="<%-originalURL%>libs/css/main.dash2.css">
<body class="shinobi-bg">
<div class="shinobi-bg-shade">
<div class="container-fluid">
@ -113,9 +113,11 @@ $.ccio.ws.on('f',function(d){
console.log(d);
switch(d.f){
case'edit_sub_account':
var account = $.ccio.subs[d.uid]
$.each(d.form,function(n,v){
$.ccio.subs[d.uid][n]=v;
account[n]=v;
});
account.detailsJSON=JSON.parse(account.details);
break;
case'add_sub_account':
$.ccio.tm(0,d,'#sub_accounts')
@ -179,7 +181,9 @@ $.sU.e.on('click','.permission',function(e){
$.each($.ccio.subs[$.pR.user],function(n,v){
$.pR.e.find('[name="'+n+'"]').val(v)
})
$.pR.e.find('[detail="allmonitors"]').val(e.d.allmonitors).change()
$.pR.e.find('[detail]').each(function(n,v){
$(v).val(e.d[$(v).attr('detail')])
}).first().change()
$.each(['monitors','monitor_edit','video_delete','video_view'],function(m,b){
if(e.d[b]){
$.each(e.d[b],function(n,v){
@ -191,37 +195,43 @@ $.sU.e.on('click','.permission',function(e){
//permission window
$.pR={e:$('#permissions'),l:$('#permissionsLabel small')};$.pR.f=$.pR.e.find('form')
$.pR.e.on('change','[detail]',function(e){
e.f=$(this).parents('form');
var details = $.pR.e.find('[name="details"]')
e.ar = JSON.parse(details.val())
e.f.find('[detail]').each(function(n,v){
v = $(v);e.ar[v.attr('detail')] = v.val()
})
details.val(JSON.stringify(e.ar))
})
$.pR.e.on('change','[detail="allmonitors"]',function(e){
e.e=$(this),
e.mon=$('#monitors_section,#monitors_edit_section,#video_delete_section')
e.details=$.pR.e.find('[name="details"]')
e.json=JSON.parse(e.details.val())
if(e.e.val()=='1'){
e.mon=$('.permission-view')
if(e.e.val() === '1'){
e.mon.hide();
e.json.allmonitors='1';
}else{
e.mon.show()
e.json.allmonitors='0';
$.pR.e.find('[monitor]').first().change()
}
e.details.val(JSON.stringify(e.json))
})
$.pR.e.on('click','[check]',function(e){
$(this).parents('.form-group-group').find('select').val($(this).attr('check')).first().change()
})
$.pR.e.on('change','[monitor]',function(e){
e.monitors=[];
e.key=$(this).attr('monitor');
e.details=$.pR.e.find('[name="details"]')
try{e.detail=JSON.parse(e.details.val())}catch(err){e.detail={}}
if(!e.detail){e.detail={}}
$.pR.e.find('[monitor="'+e.key+'"]').each(function(n,v){
v=$(v)
if(v.val()=='1'){
e.monitors.push(v.attr('mid'))
}
});
e.detail[e.key]=e.monitors;
$.pR.e.find('[monitor]').each(function(n,kel){
var monitors = [];
var key = $(kel).attr('monitor')
$.pR.e.find('[monitor="'+key+'"]').each(function(n,v){
var el = $(v)
if(el.val() === '1'){
monitors.push(el.attr('mid'))
}
});
e.detail[key] = monitors
})
e.details.val(JSON.stringify(e.detail))
});
$.pR.f.submit(function(e){

View file

@ -11,7 +11,6 @@
<div class="modal-body"></div>
<div class="modal-footer">
<button type="button" class="btn btn-default pull-left" data-dismiss="modal"><i class="fa fa-times"></i> <%- lang['Close'] %></button>
<button type="button" class="btn btn-success confirmaction"><%- lang['Save'] %></button>
</div>
</div>
</div>
@ -21,17 +20,29 @@
$.confirm={e:$('#confirm_window')};
$.confirm.title=$.confirm.e.find('.modal-title span')
$.confirm.body=$.confirm.e.find('.modal-body')
$.confirm.footer=$.confirm.e.find('.modal-footer')
$.confirm.click=function(x,e){
if(!x.class){x.class='btn-success'}
if(!x.title){x.title='Save changes'}
x.e=$.confirm.e.find('.confirmaction').removeClass('btn-danger btn-warning btn-primary btn-success').addClass(x.class).text(x.title);
x.e.click(function(){
x.e.unbind('click');$.confirm.e.modal('hide');e();
})
$.confirm.footer.find('.confirmaction').remove()
var createButton = function(x,place,callback){
$.confirm.footer.prepend('<button type="button" class="btn '+x.class+' confirmaction confirmaction'+place+'">'+x.title+'</button>')
if(!x.class){x.class='btn-success'}
if(!x.title){x.title='Save changes'}
$.confirm.footer.find('.confirmaction'+place).click(function(){
$.confirm.e.modal('hide')
callback();
})
}
if(x instanceof Array){
$.each(x,function(place,x){
createButton(x,place,x.callback)
})
}else{
createButton(x,0,e)
}
}
$(document).ready(function(){
$.confirm.e.on('hidden.bs.modal', function () {
$.confirm.e.find('.confirmaction').unbind('click');
$.confirm.footer.find('.confirmaction').remove()
})
})
</script>

View file

@ -0,0 +1,12 @@
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-title" content="Shinobi">
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
<link rel="apple-touch-icon" sizes="57x57" href="<%-originalURL%>libs/img/icon/apple-touch-icon-57x57.png" />
<link rel="apple-touch-icon" sizes="72x72" href="<%-originalURL%>libs/img/icon/apple-touch-icon-72x72.png" />
<link rel="apple-touch-icon" sizes="76x76" href="<%-originalURL%>libs/img/icon/apple-touch-icon-76x76.png" />
<link rel="apple-touch-icon" sizes="114x114" href="<%-originalURL%>libs/img/icon/apple-touch-icon-114x114.png" />
<link rel="apple-touch-icon" sizes="120x120" href="<%-originalURL%>libs/img/icon/apple-touch-icon-120x120.png" />
<link rel="apple-touch-icon" sizes="144x144" href="<%-originalURL%>libs/img/icon/apple-touch-icon-144x144.png" />
<link rel="apple-touch-icon" sizes="152x152" href="<%-originalURL%>libs/img/icon/apple-touch-icon-152x152.png" />
<link rel="apple-touch-icon" sizes="180x180" href="<%-originalURL%>libs/img/icon/apple-touch-icon-180x180.png" />

View file

@ -0,0 +1,5 @@
<meta charset="utf-8">
<meta name="ROBOTS" content="NOINDEX, NOFOLLOW">
<meta name="viewport" content="width=device-width, maximum-scale=1, user-scalable=no" />
<meta name="description" content="Shinobi, Open Source CCTV Technology">
<meta name="author" content="Moe Alam, moeiscool on GitHub">

View file

@ -1,36 +1,21 @@
<head>
<title><%-lang.Shinobi%></title>
<meta charset="utf-8">
<meta name="ROBOTS" content="NOINDEX, NOFOLLOW">
<meta name="viewport" content="width=device-width, maximum-scale=1, user-scalable=no" />
<meta name="description" content="Shinobi, Open Source CCTV Technology">
<meta name="author" content="Moe Alam, moeiscool on GitHub">
<% include header-meta.ejs %>
<meta http-equiv="content-type" content="text/html;charset=UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link rel="stylesheet" href="libs/css/bootstrap.min.css">
<link rel="stylesheet" href="libs/css/login.css">
<link rel="stylesheet" href="libs/css/material.min.css">
<link rel="stylesheet" href="libs/css/material.style.css">
<link rel="stylesheet" href="<%-originalURL%>libs/css/bootstrap.min.css">
<link rel="stylesheet" href="<%-originalURL%>libs/css/login.css">
<link rel="stylesheet" href="<%-originalURL%>libs/css/material.min.css">
<link rel="stylesheet" href="<%-originalURL%>libs/css/material.style.css">
<meta name="mobile-web-app-capable" content="yes">
<link rel="icon" href="libs/img/icon/favicon.ico" type="image/x-icon" />
<link rel="shortcut icon" href="libs/img/icon/favicon.ico" type="image/x-icon" />
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-title" content="Shinobi">
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
<link rel="apple-touch-icon" sizes="57x57" href="libs/img/icon/apple-touch-icon-57x57.png" />
<link rel="apple-touch-icon" sizes="72x72" href="libs/img/icon/apple-touch-icon-72x72.png" />
<link rel="apple-touch-icon" sizes="76x76" href="libs/img/icon/apple-touch-icon-76x76.png" />
<link rel="apple-touch-icon" sizes="114x114" href="libs/img/icon/apple-touch-icon-114x114.png" />
<link rel="apple-touch-icon" sizes="120x120" href="libs/img/icon/apple-touch-icon-120x120.png" />
<link rel="apple-touch-icon" sizes="144x144" href="libs/img/icon/apple-touch-icon-144x144.png" />
<link rel="apple-touch-icon" sizes="152x152" href="libs/img/icon/apple-touch-icon-152x152.png" />
<link rel="apple-touch-icon" sizes="180x180" href="libs/img/icon/apple-touch-icon-180x180.png" />
<script src="libs/js/jquery.min.js"></script>
<script src="libs/js/jquery-ui.min.js"></script>
<script src="libs/js/jquery.serialize.js"></script>
<link rel="icon" href="<%-originalURL%>libs/img/icon/favicon.ico" type="image/x-icon" />
<link rel="shortcut icon" href="<%-originalURL%>libs/img/icon/favicon.ico" type="image/x-icon" />
<% include header-favicon.ejs %>
<script src="<%-originalURL%>libs/js/jquery.min.js"></script>
<script src="<%-originalURL%>libs/js/jquery-ui.min.js"></script>
<script src="<%-originalURL%>libs/js/jquery.serialize.js"></script>
</head>
<% cleanLang=function(string){
<% cleanLang = function(string){
if(!string){string=''}
return string.replace(/'/g,"\\'")
} %>
}%>

View file

@ -10,7 +10,7 @@
<h4 class="modal-title" id="help_windowLabel"><i class="fa fa-question-circle"></i> &nbsp; <span><%-lang.Help%></span></h4>
</div>
<div class="modal-body">
<a href="http://shinobi.video/docs/donate"><img src="libs/img/icon/apple-touch-icon-152x152.png" class="pull-right" style="border-radius:50%;margin-left:20px;border: 1px solid #c3996b;"></a>
<a href="http://shinobi.video/docs/donate"><img src="<%-originalURL%>libs/img/icon/apple-touch-icon-152x152.png" class="pull-right" style="border-radius:50%;margin-left:20px;border: 1px solid #c3996b;"></a>
<p>For information about how to use Shinobi you can check out the <a target="_blank" href="http://shinobi.video/docs">Docs</a>.</p>
<p>If you would like to get professional support please consider ordering a <a href="http://shinobi.video/support">support package</a>. You can find <b>Moe Alam, The Author</b>, on the <a target="_blank" href="https://discord.gg/ehRd8Zz">Discord</a> Community Chat. For general questions and community support you can also try <a href="https://www.reddit.com/r/ShinobiCCTV">Reddit</a>.</p>
<p><strong>Support </strong> <a href="http://shinobi.video/support">from @moeiscool</a></p>

View file

@ -8,28 +8,42 @@
</button>
<h4 class="modal-title" id="logsLabel"><i class="fa fa-exclamation-triangle"></i> &nbsp; <%-lang.Logs%></h4>
</div>
<div class="modal-body">
<div class="form-group">
<label>
<div>
<select class="form-control" id="log_monitors">
<option class="hard" value="all"><%-lang['All Logs']%></option>
<option class="hard" value="$USER"><%-lang['For Group']%></option>
</select>
</div>
</label>
</div>
<div class="form-group">
<label>
<input class="form-control search-controller" placeholder="<%-lang.Search%>">
</label>
</div>
<table class="table table-striped">
<tbody class="search-body"></tbody>
</table>
<div class="modal-body overflow-hidden">
<div class="col-md-3">
<div class="form-group">
<label>
<div>
<select class="form-control" id="log_monitors">
<option class="hard" value="all"><%-lang['All Logs']%></option>
<option class="hard" value="$USER"><%-lang['For Group']%></option>
</select>
</div>
</label>
</div>
<div class="form-group">
<label><div><span><%-lang.Search%></span></div>
<div><input type="text" class="form-control search-controller" placeholder="<%-lang.Search%>" /></div>
</label>
</div>
<div class="form-group">
<label><div><span><%-lang['Date Range']%></span></div>
<div><input type="text" id="logs_daterange" class="form-control" value="" /></div>
</label>
</div>
</div>
<div class="col-md-9">
<div class="fixed-table-container">
<div class="fixed-table-body">
<table class="table table-striped">
<tbody class="search-body"></tbody>
</table>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default pull-left" data-dismiss="modal"><i class="fa fa-times"></i> <%-lang.Close%></button>
<button download class="btn btn-info"><%-lang.Export%></button>
<button onclick="$.log.lm.change()" class="btn btn-success"><%-lang.Check%></button>
</div>
</div>

View file

@ -1,19 +1,12 @@
<!--Confirmation Window-->
<div class="modal fade" id="add_edit" tabindex="-1" role="dialog" aria-labelledby="permissionsLabel" aria-hidden="true">
<div class="modal fade full" id="add_edit" tabindex="-1" role="dialog" aria-labelledby="permissionsLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<form class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
<h4 class="modal-title" id="permissionsLabel"><i class="fa fa-lock"></i> &nbsp; <span id="title"></span>
<div class="pull-right">
<label class="mdl-switch mdl-js-switch mdl-js-ripple-effect" for="edit">
<input type="checkbox" id="edit" value="1" class="mdl-switch__input">
<span class="monospace mdl-switch__label"></span>
</label>
</div>
</h4>
<h4 class="modal-title" id="permissionsLabel"><i class="fa fa-lock"></i> &nbsp; <span id="title"></span></h4>
</div>
<div class="modal-body" style="max-height:600px;overflow:auto">
<div class="form-group">
@ -118,6 +111,14 @@
</select></div>
</label>
</div>
<div class="form-group h_l_input h_l_limited">
<label><div><span><%-lang['Can use Amazon S3']%></span></div>
<div><select class="form-control" detail="use_aws_s3">
<option value="1" selected><%-lang.Yes%></option>
<option value="0"><%-lang.No%></option>
</select></div>
</label>
</div>
<div class="form-group h_l_input h_l_limited">
<label><div><span><%-lang['Can use WebDAV']%></span></div>
<div><select class="form-control" detail="use_webdav">
@ -126,6 +127,14 @@
</select></div>
</label>
</div>
<div class="form-group h_l_input h_l_limited">
<label><div><span><%-lang['Can use Discord Bot']%></span></div>
<div><select class="form-control" detail="use_discordbot">
<option value="1" selected><%-lang.Yes%></option>
<option value="0"><%-lang.No%></option>
</select></div>
</label>
</div>
<div class="form-group h_l_input h_l_limited">
<label><div><span><%-lang['Can use LDAP']%></span></div>
<div><select class="form-control" detail="use_ldap">
@ -137,6 +146,12 @@
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default pull-left" data-dismiss="modal"><i class="fa fa-times"></i> <%-lang.Close%></button>
<div class="pull-left">
<div class="marc-toggle display-inline">
<input type="checkbox" id="edit"/><label for="edit">Add or Edit</label>
</div>
</div>
<button type="submit" class="btn btn-success"><i class="fa fa-check"></i> <%-lang.Save%></button>
</div>
<input type="hidden" name="details" value="{}">
@ -146,11 +161,12 @@
<script>
//add new
$.aN={e:$('#add_edit')};$.aN.f=$.aN.e.find('form')
$.aN.modeIsEdit = false
$.aN.f.submit(function(e){
e.preventDefault();
e.s=$.aN.f.serializeObject()
e.cx={f:'accounts',ff:'register',form:e.s};
if($('#edit').is(':checked')){
if($.aN.modeIsEdit){
e.cx.ff='edit';
e.cx.account=$.aN.selected;
}
@ -158,21 +174,33 @@ $.aN.f.submit(function(e){
$.aN.e.modal('hide')
return false;
});
$.aN.e.on('change','[detail]',function(e){
e.ar={},e.f=$(this).parents('form');
$.each(e.f.find('[detail]'),function(n,v){
v=$(v);e.ar[v.attr('detail')]=v.val();
$.aN.e.on('change','[detail]',function(){
e = {}
e.ar = {}
if($.aN.modeIsEdit){
try{
e.ar = Object.assign(JSON.parse($.aN.selected.details),{})
}catch(err){
}
}
$.each($.aN.e.find('[detail]'),function(n,v){
var el = $(v)
e.ar[el.attr('detail')] = el.val()
});
e.f.find('[name="details"]').val(JSON.stringify(e.ar));
$.aN.e.find('[name="details"]').val(JSON.stringify(e.ar))
})
$('#edit').change(function(e){
if($('#edit').is(':checked')){
$.aN.modeIsEdit = true
$('#title').text("<%-lang['Edit']%>")
$.aN.e.find('[name="mail"],[name="ke"]').prop('disabled',true)
}else{
$.aN.modeIsEdit = false
$('#title').text("<%-lang['Add New']%>")
$.aN.e.find('input,select').prop('disabled',false)
}
$.aN.e.find('[detail]').first().change()
}).change()
$.aN.e.on('change','[selector]',function(e){
e.v=$(this).val();e.a=$(this).attr('selector')
@ -182,6 +210,7 @@ $.aN.e.on('change','[selector]',function(e){
//simple lister
$.aC={e:$('#accounts')};$.aC.t=$.aC.e.find('table')
$.aC.e.on('click','.add',function(e){
$.aN.selected = null
$.aN.e.modal('show')
$('#edit').prop('checked',false).change().parent().removeClass('is-checked')
$.aN.f[0].reset()
@ -200,7 +229,6 @@ $.aC.e.on('click','.delete',function(e){
})
$.aC.e.on('click','.permission',function(e){
$.aN.e.modal('show')
$('#edit').prop('checked',true).change().parent().addClass('is-checked')
e.e=$(this).parents('tr');
e.u=e.e.attr('ke');
e.account=$.ccio.accounts[e.u];
@ -211,8 +239,9 @@ $.aC.e.on('click','.permission',function(e){
$.aN.e.find('[name="'+n+'"]').val(v).change()
})
$.each(JSON.parse(e.account.details),function(n,v){
$.aN.e.find('[detail="'+n+'"]').val(v).change()
$.aN.e.find('[detail="'+n+'"]').val(v)
})
$('#edit').prop('checked',true).change().parent().addClass('is-checked')
// $.pR.e.modal('show');
})

View file

@ -46,11 +46,6 @@
<div><input class="form-control" name="name"></div>
</label>
</div>
<div class="form-group">
<label><div><span><%-lang['Retry Connection']%></span></div>
<div><input class="form-control" detail="fatal_max" placeholder="10"></div>
</label>
</div>
<div class="form-group">
<label><div><span><%-lang["Number of Days to keep"]%> <%-lang["Videos"]%></span></div>
<div><input class="form-control" detail="max_keep_days" placeholder="Default is global value"></div>
@ -95,20 +90,22 @@
</select></div>
</label>
</div>
<div class="form-group">
<label><div><span><%-lang['Automatic']%></span></div>
<div><select class="form-control" detail="auto_host_enable" selector="h_auto_host">
<option value="0"><%-lang.No%></option>
<option value="1" selected><%-lang.Yes%></option>
</select></div>
</label>
</div>
<div class="form-group h_auto_host_input h_auto_host_1">
<div class="form-group">
<label><div><span><%-lang['Full URL Path']%></span></div>
<div><input class="form-control" detail="auto_host" placeholder="Example : rtsp://123.123.123.123/stream/1"></div>
<div class="h_t_input h_t_h264 h_t_hls h_t_mp4 h_t_jpeg h_t_mjpeg h_t_local">
<div class="form-group h_t_input h_t_h264 h_t_hls h_t_mp4 h_t_jpeg h_t_mjpeg">
<label><div><span><%-lang['Automatic']%></span></div>
<div><select class="form-control" detail="auto_host_enable" selector="h_auto_host">
<option value="0"><%-lang.No%></option>
<option value="1" selected><%-lang.Yes%></option>
</select></div>
</label>
</div>
<div class="form-group h_auto_host_input h_auto_host_1">
<div class="form-group">
<label><div><span><%-lang['Full URL Path']%></span></div>
<div><input class="form-control" detail="auto_host" placeholder="Example : rtsp://123.123.123.123/stream/1"></div>
</label>
</div>
</div>
</div>
<div class="h_auto_host_input h_auto_host_0 auto_host_fill" style="display:none">
<div class="form-group h_t_input h_t_h264 h_t_hls h_t_mp4 h_t_jpeg h_t_mjpeg">
@ -183,6 +180,19 @@
</select></div>
</label>
</div>
<div class="form-group">
<label><div><span><%-lang['ONVIF']%></span></div>
<div><select class="form-control" detail="is_onvif" selector="h_onvif">
<option value="0" selected><%-lang.No%></option>
<option value="1"><%-lang.Yes%></option>
</select></div>
</label>
</div>
<div class="form-group h_onvif_input h_onvif_1">
<label><div><span><%-lang['ONVIF Port']%></span></div>
<div><input class="form-control" detail="onvif_port" placeholder="8000" type="number"></div>
</label>
</div>
</div>
<!-- END of Connection -->
<!-- START of Input -->
@ -279,7 +289,7 @@
</div>
<div class="form-group">
<label><div><span><%-lang['Stream Type']%></span></div>
<div><select class="form-control" detail="stream_type" selector="h_st" triggerChange="#add_monitor [detail=stream_vcodec]" triggerChangeIgnore="b64">
<div><select class="form-control" detail="stream_type" selector="h_st" triggerChange="#add_monitor [detail=stream_vcodec]" triggerChangeIgnore="b64,mjpeg">
<option value="mp4"><%-lang['Poseidon']%></option>
<!-- <option value="pam">PAM</option>-->
<option value="b64" selected><%-lang['Base64 over Websocket']%></option>
@ -431,7 +441,7 @@
</div>
</div>
</div>
<div class="h_us_input h_us_advanced" style="display:none">
<div class="h_us_input h_us_advanced h_hls_v_input h_hls_v_libx264 h_hls_v_libx265 h_hls_v_h264_nvenc h_hls_v_hevc_nvenc h_hls_v_no" style="display:none">
<div class="form-group-group navy" section id="monSectionStreamTimestamp">
<h4><%-lang['Stream Timestamp']%></h4>
<div class="form-group">
@ -958,20 +968,47 @@
<div><input class="form-control" detail="detector_command_timeout" placeholder="10"></div>
</label>
</div>
<div class="row">
<div class="form-group col-md-12">
<label><div><span><%-lang['Email on Trigger']%></span></div>
<div><select class="form-control" detail="detector_mail">
<option value="0" selected><%-lang.No%></option>
<option value="1"><%-lang.Yes%></option>
</select></div>
</label>
</div>
<div class="form-group col-md-12">
<label><div><span><%-lang['Allow Next Email']%></span></div>
<div><input class="form-control" detail="detector_mail_timeout" placeholder="10"></div>
</label>
</div>
<div class="form-group">
<label><div><span><%-lang['Email on Trigger']%></span></div>
<div><select class="form-control" detail="detector_mail" selector="h_det_email">
<option value="0" selected><%-lang.No%></option>
<option value="1"><%-lang.Yes%></option>
</select></div>
</label>
</div>
<div class="form-group h_det_email_input h_det_email_1">
<label><div><span><%-lang['Attach Video Clip']%></span></div>
<div><select class="form-control" detail="detector_mail_send_video">
<option value="0" selected><%-lang.No%></option>
<option value="1"><%-lang.Yes%></option>
</select></div>
</label>
</div>
<div class="form-group h_det_email_input h_det_email_1">
<label><div><span><%-lang['Allow Next Email']%></span></div>
<div><input class="form-control" detail="detector_mail_timeout" placeholder="10"></div>
</label>
</div>
<div class="form-group">
<label><div><span><%-lang['Discord Alert on Trigger']%></span></div>
<div><select class="form-control" detail="detector_discordbot" selector="h_det_discord">
<option value="0" selected><%-lang.No%></option>
<option value="1"><%-lang.Yes%></option>
</select></div>
</label>
</div>
<div class="form-group h_det_discord_input h_det_discord_1">
<label><div><span><%-lang['Attach Video Clip']%></span></div>
<div><select class="form-control" detail="detector_discordbot_send_video">
<option value="0" selected><%-lang.No%></option>
<option value="1"><%-lang.Yes%></option>
</select></div>
</label>
</div>
<div class="form-group h_det_discord_input h_det_discord_1">
<label><div><span><%-lang['Allow Next Discord Alert']%></span></div>
<div><input class="form-control" detail="detector_discordbot_timeout" placeholder="10"></div>
</label>
</div>
<div class="hidden">
<div><input detail="cords" placeholder=""></div>
@ -1313,30 +1350,6 @@
<input type="hidden" detail="groups">
</div>
</div>
<div class="form-group-group green" section id="monSectionLogging">
<h4><%-lang['Logging']%></h4>
<div class="row">
<div class="form-group col-md-12">
<label><div><span><%-lang['Log Level']%></span></div>
<div><select class="form-control" detail="loglevel">
<option value="quiet"><%-lang['Silent']%></option>
<option value="fatal"><%-lang['Fatal']%></option>
<option value="error" selected><%-lang['on Error']%></option>
<option value="warning"><%-lang['All Warnings']%></option>
<option value="debug"><%-lang['Debug']%></option>
</select></div>
</label>
</div>
<div class="form-group col-md-12">
<label><div><span><%-lang['Save Log in SQL']%></span></div>
<div><select class="form-control" detail="sqllog">
<option value="0" selected><%-lang.No%></option>
<option value="1"><%-lang.Yes%></option>
</select></div>
</label>
</div>
</div>
</div>
<div class="form-group-group orange" section id="monSectionCopying">
<h4><%-lang['Copy Settings']%></h4>
<div class="form-group">
@ -1440,6 +1453,32 @@
</div>
</div>
</div>
<div class="form-group-group green" section id="monSectionLogging">
<h4><%-lang['Logging']%></h4>
<div class="form-group">
<label><div><span><%-lang['Log Level']%></span></div>
<div><select class="form-control" detail="loglevel">
<option value="quiet"><%-lang['Silent']%></option>
<option value="fatal"><%-lang['Fatal']%></option>
<option value="error" selected><%-lang['on Error']%></option>
<option value="warning"><%-lang['All Warnings']%></option>
<option value="debug"><%-lang['Debug']%></option>
</select></div>
</label>
</div>
<div class="form-group">
<label><div><span><%-lang['Save Log in SQL']%></span></div>
<div><select class="form-control" detail="sqllog">
<option value="0" selected><%-lang.No%></option>
<option value="1"><%-lang.Yes%></option>
</select></div>
</label>
</div>
<div class="form-group-group green">
<h4><%-lang['Log Stream']%></h4>
<div class="data-menu logs"></div>
</div>
</div>
</div>
<div class="form-group" style="display:none">
<input type="hidden" detail="detector_cascades">

View file

@ -179,6 +179,98 @@
</div>
</div>
<% } %>
<% if(details.use_aws_s3!=='0'){ %>
<div class="form-group-group forestgreen">
<h4><%-lang['Amazon S3']%></h4>
<div class="form-group">
<label><div><span><%-lang.Bucket%></span></div>
<div><input class="form-control" detail="aws_s3_bucket" placeholder="Example : slippery-seal"></div>
</label>
</div>
<div class="row">
<div class="form-group col-md-12">
<label><div><span><%-lang.aws_accessKeyId%></span></div>
<div><input class="form-control" detail="aws_accessKeyId"></div>
</label>
</div>
<div class="form-group col-md-12">
<label><div><span><%-lang.aws_secretAccessKey%></span></div>
<div><input class="form-control" type="password" detail="aws_secretAccessKey"></div>
</label>
</div>
</div>
<div class="form-group">
<label><div><span><%-lang.Region%></span></div>
<div><select class="form-control" detail="aws_region">
<option value="us-west-1" selected>US West (N. California)</option>
<option value="us-west-2">US West (Oregon)</option>
<option value="us-east-2">US East (Ohio)</option>
<option value="us-east-1">US East (N. Virginia)</option>
<option value="ap-south-1">Asia Pacific (Mumbai)</option>
<option value="ap-northeast-2">Asia Pacific (Seoul)</option>
<option value="ap-northeast-3">Asia Pacific (Osaka-Local)**</option>
<option value="ap-southeast-1">Asia Pacific (Singapore)</option>
<option value="ap-southeast-2">Asia Pacific (Sydney)</option>
<option value="ap-northeast-1">Asia Pacific (Tokyo)</option>
<option value="ca-central-1">Canada (Central)</option>
<option value="cn-north-1">China (Beijing)</option>
<option value="cn-northwest-1">China (Ningxia)</option>
<option value="eu-central-1">EU (Frankfurt)</option>
<option value="eu-west-1">EU (Ireland)</option>
<option value="eu-west-2">EU (London)</option>
<option value="eu-west-3">EU (Paris)</option>
<option value="sa-east-1">South America (São Paulo)</option>
</select></div>
</label>
</div>
<div class="form-group">
<label><div><span><%-lang.Autosave%></span></div>
<div><select class="form-control" detail="aws_s3_save">
<option value="0" selected><%-lang.No%></option>
<option value="1"><%-lang.Yes%></option>
</select></div>
</label>
</div>
<div class="form-group">
<label><div><span><%-lang['Save Links to Database']%></span></div>
<div><select class="form-control" detail="aws_s3_log">
<option value="0"><%-lang.No%></option>
<option value="1" selected><%-lang.Yes%></option>
</select></div>
</label>
</div>
<div class="form-group">
<label><div><span><%-lang['Save Directory']%></span></div>
<div><input class="form-control" placeholder="" detail="aws_s3_dir"></div>
</label>
</div>
</div>
<% } %>
<% if(details.use_discordbot!=='0'){ %>
<div class="form-group-group forestgreen">
<h4><%-lang['Discord Bot']%></h4>
<div class="form-group">
<label><div><span><%-lang.Enabled%></span></div>
<div><select class="form-control" detail="discordbot" selector="u_discord_bot">
<option value="0" selected><%-lang.No%></option>
<option value="1"><%-lang.Yes%></option>
</select></div>
</label>
</div>
<div class="u_discord_bot_input u_discord_bot_1">
<div class="form-group">
<label><div><span><%-lang.Token%></span></div>
<div><input type="password" class="form-control" placeholder="XXXXXXXXXXXXXXXXXXXXXXXX.XXXXXXXXXXXXXXX_XXXXXXXXXXXXXXXXXX" detail="discordbot_token"></div>
</label>
</div>
<div class="form-group">
<label><div><span><%-lang['Channel ID']%></span></div>
<div><input class="form-control" placeholder="xxxxxxxxxxxxxxxxxx" detail="discordbot_channel"></div>
</label>
</div>
</div>
</div>
<% } %>
<% if(details.use_ldap!=='0'){ %>
<div class="form-group-group forestgreen">
<h4><%-lang.LDAP%></h4>

View file

@ -10,15 +10,42 @@
</div>
<div class="modal-body" style="max-height:600px;overflow:auto">
<div class="text-center msg"></div>
<div class="form-group">
<label><div><span><%-lang['All Monitors and Privileges']%></span></div>
<div><select class="form-control" detail="allmonitors">
<option value="0" selected><%-lang.No%></option>
<option value="1"><%-lang.Yes%></option>
</select></div>
</label>
<div class="form-group-group">
<h4><%-lang['Privileges']%></h4>
<div class="form-group">
<label><div><span><%-lang['All Monitors and Privileges']%></span></div>
<div><select class="form-control" detail="allmonitors">
<option value="0" selected><%-lang.No%></option>
<option value="1"><%-lang.Yes%></option>
</select></div>
</label>
</div>
<div class="form-group permission-view">
<label><div><span><%-lang['Can Create and Delete Monitors']%></span></div>
<div><select class="form-control" detail="monitor_create">
<option value="0" selected><%-lang.No%></option>
<option value="1"><%-lang.Yes%></option>
</select></div>
</label>
</div>
<div class="form-group permission-view">
<label><div><span><%-lang['Can Change User Settings']%></span></div>
<div><select class="form-control" detail="user_change">
<option value="0" selected><%-lang.No%></option>
<option value="1"><%-lang.Yes%></option>
</select></div>
</label>
</div>
<div class="form-group">
<label><div><span><%-lang['Can View Logs']%></span></div>
<div><select class="form-control" detail="view_logs">
<option value="0" selected><%-lang.No%></option>
<option value="1"><%-lang.Yes%></option>
</select></div>
</label>
</div>
</div>
<div class="form-group-group blue" id="monitors_section">
<div class="form-group-group blue permission-view" id="monitors_section">
<h4>
<%-lang['Can View Monitor']%>
<div class="pull-right">
@ -37,7 +64,7 @@
</div>
<% }) %>
</div>
<div class="form-group-group forestgreen" id="monitors_edit_section">
<div class="form-group-group forestgreen permission-view" id="monitors_edit_section">
<h4>
<%-lang['Can Edit Monitor']%>
<div class="pull-right">
@ -56,7 +83,7 @@
</div>
<% }) %>
</div>
<div class="form-group-group navy" id="video_view_section">
<div class="form-group-group navy permission-view" id="video_view_section">
<h4>
<%-lang['Can View Videos and Events']%>
<div class="pull-right">
@ -75,7 +102,7 @@
</div>
<% }) %>
</div>
<div class="form-group-group red" id="video_delete_section">
<div class="form-group-group red permission-view" id="video_delete_section">
<h4>
<%-lang['Can Delete Videos and Events']%>
<div class="pull-right">

View file

@ -8,10 +8,9 @@
</button>
<h4 class="modal-title" id="videos_viewerLabel"><i class="fa fa-film"></i> &nbsp; <%-lang.Videos%> <small> <span class="video_viewer_total"></span> <%-lang.total%></small></h4>
</div>
<div class="modal-body flex-container-modal-body">
<div style="padding:20px 0" class="flex-block flex-modal-block">
<div class="modal-body overflow-hidden">
<div style="padding:20px 0">
<div class="col-md-3">
<div class="form-group">
<label><div><span><%-lang['Date Range']%></span></div>
<div><input type="text" id="videos_viewer_daterange" class="form-control" value="" /></div>
@ -32,7 +31,8 @@
<div class="modal-footer">
<div class="row">
<div class="col-md-4 text-left">
<a class="btn btn-danger delete_selected"><i class="fa fa-trash-o"></i> &nbsp; <%-lang['Delete selected']%></a>
<a class="btn btn-danger delete_selected"><i class="fa fa-trash-o"></i> &nbsp; <%-lang['Delete']%></a>
<a class="btn btn-default export_selected"><i class="fa fa-folder-o"></i> &nbsp; <%-lang['Zip and Download']%></a>
</div>
<div class="col-md-4">
<div class="text-center" id="videos_viewer_pages"></div>

View file

@ -1,6 +1,6 @@
<% include blocks/header %>
<script>var $user=<%- JSON.stringify($user) %>;</script>
<link rel="stylesheet" href="libs/css/bootstrap.min.css">
<link rel="stylesheet" href="<%-originalURL%>libs/css/bootstrap.min.css">
<div id="main" class="container">
<a class="btn btn-danger btn-lg" record>Stream</a>
<div>
@ -19,15 +19,20 @@ requires https or firefox
</div>
<video id="video"><source></video>
<canvas id="canvas"></canvas>
<script src="libs/js/jquery.min.js"></script>
<script src="libs/js/socket.io.js"></script>
<script src="libs/js/menu.js"></script>
<script src="<%-originalURL%>libs/js/jquery.min.js"></script>
<script src="<%-originalURL%>libs/js/socket.io.js"></script>
<script src="<%-originalURL%>libs/js/menu.js"></script>
<script>
$.ccio={};$.ls=localStorage;
$.ccio.ws=io(location.origin);
$.ccio = {}
$.ls = localStorage
$.ccio.ws = io(location.origin)
$.ccio.ws.on('connect',function (d){
$(document).ready(function(e){
$.ccio.cx=function(x){if(!x.ke){x.ke=$user.ke;};if(!x.uid){x.uid=$user.uid;};return $.ccio.ws.emit('r',x)}
$.ccio.cx=function(x){
if(!x.ke){x.ke=$user.ke;}
if(!x.uid){x.uid=$user.uid;}
return $.ccio.ws.emit('r',x)
}
console.log($user)
$.ccio.cx({f:'init',ke:$user.ke,auth:$user.auth_token,uid:$user.uid})
})
@ -41,6 +46,16 @@ $.ccio.ws.on('f',function(d){
$.ccio.mon[d.mid][n]=v;
});
break;
case'disable_stream':
$.ccio.mon[d.mid].allowStream = false
if(d.mid === $.ccio.selected){
$.ccio.stopSending()
setTimeout($.ccio.startSending,2000)
}
break;
case'enable_stream':
$.ccio.mon[d.mid].allowStream = true
break;
}
})
function _base64ToArrayBuffer(base64) {
@ -52,81 +67,95 @@ function _base64ToArrayBuffer(base64) {
}
return bytes.buffer;
}
$.ccio.framerate=2;
$.ccio.stopSending=function(){
$.ls.setItem('Shinobi_Dashcam_Started','0')
$('#main').removeClass('recording');
clearInterval($.ccio.cutChunk);
clearTimeout($.ccio.sendCheckTimeout);
try{
mediaRecorder.stop()
}catch(err){
}
$('[record]').unbind('click').click($.ccio.startSending)
}
$.ccio.startSending=function(){
if($.ccio.selected===null){return false;}
$('#main').addClass('recording');
if (typeof MediaRecorder.isTypeSupported == 'function'){
/*
MediaRecorder.isTypeSupported is a function announced in https://developers.google.com/web/updates/2016/01/mediarecorder and later introduced in the MediaRecorder API spec http://www.w3.org/TR/mediastream-recording/
*/
if (MediaRecorder.isTypeSupported('video/webm;codecs=vp9')) {
var options = {mimeType: 'video/webm;codecs=vp9'};
} else if (MediaRecorder.isTypeSupported('video/webm;codecs=h264')) {
var options = {mimeType: 'video/webm;codecs=h264'};
} else if (MediaRecorder.isTypeSupported('video/webm;codecs=vp8')) {
var options = {mimeType: 'video/webm;codecs=vp8'};
}
log('Using '+options.mimeType);
mediaRecorder = new MediaRecorder($.ccio.vid.stream, options);
}else{
log('Using default codecs for browser');
mediaRecorder = new MediaRecorder($.ccio.vid.stream);
}
mediaRecorder.start(10);
$.ccio.chunker = function(){
clearInterval($.ccio.cutChunk)
$.ccio.cutChunk=setInterval(function(){
mediaRecorder.stop()
mediaRecorder.start()
},5000)
$.ccio.firstFrame = null
$.ccio.startSending = function(){
if($.ccio.selected === null){
return false
}
mediaRecorder.ondataavailable = function(e) {
//log('Data available...');
//console.log(e.data);
//console.log(e.data.type);
//console.log(e);
chunks.push(e.data);
};
$.ls.setItem('Shinobi_Dashcam_Started',1)
$('#main').addClass('recording');
if($.ccio.mon[$.ccio.selected].allowStream === true){
if (typeof MediaRecorder.isTypeSupported == 'function'){
var options = {
audioBitsPerSecond : 128000,
videoBitsPerSecond : 2500000,
}
if (MediaRecorder.isTypeSupported('video/webm;codecs=vp9')) {
options.mimeType = 'video/webm;codecs=vp9'
} else if (MediaRecorder.isTypeSupported('video/webm;codecs=h264')) {
options.mimeType = 'video/webm;codecs=h264'
} else if (MediaRecorder.isTypeSupported('video/webm;codecs=vp8')) {
options.mimeType = 'video/webm;codecs=vp8'
}
console.log('Using '+options.mimeType);
mediaRecorder = new MediaRecorder($.ccio.vid.stream, options);
}else{
console.log('Using default codecs for browser');
mediaRecorder = new MediaRecorder($.ccio.vid.stream);
}
mediaRecorder.onerror = function(e){
clearInterval($.ccio.cutChunk)
};
mediaRecorder.start(10)
$.ccio.chunker = function(){
clearInterval($.ccio.cutChunk)
$.ccio.cutChunk=setInterval(function(){
var blob = new Blob(chunks, {type: "video/webm"});
$.ccio.cx({f:'monitor_chunk',chunk:blob,mid:$.ccio.selected});
chunks = [];
},1000/$.ccio.framerate)
}
var noFirstFrame = function(e){
$.ccio.firstFrame = e.data
chunks.push(e.data);
mediaRecorder.ondataavailable = function(e) {
chunks.push(e.data);
}
}
mediaRecorder.ondataavailable = noFirstFrame
mediaRecorder.onerror = function(e){
clearInterval($.ccio.cutChunk)
}
mediaRecorder.onstart = function(){
$.ccio.chunker()
};
mediaRecorder.onstart = function(){
if($.ccio.firstFrame){
var blob = new Blob([$.ccio.firstFrame], {type: "video/webm"});
$.ccio.cx({f:'monitor_chunk',chunk:blob,mid:$.ccio.selected});
}
$.ccio.chunker()
}
mediaRecorder.onstop = function(){
var blob = new Blob(chunks, {type: "video/webm"});
$.ccio.cx({f:'monitor_chunk',chunk:blob,mid:$.ccio.selected});
// var reader = new FileReader();
// reader.addEventListener("loadend", function() {
// console.log(reader.result)
// });
// reader.readAsArrayBuffer(blob);
chunks = [];
};
mediaRecorder.onpause = function(){
clearInterval($.ccio.cutChunk)
}
mediaRecorder.onpause = function(){
clearInterval($.ccio.cutChunk)
}
mediaRecorder.onresume = function(){
$.ccio.chunker()
}
mediaRecorder.onresume = function(){
$.ccio.chunker()
}
mediaRecorder.onwarning = function(e){
clearInterval($.ccio.cutChunk)
};
mediaRecorder.onwarning = function(e){
clearInterval($.ccio.cutChunk)
}
}else{
clearTimeout($.ccio.sendCheckTimeout)
$.ccio.sendCheckTimeout = setTimeout($.ccio.startSending,2000)
}
$('[record]').unbind('click').click($.ccio.stopSending)
};
function log(message){
@ -138,9 +167,33 @@ function log(message){
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;
window.URL = window.URL || window.webkitURL || window.mozURL || window.msURL;
if(getBrowser() == "Chrome"){
var constraints = {"audio": true, "video": { "mandatory": { "minWidth": 640, "maxWidth": 640, "minHeight": 480,"maxHeight": 480 }, "optional": [] } };//Chrome
var constraints = {
"audio": true,
"video": {
"mandatory": {
"minWidth": 640,
"maxWidth": 5000,
"minHeight": 480,
"maxHeight": 2500
}, "optional": []
}
};
}else if(getBrowser() == "Firefox"){
var constraints = {audio: true,video: { width: { min: 640, ideal: 640, max: 640 }, height: { min: 480, ideal: 480, max: 480 }}}; //Firefox
var constraints = {
audio: true,
video: {
width: {
min: 640,
ideal: 640,
max: 5000
},
height: {
min: 480,
ideal: 480,
max: 2500
}
}
};
}
var mediaRecorder;
var chunks = [];
@ -149,8 +202,20 @@ var count = 0;
$.ccio.vid = {element:$('#video')[0],canvas:$('#canvas')[0],data:$('#data')};
$.ccio.vid.element.controls = false;
navigator.getUserMedia(constraints,function(stream,fn) {
$.ccio.vid.stream=stream;
$.ccio.vid.stream = stream;
$.ccio.vid.element.srcObject = stream;
$('[record]').click($.ccio.startSending)
////////
if($user.mons.length>0&&$.ls.getItem('Shinobi_Dashcam')){
$('[monitor="'+$.ls.getItem('Shinobi_Dashcam')+'"]').click()
if($.ls.getItem('Shinobi_Dashcam_Started') === 1){
setTimeout(function(){
$('[record]').click()
},3000)
}
}else{
$.ccio.selected = null;
}
}, function(err){console.error('getUserMedia',err)});
@ -187,8 +252,6 @@ navigator.getUserMedia(constraints,function(stream,fn) {
})
if($user.mons.length>0&&$.ls.getItem('Shinobi_Dashcam')){$('[monitor="'+$.ls.getItem('Shinobi_Dashcam')+'"]').click()}else{$.ccio.selected=null;}
$('body')
.on('click','.logout',function(e){
localStorage.removeItem('ShinobiLogin_'+location.host);location.href='/';
@ -264,5 +327,6 @@ $('body')
#main{text-align:center}
#msg h2{margin-top:0}
#img{border-radius:5px;overflow:hidden;max-width:100%;display:inline-block;margin-top: 30px}
#video,#canvas{position: absolute;display:none}
#canvas{position: absolute;display:none}
#video{display:inline-block}
</style>

View file

@ -8,7 +8,9 @@ if(config.ssl&&config.ssl.port&&data.protocol==='https'){
}
if(!data.port||data.port===''||data.port==80||data.port==443){data.url=baseUrl}else{data.url=baseUrl+':'+data.port}
if(data.addon || data.addon.indexOf('relative')>-1){
data.url=''
data.url = ''
}else if(config.baseURL){
data.url = config.baseURL
}
if(data.url.charAt(data.url.length - 1) !== '/'){
data.url += '/'
@ -107,9 +109,10 @@ if(data.addon.indexOf('gui')>-1){ %>
<% };
if(data.addon.indexOf('fullscreen')>-1){ %>
<style>
body,html{overflow: hidden;}
body,html{overflow: hidden;height:100%}
*{margin:0;padding:0;border:0}
.stream-element,.shinobi_stream{position:absolute;top:0;left:0;}
.stream-element,.shinobi_stream{position:absolute;top:0;left:0;height:100%}
.shinobi_stream video{object-fit: fill}
</style>
<script>
$(window).resize(function(){

View file

@ -10,7 +10,7 @@
<div class="row">
<div class="col-xs-12">
<a href="http://shinobi.video" target="_blank">
<img src="libs/img/icon/apple-touch-icon-76x76.png" style="border-radius:50%">
<img src="<%-originalURL%>libs/img/icon/apple-touch-icon-76x76.png" style="border-radius:50%">
</a>
</div>
</div>
@ -50,7 +50,7 @@
</div>
</div>
</div>
<script src="libs/js/material.min.js"></script>
<script src="<%-originalURL%>libs/js/material.min.js"></script>
<script>
$.ccio={f:$('#auth-form'),ls:localStorage.getItem('ShinobiAuth_'+location.host)}
$.ccio.gid=function(x){

View file

@ -1,18 +1,17 @@
<% var details=JSON.parse($user.details) %>
<% include blocks/header %>
<script>var $user=<%- JSON.stringify($user) %>;</script>
<link rel="stylesheet" href="libs/css/pnotify.custom.min.css">
<link rel="stylesheet" href="libs/css/vbox.css">
<link rel="stylesheet" href="libs/css/daterangepicker.css">
<link rel="stylesheet" href="libs/css/circles.css">
<!--<link rel="stylesheet" href="libs/css/poseidon.css">-->
<link rel="stylesheet" href="libs/css/bootstrap.min.css">
<link rel="stylesheet" href="libs/css/font-awesome.min.css">
<link rel="stylesheet" href="libs/css/fullcalendar.min.css">
<link rel="stylesheet" href="libs/css/gridstack.min.css">
<link rel="stylesheet" href="libs/css/gridstack-extra.min.css">
<link rel="stylesheet" href="libs/css/bootstrap-table.min.css">
<link rel="stylesheet" href="libs/css/main.dash2.css">
<link rel="stylesheet" href="<%-originalURL%>libs/css/pnotify.custom.min.css">
<link rel="stylesheet" href="<%-originalURL%>libs/css/vbox.css">
<link rel="stylesheet" href="<%-originalURL%>libs/css/daterangepicker.css">
<link rel="stylesheet" href="<%-originalURL%>libs/css/circles.css">
<link rel="stylesheet" href="<%-originalURL%>libs/css/bootstrap.min.css">
<link rel="stylesheet" href="<%-originalURL%>libs/css/font-awesome.min.css">
<link rel="stylesheet" href="<%-originalURL%>libs/css/fullcalendar.min.css">
<link rel="stylesheet" href="<%-originalURL%>libs/css/gridstack.min.css">
<link rel="stylesheet" href="<%-originalURL%>libs/css/gridstack-extra.min.css">
<link rel="stylesheet" href="<%-originalURL%>libs/css/bootstrap-table.min.css">
<link rel="stylesheet" href="<%-originalURL%>libs/css/main.dash2.css">
<style id="theme">
<% if(details.theme&&details.theme!==''){ %><%- include(__dirname+'/web/libs/themes/'+details.theme+'/style.css'); %><% } %>
</style>
@ -20,21 +19,12 @@
<%= details.css %>
</style>
<style>
<% if(details.sub&&details.allmonitors==='0'){
if(details.monitor_edit&&details.monitor_edit!==''){
details.monitor_edit.forEach(function(v,n){ %>
[mid="<%= v %>"] .permission_monitor_edit{display:inline-block}
<%
})
}
if(details.video_delete&&details.video_delete!==''){
details.video_delete.forEach(function(v,n){ %>
[mid="<%= v %>"] .permission_video_delete{display:inline-block}
<%
})
}
<% if(details.video_delete&&details.video_delete!==''){
details.video_delete.forEach(function(v,n){ %>
[mid="<%= v %>"] .permission_video_delete{display:inline-block}
<%
})
}else{ %>
.permission_video_delete,.permission_monitor_edit{display:inline-block}
th.permission_video_delete,td.permission_video_delete{display:table-cell}
<% } %>
</style>
@ -51,7 +41,7 @@
<div class="mdl-layout__header-row">
<ul class="nav navbar-nav">
<li title="<%-lang['Toggle Sidebar']%>" class_toggle="hide-side" data-target=".mdl-js-layout"><a>&nbsp;<i class="fa fa-bars"></i>&nbsp;</a></li>
<li title="<%-lang['Add Monitor']%>" mid="" ke="" class="hidden-xs permission_monitor_edit"><a monitor="edit">&nbsp;<i class="fa fa-plus"></i>&nbsp;</a></li>
<li title="<%-lang['Add Monitor']%>" mid="" ke="" class="hidden-xs permission_monitor_create"><a monitor="edit">&nbsp;<i class="fa fa-plus"></i>&nbsp;</a></li>
<li title="<%-lang['Power Video Viewer']%>" class="hidden-xs" mid="" ke=""><a monitor="powerview">&nbsp;<i class="fa fa-map-marker"></i>&nbsp;</a></li>
<li>
<a title="<%-lang['Monitor Groups']%>" id="group_list_button" class="mdl-js-button">&nbsp;<i class="fa fa-video-camera"></i>&nbsp;</a>
@ -118,23 +108,24 @@
<div class="demo-drawer mdl-layout__drawer">
<header class="demo-drawer-header">
<div class="demo-avatar-dropdown">
<button id="accbtn" style="color:#fff" class="usermail mdl-button mdl-js-button mdl-js-ripple-effect"></button>
<button id="accbtn" style="color:#fff" class="mdl-button mdl-js-button mdl-js-ripple-effect"><i class="fa fa-caret-down"></i> &nbsp;<span class="usermail"></span></button>
<ul class="mdl-menu mdl-menu--bottom-left mdl-js-menu mdl-js-ripple-effect" for="accbtn">
<li class="mdl-menu__item" data-toggle="modal" data-target="#multi_mon"><div><i class="fa fa-clone"></i><div><%- lang['Monitors'] %></div></div></li>
<li class="mdl-menu__item" mid="" ke=""><div class="flex" monitor="powerview"><i class="fa fa-map-marker"></i><div><%- lang['Power Viewer'] %></div></div></li>
<li class="mdl-menu__item" mid="" ke=""><div class="flex" monitor="timelapse"><i class="fa fa-angle-double-right"></i><div><%- lang['Time-lapse'] %></div></div></li>
<li class="mdl-menu__item" data-toggle="modal" data-target="#settings"><div><i class="fa fa-gears"></i><div><%- lang.Settings %></div></div></li>
<li class="mdl-menu__item permission_user_change" data-toggle="modal" data-target="#settings"><div><i class="fa fa-gears"></i><div><%- lang.Settings %></div></div></li>
<li class="mdl-menu__item" data-toggle="modal" data-target="#apis"><div><i class="fa fa-code"></i><div><%- lang.API %></div></div></li>
<% if(!details.sub){ %>
<li class="mdl-menu__item" data-toggle="modal" data-target="#onvif_probe"><div><i class="fa fa-rss"></i><div><%- lang.ONVIF %></div></div></li>
<li class="mdl-menu__item" data-toggle="modal" data-target="#probe"><div><i class="fa fa-search"></i><div><%- lang.FFprobe %></div></div></li>
<li class="mdl-menu__item" data-toggle="modal" data-target="#filters"><div><i class="fa fa-filter"></i><div><%- lang.Filters %></div></div></li>
<% } %>
<li class="mdl-menu__item" data-toggle="modal" data-target="#logs_modal"><div><i class="fa fa-exclamation-triangle"></i><div><%- lang.Logs %></div></div></li>
<li class="mdl-menu__item permission_view_logs" data-toggle="modal" data-target="#logs_modal"><div><i class="fa fa-exclamation-triangle"></i><div><%- lang.Logs %></div></div></li>
<li class="mdl-menu__item" class_toggle="list-blocks" data-target="#left_menu"><div><i class="fa fa-camera"></i><div><%- lang['List Toggle'] %></div></div></li>
<li class="mdl-menu__item" class_toggle="hide-side" data-target=".mdl-js-layout"><div><i class="fa fa-bars"></i><div><%- lang['Hide List'] %></div></div></li>
<li class="mdl-menu__item shinobi-detector-motion shinobi-detector-opencv shinobi-detector_plug" class_toggle="hide_indifference" data-target="body" style="display:none"><div><i class="fa fa-bolt"></i><div><%- lang['Motion GUI'] %></div></div></li>
<li class="mdl-menu__item" system="jpegToggle"><div><i class="fa fa-file-image-o"></i><div><%- lang['JPEG Mode'] %></div></div></li>
<li class="mdl-menu__item" system="switch" switch="monitorMuteAudio" type="text"><div><i class="fa fa-volume-down"></i><div><%- lang['Mute Audio'] %></div></div></li>
<li class="mdl-menu__item" system="switch" switch="monitorOrder" type="text"><div><i class="fa fa-sort"></i><div><%- lang['Order Streams'] %></div></div></li>
<li class="mdl-menu__item" system="switch" switch="notifyHide" type="text"><div><i class="fa fa-exclamation-circle"></i><div><%- lang['Hide Notes'] %></div></div></li>
<li class="mdl-menu__item logout"><div><i class="fa fa-sign-out"></i><div><%- lang.Logout %></div></div></li>
@ -178,27 +169,28 @@
<script type="text/javascript" src="https://www.dropbox.com/static/api/2/dropins.js" id="dropboxjs" data-app-key="<%= config.DropboxAppKey %>"></script>
<!--Dropbox End-->
<% } %>
<script src="libs/js/material.min.js"></script>
<script src="libs/js/pnotify.custom.min.js"></script>
<script src="<%-originalURL%>libs/js/material.min.js"></script>
<script src="<%-originalURL%>libs/js/pnotify.custom.min.js"></script>
<script><% include ../libs/js/moment.js %></script>
<script><% include ../libs/js/livestamp.min.js %></script>
<script src="libs/js/placeholder.js"></script>
<script src="libs/js/bootstrap.min.js"></script>
<script src="libs/js/bootstrap-table.min.js"></script>
<script src="libs/js/socket.io.js"></script>
<script src="libs/js/fullcalendar.min.js"></script>
<script src="libs/js/hls.min.js"></script>
<script type="text/javascript" src="libs/js/flv.shinobi.js">;</script>
<script src="libs/js/menu.js"></script>
<script src="libs/js/clock.js"></script>
<script src="libs/js/poseidon.js"></script>
<script src="libs/js/Chart.js"></script>
<script src="libs/js/clusterPoints.js"></script>
<script src="libs/js/daterangepicker.js"></script>
<script src="libs/js/jquery.canvasAreaDraw.js"></script>
<script src="libs/js/jquery-ui.min.js"></script>
<script src="libs/js/lodash.min.js"></script>
<script src="libs/js/gridstack.min.js"></script>
<script src="libs/js/gridstack.jQueryUI.min.js"></script>
<script src="<%-originalURL%>libs/js/placeholder.js"></script>
<script src="<%-originalURL%>libs/js/bootstrap.min.js"></script>
<script src="<%-originalURL%>libs/js/bootstrap-table.min.js"></script>
<script src="<%-originalURL%>libs/js/socket.io.js"></script>
<script src="<%-originalURL%>libs/js/fullcalendar.min.js"></script>
<script src="<%-originalURL%>libs/js/hls.min.js"></script>
<script type="text/javascript" src="<%-originalURL%>libs/js/flv.shinobi.js">;</script>
<script src="<%-originalURL%>libs/js/menu.js"></script>
<script src="<%-originalURL%>libs/js/clock.js"></script>
<script src="<%-originalURL%>libs/js/poseidon.js"></script>
<script src="<%-originalURL%>libs/js/Chart.js"></script>
<script src="<%-originalURL%>libs/js/clusterPoints.js"></script>
<script src="<%-originalURL%>libs/js/daterangepicker.js"></script>
<script src="<%-originalURL%>libs/js/jquery.canvasAreaDraw.js"></script>
<script src="<%-originalURL%>libs/js/jquery-ui.min.js"></script>
<!--<script src="<%-originalURL%>libs/js/jquery.ui.touch.js"></script>-->
<script src="<%-originalURL%>libs/js/lodash.min.js"></script>
<script src="<%-originalURL%>libs/js/gridstack.min.js"></script>
<script src="<%-originalURL%>libs/js/gridstack.jQueryUI.min.js"></script>
<script><% include ../libs/js/main.dash2.js %></script>
<% include blocks/help.ejs %>

View file

@ -11,7 +11,7 @@
<div class="row">
<div class="col-xs-12">
<a href="http://shinobi.video" target="_blank">
<img src="libs/img/icon/apple-touch-icon-76x76.png" style="border-radius:50%">
<img src="<%-originalURL%>libs/img/icon/apple-touch-icon-76x76.png" style="border-radius:50%">
</a>
</div>
</div>
@ -75,7 +75,7 @@
</div>
</div>
</div>
<script src="libs/js/material.min.js"></script>
<script src="<%-originalURL%>libs/js/material.min.js"></script>
<script>
<% var failedLogin;if(failedLogin===true){ %>
localStorage.removeItem('ShinobiLogin_'+location.host)

View file

@ -1,6 +1,6 @@
<% include blocks/header %>
<script>var $user=<%- JSON.stringify($user) %>;</script>
<link rel="stylesheet" href="libs/css/bootstrap.min.css">
<link rel="stylesheet" href="<%-originalURL%>libs/css/bootstrap.min.css">
<div id="main" class="container">
<a class="btn btn-danger btn-lg" record>Stream</a>
<div>
@ -17,9 +17,8 @@ requires https or firefox
</div>
<video id="video"><source></video>
<canvas id="canvas"></canvas>
<script src="libs/js/jquery.min.js"></script>
<script src="libs/js/socket.io.js"></script>
<script src="libs/js/menu.js"></script>
<script src="<%-originalURL%>libs/js/socket.io.js"></script>
<script src="<%-originalURL%>libs/js/menu.js"></script>
<script>
$.ccio={};$.ls=localStorage;
$.ccio.ws=io(location.origin);
@ -63,7 +62,7 @@ $.ccio.start=function(){
$.ccio.cx({f:'monitor_frame',frame:ctx,mid:$.ccio.selected});
delete(ctx);
},1000/$.ccio.framerate);
$('[record]').unbind('click').click($.ccio.end)
$('[record]').unbind('click').click($.ccio.end)
};
@ -74,7 +73,7 @@ $('[record]').unbind('click').click($.ccio.end)
$.ccio.vid = {e:$('#video'),c:$('#canvas')};
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia||navigator.mediaDevices.getUserMedia;
window.URL = window.URL || window.webkitURL || window.mozURL || window.msURL;
window.URL = window.URL || window.webkitURL || window.mozURL || window.msURL;
navigator.getUserMedia({video: true},function(stream,fn) {
//set video element
if ($.ccio.vid.e[0].mozSrcObject !== undefined) {

View file

@ -1,95 +1,195 @@
<% include blocks/header %>
<link rel="stylesheet" href="libs/css/pnotify.custom.min.css">
<link rel="stylesheet" href="libs/css/vbox.css">
<link rel="stylesheet" href="libs/css/circles.css">
<link rel="stylesheet" href="libs/css/material.min.css">
<link rel="stylesheet" href="libs/css/bootstrap.min.css">
<link rel="stylesheet" href="libs/css/font-awesome.min.css">
<link rel="stylesheet" href="libs/css/fullcalendar.min.css">
<link rel="stylesheet" href="libs/css/bootstrap-table.min.css">
<link rel="stylesheet" href="libs/css/main.dash2.css">
<style>
.form-group label>div:first-child{width:40%}
</style>
<body style="background:rgba(33,33,33,1);">
<div class="container-fluid">
<div class="container">
<nav class="navbar navbar-default">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<a class="navbar-brand" href="/"><%-lang.superAdminTitle%></a>
</div>
<ul class="nav navbar-nav navbar-right">
<!-- <li><a href="#">Link</a></li>-->
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">&nbsp;<i class="fa fa-bars"></i>&nbsp;</a>
<ul class="dropdown-menu">
<!--
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li role="separator" class="divider"></li>
-->
<li><a class="logout"><i class="fa fa-sign-out pull-right"></i> <%-lang.Logout%></a></li>
</ul>
</li>
</ul>
</div><!-- /.container-fluid -->
</nav>
<div class="row">
<div class="col-md-6">
<div class="form-group-group grey" id="accounts">
<h4><%-lang.Accounts%><a class="pull-right add btn btn-success btn-xs"><i class="fa fa-plus"></i></a></h4>
<table class="table table-striped"></table>
</div>
<div class="form-group-group primary no-padding" id="logs">
<h4 class="no-margin"><%-lang['Logs']%><a class="pull-right delete btn btn-danger btn-xs"><i class="fa fa-trash-o"></i></a></h4>
<div style="height:400px;overflow:auto">
<table class="table table-striped"></table>
</div>
</div>
<!DOCTYPE html>
<html lang="en">
<head>
<title><%-lang.Superuser%> - <%-lang.Shinobi%></title>
<% include blocks/header-meta.ejs %>
<% include blocks/header-favicon.ejs %>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta content='width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0, shrink-to-fit=no' name='viewport' />
<!-- Fonts and icons -->
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,700,200" rel="stylesheet" />
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/latest/css/font-awesome.min.css" />
<!-- CSS Files -->
<link href="<%-originalURL%>libs/css/bootstrap4.min.css" rel="stylesheet" />
<link href="<%-originalURL%>libs/css/main.dash2.css" rel="stylesheet" />
<link rel="stylesheet" href="<%-originalURL%>libs/css/pnotify.custom.min.css">
<link href="<%-originalURL%>libs/css/now-ui-kit.css?v=1.1.0" rel="stylesheet" />
<script src="<%-originalURL%>libs/js/jquery.min.js"></script>
<script src="<%-originalURL%>libs/js/jquery.serialize.js"></script>
<script src="<%-originalURL%>libs/js/pnotify.custom.min.js"></script>
<script src="<%-originalURL%>libs/js/popper.min.js" type="text/javascript"></script>
<script src="<%-originalURL%>libs/js/bootstrap4.min.js" type="text/javascript"></script>
<style>
.form-group label>div:first-child{width:40%}
.list-group li .form-group {margin:0}
a {cursor:pointer}
</style>
</head>
<body class="index-page sidebar-collapse bg-hexagon">
<!-- Navbar -->
<nav id="main-nav" class="navbar navbar-expand-lg bg-primary fixed-top" color-on-scroll="400">
<div class="container">
<div class="navbar-translate">
<a tabindex="1" class="navbar-brand logout" href="/" data-placement="bottom" target="_blank">
<%-lang.superAdminTitle%>
</a>
<button class="navbar-toggler navbar-toggler" type="button" data-toggle="collapse" data-target="#navigation" aria-controls="navigation-index" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-bar bar1"></span>
<span class="navbar-toggler-bar bar2"></span>
<span class="navbar-toggler-bar bar3"></span>
</button>
</div>
<div class="col-md-6">
<form class="form-group-group red" id="conf_json">
<h4><%-lang['Configuration']%> <small class="pull-right msg"></small></h4>
<div class="form-group">
<textarea name="json" style="height:300px;font-family: monospace;" class="form-control"></textarea>
</div>
<div>
<div class="pull-right">
<button type="submit" class="btn btn-success"><i class="fa fa-check"></i> <%-lang.Save%></button>
</div>
</div>
</form>
<div class="form-group-group blue" id="system">
<h4><%-lang['System']%> <small class="pull-right msg"></small></h4>
<div class="btn-group btn-group-justified">
<a restart="system" class="btn btn-danger"><i class="fa fa-retweet"></i> <%-lang['Restart Core']%></a>
<a restart="cron" class="btn btn-danger"><i class="fa fa-retweet"></i> <%-lang['Restart CRON']%></a>
<a restart="logs" class="btn btn-danger"><i class="fa fa-retweet"></i> <%-lang['Flush PM2 Logs']%></a>
<div class="collapse navbar-collapse justify-content-end" id="navigation" data-nav-image="<%-originalURL%>libs/img/blurred-image-1.jpg">
<ul class="nav navbar-nav navbar-right">
<li class="nav-item">
<a href="javascript:location.href=location.pathname" class="nav-link" class="logout">
<i class="fa fa-sign-out"></i>
<p class="d-lg-none d-xl-none"><%-lang.Logout%></p>
</a>
</li>
</ul>
</div>
</div>
</nav>
<!-- End Navbar -->
<div class="wrapper">
<div class="page-header clear-filter" filter-color="primary">
<div class="container">
<div class="row">
<div class="col-md-12">
<div id="main-card" class="card">
<ul class="nav nav-tabs nav-tabs-neutral justify-content-center bg-primary" role="tablist">
<li class="nav-item">
<a class="nav-link active" data-toggle="tab" href="#accounts" role="tab">Accounts</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="tab" href="#config" role="tab">Configuration</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="tab" href="#system" role="tab">Controls and Logs</a>
</li>
</ul>
<div class="card-body">
<!-- Tab panes -->
<div class="tab-content text-center">
<div class="tab-pane active" id="accounts" 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 add">
<p><i class="fa fa-plus-square-o"></i> Add Account</p>
</a>
</li>
</ul>
</div>
</div>
</nav>
<table class="table table-striped"></table>
</div>
<div class="tab-pane" id="config" role="tabpanel">
<small class="pull-right msg"></small>
<nav class="navbar navbar-rounded navbar-expand-lg bg-success">
<div class="container">
<div class="collapse navbar-collapse">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link add" href="javascript:$.conf.e.submit()">
<p><i class="fa fa-check"></i> <%-lang.Save%></p>
</a>
</li>
<li class="nav-item">
<a class="nav-link add" href="javascript:$.conf.e.submit()">
<p class="msg"></p>
</a>
</li>
</ul>
</div>
</div>
</nav>
<form class="form-group-group red" id="conf_json">
<small class="pull-right msg"></small>
<div id="configForHumans"></div>
<div class="form-group">
<textarea name="json" style="height:300px;font-family: monospace;" class="form-control"></textarea>
</div>
</form>
</div>
<div class="tab-pane" 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> Clear 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>
<!--
<li class="nav-item">
<a class="nav-link" system="update">
<p><i class="fa fa-arrow-up"></i> <%-lang['Update']%></p>
</a>
</li>
-->
</ul>
</div>
</div>
</nav>
<div id="logs" style="height:400px;overflow:auto">
<table class="table table-striped"></table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<% include blocks/confirm.ejs %>
<div id="toast" class="mdl-js-snackbar mdl-snackbar">
<div class="mdl-snackbar__text"></div>
<button class="mdl-snackbar__action" type="button"></button>
</div>
</body>
<script><% include ../libs/js/material.min.js %></script>
<script><% include ../libs/js/pnotify.custom.min.js %></script>
<% include blocks/confirm.ejs %>
<script src="<%-originalURL%>libs/js/pnotify.custom.min.js" type="text/javascript"></script>
<script><% include ../libs/js/moment.js %></script>
<script><% include ../libs/js/livestamp.min.js %></script>
<script><% include ../libs/js/placeholder.js %></script>
<script><% include ../libs/js/bootstrap.min.js %></script>
<script><% include ../libs/js/bootstrap-table.min.js %></script>
<script><% include ../libs/js/socket.io.js %></script>
<script src="<%-originalURL%>libs/js/livestamp.min.js" type="text/javascript"></script>
<script src="<%-originalURL%>libs/js/socket.io.js" type="text/javascript"></script>
<script src="<%-originalURL%>libs/js/placeholder.js" type="text/javascript"></script>
<script src="<%-originalURL%>libs/js/now-ui-kit.js?v=1.1.0" type="text/javascript"></script>
<script type="text/javascript">
PNotify.prototype.options.styling = "fontawesome";
$(document).ready(function() {
// the body of this function is in assets/js/now-ui-kit.js
$('#main-card').css('margin-top',$('#main-nav').height() * 2)
});
function scrollToDownload() {
if ($('.section-download').length != 0) {
$("html, body").animate({
scrollTop: $('.section-download').offset().top
}, 1000);
}
}
</script>
<script>$user=<%-JSON.stringify($user)%></script>
<script>
$.ccio={accounts:{}};$.ls=localStorage;
@ -117,7 +217,7 @@ $.ccio.ws.on('f',function(d){
$.ccio.tm(4,d.log,'#logs table')
break;
case'save_configuration':
$.conf.msg.html('Saved, Restart Shinobi to apply changes.')
d.msg = 'Saved, Restart Shinobi to apply changes.'
break;
case'edit_account':
d.msg='Account Edited';
@ -135,7 +235,7 @@ $.ccio.ws.on('f',function(d){
break;
}
if(d.msg&&typeof d.msg==='string'){
$('#toast')[0].MaterialSnackbar.showSnackbar({message:d.msg})
new PNotify({text:d.msg,type:'error'})
}
})
@ -146,12 +246,34 @@ $.ccio.tm=function(x,d,z,k){
case 0://account row
d.detailsJSON=JSON.parse(d.details);
$.ccio.accounts[d.ke]=d;
tmp+='<tr ke="'+d.ke+'"><td><b class="mail">'+d.mail+'</b></td><td>'+d.ke+'</td><td><a class="permission btn btn-xs btn-primary"><i class="fa fa-lock"></i></a></td><td><a class="delete btn btn-xs btn-danger"><i class="fa fa-trash-o"></i></a></td></tr>';
tmp+='<tr ke="'+d.ke+'"><td><b class="mail">'+d.mail+'</b></td><td>'+d.ke+'</td><td><a tabindex="1" class="permission btn btn-xs btn-primary"><i class="fa fa-lock"></i></a></td><td><a tabindex="1" class="delete btn btn-xs btn-danger"><i class="fa fa-trash-o"></i></a></td></tr>';
break;
case 4://log row, draw to global and monitor
if(!d.time){d.time=$.ccio.init('t')}
tmp+='<tr class="search-row"><td><span title="'+d.time+'" class="livestamp"></span><br><small>'+d.time+'</small><br><small>'+d.mid+'</small></td><td></td><td><pre class="pre-inline">'+$.ccio.init('jsontoblock',JSON.parse(d.info))+'</pre></td></tr>'
break;
case 5://config element
if(d.value instanceof Object){
tmp += '<div class="form-group config-row" layer="'+d.layer+'">\
<div><input class="form-control key" type="text" value="'+d.key+'"></div>\
<ul class="list-group valueObject" style="margin:0">'
++d.layer
$.each(d.value,function(key,value){
tmp += '<li class="list-group-item">'
tmp += $.ccio.tm(5,{key:key,value:value,layer:d.layer})
tmp += '</li>'
})
tmp += '</ul>'
tmp += '</div>'
}else{
tmp += '<div class="form-group config-row" layer="'+d.layer+'">\
<label>\
<div><input class="form-control key" type="text" value="'+d.key+'"></div>\
<div><input class="form-control value" type="text" value="'+d.value+'"></div>\
</label>\
</div>'
}
break;
}
if(z){
$(z).prepend(tmp)
@ -201,34 +323,40 @@ $.ccio.init=function(x,d,z,k){
}
//logs
$.logs={e:$('#logs')}
$.logs.e.find('.delete').click(function(e){
$.confirm.e.modal('show');
$.confirm.title.html('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:'Delete',class:'btn-danger'},function(){
$.ccio.cx({f:'logs',ff:'delete',ke:'$'})
$.logs.e.find('table').empty()
});
})
//config editor
$.conf={e:$('#conf_json')};$.conf.draw=$.conf.e.find('[name="json"]'),$.conf.msg=$.conf.e.find('.msg')
<%
var stringedConfig = JSON.stringify(plainConfig)
%>
var config = <%- JSON.stringify(plainConfig) || [] %>
$.conf={e:$('#conf_json')};
$.conf.configForHumans=$('#configForHumans')
$.conf.draw=$.conf.e.find('[name="json"]')
$.conf.msg=$.conf.e.find('.msg')
$.conf.valid=1;
$.conf.draw.val(JSON.stringify(<%-JSON.stringify(plainConfig)%>,null,3))
$.conf.jsonToFields = function(){
// var tmp = ''
// $.each(config,function(key,value){
// var layer = 0
// tmp += $.ccio.tm(5,{key:key,value:value,layer:layer})
// })
// $.conf.configForHumans.html(tmp)
}
$.conf.draw.val(JSON.stringify(<%-stringedConfig%>,null,3))
$.conf.draw.keyup(function(){
var msg=''
var color=''
try{
$.parseJSON($.conf.draw.val())
msg='Valid JSON'
color='success'
$.conf.valid=1
config = $.parseJSON($.conf.draw.val())
msg = 'Valid JSON'
color = 'success'
$.conf.valid = 1
$.conf.jsonToFields()
}catch(er){
msg='Not a valid JSON'
color='danger'
$.conf.valid=0
msg = 'Not a valid JSON'
color = 'danger'
$.conf.valid = 0
}
$.conf.msg.text(msg).css('color',color)
new PNotify({text:msg,type:color})
})
$.conf.e.submit(function(e){
e.preventDefault()
@ -242,22 +370,77 @@ $.conf.e.submit(function(e){
$.ccio.cx({f:'system',ff:'configure',data:$.parseJSON($.conf.draw.val())})
});
}else{
$.conf.msg.text('Invalid JSON Syntax, Cannot Save.')
new PNotify({text:'Invalid JSON Syntax, Cannot Save.',type:'error'})
}
return false;
})
$.conf.e.on('keyup','.config-row input',function(){
var newConfig = {}
var checkRow = function(v,object){
var _this = $(v)
var key = _this.find('.key:first').val()
var layer = parseInt(_this.attr('layer'))
var list = _this.find('ul').first()
var isObject = list.length > 0
if(isObject){
if(!object[key]){
if(isNaN(key) === true){
object[key] = {}
}else{
object[key] = []
}
}
list.find('.config-row[layer="'+(layer+1)+'"]').each(function(n,v){
checkRow(v,object[key])
})
}else{
var value = _this.find('.value').val()
switch(value){
case'true':
value = true
break;
case'false':
value = false
break;
default:
if(isNaN(value) === false){
value = parseFloat(value)
}
break;
}
object[key] = value
}
}
$.conf.configForHumans.children('.config-row').each(function(n,v){
checkRow(v,newConfig)
})
$.conf.draw.val(JSON.stringify(newConfig,null,3))
console.log(newConfig)
})
$.conf.e.ready(function(){
$.conf.jsonToFields()
})
//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('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:'Delete',class:'btn-danger'},function(){
$.ccio.cx({f:'logs',ff:'delete',ke:'$'})
$.logs.e.find('table').empty()
});
break;
case'update':
e.distro=$(this).attr('distro')
if(!e.distro){e.distro='master'}
$.confirm.e.modal('show')
$.confirm.title.html('Update Shinobi?')
$.confirm.body.html('Updating Shinobi means overwriting files. If you have modified any files yourself you should update Shinobi manually. The updater will download the latest '+e.distro+' from the <a href="https://github.com/ShinobiCCTV/Shinobi" target="_blank">Pro repository</a>.')
$.confirm.body.html('Updating Shinobi means overwriting files. If you have modified any files yourself you should update Shinobi manually.')
$.confirm.click({title:'Update',class:'btn-danger'},function(){
$.ccio.cx({f:'system',ff:'update',distro:e.distro})
$.ccio.cx({f:'system',ff:'update'})
});
break;
}
@ -298,3 +481,4 @@ $('body')
})
</script>
<% include blocks/mainpermissions.ejs %>
</html>