Merge branch 'storageareas' of github.com:ZoneMinder/ZoneMinder into storageareas

This commit is contained in:
Isaac Connor 2016-05-11 09:16:20 -04:00
commit b44cee4a81
8 changed files with 142 additions and 145 deletions

View File

@ -5,17 +5,22 @@ Maintainer: Dmitry Smirnov <onlyjob@debian.org>
Uploaders: Vagrant Cascadian <vagrant@debian.org> Uploaders: Vagrant Cascadian <vagrant@debian.org>
Build-Depends: debhelper (>= 9), python-sphinx | python3-sphinx, apache2-dev, dh-linktree Build-Depends: debhelper (>= 9), python-sphinx | python3-sphinx, apache2-dev, dh-linktree
,cmake ,cmake
,libavcodec-dev, libavformat-dev (>= 3:0.svn20090204), libswscale-dev (>= 3:0.svn20090204), libavutil-dev, libavdevice-dev ,libavcodec-dev, libavformat-dev (>= 3:0.svn20090204), libswscale-dev (>= 3:0.svn20090204), libavutil-dev, libavdevice-dev
,libbz2-dev ,libbz2-dev
,libgcrypt-dev ,libgcrypt-dev
,libcurl4-gnutls-dev ,libcurl4-gnutls-dev
,libgnutls-openssl-dev ,libgnutls-openssl-dev
,libjpeg8-dev|libjpeg9-dev|libjpeg62-turbo-dev, ,libjpeg8-dev|libjpeg9-dev|libjpeg62-turbo-dev,
,libmysqlclient-dev ,libmysqlclient-dev
,libpcre3-dev ,libpcre3-dev
,libpolkit-gobject-1-dev ,libpolkit-gobject-1-dev
,libv4l-dev (>= 0.8.3) [!hurd-any] ,libv4l-dev (>= 0.8.3) [!hurd-any]
,libvlc-dev ,libvlc-dev
,libdate-manip-perl
,libdbd-mysql-perl
,libphp-serialization-perl
,libsys-mmap-perl [!hurd-any]
,libwww-perl
# Unbundled (dh_linktree): # Unbundled (dh_linktree):
,libjs-jquery ,libjs-jquery
,libjs-mootools ,libjs-mootools

View File

