Atomフィード単位でAtom記事を読み出すリンクを作成する
第1回で作成した「feeds.cgi」は、FirefoxのブックマークからAtomフィードのリストを作成し、そのタイトルにAtomフィードのURLをパラメータとして与えた「atom2html.cgi」へのリンクを出力するものでした。
今回作成する「atom2msrdb_feeds.cgi」は、「atomfeeds」データベースの「feeds」テーブルから同様なAtomフィードのリストを出力します。技術的には「atom2msrdb_read.cgi」とほとんど変わらないので説明は省略します。スクリプトは次の通りです。
#!/Perl5.8/bin/perl.exe use strict; use warnings; use DBI; use URI::Escape; use CGI qw(:cgi); # 環境変数の取得 #ローカル HTTP サーバの CGI 相対ディレクトリ my $cgidir = $ENV{'CGIDIR'};# "/cgi-bin/codezine"; # CGI 最初の部分の出力 print <<HEADER; Content-type: text/html; charset=UTF-8 <html> <head> <title>ATOM DB Feeds List</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <link rel="stylesheet" type="text/css" href="/mystyle.css" /> <script type="text/javascript"> <!-- if(navigator.appCodeName.indexOf("Mozilla") != -1){ document.write( "<link rel='stylesheet' type='text/css' href='/firefox.css' />"); } --> </script> </head> <body> <h3>Atom DB Feeds List</h3> HEADER ##### my $dbh = DBI->connect( "DBI:mysql:database=atomfeeds;host=localhost;port=3306", "root", "password", {'RaiseError' => 1}); my $sth = $dbh->prepare(qq{ SELECT * FROM feeds }); $sth->execute(); while(my $row = $sth->fetchrow_hashref()){ print "<h3><a href=\"$row->{link}\">$row->{title}</a></h3><p>\n"; if($row->{logo}){ print "<img src=\"$row->{logo}\">$row->{subtitle}\n"; }elsif($row->{icon}){ print "<img src=\"$row->{icon}\">$row->{subtitle}\n"; }else{ print "$row->{subtitle}\n"; } my $url_encoding = uri_escape($row->{atom}); if($row->{updated}){ print " [ $row->{updated} ]</p>\n"; }elsif($row->{modified}){ print " [ $row->{modified} ]</p>\n"; }else{ print "</p>\n"; } print "<p>→<a href=\"$cgidir/atom2msrdb_read.cgi?atom=$url_encoding\">記事</a></p>\n<hr>\n"; } $sth->finish(); $dbh->disconnect(); ##### print "</body></html>\n"; exit(0);
feeds.cgi新版の導入
ここで「feeds.cgi」をRSSフィード対応に改造しましょう。RSSをブックマークする場合は、Firefoxのブックマークに「RSS」というフォルダを作成し、保存します。Firefoxのブックマークの実体は、特定のディレクトリに格納された「bookmarks.html」というファイルです。下記のスクリプトはその部分を調べて、リストアップし、タイトルにRSSフィードのURLをパラメータとして与えた「rss2html.cgi」のハイパーリンクを出力します(「rss2html.cgi」は連載第6回で「rss2msrdb.cgi」として登場する予定で、現時点では動作しません)。
また、新しい「feeds.cgi」は、フィードの表示順序を参照頻度の高い順に上位に表示する機能を備えています。「feeds.cgi」改訂版は、参照回数を(DBMデータベースに登録された日から経過した日数+1)で割って参照頻度としています。
スクリプトは次の通りです。
#!/Perl5.8/bin/perl.exe use strict; use warnings; use URI::Escape; use CGI qw(:cgi); # bookmarks.htmlのパスの設定(ユーザー設定が必要) my $bookmarks = $ENV{'USERDIR'}."\\Application Data\\Mozilla\\Firefox\\Profiles\\nnaannnn.default\\bookmarks.html"; my $pattern; my $title; if(param('pattern')){ $pattern = param('pattern'); $title = "Feeds検索パターン: $pattern"; }else{ $pattern = ".";# ブックマークの「RSS」と「ATOM」すべてを検索する $title = "Feedsリスト"; } # 環境変数の取得 my $cgidir = $ENV{'CGIDIR'}; print <<HEADER; Content-type: text/html; charset=UTF-8 <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <link rel="stylesheet" type="text/css" href="/mystyle.css" /> <title>Feeds</title> </head> <body> <div class="emph">$title</div> <br> <table> HEADER dbmopen(my %FEEDSCOUNT, "feedscount", 0666); # アクセス数 dbmopen(my %FEEDS, "feeds", 0666); # フィードデータ dbmopen(my %FEEDSREGISTER, "feedsregister", 0666); # アクセス頻度 open(IN, "<$bookmarks"); my $insw = 0; my $cgi; my $reader; my $url; my $favorite; while(<IN>){ # if($_ =~ /^\s+<DT><H3[^>]+>WATCH<\/H3>$/){ # last; # } if(/^\s+<DT><H3[^>]+>(RSS|ATOM)<\/H3>$/){ $insw = 1; if($1 eq "RSS"){ $cgi = "rss";$reader = "rss2html.cgi";# 2007-01-28 }elsif($1 eq "ATOM"){ $cgi = "atom";$reader = "atom2msrdb.cgi";# 2007-01-28 } }elsif(/^\s+<\/DL>/i){ $insw = 0; } if($insw == 1 && $_ =~ /^\s+<DT><A HREF="(.*?)".*?>(.*?)<\/A>$/i){ $url = $1; $favorite = $2; if($favorite =~ /$pattern/o){ # 2007-01-28 $FEEDS{$url} = join("\t", $favorite , $cgi, $reader); unless($FEEDSREGISTER{$url}){ $FEEDSREGISTER{$url} = int(time/(60*60*24)); } unless($FEEDSCOUNT{$url}){ $FEEDSCOUNT{$url} = 0; } } } } close(IN); my $num; my $rate; my $url_encoding; my $favorite_encoding; foreach $url (sort {$FEEDSCOUNT{$b}/(int(time/(60*60*24)) - $FEEDSREGISTER{$b} + 1) <=> $FEEDSCOUNT{$a}/(int(time/(60*60*24)) - $FEEDSREGISTER{$a} + 1) or $a cmp $b} keys(%FEEDS)){ $num++; $rate = sprintf("%.2f",$FEEDSCOUNT{$url}/(int(time/(60*60*24)) - $FEEDSREGISTER{$url} + 1)); ($favorite, $cgi, $reader) = split(/\t/,$FEEDS{$url});# 2007-01-28 $url_encoding = uri_escape($url); $favorite_encoding = uri_escape($favorite); print "<font color=\"#000000\"><tr bgcolor=\"#eeeeee\"><td>$num
</td><td>$rate ($FEEDSCOUNT{$url})</td><td><a href=\"$cgidir/${read
er}?${cgi}=$url_encoding\" target=\"main\">$favorite</a></td><td>
$url</td><td><a href=\"$cgidir/memol_edit.cgi?url=$url_encoding
&title=$favorite_encoding\" target=\"main\">メモ作成</a></td></tr>
</font>\n";# 2007-01-28 } dbmclose(%FEEDSCOUNT); dbmclose(%FEEDS); dbmclose(%FEEDSREGISTER); print "</table><hr></body></html>\n";
まとめ
第4回、第5回で、AtomフィードをMySQLデータベースに格納し、特定の条件を満たすものを取り出し表示することができるようになりました。第6回ではRSSフィードも取り扱えるように拡張します。
現時点でのTodoリストを残しておきます。要望等がありましたら、コメントをお願いいたします。
- RSSフィードも取り扱えるように拡張
- 各フィードやエントリへのメモを取り扱えるようなインターフェイス
- インターフェイスのAjax化
- フィードデータベースを元にしたWeb日記のリデザインと自動化

oding\">記事</a></p>\n<hr>\n";
}
$sth->finish();
$dbh->