Problem creating envelope-from in module Email::Send
Problem creating envelope-from in module Email::Send
am 16.07.2007 13:33:05 von ralph
Hi,
I am trying to use the nice Email::Send (and friends) module and have
a problem creating the 'envelope from' as documented at
http://search.cpan.org/dist/Email-Send/lib/Email/Send/SMTP.p m#ENVELOPE_GENERATION
The envelope sender and recipients are, by default, generated by
looking at the From, To, Cc, and Bcc headers. This behavior can be
modified by replacing the get_env_sender and get_env_recipients
methods, both of which receive the Email::Simple object and their only
parameter, and return email addresses.
What does this mean? I tried to use 'get_env_recipients' as a
constructor parameter (e.g. "my $mailer = Email::Send->new({mailer =>
'SMTP', get_env_sender => \&my_get_env_sender});") and MANY more
things, but obviously this is wrong....
Can anyone point me in the right direction before I become crazy?
Ralph
Re: Problem creating envelope-from in module Email::Send
am 16.07.2007 15:51:22 von hjp-usenet2
On 2007-07-16 11:33, Ralph wrote:
> I am trying to use the nice Email::Send (and friends) module and have
> a problem creating the 'envelope from' as documented at
> http://search.cpan.org/dist/Email-Send/lib/Email/Send/SMTP.p m#ENVELOPE_GENERATION
>
>
> The envelope sender and recipients are, by default, generated by
> looking at the From, To, Cc, and Bcc headers. This behavior can be
> modified by replacing the get_env_sender and get_env_recipients
> methods, both of which receive the Email::Simple object and their only
> parameter, and return email addresses.
>
>
> What does this mean?
It probably means you have to define a subclass of Email::Send::SMTP which
overrides these methods.
> I tried to use 'get_env_recipients' as a
> constructor parameter (e.g. "my $mailer = Email::Send->new({mailer =>
> 'SMTP', get_env_sender => \&my_get_env_sender});") and MANY more
> things, but obviously this is wrong....
I see no indication in the documentation of Email::Send or
Email::Send::SMTP that it recognizes a property with the name
get_env_sender.
hp
--
_ | Peter J. Holzer | I know I'd be respectful of a pirate
|_|_) | Sysadmin WSR | with an emu on his shoulder.
| | | hjp@hjp.at |
__/ | http://www.hjp.at/ | -- Sam in "Freefall"
Re: Problem creating envelope-from in module Email::Send
am 16.07.2007 23:18:46 von Gunnar Hjalmarsson
Peter J. Holzer wrote:
> On 2007-07-16 11:33, Ralph wrote:
>> I am trying to use the nice Email::Send (and friends) module and have
>> a problem creating the 'envelope from' as documented at
>> http://search.cpan.org/dist/Email-Send/lib/Email/Send/SMTP.p m#ENVELOPE_GENERATION
>>
>>
>> The envelope sender and recipients are, by default, generated by
>> looking at the From, To, Cc, and Bcc headers. This behavior can be
>> modified by replacing the get_env_sender and get_env_recipients
>> methods, both of which receive the Email::Simple object and their only
>> parameter, and return email addresses.
>>
>>
>> What does this mean?
>
> It probably means you have to define a subclass of Email::Send::SMTP which
> overrides these methods.
Do you mean that it would be doable without a need to edit the
Email/Send/SMTP.pm file? If so, could you please give us a hint how to
do it?
--
Gunnar Hjalmarsson
Email: http://www.gunnar.cc/cgi-bin/contact.pl
Re: Problem creating envelope-from in module Email::Send
am 17.07.2007 01:17:09 von Kalle Olavi Niemitalo
Gunnar Hjalmarsson writes:
> Peter J. Holzer wrote:
>> It probably means you have to define a subclass of Email::Send::SMTP which
>> overrides these methods.
>
> Do you mean that it would be doable without a need to edit the
> Email/Send/SMTP.pm file? If so, could you please give us a hint how to
> do it?
It'd be something like this. See perlobj for details.
package SMTPWithSpecificEnvSender;
use base qw(Email::Send::SMTP);
our %Args; # Hack to make mailer_args visible to get_env_sender.
sub send {
my ($class, $message, @args) = @_;
local %Args = @args;
return $class->SUPER::send($message, @args);
}
sub get_env_sender {
my ($class, $message) = @_;
return $Args{smtp_env_sender} if exists $Args{smtp_env_sender};
return $class->SUPER::get_env_sender($message);
}
package main;
my $sender = Email::Send->new(
{ mailer => 'SMTPWithSpecificEnvSender',
mailer_args => [ Host => 'smtp.example.com',
smtp_env_sender => 'your@address.example' ]});
Modules Geo::OGC::Geometry and Gtk2::Ex::Geo
am 17.07.2007 14:10:30 von Ari Jolma
I've released a versions 0.01 of Geo::OGC::Geometry and 0.54 of
Gtk2::Ex::Geo.
Geo::OGC::Geometry contains several classes in the Geo::OGC namespace.
The idea of the module is to implement the OGC (www.opengeospatial.org)
simple feature geometry model, which is a standard in the geospatial
software domain. This initial release is usable mainly for storing
geospatial data since most of the methods for testing spatial relations
and the methods that support spatial analysis are not yet implemented.
The very basic computational geometry algorithms are however implemented
and the standard methods could be implemented using those.
The Gtk2::Ex::Geo contains basic classes for developing graphical
geospatial applications. It depends on Gtk2 and Cairo and implements a
GeoCanvas and a class whose objects can be used to manage a stack of
geospatial data that are rendered on the canvas. The Gtk2::Ex::Geo
version 0.54 is the first one that is almost pure Perl (there is minimal
xs code, mostly to manage a Cairo surface and GDK pixbuf). There is a
root Layer class in the distribution that contains, e.g., a color system
dialog box, but it is meant to be an abstract class.
There are subclasses for Gtk2::Ex::Geo::Layer that build on Geo::GDAL,
which is a swig/Perl interface to the C++ GDAL library. The new versions
of these will be uploaded to CPAN in near future. The development
versions are available at http://map.hut.fi/files/Geoinformatica/
Both of these modules are a part of geospatial software stack called
Geoinformatica, whose home page is at
http://geoinformatics.tkk.fi/twiki/bin/view/Main/Geoinformat icaSoftware
These modules should be discussed on the geo-perl list:
https://list.hut.fi/mailman/listinfo/geo-perl
Best regards,
Ari Jolma
Re: Problem creating envelope-from in module Email::Send
am 17.07.2007 19:52:00 von ralph
On Jul 17, 1:17 am, Kalle Olavi Niemitalo wrote:
> [...]
> It'd be something like this. See perlobj for details.
>
> package SMTPWithSpecificEnvSender;
> use base qw(Email::Send::SMTP);
> [...]
YMMD!
MANY thanx to Finland!!
Ralph.
P.S.: Grr, is there a good reason why coders choose this complicated
sub-class-concept so often instead of just offering an 'easy to use'
parameter??
Re: Problem creating envelope-from in module Email::Send
am 22.07.2007 08:02:12 von Gunnar Hjalmarsson
Kalle Olavi Niemitalo wrote:
> Gunnar Hjalmarsson writes:
>> Peter J. Holzer wrote:
>>> It probably means you have to define a subclass of Email::Send::SMTP which
>>> overrides these methods.
>>
>> Do you mean that it would be doable without a need to edit the
>> Email/Send/SMTP.pm file? If so, could you please give us a hint how to
>> do it?
>
> It'd be something like this. See perlobj for details.
>
> package SMTPWithSpecificEnvSender;
> use base qw(Email::Send::SMTP);
> our %Args; # Hack to make mailer_args visible to get_env_sender.
> sub send {
> my ($class, $message, @args) = @_;
> local %Args = @args;
> return $class->SUPER::send($message, @args);
> }
> sub get_env_sender {
> my ($class, $message) = @_;
> return $Args{smtp_env_sender} if exists $Args{smtp_env_sender};
> return $class->SUPER::get_env_sender($message);
> }
> package main;
> my $sender = Email::Send->new(
> { mailer => 'SMTPWithSpecificEnvSender',
> mailer_args => [ Host => 'smtp.example.com',
> smtp_env_sender => 'your@address.example' ]});
Thanks Kalle, much appreciated!
As a learning exercise I decided to try it. I don't know if I missed
something, but I found that I needed to copy the whole send() method as
well as the get_env_recipients() method. The reason is that when
get_env_sender() and get_env_recipients() were called from
Email::Send::SMTP::send(), the versions in Email::Send::SMTP were run
rather than the versions in my additional package.
This code proved to work:
package Email::Send::mySMTP;
use strict;
use warnings;
use base 'Email::Send::SMTP';
use Return::Value;
our ( $SMTP, %args );
sub send {
my ($class, $message, @args) = @_;
require Net::SMTP;
if ( @_ > 1 ) {
# my %args;
if ( @args % 2 ) {
my $host = shift @args;
%args = @args;
$args{Host} = $host;
} else {
%args = @args;
}
my $host = delete($args{Host}) || 'localhost';
my $smtp_class = $args{ssl} ? 'Net::SMTP::SSL'
: $args{tls} ? 'Net::SMTP::TLS'
: 'Net::SMTP';
$SMTP->quit if $SMTP;
$SMTP = $smtp_class->new($host, %args);
return failure "Couldn't connect to $host" unless $SMTP;
my ($user, $pass)
= @args{qw[username password]};
if ( $user ) {
$SMTP->auth($user, $pass)
or return failure "Couldn't authenticate '$user:...'";
}
}
my @bad;
eval {
my $from = $class->get_env_sender($message);
# ::TLS has no useful return value, but will croak on failure.
eval { $SMTP->mail($from) }
or return failure "FROM: <$from> denied";
my @to = $class->get_env_recipients($message);
if (eval { $SMTP->isa('Net::SMTP::TLS') }) {
$SMTP->to(@to);
} else {
my @ok = $SMTP->to(@to, { SkipBad => 1 });
if ( @to != @ok ) {
my %to; @to{@to} = (1) x @to;
delete @to{@ok};
@bad = keys %to;
}
}
return failure "No valid recipients" if @bad == @to;
};
return failure $@ if $@;
return failure "Can't send data" unless $SMTP->data(
$message->as_string );
return success "Message sent", prop => { bad => [ @bad ], };
}
sub get_env_sender {
my ($class, $message) = @_;
return $args{smtp_env_sender} if exists $args{smtp_env_sender};
return $class->SUPER::get_env_sender($message);
}
sub get_env_recipients {
my ($class, $message) = @_;
my %to = map { $_->address => 1 }
map { Email::Address->parse($message->header($_)) }
qw(To Cc Bcc);
return keys %to;
}
1;
--
Gunnar Hjalmarsson
Email: http://www.gunnar.cc/cgi-bin/contact.pl
Re: Problem creating envelope-from in module Email::Send
am 22.07.2007 08:40:17 von Gunnar Hjalmarsson
Ralph wrote:
> P.S.: Grr, is there a good reason why coders choose this complicated
> sub-class-concept so often instead of just offering an 'easy to use'
> parameter??
Good question.
As regards sending emails, my favorite module is Mail::Sender. It's a
well working module without dependencies, and after seeing the struggle
in this thread with specifying an envelope sender, I'm even more
convinced that I'll keep using Mail::Sender.
A code example:
use Mail::Sender;
ref (new Mail::Sender -> MailMsg( {
smtp => 'localhost',
fake_from => 'Somebody ',
from => 'somebodyelse@example.com', # envelope sender
to => 'John Smith ',
subject => 'Test',
msg => "Just a test...\n",
} )) or die "Cannot send mail: $Mail::Sender::Error\n";
--
Gunnar Hjalmarsson
Email: http://www.gunnar.cc/cgi-bin/contact.pl
Re: Problem creating envelope-from in module Email::Send
am 22.07.2007 21:23:05 von Kalle Olavi Niemitalo
Gunnar Hjalmarsson writes:
> As a learning exercise I decided to try it. I don't know if I missed
> something, but I found that I needed to copy the whole send() method
> as well as the get_env_recipients() method. The reason is that when
> get_env_sender() and get_env_recipients() were called from
> Email::Send::SMTP::send(), the versions in Email::Send::SMTP were run
> rather than the versions in my additional package.
I don't see why that would be the case.
http://search.cpan.org/src/RJBS/Email-Send-2.185/lib/Email/S end/SMTP.pm
shows calls like "my $from = $class->get_env_sender($message);"
so Perl should resolve them to the package given by $class.
I tested the following code, exactly as shown below, and it
worked: "From your@address.example Sun Jul 22 22:14:32 2007".
The bless thing is to avoid having to make a separate file.
#! /usr/bin/perl
use strict;
use warnings;
package SMTPWithSpecificEnvSender;
use base qw(Email::Send::SMTP);
our %Args; # Hack to make mailer_args visible to get_env_sender.
sub send {
my ($class, $message, @args) = @_;
local %Args = @args;
return $class->SUPER::send($message, @args);
}
sub get_env_sender {
my ($class, $message) = @_;
return $Args{smtp_env_sender} if exists $Args{smtp_env_sender};
return $class->SUPER::get_env_sender($message);
}
package main;
use Email::Send;
my $sender = Email::Send->new(
{ mailer => bless([], 'SMTPWithSpecificEnvSender'),
mailer_args => [ Host => 'localhost',
smtp_env_sender => 'your@address.example' ]});
my $ok = $sender->send(<<'EOF');
To: Kalle@Astalo.kon.iki.fi
From: Kalle@Astalo.kon.iki.fi
Subject: testing Email::Send
hello, world
EOF
die "$ok" if !$ok;