Atomフィードブラウザ - atom2msrdb_read_js2.cgi
動作の概要と外観
図3は、「atom2msrdb_read_js.cgi」と同様に、著者のサイトのAtomフィードデータをAtomフィードデータベースから読み出して表示したFirefoxの画面です。データベースから読み出されたカテゴリとタイトルと更新日付がtext型の入力フォームで表示される点や、また、[PREV]ボタン、[NEXT]ボタンで記事の表示を切り替えることができる点も同じです。
一方、記事本体は、データベースのcontent
カラムあるいはsummary
カラムの内容をHTMLに変換した「atom2content.cgi」の出力をIFRAMEで表示しています。
スクリプト
「atom2msrdb_read_js2.cgi」の内容は以下の通りになります。
設定項目
- ポート番号
POST
か、スクリプトの$port
変数に設定します。- CGIディレクトリ
CGIDIR
にCGIを格納しているパスを設定します。例えば「/cgi-bin/awakenig」などです。既にCGIを使われている方は設定済みのはずです。CGIパラメータ
「atom2msrdb_read_js.cgi」と同様です。
SQLデータベースへの問い合わせとJavaScript
こちらも「atom2msrdb_read_js.cgi」と同様です。ただ、Atomバージョン0.3の場合、更新日付はmodified
要素に格納されています。そこでupdated
カラムが空の場合は、modified
カラムを読み出すように変更しています。
同様に、JavaScriptのupdateds
配列には、updated
カラムあるいはmodified
カラムの値が格納されます。
#!/Perl5.8/bin/perl.exe use strict; use warnings; use DBI; use CGI qw(:cgi); use URI::Escape; my $port = $ENV{'PORT'} || "8686";# Apacheサーバのport番号の設定 my $cgidir = $ENV{'CGIDIR'};# CGI格納ディレクトリの設定 "/cgi-bin/awakening"等 my $atomurl = ""; # Atom URL データの取得 if(param('atom')){ # CGI で URL を取得する $atomurl = param('atom'); }elsif($ARGV[0]){ # コマンドラインから URL を取得する $atomurl = $ARGV[0]; }else{ $atomurl = "http://homepage1.nifty.com/kazuf/renewal_atom.xml"; # print "Atom URL データが存在しない。\n";exit;# 終了する } # CGI 最初の部分の出力 print <<HEADER; Content-type: text/html; charset=UTF-8 <html> <head> <title>ATOM DB Browser</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <link rel="stylesheet" type="text/css" href="/mystyle.css" /> <script language="Javascript"> <!-- if(navigator.appCodeName.indexOf("Mozilla") != -1){ document.write( "<link rel='stylesheet' type='text/css' href='/firefox.css' />"); } //--> </script> </head> <body onLoad="msg(0);"> <div class="emph">Atom DB Browser</div> <script> HEADER # Atomフィードデータベース(atomfeeds)へのアクセス my $dbh = DBI->connect( "DBI:mysql:database=atomfeeds;host=localhost;port=3306", "root", "password", {'RaiseError' => 1}); ## feedsテーブルへのアクセス my $sth = $dbh->prepare(qq{ SELECT atom,link,ver,title,tagline,modified, info,logo,icon,subtitle,updated FROM feeds WHERE atom = \"$atomurl\" }); $sth->execute(); my $feed; while(my $row = $sth->fetchrow_hashref()){ $feed .= "<p><a href=\"$row->{link}\">$row->{title}</a></p><p>"; if($row->{logo}){ $feed .= "<img src=\"$row->{logo}\">"; }elsif($row->{icon}){ $feed .= "<img src=\"$row->{icon}\">"; } $feed .= "$row->{subtitle}</p><p>$row->{updated}</p>"; } ## entriesテーブルへのアクセス $sth = $dbh->prepare(qq{ SELECT atom, issued, published, link, title, content, name, modified, created, id, updated, summary, category FROM entries WHERE atom = \"$atomurl\" ORDER BY updated DESC }); $sth->execute(); ### JavaScript部分のCGI出力生成 my $dec_title; my $title = "var titles = new Array("; my $category = "var categories = new Array("; my $updated = "var updateds = new Array("; my $link = "var links = new Array("; my $count = 0; my $esc_id; my $linkstr; my $firstlink; my $year;my $cyear = (localtime(time))[5] + 1900; my $mon;(my $cmon = (localtime(time))[4] + 1) =~ s/^(\d)$/0$1/; while(my $row = $sth->fetchrow_hashref()){ $dec_title = entities_decode($row->{title}); chomp $dec_title; $dec_title =~ s/(["'])/\\$1/g; $title .= "\"$dec_title\","; $category .= "\"$row->{category}\","; my $esc_atomurl = uri_escape($atomurl); if($row->{updated}){ $updated .= "\"$row->{updated}\","; $esc_id = uri_escape($row->{updated}); }elsif($row->{modified}){ $updated .= "\"$row->{modified}\","; $esc_id = uri_escape($row->{modified}); }else{ $esc_id = uri_escape($row->{title}); } # atom2content.cgiへのリンク生成 $linkstr = "http://localhost:$port$cgidir/atom2content.cgi?atom= $esc_atomurl\&id=$esc_id"; $count++; if($count == 1){ $firstlink = $linkstr; } $link .= "\"$linkstr\","; } chop $title;print $title . ");\n"; chop $category;print $category . ");\n"; chop $updated;print $updated . ");\n"; chop $link;print $link . ");\n"; # Atomデータベースの終了 $sth->finish(); $dbh->disconnect(); # CGI 最後の部分の出力 print <<FOOTER; var i = 0; function nextLink () { i++; if(i >= links.length) i = 0; self.frames['r1'].location.href = links[i]; msg(i); } function prevLink () { i--; if(i < 0) i = links.length - 1; self.frames['r1'].location.href = links[i]; msg(i); } function msg(i) { document.form.title.value = titles[i]; document.form.category.value = categories[i]; document.form.updated.value = updateds[i]; } //--> </script> $feed <form name="form"> <p> <input type="text" name="category" size="20"> <input type="text" name="title" size="80"> </p> <p> <input type="text" name="updated" size="40"> </p> <p> <iframe name="r1" src="$firstlink" width="95%" height="65%"> </iframe> </p> <p> <input type="button" value="PREV" onclick="prevLink ();"> <-----> <input type="button" value="NEXT" onclick="nextLink ();"> </p> </form> </body> </html> FOOTER exit(0); # マークアップ記号の実体参照デコード # 文字実体参照と数値文字参照(注1)の両方に対応 sub entities_decode{ my($str) = @_; $str =~ s/(<|<|<)/</g; $str =~ s/(>|>|>)/>/g; $str =~ s/('|'|')/'/g; $str =~ s/("|"|")/"/g; $str =~ s/(&|&|&)/&/g; return $str; }