diff --git a/db/zm_create.sql.in b/db/zm_create.sql.in index 745420107..06bdf0f85 100644 --- a/db/zm_create.sql.in +++ b/db/zm_create.sql.in @@ -713,7 +713,7 @@ CREATE TABLE `Storage` ( -- -- Create a default storage location -- -insert into Storage VALUES (NULL, '/var/cache/zoneminder/events', 'Default', 'local', NULL, 'Medium', 0 ); +insert into Storage VALUES (NULL, '@ZM_DIR_EVENTS@', 'Default', 'local', NULL, NULL, 'Medium', 0, true ); /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; diff --git a/scripts/ZoneMinder/lib/ZoneMinder/Event.pm b/scripts/ZoneMinder/lib/ZoneMinder/Event.pm index b401054a3..f9b139095 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/Event.pm +++ b/scripts/ZoneMinder/lib/ZoneMinder/Event.pm @@ -397,7 +397,7 @@ sub delete { if ( (! $Config{ZM_OPT_FAST_DELETE}) and $event->Storage()->DoDelete() ) { $event->delete_files( ); } else { - Debug('Not deleting frames, stats and files for speed.'); + Debug('Not deleting event files for speed.'); } } # end sub delete @@ -519,6 +519,23 @@ sub DiskSpace { sub MoveTo { my ( $self, $NewStorage ) = @_; + my $OldStorage = $self->Storage(undef); + my ( $OldPath ) = ( $self->Path() =~ /^(.*)$/ ); # De-taint + if ( ! -e $OldPath ) { + $ZoneMinder::Database::dbh->commit(); + return "Old path $OldPath does not exist."; + } + # First determine if we can move it to the dest. + # We do this before bothering to lock the event + my ( $NewPath ) = ( $NewStorage->Path() =~ /^(.*)$/ ); # De-taint + if ( ! $$NewStorage{Id} ) { + return "New storage does not have an id. Moving will not happen."; + } elsif ( !$NewPath ) { + return "New path ($NewPath) is empty."; + } elsif ( ! -e $NewPath ) { + return "New path $NewPath does not exist."; + } + $ZoneMinder::Database::dbh->begin_work(); $self->lock_and_load(); # data is reloaded, so need to check that the move hasn't already happened. @@ -526,25 +543,13 @@ sub MoveTo { $ZoneMinder::Database::dbh->commit(); return "Event has already been moved by someone else."; } - my $OldStorage = $self->Storage(undef); - my ( $OldPath ) = ( $self->Path() =~ /^(.*)$/ ); # De-taint + + if ( $$OldStorage{Id} != $$self{StorageId} ) { + $ZoneMinder::Database::dbh->commit(); + return "Old Storage path changed, Event has moved somewhere else."; + } $$self{Storage} = $NewStorage; - - my ( $NewPath ) = ( $NewStorage->Path() =~ /^(.*)$/ ); # De-taint - if ( ! $$NewStorage{Id} ) { - $ZoneMinder::Database::dbh->commit(); - return "New storage does not have an id. Moving will not happen."; - } elsif ( !$NewPath ) { - $ZoneMinder::Database::dbh->commit(); - return "New path ($NewPath) is empty."; - } elsif ( ! -e $NewPath ) { - $ZoneMinder::Database::dbh->commit(); - return "New path $NewPath does not exist."; - } elsif ( ! -e $OldPath ) { - $ZoneMinder::Database::dbh->commit(); - return "Old path $OldPath does not exist."; - } ( $NewPath ) = ( $self->Path(undef) =~ /^(.*)$/ ); # De-taint if ( $NewPath eq $OldPath ) { $ZoneMinder::Database::dbh->commit(); diff --git a/scripts/ZoneMinder/lib/ZoneMinder/Storage.pm b/scripts/ZoneMinder/lib/ZoneMinder/Storage.pm index 8fbe5ed80..b6924c4e9 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/Storage.pm +++ b/scripts/ZoneMinder/lib/ZoneMinder/Storage.pm @@ -113,6 +113,15 @@ sub Name { return $_[0]{Name}; } # end sub Path +sub DoDelete { + my $self = shift; + $$self{DoDelete} = shift if @_; + if ( ! defined $$self{DoDelete} ) { + $$self{DoDelete} = 1; + } + return $$self{DoDelete}; +} + sub Server { my $self = shift; if ( ! $$self{Server} ) { diff --git a/src/zm_ffmpeg_camera.cpp b/src/zm_ffmpeg_camera.cpp index 07d7dd657..d77c1e788 100644 --- a/src/zm_ffmpeg_camera.cpp +++ b/src/zm_ffmpeg_camera.cpp @@ -677,6 +677,11 @@ int FfmpegCamera::Close() { mFormatContext = NULL; } + if ( videoStore ) { + delete videoStore; + videoStore = NULL; + } + return 0; } // end FfmpegCamera::Close diff --git a/web/ajax/stream.php b/web/ajax/stream.php index 00ed7719d..1c2fb3d62 100644 --- a/web/ajax/stream.php +++ b/web/ajax/stream.php @@ -145,7 +145,7 @@ if ( sem_acquire($semaphore,1) !== false ) { } case MSG_DATA_EVENT : { - $data = unpack( "ltype/ievent/iprogress/irate/izoom/Cpaused", $msg ); + $data = unpack( "ltype/Pevent/iprogress/irate/izoom/Cpaused", $msg ); //$data['progress'] = sprintf( "%.2f", $data['progress'] ); $data['rate'] /= RATE_BASE; $data['zoom'] = round( $data['zoom']/SCALE_BASE, 1 ); diff --git a/web/includes/Group.php b/web/includes/Group.php index 02314cc99..441eff70e 100644 --- a/web/includes/Group.php +++ b/web/includes/Group.php @@ -211,7 +211,7 @@ class Group { $group_options = array(); foreach ( $Groups as $id=>$Group ) { if ( ! $Group->ParentId() ) { - $group_options += get_options( $Group ); + $group_options += get_options($Group); } } return $group_options; @@ -280,6 +280,4 @@ public function Parents() { } } # end class Group - - ?> diff --git a/web/includes/actions.php b/web/includes/actions.php index cc264d29f..423f63bcb 100644 --- a/web/includes/actions.php +++ b/web/includes/actions.php @@ -564,7 +564,14 @@ if ( canEdit( 'Monitors' ) ) { Error("Users with Monitors restrictions cannot create new monitors."); return; } - if ( count($_POST['newMonitor']['GroupIds']) != count($Monitor->GroupIds()) or array_diff($_POST['newMonitor']['GroupIds'], $Monitor->GroupIds() ) ) { + + if ( + ( !isset($_POST['newMonitor']['GroupIds']) ) + or + ( count($_POST['newMonitor']['GroupIds']) != count($Monitor->GroupIds()) ) + or + array_diff($_POST['newMonitor']['GroupIds'], $Monitor->GroupIds()) + ) { if ( $Monitor->Id() ) dbQuery('DELETE FROM Groups_Monitors WHERE MonitorId=?', array($mid)); diff --git a/web/includes/database.php b/web/includes/database.php index f11f50d04..9ec113ff1 100644 --- a/web/includes/database.php +++ b/web/includes/database.php @@ -164,16 +164,16 @@ function dbFetchOne( $sql, $col=false, $params=NULL ) { return false; } - if ( $result && $dbRow = $result->fetch( PDO::FETCH_ASSOC ) ) { + if ( $result && $dbRow = $result->fetch(PDO::FETCH_ASSOC) ) { if ( $col ) { - if ( ! isset( $dbRow[$col] ) ) { - Warning( "$col does not exist in the returned row " . print_r($dbRow, true) ); + if ( ! array_key_exists($col, $dbRow) ) { + Warning("$col does not exist in the returned row " . print_r($dbRow, true)); } return $dbRow[$col]; } return $dbRow; } - return( false ); + return false; } function dbFetchAll( $sql, $col=false, $params=NULL ) { diff --git a/web/includes/functions.php b/web/includes/functions.php index 648ce20c3..64d6ce29b 100644 --- a/web/includes/functions.php +++ b/web/includes/functions.php @@ -2132,7 +2132,7 @@ function getStreamHTML( $monitor, $options = array() ) { if ( ZM_WEB_STREAM_METHOD == 'mpeg' && ZM_MPEG_LIVE_FORMAT ) { $streamSrc = $monitor->getStreamSrc( array( 'mode'=>'mpeg', - 'scale'=>$options['scale'], + 'scale'=>(isset($options['scale'])?$options['scale']:100), 'bitrate'=>ZM_WEB_VIDEO_BITRATE, 'maxfps'=>ZM_WEB_VIDEO_MAXFPS, 'format' => ZM_MPEG_LIVE_FORMAT diff --git a/web/skins/classic/views/console.php b/web/skins/classic/views/console.php index 57be8aabf..6d202d163 100644 --- a/web/skins/classic/views/console.php +++ b/web/skins/classic/views/console.php @@ -249,9 +249,11 @@ if ( $fclass != 'infoText' ) $dot_class=$fclass; ' : '>') . $monitor['Name'] ?>
', array_map(function($group_id){ - $Group = new Group($group_id); - $Groups = $Group->Parents(); - array_push( $Groups, $Group ); + $Group = Group::find_one(array('Id'=>$group_id)); + if ( $Group ) { + $Groups = $Group->Parents(); + array_push( $Groups, $Group ); + } return implode(' > ', array_map(function($Group){ return ''.$Group->Name().''; }, $Groups )); }, $Monitor->GroupIds() ) ); ?> diff --git a/web/skins/classic/views/js/watch.js b/web/skins/classic/views/js/watch.js index 430a9bdb3..d5860214a 100644 --- a/web/skins/classic/views/js/watch.js +++ b/web/skins/classic/views/js/watch.js @@ -1,6 +1,8 @@ -function setButtonState( element, butClass ) { - element.className = butClass; - element.disabled = (butClass != 'inactive'); +function setButtonState(element, butClass) { + if ( element ) { + element.className = butClass; + element.disabled = (butClass != 'inactive'); + } } function showEvents() { diff --git a/web/skins/classic/views/report_event_audit.php b/web/skins/classic/views/report_event_audit.php index e779d3bdf..4da7b032c 100644 --- a/web/skins/classic/views/report_event_audit.php +++ b/web/skins/classic/views/report_event_audit.php @@ -98,7 +98,7 @@ $EventsByMonitor = array(); while( $event = $result->fetch(PDO::FETCH_ASSOC) ) { $Event = new Event($event); if ( ! isset($EventsByMonitor[$event['MonitorId']]) ) - $EventsByMonitor[$event['MonitorId']] = array( 'Events'=>array(), 'MinGap'=>0, 'MaxGap'=>0, 'FileMissing'=>0, ); + $EventsByMonitor[$event['MonitorId']] = array( 'Events'=>array(), 'MinGap'=>0, 'MaxGap'=>0, 'FileMissing'=>0, 'ZeroSize'=>0 ); if ( count($EventsByMonitor[$event['MonitorId']]['Events']) ) { $last_event = end($EventsByMonitor[$event['MonitorId']]['Events']); @@ -112,6 +112,8 @@ while( $event = $result->fetch(PDO::FETCH_ASSOC) ) { } # end if has previous events if ( ! file_exists( $Event->Path().'/'.$Event->DefaultVideo() ) ) { $EventsByMonitor[$event['MonitorId']]['FileMissing'] += 1; + } else if ( ! filesize( $Event->Path().'/'.$Event->DefaultVideo() ) ) { + $EventsByMonitor[$event['MonitorId']]['ZeroSize'] += 1; } $EventsByMonitor[$event['MonitorId']]['Events'][] = $Event; } # end foreach event @@ -142,6 +144,7 @@ while( $event = $result->fetch(PDO::FETCH_ASSOC) ) { + @@ -169,6 +172,7 @@ for( $monitor_i = 0; $monitor_i < count($displayMonitors); $monitor_i += 1 ) { Id()])?$EventsByMonitor[$Monitor->Id()]['MinGap']:0 ?> Id()])?$EventsByMonitor[$Monitor->Id()]['MaxGap']:0 ?> Id()])?$EventsByMonitor[$Monitor->Id()]['FileMissing']:0 ?> + Id()])?$EventsByMonitor[$Monitor->Id()]['ZeroSize']:0 ?> StreamReplayBuffer() != 0 ); noCacheHeaders(); @@ -97,15 +96,31 @@ if ( canEdit( 'Monitors' ) ) { ?>
 -  fps
-