@ -78,8 +78,7 @@ sub zmDbConnect
{ {
zmDbDisconnect(); zmDbDisconnect();
} }
if ( !defined( $dbh ) ) if ( ( ! defined( $dbh ) ) or ! $dbh->ping() ) {
{
my ( $host, $port ) = ( $ZoneMinder::Config::Config{ZM_DB_HOST} =~ /^([^:]+)(?::(.+))?$/ ); my ( $host, $port ) = ( $ZoneMinder::Config::Config{ZM_DB_HOST} =~ /^([^:]+)(?::(.+))?$/ );
if ( defined($port) ) if ( defined($port) )

View File

@ -67,18 +67,18 @@ sub find {
my @sql_filters; my @sql_filters;
my @sql_values; my @sql_values;
if ( exists $sql_filters{Name} ) { if ( exists $sql_filters{Name} ) {
push @sql_filters , ' Name = ? '; push @sql_filters , ' Name = ? ';
push @sql_values, $sql_filters{Name}; push @sql_values, $sql_filters{Name};
} }
$sql .= ' WHERE ' . join(' AND ', @sql_filters ) if @sql_filters; $sql .= ' WHERE ' . join(' AND ', @sql_filters ) if @sql_filters;
$sql .= ' LIMIT ' . $sql_filters{limit} if $sql_filters{limit}; $sql .= ' LIMIT ' . $sql_filters{limit} if $sql_filters{limit};
my $sth = $ZoneMinder::Database::dbh->prepare_cached( $sql ) my $sth = $ZoneMinder::Database::dbh->prepare_cached( $sql )
or Fatal( "Can't prepare '$sql': ".$ZoneMinder::Database::dbh->errstr() ); or Fatal( "Can't prepare '$sql': ".$ZoneMinder::Database::dbh->errstr() );
my $res = $sth->execute( @sql_values ) my $res = $sth->execute( @sql_values )
or Fatal( "Can't execute '$sql': ".$sth->errstr() ); or Fatal( "Can't execute '$sql': ".$sth->errstr() );
my @results; my @results;
@ -86,6 +86,7 @@ sub find {
my $filter = new ZoneMinder::Event( $$db_filter{Id}, $db_filter ); my $filter = new ZoneMinder::Event( $$db_filter{Id}, $db_filter );
push @results, $filter; push @results, $filter;
} # end while } # end while
$sth->finish();
return @results; return @results;
} }
@ -94,54 +95,47 @@ sub find_one {
return $results[0] if @results; return $results[0] if @results;
} }
sub getEventPath sub getPath {
{ my $event = shift;
my $event = shift;
my $Storage = $event->Storage(); my $Storage = $event->Storage();
my $event_path = ""; my $event_path = "";
if ( $Config{ZM_USE_DEEP_STORAGE} ) if ( $Config{ZM_USE_DEEP_STORAGE} ) {
{ $event_path = join('/',
$event_path = join('/', $Storage->Path(),
$Storage->Path(), $event->{MonitorId},
$event->{MonitorId}, strftime( "%y/%m/%d/%H/%M/%S",
strftime( "%y/%m/%d/%H/%M/%S", localtime($event->{Time})
localtime($event->{Time}) ),
),
);
}
else
{
$event_path = join('/',
$Storage->Path(),
$event->{MonitorId},
$event->{Id},
); );
} } else {
$event_path = join('/',
$Storage->Path(),
$event->{MonitorId},
$event->{Id},
);
}
return( $event_path ); return( $event_path );
} }
sub GenerateVideo { sub GenerateVideo {
my ( $self, $rate, $fps, $scale, $size, $overwrite, $format ) = @_; my ( $self, $rate, $fps, $scale, $size, $overwrite, $format ) = @_;
my $event_path = getEventPath( $self ); my $event_path = $self->getPath( );
chdir( $event_path ); chdir( $event_path );
( my $video_name = $self->{Name} ) =~ s/\s/_/g; ( my $video_name = $self->{Name} ) =~ s/\s/_/g;
my @file_parts; my @file_parts;
if ( $rate ) if ( $rate ) {
{
my $file_rate = $rate; my $file_rate = $rate;
$file_rate =~ s/\./_/; $file_rate =~ s/\./_/;
$file_rate =~ s/_00//; $file_rate =~ s/_00//;
$file_rate =~ s/(_\d+)0+$/$1/; $file_rate =~ s/(_\d+)0+$/$1/;
$file_rate = 'r'.$file_rate; $file_rate = 'r'.$file_rate;
push( @file_parts, $file_rate ); push( @file_parts, $file_rate );
} } elsif ( $fps ) {
elsif ( $fps )
{
my $file_fps = $fps; my $file_fps = $fps;
$file_fps =~ s/\./_/; $file_fps =~ s/\./_/;
$file_fps =~ s/_00//; $file_fps =~ s/_00//;
@ -150,35 +144,27 @@ sub GenerateVideo {
push( @file_parts, $file_fps ); push( @file_parts, $file_fps );
} }
if ( $scale ) if ( $scale ) {
{
my $file_scale = $scale; my $file_scale = $scale;
$file_scale =~ s/\./_/; $file_scale =~ s/\./_/;
$file_scale =~ s/_00//; $file_scale =~ s/_00//;
$file_scale =~ s/(_\d+)0+$/$1/; $file_scale =~ s/(_\d+)0+$/$1/;
$file_scale = 's'.$file_scale; $file_scale = 's'.$file_scale;
push( @file_parts, $file_scale ); push( @file_parts, $file_scale );
} } elsif ( $size ) {
elsif ( $size )
{
my $file_size = 'S'.$size; my $file_size = 'S'.$size;
push( @file_parts, $file_size ); push( @file_parts, $file_size );
} }
my $video_file = "$video_name-".$file_parts[0]."-".$file_parts[1].".$format"; my $video_file = "$video_name-".$file_parts[0]."-".$file_parts[1].".$format";
if ( $overwrite || !-s $video_file ) if ( $overwrite || !-s $video_file ) {
{
Info( "Creating video file $video_file for event $self->{Id}\n" ); Info( "Creating video file $video_file for event $self->{Id}\n" );
my $frame_rate = sprintf( "%.2f", $self->{Frames}/$self->{FullLength} ); my $frame_rate = sprintf( "%.2f", $self->{Frames}/$self->{FullLength} );
if ( $rate ) if ( $rate ) {
{ if ( $rate != 1.0 ) {
if ( $rate != 1.0 )
{
$frame_rate *= $rate; $frame_rate *= $rate;
} }
} } elsif ( $fps ) {
elsif ( $fps )
{
$frame_rate = $fps; $frame_rate = $fps;
} }
@ -186,17 +172,13 @@ sub GenerateVideo {
my $height = $self->{MonitorHeight}; my $height = $self->{MonitorHeight};
my $video_size = " ${width}x${height}"; my $video_size = " ${width}x${height}";
if ( $scale ) if ( $scale ) {
{ if ( $scale != 1.0 ) {
if ( $scale != 1.0 )
{
$width = int($width*$scale); $width = int($width*$scale);
$height = int($height*$scale); $height = int($height*$scale);
$video_size = " ${width}x${height}"; $video_size = " ${width}x${height}";
} }
} } elsif ( $size ) {
elsif ( $size )
{
$video_size = $size; $video_size = $size;
} }
my $command = $Config{ZM_PATH_FFMPEG} my $command = $Config{ZM_PATH_FFMPEG}
@ -214,8 +196,7 @@ sub GenerateVideo {
my $output = qx($command); my $output = qx($command);
my $status = $? >> 8; my $status = $? >> 8;
if ( $status ) if ( $status ) {
{
Error( "Unable to generate video, check " Error( "Unable to generate video, check "
.$event_path."/ffmpeg.log for details" .$event_path."/ffmpeg.log for details"
); );
@ -232,98 +213,93 @@ sub GenerateVideo {
} # end sub GenerateVideo } # end sub GenerateVideo
sub delete { sub delete {
my $event = $_[0]; my $event = $_[0];
Info( "Deleting event $event->{Id} from Monitor $event->{MonitorId}\n" ); Info( "Deleting event $event->{Id} from Monitor $event->{MonitorId}\n" );
# Do it individually to avoid locking up the table for new events # Do it individually to avoid locking up the table for new events
my $sql = "delete from Events where Id = ?"; my $sql = "delete from Events where Id = ?";
my $sth = $ZoneMinder::Database::dbh->prepare_cached( $sql )
or Fatal( "Can't prepare '$sql': ".$ZoneMinder::Database::dbh->errstr() );
my $res = $sth->execute( $event->{Id} )
or Fatal( "Can't execute '$sql': ".$sth->errstr() );
$sth->finish();
if ( ! $Config{ZM_OPT_FAST_DELETE} ) {
my $sql = "delete from Frames where EventId = ?";
my $sth = $ZoneMinder::Database::dbh->prepare_cached( $sql ) my $sth = $ZoneMinder::Database::dbh->prepare_cached( $sql )
or Fatal( "Can't prepare '$sql': ".$ZoneMinder::Database::dbh->errstr() ); or Fatal( "Can't prepare '$sql': ".$ZoneMinder::Database::dbh->errstr() );
my $res = $sth->execute( $event->{Id} ) my $res = $sth->execute( $event->{Id} )
or Fatal( "Can't execute '$sql': ".$sth->errstr() ); or Fatal( "Can't execute '$sql': ".$sth->errstr() );
$sth->finish();
if ( ! $Config{ZM_OPT_FAST_DELETE} ) $sql = "delete from Stats where EventId = ?";
{ $sth = $ZoneMinder::Database::dbh->prepare_cached( $sql )
my $sql = "delete from Frames where EventId = ?"; or Fatal( "Can't prepare '$sql': ".$ZoneMinder::Database::dbh->errstr() );
my $sth = $ZoneMinder::Database::dbh->prepare_cached( $sql ) $res = $sth->execute( $event->{Id} )
or Fatal( "Can't prepare '$sql': ".$ZoneMinder::Database::dbh->errstr() ); or Fatal( "Can't execute '$sql': ".$sth->errstr() );
my $res = $sth->execute( $event->{Id} ) $sth->finish();
or Fatal( "Can't execute '$sql': ".$sth->errstr() );
$sql = "delete from Stats where EventId = ?"; $event->delete_files( );
$sth = $ZoneMinder::Database::dbh->prepare_cached( $sql ) } else {
or Fatal( "Can't prepare '$sql': ".$ZoneMinder::Database::dbh->errstr() ); Debug("Not deleting frames, stats and files for speed.");
$res = $sth->execute( $event->{Id} ) }
or Fatal( "Can't execute '$sql': ".$sth->errstr() );
delete_files( $event );
}
else
{
Debug("Not deleting frames, stats and files for speed.");
}
} # end sub delete } # end sub delete
sub delete_files { sub delete_files {
my $Storage = new ZoneMinder::Storage( $_[0]{StorageId} ); my $Storage = new ZoneMinder::Storage( $_[0]{StorageId} );
my $storage_path = $Storage->Path(); my $storage_path = $Storage->Path();
if ( ! $storage_path ) { if ( ! $storage_path ) {
Fatal("No storage path when deleting fileds for event $_[0]{Id} with storage id $_[0]{StorageId} "); Fatal("No storage path when deleting fileds for event $_[0]{Id} with storage id $_[0]{StorageId} ");
return; return;
} }
chdir ( $storage_path ); chdir ( $storage_path );
if ( $Config{ZM_USE_DEEP_STORAGE} ) if ( $Config{ZM_USE_DEEP_STORAGE} ) {
{ if ( ! $_[0]{MonitorId} ) {
if ( ! $_[0]{MonitorId} ) { Error("No monitor id assigned to event $_[0]{Id}");
Error("No monitor id assigned to event $_[0]{Id}"); return;
return;
}
Debug("Deleting files for Event $_[0]{Id} from $storage_path.");
my $link_path = $_[0]{MonitorId}."/*/*/*/.".$_[0]{Id};
#Debug( "LP1:$link_path" );
my @links = glob($link_path);
#Debug( "L:".$links[0].": $!" );
if ( @links )
{
( $link_path ) = ( $links[0] =~ /^(.*)$/ ); # De-taint
#Debug( "LP2:$link_path" );
( my $day_path = $link_path ) =~ s/\.\d+//;
#Debug( "DP:$day_path" );
my $event_path = $day_path.readlink( $link_path );
( $event_path ) = ( $event_path =~ /^(.*)$/ ); # De-taint
#Debug( "EP:$event_path" );
my $command = "/bin/rm -rf $event_path";
#Debug( "C:$command" );
ZoneMinder::General::executeShellCommand( $command );
unlink( $link_path ) or Error( "Unable to unlink '$link_path': $!" );
my @path_parts = split( /\//, $event_path );
for ( my $i = int(@path_parts)-2; $i >= 1; $i-- )
{
my $delete_path = join( '/', @path_parts[0..$i] );
#Debug( "DP$i:$delete_path" );
my @has_files = glob( join('/', $storage_path,$delete_path,'*' ) );
#Debug( "HF1:".$has_files[0] ) if ( @has_files );
last if ( @has_files );
@has_files = glob( join('/', $storage_path, $delete_path, '.[0-9]*' ) );
#Debug( "HF2:".$has_files[0] ) if ( @has_files );
last if ( @has_files );
my $command = "/bin/rm -rf $storage_path/$delete_path";
ZoneMinder::General::executeShellCommand( $command );
}
}
} }
else Debug("Deleting files for Event $_[0]{Id} from $storage_path.");
{ my $link_path = $_[0]{MonitorId}."/*/*/*/.".$_[0]{Id};
my $command = "/bin/rm -rf $storage_path/$_[0]{MonitorId}/$_[0]{Id}"; #Debug( "LP1:$link_path" );
my @links = glob($link_path);
#Debug( "L:".$links[0].": $!" );
if ( @links ) {
( $link_path ) = ( $links[0] =~ /^(.*)$/ ); # De-taint
#Debug( "LP2:$link_path" );
( my $day_path = $link_path ) =~ s/\.\d+//;
#Debug( "DP:$day_path" );
my $event_path = $day_path.readlink( $link_path );
( $event_path ) = ( $event_path =~ /^(.*)$/ ); # De-taint
#Debug( "EP:$event_path" );
my $command = "/bin/rm -rf $event_path";
#Debug( "C:$command" );
ZoneMinder::General::executeShellCommand( $command );
unlink( $link_path ) or Error( "Unable to unlink '$link_path': $!" );
my @path_parts = split( /\//, $event_path );
for ( my $i = int(@path_parts)-2; $i >= 1; $i-- ) {
my $delete_path = join( '/', @path_parts[0..$i] );
#Debug( "DP$i:$delete_path" );
my @has_files = glob( join('/', $storage_path,$delete_path,'*' ) );
#Debug( "HF1:".$has_files[0] ) if ( @has_files );
last if ( @has_files );
@has_files = glob( join('/', $storage_path, $delete_path, '.[0-9]*' ) );
#Debug( "HF2:".$has_files[0] ) if ( @has_files );
last if ( @has_files );
my $command = "/bin/rm -rf $storage_path/$delete_path";
ZoneMinder::General::executeShellCommand( $command ); ZoneMinder::General::executeShellCommand( $command );
}
} }
} else {
my $command = "/bin/rm -rf $storage_path/$_[0]{MonitorId}/$_[0]{Id}";
ZoneMinder::General::executeShellCommand( $command );
}
} # end sub delete_files } # end sub delete_files
sub Storage { sub Storage {

View File

@ -365,7 +365,7 @@ MAIN: while( $loop ) {
my $Event = new ZoneMinder::Event( $db_event ); my $Event = new ZoneMinder::Event( $db_event );
my $Storage = $Event->Storage(); my $Storage = $Event->Storage();
aud_print( "Database event '".$Storage->Path()."/$db_monitor/$db_event' does not exist in filesystem but too young to delete.\n" ); aud_print( "Database event '".$Event->getPath()."/$db_monitor/$db_event' does not exist in filesystem but too young to delete.\n" );
} }
} }
} }

View File

@ -15,7 +15,6 @@
#menuBar1 { #menuBar1 {
width: 100%; width: 100%;
height: 1.5em;
padding: 3px 0; padding: 3px 0;
text-align: center; text-align: center;
clear: both; clear: both;
@ -41,7 +40,6 @@
#menuBar2 { #menuBar2 {
width: 100%; width: 100%;
height: 1.2em;
padding: 3px 0; padding: 3px 0;
margin-bottom: 4px; margin-bottom: 4px;
} }
@ -57,6 +55,16 @@
text-align: right; text-align: right;
} }
#menuBar1:after,
#menuBar2:after {
content: ".";
display: block;
height: 0;
font-size: 0;
clear: both;
visibility: hidden;
}
#videoBar1 div { #videoBar1 div {
text-align: center; text-align: center;
float: center; float: center;

View File

@ -65,6 +65,15 @@
visibility: hidden; visibility: hidden;
} }
#menuBar1:after,
#menuBar2:after {
content: ".";
display: block;
height: 0;
font-size: 0;
clear: both;
visibility: hidden;
}
#imageFeed { #imageFeed {
text-align: center; text-align: center;
} }

