diff --git a/scripts/ZoneMinder/lib/ZoneMinder/Filter.pm b/scripts/ZoneMinder/lib/ZoneMinder/Filter.pm index 545bfaaad..82deff6ff 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/Filter.pm +++ b/scripts/ZoneMinder/lib/ZoneMinder/Filter.pm @@ -125,7 +125,7 @@ sub Execute { push @results, $event; } $sth->finish(); - Debug("Loaded " . @results . " events for filter $_[0]{Name} using query ($sql)"); + Debug('Loaded ' . @results . " events for filter $_[0]{Name} using query ($sql)"); return @results; } @@ -147,38 +147,59 @@ sub Sql { foreach my $term ( @{$filter_expr->{terms}} ) { if ( exists($term->{cnj}) ) { - $self->{Sql} .= " ".$term->{cnj}." "; + $self->{Sql} .= ' '.$term->{cnj}." "; } if ( exists($term->{obr}) ) { - $self->{Sql} .= " ".str_repeat( "(", $term->{obr} )." "; + $self->{Sql} .= ' '.str_repeat( "(", $term->{obr} )." "; } my $value = $term->{val}; my @value_list; if ( $term->{attr} ) { if ( $term->{attr} =~ /^Monitor/ ) { my ( $temp_attr_name ) = $term->{attr} =~ /^Monitor(.+)$/; - $self->{Sql} .= "M.".$temp_attr_name; + $self->{Sql} .= 'M.'.$temp_attr_name; } elsif ( $term->{attr} =~ /^Server/ ) { - $self->{Sql} .= "M.".$term->{attr}; + $self->{Sql} .= 'M.'.$term->{attr}; + +# StartTime options } elsif ( $term->{attr} eq 'DateTime' ) { - $self->{Sql} .= "E.StartTime"; + $self->{Sql} .= 'E.StartTime'; + } elsif ( $term->{attr} eq 'StartDateTime' ) { + $self->{Sql} .= 'E.StartTime'; } elsif ( $term->{attr} eq 'Date' ) { - $self->{Sql} .= "to_days( E.StartTime )"; + $self->{Sql} .= 'to_days( E.StartTime )'; + } elsif ( $term->{attr} eq 'StartDate' ) { + $self->{Sql} .= 'to_days( E.StartTime )'; } elsif ( $term->{attr} eq 'Time' ) { $self->{Sql} .= "extract( hour_second from E.StartTime )"; } elsif ( $term->{attr} eq 'Weekday' ) { $self->{Sql} .= "weekday( E.StartTime )"; + +# EndTIme options + } elsif ( $term->{attr} eq 'EndDateTime' ) { + $self->{Sql} .= 'E.EndTime'; + } elsif ( $term->{attr} eq 'EndDate' ) { + $self->{Sql} .= 'to_days( E.EndTime )'; + } elsif ( $term->{attr} eq 'EndTime' ) { + $self->{Sql} .= "extract( hour_second from E.EndTime )"; + } elsif ( $term->{attr} eq 'EndWeekday' ) { + $self->{Sql} .= "weekday( E.EndTime )"; + +# + } elsif ( $term->{attr} eq 'DiskSpace' ) { + $self->{Sql} .= 'E.DiskSpace'; + $self->{HasDiskPercent} = !undef; } elsif ( $term->{attr} eq 'DiskPercent' ) { - $self->{Sql} .= "zmDiskPercent"; + $self->{Sql} .= 'zmDiskPercent'; $self->{HasDiskPercent} = !undef; } elsif ( $term->{attr} eq 'DiskBlocks' ) { - $self->{Sql} .= "zmDiskBlocks"; + $self->{Sql} .= 'zmDiskBlocks'; $self->{HasDiskBlocks} = !undef; } elsif ( $term->{attr} eq 'SystemLoad' ) { - $self->{Sql} .= "zmSystemLoad"; + $self->{Sql} .= 'zmSystemLoad'; $self->{HasSystemLoad} = !undef; } else { - $self->{Sql} .= "E.".$term->{attr}; + $self->{Sql} .= 'E.'.$term->{attr}; } ( my $stripped_value = $value ) =~ s/^["\']+?(.+)["\']+?$/$1/; @@ -243,11 +264,11 @@ sub Sql { } elsif ( $term->{op} eq '!~' ) { $self->{Sql} .= " not in (".join( ",", @value_list ).")"; } else { - $self->{Sql} .= " ".$term->{op}." $value"; + $self->{Sql} .= ' '.$term->{op}." $value"; } } # end if has an operator if ( exists($term->{cbr}) ) { - $self->{Sql} .= " ".str_repeat( ")", $term->{cbr} )." "; + $self->{Sql} .= ' '.str_repeat( ")", $term->{cbr} )." "; } } # end foreach term } # end if terms @@ -284,7 +305,7 @@ sub Sql { push @auto_terms, "E.Executed = 0"; } if ( @auto_terms ) { - $sql .= " and ( ".join( " or ", @auto_terms )." )"; + $sql .= " and ( ".join( ' or ', @auto_terms )." )"; } if ( !$filter_expr->{sort_field} ) { $filter_expr->{sort_field} = 'StartTime'; @@ -292,30 +313,34 @@ sub Sql { } my $sort_column = ''; if ( $filter_expr->{sort_field} eq 'Id' ) { - $sort_column = "E.Id"; + $sort_column = 'E.Id'; } elsif ( $filter_expr->{sort_field} eq 'MonitorName' ) { - $sort_column = "M.Name"; + $sort_column = 'M.Name'; } elsif ( $filter_expr->{sort_field} eq 'Name' ) { - $sort_column = "E.Name"; + $sort_column = 'E.Name'; } elsif ( $filter_expr->{sort_field} eq 'StartTime' ) { - $sort_column = "E.StartTime"; + $sort_column = 'E.StartTime'; + } elsif ( $filter_expr->{sort_field} eq 'EndTime' ) { + $sort_column = 'E.EndTime'; } elsif ( $filter_expr->{sort_field} eq 'Secs' ) { - $sort_column = "E.Length"; + $sort_column = 'E.Length'; } elsif ( $filter_expr->{sort_field} eq 'Frames' ) { - $sort_column = "E.Frames"; + $sort_column = 'E.Frames'; } elsif ( $filter_expr->{sort_field} eq 'AlarmFrames' ) { - $sort_column = "E.AlarmFrames"; + $sort_column = 'E.AlarmFrames'; } elsif ( $filter_expr->{sort_field} eq 'TotScore' ) { - $sort_column = "E.TotScore"; + $sort_column = 'E.TotScore'; } elsif ( $filter_expr->{sort_field} eq 'AvgScore' ) { - $sort_column = "E.AvgScore"; + $sort_column = 'E.AvgScore'; } elsif ( $filter_expr->{sort_field} eq 'MaxScore' ) { - $sort_column = "E.MaxScore"; + $sort_column = 'E.MaxScore'; + } elsif ( $filter_expr->{sort_field} eq 'DiskSpace' ) { + $sort_column = 'E.DiskSpace'; } else { - $sort_column = "E.StartTime"; + $sort_column = 'E.StartTime'; } - my $sort_order = $filter_expr->{sort_asc}?"asc":"desc"; - $sql .= " order by ".$sort_column." ".$sort_order; + my $sort_order = $filter_expr->{sort_asc}?'asc':'desc'; + $sql .= ' order by '.$sort_column." ".$sort_order; if ( $filter_expr->{limit} ) { $sql .= " limit 0,".$filter_expr->{limit}; } @@ -325,7 +350,7 @@ sub Sql { } # end sub Sql sub getDiskPercent { - my $command = "df " . ($_[0] ? $_[0] : '.'); + my $command = 'df ' . ($_[0] ? $_[0] : '.'); my $df = qx( $command ); my $space = -1; if ( $df =~ /\s(\d+)%/ms ) { @@ -335,7 +360,7 @@ sub getDiskPercent { } sub getDiskBlocks { - my $command = "df ."; + my $command = 'df .'; my $df = qx( $command ); my $space = -1; if ( $df =~ /\s(\d+)\s+\d+\s+\d+%/ms ) { @@ -345,7 +370,7 @@ sub getDiskBlocks { } sub getLoad { - my $command = "uptime ."; + my $command = 'uptime .'; my $uptime = qx( $command ); my $load = -1; if ( $uptime =~ /load average:\s+([\d.]+)/ms ) { diff --git a/scripts/zmfilter.pl.in b/scripts/zmfilter.pl.in index 0560fb0c0..fca5b3d7a 100644 --- a/scripts/zmfilter.pl.in +++ b/scripts/zmfilter.pl.in @@ -214,6 +214,7 @@ sub getFilters { or AutoMessage = 1 or AutoExecute = 1 or AutoDelete = 1 + or UpdateDiskSpace = 1 ) ORDER BY Name'; my $sth = $dbh->prepare_cached( $sql ) or Fatal( "Unable toprepare '$sql': ".$dbh->errstr() ); diff --git a/web/includes/Filter.php b/web/includes/Filter.php index 59988430d..11d47973a 100644 --- a/web/includes/Filter.php +++ b/web/includes/Filter.php @@ -12,6 +12,7 @@ public $defaults = array( 'AutoArchive' => 0, 'AutoVideo' => 0, 'AutoMessage' => 0, + 'UpdateDiskSpace' => 0, 'Background' => 0, 'Concurrent' => 0, 'limit' => 100, diff --git a/web/includes/actions.php b/web/includes/actions.php index 046b7bbf2..cbadae3f6 100644 --- a/web/includes/actions.php +++ b/web/includes/actions.php @@ -148,6 +148,7 @@ Warning("Addterm"); $sql .= ', AutoExecute = '. ( !empty($_REQUEST['filter']['AutoExecute']) ? 1 : 0); $sql .= ', AutoExecuteCmd = '.dbEscape($_REQUEST['filter']['AutoExecuteCmd']); $sql .= ', AutoDelete = '. ( !empty($_REQUEST['filter']['AutoDelete']) ? 1 : 0); + $sql .= ', UpdateDiskSpace = '. ( !empty($_REQUEST['filter']['UpdateDiskSpace']) ? 1 : 0); $sql .= ', Background = '. ( !empty($_REQUEST['filter']['Background']) ? 1 : 0); $sql .= ', Concurrent = '. ( !empty($_REQUEST['filter']['Concurrent']) ? 1 : 0); diff --git a/web/includes/functions.php b/web/includes/functions.php index de42333bf..ab0e1c898 100644 --- a/web/includes/functions.php +++ b/web/includes/functions.php @@ -1057,10 +1057,17 @@ function parseSort( $saveToSession=false, $querySep='&' ) { $sortColumn = 'E.Cause'; break; case 'DateTime' : - $_REQUEST['sort_field'] = 'StartTime'; + $sortColumn = 'E.StartTime'; + break; + case 'DiskSpace' : + $sortColumn = 'E.DiskSpace'; + break; case 'StartTime' : $sortColumn = 'E.StartTime'; break; + case 'EndTime' : + $sortColumn = 'E.EndTime'; + break; case 'Length' : $sortColumn = 'E.Length'; break; @@ -1126,6 +1133,7 @@ function parseFilter( &$filter, $saveToSession=false, $querySep='&' ) { case 'ServerId': $filter['sql'] .= 'M.ServerId'; break; +# Unspecified start or end, so assume start, this is to support legacy filters case 'DateTime': $filter['sql'] .= 'E.StartTime'; break; @@ -1138,8 +1146,35 @@ function parseFilter( &$filter, $saveToSession=false, $querySep='&' ) { case 'Weekday': $filter['sql'] .= 'weekday( E.StartTime )'; break; +# Starting Time + case 'StartDateTime': + $filter['sql'] .= 'E.StartTime'; + break; + case 'StartDate': + $filter['sql'] .= 'to_days( E.StartTime )'; + break; + case 'StartTime': + $filter['sql'] .= 'extract( hour_second from E.StartTime )'; + break; + case 'StartWeekday': + $filter['sql'] .= 'weekday( E.StartTime )'; + break; +# Ending Time + case 'EndDateTime': + $filter['sql'] .= 'E.EndTime'; + break; + case 'EndDate': + $filter['sql'] .= 'to_days( E.EndTime )'; + break; + case 'EndTime': + $filter['sql'] .= 'extract( hour_second from E.EndTime )'; + break; + case 'EndWeekday': + $filter['sql'] .= 'weekday( E.EndTime )'; + break; case 'Id': case 'Name': + case 'DiskSpace': case 'MonitorId': case 'StorageId': case 'Length': @@ -1853,7 +1888,8 @@ function logState() { Logger::WARNING => array( ZM_LOG_ALERT_WAR_COUNT, ZM_LOG_ALARM_WAR_COUNT ), ); - $sql = "select Level, count(Level) as LevelCount from Logs where Level < ".Logger::INFO." and TimeKey > unix_timestamp(now() - interval ".ZM_LOG_CHECK_PERIOD." second) group by Level order by Level asc"; + # This is an expensive request, as it has to hit every row of the Logs Table + $sql = 'SELECT Level, COUNT(Level) AS LevelCount FROM Logs WHERE Level < '.Logger::INFO.' AND TimeKey > unix_timestamp(now() - interval '.ZM_LOG_CHECK_PERIOD.' second) GROUP BY Level ORDER BY Level ASC'; $counts = dbFetchAll( $sql ); foreach ( $counts as $count ) { diff --git a/web/lang/en_gb.php b/web/lang/en_gb.php index 8783f1ed8..59b5b8ba3 100644 --- a/web/lang/en_gb.php +++ b/web/lang/en_gb.php @@ -116,8 +116,11 @@ $SLANG = array( 'AttrArchiveStatus' => 'Archive Status', 'AttrAvgScore' => 'Avg. Score', 'AttrCause' => 'Cause', - 'AttrDate' => 'Date', - 'AttrDateTime' => 'Date/Time', + 'AttrStartDate' => 'Start Date', + 'AttrEndDate' => 'End Date', + 'AttrStartDateTime' => 'Start Date/Time', + 'AttrEndDateTime' => 'End Date/Time', + 'AttrDiskSpace' => 'Disk Space', 'AttrDiskBlocks' => 'Disk Blocks', 'AttrDiskPercent' => 'Disk Percent', 'AttrDuration' => 'Duration', @@ -132,9 +135,11 @@ $SLANG = array( 'AttrName' => 'Name', 'AttrNotes' => 'Notes', 'AttrSystemLoad' => 'System Load', - 'AttrTime' => 'Time', + 'AttrStartTime' => 'Start Time', + 'AttrEndTime' => 'End Time', 'AttrTotalScore' => 'Total Score', - 'AttrWeekday' => 'Weekday', + 'AttrStartWeekday' => 'Start Weekday', + 'AttrEndWeekday' => 'End Weekday', 'Auto' => 'Auto', 'AutoStopTimeout' => 'Auto Stop Timeout', 'Available' => 'Available', @@ -334,6 +339,7 @@ $SLANG = array( 'Ffmpeg' => 'Ffmpeg', 'File' => 'File', 'FilterArchiveEvents' => 'Archive all matches', + 'FilterUpdateDiskSpace' => 'Update used disk space', 'FilterDeleteEvents' => 'Delete all matches', 'FilterEmailEvents' => 'Email details of all matches', 'FilterExecuteEvents' => 'Execute command on all matches', @@ -413,6 +419,7 @@ $SLANG = array( 'LimitResultsPre' => 'Limit to first', // This is used at the beginning of the phrase 'Limit to first N results only' 'LinkedMonitors' => 'Linked Monitors', 'List' => 'List', + 'ListMatches' => 'List Matches', 'Load' => 'Load', 'Local' => 'Local', 'Log' => 'Log', diff --git a/web/skins/classic/includes/functions.php b/web/skins/classic/includes/functions.php index 9cae836ce..26cb1a26e 100644 --- a/web/skins/classic/includes/functions.php +++ b/web/skins/classic/includes/functions.php @@ -194,9 +194,19 @@ ZoneMinder requires Javascript. Please enable Javascript in your browser for thi
+ UpdateDiskSpace()) ? '' : ' checked="checked"' ?> onclick="updateButtons(this);"/> +
@@ -387,7 +396,7 @@ if ( ZM_OPT_MESSAGE ) {