root/branches/hackathon-summary/plagger/lib/Plagger/Plugin/Publish/IMAP.pm

Revision 1621 (checked in by miyagawa, 14 years ago)

Plugins refactorthon:

  • Switched from copy-and-pasted gen_filename() function to Plagger::Util::filename_for() in Publish:: plugins
  • Moved 'publish.entry.fixup' hooks to 'publish.entry' in some Notify/Publish plugins
  • Moved 'publish.init' to 'plugin.init' if it makes sense
Line 
1 package Plagger::Plugin::Publish::IMAP;
2 use strict;
3 use base qw( Plagger::Plugin );
4
5 use DateTime;
6 use DateTime::Format::Mail;
7 use Encode qw/ from_to encode/;
8 use Encode::MIME::Header;
9 use MIME::Lite;
10 use IO::File;
11 use Mail::IMAPClient;
12 use Digest::MD5 qw/ md5_hex /;;
13
14 sub register {
15     my($self, $context) = @_;
16     $self->{version} = '0.1';
17     $context->register_hook(
18       $self,
19       'plugin.init' => \&initialize,
20       'publish.entry' => \&store_entry,
21       'publish.finalize' => \&finalize,
22     );
23 }
24
25 sub rule_hook { 'publish.entry' }
26
27 sub initialize {
28   my ($self, $context, $args) = @_;
29   my $cfg = $self->conf;
30   $self->{imap} = Mail::IMAPClient->new(
31     User     => $cfg->{username},
32     Password => $cfg->{password},
33     Server   => $cfg->{host} || 'localhost',
34     Port     => $cfg->{port} || 143,
35   ) or die $context->log(error => "Cannot connect; $@");
36   $context->log(debug => "Connected IMAP-SERVER (".$cfg->{host}.")");
37   if ($cfg->{folder} && !$self->{imap}->exists($cfg->{folder})) {
38     $self->{imap}->create($cfg->{folder})
39       or die $context->log(error => "Could not create $cfg->{folder}: $@");
40     $context->log(info => "Create new folder ($cfg->{folder})");
41   }
42   if (!$cfg->{mailfrom}) {
43     $cfg->{mailfrom} = 'plagger';
44   }
45 }
46
47 sub finalize {
48   my ($self, $context, $args) = @_;
49   my $cfg  = $self->{conf};
50   $self->{imap}->disconnect();
51   if (my $msg_count = $self->{msg}) {
52     $context->log(info => "Store $msg_count Message(s)");
53   }
54   $context->log(debug => "Disconnected IMAP-SERVER (".$cfg->{host}.")");
55 }
56
57 sub store_entry {
58   my($self, $context, $args) = @_;
59   my $cfg = $self->conf;
60   my $msg;
61   my $entry = $args->{entry};
62   my $feed_title = $args->{feed}->title;
63      $feed_title =~ tr/,//d;
64   my $subject    = $entry->title || '(no-title)';
65   my $body       = $self->templatize('mail.tt', { entry => $args->{entry}, feed => $args->{feed} });
66   my $now = Plagger::Date->now(timezone => $context->conf->{timezone});
67   $msg = MIME::Lite->new(
68     Date    => $now->format('Mail'),
69     From    => encode('MIME-Header', qq("$feed_title" <$cfg->{mailfrom}>)),
70     To      => $cfg->{mailto},
71     Subject => encode('MIME-Header', $subject),
72     Type    => 'multipart/related',
73   );
74   $body = encode("utf-8", $body);
75   $msg->attach(
76     Type => 'text/html; charset=utf-8',
77     Data => $body,
78     Encoding => 'quoted-printable',
79   );
80   $msg->add('X-Tags', encode('MIME-Header',join(' ',@{$entry->tags})));
81   my $xmailer = "MIME::Lite (Publish::Maildir Ver.$self->{version} in plagger)";
82   $msg->replace('X-Mailer',$xmailer);
83   $msg->add('In-Reply-To',"<".md5_hex($entry->id_safe).'@localhost>');
84   store_maildir($self, $context,$msg->as_string());
85   $self->{msg} += 1;
86 }
87
88 sub store_maildir {
89   my($self,$context,$msg) = @_;
90   my $folder = $self->conf->{folder} || 'INBOX';
91   my $uid = $self->{imap}->append_string($folder,$msg)
92     or die $context->log(error => "Could not append: $@");
93 }
94
95 1;
96
97 =head1 NAME
98
99 Plagger::Plugin::Publish::IMAP - Transmits IMAP server
100
101 =head1 SYNOPSIS
102
103   - module: Publish::IMAP
104     config:
105       username: user
106       password: passwd
107       folder: plagger
108       mailfrom: plagger@localhost
109
110 =head1 DESCRIPTION
111
112 This plug-in changes an entry into e-mail, and transmits it to an IMAP server.
113
114 =head1 AUTHOR
115
116 Nobuhito Sato
117
118 =head1 SEE ALSO
119
120 L<Plagger>
121
122 =cut
Note: See TracBrowser for help on using the browser.