From a2e06ed70c591e5c9d38c4ce0e52c180d9444741 Mon Sep 17 00:00:00 2001 From: Andy Bauer Date: Sun, 21 Feb 2016 17:55:04 -0600 Subject: [PATCH 01/20] Prevent zmtrigger from crashing when memory handles change --- scripts/zmtrigger.pl.in | 92 ++++++++++++++++++++++------------------- 1 file changed, 49 insertions(+), 43 deletions(-) diff --git a/scripts/zmtrigger.pl.in b/scripts/zmtrigger.pl.in index 222e42f79..6111828ba 100644 --- a/scripts/zmtrigger.pl.in +++ b/scripts/zmtrigger.pl.in @@ -197,6 +197,7 @@ my %spawned_connections; my %monitors; my $monitor_reload_time = 0; +my $needsReload = 0; $! = undef; my $rin = ''; @@ -217,7 +218,7 @@ while( 1 ) if ( $nfound > 0 ) { Debug( "Got input from $nfound connections\n" ); - foreach my $connection ( @in_select_connections ) + foreach my $connection ( @in_select_connections ) { { if ( vec( $rout, $connection->fileno(), 1 ) ) { @@ -310,52 +311,56 @@ while( 1 ) # Check for alarms that might have happened my @out_messages; - foreach my $monitor ( values(%monitors) ) - { - my ( $state, $last_event ) - = zmMemRead( $monitor, - [ "shared_data:state", - "shared_data:last_event" - ] - ); + foreach my $monitor ( values(%monitors) ) { - #print( "$monitor->{Id}: S:$state, LE:$last_event\n" ); - #print( "$monitor->{Id}: mS:$monitor->{LastState}, mLE:$monitor->{LastEvent}\n" ); - if ( $state == STATE_ALARM - || $state == STATE_ALERT - ) # In alarm state - { - if ( !defined($monitor->{LastEvent}) - || ($last_event != $monitor->{LastEvent}) - ) # A new event - { + my $memVerified = 1; + if ( !zmMemRead($monitor, "shared_data:valid") ) { + zmMemInvalidate($monitor); + $memVerified = zmMemVerify($monitor); + } + + if ($memVerified) { + my ( $state, $last_event ) + = zmMemRead( $monitor, + [ "shared_data:state", + "shared_data:last_event" + ] + ); + + #print( "$monitor->{Id}: S:$state, LE:$last_event\n" ); + #print( "$monitor->{Id}: mS:$monitor->{LastState}, mLE:$monitor->{LastEvent}\n" ); + if ( $state == STATE_ALARM + || $state == STATE_ALERT + ) { # In alarm state + if ( !defined($monitor->{LastEvent}) + || ($last_event != $monitor->{LastEvent}) + ) { # A new event + push( @out_messages, $monitor->{Id}."|on|".time()."|".$last_event ); + } else { # The same one as last time, so ignore it + # Do nothing + } + } elsif ( ($state == STATE_IDLE + && $monitor->{LastState} != STATE_IDLE + ) + || ($state == STATE_TAPE + && $monitor->{LastState} != STATE_TAPE + ) + ) { # Out of alarm state + push( @out_messages, $monitor->{Id}."|off|".time()."|".$last_event ); + } + elsif ( defined($monitor->{LastEvent}) + && ($last_event != $monitor->{LastEvent}) + ) { # We've missed a whole event push( @out_messages, $monitor->{Id}."|on|".time()."|".$last_event ); + push( @out_messages, $monitor->{Id}."|off|".time()."|".$last_event ); } - else # The same one as last time, so ignore it - { - # Do nothing - } + $monitor->{LastState} = $state; + $monitor->{LastEvent} = $last_event; + } else { # Our attempt to verify the memory handle failed. We should reload the monitors. + $needsReload = 1; } - elsif ( ($state == STATE_IDLE - && $monitor->{LastState} != STATE_IDLE - ) - || ($state == STATE_TAPE - && $monitor->{LastState} != STATE_TAPE - ) - ) # Out of alarm state - { - push( @out_messages, $monitor->{Id}."|off|".time()."|".$last_event ); - } - elsif ( defined($monitor->{LastEvent}) - && ($last_event != $monitor->{LastEvent}) - ) # We've missed a whole event - { - push( @out_messages, $monitor->{Id}."|on|".time()."|".$last_event ); - push( @out_messages, $monitor->{Id}."|off|".time()."|".$last_event ); - } - $monitor->{LastState} = $state; - $monitor->{LastEvent} = $last_event; } + foreach my $connection ( @out_connections ) { if ( $connection->canWrite() ) @@ -412,7 +417,7 @@ while( 1 ) } # If necessary reload monitors - if ( (time() - $monitor_reload_time) > MONITOR_RELOAD_INTERVAL ) + if ( $needsReload || ((time() - $monitor_reload_time) > MONITOR_RELOAD_INTERVAL )) { foreach my $monitor ( values(%monitors) ) { @@ -420,6 +425,7 @@ while( 1 ) zmMemInvalidate( $monitor ); } loadMonitors(); + $needsReload = 0; } } Info( "Trigger daemon exiting\n" ); From 0fce33b2d352debadfef6564941e7707b65c4fa4 Mon Sep 17 00:00:00 2001 From: Andrew Bauer Date: Mon, 22 Feb 2016 06:59:14 -0600 Subject: [PATCH 02/20] one too many curly brackets --- scripts/zmtrigger.pl.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/zmtrigger.pl.in b/scripts/zmtrigger.pl.in index 6111828ba..d7ef79f68 100644 --- a/scripts/zmtrigger.pl.in +++ b/scripts/zmtrigger.pl.in @@ -219,7 +219,7 @@ while( 1 ) { Debug( "Got input from $nfound connections\n" ); foreach my $connection ( @in_select_connections ) { - { + if ( vec( $rout, $connection->fileno(), 1 ) ) { Debug( "Got input from connection " From 90dd078c22e70649780837756b7af9d98d8aa11c Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Mon, 22 Feb 2016 09:14:57 -0500 Subject: [PATCH 03/20] bump release --- distros/ubuntu1410/changelog | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/distros/ubuntu1410/changelog b/distros/ubuntu1410/changelog index f155ab9ef..3b9850047 100644 --- a/distros/ubuntu1410/changelog +++ b/distros/ubuntu1410/changelog @@ -1,3 +1,9 @@ +zoneminder (1.30.2-trusty-2016021901) trusty; urgency=medium + + * zmtrigger improvements + + -- Isaac Connor Fri, 19 Feb 2016 11:09:57 -0500 + zoneminder (1.30.2-trusty-2016021701) trusty; urgency=medium * printout id, and ip address when failing to connect From 7f34a0df37b790153486f2244726c95e9d31fb82 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 29 Mar 2016 11:48:30 -0400 Subject: [PATCH 04/20] Remove deprecated --enable-crashtrace --- distros/ubuntu1410/rules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/distros/ubuntu1410/rules b/distros/ubuntu1410/rules index 37fe00538..49d3549f1 100755 --- a/distros/ubuntu1410/rules +++ b/distros/ubuntu1410/rules @@ -53,7 +53,7 @@ override_dh_auto_configure: --with-mariadb=/usr --with-webdir=/usr/share/zoneminder \ --with-ffmpeg=/usr --with-cgidir=/usr/lib/cgi-bin \ --with-webuser=www-data --with-webgroup=www-data \ - --enable-crashtrace=no --enable-mmap=yes $(DEBOPT) + --enable-mmap=yes $(DEBOPT) override_dh_clean: # Add here commands to clean up after the build process. From 655116eea902fe58e589dfed6c3b3b92f1c16440 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 29 Mar 2016 11:49:15 -0400 Subject: [PATCH 05/20] add LinkPath and delete methods --- web/includes/Event.php | 44 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/web/includes/Event.php b/web/includes/Event.php index cd4f831d8..170cf8cf0 100644 --- a/web/includes/Event.php +++ b/web/includes/Event.php @@ -66,7 +66,49 @@ class Event { } -} + public function LinkPath() { + if ( ZM_USE_DEEP_STORAGE ) { + return $this->{'MonitorId'} .'/'.strftime( "%y/%m/%d/.", $this->{'Time'}).$this->{'Id'}; + } + Error("Calling Link_Path when not using deep storage"); + return ''; + } + public function delete() { + dbQuery( 'DELETE FROM Events WHERE Id = ?', array($this->{'Id'}) ); + if ( !ZM_OPT_FAST_DELETE ) { + dbQuery( 'DELETE FROM Stats WHERE EventId = ?', array($this->{'Id'}) ); + dbQuery( 'DELETE FROM Frames WHERE EventId = ?', array($this->{'Id'}) ); + if ( ZM_USE_DEEP_STORAGE ) { + # Assumption: All events haev a start time + $start_date = date_parse( $this->{'StartTime'} ); + $start_date['year'] = $start_date['year'] % 100; + + $Storage = $this->Storage(); + # So this is because ZM creates a link under teh day pointing to the time that the event happened. + $eventlink_path = $Storage->Path().'/'.$this->Link_Path(); + + if ( $id_files = glob( $eventlink_path ) ) { + # I know we are using arrays here, but really there can only ever be 1 in the array + $eventPath = preg_replace( '/\.'.$event['Id'].'$/', readlink($id_files[0]), $id_files[0] ); + deletePath( $eventPath ); + deletePath( $id_files[0] ); + $pathParts = explode( '/', $eventPath ); + for ( $i = count($pathParts)-1; $i >= 2; $i-- ) { + $deletePath = join( '/', array_slice( $pathParts, 0, $i ) ); + if ( !glob( $deletePath."/*" ) ) { + deletePath( $deletePath ); + } + } + } else { + Warning( "Found no event files under $eventlink_path" ); + } # end if found files + } else { + $eventPath = $this->Path(); + deletePath( $eventPath ); + } # USE_DEEP_STORAGE OR NOT + } # ! ZM_OPT_FAST_DELETE + } # end Event->delete +} # end class ?> From 3cb76877899e7d1ea69d5d4d06e47b8cf7f22460 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 29 Mar 2016 11:50:25 -0400 Subject: [PATCH 06/20] add zmtelemetry.pl to autotools build --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index d17ce6e9b..5f937799d 100644 --- a/configure.ac +++ b/configure.ac @@ -497,7 +497,7 @@ fi AC_SUBST(PERL_MM_PARMS) AC_SUBST(EXTRA_PERL_LIB) -AC_CONFIG_FILES([Makefile zm.conf zmconfgen.pl db/Makefile db/zm_create.sql misc/Makefile misc/apache.conf misc/logrotate.conf misc/syslog.conf misc/com.zoneminder.systemctl.policy misc/com.zoneminder.systemctl.rules onvif/Makefile onvif/scripts/Makefile scripts/Makefile scripts/zm scripts/zmaudit.pl scripts/zmcontrol.pl scripts/zmdc.pl scripts/zmfilter.pl scripts/zmpkg.pl scripts/zmtrack.pl scripts/zmcamtool.pl scripts/zmsystemctl.pl scripts/zmtrigger.pl scripts/zmupdate.pl scripts/zmvideo.pl scripts/zmwatch.pl scripts/zmx10.pl scripts/zmdbbackup scripts/zmdbrestore scripts/zmeventdump scripts/zmlogrotate.conf scripts/ZoneMinder/lib/ZoneMinder/Base.pm scripts/ZoneMinder/lib/ZoneMinder/Config.pm scripts/ZoneMinder/lib/ZoneMinder/Memory.pm scripts/ZoneMinder/lib/ZoneMinder/ConfigData.pm src/Makefile src/zm_config.h web/Makefile web/ajax/Makefile web/css/Makefile web/graphics/Makefile web/includes/Makefile web/includes/config.php web/js/Makefile web/lang/Makefile web/skins/Makefile web/skins/classic/Makefile web/skins/classic/ajax/Makefile web/skins/classic/css/Makefile web/skins/classic/css/classic/Makefile web/skins/classic/css/classic/views/Makefile web/skins/classic/css/dark/Makefile web/skins/classic/css/dark/views/Makefile web/skins/classic/css/flat/Makefile web/skins/classic/css/flat/views/Makefile web/skins/classic/graphics/Makefile web/skins/classic/includes/Makefile web/skins/classic/js/Makefile web/skins/classic/lang/Makefile web/skins/classic/views/Makefile web/skins/classic/views/js/Makefile web/skins/mobile/Makefile web/skins/mobile/ajax/Makefile web/skins/mobile/css/Makefile web/skins/mobile/graphics/Makefile web/skins/mobile/includes/Makefile web/skins/mobile/lang/Makefile web/skins/mobile/views/Makefile web/skins/mobile/views/css/Makefile web/tools/Makefile web/tools/mootools/Makefile web/views/Makefile web/skins/xml/Makefile web/skins/xml/views/Makefile web/skins/xml/includes/Makefile]) +AC_CONFIG_FILES([Makefile zm.conf zmconfgen.pl db/Makefile db/zm_create.sql misc/Makefile misc/apache.conf misc/logrotate.conf misc/syslog.conf misc/com.zoneminder.systemctl.policy misc/com.zoneminder.systemctl.rules onvif/Makefile onvif/scripts/Makefile scripts/Makefile scripts/zm scripts/zmaudit.pl scripts/zmcontrol.pl scripts/zmdc.pl scripts/zmfilter.pl scripts/zmpkg.pl scripts/zmtelemetry.pl scripts/zmtrack.pl scripts/zmcamtool.pl scripts/zmsystemctl.pl scripts/zmtrigger.pl scripts/zmupdate.pl scripts/zmvideo.pl scripts/zmwatch.pl scripts/zmx10.pl scripts/zmdbbackup scripts/zmdbrestore scripts/zmeventdump scripts/zmlogrotate.conf scripts/ZoneMinder/lib/ZoneMinder/Base.pm scripts/ZoneMinder/lib/ZoneMinder/Config.pm scripts/ZoneMinder/lib/ZoneMinder/Memory.pm scripts/ZoneMinder/lib/ZoneMinder/ConfigData.pm src/Makefile src/zm_config.h web/Makefile web/ajax/Makefile web/css/Makefile web/graphics/Makefile web/includes/Makefile web/includes/config.php web/js/Makefile web/lang/Makefile web/skins/Makefile web/skins/classic/Makefile web/skins/classic/ajax/Makefile web/skins/classic/css/Makefile web/skins/classic/css/classic/Makefile web/skins/classic/css/classic/views/Makefile web/skins/classic/css/dark/Makefile web/skins/classic/css/dark/views/Makefile web/skins/classic/css/flat/Makefile web/skins/classic/css/flat/views/Makefile web/skins/classic/graphics/Makefile web/skins/classic/includes/Makefile web/skins/classic/js/Makefile web/skins/classic/lang/Makefile web/skins/classic/views/Makefile web/skins/classic/views/js/Makefile web/skins/mobile/Makefile web/skins/mobile/ajax/Makefile web/skins/mobile/css/Makefile web/skins/mobile/graphics/Makefile web/skins/mobile/includes/Makefile web/skins/mobile/lang/Makefile web/skins/mobile/views/Makefile web/skins/mobile/views/css/Makefile web/tools/Makefile web/tools/mootools/Makefile web/views/Makefile web/skins/xml/Makefile web/skins/xml/views/Makefile web/skins/xml/includes/Makefile]) # Create the definitions for compilation and defaults for the database AC_CONFIG_COMMANDS([src/zm_config_defines.h],[perl ./zmconfgen.pl]) From e4d0f2ffdad5a4d9078f8b6276e06e0a5541936b Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 29 Mar 2016 11:50:51 -0400 Subject: [PATCH 07/20] fixup depends --- distros/ubuntu1504_cmake/control | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/distros/ubuntu1504_cmake/control b/distros/ubuntu1504_cmake/control index 5a8bd928b..8fc9a8038 100644 --- a/distros/ubuntu1504_cmake/control +++ b/distros/ubuntu1504_cmake/control @@ -16,6 +16,27 @@ Build-Depends: debhelper (>= 9), dh-systemd, python-sphinx | python3-sphinx, apa ,libpolkit-gobject-1-dev ,libv4l-dev (>= 0.8.3) [!hurd-any] ,libvlc-dev + ,libdate-manip-perl + ,libdbd-mysql-perl + ,libmime-lite-perl + ,libmime-tools-perl + ,libphp-serialization-perl + ,libmodule-load-conditional-perl + ,libnet-sftp-foreign-perl +# ,libzoneminder-perl (= ${source:Version}) + ,libarchive-zip-perl + ,libdbd-mysql-perl + ,libdevice-serialport-perl + ,libimage-info-perl + ,libjson-any-perl + ,libsys-mmap-perl [!hurd-any] + ,liburi-encode-perl + ,libwww-perl + ,libdata-dump-perl + ,libclass-std-fast-perl + ,libsoap-wsdl-perl + ,libio-socket-multicast-perl + ,libdigest-sha-perl # Unbundled (dh_linktree): ,libjs-jquery ,libjs-mootools From e3564f6a63fbb256ed721b7370a5f57cf273d02e Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 29 Mar 2016 11:51:03 -0400 Subject: [PATCH 08/20] add zmtelemtry.pl --- scripts/Makefile.am | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/Makefile.am b/scripts/Makefile.am index 1fe0a96a8..2657b8653 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -19,7 +19,8 @@ bin_SCRIPTS = \ zmcontrol.pl \ zmtrack.pl \ zmcamtool.pl \ - zmsystemctl.pl + zmsystemctl.pl \ + zmtelemetry.pl SUBDIRS = \ . \ @@ -39,6 +40,7 @@ EXTRA_DIST = \ zmtrack.pl.in \ zmcamtool.pl.in \ zmsystemctl.pl.in \ + zmtelemtry.pl.in \ ZoneMinder/Makefile.PL \ ZoneMinder/README \ ZoneMinder/Changes \ From 34c50b8cfc7a2ad8157e4000cfe637589c18af1d Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 29 Mar 2016 11:51:28 -0400 Subject: [PATCH 09/20] ipv6 support --- src/zm_remote_camera.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/zm_remote_camera.h b/src/zm_remote_camera.h index 7e3ae79a8..38c0903b6 100644 --- a/src/zm_remote_camera.h +++ b/src/zm_remote_camera.h @@ -27,6 +27,7 @@ #include #include #include +#include // // Class representing 'remote' cameras, i.e. those which are From 58f19f14e1968f0b8fd8b384f0178526733f5aa6 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 29 Mar 2016 11:51:58 -0400 Subject: [PATCH 10/20] print ip and hostname when can't connect --- src/zm_remote_camera_http.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/zm_remote_camera_http.cpp b/src/zm_remote_camera_http.cpp index 006f80faf..cb26413e0 100644 --- a/src/zm_remote_camera_http.cpp +++ b/src/zm_remote_camera_http.cpp @@ -108,7 +108,12 @@ int RemoteCameraHttp::Connect() { close(sd); sd = -1; - Warning("Can't connect to remote camera: %s", strerror(errno) ); + char buf[sizeof(struct in6_addr)]; + struct sockaddr_in *addr; + addr = (struct sockaddr_in *)p->ai_addr; + inet_ntop( AF_INET, &(addr->sin_addr), buf, INET6_ADDRSTRLEN ); + + Warning("Can't connect to remote camera mid: %d at %s: %s", id, buf, strerror(errno) ); continue; } From 1ea1852476d85f355219a0156ef3da7fc13adb03 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 29 Mar 2016 11:52:25 -0400 Subject: [PATCH 11/20] Do some Storage Areas support --- web/skins/classic/views/montagereview.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/web/skins/classic/views/montagereview.php b/web/skins/classic/views/montagereview.php index b9b5765fc..a6a8a73c0 100644 --- a/web/skins/classic/views/montagereview.php +++ b/web/skins/classic/views/montagereview.php @@ -100,6 +100,8 @@ if ( !canView( 'Events' ) ) return; } +require_once( 'includes/Monitor.php' ); + if ( !empty($_REQUEST['group']) ) { $group = $_REQUEST['group']; @@ -117,7 +119,7 @@ else // Note we round up just a bit on the end time as otherwise you get gaps, like 59.78 to 00 in the next second, which can give blank frames when moved through slowly. $eventsSql = " - select E.Id,E.Name,UNIX_TIMESTAMP(E.StartTime) as StartTimeSecs, + select E.Id,E.Name,E.StorageId,UNIX_TIMESTAMP(E.StartTime) as StartTimeSecs, case when E.EndTime is null then (Select UNIX_TIMESTAMP(DATE_ADD(E.StartTime, Interval max(Delta)+0.5 Second)) from Frames F where F.EventId=E.Id) else UNIX_TIMESTAMP(E.EndTime) end as CalcEndTimeSecs, E.Length, @@ -553,13 +555,12 @@ function SetImageSource(monId,val) else { var zeropad = ; - for(var i=0; i= eStartSecs[i] && val <= eEndSecs[i]) { var frame=parseInt((val - eStartSecs[i])/(eEndSecs[i]-eStartSecs[i])*eventFrames[i])+1; -// img = ePath[i] + zeropad.substr(frame.toString().length) + frame.toString() + "-capture.jpg"; - img = "index.php?view=image&path=" + ePath[i].substring(6) + zeropad.substr(frame.toString().length) + frame.toString() + "-capture.jpg" + "&width=" + monitorCanvasObj[monId].width + "&height=" + monitorCanvasObj[monId].height; + img = "index.php?view=image&eid=" + eId[i] + '&fid='+frame + "&width=" + monitorCanvasObj[monId].width + "&height=" + monitorCanvasObj[monId].height; return img; } } From c309cdaad4b34fce76cdaa0a1f8659fdc541fc71 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 29 Mar 2016 12:06:51 -0400 Subject: [PATCH 12/20] include Event object so it can be used elsewhere --- web/index.php | 1 + 1 file changed, 1 insertion(+) diff --git a/web/index.php b/web/index.php index 72e6dc8c0..fdd8fade0 100644 --- a/web/index.php +++ b/web/index.php @@ -49,6 +49,7 @@ if ( false ) require_once( 'includes/config.php' ); require_once( 'includes/logger.php' ); require_once( 'includes/Server.php' ); +require_once( 'includes/Event.php' ); if ( isset($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] == 'on' ) { From d91045319d3d6e31d7c7739414ad23283e5056c3 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 29 Mar 2016 12:07:13 -0400 Subject: [PATCH 13/20] Use Event object delete method in deleteEvent --- web/includes/functions.php | 42 +++----------------------------------- 1 file changed, 3 insertions(+), 39 deletions(-) diff --git a/web/includes/functions.php b/web/includes/functions.php index 6cbc24704..a9590059c 100644 --- a/web/includes/functions.php +++ b/web/includes/functions.php @@ -537,7 +537,7 @@ function deletePath( $path ) } } -function deleteEvent( $event, $mid=false ) { +function deleteEvent( $event ) { if ( empty($event) ) { Error( "Empty event passed to deleteEvent."); @@ -546,49 +546,13 @@ function deleteEvent( $event, $mid=false ) { if ( gettype($event) != 'array' ) { # $event could be an eid, so turn it into an event hash - $event = dbFetchOne( 'SELECT Id, MonitorId, StartTime FROM Events WHERE Id=?', NULL, array( $event ) ); + $event = new Event( $event ); } global $user; - if ( !$mid ) - $mid = $event['MonitorId']; - if ( $user['Events'] == 'Edit' ) { - - dbQuery( 'DELETE FROM Events WHERE Id = ?', array($event['Id']) ); - if ( !ZM_OPT_FAST_DELETE ) { - dbQuery( 'DELETE FROM Stats WHERE EventId = ?', array($event['Id']) ); - dbQuery( 'DELETE FROM Frames WHERE EventId = ?', array($event['Id']) ); - if ( ZM_USE_DEEP_STORAGE ) { - - # Assumption: All events haev a start time - $start_date = date_parse( $event['StartTime'] ); - $start_date['year'] = $start_date['year'] % 100; - - # So this is because ZM creates a link under teh day pointing to the time that the event happened. - $eventlink_path = sprintf('%s/%d/%02d/%02d/%02d/.%d', ZM_DIR_EVENTS, $mid, $start_date['year'], $start_date['month'], $start_date['day'], $event['Id'] ); - - if ( $id_files = glob( $eventlink_path ) ) { - # I know we are using arrays here, but really there can only ever be 1 in the array - $eventPath = preg_replace( '/\.'.$event['Id'].'$/', readlink($id_files[0]), $id_files[0] ); - deletePath( $eventPath ); - deletePath( $id_files[0] ); - $pathParts = explode( '/', $eventPath ); - for ( $i = count($pathParts)-1; $i >= 2; $i-- ) { - $deletePath = join( '/', array_slice( $pathParts, 0, $i ) ); - if ( !glob( $deletePath."/*" ) ) { - deletePath( $deletePath ); - } - } - } else { - Warning( "Found no event files under $eventlink_path" ); - } # end if found files - } else { - $eventPath = implode( '/', array( ZM_DIR_EVENTS, $mid, $event['Id'] ) ); - deletePath( $eventPath ); - } # USE_DEEP_STORAGE OR NOT - } # ! ZM_OPT_FAST_DELETE + $event->delete(); } # CAN EDIT } From cfa11b95dcb0054cfdef29f15f3c0908dc0bc566 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 29 Mar 2016 12:27:23 -0400 Subject: [PATCH 14/20] Add missing Server and Storage Area filters --- web/includes/functions.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/web/includes/functions.php b/web/includes/functions.php index a9590059c..499e8fd2c 100644 --- a/web/includes/functions.php +++ b/web/includes/functions.php @@ -1397,6 +1397,9 @@ function parseFilter( &$filter, $saveToSession=false, $querySep='&' ) case 'MonitorName': $filter['sql'] .= 'M.'.preg_replace( '/^Monitor/', '', $filter['terms'][$i]['attr'] ); break; + case 'ServerId': + $filter['sql'] .= 'M.ServerId'; + break; case 'DateTime': $filter['sql'] .= "E.StartTime"; break; @@ -1412,6 +1415,7 @@ function parseFilter( &$filter, $saveToSession=false, $querySep='&' ) case 'Id': case 'Name': case 'MonitorId': + case 'StorageId': case 'Length': case 'Frames': case 'AlarmFrames': @@ -1444,6 +1448,12 @@ function parseFilter( &$filter, $saveToSession=false, $querySep='&' ) case 'Notes': $value = dbEscape($value); break; + case 'ServerId': + if ( $value == 'ZM_SERVER_ID' ) { + $value = ZM_SERVER_ID; + } else { + $value = dbEscape($value); + } case 'DateTime': $value = "'".strftime( STRF_FMT_DATETIME_DB, strtotime( $value ) )."'"; break; From 22554603b122418ea81f5ee7ec7f4eb6883f2040 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 29 Mar 2016 12:31:27 -0400 Subject: [PATCH 15/20] remove duplicate zmtelemetry.pl entry --- scripts/Makefile.am | 2 -- 1 file changed, 2 deletions(-) diff --git a/scripts/Makefile.am b/scripts/Makefile.am index 09b5b03d3..2657b8653 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -10,7 +10,6 @@ bin_SCRIPTS = \ zmdc.pl \ zmaudit.pl \ zmfilter.pl \ - zmtelemetry.pl \ zmtrigger.pl \ zmx10.pl \ zmwatch.pl \ @@ -31,7 +30,6 @@ EXTRA_DIST = \ zmdc.pl.in \ zmaudit.pl.in \ zmfilter.pl.in \ - zmtelemetry.pl.in \ zmtrigger.pl.in \ zmx10.pl.in \ zmwatch.pl.in \ From 0ab6e27259dd054f4acbae839733ad32bcae217c Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 29 Mar 2016 14:35:12 -0400 Subject: [PATCH 16/20] Use Monitor object --- web/skins/classic/views/zones.php | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/web/skins/classic/views/zones.php b/web/skins/classic/views/zones.php index 9182dc98f..f5e237369 100644 --- a/web/skins/classic/views/zones.php +++ b/web/skins/classic/views/zones.php @@ -25,13 +25,12 @@ if ( !canView( 'Monitors' ) ) } $mid = validInt($_REQUEST['mid']); +$Monitor = new Monitor( $mid ); $wd = getcwd(); chdir( ZM_DIR_IMAGES ); $status = exec( escapeshellcmd( getZmuCommand( " -m ".$mid." -z" ) ) ); chdir( $wd ); - -$monitor = dbFetchMonitor( $mid ); - +$image = ZM_DIR_IMAGES.'/'.'Zones'.$Monitor->Id().'.jpg'; $zones = array(); foreach( dbFetchAll( 'select * from Zones where MonitorId = ? order by Area desc', NULL, array($mid) ) as $row ) { @@ -42,7 +41,6 @@ foreach( dbFetchAll( 'select * from Zones where MonitorId = ? order by Area desc } } -$image = 'Zones'.$monitor['Id'].'.jpg'; xhtmlHeaders(__FILE__, translate('Zones') ); ?> @@ -58,13 +56,13 @@ xhtmlHeaders(__FILE__, translate('Zones') ); foreach( array_reverse($zones) as $zone ) { ?> - <?php echo htmlspecialchars($zone['Name']) ?> + <?php echo htmlspecialchars($zone['Name']) ?> - zones + zones
@@ -84,9 +82,9 @@ foreach( $zones as $zone ) { ?> - + -  /  +  / Width*$Monitor->Height) ) ?> disabled="disabled"/>
- disabled="disabled"/> + disabled="disabled"/>
From 1262e831ac94e6c74a09fd4d48eb8515896f9a62 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 29 Mar 2016 14:36:16 -0400 Subject: [PATCH 17/20] rework zmu to load data from the last event with frames when it can't connect to zmc --- src/zm_event.cpp | 11 +++++++++++ src/zm_event.h | 5 +++-- src/zm_monitor.cpp | 42 +++++++++++++++++++++++++++++++----------- src/zmu.cpp | 1 - 4 files changed, 45 insertions(+), 14 deletions(-) diff --git a/src/zm_event.cpp b/src/zm_event.cpp index a5e0a03cd..1d8e87822 100644 --- a/src/zm_event.cpp +++ b/src/zm_event.cpp @@ -1221,6 +1221,17 @@ void EventStream::checkEventLoaded() } } +Image * EventStream::getImage( ) { + Event::Initialise(); + static char filepath[PATH_MAX]; + + Debug( 2, "EventStream::getImage path(%s) frame(%d)", event_data->path, curr_frame_id ); + snprintf( filepath, sizeof(filepath), Event::capture_file_format, event_data->path, curr_frame_id ); + Debug( 2, "EventStream::getImage path(%s) ", filepath, curr_frame_id ); + Image *image = new Image( filepath ); + return image; +} + bool EventStream::sendFrame( int delta_us ) { Debug( 2, "Sending frame %d", curr_frame_id ); diff --git a/src/zm_event.h b/src/zm_event.h index 80117cd2f..a99874394 100644 --- a/src/zm_event.h +++ b/src/zm_event.h @@ -253,18 +253,19 @@ public: void setStreamStart( int init_event_id, int init_frame_id=0 ) { loadInitialEventData( init_event_id, init_frame_id ); - loadMonitor( event_data->monitor_id ); + loadMonitor( event_data->monitor_id ); } void setStreamStart( int monitor_id, time_t event_time ) { loadInitialEventData( monitor_id, event_time ); - loadMonitor( monitor_id ); + loadMonitor( monitor_id ); } void setStreamMode( StreamMode p_mode ) { mode = p_mode; } void runStream(); + Image *getImage(); }; #endif // ZM_EVENT_H diff --git a/src/zm_monitor.cpp b/src/zm_monitor.cpp index e44c52154..83592e9e8 100644 --- a/src/zm_monitor.cpp +++ b/src/zm_monitor.cpp @@ -1131,13 +1131,32 @@ void Monitor::DumpZoneImage( const char *zone_string ) } } - int index = shared_data->last_write_index; - Snapshot *snap = &image_buffer[index]; - Image *snap_image = snap->image; + Image *zone_image = NULL; + if ( ( (!staticConfig.SERVER_ID) || ( staticConfig.SERVER_ID == server_id ) ) && connected ) { + Debug(3, "Trying to load from local zmc"); + int index = shared_data->last_write_index; + Snapshot *snap = &image_buffer[index]; + zone_image = new Image( *snap->image ); + } else { + Debug(3, "Trying to load from event"); + // Grab the most revent event image + std::string sql = stringtf( "SELECT MAX(Id) FROM Events WHERE MonitorId=%d AND Frames > 0", id ); + MYSQL_ROW eventid_row = zmDbFetchOne(sql.c_str() ); + if ( eventid_row ) { + int event_id = atoi( eventid_row[0] ); - Image zone_image( *snap_image ); - if(zone_image.Colours() == ZM_COLOUR_GRAY8) { - zone_image.Colourise(ZM_COLOUR_RGB24, ZM_SUBPIX_ORDER_RGB ); + Debug( 3, "Got event %d", event_id ); + EventStream *stream = new EventStream(); + stream->setStreamStart( event_id, 1 ); + zone_image = stream->getImage(); + } else { + Error("Unable to load an event for monitor %d", id ); + return; + } + } + + if(zone_image->Colours() == ZM_COLOUR_GRAY8) { + zone_image->Colourise(ZM_COLOUR_RGB24, ZM_SUBPIX_ORDER_RGB ); } for( int i = 0; i < n_zones; i++ ) @@ -1173,19 +1192,20 @@ void Monitor::DumpZoneImage( const char *zone_string ) colour = RGB_WHITE; } } - zone_image.Fill( colour, 2, zones[i]->GetPolygon() ); - zone_image.Outline( colour, zones[i]->GetPolygon() ); + zone_image->Fill( colour, 2, zones[i]->GetPolygon() ); + zone_image->Outline( colour, zones[i]->GetPolygon() ); } if ( extra_zone.getNumCoords() ) { - zone_image.Fill( extra_colour, 2, extra_zone ); - zone_image.Outline( extra_colour, extra_zone ); + zone_image->Fill( extra_colour, 2, extra_zone ); + zone_image->Outline( extra_colour, extra_zone ); } static char filename[PATH_MAX]; snprintf( filename, sizeof(filename), "Zones%d.jpg", id ); - zone_image.WriteJpeg( filename ); + zone_image->WriteJpeg( filename ); + delete zone_image; } void Monitor::DumpImage( Image *dump_image ) const diff --git a/src/zmu.cpp b/src/zmu.cpp index a1e8887bd..188362446 100644 --- a/src/zmu.cpp +++ b/src/zmu.cpp @@ -493,7 +493,6 @@ int main( int argc, char *argv[] ) } if ( ! monitor->connect() ) { Error( "Can't connect to capture daemon: %d %s", monitor->Id(), monitor->Name() ); - exit( -1 ); } char separator = ' '; From 1b69299c2db50a4546577c514c917f2cbd7281c8 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 29 Mar 2016 14:36:42 -0400 Subject: [PATCH 18/20] Include Monitor object so it can be used elsewhere --- web/index.php | 1 + 1 file changed, 1 insertion(+) diff --git a/web/index.php b/web/index.php index fdd8fade0..2d3e8e73a 100644 --- a/web/index.php +++ b/web/index.php @@ -50,6 +50,7 @@ require_once( 'includes/config.php' ); require_once( 'includes/logger.php' ); require_once( 'includes/Server.php' ); require_once( 'includes/Event.php' ); +require_once( 'includes/Monitor.php' ); if ( isset($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] == 'on' ) { From 50f9241c14b77ccabd7f4c4a7d0ac49fa387e22b Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 29 Mar 2016 15:38:53 -0400 Subject: [PATCH 19/20] When no Id is specified, default to ZM_DIR_EVENTS --- web/includes/Storage.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/web/includes/Storage.php b/web/includes/Storage.php index 1820b977d..4143d0585 100644 --- a/web/includes/Storage.php +++ b/web/includes/Storage.php @@ -26,6 +26,8 @@ class Storage { public function Path() { if ( isset( $this->{'Path'} ) and ( $this->{'Path'} != '' ) ) { return $this->{'Path'}; + } else if ( ! $this->{'Id'} ) { + return ZM_DIR_EVENTS; } return $this->{'Name'}; } From 204a128ecc552b441b7afaefaf643479355c5831 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 29 Mar 2016 15:46:47 -0400 Subject: [PATCH 20/20] fix use of connected when it should be mem_ptr --- src/zm_monitor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/zm_monitor.cpp b/src/zm_monitor.cpp index 83592e9e8..231852ca4 100644 --- a/src/zm_monitor.cpp +++ b/src/zm_monitor.cpp @@ -1132,7 +1132,7 @@ void Monitor::DumpZoneImage( const char *zone_string ) } Image *zone_image = NULL; - if ( ( (!staticConfig.SERVER_ID) || ( staticConfig.SERVER_ID == server_id ) ) && connected ) { + if ( ( (!staticConfig.SERVER_ID) || ( staticConfig.SERVER_ID == server_id ) ) && mem_ptr ) { Debug(3, "Trying to load from local zmc"); int index = shared_data->last_write_index; Snapshot *snap = &image_buffer[index];