毎度お世話になります。
On Sat, 03 Sep 2005 15:55:50 +0900 (JST)
Zazel <zazel.ts@...> さんwrote:
> どちらかというとそれ以前の行に問題がありそうですね。
> しかも普通なら syntax error at ファイル名 となるはずなのに
> (eval 25) となってしまうのが何かありそうです。
このeval 25は私もどういう意味なのかなと思ったのですが、聞くほうが速そ
うだと思って。
> もっとスクリプトを短くしていってエラーを出す主因を見付けないと
> だめだと思います。極端な話、1行1行削っていってエラーが出なく
> なったとき、最後に削った行が主因だろうし。もしくはエラーが出る
> スクリプトを省略せずに全部見せてくれるか。
全部載せるほうが速いので載せさせて頂きます(^^;;;
#!/PXPerl/bin/perl.exe
use encoding 'Shift_JIS';
$btime = time;# 処理開始時間取得
require 'cgi-lib.pl';
use Unicode::Japanese;
$s = Unicode::Japanese->new();
use LWP;
@header = (
'UserAgent' => "libwww-perl/$LWP::VERSION",
);
$browser = LWP::UserAgent->new;
# 環境変数の取得
$docroot = $ENV{'DOCROOT'};# ローカル HTTP サーバーのドキュメントルート
$cgidir = $ENV{'CGIDIR'};# ローカル HTTP サーバーの CGI ディレクトリ
$mp = "QT";
# RSS URL データの取得
&ReadParse(*in);
if($in{'rss'}){
# CGI で URL を取得する
$getfile = $in{'rss'};
}elsif($ARGV[0]){
# コマンドラインから URL を取得する
$getfile = $ARGV[0];
}else{
print "RSS URL データが存在しない。\n";
exit;# 終了する
}
# CGI 最初の部分の出力
print <<HEADER;
Content-type: text/html
<HTML>
<HEAD>
<TITLE>RSS Reader</TITLE>
<META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=Shift_JIS\">
<LINK REL=\"STYLESHEET\" TYPE=\"text/css\" HREF=\"/mystyle.css\">
</HEAD>
<BODY>
<div class=\"emph\">ニュース</div>
HEADER
# RSS URL の RSS ファイルを取得
unless($res = $browser->get($getfile,@header)){
print "<p>LWP::UserAgentのget関数がundef値を返しました。</p></BODY></HTML>\n";
exit;
}
$content = $res->content;# UserAgentのget関数の戻り値
# エンコーディングの取得
if($content =~ /<\?xml +version="1.0" +encoding="([^"]+)" *\?>/){
$encoding = $1;$enc = $encoding;
$encoding =~ s/^Shift_*JIS$/sjis/i; # シフト JIS
$encoding =~ s/^euc-*j*p*$/euc/i; # EUC-JP
$encoding =~ s/^utf-*8$/utf8/i; # UTF-8
$encoding =~ s/^ISO-8859-1$/ascii/i;# ISO-8859-1
$encoding =~ s/^us-ascii$/ascii/i; # US-ASCII
$encoding =~ s/^ISO-2022-JP$/jis/i; # JIS
}
if($encoding eq ""){
# エンコーディング情報のないものは、UTF-8 とする
# 実際のRSSファイルにはXMLを宣言する行、<?xml...?>自体がないものもある
$encoding = "utf8";$enc = "None";
}
# エンコーディング情報をもとに、シフト JIS 文字コードに変換
$content = $s->set($content,$encoding)->sjis;
# RSS ファイルの解析
# 解析用の前処理: 文字列データから行頭行末の空白を取り除き、改行文字を削除する
$content =~ s/[ \t]*[\r\n]+[ \t]*//g;
# 終了タグの後に改行を入れる
$content =~ s/(<\/[^>]+>)/$1\n/g;
# 主要素の開始タグの後に改行を入れ、要素タグのみの行を作る
$content =~ s/(<channel[^>]*>)/$1\n/;
$content =~ s/(<image[^>]*>)/$1\n/g;
$content =~ s/(<item[^>]*>)/$1\n/g;
# データ文字列を改行で分割して、行単位のデータで配列に格納する
@content = split(/\n+/, $content);
# データを行単位で処理する。
foreach $line (@content){
# RSS バージョンの取得
if($line =~ /<rss.+?version\s*=\s*['"](.+?)['"]/i){
# Rich Site Summary/Really Simple Syndicationのバージョン取得
$ver = $1;
}elsif($line =~ /xmlns\s*=\s*"http:\/\/purl\.org\/rss\/(.+?)\/"/){
# RDF Site Summary 1.0 のバージョンの取得
$ver = $1;
}elsif($line =~ /xmlns\s*=\s*"http:\/\/my\.netscape\.com\/rdf\/simple\/0\.9\/"/){
# RDF Site Summary 0.9 のバージョンの取得
$ver = "0.9";
}
# rdf:RDF か rss のルート要素からXML 名前空間のリストを得る
if($line =~ /(<rdf:RDF|<rss)/i){
@nss = ($line =~ /(xmlns:?\w*?\s*=\s*["'].+?["'])/ig);
}
# CDATA セクションの処理 <![CDATA[・・・]]> の除去と実体参照エンコード
if($line =~ /<[^>]+><!\[CDATA\[/i && $line !~ /\]\]><\/[^>]+>/){
$line =~ s/<[^>]+><!\[CDATA\[//i;
$cdatasw = 1;
$cdata = $line;
}elsif($cdatasw == 1 && $line !~ /\]\]><\/[^>]+>/){
$line =~ s/<!\[CDATA\[//gi;
$line =~ s/\]\]>//g;
$cdata .= $line;
}elsif($cdatasw == 1 && $line =~ /\]\]><\/[^>]+>/){
$line =~ s/\]\]><\/([^>]+)>//;
$prop = $1;
$cdata .= $line;
$line = "<$prop>" . &entities_encode($cdata) . "</$prop>";
$cdatasw = 0;$cdata = "";
}
# channel、item、image 要素開始の判定
if($line =~ /<channel/){
$csw = 1;
}elsif($line =~ /<item( |>)/){
$isw = 1;$csw = 0;
}elsif($line =~ /<image/){
$imgsw = 1;$csw = 0;
}
# 要素データを主要素毎に要素名をキーとして取得
if(($buff = $line) =~ s/<\/?([^>]+)>//g){
# channel 要素の格納
if($csw == 1){
$channel{$1} = $buff;
}
# image 要素の格納
if($imgsw == 1){
$image{$1} = $buff;
}
# item 要素の格納
if($isw == 1){
if($1 eq 'guid'){
# RSS 2.0 の guid 要素は、isPermaLink属性が true の場合には URL
if($line =~ /isPermaLink\s*=\s*['"]true['"]/i){
$item{'guid'} = $buff;
}
}else{
$item{$1} = $buff;
}
}
}
# enclosureタグからURL属性を取得する
if($line =~ /<enclosure +url="([^"]+)"[^>]+>/){
$item{'enclosure_url'} = $1;
}
# channel 要素終了の判定
if($csw == 1 && $line =~ /<\/channel>/){
$csw = 0;# RSS 1.0
}
# image 要素終了の判定
if($imgsw == 1 && $line =~ /<\/image>/){
$imgsw = 0;
}
# item 要素終了の判定と item ごとのデータの格納
if($isw == 1 && $line =~ /<\/item>/){
# item 日付要素の選択
# Dublin Core モジュールの dc:date 要素があれば、
if($item{'dc:date'}){
$item{'date'} = $item{'dc:date'};
$elms{'dc:date'} = 1;# マッチした要素の収集
# RSS 2.0 の pubDate 要素があれば、
}elsif($item{'pubDate'}){
$item{'date'} = $item{'pubDate'};
$elms{'pubDate'} = 1;
}
# 表示要素追加時チェック部(1)
push(@items, join("\t",$item{'date'},$item{'link'},$item{'guid'},$item{'title'},$item{'dc:description'},$item{'description'},$item{'content:encoded'},$item{'dc:subject'},$item{'category'},$item{'dc:creator'},$item{'author'},$item{'slash:department'},$item{'prism:publicationName'},$item{'enclosure_url'}));
$isw = 0;%item = ();
}
}
# channel 要素の description 要素を実体参照デコードしておく
$channel{'description'} = &entities_decode($channel{'description'});
# 実体参照への変換が二重に行われている場合の対応
if($channel{'description'} =~ /&[a-z0-9]{2};/){
$channel{'description'} = &entities_decode($channel{'description'});
}
# image 要素データがある場合とない場合に分けて HTML 出力の仕方を指定
# image 要素データがある場合には、channel 主要素の title 要素
if($image{'url'}){
print "<dl><dt><a href=\"",$channel{'link'},"\" target=\"main\">", $channel{'title'}, "</a><dd><p><a href=\"",$image{'link'},"\" target=\"main\"><img src=\"",$image{'url'},"\"></a> ",$channel{'description'},"</p></dl>\n";
}else{
print "<dl><dt><a href=\"",$channel{'link'},"\" target=\"main\">", $channel{'title'}, "</a><dd><p>",$channel{'description'},"</p></dl>\n";
}
# item 要素データを HTML 表に変換して出力
print "<table border=0>\n";
# item ごとに表示要素を処理する
foreach $item (@items){
# 表示要素追加時チェック部(2)
($date,$ilink,$iguid,$ititle,$idescription,$rdescription,$cdescription,$isubject,$rcategory,$icreator,$rauthor,$sdepartment,$prismpubname,$enclosure_url) = split(/\t/,$item);
print "<tr bgcolor=\"#eeeeee\">";
# タイトルとリンクの処理
if($ititle){
$title = &entities_decode($ititle);
# 実体参照への変換が二重に行われている場合の対応
if($title =~ /&[a-z0-9]{2};/){
$title = &entities_decode($title);
}
# タイトルにリンクがある場合は、別にリンクする
if($title =~ s/(<a.+?)>(.+?)(<\/a>)/$2/i){
$titlelink = " -> $1 target=\"main\">LINK$3";
}else{
$titlelink = "";
}
# RDF/RSS の item 主要素の link 要素の場合
if($ilink){
print "<td><font color=\"#000000\"><a href=\"", $ilink, "\" target=\"main\">", $title, "</a></font>$titlelink</td>";
$elms{'link'} = 1;
# RSS 2.0 の guid 要素の場合
}elsif($iguid){
print "<td><font color=\"#000000\"><a href=\"", $iguid, "\" target=\"main\">", $title, "</a></font>$titlelink</td>";
$elms{'guid'} = 1;
}else{
print "<td><font color=\"#000000\">$title</font>$titlelink</td>";
}
$elms{'title'} = 1;
}else{
# タイトルがない場合は、リンク文字列にリンクしてタイトルに表示する
# RDF/RSS の item 主要素の link 要素の場合
if($ilink){
if($ilink !~ /http:/){ # PATH のみの URL の場合、
($linkhead = $channel{'link'}) =~ s/^(http:\/\/.+?\/)(~\w+?\/)*.*$/$1$2/; # channel のリンクから BASE URL を取り出し、
$ilink = $linkhead . $ilink; # PATH に URL を付加する。
}
print "<td><font color=\"#000000\"><a href=\"", $ilink, "\" target=\"main\">", $ilink, "</a></font></td>";
$elms{'link'} = 1;
# RSS 2.0 の guid 要素の場合
}elsif($iguid){
print "<td><font color=\"#000000\"><a href=\"", $iguid, "\" target=\"main\">", $iguid, "</a></font></td>";
$elms{'guid'} = 1;
}
}
# 表示要素追加時チェック部(3)
# item 記事要素に相当する要素の処理
if($idescription){
# Dublin Core モジュールの dc:description 要素
$description = &entities_decode($idescription);
$elms{'dc:description'} = 1;
}elsif($rdescription){
# RDF/RSS の item 主要素の description 要素
$description = &entities_decode($rdescription);
$elms{'description'} = 1;
}elsif($cdescription){
# content モジュールの content:encoded 要素
$description = &entities_decode($cdescription);
$elms{'content:encoded'} = 1;
}
# 実体参照への変換が二重に行われている場合の対応
if($description =~ /&[a-z0-9]{2};/){
$description = &entities_decode($description);
}
# item 記事相当要素の出力
if($description){
# HTML 表の表示が乱れるため、<p>タグは除去、</p>タグを<br>に置換して出力
$description =~ s/<p.*?>//ig;
$description =~ s/<\/p>/<br>/ig;
print "<td>",$description,"</td>\n";$description = "";
}
# item 日付要素
if($date){
print "<td>",$date,"</td>\n";
}
# item 製作者要素
if($icreator){
# Dublin Core モジュールの dc:creator 要素
print "<td>",$icreator,"</td>\n";
$elms{'dc:creator'} = 1;
}elsif($author){
# RSS 2.0 の item 主要素の author 要素
print "<td>",$author,"</td>\n";
$elms{'author'} = 1;
}
# item カテゴリー要素
if($isubject){
$isubject = &entities_decode($isubject);
if($isubject =~ /&[a-z0-9]{2};/){
$isubject = &entities_decode($isubject);
}
print "<td>",$isubject,"</td>\n";
$elms{'dc:subject'} = 1;
}elsif($rcategory){
print "<td>",$rcategory,"</td>\n";
$elms{'category'} = 1;
}
# Slash モジュールの item 特殊分類要素
if($sdepartment){
$sdepartment = &entities_decode($sdepartment);
print "<td>",$sdepartment,"</td>\n";
$elms{'slash:department'} = 1;
}
# PRISM モジュールの item 特殊分類要素
if($prismpubname){
print "<td>",$prismpubname,"</td>\n";
$elms{'prism:publicationName'} = 1;
}
# RSS 2.0のenclosureタグのurl属性
#<A HREF SRC="MyMovie.qtl"> Click Here for a QuickTimeMovie </A>
#Important
#For this to work, your Web server must be configured to associate
#the .qtl file extension with the correct MIME type:
#.qtl = application /x-quicktimeplayer
#MyMovie.qtl
#<?xml version="1.0"?>
#<?quicktime type="application/x-quicktime-media-link"?>
#<embed src="http://www.myserver.com/Movies/My.mov" />
if($enclosure_url){
if($enclosure_url !~ /\.mp3/i){
$count++;
if($mp eq "QT"){
open(QT,"> qt${count}.qtl");
print QT "<?xml version=\"1.0\"?>\n";
print QT "<?quicktime type=\"application/x-quicktime-media-link\"?>\n";
print QT "<embed src=\"$enclosure_url\" autoplay=\"true\" />\n";
close(QT);
print "<td><a href=\"./qt${count}.qtl\">Podcast</a></td>\n";
}elsif($mp eq "WM"){
open(WM,"> wm${count}.asx");
print WM "<ASX version=\"3.0\">\n";
print WM "<Entry>\n<Ref href=\"$enclosure_url\" />\n</Entry>\n</ASX>\n";
close(WM);
print "<td><a href=\"./wm${count}.asx\">Podcast</a></td>\n";
}
}else{
print "<td><a href=\"$enclosure_url\" target=\"status\">Podcast</a></td>\n";
}
# print "<td><a href=\"",$enclosure_url,"\" target=\"_blank\">Podcast</a></td>\n";
# print "<td><a href=\"",$enclosure_url,"\">Podcast</a></td>\n";
}
# メモ作成用「メモる」システム CGI、memol_edit.cgiへのタイトルとリンク出力
if($ilink){
$ilink_encoding = &juri_encode($ilink);
}elsif($iguid){
$ilink_encoding = &juri_encode($iguid);
}
$ititle_encoding = &juri_encode($ititle);
print "<td><a href=\"$cgidir/memol_edit.cgi?url=$ilink_encoding&title=$ititle_encoding\" target=\"main\">メモ作成</a></td>\n";
}
print "</tr></table>\n";# RSS ファイルの記事内容表出力終了
print "<hr>\n";
# 解析したRSSファイルの情報を表示する
# エンコーディングの表示
print "エンコーディング: $enc<br><br>\n";
# 表示要素追加時チェック部(4)
# RSS/モジュールとRSS要素の表を作成する
foreach $elm (sort keys(%elms)){
if($elm !~ /:/){
$mod{$ver} .= $elm . "\t";# RSSバージョンデフォルト要素
}elsif($elm =~ /^dc:/){
$mod{'Dublin Core'} .= $elm . "\t";# Dublin Core モジュール要素
}elsif($elm =~ /^content:/){
$mod{'Content'} .= $elm . "\t";# Content モジュール要素
}elsif($elm =~ /^slash:/){
$mod{'Slash'} .= $elm . "\t";# Slash モジュール要素
}elsif($elm =~ /^prism:/){
$mod{'PRISM'} .= $elm . "\t";# PRISM モジュール要素
}
}
print "<table border=0><tr bgcolor=\"#eeeeee\"><th>RSS/モジュール</th><th>item 表示要素</th></tr>\n";
foreach $key (sort keys(%mod)){
print "<tr bgcolor=\"#eeeeee\"><td>$key</td><td>$mod{$key}</td></tr>\n";
}
print "</table><br>\n";
# XML 名前空間のリストを表示
print "<table border=0><tr bgcolor=\"#eeeeee\"><th>XML 名前空間</th><tr>\n";
if(@nss){
foreach $ns (sort @nss){
print "<tr bgcolor=\"#eeeeee\"><td>$ns</td></tr>\n";
}
}else{
print "<tr bgcolor=\"#eeeeee\"><td>None</td></tr>\n";
}
print "</table><br>\n";
print "<hr>\n";
# 表示に要した秒数を計算して出力
$etime = time - $btime;
print "表示に要した時間: $etime 秒<br>";
# HTML 出力終了
print "</BODY>\n</HTML>\n";
# サブルーチン
# Jperl 用 URL エンコーディング
sub juri_encode{
my($str) = @_;
$str =~ s/([^a-z0-9\-_.!*'\(\)~ ])/blength($1) == 2 ? sprintf "%%%1s%1s%%%1s%1s", split("",unpack("H4", $1)) : sprintf "%%%02X", ord($1)/egi;
$str =~ tr/ /+/;
return $str;
}
sub blength{
my($s) = @_;
use bytes;
return bytes::length($s);
}
# マークアップ記号の実体参照デコード
# 文字実体参照と数値実体参照の両方に対応
sub entities_decode{
my($str) = @_;
$str =~ s/(<|<)/</g;
$str =~ s/(>|>)/>/g;
$str =~ s/('|')/'/g;
$str =~ s/("|")/"/g;
$str =~ s/(&|&)/&/g;
return $str;
}
# マークアップ記号の実体参照エンコード
sub entities_encode{
my($str) = @_;
$str =~ s/&/&/g;
$str =~ s/</</g;
$str =~ s/>/>/g;
$str =~ s/'/'/g;
$str =~ s/"/"/g;
return $str;
}
藤岡 和夫
kazuf@...
TS Networkのために http://homepage1.nifty.com/kazuf/