読者です 読者をやめる 読者になる 読者になる

CustomFeed::POP3 UIDL 対応ほか

CustomFeed::POP3 は、サーバにあるメールを全部ダウンロードして処理を行う。読んで消す場合は問題ないけど、サーバに残したい場合に困る。
全部取得してから Rule::Fresh, Rule::Deduped で対処してもいいけど、UIDL を見て余計な取得が起きないようにしたほうが良さそう。
なので、以下のように直してみた。

  • UIDL を cache に保存して、一旦取得したメールは無視する (この挙動、config で指定できたほうがよい?)
  • feed, entry に URI を付ける。feed は pop://username@host, entry は mid://message-id (RFC 2392)
  • feed の title は config で指定できるようにした
  • 1 entry ごとに別々の feed になるってのは、どうなんだろう? 一つの feed にまとめていれちゃってもよさそうな気がするが、互換性のためにそのままにしておく。
--- lib/Plagger/Plugin/CustomFeed/POP3.pm       (リビジョン 999)
+++ lib/Plagger/Plugin/CustomFeed/POP3.pm       (作業コピー)
@@ -37,16 +37,28 @@
     $context->log(info => "Login to pop3 server($host) succeeded.");

     my $msgnums = $pop->list;
+    my $uidls   = $pop->uidl;
+
     for my $msgnum (keys %$msgnums) {
+        my $key = sprintf '%s:%s:%s',
+            $host, $self->conf->{username}, $uidls->{$msgnum};
+        if($self->cache->get($key)){
+            $context->log( debug => "skip the message : $msgnum" );
+            next;
+        }
         $context->log(debug => "get the message : $msgnum");

         my $msg = $pop->get($msgnum);
         my $feed = $self->mail2feed(join '', @$msg);
+        $feed->link(URI->new(sprintf 'pop://%s@%s', $self->conf->{username}, $host));
+        $feed->title( $self->conf->{title} || $feed->link );
         $context->update->add($feed);

         if ($self->conf->{delete}) {
             $context->log(info => "delete message : $msgnum");
             $pop->delete($msgnum)
+        } else {
+            $self->cache->set( $key => 1 );
         }
     }

@@ -62,12 +74,14 @@

     my $feed = Plagger::Feed->new;
     $feed->type('pop3');
-    $feed->title($email->header('Subject'));

     $entry->title($email->header('Subject'));
     $entry->author($email->header('From'));
     $entry->date(Plagger::Date->parse($format, $email->header('Date'))) if $email->header('Date');
     $entry->body($self->get_body($email));
+    if($email->header('Message-Id') =~ /<(.*?)>/){
+        $entry->link(URI->new("mid://$1"));
+    }

     $feed->add_entry($entry);