MikaTypeLogStripper

name

mikatype.logをExcelに貼り付けるtableを作成するfilterです.

error対処

Internal Server Error

が出た場合.

bob% tail /var/log/apache2/error_log 
[Wed Nov 26 16:34:27 2014] [error] [client 192.168.1.51] warning: HikiDoc#to_html is deprecated. Please use HikiDoc.to_html or HikiDoc.to_xhtml instead., referer: http://192.168.1.32/~yoshii/hiki/
[Wed Nov 26 16:35:08 2014] [error] [client 172.29.0.42] warning: HikiDoc#to_html is deprecated. Please use HikiDoc.to_html or HikiDoc.to_xhtml instead., referer: http://192.218.172.38/~yoshii/Thesis/Undergraduate/nishitani/
[Wed Nov 26 17:00:31 2014] [error] [client 172.29.0.42] /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/rubygems/core_ext/kernel_require.rb:55:in `require': cannot load such file -- md5 (LoadError), referer: http://ist.ksc.kwansei.ac.jp/~nishitani/?cmd=view&p=MikaTypeExam&key=mikatype
[Wed Nov 26 17:00:31 2014] [error] [client 172.29.0.42] \tfrom /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/rubygems/core_ext/kernel_require.rb:55:in `require', referer: http://ist.ksc.kwansei.ac.jp/~nishitani/?cmd=view&p=MikaTypeExam&key=mikatype
[Wed Nov 26 17:00:31 2014] [error] [client 172.29.0.42] \tfrom /Users/bob/Sites/openHP/Apps/MikaTypeLogStripper.cgi:10:in `<main>', referer: http://ist.ksc.kwansei.ac.jp/~nishitani/?cmd=view&p=MikaTypeExam&key=mikatype
[Wed Nov 26 17:00:31 2014] [error] [client 172.29.0.42] Premature end of script headers: MikaTypeLogStripper.cgi, referer: http://ist.ksc.kwansei.ac.jp/~nishitani/?cmd=view&p=MikaTypeExam&key=mikatype
[Wed Nov 26 17:00:31 2014] [error] [client 172.29.0.42] /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/rubygems/core_ext/kernel_require.rb:55:in `require': cannot load such file -- md5 (LoadError), referer: http://ist.ksc.kwansei.ac.jp/~nishitani/?cmd=view&p=MikaTypeExam&key=mikatype
[Wed Nov 26 17:00:31 2014] [error] [client 172.29.0.42] \tfrom /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/rubygems/core_ext/kernel_require.rb:55:in `require', referer: http://ist.ksc.kwansei.ac.jp/~nishitani/?cmd=view&p=MikaTypeExam&key=mikatype
[Wed Nov 26 17:00:31 2014] [error] [client 172.29.0.42] \tfrom /Users/bob/Sites/openHP/Apps/MikaTypeLogStripper.cgi:10:in `<main>', referer: http://ist.ksc.kwansei.ac.jp/~nishitani/?cmd=view&p=MikaTypeExam&key=mikatype
[Wed Nov 26 17:00:31 2014] [error] [client 172.29.0.42] Premature end of script headers: MikaTypeLogStripper.cgi, referer: http://ist.ksc.kwansei.ac.jp/~nishitani/?cmd=view&p=MikaTypeExam&key=mikatype

でrubygemsのerrorが確認できる.

bob% gem environment
RubyGems Environment:
  - RUBYGEMS VERSION: 1.6.2
  - RUBY VERSION: 1.8.7 (2010-01-10 patchlevel 249) [i686-darwin11.4.2]
  - INSTALLATION DIRECTORY: /Users/bob/.rbenv/versions/1.8.7-p249/lib/ruby/gems/1.8
  - RUBY EXECUTABLE: /Users/bob/.rbenv/versions/1.8.7-p249/bin/ruby
  - EXECUTABLE DIRECTORY: /Users/bob/.rbenv/versions/1.8.7-p249/bin

なんで1.8.7系列を指定.具体的には,

