diff --git a/web/ajax/event.php b/web/ajax/event.php index 906fe255a..a0b9cb57a 100644 --- a/web/ajax/event.php +++ b/web/ajax/event.php @@ -93,7 +93,7 @@ if ( canView('Events') or canView('Snapshots') ) { $exportFormat, $exportCompress, $exportStructure, - (!empty($_REQUEST['exportFile'])?$_REQUEST['exportFile']:'zmExport'), + (!empty($_REQUEST['exportFile'])?$_REQUEST['exportFile']:'zmExport') )) { ajaxResponse(array('exportFile'=>$exportFile)); } else { 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/includes/Event.php b/web/includes/Event.php index 328b06f66..e042849e9 100644 --- a/web/includes/Event.php +++ b/web/includes/Event.php @@ -650,6 +650,23 @@ class Event extends ZM_Object { } return false; } + function canEdit($u=null) { + global $user; + if (!$u) $u=$user; + if (!$u) { + # auth turned on and not logged in + return false; + } + if (!empty($u['MonitorIds']) ) { + if (!in_array($this->{'MonitorId'}, explode(',', $u['MonitorIds']))) { + return false; + } + } + if ($u['Events'] != 'Edit') { + return false; + } + return true; + } } # end class ?> diff --git a/web/includes/Monitor.php b/web/includes/Monitor.php index 027cafadd..788486b2e 100644 --- a/web/includes/Monitor.php +++ b/web/includes/Monitor.php @@ -495,6 +495,10 @@ class Monitor extends ZM_Object { return $this->Server()->UrlToIndex($port); } + public function UrlToZMS($port=null) { + return $this->Server()->UrlToZMS($port).'?mid='.$this->Id(); + } + public function sendControlCommand($command) { // command is generally a command option list like --command=blah but might be just the word quit diff --git a/web/includes/actions/monitor.php b/web/includes/actions/monitor.php index 1c6e1f72f..ee041967c 100644 --- a/web/includes/actions/monitor.php +++ b/web/includes/actions/monitor.php @@ -205,7 +205,7 @@ if ( $action == 'save' ) { } // end if changes in width or height } else { global $error_message; - $error_message = dbError(); + $error_message = dbError('unknown'); } // end if successful save $restart = true; } else { // new monitor diff --git a/web/includes/actions/settings.php b/web/includes/actions/settings.php index a4aa1b489..710bfa641 100644 --- a/web/includes/actions/settings.php +++ b/web/includes/actions/settings.php @@ -20,18 +20,18 @@ // Monitor control actions, require a monitor id and control view permissions for that monitor -if ( empty($_REQUEST['mid']) ) { +if (empty($_REQUEST['mid'])) { ZM\Warning('Settings requires a monitor id'); return; } -if ( ! canView('Control', $_REQUEST['mid']) ) { +if (!canView('Control', $_REQUEST['mid'])) { ZM\Warning('Settings requires the Control permission'); return; } require_once('includes/Monitor.php'); $mid = validInt($_REQUEST['mid']); -if ( $action == 'settings' ) { +if ($action == 'settings') { $args = ' -m ' . escapeshellarg($mid); $args .= ' -B' . escapeshellarg($_REQUEST['newBrightness']); $args .= ' -C' . escapeshellarg($_REQUEST['newContrast']); @@ -45,5 +45,7 @@ if ( $action == 'settings' ) { dbQuery( 'UPDATE Monitors SET Brightness = ?, Contrast = ?, Hue = ?, Colour = ? WHERE Id = ?', array($brightness, $contrast, $hue, $colour, $mid)); + global $redirect; + $redirect = '?view=watch&mid='.$mid; } ?> diff --git a/web/skins/classic/views/event.php b/web/skins/classic/views/event.php index 81d4e97be..e352f305b 100644 --- a/web/skins/classic/views/event.php +++ b/web/skins/classic/views/event.php @@ -150,6 +150,7 @@ if ( $Event->Id() and !file_exists($Event->Path()) ) DefaultVideo() ? '' : 'style="display:none;"' ?> > 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')); ?> +
-
- - - - -
- -
-

-', $Event->Id(), $Frame->FrameId(), $scale, ( $show=='anal'?'capt':'anal' ) ); -} ?> +

diff --git a/web/skins/classic/views/js/event.js b/web/skins/classic/views/js/event.js index 050a78d59..05914f911 100644 --- a/web/skins/classic/views/js/event.js +++ b/web/skins/classic/views/js/event.js @@ -34,7 +34,7 @@ function streamReq(data) { data.view = 'request'; data.request = 'stream'; - $j.getJSON(thisUrl, data) + $j.getJSON(monitorUrl, data) .done(getCmdResponse) .fail(logAjaxFail); } @@ -300,7 +300,7 @@ function getCmdResponse(respObj, respText) { if (streamStatus.auth) { // Try to reload the image stream. - var streamImg = $j('#evtStream'); + var streamImg = document.getElementById('evtStream'); if (streamImg) { streamImg.src = streamImg.src.replace(/auth=\w+/i, 'auth='+streamStatus.auth); } @@ -657,6 +657,7 @@ function getFrameResponse(respObj, respText) { function frameQuery(eventId, frameId, loadImage) { var data = {}; + if (auth_hash) data.auth = auth_hash; data.loopback = loadImage; data.id = {eventId, frameId}; 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); diff --git a/web/skins/classic/views/js/video.js b/web/skins/classic/views/js/video.js index 970119f4f..c764f33b5 100644 --- a/web/skins/classic/views/js/video.js +++ b/web/skins/classic/views/js/video.js @@ -16,6 +16,9 @@ function generateVideoResponse( data, responseText ) { } function generateVideo() { + $j.ajaxSetup({ + timeout: 0 + }); var form = $j('#videoForm').serialize(); $j.getJSON(thisUrl + '?view=request&request=event&action=video', form) .done(generateVideoResponse) diff --git a/web/skins/classic/views/options.php b/web/skins/classic/views/options.php index 22b164202..25cad40cc 100644 --- a/web/skins/classic/views/options.php +++ b/web/skins/classic/views/options.php @@ -44,8 +44,9 @@ $tabs['medband'] = translate('MediumBW'); $tabs['lowband'] = translate('LowBW'); $tabs['users'] = translate('Users'); $tabs['control'] = translate('Control'); +$tabs['privacy'] = translate('Privacy'); -if ( isset($_REQUEST['tab']) ) +if (isset($_REQUEST['tab'])) $tab = validHtmlStr($_REQUEST['tab']); else $tab = 'system'; @@ -53,7 +54,6 @@ else $focusWindow = true; xhtmlHeaders(__FILE__, translate('Options')); - ?> @@ -62,7 +62,7 @@ xhtmlHeaders(__FILE__, translate('Options'));