package Feed::Mail; use Moose::Role; use 5.016; use namespace::autoclean; use Encode; use Encode::MIME::Header; use MIME::Lite; use DateTime::Format::Mail; use Digest::SHA1 qw/ sha1_hex /; use Template; use Template::Provider::Encoding; use Template::Stash::ForceUTF8; use Moose::Util::TypeConstraints; subtype 'ArrayOfStr', as 'ArrayRef[Str]'; coerce 'ArrayOfStr', from 'Str', via { [ $_ ] }; has _mail_folders => ( is => 'ro', isa => 'ArrayOfStr', coerce => 1, default => sub { [] }, traits => [ 'Array' ], init_arg => 'mail_folders', handles => { mail_folders => 'elements', } ); has tt => ( is => 'ro', isa => 'Template', lazy_build => 1, ); has template => ( is => 'ro', isa => 'Str', lazy_build => 1, ); has date_formatter => ( is => 'ro', lazy_build => 1, ); sub _build_tt { my ($self) = @_; return Template->new( LOAD_TEMPLATES => [ Template::Provider::Encoding->new ], STASH => Template::Stash::ForceUTF8->new, ); } sub _build_template { my ($self) = @_; my $curpos = tell(DATA); binmode(DATA); my $template = do {local $/;}; seek(DATA,$curpos,0); return $template; } sub _build_date_formatter { return DateTime::Format::Mail->new(); } sub entry_to_mime { my ($self,$entry) = @_; my $from = 'feeder@localhost'; my $date = $entry->modified; my $from_name = $entry->author // $self->title; $from_name =~ tr/,//d; my $id = sha1_hex($entry->id); my $body = $self->prepare_body($entry); my $msg = MIME::Lite->new( Date => $self->date_formatter->format_datetime($entry->modified), From => encode('MIME-Header',qq{"$from_name" <$from>}), To => $from, Subject => encode('MIME-Header',$entry->title//'(no title)'), Type => 'multipart/related', ); $msg->attach( Type => 'text/html; charset=utf-8', Data => encode('utf-8',$body), Encoding => 'quoted-printable', ); $msg->add('Message-Id', "<$id.feeder\@localhost>"); $msg->add('X-Tags', encode('MIME-Header', join(' ', $entry->tags ))); return $msg; } sub prepare_body { my ($self,$entry) = @_; my $template=$self->template; my $out; $self->tt->process( \$template, { feeder => $self, feed => $self->feed, entry => $entry, content => $entry->content, }, \$out, ) or die $self->tt->error; return $out; } 1; __DATA__ [% USE encoding 'utf-8' -%]
[% SET link = entry.link || entry.id -%] [% entry.title %]
[% feed.title %]
[% IF entry.author %] by [% entry.author | html %] [% END %] [% IF entry.tags.size %] on [% entry.tags.join(',') %] [% END %]
[% IF content.body -%] [% IF content.body.match('(?i)^]') %] [% content.body %] [% ELSE %]
[% content.body %]
[% END %] [% ELSE %]
[% END %]
[% IF entry.issued %] Posted on [% self.date_formatter.format_datetime(entry.issued) %] [% END %] [% IF entry.modified %] Modified on [% self.date_formatter.format_datetime(entry.modified) %] [% END %] | permalink | [% feed.title | html %]