From 644c6e6b41b37f5fb378526be4395fc89eca1ce1 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Thu, 28 Oct 2021 11:48:08 -0400 Subject: [PATCH 1/8] Just return the error --- scripts/ZoneMinder/lib/ZoneMinder/Event.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/ZoneMinder/lib/ZoneMinder/Event.pm b/scripts/ZoneMinder/lib/ZoneMinder/Event.pm index cc5722679..b740481eb 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/Event.pm +++ b/scripts/ZoneMinder/lib/ZoneMinder/Event.pm @@ -720,7 +720,7 @@ sub CopyTo { } # end foreach file. } # end if ! moved - return $error if $error; + return $error; } # end sub CopyTo sub MoveTo { From dedd755e5c63413017319dca7885e8439d4a1604 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Thu, 28 Oct 2021 12:46:42 -0400 Subject: [PATCH 2/8] Handle auth to mysql problems more gracefully --- distros/ubuntu2004/zoneminder.postinst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/distros/ubuntu2004/zoneminder.postinst b/distros/ubuntu2004/zoneminder.postinst index 4be136a71..6f26bca24 100644 --- a/distros/ubuntu2004/zoneminder.postinst +++ b/distros/ubuntu2004/zoneminder.postinst @@ -5,6 +5,12 @@ set +e create_db () { echo "Checking for db" mysqladmin --defaults-file=/etc/mysql/debian.cnf -f reload + if [ $? -ne 0 ]; then + echo "Cannot talk to database. You will have to create the db manually with something like:"; + echo "cat /usr/share/zoneminder/db/zm_create.sql | mysql -u root"; + return; + fi + # test if database if already present... if ! $(echo quit | mysql --defaults-file=/etc/mysql/debian.cnf zm > /dev/null 2> /dev/null) ; then echo "Creating zm db" From e063f0715fd35ec43a8feed4ea88c592bb79f218 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Thu, 28 Oct 2021 13:00:41 -0400 Subject: [PATCH 3/8] reset starttime when changing events. Fixes super fast playback after switch to next event. Also, skip some unneeded calculations and logging. --- src/zm_eventstream.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/zm_eventstream.cpp b/src/zm_eventstream.cpp index 621970130..5e1ad605d 100644 --- a/src/zm_eventstream.cpp +++ b/src/zm_eventstream.cpp @@ -663,6 +663,7 @@ bool EventStream::checkEventLoaded() { else curr_frame_id = 1; Debug(2, "New frame id = %ld", curr_frame_id); + start = std::chrono::system_clock::now(); return true; } else { Debug(2, "No next event loaded using %s. Pausing", sql.c_str()); @@ -957,18 +958,20 @@ void EventStream::runStream() { static_cast(std::chrono::duration_cast(delta).count())); // if effective > base we should speed up frame delivery - delta = std::chrono::duration_cast((delta * base_fps) / effective_fps); - Debug(3, "delta %" PRIi64 " us = base_fps (%f) / effective_fps (%f)", + if (base_fps < effective_fps) { + delta = std::chrono::duration_cast((delta * base_fps) / effective_fps); + Debug(3, "delta %" PRIi64 " us = base_fps (%f) / effective_fps (%f)", static_cast(std::chrono::duration_cast(delta).count()), base_fps, effective_fps); - // but must not exceed maxfps - delta = std::max(delta, Microseconds(lround(Microseconds::period::den / maxfps))); - Debug(3, "delta %" PRIi64 " us = base_fps (%f) /effective_fps (%f) from 30fps", + // but must not exceed maxfps + delta = std::max(delta, Microseconds(lround(Microseconds::period::den / maxfps))); + Debug(3, "delta %" PRIi64 " us = base_fps (%f) / effective_fps (%f) from 30fps", static_cast(std::chrono::duration_cast(delta).count()), base_fps, effective_fps); + } // +/- 1? What if we are skipping frames? curr_frame_id += (replay_rate>0) ? frame_mod : -1*frame_mod; From b4314e5d46228cedd608e9048c001d4a24f67c31 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Thu, 28 Oct 2021 15:11:42 -0400 Subject: [PATCH 4/8] Remove debugging --- web/skins/classic/views/js/filter.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/web/skins/classic/views/js/filter.js b/web/skins/classic/views/js/filter.js index 35254baf8..5765a0e76 100644 --- a/web/skins/classic/views/js/filter.js +++ b/web/skins/classic/views/js/filter.js @@ -167,7 +167,6 @@ function submitToExport(element) { } function submitAction(button) { - console.log(button.value); var form = button.form; form.elements['action'].value = button.value; form.submit(); @@ -175,7 +174,6 @@ function submitAction(button) { function deleteFilter(element) { var form = element.form; - console.log(form); if (confirm(deleteSavedFilterString+" '"+form.elements['filter[Name]'].value+"'?")) { form.elements['action'].value = 'delete'; form.submit(); @@ -384,7 +382,6 @@ function debugFilter() { } function manageModalBtns(id) { - console.log(id); // Manage the CANCEL modal button var cancelBtn = document.getElementById(id+"CancelBtn"); if ( cancelBtn ) { From 4122ae99a5ecf552c9d4f3b0a5d96bed4cc53eb2 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Thu, 28 Oct 2021 12:03:58 -0400 Subject: [PATCH 5/8] add a comment about rollbacks --- scripts/ZoneMinder/lib/ZoneMinder/Event.pm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/ZoneMinder/lib/ZoneMinder/Event.pm b/scripts/ZoneMinder/lib/ZoneMinder/Event.pm index b740481eb..5f11b1ada 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/Event.pm +++ b/scripts/ZoneMinder/lib/ZoneMinder/Event.pm @@ -744,11 +744,11 @@ sub MoveTo { $$self{StorageId} = $$NewStorage{Id}; $self->Storage($NewStorage); $error .= $self->save(); - if ($error) { - $ZoneMinder::Database::dbh->commit() if !$was_in_transaction; - return $error; - } + + # Going to leave it to upper layout as to whether we rollback or not $ZoneMinder::Database::dbh->commit() if !$was_in_transaction; + return $error if $error; + $self->delete_files($OldStorage); return $error; } # end sub MoveTo From df88c5bbef9f58c7552abe5562cb32eaf16c315d Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Thu, 28 Oct 2021 15:26:12 -0400 Subject: [PATCH 6/8] layout->layer --- scripts/ZoneMinder/lib/ZoneMinder/Event.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/ZoneMinder/lib/ZoneMinder/Event.pm b/scripts/ZoneMinder/lib/ZoneMinder/Event.pm index 5f11b1ada..0276af097 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/Event.pm +++ b/scripts/ZoneMinder/lib/ZoneMinder/Event.pm @@ -745,7 +745,7 @@ sub MoveTo { $self->Storage($NewStorage); $error .= $self->save(); - # Going to leave it to upper layout as to whether we rollback or not + # Going to leave it to upper layer as to whether we rollback or not $ZoneMinder::Database::dbh->commit() if !$was_in_transaction; return $error if $error; From 1168fc52a5536f7d0d3c70ee58eac882a985398b Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Fri, 29 Oct 2021 18:53:23 -0400 Subject: [PATCH 7/8] spacing and check for permission to view the specific event instead of events in general --- web/skins/classic/views/frame.php | 124 +++++++++++++++--------------- 1 file changed, 62 insertions(+), 62 deletions(-) diff --git a/web/skins/classic/views/frame.php b/web/skins/classic/views/frame.php index bdd2e1071..9931c910a 100644 --- a/web/skins/classic/views/frame.php +++ b/web/skins/classic/views/frame.php @@ -18,30 +18,28 @@ // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // -if ( !canView('Events') ) { - $view = 'error'; - return; -} - require_once('includes/Frame.php'); $eid = validInt($_REQUEST['eid']); $fid = empty($_REQUEST['fid']) ? 0 : validInt($_REQUEST['fid']); $Event = new ZM\Event($eid); +if (!$Event->canView()) { + $view = 'error'; + return; +} $Monitor = $Event->Monitor(); # This is kinda weird.. so if we pass fid=0 or some other non-integer, then it loads max score # perhaps we should consider being explicit, like fid = maxscore -if ( !empty($fid) ) { - $sql = 'SELECT * FROM Frames WHERE EventId = ? AND FrameId = ?'; - if ( !($frame = dbFetchOne($sql, NULL, array($eid, $fid))) ) +if (!empty($fid)) { + $sql = 'SELECT * FROM Frames WHERE EventId=? AND FrameId=?'; + if (!($frame = dbFetchOne($sql, NULL, array($eid, $fid)))) $frame = array('EventId'=>$eid, 'FrameId'=>$fid, 'Type'=>'Normal', 'Score'=>0); } else { - $frame = dbFetchOne('SELECT * FROM Frames WHERE EventId = ? AND Score = ?', NULL, array($eid, $Event->MaxScore())); + $frame = dbFetchOne('SELECT * FROM Frames WHERE EventId=? AND Score=?', NULL, array($eid, $Event->MaxScore())); } $Frame = new ZM\Frame($frame); - $maxFid = $Event->Frames(); $firstFid = 1; @@ -51,11 +49,11 @@ $lastFid = $maxFid; $alarmFrame = ( $Frame->Type() == 'Alarm' ) ? 1 : 0; -if ( isset($_REQUEST['scale']) ) { +if (isset($_REQUEST['scale'])) { $scale = validNum($_REQUEST['scale']); -} else if ( isset($_COOKIE['zmWatchScale'.$Monitor->Id()]) ) { +} else if (isset($_COOKIE['zmWatchScale'.$Monitor->Id()])) { $scale = validNum($_COOKIE['zmWatchScale'.$Monitor->Id()]); -} else if ( isset($_COOKIE['zmWatchScale']) ) { +} else if (isset($_COOKIE['zmWatchScale'])) { $scale = validNum($_COOKIE['zmWatchScale']); } else { $scale = max(reScale(SCALE_BASE, $Monitor->DefaultScale(), ZM_WEB_DEFAULT_SCALE), SCALE_BASE); @@ -63,7 +61,7 @@ if ( isset($_REQUEST['scale']) ) { $scale = $scale ? $scale : 0; $imageData = $Event->getImageSrc($frame, $scale, 0); -if ( !$imageData ) { +if (!$imageData) { ZM\Error("No data found for Event $eid frame $fid"); $imageData = array(); } @@ -92,78 +90,80 @@ xhtmlHeaders(__FILE__, translate('Frame').' - '.$Event->Id().' - '.$Frame->Frame
- - - - + + + +

