Skip to content

Instantly share code, notes, and snippets.

@anazawa
Created October 10, 2012 10:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anazawa/3864493 to your computer and use it in GitHub Desktop.
Save anazawa/3864493 to your computer and use it in GitHub Desktop.
Sylpheed RSS Fetcher

PURPOSE

Sylpheed でフィードを読み込むプラグインのプロトタイプを作ること

SYNOPSIS

  • 「メール箱」->「新規フォルダを作成」->「RSS」

  • フィードを再読み込みする

    $ sylfeed update
    $ sylfeed -v update
    Load http://www.effectiveperlprogramming.com/feed
        - Add http://www.effectiveperlprogramming.com/?p=1557
    ...
    Done.
  • フィードを追加する

    $ ppit set sylfeed

    ---
    feeds:
      - http://www.effectiveperlprogramming.com/feed
    folder: /home/anazawa/Mail/RSS
    time_zone: Asia/Tokyo
    log_file: /home/anazawa/.sylpheed-2.0/sylfeed.log

LIMITATIONS

  • エントリを削除しても、update すると再び追加してしまう
  • エントリを別のフォルダに振り分けられない

DEPENDENCIES

SEE ALSO

  • Sylpheed - lightweight and user-friendly e-mail client

0.03 Nov 16th, 2012

  • rename sylpheed_rss to sylfeed
  • [Config] add 'log_file' which defaults to "~/.sylpheed-2.0/sylfeed.log"
  • use Log::Handler

0.02 Oct 11th, 2012

  • [Config] rename 'dir' to 'folder'

0.01 Oct 10th, 2012

  • initial commit
#!/usr/bin/env perl
package sylfeed;
use strict;
use warnings;
use Config::Pit;
use DateTime::Format::Mail;
use Digest::MD5 qw/md5_hex/;
use Encode;
use Getopt::Long;
use Log::Handler;
use Mail::Box::MH;
use Mail::Message;
use Path::Class;
use URI;
use XML::Feed;
our $VERSION = '0.03';
GetOptions(\my %options, qw/verbose/) or exit 1;
if ( !$ARGV[0] or $ARGV[0] ne 'update' ) {
print "sylfeed $VERSION\n";
print "Usage: sylfeed [-v] update\n";
exit;
}
my $config = Config::Pit::get('sylfeed', require => {
time_zone => 'Asia/Tokyo',
folder => "$ENV{HOME}/Mail/RSS",
feeds => [ 'http://rss.rssad.jp/rss/gihyo/feed/atom' ],
log_file => "$ENV{HOME}/.sylpheed-2.0/sylfeed.log",
});
my $log = Log::Handler->new(
file => {
filename => $config->{log_file},
maxlevel => 'info',
timeformat => '%Y-%m-%d %H:%M:%S',
},
);
if ( $options{verbose} ) {
$log->add(
screen => {
maxlevel => 'info',
timeformat => '%H:%M:%S',
},
);
}
my $folder = Mail::Box::MH->new(
access => 'rw',
folder => dir( $config->{folder} ),
keep_index => 1,
) or $log->error( "Cannot open $config->{folder}: $!" );
die unless $folder;
local $XML::Atom::ForceUnicode = 1;
my %has_entry = map {
my $entry_id = $_->get( 'X-Sylpheed-Rss-Article-Identifier' );
$entry_id ? ( $entry_id => 1 ) : ();
} $folder->messages;
my $mime_header = Encode::find_encoding( 'MIME-Header' );
my %add_link = (
'text/html' => sub {
my ( $body_ref, $link ) = @_;
${ $body_ref } .= qq{\n<p><a href="$link">Read more ... </a></p>\n};
},
'text/plain' => sub {
my ( $body_ref, $link ) = @_;
${ $body_ref } .= "\n\n$link\n";
},
);
$log->info( "Start updating feeds ..." );
for my $url ( @{$config->{feeds}} ) {
$log->info( "Load $url" );
my $feed = XML::Feed->parse( URI->new($url) )
or $log->error( XML::Feed->errstr );
next unless $feed;
for my $entry ( $feed->entries ) {
my $entry_id = md5_hex( $entry->id );
next if $has_entry{ $entry_id };
$log->info( " - Add " . $entry->id );
my $date = do {
my $issued = $entry->issued;
$issued->set_time_zone( $config->{time_zone} );
DateTime::Format::Mail->format_datetime( $issued );
};
my ( $media_type, $body );
for my $attr (qw/content summary/) {
my $content = $entry->$attr;
if ( $body = $content->body ) {
$media_type = $content->type || 'text/html';
last;
}
}
do { $add_link{$media_type} || sub {} }->( \$body, $entry->link );
my %header = (
'From' => $feed->title,
'Subject' => $entry->title,
'Date' => $date,
'X-Sylpheed-Rss-Author' => $entry->author || $feed->author,
'X-Sylpheed-Rss-Source-Url' => $url,
'X-Sylpheed-Rss-Source-Homepage-Url' => $feed->link,
'X-Sylpheed-Rss-Source-Name' => $feed->title,
'X-Sylpheed-Rss-Article-Url' => $entry->link,
'X-Sylpheed-Rss-Article-Identifier' => $entry_id,
'Content-Type' => "$media_type; charset=utf-8",
'Content-Transfer-Encoding' => 'quoted-printable',
);
@header{ keys %header }
= map { $mime_header->encode($_) } values %header;
$folder->addMessage(
Mail::Message->build(
%header,
data => Encode::encode( 'utf-8', $body ),
)
);
}
}
$folder->close or $log->error( "Cannot close $config->{folder}: $!" );
$log->info( "Done." );
1;
@anazawa
Copy link
Author

anazawa commented Oct 10, 2012

libsylph の Perl binding ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment