検索結果をアクセスランキング順にソートする方法(3)2006年03月23日 11時22分44秒

(3)では、リンクをクリックした時に、アクセス数をカウントする部分を紹介します。

次の link.cgi を /cgi-bin/ に置きます。

  • 1行目のPerl のパスは各環境に合わせて書き換えます。
  • link.cgi には chmod +x で実行属性を付けます。
  • $index にはインデックスのパスを指定します。
  • Replace 部分は、.namazurc で設定した逆のものを設定します。(逆変換)
  • インデックスのあるディレクトリは、CGI の実行ユーザに対して書き込み許可が必要です。

#!/usr/bin/perl

use CGI;
use Fcntl;
use SDBM_File;
use Config;

sub safe_die($);

my $index = "/usr/local/var/namazu/index";

my $query = new CGI;
my $uri = $query->param('uri');
my $path = $uri;

# Replace
$path =~ s!^http://www.foo.bar.jp/~foo/!/home/foo/public_html/!s;

my $flags = O_CREAT | O_RDWR | BINARY();

tie( %dbhash, 'SDBM_File', "$index/NMZ.sdbm.accessrank", 
        $flags, 0666)
        or safe_die("Cannot open database $!");

chmod 0666, 'NMZ.sdbm.accessrank.dir', 'NMZ.sdbm.accessrank.pag';

if (exists($dbhash{$path})) {
    $dbhash{$path}++ if ($dbhash{$path} != 2147483647);
} else {
    $dbhash{$path} = 1;
}

my $nmz_uri = "$index/NMZ.field.uri";
my $nmz_access_rank = "$index/NMZ.field.accessrank";

open(NMZ_URI, "< $nmz_uri") or safe_die("Cannot open file $!");
binmode NMZ_URI;

open(NMZ_ACCESS_RANK, "> $nmz_access_rank.$$.tmp")
        or safe_die("Cannot open file $!");
binmode NMZ_ACCESS_RANK;

open(NMZ_ACCESS_RANK_I, "> $nmz_access_rank.i.$$.tmp")
        or safe_die("Cannot open file $!");
binmode NMZ_ACCESS_RANK_I;

chmod 0666, "$nmz_access_rank.$$.tmp", 
        "$nmz_access_rank.i.$$.tmp";

my $offset = 0;
while(my $uri = <NMZ_URI>) {
    my $count;

    chomp $uri;
    if (exists($dbhash{$uri})) {
        $count = $dbhash{$uri};
    } else {
        $count = 0;
    }

    printf NMZ_ACCESS_RANK "%-10d\n", $count;
    print NMZ_ACCESS_RANK_I pack('N', $offset);

    $offset += 11;
}

close(NMZ_ACCESS_RANK_I);
close(NMZ_ACCESS_RANK);

rename("$nmz_access_rank.$$.tmp", "$nmz_access_rank");
rename("$nmz_access_rank.i.$$.tmp", "$nmz_access_rank.i");

close(NMZ_URI);

untie( %dbhash );

print "Location: $uri\n\n";

sub BINARY {
    return O_BINARY if $Config{osname} =~ /^(MS)?Win/;
}

sub safe_die($)
{
    my ($msg) = @_;

    open(OUT, ">> $index/error.txt");
    print $msg . "\n";
    close(OUT);

    print "Content-Type: text/plain\n\n";
    print "Error: $msg\n";

    exit 1;
}

コメント

コメントをどうぞ

※メールアドレスとURLの入力は必須ではありません。 入力されたメールアドレスは記事に反映されず、ブログの管理者のみが参照できます。

※なお、送られたコメントはブログの管理者が確認するまで公開されません。

名前:
メールアドレス:
URL:
コメント:

トラックバック

このエントリのトラックバックURL: http://namazu.asablo.jp/blog/2006/03/23/300327/tb

※なお、送られたトラックバックはブログの管理者が確認するまで公開されません。