SHOEISHA iD

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

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

PerlでデスクトップCGI

デスクトップCGIフレームワークでDHTMLを実現する

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


  • X ポスト
  • このエントリーをはてなブックマークに追加

Atomフィードブラウザ - atom2msrdb_read_js2.cgi

動作の概要と外観

 図3は、「atom2msrdb_read_js.cgi」と同様に、著者のサイトのAtomフィードデータをAtomフィードデータベースから読み出して表示したFirefoxの画面です。データベースから読み出されたカテゴリとタイトルと更新日付がtext型の入力フォームで表示される点や、また、[PREV]ボタン、[NEXT]ボタンで記事の表示を切り替えることができる点も同じです。

 一方、記事本体は、データベースのcontentカラムあるいはsummaryカラムの内容をHTMLに変換した「atom2content.cgi」の出力をIFRAMEで表示しています。

図3 atom2msrdb_read_js2.cgi実行画面
図3 atom2msrdb_read_js2.cgi実行画面

スクリプト

 「atom2msrdb_read_js2.cgi」の内容は以下の通りになります。

設定項目

  • ポート番号
  • Apacheサーバの動作しているポート番号を環境変数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カラムの値が格納されます。

atom2msrdb_read_js2.cgi
#!/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 ();">
  &lt;-----&gt; 
  <input type="button" value="NEXT" onclick="nextLink ();">
</p>
</form>
</body>
</html>
FOOTER

exit(0);
# マークアップ記号の実体参照デコード
# 文字実体参照と数値文字参照(注1)の両方に対応
sub entities_decode{
  my($str) = @_;
  $str =~ s/(&lt;|&#60;|&#x3C;)/</g;
  $str =~ s/(&gt;|&#62;|&#x3E;)/>/g;
  $str =~ s/(&apos;|&#39;|&#x27;)/'/g;
  $str =~ s/(&quot;|&#34;|&#x22;)/"/g;
  $str =~ s/(&amp;|&#38;|&#x26;)/&/g;
  return $str;
}

次のページ
Atomフィードブラウザのコンテンツ出力用CGI - 「atom2content.cgi」

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

  • X ポスト
  • このエントリーをはてなブックマークに追加
PerlでデスクトップCGI連載記事一覧

もっと読む

この記事の著者

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

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

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

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

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/1189 2007/05/22 11:44

おすすめ

アクセスランキング

アクセスランキング

イベント

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

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

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

メールバックナンバー

アクセスランキング

アクセスランキング