Home > 2004年 > 3月 > 10日(水) - RSSの話

RSSの話

  • Posted by:
  • WWW

昨日の日誌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を使用)完了してしまいます....生成過程は別としても,アップまでの処理が手抜きですね(ぉ

ちなみに,ソースの中でpushpopを使っている部分ですが,これは日誌の記事をその日の中だけで逆順になるように(※1)しているだけだったりします(苦笑).2回出てくるのは,その日の記事の途中で取得終了になった場合の対策ということで.それにしても何と冗長な...

  1. その日の中で逆順にしないと,最新記事が一番上に行きませんから...

Trackbacks:0

Home > 2004年 > 3月 > 10日(水) - RSSの話

Categories

Tag Cloud

OpenID accepted here

Accepted OpenID

CC Licence

Creative Commons License

このブログはクリエイティブ・コモンズでライセンスされています。

Feeds

Return to page top