/ / 最新

swk's log - MHonArc の index から RSS

2005-03-07

* MHonArc の index から RSS [tech]

arpwatch を仕込んだ話 [2005-02-25-4] の続き,というか詳細.

基本方針としては,/etc/aliases の中で mhonarc を呼んでいるところで, mhonarc を mhonarc-rss なるスクリプトで置き換えることにする. mhonarc-rss は内部で mhonarc を呼び,続いて RSS を生成する.

手抜きのため,以下のような前提を置いている.

  • mhonarc を呼ぶときには -outdir が指定されている.このディレクトリ名がメーリングリスト名である
  • この出力ディレクトリは「http://www.example.org/ml/メーリングリスト名/」のような,メーリングリスト名で終わる URL で公開される
  • RSS の配布もこのディレクトリで行う (index.rdf)

以下のスクリプト mhonarc-rss とテンプレートファイル mhonarc_idx.tt をどこかに置く.スクリプトの # -- config -- の辺りを適当に書き換える.テンプレートも,各サイトの MHonArc のインデックスのフォーマットに合わせて適当に直す.スクリプトの元ネタは以下のページ:

mhonarc-rss:

#!/usr/local/bin/perl
# mhonarc-rss - generate RSS feed from MHonArc index
# derived from: 
# ttrss.pl - Generate feed from a site which is grabbable with Template::Extract.
# 2004.01.11 Naoya Ito <naoya@naoya.dyndns.org>
# 2005.03    modified by swk(at)kagami.org

use strict;
use warnings;
use Template::Extract;
use XML::RSS;
use FileHandle;
use URI;
use Jcode;

# -- config ---
my $template_path = "/path/to/mhonarc_idx.tt";
my $uribase = "http://www.example.org/ml/";
my $num_items = 20;
my $mhonarc_path = "/usr/local/bin/mhonarc";
# -------------

&run_mhonarc_sync(@ARGV);

my $outdir = "";
while (@ARGV) {
    if ($ARGV[0] eq "-outdir") {
        $outdir = $ARGV[1];
        last;
    }
    shift;
}
if ($outdir eq "") {
    # no -outdir specified
    exit;
}

$outdir =~ m#/([^/]+)/?$#;
my $listname = $1;

eval {
    local $/; # read from file at once
    my $fh_idx = FileHandle->new("${outdir}/index.html")
        or die "cannot open ${outdir}/index.html: $!";
    my $document = $fh_idx->getline;
    $fh_idx->close;
 
    local $/; # read from file at once
    my $fh_t = FileHandle->new($template_path)
        or die "cannot open $template_path: $!";
    my $template = $fh_t->getline;
    $fh_t->close;

    my $obj = Template::Extract->new;
    my $ext = $obj->extract($template, $document);
 
    my $rss = XML::RSS->new;
    $rss->channel( title => "ML: $listname",
                   link  => "$uribase$listname/",
                   description => "RSS feed from $listname mailing list");
    for my $item (@{$ext->{items}}) {
        $rss->add_item(
            title => $item->{title},
            link  => URI->new_abs($item->{link}, "$uribase$listname/"),
        );
        $num_items--;
        last if ($num_items <= 0)
    }

    my $fh_rdf = FileHandle->new("> ${outdir}/index.rdf");
    print $fh_rdf Jcode->new($rss->as_string)->utf8;
    close($fh_rdf);
}; if (my $err = $@) {
    die;
}

sub run_mhonarc_sync
{
    my @args = @_;
    unshift(@args, $mhonarc_path);
    my $pid;   

    if (($pid = fork()) == 0) {
        exec(@args);
        die;
    } elsif ($pid < 0) {
        die;
    }
    
    wait;
}

mhonarc_idx.tt:

<ul>
<li><a href="threads.html">Thread Index</a></li>
</ul>
[% ... %]
<hr>
<ul>
[% FOREACH items %]
<LI><STRONG><a name="[% ... %]" href="[% link %]">[% title %]</a></STRONG>
<UL><LI> [% yy %]/[% mm %]/[% dd %] &nbsp; <EM>From</EM>: [% from %]</LI></UL>
</LI>
[% END %]

/etc/aliases 等で mhonarc を呼んでいる部分は,たぶん以下のようになっていると思うので (ここでは arpwatcher というメーリングリストの例),

arpwatcher-mhonarcadd: "|/usr/local/bin/mhonarc -quiet -add -rcfile /path/to/mhonarc.rc -outdir /path/to/ml/arpwatcher"

これを次のように変える.mhonarc の代わりに mhonarc-rss を呼ぶように変えるだけ.

arpwatcher-mhonarcadd: "|/path/to/mhonarc-rss -quiet -add -rcfile /path/to/mhonarc.rc -outdir /path/to/ml/arpwatcher"

しばらく動かしてみて思ったこと.RSS ってメール程の速報性はないので, arpwatch のように 1 分 1 秒でも早い情報が重要な用途にはただのメールの方がいいのかなあ,とか身も蓋もないことを感じた.もうちょっと中程度の速報性が要求されるもの向きだな.

[ コメントを全部見る / コメントを書く] [ TrackBack ( )] [固定リンク]

* [Herman] I feel staisiefd after reading that one.... (2013-03-23 10:41:41)

最終更新時間: 2009-01-04 15:31


Shingo W. Kagami - swk(at)kagami.org