#!/usr/bin/perl # #強化型ゆいぼーど(log.cgi)を改造したアンケート箱(軽量版) require './jcodeLE.pl'; require './prei.cgi'; $| = 1; &winit;&noaxschk; &init; &decode;&jikan; &readlog; ($title,$chkkey,$ddata,$oname,$ochat,$ohost,$odate) = split(/:#/,$set); if($odate eq ''){ $title='Broken Box'; $ochat='No data in file.'; }else{ $counter = int($counter); } if ($referer =~ /$cgichk/i ){ &write if($vote || $voten); &edit if ($erase); } &html;exit; ################################################## sub init{ #初期設定など $rootpwd = 'master777'; #総合管理者のパスワード(重要!) $pagemax = 15; #1ページに表示する件数 $vmax = 500; #保存する件数 $brmax = 10; #コメントの最大行数 $chatmax = 1024; #コメントの最大バイト数 $seritime = 1800; #連続投票の制限時間&項目作成制限の目安時間(秒数) $votencount = 5; #連続項目作成の制限個数 }#init END ################################################## sub html { my($roomtotal,$count,$i,$line,$voten,$name,$wchat,$cdate,$host,$ps,$times,$invalid,$color,$page3,$time2); print "Content-type: text/html\n\n"; print <<"_HTML_"; $title $metacode $bodys _HTML_ if( $detail ){ #投票一覧の処理 &makedetail(); print $original;#この行だけは消さないでっ!! return; } #if END &makevotes; &sortvotes; print <<"_HTML_"; [リストに戻る]

$title

$titimg $acou
$ochat
_HTML_ if( $pass eq $rootpwd ){ print "
$oname($odate $ohost)
"; } else{ print "
$oname($odate)
"; } print "
"; print "${date}現在の集計状況
"; &printtable; print "全発言\表\示 /\n"; print "全投票\表\示
\n"; if( $pass ne $rootpwd ){ print <<"_VOTE_";
"; print <<"_CMNT_";

項目を追加する場合→全角${votenmax}文字まで

上記項目を選択した理由を簡単にお書き下さい。(タグは使えません。)

(${brmax}行まで)
有効票無効票(意見のみ)

一人連続投票制限があります。
_CMNT_ } #if END if( $voteall ){ #全投票一覧の処理。重い foreach $detail (@sortedvotes){ print ""; &makedetail; } print $original;#この行だけは消さないでっ!! return; } #if END print "最近の投票 Page:"; $roomtotal = @lines; $count = int(($roomtotal-1)/$pagemax); for($i=0;$i<=$count;$i++){ #ページ番号を書く if($i eq $page){ print "[$i] \n"; }else{ print "[$i] \n"; } } print "
"; if(@lines >= $pagemax){ #1ページ分の発言を取り出す $page3 = $page2+$pagemax-1; $page3 = @lines-1 if($page3 > @lines-1); @lines = @lines[$page2 .. $page3]; } foreach $line(@lines){ ($voten,$name,$vote,$wchat,$cdate,$host,$times,$invalid,$time2) = split(/:#/,$line); if($invalid){ $color = '#0000FF'; }else{ $color = '#000000'; } print "$vote\n"; print "

$wchat

