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, ); sub list_addresses($self) { return +{ return_path => $self->return_path, }; } 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 command_line_spec($self) { return { name => 'sietima', title => 'a simple mailing list manager', options => [ { name => 'verbose', summary => 'more chatty', type => 'flag', multiple => 1, aliases => ['v'], }, ], subcommands => { send => { op => 'handle_mail_from_stdin', summary => 'send email from STDIN', }, }, }; } 1;