| 1 | # tdiary_vote.rb $Revision: 2 $ |
|---|
| 2 | # Copyright (C) 2006 Michitaka Ohno <elpeo@mars.dti.ne.jp> |
|---|
| 3 | # You can redistribute it and/or modify it under GPL2. |
|---|
| 4 | # |
|---|
| 5 | # ref. http://elpeo.jp/diary/20060622.html#p01 |
|---|
| 6 | # |
|---|
| 7 | # .tdiary-vote { |
|---|
| 8 | # float: left; |
|---|
| 9 | # background-color: aqua; |
|---|
| 10 | # } |
|---|
| 11 | |
|---|
| 12 | require 'digest/md5' |
|---|
| 13 | require 'pstore' |
|---|
| 14 | |
|---|
| 15 | @tdiary_vote_db = "#{@cache_path}/tdiary_vote" |
|---|
| 16 | @tdiary_vote_label = "投票" |
|---|
| 17 | @tdiary_vote_date = nil |
|---|
| 18 | |
|---|
| 19 | def vote( *items ) |
|---|
| 20 | return '' unless @tdiary_vote_date |
|---|
| 21 | h, voted = get_vote( @tdiary_vote_date, @cgi.cookies['tdiary_vote'][0] ) |
|---|
| 22 | max = h.empty? ? 1 : h.values.max |
|---|
| 23 | r = %Q[<table border="1">] |
|---|
| 24 | items.sort{|a, b| h[b] <=> h[a]}.each do |item| |
|---|
| 25 | num = h[item] |
|---|
| 26 | r << %Q[<tr>] |
|---|
| 27 | r << %Q[<td>#{CGI.escapeHTML( item )}</td>] |
|---|
| 28 | r << %Q[<td><span class="tdiary-vote" style="height: 2.5ex; width: #{(100*num/max).to_i}px"></span>#{num}</td>] |
|---|
| 29 | unless voted then |
|---|
| 30 | r << %Q[<td>] |
|---|
| 31 | r << %Q[<form submit="#{@conf.index}" method="POST" style="margin: 0px; padding: 0px">] |
|---|
| 32 | r << %Q[#{csrf_protection}] |
|---|
| 33 | r << %Q[<input type="hidden" name="date" value="#{@tdiary_vote_date.strftime( "%Y%m%d" )}">] |
|---|
| 34 | r << %Q[<input type="hidden" name="name" value="">] |
|---|
| 35 | r << %Q[<input type="hidden" name="body" value="">] |
|---|
| 36 | r << %Q[<input type="hidden" name="vote" value="#{CGI.escapeHTML( item )}">] |
|---|
| 37 | r << %Q[<input type="submit" name="comment" value="#{@tdiary_vote_label}">] |
|---|
| 38 | r << %Q[</form>] |
|---|
| 39 | r << %Q[</td>] |
|---|
| 40 | end |
|---|
| 41 | r << %Q[</tr>] |
|---|
| 42 | end |
|---|
| 43 | r << %Q[</table>] |
|---|
| 44 | end |
|---|
| 45 | |
|---|
| 46 | def get_vote( date, uid ) |
|---|
| 47 | h = Hash.new(0) |
|---|
| 48 | voted = false |
|---|
| 49 | file = "#{@tdiary_vote_db}/#{date.strftime( "%Y%m%d" )}.db" |
|---|
| 50 | if File.exist?( file ) then |
|---|
| 51 | PStore.new( file ).transaction do |db| |
|---|
| 52 | h.update( db['vote'] ) if db.root?( 'vote' ) |
|---|
| 53 | voted = db['voter'].include?( uid ) if db.root?( 'voter' ) |
|---|
| 54 | db.abort |
|---|
| 55 | end |
|---|
| 56 | end |
|---|
| 57 | [h, voted] |
|---|
| 58 | end |
|---|
| 59 | |
|---|
| 60 | def add_vote( date, item, uid ) |
|---|
| 61 | Dir::mkdir( @tdiary_vote_db ) unless File::directory?( @tdiary_vote_db ) |
|---|
| 62 | file = "#{@tdiary_vote_db}/#{date.strftime( "%Y%m%d" )}.db" |
|---|
| 63 | PStore.new( file ).transaction do |db| |
|---|
| 64 | db['voter'] = Hash.new unless db.root?( 'voter' ) |
|---|
| 65 | db.abort if db['voter'].include?( uid ) |
|---|
| 66 | db['voter'][uid] = @cgi.remote_addr |
|---|
| 67 | db['vote'] = Hash.new(0) unless db.root?( 'vote' ) |
|---|
| 68 | db['vote'][item] += 1 |
|---|
| 69 | end |
|---|
| 70 | end |
|---|
| 71 | |
|---|
| 72 | add_body_enter_proc do |date| |
|---|
| 73 | @tdiary_vote_date = date |
|---|
| 74 | '' |
|---|
| 75 | end |
|---|
| 76 | |
|---|
| 77 | add_body_leave_proc do |date| |
|---|
| 78 | @tdiary_vote_date = nil |
|---|
| 79 | '' |
|---|
| 80 | end |
|---|
| 81 | |
|---|
| 82 | unless bot? then |
|---|
| 83 | if @mode == 'comment' && @cgi.valid?( 'vote' ) && @cgi.cookies['tdiary_vote'][0] then |
|---|
| 84 | add_vote( @date, @cgi.params['vote'][0], @cgi.cookies['tdiary_vote'][0] ) |
|---|
| 85 | end |
|---|
| 86 | |
|---|
| 87 | add_footer_proc do |
|---|
| 88 | uid = @cgi.cookies['tdiary_vote'][0] || Digest::MD5.hexdigest( @cgi.remote_addr + Time.now.to_s + rand.to_s ) |
|---|
| 89 | cookie_path = File::dirname( @cgi.script_name ) |
|---|
| 90 | cookie_path += '/' if cookie_path !~ /\/$/ |
|---|
| 91 | cookie = CGI::Cookie::new( |
|---|
| 92 | 'name' => 'tdiary_vote', |
|---|
| 93 | 'value' => uid, |
|---|
| 94 | 'path' => cookie_path, |
|---|
| 95 | 'expires' => Time.now.gmtime + 30*24*60*60 |
|---|
| 96 | ) |
|---|
| 97 | add_cookie( cookie ) |
|---|
| 98 | '' |
|---|
| 99 | end |
|---|
| 100 | end |
|---|