\n"; if( $pass eq $rootpwd ){ print "($cdate $host $time2)\n"; }else{ print "($cdate)\n"; } print "
\n"; } if( $pass eq $rootpwd ){ #削除機能 print <<"_HTML_";
削除キーワード(項目データの中に含まれる文字列。秒数指定が安全)
削除用パスワード
_HTML_ } #if END $pass=''; print $original;#この行だけは消さないでっ!! }#html END ################################################## sub write { my($line,$dmy1,$dmy2,$dmy3,$dmy4,$wchata,$wchatb,$filedata); my($hs,$t1,$t2,$dt,$vtn,$vt,$iv,$vc); $t1 = time; $vc = 0; foreach $line(@lines){ #一人連続投票をチェック ($vtn,$dmy1,$vt,$dmy2,$dmy3,$hs,$dmy4,$iv,$t2) = split(/:#/,$line); $dt = $t1-$t2; last if($dt >= $seritime); if($hs eq $host){ $dt = int(($seritime-$dt)/60); &err("一人連続投票制限にかかりました(再び投票できるのは$dt分後)") if(($vt eq $vote) && ($iv eq $invalid)); if(($voten ne '') && ($vtn ne '')){ $vc++; $dt = int($seritime/60); &err("一人連続項目作成制限にかかりました($votencount項目/$dt分)") if($vc >= $votencount); } } } ($line)=@lines; ($dmy1,$dmy2,$wchatb) = split(/:#/,$line); $wchata = $chat; $wchata =~ s/ //g;$wchata =~ s/ //g;$wchata =~ s/
//ig;$wchata =~ s/>//ig; $wchatb =~ s/ //g;$wchatb =~ s/ //g;$wchatb =~ s/
//ig;$wchatb =~ s/>//ig; if(($wchata ne $wchatb) || $wchata==''){ #同内容の連続書き込みを禁止する機能らしい if( $ddata <= $daylimit ){ #コメント無しの新規項目を許すようにした $filedata = -M "$chat_file"; if( $filedata < $ddata/2 ){ $ddata += $aday; }else{ $ddata /= 2; } } $ddata = $hday if($ddata < $hday); $ddata = $daylimit if($ddata > $daylimit); $value = "$voten:#$name:#$vote:#$chat:#$date:#$host:#$times:#$invalid:#$t1:#\n"; #比較が面倒くさいので投票時刻の他にtimeで得た経過秒数も記録しておく &writelog; } $chat = ''; }#write END ################################################## sub decode{ #一般的なデコード&変数への代入 my($cou_file,$brnum,$i); if($ENV{'REQUEST_METHOD'} eq "POST"){ read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); }else{ $buffer = $ENV{'QUERY_STRING'}; } &decodearg($buffer,$cgi_log); $name = 'N'; $voten = $FORM{'voten'};&err("項目名が長すぎます。") if(length($voten) > ($votenmax*2)); $chat = $FORM{'chat'}; $room = $FORM{'room'}; $erase = $FORM{'erase'}; $room = '000' if($room eq ''); $chat_file = "./$logdir/log.$room.cgi"; $cou_file = "./$coudir/cou.$room.dat"; $pass = $FORM{'pass'};$pass = $$ unless($pass); $page = $FORM{'page'};$page = 0 if($page < 0);$page = int($page); $pagemax = $COOKIE{'pm'} if($COOKIE{'pm'} > 0); $pagemax = $FORM{'pm'} if($FORM{'pm'} > 0); $pagemax = int($pagemax); $page2 = $page*$pagemax; $_ = $chat;$brnum = s/
//ig; if($brnum > $brmax){ $i = $brnum - $brmax; &err("コメントの行数が多すぎます。$i行減らして下さい。"); } $len = length($chat); if($len > $chatmax){ $i = $len - $chatmax; &err("コメントの文字数が多すぎます。$iバイト減らして下さい。"); } $vote = $FORM{'vote'}; #既存項目への投票 $voten = $FORM{'voten'}; #項目の新規作成 &err("項目名が長すぎます。") if(length($voten) > ($votemax*2)); $invalid = $FORM{'invalid'}; #無効票オプション &newvote; $detail = $FORM{'detail'}; #投票一覧の要求 $voteall = $FORM{'vall'}; #全投票の要求 #カウンタ制御 if(!$detail){ open(DB,"+<$cou_file")|| &err("カウンタファイルが開けません。"); $acou = 1 + ; $acou = 0 if($acou > 99999); seek(DB,0,0); print DB "$acou\n"; close(DB); } }#decode END ################################################## sub readlog{ #配列@linesにログを読み込む open(DB,"$chat_file") || &err("ログファイルが読めません。"); seek(DB,0,0); @lines = ; close(DB); $set=shift(@lines); }#readlog END ################################################## sub writelog{ #$valueを@linesに加えたのち、書き込む (@lines < $vmax-1) || (@lines = @lines[0 .. $vmax - 2]); unshift( @lines,$value); $set = "$title:#$vkey:#$ddata:#$oname:#$ochat:#$ohost:#$odate:#\n"; open(DB,">$chat_file") || &err("ログファイルに書き込めません"); eval 'flock(DB,2);'; seek(DB,0,0); print DB $set; print DB @lines; eval 'flock(DB,8);'; close(DB); }#writelog END ################################################## sub edit{ my($linenum1,$linenum2); $linenum1 = @lines; @lines=grep(!/$erase/,@lines); $linenum2 = @lines; if( $linenum1 ne $linenum2 ){ $value='';&writelog;&readlog; } }#edit END ################################################## #新規項目(指定されていれば)を作成する #既存項目と同じ名前だとその項目に投票される sub newvote{ if($voten){ &err("項目への投票と新規項目作成が同時に行われました。") if($vote); $vote = $voten; } } ################################################## #@linesから項目リストを抽出する($voteだけを見ている) sub makevotes{ my($line,$dmy1,$dmy2,$dmy3,$dmy4,$dmy5,$voten,$vote,$invalid); foreach $line(@lines){ ($voten,$dmy1,$vote,$dmy2,$dmy3,$dmy4,$dmy5,$invalid) = split(/:#/,$line); foreach $v(keys(%votes)){ if($vote eq $v){ $votes{$vote}++; $invalids{$vote}++ if($invalid); $vote = ''; last; } } if($vote){ $votes{$vote} = 1; #重複が無いように項目のリストを作る $invalids{$vote} = 1 if($invalid); } } } ################################################## #項目リスト(%votes、%invalid)から投票状況のテーブルを作成 sub printtable{ my($vc,$ac,$per,$v,$vt,$link); #,$iw,$bar,$i); $vc = 0; $ac = 0; foreach $vote(keys(%votes)){ $vc += $votes{$vote}-$invalids{$vote}; $ac += $votes{$vote}; } print ""; print "\n"; foreach $vote (@sortedvotes){ $v = $votes{$vote}-$invalids{$vote}; if($vc != 0){ $per = int($v*100/$vc); } else{ $per = 0; } $iw = $per; $iw = 1 if($iw == 0); # $i = $per/5; # $bar = '+'; # for(;$i>1;$i--){ # $bar = "$bar+"; # } $vt = $vote; $vt =~ s/([^0-9A-Za-z_ ])/'%'.unpack('H2',$1)/ge; #英数字でない所をエンコードする $vt =~ s/\s/+/g; if($voteall){ $link = "#$vote"; }else{ $link = "$cgi_log?detail=$vt&room=$room"; } print "$per% \n"; # print "$per% \n"; } print"
選択項目有効票数(投票数)割合グラフ
$vote$v($votes{$vote})
$vote$v($votes{$vote})$bar
\n"; print"有効投票総数$vc票(投票総数$ac票)\n"; } ################################################## #投票項目の一覧を作成 sub makedetail{ my($dmy1,$dmy2,$dmy3,$dmy4,$dmy5,$vt,$cm,$dt,$iv,$cl); print "\

[$detailについてのコメント一覧\]

"; foreach $line(@lines){ ($dmy1,$dmy2,$vt,$cm,$dt,$dmy4,$dmy5,$iv) = split(/:#/,$line); if($iv){ $cl = '#0000FF'; }else{ $cl = '#000000'; } if($detail eq $vt){ print "$cm\
($dt)
\n"; } } #print"
\n"; } ################################################## #投票項目をソート sub sortvotes{ @sortedvotes = sort{$votes{$b}*1000-$invalids{$b}*999<=>$votes{$a}*1000-$invalids{$a}*999}keys(%votes); } __END__