--- db/prgsrc/db.cgi 2001/12/03 13:57:20 1.40 +++ db/prgsrc/db.cgi 2001/12/21 11:54:37 1.53 @@ -1,17 +1,22 @@ -#!/perl/bin/perl -w +#!/usr/bin/perl -w use DBI; use CGI ':all'; -use Text::Query; +#use Text::Query; use strict; use Time::Local; use POSIX qw(locale_h); use locale; -#open STDERR, ">errors1"; +open STDERR, ">errors1"; my $printqueries=0; my %forbidden=(); my $debug=0; #added by R7 +if (param('debug')) {$debug=1; $printqueries=1} +*STDERR=*STDOUT if $debug; my %fieldname= (0,'Question', 1, 'Answer', 2, 'Comments', 3, 'Authors', 4, 'Sources'); +my %rusfieldname=('Question','Вопрос', 'Answer', 'Ответ', + 'Comments', 'Комментарии', 'Authors', 'Автор', + 'Sources', 'Источник','old','Старый','rus','Новый'); my %searchin; my $rl=qr/[йцукенгшщзхъфывапролджэячсмитьбюё]/; my $RL=qr/[ЙЦУКЕНГШЩЗХЪЭЖДЛОРПАВЫФЯЧСМИТЬБЮЁ]/; @@ -21,14 +26,15 @@ my $Ll=qr/(?:[A-Z])|(?:${RL})/; + my $thislocale; +$searchin{$_}=1 foreach param('searchin'); +my %TypeName=('children'=>'Д', 'game'=>'И', + 'chgk'=>'Ч', 'brain'=>'Б', 'beskrylka'=>'Л','ehruditka'=>'Э'); + + -$searchin{'question'}=param('Question'); -$searchin{'answer'}=param('Answer'); -$searchin{'comments'}=param('Comments'); -$searchin{'authors'}=param('Authors'); -$searchin{'sources'}=param('Sources'); my $all=param('all'); $all=0 if lc $all eq 'no'; my ($PWD) = `pwd`; @@ -69,7 +75,7 @@ sub GetTournament { foreach $name (@{$sth->{NAME}}) { $Tournament{$name} = $arr[$i++]; } - + $sth->finish; return %Tournament; } @@ -90,6 +96,7 @@ sub GetQuestion { $Question{$name} = $arr[$i++]; } + $sth->finish; return %Question; } @@ -99,7 +106,7 @@ sub GetTourQuestions { my (@arr, @Questions); my ($sth) = $dbh->prepare("SELECT QuestionId FROM Questions - WHERE ParentId=$ParentId ORDER BY QuestionId"); + WHERE ParentId=$ParentId"); $sth->execute; @@ -107,6 +114,7 @@ sub GetTourQuestions { push @Questions, $arr[0]; } + $sth->finish; return @Questions; } @@ -123,7 +131,7 @@ sub GetTours { while (@arr = $sth->fetchrow) { push @Tours, $arr[0]; } - + $sth->finish; return @Tours; } @@ -137,10 +145,58 @@ print "timeb=".time.br if $debug; $sth->execute; my @a=$sth->fetchrow; print "timee0=".time.br if $debug; + $sth->finish; $a[0]||0; } +sub printform +{ + + my $submit=submit(-value=>'Поиск'); + my $inputstring=textfield(-name=>'sstr', + -default=>param('sstr')||'', + -size=>30, + -maxlength=>30); + my $qnumber="Выводить по".br. textfield(-name=>'kvo', + -default=>param('kvo')||'150', + -size=>3, + -maxlength=>5). br."вопросов"; + + my @df=keys %searchin; + @df=('Question', 'Answer') unless @df; + my $fields=checkbox_group('searchin',['Question','Answer','Comments','Authors','Sources'], [@df], + 'false',\%rusfieldname); + + my $metod=radio_group(-name=>'metod',-values=>['old','rus'], + -default=>(param('metod')||'rus'), + -labels=>\%rusfieldname); + my $all=radio_group(-name=>'all',-values=>['yes','no'], + -default=>(param('all')||'no'), + -labels=>{'yes'=>'Все','no'=>'Любое'}); + +################################################# +return start_form(-method=>'get', + -action=>url, + -enctype=> + "application/x-www-form-urlencoded" +).br. +table(Tr +( + td({-valign=>'TOP'},$inputstring.$submit.p."Метод: $metod".p."Слова: $all"), + td({-valign=>'TOP'},(' 'x 8).'Поля:'), + td({-valign=>'TOP'},$fields), td(" "x5), + td({-valign=>'TOP'},$qnumber) +) +) + +#$fields. +#$inputstring.$submit.br.$metod.$all +.endform +.hr + +} + sub proxy { #print "time0=".time.br if $debug; @@ -151,7 +207,7 @@ sub proxy $text=~s/p(${RLrl})/р$1/gom; $text=~s/(${RLrl})p/$1р/gom; $text=~s/\s+/ /gmo; - $text=~s/[^йцукенгшщзхъфывапролджэячсмитьбюЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮQWERTYUIOPASDFGHJKLZXCVBNM]/ /g; + $text=~s/[^йцукенгшщзхъфывапролджэячсмитьбюЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮQWERTYUIOPASDFGHJKLZXCVBNM0-9]/ /g; $text=uc $text; my @list= $text=~m/(?:(?:${RLrl})+)|(?:[A-Za-z0-9]+)/gom; my (%c, %good,$sstr); @@ -168,6 +224,8 @@ sub proxy $good{$_}=1 if $c{$_}<200; } + $good{$words[$_]}=0 foreach 16..$#words; + # foreach (@list) # { # if ($good{$_}) @@ -219,6 +277,7 @@ print "$query",br if $printqueries; { push (@{$nf[$i]},$arr[0]) } + $sth->finish; } @@ -265,6 +324,7 @@ print STDERR "!$query\n",br if $printque { @blob=(@blob,unpack 'C*',$arr[0]); } + $sth->finish; $query="select number from nf where ".(join ' OR ', @arr1); print "$query\n",br if $printqueries; $sth=$dbh -> prepare($query); @@ -274,7 +334,7 @@ print "$query\n",br if $printqueries; { $frequence[$i]+=$arr[0]; } - + $sth->finish; if (@blob < 4) @@ -296,7 +356,7 @@ print "$query\n",br if $printqueries; $ii+=4; $number=$lo+$hi*256; $field=$fieldname{$field}; - if ($searchin{lc $field}) + if ($searchin{$field}) { push @{$tasksof{$i}{$number}}, $wordnumber; # дополнили в хэше, висящем на @@ -395,17 +455,17 @@ sub Search { my $sstr=$$s; my (@arr, @Questions, @fields); my (@sar, $i, $sth,$where,$query); - my $ip=$ENV{'REMOTE_ADDR'}; +# my $ip=$ENV{'REMOTE_ADDR'}; - $ip=$dbh->quote($ip); - $query= - "INSERT into queries (query,metod,searchin,ip) - values (". $dbh->quote($sstr).', '. - $dbh->quote($metod) . ', ' . - $dbh->quote(join ' ', grep $searchin{$_}, keys %searchin) . - ", $ip)"; -print $query if $printqueries; - $dbh -> do ($query); +# $ip=$dbh->quote($ip); +# $query= +# "INSERT into queries (query,metod,searchin,ip) +# values (". $dbh->quote($sstr).', '. +# $dbh->quote($metod) . ', ' . +# $dbh->quote(join ' ', grep $searchin{$_}, keys %searchin) . +# ", $ip)"; +#print $query if $printqueries; +# $dbh -> do ($query); if ($metod eq 'rus') { my @tasks=russearch($dbh,$sstr,$all,$allnf); @@ -450,10 +510,11 @@ print $query if $printqueries; ###### { - foreach (qw/Question Answer Sources Authors Comments/) { - if (param($_)) { +# foreach (qw/Question Answer Sources Authors Comments/) { + foreach (param('searchin')) { +# if (param($_)) { push @fields, "IFNULL($_, '')"; - } +# } } @sar = split " ", $sstr; for $i (0 .. $#sar) { @@ -480,7 +541,7 @@ print $query if $printqueries; while (@arr = $sth->fetchrow) { push @Questions, $arr[0] unless $forbidden{$arr[0]}; } - + $sth->finish; print "@Questions" if $printqueries; return @Questions; } @@ -490,7 +551,7 @@ print "@Questions" if $printqueries; пП рР сС тТ уУ фФ хХ цЦ чЧ шШ щЩ ьЬ ыЫ эЭ юЮ яЯ/; sub NoCase { - my ($sstr) = shift; + my ($sstr) = shift; my ($res); if (($res) = grep(/$sstr/, @letters)) { @@ -504,27 +565,77 @@ sub PrintList { my ($dbh,$Questions,$shablon)=@_; my $first=param('first') ||1; - my $kvo=param('kvo') ||30; + my $kvo=param('kvo') ||150; $first=$first-($first-1)%$kvo; my $last=$first+$kvo-1; $last=scalar @$Questions if scalar @$Questions <$last; my($f,$l); my $nav=''; + my $qs=query_string; + $qs=~s/\;/\&/g; + $qs=~s/\&first\=[^\&]+//g; + my $sstr=param('sstr'); + $qs=~s/sstr=[^\&]+/sstr=$sstr/; + if ($first>$kvo*3+1) + { + $nav.= + (" "x4). + a({href=>url."?".$qs."\&first=1"},"<<").(" "x4). + a({href=>(url."?".$qs."\&first=".($first-$kvo))},"<").(" "x4) + } + + else {$nav.=' 'x15;} + + my ($fprint,$lprint); + my $llprint=$#$Questions- ($#$Questions+1)%$kvo+2; + if ($#$Questions+1<=$kvo*7) + { $fprint=1; + $lprint=$llprint; + } + elsif ($first>$kvo*3 && $#$Questions+1-$first>$kvo*3) + { + $fprint=$first-$kvo*3; + $lprint=$first+$kvo*3; + } + elsif ($first<=$kvo*3) + { + $fprint=1; $lprint=6*$kvo+1; + } + else + { + $lprint=$llprint; + $fprint=$lprint-$kvo*6 + } + +# my $fprint=($first>$kvo*3) ? $first-$kvo*3 : 1; +# my $lprint=$#$Questions+1-$fprint>$kvo*7 ? $kvo*7 :$#$Questions+1; +# if ($lprint-$fprint<$kvo*6 && $fprint>1) +# { +# $fprint=$lprint-$kvo*6; +# $fprint=1 if ($fprint<=0) +# } - for($f=1; $f<=@$Questions; $f+=$kvo) + + + for($f=$fprint; $f<=$lprint; $f+=$kvo) { +# next if $first-$f>$kvo*3; $l=$f+$kvo-1; $l=$#$Questions+1 if $l>$#$Questions+1; if ($f==$first) {$nav.="[$f-$l] ";} else { - my $qs=query_string; - $qs=~s/\;/\&/g; - $qs=~s/\&first\=[^\&]+//g; - $qs.="\&first=$f"; - - $nav.= "[".a({href=>(url."?".$qs)},"$f-$l")."] ";} + $nav.= "[".a({href=>(url."?".$qs."\&first=$f")},"$f-$l")."] ";} } + if ($lprint+$kvo<$#$Questions) + { + $nav.= + (" "x4). + a({href=>(url."?".$qs."\&first=".($first+$kvo))},">").(" "x4). + a({href=>url."?".$qs."\&first=$llprint"},">>").(" "x4) + } + + print "$nav".br."\n"; for (my $i = $first; $i <= $last; $i++) { my $output = &PrintQuestion($dbh, $$Questions[$i-1], 1, $i, 1); @@ -536,13 +647,16 @@ sub PrintList { } print $output; } + + print "$nav".br."\n"; } sub PrintSearch { my ($dbh, $sstr, $metod) = @_; - + print h2("Поиск в базе вопросов"); + print printform; my @allnf; my (@Questions) = &Search($dbh, \$sstr,$metod,$all,\@allnf); my ($output, $i, $suffix, $hits) = ('', 0, '', $#Questions + 1); @@ -619,6 +733,13 @@ sub PrintRandom { return $output; } +sub PrintEditor { + my $t=shift; #ссылка на Хэш с полями + my $ed=$$t{'Editors'}; + my $edname=($ed=~/\,/ ) ? "Редакторы" : "Редактор" ; + return h4({align=>"center"},"$edname: $ed" ); +} + sub PrintTournament { my ($dbh, $Id, $answer) = @_; my (%Tournament, @Tours, $i, $list, $qnum, $imgsrc, $alt, @@ -632,7 +753,7 @@ sub PrintTournament { my ($Copyright) = $Tournament{'Copyright'}; @Tours = &GetTours($dbh, $Id); - + $list=''; if ($Id) { for ($Tournament{'Type'}) { /Г/ && do { @@ -652,6 +773,7 @@ sub PrintTournament { $output .= h2({align=>"center"}, "$title") . p . "\n"; + $output.=&PrintEditor(\%Tournament); last; }; /Т/ && do { @@ -718,10 +840,11 @@ sub PrintTournament { $output .= p("Копирайт: " . $Copyright); } + + if ($Info) { $output .= p($Info); } - return $output; } @@ -761,6 +884,7 @@ sub PrintTour { $Tournament{'PlayedAt'}, "
", $Tour{"Title"} . " ($qnum вопрос$suffix)\n") . p; + $output .=&PrintEditor(\%Tour); my (@Questions) = &GetTourQuestions($dbh, $Id); for ($q = 0; $q <= $#Questions; $q++) { @@ -858,31 +982,31 @@ sub PrintQuestion { if ($Question{'Authors'}) { my $q=$Question{'Authors'}; - my $sth=$dbh->prepare("select Authors.Id,Name, Surname, Nicks from Authors, A2Q - where Authors.Id=Author And Question=$Id"); - $sth->execute; - my ($AuthorId,$Name, $Surname,$other,$Nicks); - - while ((($AuthorId,$Name, $Surname,$Nicks)=$sth->fetchrow),$AuthorId) - { - my ($firstletter)=$Name=~m/^./g; - $Name=~s/\./\\\./g; - my $sha="(?:$Name\\s+$Surname)|(?:$Surname\\s+$Name)|(?:$firstletter\\.\\s*$Surname)|(?:$Surname\\s+$firstletter\\.)|(?:$Surname)|(?:$Name)"; - if ($Nicks) - { - $Nicks=~s/^\|//; - foreach (split /\|/, $Nicks) - { - s/\s+/ /g; - s/\s+$//; - s/ /\\s+/g; - s/\./\\\./g; - if (s/>$//) {$sha="$sha|(?:$_)"} - else {$sha="(?:$_)|$sha"} - } - } - $q=~s/($sha)/a({href=>url."?qofauthor=$AuthorId"},$1)/ei; - } +# my $sth=$dbh->prepare("select Authors.Id,Name, Surname, Nicks from Authors, A2Q +# where Authors.Id=Author And Question=$Id"); +# $sth->execute; +# my ($AuthorId,$Name, $Surname,$other,$Nicks); + +# while ((($AuthorId,$Name, $Surname,$Nicks)=$sth->fetchrow),$AuthorId) +# { +# my ($firstletter)=$Name=~m/^./g; +# $Name=~s/\./\\\./g; +# my $sha="(?:$Name\\s+$Surname)|(?:$Surname\\s+$Name)|(?:$firstletter\\.\\s*$Surname)|(?:$Surname\\s+$firstletter\\.)|(?:$Surname)|(?:$Name)"; +# if ($Nicks) +# { +# $Nicks=~s/^\|//; +# foreach (split /\|/, $Nicks) +# { +# s/\s+/ /g; +# s/\s+$//; +# s/ /\\s+/g; +# s/\./\\\./g; +# if (s/>$//) {$sha="$sha|(?:$_)"} +# else {$sha="(?:$_)|$sha"} +# } +# } +# $q=~s/($sha)/a({href=>url."?qofauthor=$AuthorId"},$1)/ei; +# } $output .= &PrintField("Автор(ы)", $q, $text); @@ -897,8 +1021,8 @@ sub PrintQuestion { $output .= &PrintField("Комментарии", $Question{'Comments'}, $text); } } - $output.=br.a({href=> url."?metod=proxy&qid=$Id"}, 'Близкие вопросы').p - if $answer; +# $output.=br.a({href=> url."?metod=proxy&qid=$Id"}, 'Близкие вопросы').p +# if $answer; return $output; } @@ -924,17 +1048,31 @@ sub Get12Random { my (%chosen); srand; - for ($i = 0; $i < $num; $i++) { - do { - $q = int(rand($qnum)); - $sth = $dbh->prepare("SELECT Type FROM Questions - WHERE QuestionId=$q"); - $sth->execute; - $t = ($sth->fetchrow)[0]; - } until !$chosen{$q} && $t && $type =~ /[$t]/; - $chosen{$q} = 'y'; - push @questions, $q; + my $where=0; + my $r=int (rand(10000)); + + foreach (split '', $type) + { + $where.= " OR (Type ='$_') OR (Type ='$_Д') "; + } + $where.= "OR (Type='ЧБ')" if ($type=~/Ч|Б/); + + $q="select QuestionId, QuestionId/$r-floor(QuestionId/$r) as val + from Questions where $where order by val limit $num"; + +# Когда на куличках появится mysql >=3.23 надо заменить на order by rand(); + + $sth=$dbh->prepare($q); + $sth->execute; + while (($i)=$sth->fetchrow) + { + push @questions,$i; } + + for ($i=@questions; --$i;){ + my $j=rand ($i+1); + @questions[$i,$j]=@questions[$j,$i] unless $i==$j; + } return @questions; } @@ -1023,12 +1161,14 @@ sub PrintDates { " " . a({href=>url . "?tour=$Tournament{'Id'}&answer=0"}, $Tournament{'Title'}, $Tournament{'PlayedAt'})); } + $sth->finish; $output .= dl($list); return $output; } sub PrintQOfAuthor { + my ($dbh, $id) = @_; $id=$dbh->quote($id); my $sth = $dbh->prepare("SELECT Name, Surname FROM Authors WHERE Id=$id"); @@ -1041,6 +1181,7 @@ sub PrintQOfAuthor my @Questions; while (($q)=$sth->fetchrow,$q) {push @Questions,$q unless $forbidden{$q}} + $sth->finish; my ($output, $i, $suffix, $hits) = ('', 0, '', $#Questions + 1); @@ -1051,7 +1192,8 @@ sub PrintQOfAuthor } else { $suffix = 'я'; } - + print h2("Поиск в базе вопросов"); + print printform; print p({align=>"center"}, "Автор ".strong("$name $surname. ") . " : $hits попадани$suffix."); @@ -1113,6 +1255,7 @@ a({href=>url."?authors=surname"},"фамили } } $output.=""; + $sth->finish; return $output; } @@ -1141,6 +1284,7 @@ MAIN: print &Include_virtual("../dimrub/db/reklama.html"); } + if ($^O =~ /win/i) { $thislocale = "Russian_Russia.20866"; } else { @@ -1168,17 +1312,18 @@ if ((uc 'а') ne 'А') {print "Koi8-r loca if (param('rand')) { my ($type, $qnum) = ('', 12); - $type .= 'Б' if (param('brain')); - $type .= 'Ч' if (param('chgk')); + $type.=$TypeName{$_} foreach param('type'); +# $type .= 'Б' if (param('brain')); +# $type .= 'Ч' if (param('chgk')); $qnum = param('qnum') if (param('qnum') =~ /^\d+$/); $qnum = 0 if (!$type); - if (param('email') && -x $SENDMAIL && - open(F, "| $SENDMAIL -t -n")) { - my ($Email) = param('email'); + my $Email; + if (($Email=param('email')) && -x $SENDMAIL && + open(F, "| $SENDMAIL $Email")) { my ($mime_type) = $text ? "plain" : "html"; print F <Reload для получения еще одного пакета"; } else { print &PrintRandom($dbh, $type, $qnum, $text); @@ -1208,8 +1353,10 @@ print $query if $printqueries; my $sth=$dbh->prepare($query); $sth->execute; my $sstr= join ' ',$sth->fetchrow; - $searchin{'question'}=1; - $searchin{'answer'}=1; + $sth->finish; + $searchin{'Question'}=1; + $searchin{'Answer'}=1; + $sstr=~tr/ёЁ/еЕ/; $sstr=~s/[^йцукенгшщзхъфывапролджэячсмитьбюЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮa-zA-Z0-9]/ /gi; # print &PrintQuestion($dbh,$qid, 1, '!'); &PrintSearch($dbh, $sstr, 'proxy'); @@ -1249,6 +1396,7 @@ $sstr=~s/[^йцукенгшщзхъфывапролджэячсмит WHERE FileName = '$tour.txt'"); $sth->execute; $tour = ($sth->fetchrow)[0]; + $sth->finish; } print &PrintTournament($dbh, $tour, param('answer')); }