bob% head MikaTypeLogStripper.cgi
#!/Users/bob/.rbenv/versions/1.8.7-p249/bin/ruby
#!/usr/bin/env ruby
#!/Users/bob/.rbenv/shims/ruby #こいつではダメ!!
require 'tmpdir'
require 'fileutils'
# UpLoadLog.rb

としている.

ソースの解説

Header部

必要なファイルを読み込みます.tmp_fileの名前に使うsession_idを作ります.

#!/usr/bin/env ruby
require 'tmpdir'
require 'fileutils'
# UpLoadLog.rb
require 'cgi'
require 'stringio'
require 'md5'
require 'kconv'
require 'scanf'
require 'date'


def generate_session_id
  m = MD5.new
  m.update(Time.now.to_s)
  m.update($$.to_s)
  m.update(rand.to_s)
  m.update('secret words')          # 適当な文字列
  m.hexdigest
end

display_form(cgi)

sessionの最初の部分です.ここでは,ファイルを読み込んでuploadする操作を提供しています.

def display_form(cgi)
  action = ENV['script_name']
  return <<EOF
<form action="#{action}" method="post" enctype="multipart/form-data">
  File to Upload: <input type="file" name="file_name"><br>
  <input type="submit" name="Submit" value="Upload">
EOF
end

MikaTypeFilter(cgi,infile)

process_formから呼ばれるfilterでする実際の作業をここで記述しています.

def MikaTypeFilter(cgi,infile)
  cont=File.open(infile)
  cont_utf=NKF.nkf("-w",cont.read) #change to utf
  cont.close
  out1=[]
  cont_utf.lines.each do |line|
    seq=line.split(/練習時間/)
    day1 = "20"+seq[0].split(/ /)[0].to_s
    day2 =Date.parse(day1)
    time1=seq[1].scanf('%d 時間 %d 分 %d 秒')
    time2=(time1[0]*60+time1[1]+time1[2].to_f/60.0)
    out1 << [day2,time2]
  end
  
  first_day=out1[0][0]
  i=0
  sum=0
  out2=[]
  out1.each do |dat1|
    day=(dat1[0]-first_day).to_i
    sum += dat1[1]
    if i!=0 then
      if out2[i-1][0]!=day then
        out2 << [day,dat1[1],sum]
        i+=1
      else
        out2[i-1][1]+=dat1[1]
        out2[i-1][2]+=dat1[1]
      end
    else
      out2 << [day,dat1[1],sum]
      i+=1
    end
  end
    
  ret1="<table border=\"1\">"
  ret1+="<tr><td>day</td><td>practice[min/day]</td><td>total[min]</td></tr>\n"
  out2.each do |ele|
    ret1 += sprintf("<tr><td>%d</td><td>%5.2f</td><td>%5.2f</td></tr>\n",ele[0],ele[1],ele[2])
  end
  ret1 += "</table>"
  section=ret1.length
  return ret1[0..section-2]
end

process_form(cgi,dest_file)

実際の作業結果を表示するprocess_formの部分です.

def process_form(cgi,dest_file)
  fileObj = cgi.params['file_name'][0]
  str = '<h1>Upload report</h1>'
  if fileObj
    path = fileObj.original_filename
    str += "Original Filename:  #{path}" + cgi.br
    dest = dest_file
    File.open(dest.untaint,'wb') {|f| f << fileObj.read }
     str +=MikaTypeFilter(cgi,dest)
  end
  return str
end

main_loop

全体のコントロール部分です.複数のアクセスがあった場合にどうやってsessionを維持しているのか?? 忘れてしまいました.

cgi = CGI.new('html4Tr')

session_id = generate_session_id
datafile = File.join(Dir.tmpdir, session_id)

if cgi.request_method !~ %r{POST}
  buf = display_form(cgi)
else 
  buf = process_form(cgi,datafile)
end

cgi.out() do
  cgi.html() do
    cgi.head{ cgi.title{'Upload Form'} } + cgi.body() { buf }
  end
end

exit 0
Last modified:2016/07/19 12:42:21
Keyword(s):
References:[WebApps]