#!/usr/local/bin/perl # ###################################################################### ### ### ### CGIクイズシステム TakaQ Ver.2.05 ### [4/5] 管理 (tqadmin.cgi) ### (c) 1996-1999 Takahiro Nishida ### http://www.mytools.net/ ### ### ###################################################################### # ### 変数設定部 (詳細は上記ページをご覧下さい) ###################### $password = "TakaQV204"; ### 変数設定部 (ここまで)########################################### require "./tqlib.pl"; print "Content-type: text/html\n\n"; &main; sub main{ &tqlib'file_lock; &init_variables; &parse_form; &exec_action; &show_html; &tqlib'unlock; } sub parse_form{ if($ENV{'REQUEST_METHOD'} eq "POST"){ read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); }else{ $buffer = $ENV{'QUERY_STRING'}; } @pairs = split(/&/, $buffer); foreach $pair (@pairs) { ($name, $value) = split(/=/, $pair); $FORM{$name} = $value; } } sub init_variables{ $ext = $tqlib'ext; $basedir = $tqlib'basedir; $method = $tqlib'method; $gnrfile = "$basedir/genre.txt"; @datafile = ("rate.txt", "summery.txt", "highscore.txt", "message.txt"); $noact = "
何も変更されませんでした。";
}
########################## 作業関数 #########################
# 作業の実行
sub exec_action{
if($FORM{'pwd'} ne $password){
$actmes = "パスワードが違います。 $noact";
return;
}
&tqlib'checkvar($FORM{'dirname'});
&genre_check($FORM{'dirname'}) || return;
if($FORM{act} eq "gnew" ){ &genre_new ($FORM{dirname}); &genre_info($FORM{dirname}); return; }
if(!($vg = &get_genreinfo($FORM{dirname}))){
$actmes = "指定されたディレクトリ名のジャンル情報がありません。$noact";
$html="top";
return;
}
if($FORM{act} eq "ginfo"){ &genre_info($FORM{dirname}); return; }
if($FORM{act} eq "gfix" ){ &genre_fix ($FORM{dirname}); &genre_info($FORM{dirname}); return; }
if($FORM{act} eq "gdel" ){ &genre_del ($FORM{dirname}); return; }
if($FORM{act} eq "qinfo"){ &quiz_info ($FORM{dirname}); return; }
if($FORM{act} eq "qfix" ){ &quiz_fix ($FORM{dirname}); &quiz_info ($FORM{dirname}); return; }
if($FORM{act} eq "qdel" ){ &quiz_del ($FORM{dirname}); &quiz_info ($FORM{dirname}); return; }
if($FORM{act} eq "qchg" ){ &quiz_chg ($FORM{dirname}); &quiz_info ($FORM{dirname}); return; }
if($FORM{act} eq "dinfo"){ &data_info ($FORM{dirname}); return; }
if($FORM{act} eq "dfix") { &data_fix ($FORM{dirname}); &data_info ($FORM{dirname}); return; }
$actmes="作業が選択されていません。 $noact";
return;
}
# ジャンル情報の表示用変数の取得
sub genre_info{
local ( $genre ) = @_;
# ジャンル情報を書き直した場合があるので、再度取り直し
if(!($vg = &get_genreinfo($FORM{dirname}))){
$actmes = "指定されたディレクトリ名のジャンル情報がありません。$noact";
$html="top";
return;
}
$dir="$basedir/data/$genre";
@vgi=split("\t",$vg);
$sgno = shift(@vgi);
$sqno = &tqlib'count_quiz($dir);
# オプションの分析
@opts=split("",$vgi[$#vgi-1]);
for (0..$#opts){
$radio{"$_-$opts[$_]"}="checked";
}
if(!($actmes)){
$actmes="ジャンル $genre の情報を表\示しています。";
}
if(!($html)){
$html="ginfo";
}
return;
}
# 新ジャンルの登録
sub genre_new{
local ( $genre ) = @_;
if(&get_genreinfo($genre)){
$actmes="既に同じディレクトリ名($genre)のジャンル情報が存在します。$noact";
$html="top";
return;
}
# 必要な情報ファイルが開けるかどうかのチェック
$dir="$basedir/data/$genre";
pop( @datafile );
@err=();
foreach $file(@datafile){
if(!(open(FILE,">>$dir/$file"))){
push(@err,"$file $dir/$FORM{fqno}.q $noact";
return;
}
print FILE "$FORM{'fono'}\t$FORM{'fcno'}\t$FORM{'fidx'}\t\n";
print FILE "$FORM{'fqst'}\n$FORM{'fcom'}\n$FORM{'fans'}\n";
$zz=1;
while($FORM{"fwrg$zz"} ne ""){
print FILE $FORM{"fwrg$zz"}."\n";
$zz++;
}
close(FILE);
if($new){
$actmes="問題 No.$FORM{'fqno'} を新規登録しました。";
$FORM{'fqno'}="";
}
else{
$actmes="問題 No.$FORM{'fqno'}を修正しました。";
}
return;
}
# 問題削除
sub quiz_del{
local ( $genre ) = @_;
$dir="$basedir/data/$genre";
$btime=time();
$qno=&tqlib'count_quiz($dir);
if(!(&change_name("$dir/$FORM{'fqno'}.q", "$dir/del_$btime.q"))){ return; }
for($FORM{'fqno'}+1..$qno){
$preno=$_-1;
if(!(&change_name("$dir/$_.q", "$dir/$preno.q", 1))){ return; }
}
$actmes="問題 No.$FORM{'fqno'} を削除しました。削除されたファイルは $dir/del_$btime.q として保存されました。";
return;
}
# 問題番号の変更
sub quiz_chg{
local ( $genre ) = @_;
$dir="$basedir/data/$genre";
$qno = &tqlib'count_quiz($dir);
for(0..1){
if(!(($FORM{"fqch$_"}=~/^\d+$/)&&($FORM{"fqch$_"}>0)&&($FORM{"fqch$_"}<=$qno))){
$actmes="フォームに入力された内容が不正です。$noact";
return;
}
}
if(!(&change_name("$dir/$FORM{'fqch0'}.q", "$dir/change.q"))){ return; }
if($FORM{'fqch0'}>$FORM{'fqch1'}){
for($i=$FORM{'fqch0'};$i>$FORM{'fqch1'};$i--){
$ii=$i-1;
if(!(&change_name("$dir/$ii.q", "$dir/$i.q", 1))){ return; }
}
}
if($FORM{'fqch0'}<$FORM{'fqch1'}){
for($i=$FORM{'fqch0'};$i<$FORM{'fqch1'};$i++){
$ii=$i+1;
if(!(&change_name("$dir/$ii.q", "$dir/$i.q", 1))){ return; }
}
}
if(!(&change_name("$dir/change.q", "$dir/$FORM{'fqch1'}.q", 1))){ return; }
$actmes="No.$FORM{'fqch0'} を No.$FORM{'fqch1'} に変更しました。";
return;
}
# rename用の補助関数
sub change_name{
local( $from, $to, $prio ) = @_;
if(!(rename($from, $to))){
if($prio){
$actmes="
");
}
close(FILE);
}
if(@err){
$actmes="ディレクトリ $dir に必要な以下のファイルが存在しないか開けません。
@err $noact";
$html="top";
return;
}
push( @datafile, 'message.txt' );
$qno=&tqlib'count_quiz($dir);
&init_datafile($genre);
open(FILE,">$gnrfile") || die &tqlib'error($gnrfile,0);
print FILE "$genre\t$genre\t$qno\t3\t80\t$genre\t000\t\n";
print FILE @cgnrs;
close(FILE);
$actmes="新ジャンル $genre を登録しました。細かい設定は \"ジャンル修正\" で行なってください。";
$html="top";
return;
}
# ジャンル情報の修正
sub genre_fix{
local ( $genre ) = @_;
# 入力された変数の妥当性チェック
$dir="$basedir/data/$genre";
@gvnm = ( 'fname', 'fout', 'fdif', 'fsuc', 'fcom', 'fzur', 'fxsh', 'fjun', 'fgno');
@gvck = ( '.+', '\d+', '\d+', '\d+', '.+', '[01]', '[01]', '[01]', '\d+' );
@err=();
for(0..$#gvck){
$vnm = $gvnm[$_];
if(!($FORM{$vnm}=~/^$gvck[$_]$/)){
push(@err,"($_)");
}
else{
$FORM{$vnm} = &tqlib'decode($FORM{$vnm}, 1);
}
}
if(@err){
&genre_info($genre);
$actmes="以下の入力項目に謝りがありました。
".join("
",@err).$noact;
$html="ginfo";
return;
}
# 数値チェック
$qno=&tqlib'count_quiz($dir);
# 出題数が問題数を超えていないか
if($FORM{fout}>$qno){
$FORM{fout}=$qno;
}
# 出題順が固定なら、出題数=問題数
if($FORM{fjun}){
$FORM{fout}=$qno;
}
# 合格点が100%より大きい場合は100%に、0%より小さい場合は0%に
if($FORM{fsuc}>100) { $FORM{fsuc}=100; }
if($FORM{fsuc}<0) { $FORM{fsuc}=0; }
# 難易度が7より大きい場合は7に、1より小さい場合は場合は1に
if($FORM{fdif}>7) { $FORM{fdif}=7; }
if($FORM{fdif}<1) { $FORM{fdif}=1; }
@vgi=split("\t",$vg);
$sgno = shift(@vgi);
splice(@cgnrs, $sgno-1, 1);
$newginfo="$genre\t$FORM{fname}\t$FORM{fout}\t$FORM{fdif}\t$FORM{fsuc}\t$FORM{fcom}\t$FORM{fzur}$FORM{fxsh}$FORM{fjun}\t\n";
splice(@cgnrs, $FORM{fgno}-1, 0, $newginfo);
open(FILE,">$gnrfile") || die &tqlib'error($gnrfile,0);
print FILE @cgnrs;
close(FILE);
&genre_info($genre);
$actmes = "ジャンル $genre の情報を修正しました。";
$html="ginfo";
return;
}
# ジャンル情報削除
sub genre_del{
local ( $genre ) = @_;
@vgi=split("\t",$vg);
$sgno = shift(@vgi);
splice(@cgnrs, $sgno-1, 1);
open(FILE,">$gnrfile") || die &tqlib'error($gnrfile,0);
print FILE @cgnrs;
close(FILE);
$actmes="ジャンル $genre の情報を削除しました。ファイルの削除は手作業で行ってください。";
$html="top";
return;
}
# 問題一覧の表示(準備)
sub quiz_info{
local ( $genre ) = @_;
$dir="$basedir/data/$genre";
$sqno=&tqlib'count_quiz($dir);
# $fqno...修正対象の問題番号
@fquiz=();
if(open(FILE,"$dir/$FORM{fqno}.q")){
foreach(
変更したい部分を記入し直して「登録」を押してください。";
}
$fqmes="問題 No.$fqno の情報";
}
else{
$fqno=$sqno+1;
$fquiz[0]="0"; $fquiz[1]="0";
$fqmes="新規登録";
}
# $sgenre .. 関数show_html_quiz_.+ で使用する変数
$sgenre=$genre;
if(!($actmes)){
$actmes="新しい問題を入力して「登録」を押してください。";
}
$html="qinfo";
return;
}
# 問題修正
sub quiz_fix{
local( $genre ) = @_;
$dir="$basedir/data/$genre";
# 新規作成か修正か
if(!(-f "$basedir/data/$genre/$FORM{'fqno'}.q")){
$new=1;
}
$FORM{'fidx'} = &tqlib'decode($FORM{'fidx'},1);
$FORM{'fqst'} = &tqlib'decode($FORM{'fqst'},1);
$FORM{'fcom'} = &tqlib'decode($FORM{'fcom'},1);
$FORM{'fans'} = &tqlib'decode($FORM{'fans'},1);
$zz=1;
while($FORM{"fwrg$zz"} ne ""){
$FORM{"fwrg$zz"} = &tqlib'decode($FORM{"fwrg$zz"},1);
$zz++;
}
if(!($FORM{'fono'}=~/^\d+$/)){
$actmes="出題回数の値が不正です。$noact";
return;
}
if(!(($FORM{'fcno'}=~/^\d+$/)&&($FORM{'fcno'}<=$FORM{'fono'}))){
$actmes="正解回数の値が不正です。$noact";
return;
}
if($FORM{'fidx'} eq ""){
$actmes="見出しが入力されていません。$noact";
return;
}
if($FORM{'fqst'} eq ""){
$actmes="問題文が入力されていません。$noact";
return;
}
if($FORM{'fans'} eq ""){
$actmes="正答が入力されていません。$noact";
return;
}
if($FORM{'fwrg1'} eq ""){
$actmes="誤答が入力されていません。$noact";
return;
}
if(!(open(FILE,">$dir/$FORM{fqno}.q"))){
$actmes="指定された問題ファイルが見付かりませんでした。
!致命的エラー!
$from の名前を変更できません。
$from のディレクトリのファイルの名前が壊れた可能性があります。
下の問題一覧で確認して、壊れているファイルを再アップロードしてください。";
}
else{
$actmes="$from の名前を変更することができません。パーミッションを確認してください。$noact";
}
return(0);
}
return(1);
}
# データファイルの情報表示(準備)
sub data_info{
local ( $genre ) = @_;
&summery_info($genre);
&rate_info($genre);
&highscore_info($genre);
$sgenre=$genre;
if(!($actmes)){
$actmes="ジャンル $genre のデータファイルを表\示しています。";
}
$html="dinfo";
return;
}
# 得点別人数分布ファイルの情報
sub summery_info{
local ( $genre ) = @_;
$summfile = "$basedir/data/$genre/summery.txt";
@fsumm=("E");
open(FILE, "$summfile") || die return;
$sms=
\n";
}
}
########################## HTML表示関数 #########################
# 表示
sub show_html{
&show_html_header;
print "
\n";
if( $html eq "top" || $html eq "" ){
&show_html_top;
}
if( $html eq "ginfo" ){
&show_html_genre_info;
}
if( $html eq "qinfo" ){
&show_html_quiz_form;
&show_html_quiz_info;
}
if( $html eq "dinfo" ){
&show_html_data_form;
&show_html_data_info;
}
print "
\n";
if( $html eq "top" || $html eq "ginfo" || $html eq "" ){
&diag_file;
&show_html_genre_status;
}
&show_html_footer;
}
# 共通のヘッダ
sub show_html_header{
if($actmes=~/$noact/){
$actbg="#FF0000";
}
else{
$actbg="#000000";
}
#---------------------------------
print <<"EOF";
TakaQ 管理ページ
$actmes