昨日の日誌でRSSのエラーの話を書いてしまったので,それ繋がりで少し(^^;
ありみかさんがさとみかんでのRSS生成について少しだけ説明していましたので,こっちの生成方法も暴露してしまいます(苦笑).
うちのRSS生成についても,実はかなり手抜きでして,日誌フォルダにあるファイルの一覧を取ってきて,そこから数字のみのファイル名を抽出→ソート→HTMLファイル読み込み→データの抽出→出力なんてことをPerlでやってます.ちょっと長いけど以下ソース.
#!/usr/bin/perl
use Jcode;
my $jconv = new Jcode;
$maxdata = 15; #最大抽出記事数
$date_title = "h2"; #年月日を取得する際の直前の要素
$item_title = "h3"; #タイトルとリンクを抜き出す要素
$item_descr = "p"; #説明文を抜き出す要素
$host = "http://kita2.net/nisshi/";
$dir = "(日誌ファイルのあるフォルダ)";
opendir DIR, $dir;
@fileex = readdir DIR;
closedir DIR;
for ($x = 0; $x <= $#fileex; $x++) {
$fileex[$x] =~ s/^n_([0-9]+)\.html$/$1/g;
if ($fileex[$x] =~ /^\D/) {
if ($x == $#fileex) {
$fileex[$#fileex] = 1;
last;
}
splice(@fileex,$x,1);
redo;
}
}
@fnm = sort {$b cmp $a} @fileex;
$p = 0; # ポインタ
open(IN, "$dir/n_$fnm[0].html");
($x,$x,$x,$x,$x,$x,$x,$x,$x,$ftime) = stat IN;
($sec,$min,$hour,$mday,$mon,$year) = gmtime $ftime;
$year += 1900;
$mon += 1;
$update = sprintf("%d-%02d-%02dT%02d:%02d:%02d+09:00",$year,$mon,$mday,$hour,$min,$sec);
$p = &filerss_conv("n_$fnm[0].html");
if ($p < $maxdata) {
open(IN, "$dir/n_$fnm[1].html");
$p = &filerss_conv("n_$fnm[1].html");
}
open(OUT,">$dir/rss.rdf");
#以下、RSSの構文に従って出力
print OUT $jconv->set(\<<EOF)->utf8; # 出力時にまとめてUTF-8へ変換
<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet href="nisshi.xsl" type="text/xsl"?>
<rdf:RDF
xmlns="http://purl.org/rss/1.0/"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xml:lang="ja">
<channel rdf:about="http://kita2.net/nisshi/rss">
<title>HashiMのたわごと(?) - 最新$maxdata記事 -</title>
<link>$host</link>
<description>HashiMの日常の出来事をつらつらと並べ立てた日記のようなもの</description>
<dc:date>$update</dc:date>
<dc:creater>HashiM</dc:creater>
<items>
<rdf:Seq>
EOF
foreach $ttl (0..$maxdata-1) {
print OUT "\t<rdf:li rdf:resource=\"$link[$ttl]\" />\n";
}
print OUT $jconv->set(\<<EOF)->utf8; # 出力時にまとめてUTF-8へ変換
</rdf:Seq>
</items>
</channel>
EOF
foreach $i (0..$maxdata-1){
print OUT $jconv->set(\<<EOF)->utf8;
<item rdf:about="$link[$i]">
<title>$title[$i]</title>
<link>$link[$i]</link>
<description>$descr[$i]</description>
<dc:date>$ymd[$i]</dc:date>
</item>
EOF
}
print OUT "</rdf:RDF>\n";
close(OUT);
exit;
#--------------------------------------------------------------------
sub filerss_conv {
local($name) = @_;
local(@tlk,@ttl,@tstr,@tymd,$titm);
while(<IN>){
if (m|<${date_title} id="n\d+">(\d+)年 ?(\d+)月 ?(\d+)日|) {
$date = sprintf("%d-%02d-%02d",$1,$2,$3);
}
elsif (m|<${item_title} id="(.*?)">(.*?)</${item_title}>|) {
$tlk[$titm] = $host . $name . "#" . $1;
$ttl[$titm] = $2;
$ttl[$titm] =~ s/<.*?>//g; #不要なマークアップを削除
$isItem = 1;
}
elsif (m|<${item_descr}.*?>(.*?)</${item_descr}>| and $isItem) {
$str = $1;
$str =~ s/<.*?>//g; #不要なマークアップを削除
$tstr[$titm] = $str;
$tymd[$titm] = $date;
$isItem = 0; #説明文は1要素だけにしておく
$titm++;
}
elsif (m|<div class="day|) {
foreach $pend (0..$titm-1) {
push(@link, pop(@tlk));
push(@title, pop(@ttl));
push(@descr, pop(@tstr));
push(@ymd, pop(@tymd));
$p++;
if ($p == $maxdata) { last; }
}
$titm = 0;
if ($p == $maxdata) { last; }
}
}
if ($titm) {
foreach $pend (0..$titm-1) {
push(@link, pop(@tlk));
push(@title, pop(@ttl));
push(@descr, pop(@tstr));
push(@ymd, pop(@tymd));
$p++;
if ($p == $maxdata) { last; }
}
}
close(IN);
return($p);
}
なんか配列変数の関係はかな~り無駄なことをやっている気がするのですが,一応これをコマンドライン上でperl (フォルダ名)rss.cgi
とするだけにしてます.すると勝手にnisshiフォルダ内にRSSが出来上るって感じ(苦笑).FTPアップ時には,更新されたファイルのみを転送するようにしてやれば(FFFTPを使用)完了してしまいます....生成過程は別としても,アップまでの処理が手抜きですね(ぉ
ちなみに,ソースの中でpush
とpop
を使っている部分ですが,これは日誌の記事をその日の中だけで逆順になるように(※1)しているだけだったりします(苦笑).2回出てくるのは,その日の記事の途中で取得終了になった場合の対策ということで.それにしても何と冗長な...
- その日の中で逆順にしないと,最新記事が一番上に行きませんから...
Trackbacks:0
- TrackBack URL for this entry
- http://kita2.net/mt/mt-tb.cgi/486
- Listed below are links to weblogs that reference
- RSSの話 from HashiMのたわごと(?)