SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

PerlでデスクトップCGI

デスクトップCGIでWebとデスクトップを融合する 第5回

MySQLでAtomフィードをデータベース化 - 後編


ダウンロード ソースコード (11.0 KB)

Atomフィード単位でAtom記事を読み出すリンクを作成する

 第1回で作成した「feeds.cgi」は、FirefoxのブックマークからAtomフィードのリストを作成し、そのタイトルにAtomフィードのURLをパラメータとして与えた「atom2html.cgi」へのリンクを出力するものでした。

 今回作成する「atom2msrdb_feeds.cgi」は、「atomfeeds」データベースの「feeds」テーブルから同様なAtomフィードのリストを出力します。技術的には「atom2msrdb_read.cgi」とほとんど変わらないので説明は省略します。スクリプトは次の通りです。

atom2msrdb_feeds.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_enc
oding\">記事</a></p>\n<hr>\n";
}
$sth->finish();
$dbh->disconnect();
#####

print "</body></html>\n";
exit(0);
atom2msrdb_feeds.cgi実行画面
atom2msrdb_feeds.cgi実行画面

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)で割って参照頻度としています。

 スクリプトは次の通りです。

feeds.cgi改訂版
#!/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\\Firef
ox\\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リストを残しておきます。要望等がありましたら、コメントをお願いいたします。

  1. RSSフィードも取り扱えるように拡張
  2. 各フィードやエントリへのメモを取り扱えるようなインターフェイス
  3. インターフェイスのAjax化
  4. フィードデータベースを元にしたWeb日記のリデザインと自動化

この記事は参考になりましたか?

連載通知を行うには会員登録(無料)が必要です。
既に会員の方はを行ってください。
PerlでデスクトップCGI連載記事一覧

もっと読む

この記事の著者

jscripter(ジェイスクリプター)

NIFTY SERVEのFGALEL(エントリーラボ)、FGALTS(テキスト&スクリプト)に参画し、FGALTSでシスオペを務める。現在、TSNETメンバー。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/977 2007/03/01 10:31

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー