#!/home/Stud/sasada/bin/ruby # # @file vote.cgi # @author K.S. # # $Date: 2003/04/21 14:43:25 $ # $Id: kodiary.rb,v 1.1.1.1 2003/04/21 14:43:25 ko1 Exp $ # # ko1 diary vote system # require 'tton' require 'cgi' require 'erb' require 'kconv' # require 'pstore' require 'yaml' require 'yaml/store' module Vote class VoteShow def initialize @dat= VoteData.new end def show_all tl = @dat.get_titles show_contents '投票一覧', 'いちらーん', ERB.new(SHOW_ALL_SCRIPT).result(binding) end def show no res = @dat.get_result no if !res raise "#{no}番目の投票はありまへん。" end total = res.total com = @dat.get_comment no show_contents res.title, 'とーひょーけっか', ERB.new(SHOW_SCRIPT).result(binding) end def show_contents title, subtitle, contents ERB.new(SHOW_CONTENTS).result(binding) end end class VoteData def initialize end def get_titles Dir['./vdat/00*.yaml'].map{|d| title = '' sels = [] since = nil db = YAML::Store.new(d) db.transaction { entry = db['data'] title = entry.title sels = entry.sel since = entry.since } /(\d+)/ =~ d [$1.to_i, title, since, sels] } end def up no,v fn = VoteData.result_filename(no) if FileTest.exist? fn db = YAML::Store.new(fn) obj = nil db.transaction { obj = db['data'] obj.up(v) db['data'] = obj } end end def get_result no fn = VoteData.result_filename(no) if FileTest.exist? fn db = YAML::Store.new(fn) obj = nil db.transaction { obj = db['data'] } obj else nil end end def self.result_filename no './vdat/%08d.yaml' % no end def get_comment no if FileTest.exist? comment_filename(no) comment = File.read(comment_filename(no)) @tton ||= TtoN::Text2HtmlDiaryComment.new nil @tton.parse comment else '' end end def comment_filename no './vdat/%08d.txt' % no end def add_comment no,name,body fn = comment_filename no body = "\n\n* #{name}(#{Time.now.to_s})\n#{body}\n\n" body = Kconv::tosjis body open(fn,'a'){|f| f.flock(File::LOCK_EX) f.write body } back = './vdat/c_add_backup.txt' open(back,"a"){|f| f.flock(File::LOCK_EX) f.write "-- \n" + "A comment to #{@no} from #{ENV['REMOTE_HOST']}(#{ENV['REMOTE_ADDR']})" + body } end def self.regist v no = 0 Dir['./vdat/00*.yaml'].map{|d| /(\d+)/ =~ d n = $1.to_i if n > no no = n end } no+=1 fn = result_filename no db = YAML::Store.new(fn) db.transaction{ db['data'] = v } File.chmod(0777,fn) no end end class VoteItem attr_reader :title, :sel, :since def initialize title,sel @title = title @sel = sel @cnt = Array.new(sel.size,0) @since = Time.now end def up n if @cnt.size < n || n < 1 raise "そんな選択肢ねーです : #{n}" else @cnt[n-1]+=1 end end def at n [@sel[n], @cnt[n]] end def each @sel.each_with_index{|e,i| yield e,@cnt[i] } end def total r = 0 @cnt.each{|i| r += i } r end end class VoteAction def initialize @show = VoteShow.new @data = VoteData.new @cgi = CGI.new() #@cgi = {'mode' => 'show', 'no' => '1'} ; def @cgi.out ;puts yield ; end @mode = @cgi['mode'] @v = @cgi['v'][0] @no= @cgi['no'][0] @name = @cgi['name'][0] @body = @cgi['body'][0] @v &&= @v.to_i @no&&= @no.to_i end ReqEnv = %w{REMOTE_ADDR HTTP_REFERER HTTP_USER_AGENT} def exec begin # ログかき if ENV['REMOTE_ADDR'] != '165.93.176.60' && # my 研究室 ENV['REMOTE_ADDR'] != nil require 'resolv' log = "#{Time.now.asctime}\n" addr = ENV['REMOTE_ADDR'] from = ENV['HTTP_REFERER'] agnt = ENV['HTTP_USER_AGENT'] begin name = Resolv.getname(addr) rescue name = '' end log = " at #{Time.now.asctime} / #{name} (#{addr})\nwith #{agnt} from #{from}\n" # ReqEnv.each{|k| log << "#{k} => #{ENV[k]}\n" } open('./vdat/log','a'){|f| f.write "\n--- #{@mode}/#{@no}/#{@v}/#{@name}/#{@body}\n#{log}" } File.chmod(0777,'./vdat/log') end # 実際 @cgi.out{exec_} rescue => e @cgi.out{ @show.show_contents 'エラーが起こりました', 'ごめんなさい', e.to_s # + "\n" + e.backtrace.join("\n") } end end def exec_ case @mode when 'vote' if !@v || !@no raise "ちゃんとしていしてください" end @data.up @no,@v @show.show @no when 'show' @show.show @no when 'comment' if @name.size == 0 || @body.size == 0 raise "なまえとかちゃんとかいてくださいー" end @data.add_comment @no,@name,@body @show.show @no else @show.show_all end end end end if __FILE__ == $0 eval DATA.read v = Vote::VoteAction.new v.exec end __END__ module Vote class VoteShow ##################################################################### ##################################################################### SHOW_ALL_SCRIPT = <<__________________________________________
項目 | 結果 |
<%= e %> | <%= '*' * (total > 0 ? 60 * v / total : 0) %> <%= v %>(<%= ((total > 0) ? v * 100 / total : "") %>%) |
全部で <%= total %> 票。
投票についてご意見があれば、どうぞ。こんな投票しろー、とか、こんな選択肢くわえろー、とか。
Sasada Koichi / sasada@namikilab.tuat.ac.jp