カラクリサイクル

『輝かしい青春』なんて失かった人の雑記

blosxomで動的なページを静的生成させるスクリプトを書いた

概要: blosxomで生成される動的なページを静的生成する。


昨日の事なんだけど、今の空繰再繰、無貌断片は表示以外の処理をサーバサイドでしてないから、 なんとか静的生成できないかなぁと考えていて、そうだHTTP::Request::AsCGI使えばできるんじゃね? と思いついたので実際にスクリプトを書いていました。

で、以下が昨日と今日の成果。

blosxom-static.pl

#!/usr/bin/perl

use strict;
use warnings;

our $VERSION = '0.1';

use Getopt::Long;
use Perl6::Say;
use YAML::Tiny;
use HTTP::Request;
use HTTP::Request::AsCGI;
use Path::Class;

my $config_file = q{};
my $request     = q{};
my $output      = q{};
my $version;

GetOptions(
    '--config=s'    => \$config_file,
    '--request=s'   => \$request,
    '--output=s'    => \$output,
    '--version'     => \$version,
) or die "Usage: $0 --config={config}.yaml --request={http://host.name/foo/bar} --output={/path/to/output.html}";

if ( $version ) {
    say "$0 - $VERSION";
}

# -- load configuration file --------- #

my $config = YAML::Tiny::LoadFile( $config_file );

# -- setup blosxom ------------------- #

my $blosxom = $config->{'blosxom'} or die "blosxom path is not specified.";

# -- setup request ------------------- #

my $env = $config->{'env'} || {};

print "request ${request} ...";

my $req = HTTP::Request->new( GET => $request );
my $ctx = HTTP::Request::AsCGI->new( $req, %{ $env } )->setup;

# -- run blosxom --------------------- #

do $blosxom;
die $@ if ( $@ );

# -- get response -------------------- #

          $ctx->restore;
my $res = $ctx->response;

# -- save file ----------------------- #

if ( $res->code eq '200' ) {
    my $body = $res->content;

    my $file = file( $output )->absolute->cleanup;

    if ( ! -d $file->dir ) {
       $file->dir->mkpath or die "Failed to mkpath: $!";
    }

    my $fh = $file->openw;
    print $fh $body;
    close($fh);

    say "generated.";
}
else {
    say $res->code;
}

使い方は上記のスクリプトをblosxom-static.plという名前あたりで保存、 で、下記のようなYAML設定ファイルを用意する。

config.yaml

blosxom: /path/to/blosxom.cgi

env:
  ENV_FOO: value
  ENV_BAR: value
  ENV_BAZ: value

で、あとはスクリプトに実行権限をつけて、

./blosxom-static.pl --config=./config.yaml --request={リクエストするURI} --output={ファイルを保存するパス}

で実行するとステータスコードが200の場合にのみ、 --requestで指定したURIのページが--outputに生成されます。

あとはこのスクリプトを生成したいURI毎に叩いてやればblosxomのページが静的生成されるという寸法です。 あと自分の環境でテストした範囲ではうまく動いてくれましたが、生成するURIによっては環境変数をenv:で指定してやらないと うまく変数が設定されないという場合もあるかもしれません。

で、実際のところ本当は、

variable:
  year:
    start: 2006
    end:   2009
  month:
    start: 1
    end:   12
    format: %02d
  day:
    start: 1
    end:    31
    format: %02d

generate:
  - request: http://blog.nyarla.net/{year}/{month}/{day}/{section}
    path:    /{year}/{month}/{day}/{section}.html

みたいなYAMLファイルを食わせると、総当りでURIを生成して自動的にコマンドを叩くスクリプトを書いてたりしたんですが、 色々試した結果、404になるURIが大量に生成されるとかなんとかでお蔵入りしました。

まあ昨日はURIを総当りで生成する部分まで完成して、blosxomを連続で実行する部分で躓いていたんですが、 今日外部コマンド経由でblosxomを実行することを思いつき、一応完成しました。 が、上記の通り使い物にならなかったので、blosxomを一回実行してページを生成するスクリプトのみの公開となりましたとさ。

あとはまあblosxomの$entries_dir読み込んでURIを手作業で生成するスクリプトでも書いてやればいいかなぁと思ってます。 今はめんどくさくなって書いてないけど。

あと静的生成できるようにしてやればサーバの負荷軽減できてウハウハじゃね?とか思ってたんですが、 静的生成したページを今のURIに配置してやるのが面倒だったり (今のwww以下はSubversionで自動チェックアウトさせてたりする)、 ローカルのサーバ環境でのテストとかめんどくさくなりそうですよししょーな感じなので、 結局このスクリプトもお蔵入りかなぁという感じです。 まあスクリプト書いてたときは楽しかったからいいんだけど、結局徒労に終わってるんじゃね?と思わなかったり。

まあblosxomの動的生成ページを静的生成させたいという場合には上記のスクリプトを使ってみるといいかも知れません。