From 4ba7568909fe620ee9fb99cb6bbe058df8c0061c Mon Sep 17 00:00:00 2001 From: dakkar Date: Sun, 19 Jun 2016 17:55:45 +0100 Subject: AvoidDups role --- TODO.md | 2 -- lib/Sietima.pm | 9 ++++++--- lib/Sietima/Role/AvoidDups.pm | 26 ++++++++++++++++++++++++++ lib/Sietima/Role/NoMail.pm | 8 +++----- t/lib/Test/Sietima.pm | 7 +++++++ t/tests/sietima/role/avoid-dups.t | 28 ++++++++++++++++++++++++++++ 6 files changed, 70 insertions(+), 10 deletions(-) create mode 100644 lib/Sietima/Role/AvoidDups.pm create mode 100644 t/tests/sietima/role/avoid-dups.t diff --git a/TODO.md b/TODO.md index 829fd61..a233d4b 100644 --- a/TODO.md +++ b/TODO.md @@ -15,8 +15,6 @@ * `List-Archive: NO` (configurable) * de-bounce * add `X-Been-There` header -* avoid duplicates - * if member is in to/cc, don't send from list * subject [tag] * test what happens with mime-word-encoded subjects! * reply-to munging diff --git a/lib/Sietima.pm b/lib/Sietima.pm index 1e463ec..704d4f8 100644 --- a/lib/Sietima.pm +++ b/lib/Sietima.pm @@ -54,11 +54,11 @@ sub handle_mail { return; } -sub addresses_to_send_to { +sub subscribers_to_send_to { state $check = compile(Object,EmailMIME); my ($self,$incoming_mail) = $check->(@_); - return [ map { $_->address } @{$self->subscribers} ]; + return $self->subscribers; } sub munge_mail { @@ -68,7 +68,10 @@ sub munge_mail { return Sietima::Message->new({ mail => $incoming_mail, from => $self->return_path, - to => $self->addresses_to_send_to($incoming_mail), + to => [ + map { $_->address } + @{$self->subscribers_to_send_to($incoming_mail)}, + ], }); } diff --git a/lib/Sietima/Role/AvoidDups.pm b/lib/Sietima/Role/AvoidDups.pm new file mode 100644 index 0000000..da1af00 --- /dev/null +++ b/lib/Sietima/Role/AvoidDups.pm @@ -0,0 +1,26 @@ +package Sietima::Role::AvoidDups; +use 5.020; +use Moo::Role; +use Email::Address; +use namespace::clean; + +around subscribers_to_send_to => sub { + my ($orig,$self,$mail) = @_; + + my @already_receiving = map { + Email::Address->parse($_) + } $mail->header_str('to'),$mail->header_str('cc'); + + my %already_receiving = map { + $_->address => 1 + } @already_receiving; + + return [ + grep { + not $already_receiving{$_->address} + } + @{$self->$orig($mail)}, + ]; +}; + +1; diff --git a/lib/Sietima/Role/NoMail.pm b/lib/Sietima/Role/NoMail.pm index 233f6b9..a0753b9 100644 --- a/lib/Sietima/Role/NoMail.pm +++ b/lib/Sietima/Role/NoMail.pm @@ -3,15 +3,13 @@ use 5.020; use Moo::Role; use namespace::clean; -around addresses_to_send_to => sub { +around subscribers_to_send_to => sub { my ($orig,$self,@etc) = @_; return [ - map { $_->address } - grep { $_->prefs->{wants_mail} // 1 } - @{$self->subscribers}, + grep { $_->prefs->{wants_mail} // 1 } + @{$self->$orig(@etc)}, ]; }; 1; - diff --git a/t/lib/Test/Sietima.pm b/t/lib/Test/Sietima.pm index 0661786..48c92cc 100644 --- a/t/lib/Test/Sietima.pm +++ b/t/lib/Test/Sietima.pm @@ -48,12 +48,19 @@ sub make_sietima { }); } +my $maybe = sub { + my ($obj,$method,$arg) = @_; + return $obj unless $arg; + return $obj->$method($arg); +}; + sub make_mail { my (%args) = @_; Email::Stuffer ->from($args{from}||'someone@users.example.com') ->to($args{to}||$return_path) + ->$maybe(cc => $args{cc}) ->subject($args{subject}||'Test Message') ->text_body($args{body}||'some simple message') ->email; diff --git a/t/tests/sietima/role/avoid-dups.t b/t/tests/sietima/role/avoid-dups.t new file mode 100644 index 0000000..997f3fd --- /dev/null +++ b/t/tests/sietima/role/avoid-dups.t @@ -0,0 +1,28 @@ +#!perl +use strict; +use warnings; +use 5.020; +use lib 't/lib'; +use Test::Sietima; + +my $s = make_sietima( + with_traits => ['AvoidDups'], + subscribers => [ + 'one@users.example.com', + 'two@users.example.com', + ], +); + +test_sending( + sietima => $s, + mail => { cc => 'one@users.example.com' }, + to => ['two@users.example.com'], +); + +test_sending( + sietima => $s, + mail => { to => $s->return_path . ' one@users.example.com' }, + to => ['two@users.example.com'], +); + +done_testing; -- cgit v1.2.3