Id().'-'.$Frame->FrameId().' ('.$Frame->Score().')' ?>

-
'changeScale','id'=>'scale')); ?>
+
+ + 'changeScale','id'=>'scale')); ?> +
- From 224b34d69df71af704989fbd3cbd5dbacc970f24 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Fri, 29 Oct 2021 18:54:23 -0400 Subject: [PATCH 8/8] Send all stats rows instead of just 1. Handle receiving all rows, and don't list event id and frame id --- web/ajax/stats.php | 41 ++++++++---------- web/skins/classic/views/js/frame.js | 64 +++++++++++++++-------------- 2 files changed, 51 insertions(+), 54 deletions(-) diff --git a/web/ajax/stats.php b/web/ajax/stats.php index 06ce9d733..9226814b4 100644 --- a/web/ajax/stats.php +++ b/web/ajax/stats.php @@ -1,7 +1,6 @@ 1 ) { - $stat['BlobSizes'] = sprintf( "%d-%d (%d%%-%d%%)", $stat['MinBlobSize'], $stat['MaxBlobSize'], (100*$stat['MinBlobSize']/$stat['Area']), (100*$stat['MaxBlobSize']/$stat['Area']) ); + if ($stat['Blobs'] > 1) { + $stat['BlobSizes'] = sprintf('%d-%d (%d%%-%d%%)', $stat['MinBlobSize'], $stat['MaxBlobSize'], (100*$stat['MinBlobSize']/$stat['Area']), (100*$stat['MaxBlobSize']/$stat['Area'])); } else { - $stat['BlobSizes'] = sprintf( "%d (%d%%)", $stat['MinBlobSize'], 100*$stat['MinBlobSize']/$stat['Area'] ); + $stat['BlobSizes'] = sprintf('%d (%d%%)', $stat['MinBlobSize'], 100*$stat['MinBlobSize']/$stat['Area']); } - $stat['AlarmLimits'] = validHtmlStr($stat['MinX'].",".$stat['MinY']."-".$stat['MaxX'].",".$stat['MaxY']); - } - $data['raw'] = $stat; + $stat['AlarmLimits'] = validHtmlStr($stat['MinX'].','.$stat['MinY'].'-'.$stat['MaxX'].','.$stat['MaxY']); + $data['raw'][] = $stat; + } # end foreach stat/zone } else { $data['html'] = getStatsTableHTML($eid, $fid, $row); $data['id'] = '#contentStatsTable' .$row; diff --git a/web/skins/classic/views/js/frame.js b/web/skins/classic/views/js/frame.js index c10b6e87a..1040d5a48 100644 --- a/web/skins/classic/views/js/frame.js +++ b/web/skins/classic/views/js/frame.js @@ -12,10 +12,10 @@ function changeScale() { last: $j('#lastLink') }; - if ( img ) { + if (img) { var baseWidth = $j('#base_width').val(); var baseHeight = $j('#base_height').val(); - if ( ! parseInt(scale) ) { + if (!parseInt(scale)) { var newSize = scaleToFit(baseWidth, baseHeight, img, $j('#controls')); newWidth = newSize.width; newHeight = newSize.height; @@ -30,7 +30,7 @@ function changeScale() { } setCookie('zmWatchScale', scale, 3600); $j.each(controlsLinks, function(k, anchor) { //Make frames respect scale choices - if ( anchor ) { + if (anchor) { anchor.prop('href', anchor.prop('href').replace(/scale=.*&/, 'scale=' + scale + '&')); } }); @@ -39,11 +39,11 @@ function changeScale() { onStatsResize(newWidth); } -function getFrmStatsCookie() { +function getFrameStatsCookie() { var cookie = 'zmFrameStats'; var stats = getCookie(cookie); - if ( !stats ) { + if (!stats) { stats = 'on'; setCookie(cookie, stats, 10*365); } @@ -53,29 +53,33 @@ function getFrmStatsCookie() { function getStat(params) { $j.getJSON(thisUrl + '?view=request&request=stats&raw=true', params) .done(function(data) { - var stat = data.raw; + var stats = data.raw; + $j('#frameStatsTable').empty().append(''); - $j.each( statHeaderStrings, function( key ) { - var th = $j('').addClass('text-right').text(statHeaderStrings[key]); - var tdString; + for (const stat of stats) { + $j.each(statHeaderStrings, function(key) { + var th = $j('').addClass('text-right').text(statHeaderStrings[key]); + var tdString; - switch (stat ? key : 'n/a') { - case 'FrameId': - tdString = '' + stat[key] + ''; - break; - case 'n/a': - tdString = 'n/a'; - break; - default: - tdString = stat[key]; - } + switch (stat ? key : 'n/a') { + case 'FrameId': + case 'EventId': + //tdString = '' + stat[key] + ''; + break; + case 'n/a': + tdString = 'n/a'; + break; + default: + tdString = stat[key]; + } - var td = $j('').html(tdString); - var row = $j('').append(th, td); + var td = $j('').html(tdString); + var row = $j('').append(th, td); - $j('#frameStatsTable tbody').append(row); - }); + $j('#frameStatsTable tbody').append(row); + }); + } // end foreach stat }) .fail(logAjaxFail); } @@ -85,16 +89,16 @@ function onStatsResize(vidwidth) { var width = $j(window).width() - vidwidth; // Hide the stats table if we have run out of room to show it properly - if ( width < minWidth ) { + if (width < minWidth) { statsBtn.prop('disabled', true); - if ( table.is(':visible') ) { + if (table.is(':visible')) { table.toggle(false); wasHidden = true; } // Show the stats table if we hid it previously and sufficient room becomes available - } else if ( width >= minWidth ) { + } else if (width >= minWidth) { statsBtn.prop('disabled', false); - if ( !table.is(':visible') && wasHidden ) { + if (!table.is(':visible') && wasHidden) { table.toggle(true); wasHidden = false; } @@ -102,7 +106,7 @@ function onStatsResize(vidwidth) { } function initPage() { - if ( scale == '0' || scale == 'auto' ) changeScale(); + if (scale == '0' || scale == 'auto') changeScale(); // Don't enable the back button if there is no previous zm page to go back to backBtn.prop('disabled', !document.referrer.length); @@ -125,7 +129,7 @@ function initPage() { var cookie = 'zmFrameStats'; // Toggle the visiblity of the stats table and write an appropriate cookie - if ( table.is(':visible') ) { + if (table.is(':visible')) { setCookie(cookie, 'off', 10*365); table.toggle(false); } else { @@ -143,7 +147,7 @@ function initPage() { // Load the frame stats getStat({eid: eid, fid: fid}); - if ( getFrmStatsCookie() != 'on' ) { + if (getFrameStatsCookie() != 'on') { table.toggle(false); } else { onStatsResize($j('#base_width').val() * scale / SCALE_BASE);