Merge branch 'dev' into 'master'

Helios 685

See merge request Shinobi-Systems/Shinobi!472
node-20
Moe 2023-07-02 21:02:07 +00:00
commit 9844de231d
17 changed files with 165 additions and 58 deletions

View File

@ -4822,8 +4822,6 @@ module.exports = function(s,config,lang){
"name": "detail=audio_note",
"field": lang["Notification Sound"],
"description": lang["fieldTextAudioNote"],
"default": "",
"example": "",
"fieldType": "select",
"possible": s.listOfAudioFiles
},
@ -4831,8 +4829,6 @@ module.exports = function(s,config,lang){
"name": "detail=audio_alert",
"field": lang["Alert Sound"],
"description": lang["fieldTextAudioAlert"],
"default": "",
"example": "",
"fieldType": "select",
"possible": s.listOfAudioFiles
},
@ -4841,15 +4837,12 @@ module.exports = function(s,config,lang){
"field": lang["Alert Sound Delay"],
"description": lang["fieldTextAudioDelay"],
"default": "1",
"example": "",
"possible": ""
},
{
"name": "detail=event_mon_pop",
"field": lang["Popout Monitor on Event"],
"description": lang["fieldTextEventMonPop"],
"default": "en_CA",
"example": "",
"fieldType": "select",
"possible": [
{
@ -7449,6 +7442,7 @@ module.exports = function(s,config,lang){
streamBlockHudControlsHtml: `<span title="${lang['Currently viewing']}" class="label label-default">
<span class="viewers"></span>
</span>
<a class="btn btn-sm badge btn-primary run-monitor-detection-trigger-marker">${lang['Add Marker']}</a>
<a class="btn btn-sm badge btn-warning run-monitor-detection-trigger-test">${lang['Test Object Event']}</a>
<a class="btn btn-sm badge btn-warning run-monitor-detection-trigger-test-motion">${lang['Test Motion Event']}</a>
`,
@ -7689,6 +7683,18 @@ module.exports = function(s,config,lang){
attributes: 'shinobi-switch="dontShowDetection" ui-change-target=".dot" on-class="dot-green" off-class="dot-grey"',
color: 'grey',
},
{
label: lang[`Alert on Event`],
class: 'cursor-pointer',
attributes: 'shinobi-switch="alertOnEvent" ui-change-target=".dot" on-class="dot-green" off-class="dot-grey"',
color: 'grey',
},
{
label: lang[`Popout on Event`],
class: 'cursor-pointer',
attributes: 'shinobi-switch="popOnEvent" ui-change-target=".dot" on-class="dot-green" off-class="dot-grey"',
color: 'grey',
},
]
},
{

View File

@ -748,6 +748,9 @@
"Rotate": "Rotate",
"Trigger Event": "Trigger Event",
"Test": "Test",
"Popout on Event": "Popout on Event",
"Alert on Event": "Alert on Event",
"Add Marker": "Add Marker",
"Test Object Event": "Test Object Event",
"Test Motion Event": "Test Motion Event",
"Primary Engine": "Primary Engine",

View File

@ -207,28 +207,28 @@ module.exports = function(s,config){
}
return url
}
s.file = function(x,e,callback){
s.file = async function(x,e,callback){
if(!e){e={}};
switch(x){
case'size':
return fs.statSync(e.filename)["size"];
break;
case'delete':
if(!e){return false;}
fs.rm(e,(err)=>{
if(err){
s.debugLog(err)
if(s.isWin){
exec('rd /s /q "' + e + '"',{detached: true},function(err){
if(callback)callback(err)
})
}else{
exec('rm -rf '+e,{detached: true},function(err){
if(callback)callback(err)
})
}
if (!e) { return false; }
try{
return await fs.promises.rm(e, { force: true })
}catch(err){
s.debugLog(err)
if(s.isWin){
exec('rd /s /q "' + e + '"', { detached: true }, function (err) {
if (callback) callback(err)
})
}else{
exec('rm -rf ' + e, { detached: true }, function (err) {
if (callback) callback(err)
})
}
})
}
break;
case'deleteFolder':
if(!e){return false;}

View File

@ -38,7 +38,7 @@ module.exports = (s,config,lang) => {
async function saveImageFromEvent(options,frameBuffer){
const monitorId = options.mid || options.id
const groupKey = options.ke
if(imageSaveEventLock[groupKey + monitorId])return;
if(!frameBuffer || imageSaveEventLock[groupKey + monitorId])return;
const eventTime = options.time
const objectsFound = options.matrices
const monitorConfig = Object.assign({id: monitorId},s.group[groupKey].rawMonitorConfigurations[monitorId])

View File

@ -748,6 +748,8 @@ module.exports = (s,config,lang) => {
})
}
function monitorIdle(e){
const monitorId = e.mid || e.id
const groupKey = e.ke
s.tx({f:'monitor_idle',mid:monitorId,ke:groupKey,time:s.formattedTime()},'GRP_'+groupKey);
s.userLog(e,{type:lang['Monitor Idling'],msg:lang.MonitorIdlingText});
s.sendMonitorStatus({

View File

@ -163,11 +163,11 @@ module.exports = function(s,config,lang,app,io){
limit: 1
},async function(){
s.setDiskUsedForGroup(e.ke,-(r.size / 1048576),'timelapseFrames')
s.file('delete',e.fileLocation)
const fileDirectory = getFileDirectory(folderPath);
const folderIsEmpty = (await fs.promises.readdir(folderPath)).filter(file => file.indexOf('.jpg') > -1).length === 0;
await s.file('delete', e.fileLocation);
const fileDirectory = getFileDirectory(e.fileLocation);
const folderIsEmpty = (await fs.promises.readdir(fileDirectory)).filter(file => file.indexOf('.jpg') > -1).length === 0;
if(folderIsEmpty){
await fs.rm(folderPath, { recursive: true })
await fs.rm(fileDirectory, { recursive: true })
}
})
}else{

14
package-lock.json generated
View File

@ -31,7 +31,7 @@
"ldapauth-fork": "^5.0.2",
"marked": "^4.3.0",
"moment": "^2.29.4",
"mp4frag": "^0.6.0",
"mp4frag": "^0.6.1",
"mqtt": "^4.3.7",
"mysql": "^2.18.1",
"mysql2": "^2.1.0",
@ -5037,9 +5037,9 @@
}
},
"node_modules/mp4frag": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/mp4frag/-/mp4frag-0.6.0.tgz",
"integrity": "sha512-MvBAaWkW94SSpam/QsCmbMi7+ZY2YHzAjj6Uno7AZ6qxH7gZstN+L3jFopdN5F3/5mRK25gvA4k0DVpCbDe7+g==",
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/mp4frag/-/mp4frag-0.6.1.tgz",
"integrity": "sha512-x2xVwVZqT+P1dmGLpBStS6Op6oownx2Q/6qh5ov3hOIH4rTNab0p6Gi/l+EliG0FKW9R6jA2eGr0vnHvJVMT9w==",
"engines": {
"node": ">=10"
}
@ -11781,9 +11781,9 @@
"integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w=="
},
"mp4frag": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/mp4frag/-/mp4frag-0.6.0.tgz",
"integrity": "sha512-MvBAaWkW94SSpam/QsCmbMi7+ZY2YHzAjj6Uno7AZ6qxH7gZstN+L3jFopdN5F3/5mRK25gvA4k0DVpCbDe7+g=="
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/mp4frag/-/mp4frag-0.6.1.tgz",
"integrity": "sha512-x2xVwVZqT+P1dmGLpBStS6Op6oownx2Q/6qh5ov3hOIH4rTNab0p6Gi/l+EliG0FKW9R6jA2eGr0vnHvJVMT9w=="
},
"mqtt": {
"version": "4.3.7",

View File

@ -37,7 +37,7 @@
"ldapauth-fork": "^5.0.2",
"marked": "^4.3.0",
"moment": "^2.29.4",
"mp4frag": "^0.6.0",
"mp4frag": "^0.6.1",
"mqtt": "^4.3.7",
"mysql": "^2.18.1",
"mysql2": "^2.1.0",

View File

@ -1017,6 +1017,10 @@ function onDashboardReadyExecute(theAction){
function popImage(imageSrc){
$('body').append(`<div class="popped-image"><img src="${imageSrc}"></div>`)
}
function setSubmitButton(editorForm,text,icon,toggle){
var submitButtons = editorForm.find('[type="submit"]').prop('disabled',toggle)
submitButtons.html(`<i class="fa fa-${icon}"></i> ${text}`)
}
$(document).ready(function(){
onInitWebsocket(function(){
loadMonitorsIntoMemory(function(data){

View File

@ -963,6 +963,30 @@ function openAllLiveGridPlayers(){
openLiveGrid()
})
}
function addMarkAsEvent(monitorId){
runTestDetectionTrigger(monitorId,{
"name":"Marker",
"reason":"marker",
"matrices": [
{
x: 0,
y: 0,
width: 1,
height: 1,
tag: 'Marked',
confidence: 100,
}
]
});
}
function addMarkAsEventToAllOpenMonitors(){
$.each(loadedMonitors,function(n,monitor){
var monitorId = monitor.mid
if(liveGridPlayingNow[monitorId]){
addMarkAsEvent(monitorId)
}
})
}
$(document).ready(function(e){
liveGrid
.on('dblclick','.stream-block',function(){
@ -976,15 +1000,14 @@ $(document).ready(function(e){
.on('click','.launch-live-grid-monitor',function(){
var monitorId = $(this).parents('[data-mid]').attr('data-mid')
if(isMobile){
createLivePlayerTab(loadedMonitors[monitorId])
}else{
mainSocket.f({
f: 'monitor',
ff: 'watch_on',
id: monitorId
})
openLiveGrid()
closeAllLiveGridPlayers()
}
mainSocket.f({
f: 'monitor',
ff: 'watch_on',
id: monitorId
})
openLiveGrid()
})
.on('click','.monitor-live-group-open',function(){
var monitorIds = $(this).attr('monitor-ids').split(',')
@ -1086,6 +1109,11 @@ $(document).ready(function(e){
var monitorId = el.parents('[data-mid]').attr('data-mid')
runTestDetectionTrigger(monitorId)
})
.on('click','.run-monitor-detection-trigger-marker',function(){
var el = $(this)
var monitorId = el.parents('[data-mid]').attr('data-mid')
addMarkAsEvent(monitorId)
})
.on('click','.run-monitor-detection-trigger-test-motion',function(){
var el = $(this)
var monitorId = el.parents('[data-mid]').attr('data-mid')
@ -1244,7 +1272,7 @@ $(document).ready(function(e){
}
playAudioAlert()
var monitorPop = monitorPops[monitorId]
if($user.details.event_mon_pop === '1' && (!monitorPop || monitorPop.closed === true)){
if(window.popLiveOnEvent && (!monitorPop || monitorPop.closed === true)){
popOutMonitor(monitorId)
}
// console.log({
@ -1292,12 +1320,28 @@ $(document).ready(function(e){
window.dontShowDetection = true
}
}
dashboardSwitchCallbacks.alertOnEvent = function(toggleState){
// audio_alert
if(toggleState !== 1){
window.audioAlertOnEvent = false
}else{
window.audioAlertOnEvent = true
}
}
dashboardSwitchCallbacks.popOnEvent = function(toggleState){
if($user.details.event_mon_pop === '1'){
window.popLiveOnEvent = true
}else if(toggleState !== 1){
window.popLiveOnEvent = false
}else{
window.popLiveOnEvent = true
}
}
dashboardSwitchCallbacks.monitorMuteAudio = function(toggleState){
var monitorMutes = dashboardOptions().monitorMutes || {}
$('.monitor_item video').each(function(n,vidEl){
var el = $(this)
var monitorId = el.parents('[data-mid]').attr('data-mid')
console.log(monitorId,monitorMutes[monitorId])
if(toggleState === 1){
vidEl.muted = true
}else{

View File

@ -0,0 +1,41 @@
function keyShortcutsForLiveGridUtils(enable) {
function cleanup(){
document.removeEventListener('keydown', keyShortcuts['liveGridUtils'].keydown);
document.removeEventListener('keyup', keyShortcuts['liveGridUtils'].keyup);
delete(keyShortcuts['liveGridUtils'])
}
if(enable){
let isKeyPressed = false;
function handleKeyboard(event){
if (isKeyPressed) {
return;
}
event.preventDefault();
switch(event.code){
case 'Enter':
addMarkAsEventToAllOpenMonitors()
break;
}
}
function handleKeyup(event) {
isKeyPressed = false;
}
keyShortcuts['liveGridUtils'] = {
keydown: handleKeyboard,
keyup: handleKeyup,
}
document.addEventListener('keydown', keyShortcuts['liveGridUtils'].keydown);
document.addEventListener('keyup', keyShortcuts['liveGridUtils'].keyup);
}else{
cleanup()
}
}
addOnTabOpen('liveGrid', function () {
keyShortcutsForLiveGridUtils(true)
})
addOnTabReopen('liveGrid', function () {
keyShortcutsForLiveGridUtils(true)
})
addOnTabAway('liveGrid', function () {
keyShortcutsForLiveGridUtils(false)
})

View File

@ -758,10 +758,6 @@ monitorEditorWindow.on('change','[detail="auto_host"]',function(e){
}
})
editorForm.submit(function(e){
function setSubmitButton(text,icon,toggle){
var submitButtons = editorForm.find('[type="submit"]').prop('disabled',toggle)
submitButtons.html(`<i class="fa fa-${icon}"></i> ${text}`)
}
e.preventDefault();
var validation = getMonitorEditFormFields()
if(!validation.ok){
@ -770,7 +766,7 @@ editorForm.submit(function(e){
new PNotify({title:'Configuration Invalid',text:errorsFound.join('<br>'),type:'error'});
}
var monitorConfig = validation.monitorConfig
setSubmitButton(lang[`Please Wait...`], `spinner fa-pulse`, true)
setSubmitButton(editorForm, lang[`Please Wait...`], `spinner fa-pulse`, true)
$.post(getApiPrefix()+'/configureMonitor/'+$user.ke+'/'+monitorConfig.mid,{data:JSON.stringify(monitorConfig)},function(d){
if(d.ok === false){
new PNotify({
@ -780,7 +776,7 @@ editorForm.submit(function(e){
})
}
debugLog(d)
setSubmitButton(lang.Save, `check`, false)
setSubmitButton(editorForm, lang.Save, `check`, false)
})
//
if(copySettingsSelector.val() === '1'){

View File

@ -143,13 +143,14 @@ $(document).ready(function(){
var drawMonitor = function(preloadedData){
var MonitorSettings = definitions['Monitor Settings']
var html = ''
var monitorId = preloadedData ? preloadedData.mid : ''
Object.keys(MonitorSettings.blocks).forEach(function(blockKey){
var block = MonitorSettings.blocks[blockKey]
html += drawBlock(block,preloadedData)
})
var monitorSelect = `<select class="form-select state-monitor-row-select mb-2">`
$.each(loadedMonitors,function(n,monitor){
monitorSelect += `<option value="${monitor.mid}">${monitor.name} (${monitor.mid})</option>`
monitorSelect += `<option ${monitorId === monitor.mid ? 'selected' : ''} value="${monitor.mid}">${monitor.name} (${monitor.mid})</option>`
})
monitorSelect += `</select>`
var fullHtml = `<div class="form-group state-monitor-row">

View File

@ -230,6 +230,9 @@ function toggleSubStream(monitorId,callback){
}
function playAudioAlert(){
var fileName = $user.details.audio_alert
if(window.audioAlertOnEvent && !fileName){
fileName = `alert.mp3`
}
if(fileName && window.soundAlarmed !== true){
window.soundAlarmed = true
var audio = new Audio(`libs/audio/${fileName}`)

View File

@ -113,13 +113,19 @@ $(document).ready(function(e){
});
monitorConfig.details.cords = JSON.stringify(regionCoordinates)
monitorConfig.details = JSON.stringify(monitorConfig.details)
setSubmitButton(regionEditorForm, lang[`Please Wait...`], `spinner fa-pulse`, true)
$.post(getApiPrefix(`configureMonitor`)+ '/' + monitorId,{
data: JSON.stringify(monitorConfig)
},function(d){
debugLog(d)
if(d.ok){
if(d.ok === false){
new PNotify({
title: lang['Action Failed'],
text: d.msg,
type: 'danger'
})
}
debugLog(d)
setSubmitButton(regionEditorForm, lang.Save, `check`, false)
})
}
var initiateRegionList = function(presetVal){
@ -142,7 +148,7 @@ $(document).ready(function(e){
}
function setGridDisplayBasedOnFields(){
var isOn = accuracyModeToggle.val() === '1'
var tileSize = tileSizeField.val()
var tileSize = tileSizeField.val() || 20
displayGridOverCanvas(isOn,tileSize)
}
function initLiveStream(monitorId){

View File

@ -125,11 +125,11 @@ function getFrameOnVideoRow(percentageInward, video) {
};
}
var closestFrame = frames.reduce(function(prev, curr) {
var closestFrame = frames.length > 0 ? frames.reduce(function(prev, curr) {
var prevDiff = Math.abs(timeAdded - new Date(prev.time));
var currDiff = Math.abs(timeAdded - new Date(curr.time));
return (prevDiff < currDiff) ? prev : curr;
});
}) : null;
return {
timeInward: timeInward,

View File

@ -33,6 +33,7 @@
<script src="<%-window.libURL%>assets/js/bs5.schedules.js"></script>
<script src="<%-window.libURL%>assets/js/bs5.liveGrid.js"></script>
<script src="<%-window.libURL%>assets/js/bs5.liveGrid.cycle.js"></script>
<script src="<%-window.libURL%>assets/js/bs5.liveGrid.keyboard.js"></script>
<script src="<%-window.libURL%>assets/js/bs5.regionEditor.js"></script>
<script src="<%-window.libURL%>assets/js/bs5.timelapseViewer.js"></script>
<script src="<%-window.libURL%>assets/js/bs5.eventFilters.js"></script>