summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authordakkar <dakkar@thenautilus.net>2012-12-09 15:16:41 +0000
committerdakkar <dakkar@thenautilus.net>2012-12-09 15:16:41 +0000
commitea5d5fe4d5617326ec61c26157bca886b8614435 (patch)
tree9c184aee2ff80ca26d7d39922f40c58990884184 /lib
parentextract author name for email address (diff)
downloadfeeder-ea5d5fe4d5617326ec61c26157bca886b8614435.tar.gz
feeder-ea5d5fe4d5617326ec61c26157bca886b8614435.tar.bz2
feeder-ea5d5fe4d5617326ec61c26157bca886b8614435.zip
maildir publisher
Diffstat (limited to 'lib')
-rw-r--r--lib/Feed.pm13
-rw-r--r--lib/Feed/Mail.pm179
-rw-r--r--lib/Feed/MailDir.pm76
-rw-r--r--lib/Feed/Printer.pm2
4 files changed, 269 insertions, 1 deletions
diff --git a/lib/Feed.pm b/lib/Feed.pm
index fbcdf10..652c438 100644
--- a/lib/Feed.pm
+++ b/lib/Feed.pm
@@ -30,6 +30,19 @@ has feed => (
builder => 'get_feed',
);
+has title => (
+ is => 'ro',
+ isa => 'Str',
+ lazy_build => 1,
+ builder => 'extract_title',
+);
+
+sub extract_title {
+ my ($self) = @_;
+
+ return $self->feed->title;
+}
+
has _entries => (
is => 'ro',
isa => 'ArrayRef[XML::Feed::Entry]',
diff --git a/lib/Feed/Mail.pm b/lib/Feed/Mail.pm
new file mode 100644
index 0000000..cc52b6a
--- /dev/null
+++ b/lib/Feed/Mail.pm
@@ -0,0 +1,179 @@
+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 $/;<DATA>};
+ 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' -%]
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+ <head>
+ <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
+ <style TYPE=text/css>
+ body { padding:0; margin:20px }
+ strong { font-weight:bold; font-size:1.2em }
+ div#msgheader { background:#65869E; color:#F5F5F5; padding:10px; margin:-20px -20px 0 -20px }
+ div#msgbody { margin: 1em }
+ div#msgfooter { text-align:right; font-size:0.8em }
+ #msgheader a:link { color:#F5F5F5 }
+ #msgheader a { font-size: 90% }
+ #msgbody a:link { color:#000000 }
+ #msgbody img { border:1px solid; background:#F5F5F5 }
+ #msgbody hr { border:1px solid }
+ #msgbody pre { font-size: 90% }
+ </style>
+ </head>
+ <body>
+ <div id="msgheader">
+ [% SET link = entry.link || entry.id -%]
+ <a href="[% link | html %]"><strong>[% entry.title %]</strong></a><br />
+ [% feed.title %]<br />
+ [% IF entry.author %]
+ by [% entry.author | html %]
+ [% END %]
+ [% IF entry.tags.size %]
+ on [% entry.tags.join(',') %]
+ [% END %]
+ </div>
+ <div id="msgbody">
+ [% IF content.body -%]
+ [% IF content.body.match('(?i)^<p[ >]') %]
+ [% content.body %]
+ [% ELSE %]
+ <div id="msgbody">[% content.body %]</div>
+ [% END %]
+ [% ELSE %]
+ <br />
+ [% END %]
+ </div>
+ <div id="msgfooter">
+ [% 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 %]
+ |
+ <a href="[% entry.link | html %]">permalink</a>
+ |
+ <a href="[% feed.link | html %]">[% feed.title | html %]</a>
+ <br clear="all" />
+ </div>
+ </body>
+</html>
diff --git a/lib/Feed/MailDir.pm b/lib/Feed/MailDir.pm
new file mode 100644
index 0000000..4b8f542
--- /dev/null
+++ b/lib/Feed/MailDir.pm
@@ -0,0 +1,76 @@
+package Feed::MailDir;
+use Moose::Role;
+use 5.016;
+use namespace::autoclean;
+use Encode;
+use Encode::IMAPUTF7;
+use MooseX::Types::Path::Class 'Dir';
+use Maildir::Lite;
+
+with 'Feed::Mail';
+
+requires 'extract_entries';
+
+has maildir_base => (
+ is => 'ro',
+ isa => Dir,
+ coerce => 1,
+ required => 1,
+);
+
+has maildir_folder => (
+ is => 'ro',
+ isa => 'Maildir::Lite',
+ lazy_build => 1,
+);
+
+sub _build_maildir_folder {
+ my ($self) = @_;
+
+ my $feed = $self->feed;
+
+ my $folder = encode('IMAP-UTF-7',$self->maildir_folder_for($feed));
+
+ $self->maildir_base->mkpath;
+
+ return Maildir::Lite->new(
+ dir => $self->maildir_base->subdir($folder)->stringify,
+ );
+}
+
+sub process_entry {
+ my ($self,$entry) = @_;
+
+ my ($msg) = $self->entry_to_mime($entry);
+
+ $self->store_into_maildir($msg);
+
+ return;
+}
+
+sub _clean_folder_part {
+ return map { s{\W+}{-}gr } @_;
+}
+
+sub maildir_folder_for {
+ my ($self,$feed) = @_;
+
+ my (@comps) = _clean_folder_part($self->mail_folders,$self->title);
+ return join '.','',@comps;
+}
+
+sub store_into_maildir {
+ my ($self,$msg) = @_;
+
+ my ($fh,$stat) = $self->maildir_folder->creat_message();
+ die "maildir create message failed ($stat)" if $stat;
+
+ binmode($fh);
+ $msg->print($fh)
+ or die "print to maildir failed: $!";
+
+ $self->maildir_folder->deliver_message($fh)
+ and die "maildir write failed";
+}
+
+1;
diff --git a/lib/Feed/Printer.pm b/lib/Feed/Printer.pm
index 89dd93f..8d673e0 100644
--- a/lib/Feed/Printer.pm
+++ b/lib/Feed/Printer.pm
@@ -8,7 +8,7 @@ requires 'process';
before process => sub {
my ($self) = @_;
- say $self->feed->title;
+ say $self->title;
};
sub process_entry {