View File

@ -38,7 +38,7 @@ var popupSizes = {
'events': { 'width': 960, 'height': 780 }, 'events': { 'width': 960, 'height': 780 },
'export': { 'width': 400, 'height': 340 }, 'export': { 'width': 400, 'height': 340 },
'filter': { 'width': 900, 'height': 600 }, 'filter': { 'width': 900, 'height': 600 },
'filtersave': { 'width': 610, 'height': 220 }, 'filtersave': { 'width': 610, 'height': 260 },
'frame': { 'addWidth': 32, 'minWidth': 384, 'addHeight': 100 }, 'frame': { 'addWidth': 32, 'minWidth': 384, 'addHeight': 100 },
'frames': { 'width': 500, 'height': 600 }, 'frames': { 'width': 500, 'height': 600 },
'function': { 'width': 300, 'height': 160 }, 'function': { 'width': 300, 'height': 160 },

View File

@ -38,7 +38,7 @@ var popupSizes = {
'events': { 'width': 1220, 'height': 780 }, 'events': { 'width': 1220, 'height': 780 },
'export': { 'width': 400, 'height': 340 }, 'export': { 'width': 400, 'height': 340 },
'filter': { 'width': 900, 'height': 600 }, 'filter': { 'width': 900, 'height': 600 },
'filtersave': { 'width': 610, 'height': 220 }, 'filtersave': { 'width': 610, 'height': 260 },
'frame': { 'addWidth': 32, 'minWidth': 384, 'addHeight': 100 }, 'frame': { 'addWidth': 32, 'minWidth': 384, 'addHeight': 100 },
'frames': { 'width': 500, 'height': 600 }, 'frames': { 'width': 500, 'height': 600 },
'function': { 'width': 300, 'height': 160 }, 'function': { 'width': 300, 'height': 160 },