Merge branch 'storageareas' of github.com:ZoneMinder/ZoneMinder into storageareas
This commit is contained in:
commit
b44cee4a81
|
@ -16,6 +16,11 @@ Build-Depends: debhelper (>= 9), python-sphinx | python3-sphinx, apache2-dev, dh
|
||||||
,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
|
||||||
|
|
|
@ -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) )
|
||||||
|
|
|
@ -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,15 +95,13 @@ 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},
|
||||||
|
@ -110,9 +109,7 @@ sub getEventPath
|
||||||
localtime($event->{Time})
|
localtime($event->{Time})
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$event_path = join('/',
|
$event_path = join('/',
|
||||||
$Storage->Path(),
|
$Storage->Path(),
|
||||||
$event->{MonitorId},
|
$event->{MonitorId},
|
||||||
|
@ -126,22 +123,19 @@ sub getEventPath
|
||||||
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"
|
||||||
);
|
);
|
||||||
|
@ -234,31 +215,31 @@ 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 )
|
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} )
|
if ( ! $Config{ZM_OPT_FAST_DELETE} ) {
|
||||||
{
|
|
||||||
my $sql = "delete from Frames where EventId = ?";
|
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();
|
||||||
|
|
||||||
$sql = "delete from Stats where EventId = ?";
|
$sql = "delete from Stats where EventId = ?";
|
||||||
$sth = $ZoneMinder::Database::dbh->prepare_cached( $sql )
|
$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() );
|
||||||
$res = $sth->execute( $event->{Id} )
|
$res = $sth->execute( $event->{Id} )
|
||||||
or Fatal( "Can't execute '$sql': ".$sth->errstr() );
|
or Fatal( "Can't execute '$sql': ".$sth->errstr() );
|
||||||
|
$sth->finish();
|
||||||
|
|
||||||
delete_files( $event );
|
$event->delete_files( );
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
Debug("Not deleting frames, stats and files for speed.");
|
Debug("Not deleting frames, stats and files for speed.");
|
||||||
}
|
}
|
||||||
} # end sub delete
|
} # end sub delete
|
||||||
|
@ -276,51 +257,46 @@ sub delete_files {
|
||||||
|
|
||||||
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.");
|
Debug("Deleting files for Event $_[0]{Id} from $storage_path.");
|
||||||
my $link_path = $_[0]{MonitorId}."/*/*/*/.".$_[0]{Id};
|
my $link_path = $_[0]{MonitorId}."/*/*/*/.".$_[0]{Id};
|
||||||
#Debug( "LP1:$link_path" );
|
#Debug( "LP1:$link_path" );
|
||||||
my @links = glob($link_path);
|
my @links = glob($link_path);
|
||||||
#Debug( "L:".$links[0].": $!" );
|
#Debug( "L:".$links[0].": $!" );
|
||||||
if ( @links )
|
if ( @links ) {
|
||||||
{
|
|
||||||
( $link_path ) = ( $links[0] =~ /^(.*)$/ ); # De-taint
|
( $link_path ) = ( $links[0] =~ /^(.*)$/ ); # De-taint
|
||||||
#Debug( "LP2:$link_path" );
|
#Debug( "LP2:$link_path" );
|
||||||
|
|
||||||
( my $day_path = $link_path ) =~ s/\.\d+//;
|
( my $day_path = $link_path ) =~ s/\.\d+//;
|
||||||
#Debug( "DP:$day_path" );
|
#Debug( "DP:$day_path" );
|
||||||
my $event_path = $day_path.readlink( $link_path );
|
my $event_path = $day_path.readlink( $link_path );
|
||||||
( $event_path ) = ( $event_path =~ /^(.*)$/ ); # De-taint
|
( $event_path ) = ( $event_path =~ /^(.*)$/ ); # De-taint
|
||||||
#Debug( "EP:$event_path" );
|
#Debug( "EP:$event_path" );
|
||||||
my $command = "/bin/rm -rf $event_path";
|
my $command = "/bin/rm -rf $event_path";
|
||||||
#Debug( "C:$command" );
|
#Debug( "C:$command" );
|
||||||
ZoneMinder::General::executeShellCommand( $command );
|
ZoneMinder::General::executeShellCommand( $command );
|
||||||
|
|
||||||
unlink( $link_path ) or Error( "Unable to unlink '$link_path': $!" );
|
unlink( $link_path ) or Error( "Unable to unlink '$link_path': $!" );
|
||||||
|
|
||||||
my @path_parts = split( /\//, $event_path );
|
my @path_parts = split( /\//, $event_path );
|
||||||
for ( my $i = int(@path_parts)-2; $i >= 1; $i-- )
|
for ( my $i = int(@path_parts)-2; $i >= 1; $i-- ) {
|
||||||
{
|
|
||||||
my $delete_path = join( '/', @path_parts[0..$i] );
|
my $delete_path = join( '/', @path_parts[0..$i] );
|
||||||
#Debug( "DP$i:$delete_path" );
|
#Debug( "DP$i:$delete_path" );
|
||||||
my @has_files = glob( join('/', $storage_path,$delete_path,'*' ) );
|
my @has_files = glob( join('/', $storage_path,$delete_path,'*' ) );
|
||||||
#Debug( "HF1:".$has_files[0] ) if ( @has_files );
|
#Debug( "HF1:".$has_files[0] ) if ( @has_files );
|
||||||
last if ( @has_files );
|
last if ( @has_files );
|
||||||
@has_files = glob( join('/', $storage_path, $delete_path, '.[0-9]*' ) );
|
@has_files = glob( join('/', $storage_path, $delete_path, '.[0-9]*' ) );
|
||||||
#Debug( "HF2:".$has_files[0] ) if ( @has_files );
|
#Debug( "HF2:".$has_files[0] ) if ( @has_files );
|
||||||
last if ( @has_files );
|
last if ( @has_files );
|
||||||
my $command = "/bin/rm -rf $storage_path/$delete_path";
|
my $command = "/bin/rm -rf $storage_path/$delete_path";
|
||||||
ZoneMinder::General::executeShellCommand( $command );
|
ZoneMinder::General::executeShellCommand( $command );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
my $command = "/bin/rm -rf $storage_path/$_[0]{MonitorId}/$_[0]{Id}";
|
my $command = "/bin/rm -rf $storage_path/$_[0]{MonitorId}/$_[0]{Id}";
|
||||||
ZoneMinder::General::executeShellCommand( $command );
|
ZoneMinder::General::executeShellCommand( $command );
|
||||||
}
|
}
|
||||||
|
|
|
@ -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" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 },
|
||||||
|
|
|
@ -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 },
|
||||||
|
|
Loading…
Reference in New Issue