diff --git a/db/zm_create.sql.in b/db/zm_create.sql.in index c9b2b6ea1..240f07153 100644 --- a/db/zm_create.sql.in +++ b/db/zm_create.sql.in @@ -287,6 +287,9 @@ CREATE TABLE `Filters` ( `AutoVideo` tinyint(3) unsigned NOT NULL default '0', `AutoUpload` tinyint(3) unsigned NOT NULL default '0', `AutoEmail` tinyint(3) unsigned NOT NULL default '0', + `EmailTo` TEXT, + `EmailSubject` TEXT, + `EmailBody` TEXT, `AutoMessage` tinyint(3) unsigned NOT NULL default '0', `AutoExecute` tinyint(3) unsigned NOT NULL default '0', `AutoExecuteCmd` tinytext, diff --git a/db/zm_update-1.35.0.sql b/db/zm_update-1.35.0.sql new file mode 100644 index 000000000..2e9132a63 --- /dev/null +++ b/db/zm_update-1.35.0.sql @@ -0,0 +1,41 @@ +SET @s = (SELECT IF( + (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE() + AND table_name = 'Filters' + AND column_name = 'EmailTo' + ) > 0, +"SELECT 'Column EmailTo already exists in Filters'", +"ALTER TABLE `Filters` ADD `EmailTo` TEXT AFTER `AutoEmail`" +)); + +PREPARE stmt FROM @s; +EXECUTE stmt; + +UPDATE Filters SET EmailTo=(SELECT Value FROM Config WHERE Name='ZM_EMAIL_ADDRESS') WHERE AutoEmail=1; + +SET @s = (SELECT IF( + (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE() + AND table_name = 'Filters' + AND column_name = 'EmailSubject' + ) > 0, +"SELECT 'Column EmailSubject already exists in Filters'", +"ALTER TABLE `Filters` ADD `EmailSubject` TEXT AFTER `EmailTo`" +)); + +PREPARE stmt FROM @s; +EXECUTE stmt; + +UPDATE Filters SET EmailSubject=(SELECT Value FROM Config WHERE Name='ZM_EMAIL_SUBJECT') WHERE AutoEmail=1; + +SET @s = (SELECT IF( + (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE() + AND table_name = 'Filters' + AND column_name = 'EmailBody' + ) > 0, +"SELECT 'Column EmailBody already exists in Filters'", +"ALTER TABLE `Filters` ADD `EmailBody` TEXT AFTER `EmailSubject`" +)); + +PREPARE stmt FROM @s; +EXECUTE stmt; + +UPDATE Filters SET EmailBody=(SELECT Value FROM Config WHERE Name='ZM_EMAIL_BODY') WHERE AutoEmail=1; diff --git a/docs/userguide/filterevents.rst b/docs/userguide/filterevents.rst index 8359aaf89..436034da0 100644 --- a/docs/userguide/filterevents.rst +++ b/docs/userguide/filterevents.rst @@ -68,9 +68,13 @@ Here is what the filter window looks like * %ESM% Maximum score of the event * %EP% Path to the event * %EPS% Path to the event stream + * %EPF1% Path to the frame view for the first alarmed event image + * %EPFM% Path to the frame view for the (first) event image with the highest score + * %EFMOD% Path to image containing object detection, in frame view * %EPI% Path to the event images - * %EPI1% Path to the first alarmed event image - * %EPIM% Path to the (first) event image with the highest score + * %EPI1% Path to the first alarmed event image, suitable for use in img tags + * %EPIM% Path to the (first) event image with the highest score, suitable for use in img tags + * %EIMOD% Path to image containing object detection, suitable for use in img tags * %EI1% Attach first alarmed event image * %EIM% Attach (first) event image with the highest score * %EV% Attach event mpeg video @@ -81,7 +85,6 @@ Here is what the filter window looks like * %MEW% Number of events for the monitor in the last week * %MEM% Number of events for the monitor in the last month * %MEA% Number of archived events for the monitor - * %MOD% Path to image containing object detection * %MP% Path to the monitor window * %MPS% Path to the monitor stream * %MPI% Path to the monitor recent image diff --git a/scripts/ZoneMinder/lib/ZoneMinder/ConfigData.pm.in b/scripts/ZoneMinder/lib/ZoneMinder/ConfigData.pm.in index cd93dfe15..24c5238e8 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/ConfigData.pm.in +++ b/scripts/ZoneMinder/lib/ZoneMinder/ConfigData.pm.in @@ -2213,7 +2213,7 @@ our @options = ( that match the appropriate filters will be sent to. `, type => $types{email}, - category => 'mail', + category => 'hidden', }, { name => 'ZM_EMAIL_TEXT', @@ -2253,7 +2253,7 @@ our @options = ( sent for any events that match the appropriate filters. `, type => $types{string}, - category => 'mail', + category => 'hidden', }, { name => 'ZM_EMAIL_BODY', @@ -2280,7 +2280,7 @@ our @options = ( sent for any events that match the appropriate filters. `, type => $types{text}, - category => 'mail', + category => 'hidden', }, { name => 'ZM_OPT_MESSAGE', diff --git a/scripts/zmfilter.pl.in b/scripts/zmfilter.pl.in index be9996fe2..aa5e8ad4e 100644 --- a/scripts/zmfilter.pl.in +++ b/scripts/zmfilter.pl.in @@ -196,7 +196,7 @@ my $last_action = 0; while( !$zm_terminate ) { my $now = time; if ( ($now - $last_action) > $Config{ZM_FILTER_RELOAD_DELAY} ) { - Debug("Reloading filters"); + Debug('Reloading filters'); $last_action = $now; @filters = getFilters({ Name=>$filter_name, Id=>$filter_id }); } @@ -699,8 +699,10 @@ sub substituteTags { $text =~ s/%ESM%/$Event->{MaxScore}/g; if ( $first_alarm_frame ) { - $text =~ s/%EPI1%/$url?view=frame&mid=$Event->{MonitorId}&eid=$Event->{Id}&fid=$first_alarm_frame->{FrameId}/g; - $text =~ s/%EPIM%/$url?view=frame&mid=$Event->{MonitorId}&eid=$Event->{Id}&fid=$max_alarm_frame->{FrameId}/g; + $text =~ s/%EPF1%/$url?view=frame&mid=$Event->{MonitorId}&eid=$Event->{Id}&fid=$first_alarm_frame->{FrameId}/g; + $text =~ s/%EPFM%/$url?view=frame&mid=$Event->{MonitorId}&eid=$Event->{Id}&fid=$max_alarm_frame->{FrameId}/g; + $text =~ s/%EPI1%/$url?view=image&mid=$Event->{MonitorId}&eid=$Event->{Id}&fid=$first_alarm_frame->{FrameId}/g; + $text =~ s/%EPIM%/$url?view=image&mid=$Event->{MonitorId}&eid=$Event->{Id}&fid=$max_alarm_frame->{FrameId}/g; if ( $attachments_ref ) { if ( $text =~ s/%EI1%//g ) { my $path = generateImage($Event, $first_alarm_frame); @@ -748,13 +750,14 @@ sub substituteTags { } } - if ( $text =~ s/%EIMOD%//g ) { - $text =~ s/%EIMOD%/$url?view=frame&mid=$Event->{MonitorId}&eid=$Event->{Id}&fid=objdetect/g; + if ( $text =~ s/%EIMOD%//g or $text =~ s/%EFMOD%//g ) { + $text =~ s/%EFMOD%/$url?view=frame&mid=$Event->{MonitorId}&eid=$Event->{Id}&fid=objdetect/g; + $text =~ s/%EIMOD%/$url?view=image&mid=$Event->{MonitorId}&eid=$Event->{Id}&fid=objdetect/g; my $path = $Event->Path().'/objdetect.jpg'; if ( -e $path ) { push @$attachments_ref, { type=>'image/jpeg', path=>$path }; } else { - Warning('No image for EIMOD at ' . $path); + Warning('No image for MOD at '.$path); } } @@ -796,17 +799,17 @@ sub sendEmail { Error('No from email address defined, not sending email'); return 0; } - if ( ! $Config{ZM_EMAIL_ADDRESS} ) { + if ( ! $$filter{EmailTo} ) { Error('No email address defined, not sending email'); return 0; } Info('Creating notification email'); - my $subject = substituteTags($Config{ZM_EMAIL_SUBJECT}, $filter, $Event); + my $subject = substituteTags($$filter{EmailSubject}, $filter, $Event); return 0 if !$subject; my @attachments; - my $body = substituteTags($Config{ZM_EMAIL_BODY}, $filter, $Event, \@attachments); + my $body = substituteTags($$filter{EmailBody}, $filter, $Event, \@attachments); return 0 if !$body; Info("Sending notification email '$subject'"); @@ -816,7 +819,7 @@ sub sendEmail { ### Create the multipart container my $mail = MIME::Lite->new ( From => $Config{ZM_FROM_EMAIL}, - To => $Config{ZM_EMAIL_ADDRESS}, + To => $$filter{EmailTo}, Subject => $subject, Type => 'multipart/mixed' ); @@ -827,7 +830,7 @@ sub sendEmail { ); ### Add the attachments foreach my $attachment ( @attachments ) { - Info( "Attaching '$attachment->{path}'" ); + Info("Attaching '$attachment->{path}'"); $mail->attach( Path => $attachment->{path}, Type => $attachment->{type}, @@ -849,7 +852,7 @@ sub sendEmail { $mail->send(); } else { ### Send using SSMTP - $mail->send('sendmail', $ssmtp_location, $Config{ZM_EMAIL_ADDRESS}); + $mail->send('sendmail', $ssmtp_location, $$filter{EmailTo}); } } else { MIME::Lite->send('smtp', $Config{ZM_EMAIL_HOST}, Timeout=>60); @@ -858,7 +861,7 @@ sub sendEmail { } else { my $mail = MIME::Entity->build( From => $Config{ZM_FROM_EMAIL}, - To => $Config{ZM_EMAIL_ADDRESS}, + To => $$filter{EmailTo}, Subject => $subject, Type => (($body=~//)?'text/html':'text/plain'), Data => $body diff --git a/web/includes/Filter.php b/web/includes/Filter.php index 8bccf3860..c15d8ba6a 100644 --- a/web/includes/Filter.php +++ b/web/includes/Filter.php @@ -11,6 +11,9 @@ class Filter extends ZM_Object { 'AutoExecute' => 0, 'AutoExecuteCmd' => 0, 'AutoEmail' => 0, + 'EmailTo' => '', + 'EmailSubject' => '', + 'EmailBody' => '', 'AutoDelete' => 0, 'AutoArchive' => 0, 'AutoVideo' => 0, diff --git a/web/lang/en_gb.php b/web/lang/en_gb.php index 85b9bb52e..4c43acba9 100644 --- a/web/lang/en_gb.php +++ b/web/lang/en_gb.php @@ -362,6 +362,9 @@ $SLANG = array( 'FilterCopyEvents' => 'Copy all matches', 'FilterMoveEvents' => 'Move all matches', 'FilterEmailEvents' => 'Email details of all matches', + 'FilterEmailTo' => 'Email To', + 'FilterEmailSubject' => 'Email Subject', + 'FilterEmailBody' => 'Email Body', 'FilterExecuteEvents' => 'Execute command on all matches', 'FilterLog' => 'Filter log', 'FilterMessageEvents' => 'Message details of all matches', diff --git a/web/skins/classic/css/base/views/filter.css b/web/skins/classic/css/base/views/filter.css index 638b85c9b..88854988e 100644 --- a/web/skins/classic/css/base/views/filter.css +++ b/web/skins/classic/css/base/views/filter.css @@ -56,9 +56,14 @@ select { width: 300px; text-align: right; } +input[name="filter[EmailSubject]"], +input[name="filter[EmailTo]"], +textarea[name="filter[EmailBody]"] { +width: 500px; +} select#Id { -min-width: 400px; +min-width: 500px; } .Name input { -min-width: 400px; +min-width: 500px; } diff --git a/web/skins/classic/views/filter.php b/web/skins/classic/views/filter.php index 27a434f73..e9af1b049 100644 --- a/web/skins/classic/views/filter.php +++ b/web/skins/classic/views/filter.php @@ -387,8 +387,22 @@ if ( ZM_OPT_EMAIL ) { ?>
- AutoEmail() ) { ?> checked="checked" data-on-click-this="updateButtons"/> + AutoEmail() ) { ?> checked="checked" data-on-click-this="click_AutoEmail"/>
++ + +
++ + +
++ + +
+