RssUpdate関数

「#--RssUpdate」で検索すると確実にヒットします。

この関数は、RSSファイルを更新します。

あらかじめ指定されたRSSURLからRSSファイルを取得し、あらたに入力された情報を反映させてRSSファイルを作成(更新)します。

引数はありませんが、RSSURLから更新もとのRSSファイルを取得したり、入力情報を利用したりします。

戻り値もありませんが、この関数の結果はすべてDownload関数に反映されます。

それでは処理の流れを見てみましょう。

RSSファイルの取得

あらかじめ指定されている更新もとのRSSファイルを取得します。

LWP::UserAgentとHTTP::Requestを使ってRSSファイルを取得するまでの流れは、変数名が違うだけでRSSリーダーのAnalyze関数と同じですから詳しくはそちらを参照してください。

ここでは違う部分を見ていきましょう。

まずは、更新もとのRSSファイルのURLにアクセスできなかった場合です。

if (!$response->is_success) {
my $message = $response->message;
my $size = length($message);
&Download('text/plain', $size, 'error.txt', $message);
}

アクセスできなかった場合は、エラーメッセージを作成しそのサイズを計測後、Download関数に渡してこの関数終了です。

アクセスに成功した場合は、RSSファイル本体とそのサイズだけでなく、ここではコンテンツタイプも取得します。

my $content_type = $response->content_type;
my $content_size = $response->content_length;
my $content = $response->content;

この中で、環境によって取得できないものはRSSファイルサイズです。

なのでもし取得できていない場合には、RSSリーダーのAnalyze関数内のRSSファイルサイズを計測した方法と同じやり方を使います。

リミッター

リミッターをかけている方法も同じです。

if ($content_size > ($READ_RSS_LIMITER * 1000000)) {
$content_size = &CommaFormat($content_size);
my $message = "RSS File Size Over ${content_size}bytes";
my $size = length($message);
&Download('text/plain', $size, 'error.txt', $message);
}

違うところは、Download関数にその後の処理をゆだねてこの関数が終了するところです。

更新手順

RSSファイルをXML::RSSを使って分析させたり、RSSバージョンを選定する部分は、RSSリーダーのAnalyze関数と同じです。

ここからは、RSSファイルを更新していきます。

更新情報のカット

まずは、入力画面で「TAIL CUT」をチェックした(末尾の更新情報(一番古い更新情報)をカットする)場合の処理です。

pop (@{$XML__RSS->{'items'}}) if $PARAM->{'kill'};

ページの更新情報は配列「@{$XML__RSS->{'items'}}」に新しいものから順に格納されています。

なので、pop関数を使って一番古い末尾にある更新情報をカットします。

更新情報の取得

更新情報(新たに入力された情報)を取得し、RSSの構成要素ごとに整理します。

my $input = &SplitPart($XML__RSS->{'version'});
my %channel = %{$input->{'channel'}};
my %image = %{$input->{'image'}};
my %item = %{$input->{'item'}};

SplitPart関数で処理された入力情報は、連想配列リファレンス形式で帰ってきます。

そこからさらにわかりやすくするため、チャンネル、イメージとアイテム用の連想配列に代入しなおします。

入力チェック

入力された情報の中で、チャンネルとアイテムをチェックします。

イメージは、サイトバナーがない場合もあるのでチェックしません。

if (my $message = &InputCheck(\%channel)) {
my $size = length($message);
&Download('text/plain', $size, 'error.txt', $message);
}
if (my $message = &InputCheck(\%item)) {
my $size = length($message);
&Download('text/plain', $size, 'error.txt', $message);
}

入力に不備があると、InputCheck関数からエラーメッセージが帰ってきます。

すると、if文が成立し、Download関数が呼び出されてこの関数終了です。

RSSファイルの更新

更新もとのRSSファイルから取得した情報と、入力された情報を使って、RSSファイルを更新します。

チャンネルの更新

まずは、RSSのチャンネル情報を更新します。

%{$XML__RSS->{'channel'}} = ();
%{$XML__RSS->{'channel'}} = %channel;

更新もとのチャンネルを初期化し、入力されたチャンネル情報と入れ替えます。

イメージの更新

ウェブサイトのバナーファイルURLが入力されていれば、イメージ情報を作成し更新します。

if ($image{'url'}) {
$image{'title'} = $channel{'title'};
$image{'link'} = $channel{'link'};
}
%{$XML__RSS->{'image'}} = ();
%{$XML__RSS->{'image'}} = %image;

バナーファイルのURLは、連想配列の変数「$image{'url'}」に格納されています。

もし何らかの文字列が入っていれば、if文が成立しイメージ情報を作成します。

イメージ情報は、最低でもバナーファイルのURL、タイトルとリンク先が必要です。

なので、残りのタイトルとリンク先についてはチャンネルから引用します。

イメージ情報が作成されてもされなくても、更新もとのRSSファイルのイメージ情報を初期化し入力情報と入れ替えます。

アイテムの更新

次にアイテムを更新します。

アイテムの更新とは、リスト形式で記述されている更新情報群の頭に、新たに入力された更新情報を追加することをさします。

そしてこのアイテムの更新に関しては、XML::RSSモジュールでやり方が決められています。

$item{'mode'} = "insert";
$XML__RSS->add_item(%item);

追加するアイテムの連想配列の要素に新しく「mode」を作成し、「insert」を代入します。

そして、XML::RSSのadd_item関数に追加するアイテムの連想配列を渡します。

仕上げ

各アイテムの概要(description)を、「<![CDATA[」と「]]>」ではさみます。

for (my $i=0;$i<=$#{$XML__RSS->{'items'}};$i++) {
$XML__RSS->{'items'}->[$i]->{'description'} = "<![CDATA[" . $XML__RSS->{'items'}->[$i]->{'description'} . "]]>";
}

これは、もし概要の文字列中にHTMLタグが使われていた場合、RSSのタグ(XMLのタグ)と区別するためです。

さらに、更新するRSSのバージョンを引き継がせます。

$XML__RSS->{'output'} = $XML__RSS->{'version'};

これで、更新用のRSSデータがすべてXML::RSS($XML__RSS)にセットされました。

ダウンロードの準備

最後に更新するRSSファイルをダウンロードできるように準備します。

ファイル名の作成

まずは、ダウンロードするRSSファイル名を更新もとのRSSURLから生成します。

my @parts = split(/\//, $PARAM->{'feed'});
my $file_name = pop @parts;

更新もとのRSSURLを「/」ごとに分解し、末尾のパートを取り出せばそれがファイル名になります。

RSSファイルの作成

ダウンロードするRSSファイルを作成します。

my $file_content = &Utf8Flag($XML__RSS->as_string, 'off');
my $file_size = length($file_content);

XML::RSS($XML__RSS)にセットされた更新用のRSSファイルを取り出すには、as_string($XML__RSS->as_string)を呼び出します。

さらに、それをダウンロードするのに正しくバイト数を測定する必要があるため、Utf8Flag関数でUtf8フラグを解除しlength関数で測定します。

ダウンロード

ダウンロードを促します。

&Download($content_type, $file_size, $file_name, $file_content);

作成した各データをDownload関数に渡してこの関数終了です。