package Sietima;
use Moo;
use Sietima::Policy;
use Types::Standard qw(ArrayRef Object FileHandle Maybe);
use Type::Params qw(compile);
use Sietima::Types qw(Address AddressFromStr
EmailMIME Message
Subscriber SubscriberFromAddress SubscriberFromStr SubscriberFromHashRef
Transport);
use Sietima::Message;
use Sietima::Subscriber;
use Email::Sender::Simple qw();
use Email::Sender;
use Email::Address;
use namespace::clean;
with 'MooX::Traits';
has return_path => (
isa => Address,
is => 'ro',
required => 1,
coerce => AddressFromStr,
);
my $subscribers_array = ArrayRef[
Subscriber->plus_coercions(
SubscriberFromAddress,
SubscriberFromStr,
SubscriberFromHashRef,
)
];
has subscribers => (
isa => $subscribers_array,
is => 'lazy',
coerce => $subscribers_array->coercion,
);
sub _build_subscribers { +[] }
has transport => (
isa => Transport,
is => 'lazy',
);
sub _build_transport { Email::Sender::Simple->default_transport }
sub handle_mail_from_stdin($self,@) {
my $mail_text = do { local $/; <> };
my $incoming_mail = Email::MIME->new(\$mail_text);
return $self->handle_mail($incoming_mail);
}
sub handle_mail($self,$incoming_mail) {
state $check = compile(Object,EmailMIME); $check->(@_);
my (@outgoing_messages) = $self->munge_mail($incoming_mail);
for my $outgoing_message (@outgoing_messages) {
$self->send_message($outgoing_message);
}
return;
}
sub subscribers_to_send_to($self,$incoming_mail) {
state $check = compile(Object,EmailMIME); $check->(@_);
return $self->subscribers;
}
sub munge_mail($self,$incoming_mail) {
state $check = compile(Object,EmailMIME); $check->(@_);
return Sietima::Message->new({
mail => $incoming_mail,
from => $self->return_path,
to => $self->subscribers_to_send_to($incoming_mail),
});
}
sub send_message($self,$outgoing_message) {
state $check = compile(Object,Message); $check->(@_);
my $envelope = $outgoing_message->envelope;
if ($envelope->{to} && $envelope->{to}->@*) {
$self->transport->send(
$outgoing_message->mail,
$envelope,
);
}
return;
}
sub _trait_namespace { 'Sietima::Role' }
sub list_addresses($self) {
return +{
return_path => $self->return_path,
};
}
sub command_line_spec($self) {
return {
name => 'sietima',
title => 'a simple mailing list manager',
subcommands => {
send => {
op => 'handle_mail_from_stdin',
summary => 'send email from STDIN',
},
},
};
}
1;