Rubyなカウンタ

このページのトップページに設置してあるカウンタです。初めてRubyを触って作ったもので、SSIで呼び出すようになっています。内部のプライベートIPからアクセスしたときはカウンタが増えないようになっていて、外部からアクセスした場合は最初のアクセスから一定時間はカウンタが増えないようになっています。HTMLファイルから、<--#exec cmd="./count.rb" -->のように呼び出して使っています。

リロードしても数値が増加しないカウンタが欲しいと思っていたのと、Rubyでとりあえず何か作ってみようと思ったので作ってみました。まだ、「Rubyプログラム入門」という本の1章を読み終わるか終わらないか位までしか読んでいない状態で作ったので、ぼろぼろですが...(^^; ファイルのロックもしていませんが、このページのようにアクセス数が少ない場合はたぶん大丈夫でしょう。おかしいところなど ( 特にセキュリティー関連 ) があったら指摘してもらえると嬉しいです。



#!/usr/bin/ruby

# ファイル名や、カウントの間隔を設定。
$file_counter = "count"     #カウントを書き込むファイル
$file_iplog = "ip.log"      #最近のアクセスのIPを記録するファイル。
$file_log = "access.txt"    #来た人の情報を記録するファイル。
$iplog_delete_time = 15*60  #カウントの間隔(秒)

# 現在のカウントを得る関数
def get_count
  # カウンタの読み込み
  f_count = open( $file_counter , "r+" )
  count = Integer( f_count.gets ) + 1
  f_count.close
  count
end

# カウントをファイルに書き込む。
def put_count( count )
  # カウンタの書き込み
  f_count = open( $file_counter , "w" )
  f_count.write( count );
  f_count.close

  # 来た人のログを書き込み。
  f_log = open( $file_log , "a" )
  f_log.puts( "%d : %s : %s : %s" % [ count , ENV["REMOTE_HOST"] , ENV["HTTP_USER_AGENT"] , ENV["DATE_LOCAL"] ])
  f_log.close
end

# 内部からのアクセスと外からのアクセスで処理を分ける。
if ENV["SERVER_ADDR"] == "192.168.1.10"

  # 内部からのアクセスの場合は、カウンタを表示するだけ。
  str_print = "(next)%d" % [ get_count() ]

else

  # 外部からのアクセスの場合。

  # 最近のアクセス記録を読み込み、
  # { "IPアドレス"=>"時間" }と{ "IPアドレス"=>"そのカウント数"}の
  # ハッシュを作る。
  f_iplog = open( $file_iplog , "r")
  iptime = Hash.new
  ipcount = Hash.new
  while line = f_iplog.gets
    ipstr = line.split(/,/)
    if ( ipstr.size >= 2 )
      iptime[ipstr[0]] = ipstr[1].chomp
      ipcount[ipstr[0]] = ipstr[2].chomp
    end
  end
  f_iplog.close

  # 時間のハッシュから、カウント間隔が過ぎたものを削除
  iptime.delete_if do |k,v|
    Time.now.to_i - Integer(v) > $iplog_delete_time
  end

  # 時間ハッシュに、今回のアクセスのIPがあれば、
  # そのIPのカウントを表示する。
  if( iptime.key?( ENV["REMOTE_ADDR"] ) )
    str_print = ipcount[ ENV["REMOTE_ADDR"] ]
  else
    # 時間ハッシュにIPがない場合は、
    # カウンタを読み、ログを取り、各ハッシュに今回のIPを記録。
    count = get_count()
    put_count( count )
    str_print = String( count )
    iptime[ ENV["REMOTE_ADDR"] ] = String( Time.now.to_i )
    ipcount[ ENV["REMOTE_ADDR"] ] = String( count )
  end

  # ハッシュのデータを、最近のアクセス記録ファイルに記録。
  f_iplog = open( $file_iplog , "w" )
  if( iptime.size > 0 )
    iptime.each do |k,v|
      f_iplog.puts( k + "," + v + "," + ipcount[k] )
    end
  end
  f_iplog.close

end

# 表示。
print str_print