ウェブ上で閲覧できるRSSリーダをDIYしてみた。

 暇なのでウェブ上で閲覧できるRSSリーダDIYしてみた。
 http://heiligzwei.s317.xrea.com/antena.html


 いや、はてなRSSでいいじゃん。と言われそうだが、某Gigazineのごとく1時間毎に記事を更新するサイトに画面を占領されると非常にうっとおしいので、僕としてはフィード毎に最大表示件数を設定できないとイヤンなのである。

 というわけで、XML::FeedPP(http://www.kawa.net/works/perl/feedpp/feedpp.html)というモジュールを使ってperlRSSリーダを作ってみたのだが、10サイトぐらい登録した時点で非常に動作が重くなる。イライラ。

 そこでjQuery投入。
 表示の遅いカテゴリはNow Loadingしてくれるのでかなりイライラ感は削減できたと思う。

 あとFeedPPはフィードの形式(RSS0.9、1.0、2.0、Atomなど)を判別して自動的に解釈してくれる点でXML::RSSより遥かに便利なのだが、いくつかのフィードはパースできない様である。DesignWalkerさんのhttp://feeds.feedburner.jp/designwalkerみたいにcontent部分が長いとかタグが多いとかいうフィードが読み込めないのかなあと思う。


 antena.cgiのソース部分はこんな感じ。

#!/usr/bin/perl

use strict;
use lib qw(../cpan);

use LWP::Simple;
use Time::Local;
use XML::FeedPP;
use CGI;
my $query = new CGI;

print <<EOM;
Content-type: text/html

<html>
<body>
EOM

my $words = $query->param('words');
$words =~ tr/,/|/;
my @urls = split(",", $query->param('url'));
my @outputs; my $i = 0;
foreach my $url (@urls){
    my $i2 = 0;
    ($url, my $limit) = split("&", $url);
    my $feed = XML::FeedPP->new($url);
    my $date; my $modified;
    foreach my $item ($feed->get_item()){
        my $flag = 0;
        if ($item->title() =~ /$words/ || !$words){ $flag = 1; }
        my $category;
        if (ref($item->category()) eq 'ARRAY'){
            foreach my $cat (@{$item->category()}){
                if(ref($cat) eq 'HASH'){
                    $category = $category.value(%$cat);
                }else{
                    $category = $category.$cat;
                }
            }
        }else{
            $category = $item->category();
        }
        if ($category =~ /$words/){ $flag = 1; }
        if ($item->pubDate() =~ /(\d{4})-0?(\d{1,2})-0?(\d{1,2})T(\d{2}):(\d{2}):(\d{2}).+/){
            $modified = timelocal($6, $5, $4, $3, $2 - 1, $1);
            $date = "$2$3$4:$5";
        }elsif ($item->pubDate() =~ /(\d{4})-0?(\d{1,2})-0?(\d{1,2})/){
            $modified = timelocal(0, 0, 0, $3, $2 - 1, $1);
            $date = "$2$3日";
        }else{
            $modified = time;
        }
        my $expiredate = time - ($query->param('expire') * 86400);
        if ($expiredate > $modified){ $flag = 0; }
        if ($limit && $i2 > $limit - 1){ $flag = 0; }
        if ($flag == 0){ next;}
        $outputs[$i][0] = $item->link();
        $outputs[$i][1] = $item->title();
        $outputs[$i][2] = $feed->link();
        $outputs[$i][3] = $feed->title();
        $outputs[$i][4] = $date;
        $outputs[$i][5] = $modified;
        $i++; $i2++
    }
}
@outputs = sort {$b->[5] <=> $a->[5]} @outputs;
my $j = 0;
for my $output(@outputs){
print <<EOM;
<div class="headline"><a class="headline" href="@$output[0]" target="_blank">@$output[1]</a></div>
<div><a class="site" href="@$output[2]" target="_blank"><span class="site">@$output[3]</span></a>
 <span class="date">@$output[4]</span></div>
EOM
    if($j == $query->param('count') - 1){last;}
    $j++;
}

print <<EOM;
</body>
</html>
EOM