From 277fdafa85eebd2f9dde0c92ba659c578787040b Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 24 May 2016 16:45:55 -0400 Subject: [PATCH 1/7] Remove entry for Server Name, making Server Id just say Server. The filters will be populated with a dropdown, so no need to go by Id or Name --- web/lang/en_gb.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/web/lang/en_gb.php b/web/lang/en_gb.php index d559a567a..1d4025a68 100644 --- a/web/lang/en_gb.php +++ b/web/lang/en_gb.php @@ -125,8 +125,7 @@ $SLANG = array( 'AttrMaxScore' => 'Max. Score', 'AttrMonitorId' => 'Monitor Id', 'AttrMonitorName' => 'Monitor Name', - 'AttrServerId' => 'Server Id', - 'AttrServerName' => 'Server Name', + 'AttrServerId' => 'Server', 'AttrName' => 'Name', 'AttrNotes' => 'Notes', 'AttrSystemLoad' => 'System Load', From 7cfa2a5eaafc61ec03fe52e7f9ccb0d01b3a6377 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 24 May 2016 16:46:34 -0400 Subject: [PATCH 2/7] Replace the server attribute with a server entry, populated with a dropdown.Makes things more friendly and less error-prone --- web/skins/classic/views/filter.php | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/web/skins/classic/views/filter.php b/web/skins/classic/views/filter.php index 870d873df..9c05e2809 100644 --- a/web/skins/classic/views/filter.php +++ b/web/skins/classic/views/filter.php @@ -85,7 +85,6 @@ $attrTypes = array( 'DiskBlocks' => translate('AttrDiskBlocks'), 'SystemLoad' => translate('AttrSystemLoad'), 'ServerId' => translate('AttrServerId'), - 'ServerName' => translate('AttrServerName'), ); $opTypes = array( '=' => translate('OpEq'), @@ -226,6 +225,18 @@ for ( $i = 0; isset($_REQUEST['filter']) && $i < count($_REQUEST['filter']['term ?> + + + Date: Tue, 24 May 2016 16:49:04 -0400 Subject: [PATCH 3/7] whitespace, google code style. Adds special cases for ServerId Attribute. ANd uses * to load all event fields instead of specifying each one. --- scripts/ZoneMinder/lib/ZoneMinder/Filter.pm | 660 +++++++++----------- 1 file changed, 306 insertions(+), 354 deletions(-) diff --git a/scripts/ZoneMinder/lib/ZoneMinder/Filter.pm b/scripts/ZoneMinder/lib/ZoneMinder/Filter.pm index b7806ec4a..e15533727 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/Filter.pm +++ b/scripts/ZoneMinder/lib/ZoneMinder/Filter.pm @@ -43,8 +43,8 @@ our @ISA = qw(Exporter ZoneMinder::Base); # will save memory. our %EXPORT_TAGS = ( 'functions' => [ qw( - ) ] -); + ) ] + ); push( @{$EXPORT_TAGS{all}}, @{$EXPORT_TAGS{$_}} ) foreach keys %EXPORT_TAGS; our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); @@ -66,410 +66,362 @@ use ZoneMinder::Database qw(:all); use POSIX; sub new { - my ( $parent, $id, $data ) = @_; + my ( $parent, $id, $data ) = @_; - my $self = {}; - bless $self, $parent; - $$self{dbh} = $ZoneMinder::Database::dbh; + my $self = {}; + bless $self, $parent; + $$self{dbh} = $ZoneMinder::Database::dbh; #zmDbConnect(); - if ( ( $$self{Id} = $id ) or $data ) { + if ( ( $$self{Id} = $id ) or $data ) { #$log->debug("loading $parent $id") if $debug or DEBUG_ALL; - $self->load( $data ); - } - return $self; + $self->load( $data ); + } + return $self; } # end sub new sub load { - my ( $self, $data ) = @_; - my $type = ref $self; - if ( ! $data ) { + my ( $self, $data ) = @_; + my $type = ref $self; + if ( ! $data ) { #$log->debug("Object::load Loading from db $type"); - $data = $$self{dbh}->selectrow_hashref( 'SELECT * FROM Filter WHERE Id=?', {}, $$self{Id} ); - if ( ! $data ) { - Error( "Failure to load Filter record for $$self{Id}: Reason: " . $$self{dbh}->errstr ); - } else { - Debug( 3, "Loaded Filter $$self{Id}" ); - } # end if - } # end if ! $data - if ( $data and %$data ) { - @$self{keys %$data} = values %$data; - } # end if + $data = $$self{dbh}->selectrow_hashref( 'SELECT * FROM Filter WHERE Id=?', {}, $$self{Id} ); + if ( ! $data ) { + Error( "Failure to load Filter record for $$self{Id}: Reason: " . $$self{dbh}->errstr ); + } else { + Debug( 3, "Loaded Filter $$self{Id}" ); + } # end if + } # end if ! $data + if ( $data and %$data ) { + @$self{keys %$data} = values %$data; + } # end if } # end sub load sub Name { - if ( @_ > 1 ) { - $_[0]{Name} = $_[1]; - } - return $_[0]{Name}; + if ( @_ > 1 ) { + $_[0]{Name} = $_[1]; + } + return $_[0]{Name}; } # end sub Path sub find { - shift if $_[0] eq 'ZoneMinder::Filter'; - my %sql_filters = @_; + shift if $_[0] eq 'ZoneMinder::Filter'; + my %sql_filters = @_; - my $sql = 'SELECT * FROM Filters'; - my @sql_filters; - my @sql_values; + my $sql = 'SELECT * FROM Filters'; + my @sql_filters; + my @sql_values; - if ( exists $sql_filters{Name} ) { - push @sql_filters , ' Name = ? '; - push @sql_values, $sql_filters{Name}; - } + if ( exists $sql_filters{Name} ) { + push @sql_filters , ' Name = ? '; + push @sql_values, $sql_filters{Name}; + } - $sql .= ' WHERE ' . join(' AND ', @sql_filters ) if @sql_filters; - $sql .= ' LIMIT ' . $sql_filters{limit} if $sql_filters{limit}; + $sql .= ' WHERE ' . join(' AND ', @sql_filters ) if @sql_filters; + $sql .= ' LIMIT ' . $sql_filters{limit} if $sql_filters{limit}; - my $sth = $ZoneMinder::Database::dbh->prepare_cached( $sql ) - or Fatal( "Can't prepare '$sql': ".$ZoneMinder::Database::dbh->errstr() ); - my $res = $sth->execute( @sql_values ) - or Fatal( "Can't execute '$sql': ".$sth->errstr() ); + my $sth = $ZoneMinder::Database::dbh->prepare_cached( $sql ) + or Fatal( "Can't prepare '$sql': ".$ZoneMinder::Database::dbh->errstr() ); + my $res = $sth->execute( @sql_values ) + or Fatal( "Can't execute '$sql': ".$sth->errstr() ); - my @results; + my @results; - while( my $db_filter = $sth->fetchrow_hashref() ) { - my $filter = new ZoneMinder::Filter( $$db_filter{Id}, $db_filter ); - push @results, $filter; - } # end while - return @results; + while( my $db_filter = $sth->fetchrow_hashref() ) { + my $filter = new ZoneMinder::Filter( $$db_filter{Id}, $db_filter ); + push @results, $filter; + } # end while + $sth->finish(); + + return @results; } sub find_one { - my @results = find(@_); - return $results[0] if @results; + my @results = find(@_); + return $results[0] if @results; } sub Execute { - my $self = $_[0]; + my $self = $_[0]; - my $sql = $self->Sql(); + my $sql = $self->Sql(); - if ( $self->{HasDiskPercent} ) - { - my $disk_percent = getDiskPercent(); - $sql =~ s/zmDiskPercent/$disk_percent/g; - } - if ( $self->{HasDiskBlocks} ) - { - my $disk_blocks = getDiskBlocks(); - $sql =~ s/zmDiskBlocks/$disk_blocks/g; - } - if ( $self->{HasSystemLoad} ) - { - my $load = getLoad(); - $sql =~ s/zmSystemLoad/$load/g; - } + if ( $self->{HasDiskPercent} ) { + my $disk_percent = getDiskPercent(); + $sql =~ s/zmDiskPercent/$disk_percent/g; + } + if ( $self->{HasDiskBlocks} ) { + my $disk_blocks = getDiskBlocks(); + $sql =~ s/zmDiskBlocks/$disk_blocks/g; + } + if ( $self->{HasSystemLoad} ) { + my $load = getLoad(); + $sql =~ s/zmSystemLoad/$load/g; + } - my $sth = $$self{dbh}->prepare_cached( $sql ) - or Fatal( "Can't prepare '$sql': ".$$self{dbh}->errstr() ); - my $res = $sth->execute(); - if ( !$res ) - { - Error( "Can't execute filter '$sql', ignoring: ".$sth->errstr() ); - return; - } - my @results; + my $sth = $$self{dbh}->prepare_cached( $sql ) + or Fatal( "Can't prepare '$sql': ".$$self{dbh}->errstr() ); + my $res = $sth->execute(); + if ( !$res ) { + Error( "Can't execute filter '$sql', ignoring: ".$sth->errstr() ); + return; + } + my @results; - while( my $event = $sth->fetchrow_hashref() ) { - push @results, $event; - } - $sth->finish(); - return @results; + while( my $event = $sth->fetchrow_hashref() ) { + push @results, $event; + } + $sth->finish(); + return @results; } sub Sql { - my $self = $_[0]; - if ( ! $$self{Sql} ) { - my $filter_expr = ZoneMinder::General::jsonDecode( $self->{Query} ); - my $sql = "SELECT E.Id, - E.MonitorId, - M.Name as MonitorName, - M.DefaultRate, - M.DefaultScale, - E.Name, - E.Cause, - E.Notes, - E.StartTime, - unix_timestamp(E.StartTime) as Time, - E.Length, - E.Frames, - E.AlarmFrames, - E.TotScore, - E.AvgScore, - E.MaxScore, - E.Archived, - E.Videoed, - E.Uploaded, - E.Emailed, - E.Messaged, - E.Executed - FROM Events as E - INNER JOIN Monitors as M on M.Id = E.MonitorId - "; - $self->{Sql} = ''; + my $self = $_[0]; + if ( ! $$self{Sql} ) { + my $filter_expr = ZoneMinder::General::jsonDecode( $self->{Query} ); + my $sql = "SELECT E.*, + unix_timestamp(E.StartTime) as Time, + M.Name as MonitorName, + M.DefaultRate, + M.DefaultScale, + FROM Events as E + INNER JOIN Monitors as M on M.Id = E.MonitorId + "; + $self->{Sql} = ''; - if ( $filter_expr->{terms} ) { - for ( my $i = 0; $i < @{$filter_expr->{terms}}; $i++ ) { - if ( exists($filter_expr->{terms}[$i]->{cnj}) ) { - $self->{Sql} .= " ".$filter_expr->{terms}[$i]->{cnj}." "; - } - if ( exists($filter_expr->{terms}[$i]->{obr}) ) { - $self->{Sql} .= " ".str_repeat( "(", $filter_expr->{terms}[$i]->{obr} )." "; - } - my $value = $filter_expr->{terms}[$i]->{val}; - my @value_list; - if ( $filter_expr->{terms}[$i]->{attr} ) { - if ( $filter_expr->{terms}[$i]->{attr} =~ /^Monitor/ ) { - my ( $temp_attr_name ) = $filter_expr->{terms}[$i]->{attr} =~ /^Monitor(.+)$/; - $self->{Sql} .= "M.".$temp_attr_name; - } elsif ( $filter_expr->{terms}[$i]->{attr} eq 'DateTime' ) { - $self->{Sql} .= "E.StartTime"; - } elsif ( $filter_expr->{terms}[$i]->{attr} eq 'Date' ) { - $self->{Sql} .= "to_days( E.StartTime )"; - } elsif ( $filter_expr->{terms}[$i]->{attr} eq 'Time' ) { - $self->{Sql} .= "extract( hour_second from E.StartTime )"; - } elsif ( $filter_expr->{terms}[$i]->{attr} eq 'Weekday' ) { - $self->{Sql} .= "weekday( E.StartTime )"; - } elsif ( $filter_expr->{terms}[$i]->{attr} eq 'DiskPercent' ) { - $self->{Sql} .= "zmDiskPercent"; - $self->{HasDiskPercent} = !undef; - } elsif ( $filter_expr->{terms}[$i]->{attr} eq 'DiskBlocks' ) { - $self->{Sql} .= "zmDiskBlocks"; - $self->{HasDiskBlocks} = !undef; - } elsif ( $filter_expr->{terms}[$i]->{attr} eq 'SystemLoad' ) { - $self->{Sql} .= "zmSystemLoad"; - $self->{HasSystemLoad} = !undef; - } else { - $self->{Sql} .= "E.".$filter_expr->{terms}[$i]->{attr}; - } + if ( $filter_expr->{terms} ) { + foreach my $term ( @{$filter_expr->{terms}} ) { - ( my $stripped_value = $value ) =~ s/^["\']+?(.+)["\']+?$/$1/; - foreach my $temp_value ( split( /["'\s]*?,["'\s]*?/, $stripped_value ) ) { - if ( $filter_expr->{terms}[$i]->{attr} =~ /^Monitor/ ) { - $value = "'$temp_value'"; - } elsif ( $filter_expr->{terms}[$i]->{attr} eq 'Name' - || $filter_expr->{terms}[$i]->{attr} eq 'Cause' - || $filter_expr->{terms}[$i]->{attr} eq 'Notes' - ) { - $value = "'$temp_value'"; - } elsif ( $filter_expr->{terms}[$i]->{attr} eq 'DateTime' ) { - $value = DateTimeToSQL( $temp_value ); - if ( !$value ) { - Error( "Error parsing date/time '$temp_value', " - ."skipping filter '$self->{Name}'\n" ); - return; - } - $value = "'$value'"; - } elsif ( $filter_expr->{terms}[$i]->{attr} eq 'Date' ) { - $value = DateTimeToSQL( $temp_value ); - if ( !$value ) { - Error( "Error parsing date/time '$temp_value', " - ."skipping filter '$self->{Name}'\n" ); - return; - } - $value = "to_days( '$value' )"; - } elsif ( $filter_expr->{terms}[$i]->{attr} eq 'Time' ) { - $value = DateTimeToSQL( $temp_value ); - if ( !$value ) { - Error( "Error parsing date/time '$temp_value', " - ."skipping filter '$self->{Name}'\n" ); - return; - } - $value = "extract( hour_second from '$value' )"; - } else { - $value = $temp_value; - } - push( @value_list, $value ); - } # end foreach temp_value - } # end if has an attr - if ( $filter_expr->{terms}[$i]->{op} ) { - if ( $filter_expr->{terms}[$i]->{op} eq '=~' ) { - $self->{Sql} .= " regexp $value"; - } elsif ( $filter_expr->{terms}[$i]->{op} eq '!~' ) { - $self->{Sql} .= " not regexp $value"; - } elsif ( $filter_expr->{terms}[$i]->{op} eq '=[]' ) { - $self->{Sql} .= " in (".join( ",", @value_list ).")"; - } elsif ( $filter_expr->{terms}[$i]->{op} eq '!~' ) { - $self->{Sql} .= " not in (".join( ",", @value_list ).")"; - } else { - $self->{Sql} .= " ".$filter_expr->{terms}[$i]->{op}." $value"; - } - } # end if has an operator - if ( exists($filter_expr->{terms}[$i]->{cbr}) ) { - $self->{Sql} .= " ".str_repeat( ")", $filter_expr->{terms}[$i]->{cbr} )." "; - } - } # end foreach term - } # end if terms + if ( exists($term->{cnj}) ) { + $self->{Sql} .= " ".$term->{cnj}." "; + } + if ( exists($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; + } elsif ( $term->{attr} =~ /^Server/ ) { + $self->{Sql} .= "M.".$term->{attr}; + } elsif ( $term->{attr} eq 'DateTime' ) { + $self->{Sql} .= "E.StartTime"; + } elsif ( $term->{attr} eq 'Date' ) { + $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 )"; + } elsif ( $term->{attr} eq 'DiskPercent' ) { + $self->{Sql} .= "zmDiskPercent"; + $self->{HasDiskPercent} = !undef; + } elsif ( $term->{attr} eq 'DiskBlocks' ) { + $self->{Sql} .= "zmDiskBlocks"; + $self->{HasDiskBlocks} = !undef; + } elsif ( $term->{attr} eq 'SystemLoad' ) { + $self->{Sql} .= "zmSystemLoad"; + $self->{HasSystemLoad} = !undef; + } else { + $self->{Sql} .= "E.".$term->{attr}; + } - if ( $self->{Sql} ) - { - if ( $self->{AutoMessage} ) - { - # Include all events, including events that are still ongoing - # and have no EndTime yet - $sql .= " and ( ".$self->{Sql}." )"; - } - else - { - # Only include closed events (events with valid EndTime) - $sql .= " where not isnull(E.EndTime) and ( ".$self->{Sql}." )"; + ( my $stripped_value = $value ) =~ s/^["\']+?(.+)["\']+?$/$1/; + foreach my $temp_value ( split( /["'\s]*?,["'\s]*?/, $stripped_value ) ) { + if ( $term->{attr} =~ /^Monitor/ ) { + $value = "'$temp_value'"; + } elsif ( $term->{attr} eq 'ServerId' ) { + if ( $temp_value eq 'ZM_SERVER_ID' ) { + $value = "'$Config{ZM_SERVER_ID}'"; + # This gets used later, I forget for what + $$self{Server} = new ZoneMinder::Server( $Config{ZM_SERVER_ID} ); + } else { + $value = "'$temp_value'"; + # This gets used later, I forget for what + $$self{Server} = new ZoneMinder::Server( $temp_value ); + } + } elsif ( $term->{attr} eq 'Name' + || $term->{attr} eq 'Cause' + || $term->{attr} eq 'Notes' + ) { + $value = "'$temp_value'"; + } elsif ( $term->{attr} eq 'DateTime' ) { + $value = DateTimeToSQL( $temp_value ); + if ( !$value ) { + Error( "Error parsing date/time '$temp_value', " + ."skipping filter '$self->{Name}'\n" ); + return; + } + $value = "'$value'"; + } elsif ( $term->{attr} eq 'Date' ) { + $value = DateTimeToSQL( $temp_value ); + if ( !$value ) { + Error( "Error parsing date/time '$temp_value', " + ."skipping filter '$self->{Name}'\n" ); + return; + } + $value = "to_days( '$value' )"; + } elsif ( $term->{attr} eq 'Time' ) { + $value = DateTimeToSQL( $temp_value ); + if ( !$value ) { + Error( "Error parsing date/time '$temp_value', " + ."skipping filter '$self->{Name}'\n" ); + return; + } + $value = "extract( hour_second from '$value' )"; + } else { + $value = $temp_value; } + push( @value_list, $value ); + } # end foreach temp_value + } # end if has an attr + if ( $term->{op} ) { + if ( $term->{op} eq '=~' ) { + $self->{Sql} .= " regexp $value"; + } elsif ( $term->{op} eq '!~' ) { + $self->{Sql} .= " not regexp $value"; + } elsif ( $term->{op} eq '=[]' ) { + $self->{Sql} .= " in (".join( ",", @value_list ).")"; + } elsif ( $term->{op} eq '!~' ) { + $self->{Sql} .= " not in (".join( ",", @value_list ).")"; + } else { + $self->{Sql} .= " ".$term->{op}." $value"; + } + } # end if has an operator + if ( exists($term->{cbr}) ) { + $self->{Sql} .= " ".str_repeat( ")", $terms->{cbr} )." "; } - my @auto_terms; - if ( $self->{AutoArchive} ) - { - push( @auto_terms, "E.Archived = 0" ) - } - if ( $self->{AutoVideo} ) - { - push( @auto_terms, "E.Videoed = 0" ) - } - if ( $self->{AutoUpload} ) - { - push( @auto_terms, "E.Uploaded = 0" ) - } - if ( $self->{AutoEmail} ) - { - push( @auto_terms, "E.Emailed = 0" ) - } - if ( $self->{AutoMessage} ) - { - push( @auto_terms, "E.Messaged = 0" ) - } - if ( $self->{AutoExecute} ) - { - push( @auto_terms, "E.Executed = 0" ) - } - if ( @auto_terms ) - { - $sql .= " and ( ".join( " or ", @auto_terms )." )"; - } - if ( !$filter_expr->{sort_field} ) - { - $filter_expr->{sort_field} = 'StartTime'; - $filter_expr->{sort_asc} = 0; - } - my $sort_column = ''; - if ( $filter_expr->{sort_field} eq 'Id' ) - { - $sort_column = "E.Id"; - } - elsif ( $filter_expr->{sort_field} eq 'MonitorName' ) - { - $sort_column = "M.Name"; - } - elsif ( $filter_expr->{sort_field} eq 'Name' ) - { - $sort_column = "E.Name"; - } - elsif ( $filter_expr->{sort_field} eq 'StartTime' ) - { - $sort_column = "E.StartTime"; - } - elsif ( $filter_expr->{sort_field} eq 'Secs' ) - { - $sort_column = "E.Length"; - } - elsif ( $filter_expr->{sort_field} eq 'Frames' ) - { - $sort_column = "E.Frames"; - } - elsif ( $filter_expr->{sort_field} eq 'AlarmFrames' ) - { - $sort_column = "E.AlarmFrames"; - } - elsif ( $filter_expr->{sort_field} eq 'TotScore' ) - { - $sort_column = "E.TotScore"; - } - elsif ( $filter_expr->{sort_field} eq 'AvgScore' ) - { - $sort_column = "E.AvgScore"; - } - elsif ( $filter_expr->{sort_field} eq 'MaxScore' ) - { - $sort_column = "E.MaxScore"; - } - else - { - $sort_column = "E.StartTime"; - } - 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}; - } - Debug( "SQL:$sql\n" ); - $self->{Sql} = $sql; - } # end if has Sql - return $self->{Sql}; + } # end foreach term + } # end if terms + + if ( $self->{Sql} ) { + if ( $self->{AutoMessage} ) { +# Include all events, including events that are still ongoing +# and have no EndTime yet + $sql .= " and ( ".$self->{Sql}." )"; + } else { +# Only include closed events (events with valid EndTime) + $sql .= " where not isnull(E.EndTime) and ( ".$self->{Sql}." )"; + } + } + my @auto_terms; + if ( $self->{AutoArchive} ) { + push @auto_terms, "E.Archived = 0"; + } + if ( $self->{AutoVideo} ) { + push @auto_terms, "E.Videoed = 0"; + } + if ( $self->{AutoUpload} ) { + push @auto_terms, "E.Uploaded = 0"; + } + if ( $self->{AutoEmail} ) { + push @auto_terms, "E.Emailed = 0"; + } + if ( $self->{AutoMessage} ) { + push @auto_terms, "E.Messaged = 0"; + } + if ( $self->{AutoExecute} ) { + push @auto_terms, "E.Executed = 0"; + } + if ( @auto_terms ) { + $sql .= " and ( ".join( " or ", @auto_terms )." )"; + } + if ( !$filter_expr->{sort_field} ) { + $filter_expr->{sort_field} = 'StartTime'; + $filter_expr->{sort_asc} = 0; + } + my $sort_column = ''; + if ( $filter_expr->{sort_field} eq 'Id' ) { + $sort_column = "E.Id"; + } elsif ( $filter_expr->{sort_field} eq 'MonitorName' ) { + $sort_column = "M.Name"; + } elsif ( $filter_expr->{sort_field} eq 'Name' ) { + $sort_column = "E.Name"; + } elsif ( $filter_expr->{sort_field} eq 'StartTime' ) { + $sort_column = "E.StartTime"; + } elsif ( $filter_expr->{sort_field} eq 'Secs' ) { + $sort_column = "E.Length"; + } elsif ( $filter_expr->{sort_field} eq 'Frames' ) { + $sort_column = "E.Frames"; + } elsif ( $filter_expr->{sort_field} eq 'AlarmFrames' ) { + $sort_column = "E.AlarmFrames"; + } elsif ( $filter_expr->{sort_field} eq 'TotScore' ) { + $sort_column = "E.TotScore"; + } elsif ( $filter_expr->{sort_field} eq 'AvgScore' ) { + $sort_column = "E.AvgScore"; + } elsif ( $filter_expr->{sort_field} eq 'MaxScore' ) { + $sort_column = "E.MaxScore"; + } else { + $sort_column = "E.StartTime"; + } + 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}; + } + Debug( "SQL:$sql\n" ); + $self->{Sql} = $sql; + } # end if has Sql + return $self->{Sql}; } # end sub Sql -sub getDiskPercent -{ - my $command = "df ."; - my $df = qx( $command ); - my $space = -1; - if ( $df =~ /\s(\d+)%/ms ) - { - $space = $1; - } - return( $space ); +sub getDiskPercent { + my $command = "df ."; + my $df = qx( $command ); + my $space = -1; + if ( $df =~ /\s(\d+)%/ms ) { + $space = $1; + } + return( $space ); } -sub getDiskBlocks -{ - my $command = "df ."; - my $df = qx( $command ); - my $space = -1; - if ( $df =~ /\s(\d+)\s+\d+\s+\d+%/ms ) - { - $space = $1; - } - return( $space ); + +sub getDiskBlocks { + my $command = "df ."; + my $df = qx( $command ); + my $space = -1; + if ( $df =~ /\s(\d+)\s+\d+\s+\d+%/ms ) { + $space = $1; + } + return( $space ); } -sub getLoad -{ - my $command = "uptime ."; - my $uptime = qx( $command ); - my $load = -1; - if ( $uptime =~ /load average:\s+([\d.]+)/ms ) - { - $load = $1; - Info( "Load: $load" ); - } - return( $load ); + +sub getLoad { + my $command = "uptime ."; + my $uptime = qx( $command ); + my $load = -1; + if ( $uptime =~ /load average:\s+([\d.]+)/ms ) { + $load = $1; + Info( "Load: $load" ); + } + return( $load ); } # # More or less replicates the equivalent PHP function # -sub strtotime -{ - my $dt_str = shift; - return( Date::Manip::UnixDate( $dt_str, '%s' ) ); +sub strtotime { + my $dt_str = shift; + return( Date::Manip::UnixDate( $dt_str, '%s' ) ); } # # More or less replicates the equivalent PHP function # -sub str_repeat -{ - my $string = shift; - my $count = shift; - return( ${string}x${count} ); +sub str_repeat { + my $string = shift; + my $count = shift; + return( ${string}x${count} ); } # Formats a date into MySQL format -sub DateTimeToSQL -{ - my $dt_str = shift; - my $dt_val = strtotime( $dt_str ); - if ( !$dt_val ) - { - Error( "Unable to parse date string '$dt_str'\n" ); - return( undef ); - } - return( strftime( "%Y-%m-%d %H:%M:%S", localtime( $dt_val ) ) ); +sub DateTimeToSQL { + my $dt_str = shift; + my $dt_val = strtotime( $dt_str ); + if ( !$dt_val ) { + Error( "Unable to parse date string '$dt_str'\n" ); + return( undef ); + } + return( strftime( "%Y-%m-%d %H:%M:%S", localtime( $dt_val ) ) ); } 1; @@ -482,8 +434,8 @@ ZoneMinder::Database - Perl extension for blah blah blah =head1 SYNOPSIS - use ZoneMinder::Filter; - blah blah blah +use ZoneMinder::Filter; +blah blah blah =head1 DESCRIPTION From 7277283659778bddfd222284a81b297b0468b699 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Fri, 27 May 2016 10:12:46 -0400 Subject: [PATCH 4/7] rename AttrServerId to AttrServer, because that is the text that is returned --- web/lang/en_gb.php | 2 +- web/skins/classic/views/filter.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/web/lang/en_gb.php b/web/lang/en_gb.php index 1d4025a68..c265d9a6b 100644 --- a/web/lang/en_gb.php +++ b/web/lang/en_gb.php @@ -125,7 +125,7 @@ $SLANG = array( 'AttrMaxScore' => 'Max. Score', 'AttrMonitorId' => 'Monitor Id', 'AttrMonitorName' => 'Monitor Name', - 'AttrServerId' => 'Server', + 'AttrServer' => 'Server', 'AttrName' => 'Name', 'AttrNotes' => 'Notes', 'AttrSystemLoad' => 'System Load', diff --git a/web/skins/classic/views/filter.php b/web/skins/classic/views/filter.php index 9c05e2809..b61884471 100644 --- a/web/skins/classic/views/filter.php +++ b/web/skins/classic/views/filter.php @@ -84,7 +84,7 @@ $attrTypes = array( 'DiskPercent' => translate('AttrDiskPercent'), 'DiskBlocks' => translate('AttrDiskBlocks'), 'SystemLoad' => translate('AttrSystemLoad'), - 'ServerId' => translate('AttrServerId'), + 'ServerId' => translate('AttrServer'), ); $opTypes = array( '=' => translate('OpEq'), From 408646ea4d53ac4f9c44497c546228563a3ae9f1 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Fri, 27 May 2016 10:52:59 -0400 Subject: [PATCH 5/7] remove extra s --- scripts/ZoneMinder/lib/ZoneMinder/Filter.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/ZoneMinder/lib/ZoneMinder/Filter.pm b/scripts/ZoneMinder/lib/ZoneMinder/Filter.pm index e15533727..c6d32f702 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/Filter.pm +++ b/scripts/ZoneMinder/lib/ZoneMinder/Filter.pm @@ -289,7 +289,7 @@ sub Sql { } } # end if has an operator if ( exists($term->{cbr}) ) { - $self->{Sql} .= " ".str_repeat( ")", $terms->{cbr} )." "; + $self->{Sql} .= " ".str_repeat( ")", $term->{cbr} )." "; } } # end foreach term } # end if terms From 2da709848a9db102dbffe40e038c0af834b8aa23 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Mon, 30 May 2016 09:30:02 -0400 Subject: [PATCH 6/7] remove extra comma screwing up the sql --- scripts/ZoneMinder/lib/ZoneMinder/Filter.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/ZoneMinder/lib/ZoneMinder/Filter.pm b/scripts/ZoneMinder/lib/ZoneMinder/Filter.pm index c6d32f702..5d79dc266 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/Filter.pm +++ b/scripts/ZoneMinder/lib/ZoneMinder/Filter.pm @@ -182,7 +182,7 @@ sub Sql { unix_timestamp(E.StartTime) as Time, M.Name as MonitorName, M.DefaultRate, - M.DefaultScale, + M.DefaultScale FROM Events as E INNER JOIN Monitors as M on M.Id = E.MonitorId "; From aaf8f6c98b4236f82fe4abbf171928d624a72080 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 18 Oct 2016 10:14:19 -0400 Subject: [PATCH 7/7] add the missing case for ServerId in Filter processing. --- web/includes/functions.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/web/includes/functions.php b/web/includes/functions.php index 9b5d1e8f1..7ec725a4a 100644 --- a/web/includes/functions.php +++ b/web/includes/functions.php @@ -1196,6 +1196,9 @@ function parseFilter( &$filter, $saveToSession=false, $querySep='&' ) { case 'MonitorName': $filter['sql'] .= 'M.'.preg_replace( '/^Monitor/', '', $filter['terms'][$i]['attr'] ); break; + case 'ServerId': + $filter['sql'] .= 'M.ServerId'; + break; case 'DateTime': $filter['sql'] .= "E.StartTime"; break; @@ -1241,6 +1244,13 @@ function parseFilter( &$filter, $saveToSession=false, $querySep='&' ) { case 'Notes': $value = dbEscape($value); break; + case 'ServerId': + if ( $value == 'ZM_SERVER_ID' ) { + $value = ZM_SERVER_ID; + } else { + $value = dbEscape($value); + } + break; case 'DateTime': $value = "'".strftime( STRF_FMT_DATETIME_DB, strtotime( $value ) )."'"; break;