SimpleBoxes

人気記事リスト

SimpleBoxesは、sbで運用しています。

Serene Bachではなく、あえてsbで運用しています。

sbのアクセス解析でどのログにアクセスが多いかは大体分かるのですが、アドレスが並んでいるだけなので、ちょっと分かりづらい。

そこで、アクセスの多い記事をリスト表示するスクリプトをでっち上げてみました。

javascriptを利用して表示するという形式を取っています。perlスクリプトをCGIとして動的に出力していますが、アクセスログが結構なサイズになるので、適時キャッシュするようにしています。

折角作ったので、ソースならびに簡単な説明を「続き」に載せておきます。

ただし、このスクリプトは汎用性はあまりありません。アクセスログの形式が異なるためSerene Bachでは動作しませんし、単一のログディレクトリのみが対象となります(カテゴリーなどで別ディレクトリに保存している場合、対象とならない)。

それでもよければ、ご自由にお使いください。

#!/usr/bin/perl

use strict;
eval { sbvogue(); };
exit(0);

sub sbvogue
{
  my %config = (
    'url'   => 'ログディレクトリアドレス', # 例 : http://serennz.sakura.ne.jp/sb/log/
    'dir'   => 'ログディレクトリのパス', # 例 : ./log/
    'limit' => 10, # 表示数
    'log'   => 'アクセスログファイルのパス', # 例 : ./data/log.cgi
    'cache' => 'キャッシュファイルのパス', # 例 : ./log/cache.js
    'expire' => 24 * 60 * 60, # キャッシュの有効期間 (24 * 60 * 60 = 24 hours)
  );
  my $cache = sbvogue_loadcache($config{'cache'},$config{'expire'});
  if (!$cache)
  {
    my $count = sbvogue_loadlog($config{'log'},$config{'url'});
    my @order = sort { $count->{$b} <=> $count->{$a} } keys( %{$count} );
    my $num = 0;
    $cache = 'document.write(\'<ol>\\n\');' . "\n";
    foreach my $page ( @order )
    {
      my $file = $config{'dir'} . $page;
      next if (!-r $file);
      my $title = sbvogue_title($file);
      next if ($title eq '');
      $cache .= 'document.write(\'<li><a href="' . $config{'url'} . $page . '">';
      $cache .= $title . '</a></li>\\n\');' . "\n";
      $num++;
      last if ($num == $config{'limit'});
    }
    $cache .= 'document.write(\'</ol>\\n\');' . "\n";
    sbvogue_makecache($config{'cache'},$cache);
  }
  print 'Content-Type: text/javascript' . "\n\n" . $cache;
}
sub sbvogue_loadlog
{
  my $file = shift;
  my $url  = shift;
  my %count = ();
  open(IN,"<$file") or return( \%count );
  my $tmp = <IN>;
  while (my $line = <IN>)
  {
    my @elem = ($line =~ /(.*?)<>/g);
    my $page = ($elem[5] eq '') ? $elem[3] : $elem[5];
    next if ($page !~ /^\Q$url\E/);
    $page =~ s/^\Q$url\E//;
    next if (!$page);
    $page = substr($page,0,index($page,'#')) if (index($page,'#') > -1);
    $count{$page}++ if ($page);
  }
  close(IN);
  return( \%count );
}
sub sbvogue_title
{
  my $file = shift;
  my $title = '';
  open(IN,"<$file") or return( $title );
  while (my $line = <IN>)
  {
    if ($line =~ /<title>(.+?)\s\|\s(.+?)<\/title>/)
    {
      $title = $2;
      last;
    }
  }
  close(IN);
  return( $title );
}
sub sbvogue_loadcache
{
  my $file = shift;
  my $expire = shift;
  my $cache = '';
  return($cache) if (!-e $file);
  return($cache) if (-z $file);
  if (time - (stat($file))[9] < $expire)
  {
    open(IN,"<$file") or return( $cache );
    while (my $line = <IN>)
    {
      $cache .= $line;
    }
    close(IN);
  }
  return( $cache );
}
sub sbvogue_makecache
{
  my $file = shift;
  my $cache = shift;
  open(OUT,">$file");
  print OUT $cache;
  close(OUT);
  chmod(0666,$file);
}

上記のコードを適当なスクリプト名(例えば、rank.cgi)で、保存します。

最初の方にある%configが設定になるので、適切な内容に編集して下さい。

実行可能なパーミッションを与えて、sb.cgiと同じディレクトリに置きます。

呼び出しには、以下のような記述をテンプレートに追加します。

<script src="{site_top}rank.cgi" type="text/javascript"></script>
<noscript><p>Not available, please enable javascript on your browser.</p></noscript>

強調したrank.cgiはスクリプト名に依存します。

スポンサーリンク

<< sb like for Wordpress :: 今朝はちょっと寒かった >>