Use Email::MIME instead of Email::Simple

Email::Simple cannot handle non-ASCII characters.

Fixes #191.
This commit is contained in:
Eelco Dolstra 2014-11-19 14:44:04 +01:00
parent 41bc918382
commit 8523130ebb
6 changed files with 90 additions and 95 deletions

View file

@ -99,6 +99,7 @@ in rec {
DataDump
DateTime
DigestSHA1
EmailMIME
EmailSender
FileSlurp
IOCompress

View file

@ -8,6 +8,7 @@ use Crypt::RandPasswd;
use Digest::SHA1 qw(sha1_hex);
use Hydra::Helper::Nix;
use Hydra::Helper::CatalystUtils;
use Hydra::Helper::Email;
use LWP::UserAgent;
use JSON;
use HTML::Entities;
@ -279,13 +280,15 @@ sub reset_password :Chained('user') :PathPart('reset-password') :Args(0) {
my $password = Crypt::RandPasswd->word(8,10);
setPassword($user, $password);
sendEmail($c,
sendEmail(
$c->config,
$user->emailaddress,
"Hydra password reset",
"Hi,\n\n".
"Your password has been reset. Your new password is '$password'.\n\n".
"You can change your password at " . $c->uri_for($self->action_for('edit'), [$user->username]) . ".\n\n".
"With regards,\n\nHydra.\n"
"With regards,\n\nHydra.\n",
[]
);
$c->flash->{successMsg} = "A new password has been sent to ${\$user->emailaddress}.";

View file

@ -4,10 +4,6 @@ use utf8;
use strict;
use Exporter;
use Readonly;
use Email::Simple;
use Email::Sender::Simple qw(sendmail);
use Email::Sender::Transport::SMTP;
use Sys::Hostname::Long;
use Nix::Store;
use Hydra::Helper::Nix;
use feature qw/switch/;
@ -19,7 +15,6 @@ our @EXPORT = qw(
forceLogin requireUser requireProjectOwner requireAdmin requirePost isAdmin isProjectOwner
trim
getLatestFinishedEval
sendEmail
paramToList
backToReferer
$pathCompRE $relPathRE $relNameRE $projectNameRE $jobsetNameRE $jobNameRE $systemRE $userNameRE $inputNameRE
@ -193,27 +188,6 @@ sub getLatestFinishedEval {
}
sub sendEmail {
my ($c, $to, $subject, $body) = @_;
my $sender = $c->config->{'notification_sender'} ||
(($ENV{'USER'} || "hydra") . "@" . hostname_long);
my $email = Email::Simple->create(
header => [
To => $to,
From => "Hydra <$sender>",
Subject => $subject
],
body => $body
);
print STDERR "Sending email:\n", $email->as_string if $ENV{'HYDRA_MAIL_TEST'};
sendmail($email);
}
# Catalyst request parameters can be an array or a scalar or
# undefined, making them annoying to handle. So this utility function
# always returns a request parameter as a list.

View file

@ -0,0 +1,49 @@
package Hydra::Helper::Email;
use strict;
use Exporter 'import';
use Email::Sender::Simple qw(sendmail);
use Email::MIME;
use File::Slurp;
use Sys::Hostname::Long;
our @EXPORT = qw(sendEmail getBaseUrl);
sub sendEmail {
my ($config, $to, $subject, $body, $extraHeaders) = @_;
my $url = getBaseUrl($config);
my $sender = $config->{'notification_sender'} // (($ENV{'USER'} // "hydra") . "@" . $url);
my @headers = (
To => $to,
From => "Hydra Build Daemon <$sender>",
Subject => $subject,
'X-Hydra-Instance' => $url, @{$extraHeaders}
);
my $email = Email::MIME->create(
attributes => {
encoding => 'quoted-printable',
charset => 'UTF-8',
},
header_str => [ @headers ],
body_str => $body
);
print STDERR "sending email:\n", $email->as_string if $ENV{'HYDRA_MAIL_TEST'};
if (defined $ENV{'HYDRA_MAIL_SINK'}) {
# For testing, redirect all mail to a file.
write_file($ENV{'HYDRA_MAIL_SINK'}, { append => 1 }, $email->as_string . "\n");
} else {
sendmail($email, { from => $sender });
}
}
sub getBaseUrl {
my ($config) = @_;
return $config->{'base_uri'} // "http://" . hostname_long . ":3000";
}
1;

View file

@ -1,23 +1,19 @@
package Hydra::Plugin::EmailNotification;
use utf8;
use strict;
use parent 'Hydra::Plugin';
use POSIX qw(strftime);
use Email::Sender::Simple qw(sendmail);
use Email::Sender::Transport::SMTP;
use Email::Simple;
use Email::Simple::Creator;
use Sys::Hostname::Long;
use File::Slurp;
use Template;
use Hydra::Helper::Nix;
use Hydra::Helper::CatalystUtils;
use Hydra::Helper::Email;
my $template = <<EOF;
Hi,
The status of Hydra job [% showJobName(build) %] [% IF showSystem %](on [% build.system %]) [% END %][% IF prevBuild && build.buildstatus != prevBuild.buildstatus %]has changed from "[% showStatus(prevBuild) %]" to "[% showStatus(build) %]"[% ELSE %]is "[% showStatus(build) %]"[% END %]. For details, see
The status of Hydra job [% showJobName(build) %] [% IF showSystem %](on [% build.system %]) [% END %][% IF prevBuild && build.buildstatus != prevBuild.buildstatus %]has changed from "[% showStatus(prevBuild) %]" to "[% showStatus(build) %]"[% ELSE %]is "[% showStatus(build) %]"[% END %]. For details, see
[% baseurl %]/build/[% build.id %]
@ -100,7 +96,7 @@ sub buildFinished {
my $vars =
{ build => $build, prevBuild => getPreviousBuild($build)
, dependents => [grep { $_->id != $build->id } @builds]
, baseurl => $self->{config}->{'base_uri'} || "http://localhost:3000"
, baseurl => getBaseUrl($self->{config})
, showJobName => \&showJobName, showStatus => \&showStatus
, showSystem => index($build->job->name, $build->system) == -1
, nrCommits => $nrCommits
@ -114,37 +110,18 @@ sub buildFinished {
# stripping trailing spaces from lines
$body =~ s/[\ ]+$//gm;
my $sender = $self->{config}->{'notification_sender'} ||
(($ENV{'USER'} || "hydra") . "@" . hostname_long);
#my $loglines = 50;
#my $logtext = logContents($build->drvpath, $loglines);
#$logtext = removeAsciiEscapes($logtext);
my $email = Email::Simple->create(
header => [
To => $to,
From => "Hydra Build Daemon <$sender>",
Subject =>
my $subject =
showStatus($build) . ": Hydra job " . showJobName($build)
. ($vars->{showSystem} ? " on " . $build->system : "")
. (scalar @{$vars->{dependents}} > 0 ? " (and " . scalar @{$vars->{dependents}} . " others)" : ""),
'X-Hydra-Instance' => $vars->{baseurl},
'X-Hydra-Project' => $build->project->name,
'X-Hydra-Jobset' => $build->jobset->name,
'X-Hydra-Job' => $build->job->name,
'X-Hydra-System' => $build->system
],
body => "",
);
$email->body_set($body);
. (scalar @{$vars->{dependents}} > 0 ? " (and " . scalar @{$vars->{dependents}} . " others)" : "");
if (defined $ENV{'HYDRA_MAIL_SINK'}) {
# For testing, redirect all mail to a file.
write_file($ENV{'HYDRA_MAIL_SINK'}, { append => 1 }, $email->as_string . "\n");
} else {
sendmail($email);
}
sendEmail(
$self->{config}, $to, $subject, $body,
[ 'X-Hydra-Project' => $build->project->name,
, 'X-Hydra-Jobset' => $build->jobset->name,
, 'X-Hydra-Job' => $build->job->name,
, 'X-Hydra-System' => $build->system
]);
}
}

View file

@ -7,17 +7,16 @@ use Hydra::Schema;
use Hydra::Plugin;
use Hydra::Helper::Nix;
use Hydra::Helper::AddBuilds;
use Hydra::Helper::Email;
use Hydra::Model::DB;
use Digest::SHA qw(sha256_hex);
use Email::Sender::Simple qw(sendmail);
use Email::Sender::Transport::SMTP;
use Email::Simple;
use Email::Simple::Creator;
use Sys::Hostname::Long;
use Config::General;
use Data::Dump qw(dump);
use Try::Tiny;
STDOUT->autoflush();
STDERR->autoflush(1);
binmode STDERR, ":encoding(utf8)";
my $db = Hydra::Model::DB->new();
my $config = getHydraConfig();
@ -49,7 +48,7 @@ sub setJobsetError {
$jobset->update({ errormsg => $errorMsg, errortime => time, fetcherrormsg => undef });
});
};
if (defined $errorMsg && $errorMsg ne ($prevError // "")) {
if (defined $errorMsg && $errorMsg ne ($prevError // "") || $ENV{'HYDRA_MAIL_TEST'}) {
sendJobsetErrorNotification($jobset, $errorMsg);
}
}
@ -58,42 +57,34 @@ sub setJobsetError {
sub sendJobsetErrorNotification() {
my ($jobset, $errorMsg) = @_;
chomp $errorMsg;
return if $jobset->project->owner->emailonerror == 0;
return if $errorMsg eq "";
my $url = hostname_long;
my $projectName = $jobset->project->name;
my $jobsetName = $jobset->name;
my $sender = $config->{'notification_sender'} ||
(($ENV{'USER'} || "hydra") . "@" . $url);
my $body = "Hi,\n"
. "\n"
. "This is to let you know that Hydra jobset evaluation of $projectName:$jobsetName "
. "This is to let you know that evaluation of the Hydra jobset $projectName:$jobsetName\n"
. "resulted in the following error:\n"
. "\n"
. "$errorMsg"
. "\n"
. "Regards,\n\nThe Hydra build daemon.\n";
my $email = Email::Simple->create(
header => [
To => $jobset->project->owner->emailaddress,
From => "Hydra Build Daemon <$sender>",
Subject => "Hydra $projectName:$jobsetName evaluation error",
'X-Hydra-Instance' => $url,
'X-Hydra-Project' => $projectName,
'X-Hydra-Jobset' => $jobsetName
],
body => ""
);
$email->body_set($body);
print STDERR $email->as_string if $ENV{'HYDRA_MAIL_TEST'};
sendmail($email);
try {
sendEmail(
$config,
$jobset->project->owner->emailaddress,
"Hydra $projectName:$jobsetName evaluation error",
$body,
[ 'X-Hydra-Project' => $projectName
, 'X-Hydra-Jobset' => $jobsetName
]);
} catch {
warn "error sending email: $_\n";
};
}