diff --git a/scripts/ZoneMinder/lib/ZoneMinder/Event.pm b/scripts/ZoneMinder/lib/ZoneMinder/Event.pm index 220e7456d..168468b61 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/Event.pm +++ b/scripts/ZoneMinder/lib/ZoneMinder/Event.pm @@ -35,6 +35,8 @@ require Date::Manip; require File::Find; require File::Path; require File::Copy; +require File::Slurp; +require File::Basename; require Number::Bytes::Human; #our @ISA = qw(ZoneMinder::Object); @@ -419,7 +421,6 @@ sub delete_files { my $deleted = 0; if ( $$Storage{Type} eq 's3fs' ) { my ( $aws_id, $aws_secret, $aws_host, $aws_bucket ) = ( $$Storage{Url} =~ /^\s*([^:]+):([^@]+)@([^\/]*)\/(.+)\s*$/ ); -Debug("Trying to delete from S3 on $aws_host / $aws_bucket ($$Storage{Url})"); eval { require Net::Amazon::S3; my $s3 = Net::Amazon::S3->new( { @@ -547,38 +548,93 @@ sub MoveTo { } Debug("Moving event $$self{Id} from $OldPath to $NewPath"); + my $moved = 0; + + if ( $$NewStorage{Type} eq 's3fs' ) { + my ( $aws_id, $aws_secret, $aws_host, $aws_bucket ) = ( $$NewStorage{Url} =~ /^\s*([^:]+):([^@]+)@([^\/]*)\/(.+)\s*$/ ); + eval { + require Net::Amazon::S3; + my $s3 = Net::Amazon::S3->new( { + aws_access_key_id => $aws_id, + aws_secret_access_key => $aws_secret, + ( $aws_host ? ( host => $aws_host ) : () ), + }); + my $bucket = $s3->bucket($aws_bucket); + if ( ! $bucket ) { + Error("S3 bucket $bucket not found."); + die; + } + + my $event_path = 'events/'.$self->RelativePath(); +Info("Making dir ectory $event_path/"); + if ( ! $bucket->add_key( $event_path.'/','' ) ) { + die "Unable to add key for $event_path/"; + } + + my @files = glob("$OldPath/*"); +Debug("Files to move @files"); + for my $file (@files) { + next if $file =~ /^\./; + ( $file ) = ( $file =~ /^(.*)$/ ); # De-taint + my $starttime = time; + Debug("Moving file $file to $NewPath"); + my $size = -s $file; + if ( ! $size ) { + Info("Not moving file with 0 size"); + } + my $file_contents = File::Slurp::read_file($file); + if ( ! $file_contents ) { + die "Loaded empty file, but it had a size. Giving up"; + } + + my $filename = $event_path.'/'.File::Basename::basename($file); + if ( ! $bucket->add_key( $filename, $file_contents ) ) { + die "Unable to add key for $filename"; + } + my $duration = time - $starttime; + Debug("PUT to S3 " . Number::Bytes::Human::format_bytes($size) . " in $duration seconds = " . Number::Bytes::Human::format_bytes($size/$duration) . "/sec"); + } # end foreach file. + + $moved = 1; + }; + Error($@) if $@; + die $@ if $@; + } # end if s3 + my $error = ''; - File::Path::make_path( $NewPath, {error => \my $err} ); - if ( @$err ) { - for my $diag (@$err) { - my ($file, $message) = %$diag; - next if $message eq 'File exists'; - if ($file eq '') { - $error .= "general error: $message\n"; - } else { - $error .= "problem making $file: $message\n"; + if ( ! $moved ) { + File::Path::make_path( $NewPath, {error => \my $err} ); + if ( @$err ) { + for my $diag (@$err) { + my ($file, $message) = %$diag; + next if $message eq 'File exists'; + if ($file eq '') { + $error .= "general error: $message\n"; + } else { + $error .= "problem making $file: $message\n"; + } } } - } - if ( $error ) { - $ZoneMinder::Database::dbh->commit(); - return $error; - } - my @files = glob("$OldPath/*"); - - for my $file (@files) { - next if $file =~ /^\./; - ( $file ) = ( $file =~ /^(.*)$/ ); # De-taint - my $starttime = time; - Debug("Moving file $file to $NewPath"); - my $size = -s $file; - if ( ! File::Copy::copy( $file, $NewPath ) ) { - $error .= "Copy failed: for $file to $NewPath: $!"; - last; + if ( $error ) { + $ZoneMinder::Database::dbh->commit(); + return $error; } - my $duration = time - $starttime; - Debug("Copied " . Number::Bytes::Human::format_bytes($size) . " in $duration seconds = " . Number::Bytes::Human::format_bytes($size/$duration) . "/sec"); - } # end foreach file. + my @files = glob("$OldPath/*"); + + for my $file (@files) { + next if $file =~ /^\./; + ( $file ) = ( $file =~ /^(.*)$/ ); # De-taint + my $starttime = time; + Debug("Moving file $file to $NewPath"); + my $size = -s $file; + if ( ! File::Copy::copy( $file, $NewPath ) ) { + $error .= "Copy failed: for $file to $NewPath: $!"; + last; + } + my $duration = time - $starttime; + Debug("Copied " . Number::Bytes::Human::format_bytes($size) . " in $duration seconds = " . ($duration?Number::Bytes::Human::format_bytes($size/$duration):'inf') . "/sec"); + } # end foreach file. + } # end if ! moved if ( $error ) { $ZoneMinder::Database::dbh->commit(); @@ -593,8 +649,8 @@ sub MoveTo { $ZoneMinder::Database::dbh->commit(); return $error; } - $self->delete_files( $OldStorage ); $ZoneMinder::Database::dbh->commit(); + $self->delete_files( $OldStorage ); return $error; } # end sub MoveTo diff --git a/scripts/zmaudit.pl.in b/scripts/zmaudit.pl.in index 0e1faf640..0ab4e4e9d 100644 --- a/scripts/zmaudit.pl.in +++ b/scripts/zmaudit.pl.in @@ -246,7 +246,7 @@ MAIN: while( $loop ) { { my @day_dirs = glob("$monitor_dir/[0-9][0-9]/[0-9][0-9]/[0-9][0-9]"); - Debug(qq`Checking for Deep Events under using glob("$monitor_dir/[0-9][0-9]/[0-9][0-9]/[0-9][0-9]") returned `. scalar @day_dirs . " events"); + Debug(qq`Checking for Deep Events under $$Storage{Path} using glob("$monitor_dir/[0-9][0-9]/[0-9][0-9]/[0-9][0-9]") returned `. scalar @day_dirs . ' events'); foreach my $day_dir ( @day_dirs ) { Debug( "Checking day dir $day_dir" ); ( $day_dir ) = ( $day_dir =~ /^(.*)$/ ); # De-taint @@ -294,7 +294,7 @@ MAIN: while( $loop ) { } # end foreach day dir } - Debug("Checking for Medium Scheme Events under $monitor_dir"); + Debug("Checking for Medium Scheme Events under $$Storage{Path}/$monitor_dir"); { my @event_dirs = glob("$monitor_dir/[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]/*"); Debug(qq`glob("$monitor_dir/[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]/*") returned ` . scalar @event_dirs . " entries." ); diff --git a/scripts/zmpkg.pl.in b/scripts/zmpkg.pl.in index d772c9944..6b6839bff 100644 --- a/scripts/zmpkg.pl.in +++ b/scripts/zmpkg.pl.in @@ -205,6 +205,7 @@ if ( $command =~ /^(?:start|restart)$/ ) { $sql = 'SELECT * FROM Monitors'; } + { my $sth = $dbh->prepare_cached( $sql ) or Fatal( "Can't prepare '$sql': ".$dbh->errstr() ); my $res = $sth->execute( @values ) @@ -229,10 +230,24 @@ if ( $command =~ /^(?:start|restart)$/ ) { } } $sth->finish(); - + } + { + my $sql = 'SELECT Id FROM Filters WHERE Background=1'; + my $sth = $dbh->prepare_cached($sql) + or Fatal( "Can't prepare '$sql': ".$dbh->errstr() ); + my $res = $sth->execute() + or Fatal( "Can't execute: ".$sth->errstr() ); + if ( $sth->rows ) { + while( my $filter = $sth->fetchrow_hashref() ) { # This is now started unconditionally - runCommand('zmdc.pl start zmfilter.pl'); - + runCommand("zmdc.pl start zmfilter.pl --filter_id=$$filter{Id}"); + } + } else { + runCommand('zmdc.pl start zmfilter.pl'); + } + $sth->finish(); + } + if ( $Config{ZM_RUN_AUDIT} ) { if ( $Server and exists $$Server{'zmaudit'} and ! $$Server{'zmaudit'} ) { Debug("Not running zmaudit.pl because it is turned off for this server."); diff --git a/src/zm_event.cpp b/src/zm_event.cpp index 97f2769f9..c886165a3 100644 --- a/src/zm_event.cpp +++ b/src/zm_event.cpp @@ -209,15 +209,6 @@ Event::Event( delete videowriter; videowriter = NULL; } - - snprintf( timecodes_name, sizeof(timecodes_name), "%d-%s", id, "video.timecodes" ); - snprintf( timecodes_file, sizeof(timecodes_file), staticConfig.video_file_format, path, timecodes_name ); - - /* Create timecodes file */ - timecodes_fd = fopen(timecodes_file, "wb"); - if ( timecodes_fd == NULL ) { - Error("Failed creating timecodes file"); - } } } else { /* No video object */ @@ -238,12 +229,6 @@ Event::~Event() { } delete videowriter; videowriter = NULL; - - /* Close the timecodes file */ - if ( timecodes_fd ) { - fclose(timecodes_fd); - timecodes_fd = NULL; - } } @@ -268,10 +253,9 @@ Event::~Event() { snprintf( sql, sizeof(sql), "UPDATE Events SET Name='%s%d', EndTime = from_unixtime( %ld ), Length = %s%ld.%02ld, Frames = %d, AlarmFrames = %d, TotScore = %d, AvgScore = %d, MaxScore = %d, DefaultVideo = '%s' where Id = %d", monitor->EventPrefix(), id, end_time.tv_sec, delta_time.positive?"":"-", delta_time.sec, delta_time.fsec, frames, alarm_frames, tot_score, (int)(alarm_frames?(tot_score/alarm_frames):0), max_score, video_name, id ); db_mutex.lock(); - if ( mysql_query(&dbconn, sql) ) { + while ( mysql_query(&dbconn, sql) ) { Error("Can't update event: %s", mysql_error(&dbconn)); - } else { - Debug(1,"Success updating event"); + sleep(1); } db_mutex.unlock(); } @@ -338,11 +322,7 @@ bool Event::WriteFrameVideo( const Image *image, const struct timeval timestamp, Error("Failed encoding video frame"); } - /* Add the frame to the timecodes file */ - if ( timecodes_fd ) - fprintf(timecodes_fd, "%u\n", timeMS); - - return( true ); + return true; } void Event::updateNotes( const StringSetMap &newNoteSetMap ) { @@ -579,8 +559,9 @@ Debug(3, "Writing video"); id ); db_mutex.lock(); - if ( mysql_query( &dbconn, sql ) ) { + while ( mysql_query( &dbconn, sql ) ) { Error( "Can't update event: %s", mysql_error( &dbconn ) ); + sleep(1); } db_mutex.unlock(); }