1: #!/usr/bin/perl -w
2:
3: use DBI;
4: use CGI ':all';
5: use strict;
6: use Time::Local;
7: use POSIX qw(locale_h);
8: use locale;
9: open STDERR, ">>errors1";
10: my $printqueries=0;
11: my %forbidden=();
12: my $debug=0; #added by R7
13: if (param('debug')) {$debug=1; $printqueries=1}
14: *STDERR=*STDOUT if $debug;
15: my %fieldname= (0,'Question', 1, 'Answer', 2, 'Comments', 3, 'Authors', 4, 'Sources');
16: my %rusfieldname=('Question','Вопрос', 'Answer', 'Ответ',
17: 'Comments', 'Комментарии', 'Authors', 'Автор',
18: 'Sources', 'Источник','old','Старый','rus','Новый');
19: my %searchin;
20: my $rl=qr/[йцукенгшщзхъфывапролджэячсмитьбюё]/;
21: my $RL=qr/[ЙЦУКЕНГШЩЗХЪЭЖДЛОРПАВЫФЯЧСМИТЬБЮЁ]/;
22: my $RLrl=qr/(?:(?:${rl})|(?:${RL}))+/;
23: my $l=qr/(?:(?:${RLrl})|(?:[\w\-]))+/;
24: my $Ll=qr/(?:[A-Z])|(?:${RL})/;
25: my %metodchar=('rus',1,'old',2);
26:
27:
28:
29: my $thislocale;
30:
31: $searchin{$_}=1 foreach param('searchin');
32: my %TypeName=('children'=>'Д', 'game'=>'И',
33: 'chgk'=>'Ч', 'brain'=>'Б', 'beskrylka'=>'Л','ehruditka'=>'Э');
34:
35:
36:
37: my $all=param('all');
38: $all=0 if lc $all eq 'no';
39: my ($PWD) = `pwd`;
40: chomp $PWD;
41: my ($SRCPATH) = "$PWD/../dimrub/src";
42: my ($ZIP) = "/home/piataev/bin/zip";
43: my $DUMPFILE = "/tmp/chgkdump";
44: my ($SENDMAIL) = "/usr/sbin/sendmail";
45: my ($TMPDIR) = "/tmp";
46: my ($TMSECS) = 30*24*60*60;
47: my (%RevMonths) =
48: ('Jan', '0', 'Feb', '1', 'Mar', '2', 'Apr', '3', 'May', '4', 'Jun', '5',
49: 'Jul', '6', 'Aug', '7', 'Sep', '8', 'Oct', '9', 'Nov', '10',
50: 'Dec', '11',
51: 'Янв', '0', 'Фев', 1, 'Мар', 2, 'Апр', 3, 'Май', '4',
52: 'Июн', '5', 'Июл', 6, 'Авг', '7', 'Сен', '8',
53: 'Окт', '9', 'Ноя', '19', 'Дек', '11');
54: my @months=('000','Jan',"Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct",
55: "Nov","Dec");
56:
57:
58: # Determine whether the given time is within 2 months from now.
59: sub NewEnough {
60: my ($a) = @_;
61: my ($year, $month, $day) = split('-', $a);
62:
63: return (time - timelocal(0, 0, 0, $day, $month -1, $year) < $TMSECS);
64: }
65:
66: # Reads one question from the DB. Gets DB handler and Question ID.
67: sub GetTournament {
68: my ($dbh, $Id) = @_;
69: my (%Tournament, $field, @arr);
70:
71: return %Tournament if ($Id == 0);
72:
73: my ($sth) = $dbh->prepare("SELECT * FROM Tournaments WHERE Id=$Id");
74: $sth->execute;
75:
76: @arr = $sth->fetchrow;
77: my($i, $name) = 0;
78: foreach $name (@{$sth->{NAME}}) {
79: $Tournament{$name} = $arr[$i++];
80: }
81: $sth->finish;
82: return %Tournament;
83: }
84:
85: # Reads one question from the DB. Gets DB handler and Question ID.
86: sub GetQuestion {
87: my ($dbh, $QuestionId) = @_;
88: my (%Question, $field, @arr);
89:
90: my($sth) = $dbh->prepare("
91: SELECT * FROM Questions WHERE QuestionId=$QuestionId
92: ");
93:
94: $sth->execute;
95:
96: @arr = $sth->fetchrow;
97: my($i, $name) = 0;
98: foreach $name (@{$sth->{NAME}}) {
99: $Question{$name} = $arr[$i++];
100: }
101:
102: $sth->finish;
103: return %Question;
104: }
105:
106: # Gets numbers of all the questions from the given tour.
107: sub GetTourQuestions {
108: my ($dbh, $ParentId) = @_;
109: my (@arr, @Questions);
110:
111: my ($sth) = $dbh->prepare("SELECT QuestionId FROM Questions
112: WHERE ParentId=$ParentId order by Number");
113:
114: $sth->execute;
115:
116: while (@arr = $sth->fetchrow) {
117: push @Questions, $arr[0];
118: }
119:
120: $sth->finish;
121: return @Questions;
122: }
123:
124: # Returns list of children of the given tournament.
125: sub GetTours {
126: my ($dbh, $ParentId) = @_;
127: my (@arr, @Tours);
128:
129: my ($sth) = $dbh->prepare("SELECT Id FROM Tournaments
130: WHERE ParentId=$ParentId ORDER BY Id");
131:
132: $sth->execute;
133:
134: while (@arr = $sth->fetchrow) {
135: push @Tours, $arr[0];
136: }
137: $sth->finish;
138: return @Tours;
139: }
140:
141: sub count
142: {
143: my ($dbh,$word)=@_;
144: print "timeb=".time.br if $debug;
145: $word=$dbh->quote(uc $word);
146: my $query="SELECT number from nests,nf where $word=w1 AND w2=nf.id";
147: my $sth=$dbh->prepare($query);
148: $sth->execute;
149: my @a=$sth->fetchrow;
150: print "timee0=".time.br if $debug;
151: $sth->finish;
152: $a[0]||0;
153: }
154:
155:
156: sub printform
157: {
158:
159: my $submit=submit(-value=>'Поиск');
160: my $inputstring=textfield(-name=>'sstr',
161: -default=>param('sstr')||'',
162: -size=>30,
163: -maxlength=>50);
164: my $qnumber="Выводить по".br. textfield(-name=>'kvo',
165: -default=>param('kvo')||'150',
166: -size=>3,
167: -maxlength=>5). br."вопросов";
168:
169: my @df=keys %searchin;
170: @df=('Question', 'Answer') unless @df;
171: my $fields=checkbox_group('searchin',['Question','Answer','Comments','Authors','Sources'], [@df],
172: 'false',\%rusfieldname);
173:
174: my $metod=radio_group(-name=>'metod',-values=>['old','rus'],
175: -default=>(param('metod')||'rus'),
176: -labels=>\%rusfieldname);
177: my $all=radio_group(-name=>'all',-values=>['yes','no'],
178: -default=>(param('all')||'no'),
179: -labels=>{'yes'=>'Все','no'=>'Любое'});
180:
181: #################################################
182: return start_form(-method=>'get',
183: -action=>url,
184: -enctype=>
185: "application/x-www-form-urlencoded"
186: ).br.
187: table(Tr
188: (
189: td({-valign=>'TOP'},$inputstring.$submit.p."Метод: $metod".p."Слова: $all"),
190: td({-valign=>'TOP'},(' 'x 8).'Поля:'),
191: td({-valign=>'TOP'},$fields), td(" "x5),
192: td({-valign=>'TOP'},$qnumber)
193: )
194: )
195:
196: #$fields.
197: #$inputstring.$submit.br.$metod.$all
198: .endform
199: .hr
200:
201: }
202:
203: sub proxy
204: {
205: #print "time0=".time.br if $debug;
206: my ($dbh,$ptext,$allnf)=@_;
207: my $text=$$ptext;
208: $text=~tr/ёЁ/еЕ/;
209: $text=~s/(${RLrl})p(${RLrl})/$1p$2/gom;
210: $text=~s/p(${RLrl})/р$1/gom;
211: $text=~s/(${RLrl})p/$1р/gom;
212: $text=~s/\s+/ /gmo;
213: $text=~s/[^йцукенгшщзхъфывапролджэячсмитьбюЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮQWERTYUIOPASDFGHJKLZXCVBNM0-9]/ /g;
214: $text=uc $text;
215: my @list= $text=~m/(?:(?:${RLrl})+)|(?:[A-Za-z0-9]+)/gom;
216: my (%c, %good,$sstr);
217: foreach (@list)
218: {
219: $c{$_}=count($dbh,$_)||10000;
220: }
221: my @words=sort {$c{$a}<=> $c{$b}} @list;
222:
223: # $good{$words[$_]}=1 foreach 0..4;
224:
225: foreach (@words)
226: {
227: $good{$_}=1 if $c{$_}<200;
228: }
229:
230: $good{$words[$_]}=0 foreach 16..$#words;
231:
232: # foreach (@list)
233: # {
234: # if ($good{$_})
235: # {
236: # $good{$_}=0;
237: # $sstr.=" $_";
238: # }
239: # }
240: $sstr.=" $_" foreach grep {$good{$_}} @list;
241: print "time05=".time.br if $debug;
242: $$ptext=$sstr;
243: return russearch($dbh,$sstr,0,$allnf);
244: }
245:
246:
247: sub russearch {
248: my ($dbh, $sstr, $all,$allnf)=@_;
249: my (@qw,@w,@tasks,$qw,@arr,$nf,$sth,@nf,$w,$where,$e,@where,%good,$i,%where,$from);
250: my($number,@good,$t,$task,@rho,$rank,%rank,$r2,$r1,$word,$n,@last,$good,@words,%number,$taskid);
251: my ($hi, $lo, $wordnumber,$query,$blob,$field,$sf,$ii);
252: my @frequence;
253: my (@arr1,@ar,@sf,@arr2);
254: my %tasks;
255: my $tasks;
256: my @verybad;
257: my %nf;
258: my %tasksof;
259: my %wordsof;
260: my %relevance;
261: my @blob;
262: my %count;
263:
264: $sstr=~tr/йцукенгшщзхъфывапролджэячсмитьбю/ЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮ/;
265: @qw=@w =split (' ', uc $sstr);
266:
267: #-----------
268: foreach $i (0..$#w) # заполняем массив @nf начальных форм
269: # $nf[$i] -- ссылка на массив возможных
270: # начальных форм словоформы $i
271: {
272: $qw= $dbh->quote (uc $w[$i]);
273: $query=" select distinct w2 from nests
274: where w1=$qw";
275: print "$query",br if $printqueries;
276: $sth=$dbh -> prepare($query);
277: $sth -> execute;
278: @{$nf[$i]}=();
279: while (@arr = $sth->fetchrow)
280: {
281: push (@{$nf[$i]},$arr[0])
282: }
283: $sth->finish;
284: }
285:
286:
287: my @bad=grep {!@{$nf[$_]}} 0..$#w; # @bad -- номера словоформ,
288: # которых нет в словаре
289:
290: if (@bad) #есть неопознанные словоформы
291: {
292: require "cw.pl";
293: foreach $i(@bad)
294: {
295: if (@arr=checkword($dbh,$w[$i]))
296: {push (@{$nf[$i]}, @arr);}
297: else
298: {push (@verybad,$i);}
299: }
300: }
301: return () if ($all && @verybad);
302:
303:
304: my $kvo=0;
305: push @$allnf, @{$_} foreach @nf;
306: print "nf=@$allnf" if $printqueries;
307:
308: foreach $i (0..$#w) #запросы в базу...
309: {
310: @arr=@{$nf[$i]} if $nf[$i];
311: @arr2=@arr1=@arr;
312:
313:
314:
315:
316: $_= " word2question.word=".$_. ' ' foreach @arr;
317: $_= " nf.id=".$_. ' ' foreach @arr1;
318: # @arr=(0) unless @arr;
319: $query="select questions from word2question where". (join ' OR ', @arr);
320: print STDERR "!$query\n",br if $printqueries;
321:
322: $sth=$dbh -> prepare($query);
323: $sth->execute;
324:
325: @blob=();
326: while (@arr=$sth->fetchrow)
327: {
328: @blob=(@blob,unpack 'C*',$arr[0]);
329: }
330: $sth->finish;
331: $query="select number from nf where ".(join ' OR ', @arr1);
332: print "$query\n",br if $printqueries;
333: $sth=$dbh -> prepare($query);
334: $sth->execute;
335:
336: while (@arr=$sth->fetchrow)
337: {
338: $frequence[$i]+=$arr[0];
339: }
340: $sth->finish;
341:
342:
343: if (@blob < 4)
344: {
345: $tasksof{$i}=undef;
346: } else
347: {
348: $kvo++;
349: $ii=0;
350: while ($ii<$#blob) # создаём хэш %tasksof, ключи которого --
351: # номера искомых словоформ, а значения --
352: # списки вопросов, в которых есть соответствующа
353: # словоформа.
354: # Каждый список в свою очередь также оформлен в
355: # виде хэша, ключи которого -- номера вопросов,
356: # а значения -- списки номеров вхождений. Вот.
357: {
358: ($field,$lo,$hi,$wordnumber)=@blob[$ii..($ii+3)];
359: $ii+=4;
360: my $addnumber=($field >> 4) << 16;
361: $number=(($field >> 4) << 16)+($hi << 8) + $lo;
362: $field=$fieldname{$field & 0xF};
363: if ($searchin{$field})
364: {
365: push @{$tasksof{$i}{$number}}, $wordnumber;
366: # дополнили в хэше, висящем на
367: # словоформе $i в %tasksof список
368: # вхождений $i в вопрос $number.
369: push @{$wordsof{$number}{$i}}, $wordnumber;
370: # дополнили в хэше, висящем на
371: # вопросе $number в %wordsof список
372: # вхождений $i в вопрос $number.
373:
374:
375: }
376: } #while ($ii<$#blob)
377: }
378: } #foreach $i
379:
380: #print "keys tasksof", join ' ', keys %{$tasksof{0}};
381: #Ищем пересечение или объединение списков вопросов (значений %tasksof)
382: foreach $sf (keys %tasksof)
383: {
384: $count{$_}++ foreach keys %{$tasksof{$sf}};
385: }
386: @tasks= ($all ? (grep {$count{$_}==$kvo} keys %count) :
387: keys %count) ;
388:
389:
390: print "\n\$#tasks=",$#tasks,br if $printqueries;
391: ############ Сортировка найденных вопросов
392:
393: foreach (keys %wordsof)
394: {
395: $relevance{$_}=&relevance($#w,$wordsof{$_},\@frequence) if $_
396: }
397:
398: @tasks=sort {$relevance{$b}<=>$relevance{$a}} @tasks;
399:
400:
401: ############
402:
403: print "tasks=@tasks" if $printqueries;
404:
405: #print "$_ $relevance{$_} | " foreach @tasks;
406: #print br;
407: print "allnf=@$allnf",br if $printqueries;
408: return @tasks;
409: }
410:
411:
412: sub distance {
413: # на входе -- номера словоформ и ссылки на
414: # списки вхождений. На выходе -- расстояние,
415: # вычисляемое по формуле min(|b-a-pb+pa|)
416: # pb,pa
417: # (pb и pa -- позиции слов b и a)
418: my ($a,$b,$lista,$listb)=@_;
419: my ($pa,$pb,$min,$curmin);
420: $min=10000;
421: foreach $pa (@$lista)
422: {
423: foreach $pb (@$listb)
424: {
425: $curmin=abs($b-$a-$pb+$pa);
426: $min= $curmin if $curmin<$min;
427: }
428: }
429: return $min;
430:
431: }
432:
433: sub relevance {
434: # На входе -- количество искомых словоформ -1 и
435: # ссылка на hash, ключи которого --
436: # номера словоформ, а значения -- списки вхождений
437:
438: my ($n,$words,$frequence)=@_;
439: my $relevance=0;
440: my ($first,$second,$d);
441: foreach $first (0..$n)
442: {
443: $relevance+=scalar @{$$words{$first}}+1000+1000/$$frequence[$first]
444: if $$words{$first};
445: foreach $second ($first+1..$n)
446: {
447: $d=&distance($first,$second,$$words{$first},$$words{$second});
448: $relevance+=($d>10?0:10-$d)*10;
449: }
450: }
451: return $relevance;
452: }
453:
454:
455:
456: # Returns list of QuestionId's, that have the search string in them.
457: sub Search {
458: my ($dbh, $s,$metod,$all,$allnf) = @_;
459: my $sstr=$$s;
460: my (@arr, @Questions, @fields);
461: my (@sar, $i, $sth,$where,$query);
462: # my $ip=$ENV{'REMOTE_ADDR'};
463:
464: # $ip=$dbh->quote($ip);
465: # $query=
466: # "INSERT into queries (query,metod,searchin,ip)
467: # values (". $dbh->quote($sstr).', '.
468: # $dbh->quote($metod) . ', ' .
469: # $dbh->quote(join ' ', grep $searchin{$_}, keys %searchin) .
470: # ", $ip)";
471: #print $query if $printqueries;
472: # $dbh -> do ($query);
473: if ($metod eq 'rus')
474: {
475: my @tasks=russearch($dbh,$sstr,$all,$allnf);
476: return @tasks
477: }
478: elsif ($metod eq 'proxy')
479: {
480: # $searchin{'question'}=1;
481: # $searchin{'answer'}=1;
482: my @task=proxy($dbh,$s,$allnf);
483: # $$s=$sstr;
484: return @task
485: }
486:
487:
488:
489: ###Simple and advanced query processing. Added by R7
490: if ($metod eq 'simple' || $metod eq 'advanced')
491: {
492: foreach (qw/Question Answer Sources Authors Comments/) {
493: if (param($_)) {
494: push @fields, $_;
495: }
496: }
497:
498: @fields=(qw/Question Answer Sources Authors Comments/) unless scalar @fields;
499: my $fields=join ",", @fields;
500: my $q=new Text::Query($sstr,
501: -parse => 'Text::Query::'.
502: (($metod eq 'simple') ? 'ParseSimple':'ParseAdvanced'),
503: -solve => 'Text::Query::SolveSQL',
504: -build => 'Text::Query::BuildSQLMySQL',
505: -fields_searched => $fields);
506:
507: $where= $$q{'matchexp'};
508: $query= "SELECT Questionid FROM Questions
509: WHERE $where";
510: print br."Query is: $query".br if $debug;
511:
512: $sth = $dbh->prepare($query);
513: } else
514: ######
515: {
516:
517: # foreach (qw/Question Answer Sources Authors Comments/) {
518: foreach (param('searchin')) {
519: # if (param($_)) {
520: push @fields, "IFNULL($_, '')";
521: # }
522: }
523: @sar = split " ", $sstr;
524: for $i (0 .. $#sar) {
525: $sar[$i] = $dbh->quote("%${sar[$i]}%");
526: }
527:
528: my($f) = "CONCAT(" . join(',', @fields) . ")";
529: if (param('all') eq 'yes') {
530: $sstr = join " AND $f LIKE ", @sar;
531: } else {
532: $sstr = join " OR $f LIKE ", @sar;
533: }
534:
535: my $query;
536: $query="SELECT QuestionId FROM Questions
537: WHERE $f LIKE $sstr ORDER BY QuestionId";
538:
539:
540: print $query if $printqueries;
541: $sth = $dbh->prepare($query)
542: } #else -- processing old-style query (R7)
543:
544: $sth->execute;
545: while (@arr = $sth->fetchrow) {
546: push @Questions, $arr[0] unless $forbidden{$arr[0]};
547: }
548: $sth->finish;
549: print "@Questions" if $printqueries;
550: return @Questions;
551: }
552:
553: # Substitute every letter by a pair (for case insensitive search).
554: my (@letters) = qw/аА бБ вВ гГ дД еЕ жЖ зЗ иИ йЙ кК лЛ мМ нН оО
555: пП рР сС тТ уУ фФ хХ цЦ чЧ шШ щЩ ьЬ ыЫ эЭ юЮ яЯ/;
556:
557: sub NoCase {
558: my ($sstr) = shift;
559: my ($res);
560:
561: if (($res) = grep(/$sstr/, @letters)) {
562: return "[$res]";
563: } else {
564: return $sstr;
565: }
566: }
567:
568: sub PrintList {
569: my ($dbh,$Questions,$shablon,$was)=@_;
570:
571: my $first=param('first') ||1;
572: my $kvo=param('kvo') ||150;
573:
574: $first=$first-($first-1)%$kvo;
575: my $last=$first+$kvo-1;
576: $last=scalar @$Questions if scalar @$Questions <$last;
577: my($f,$l);
578: my $nav='';
579: my $qs=query_string;
580: $qs=~s/\;/\&/g;
581: $qs=~s/\&first\=[^\&]+//g;
582: my $sstr=param('sstr');
583: $qs=~s/sstr=[^\&]+/sstr=$sstr/;
584: $qs=~s/\&was=[^\&]+//;
585: $qs.="&was=$was";
586: if ($first>$kvo*3+1)
587: {
588: $nav.=
589: (" "x4).
590: a({href=>url."?".$qs."\&first=1"},"<<").(" "x4).
591: a({href=>(url."?".$qs."\&first=".($first-$kvo))},"<").(" "x4)
592: }
593:
594: else {$nav.=' 'x15;}
595:
596: my ($fprint,$lprint);
597: my $llprint=$#$Questions- ($#$Questions+1)%$kvo+2;
598: if ($#$Questions+1<=$kvo*7)
599: { $fprint=1;
600: $lprint=$llprint;
601: }
602: elsif ($first>$kvo*3 && $#$Questions+1-$first>$kvo*3)
603: {
604: $fprint=$first-$kvo*3;
605: $lprint=$first+$kvo*3;
606: }
607: elsif ($first<=$kvo*3)
608: {
609: $fprint=1; $lprint=6*$kvo+1;
610: }
611: else
612: {
613: $lprint=$llprint;
614: $fprint=$lprint-$kvo*6
615: }
616:
617: # my $fprint=($first>$kvo*3) ? $first-$kvo*3 : 1;
618: # my $lprint=$#$Questions+1-$fprint>$kvo*7 ? $kvo*7 :$#$Questions+1;
619: # if ($lprint-$fprint<$kvo*6 && $fprint>1)
620: # {
621: # $fprint=$lprint-$kvo*6;
622: # $fprint=1 if ($fprint<=0)
623: # }
624:
625:
626:
627: for($f=$fprint; $f<=$lprint; $f+=$kvo)
628: {
629: # next if $first-$f>$kvo*3;
630: $l=$f+$kvo-1;
631: $l=$#$Questions+1 if $l>$#$Questions+1;
632: if ($f==$first) {$nav.="[$f-$l] ";}
633: else {
634: $nav.= "[".a({href=>(url."?".$qs."\&first=$f")},"$f-$l")."] ";}
635: }
636: if ($lprint+$kvo<$#$Questions)
637: {
638: $nav.=
639: (" "x4).
640: a({href=>(url."?".$qs."\&first=".($first+$kvo))},">").(" "x4).
641: a({href=>url."?".$qs."\&first=$llprint"},">>").(" "x4)
642: }
643:
644:
645: print "$nav".br."\n";
646: for (my $i = $first; $i <= $last; $i++) {
647: my $output = &PrintQuestion($dbh, $$Questions[$i-1], 1, 0, 1);
648: if (param('metod') eq 'rus' || param('metod') eq 'proxy')
649: {
650: $output=~s/\b($shablon)\b/\<strong\>$1\<\/strong\>/gi;
651: } else {
652: $output=~s/($shablon)/\<strong\>$1\<\/strong\>/gi;
653: }
654: print $output;
655: }
656:
657:
658: print "$nav".br."\n";
659:
660: }
661:
662: sub PrintSearch {
663: my ($dbh, $sstr, $metod,$was) = @_;
664: my $t=time;
665: print h2("Поиск в базе вопросов");
666: print printform;
667: my @allnf;
668: my @Questions;
669: if ($was)
670: {
671: my $sth=$dbh->prepare ("select sstr,questions,allnf from lastqueries where id=".param('was'));
672: $sth->execute;
673: my ($q,$nf);
674: ($sstr, $q,$nf)=($sth->fetchrow);
675: @Questions=unpack 'L*',$q;
676: @allnf=unpack 'L*',$nf;
677: $sth->finish;
678: } else
679: {
680: @Questions=&Search($dbh, \$sstr,$metod,$all,\@allnf);
681: my $tmp=$dbh->quote(pack("L*",@Questions));
682: my $qsstr=$dbh->quote($sstr);
683: my $nf=$dbh->quote(pack("L*", @allnf));
684: my $ss=200;
685: do
686: {
687: $was=int rand(32000);
688: }
689: while (--$ss && (!$dbh->do ("insert into lastqueries (id,sstr,questions,allnf)
690: values ($was, $qsstr,$tmp,$nf)")));
691: print "Something is wrong...".br unless $ss;
692: }
693:
694:
695:
696: print p. "Время поиска: " . (time-$t) ." сек.".p;
697: my ($output, $i, $suffix, $hits) = ('', 0, '', $#Questions + 1);
698:
699: my $shablon;
700: $metod='rus' if $metod eq 'proxy';
701: if ($metod eq 'rus')
702: {
703: my $where='0';
704: $where.= " or w2=$_ " foreach @allnf;
705: my $query="select w1 from nests where $where";
706: my $sth=$dbh->prepare($query);
707: print "$query" if $printqueries;
708:
709: $sth->execute;
710: my @shablon;
711: while (my @arr = $sth->fetchrow)
712: {
713: push @shablon,"(?:$arr[0])";
714: }
715: $sth->finish;
716: $shablon= join "|", @shablon;
717: $shablon=~s/[её]/\[ЕЁ\]/gi;
718: # $shablon=~s/([йцукенгшщзхъфывапролджэячсмитьбюЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮ])/&NoCase($1)/ge;
719: $shablon=qr/$shablon/i;
720: print "!$shablon!",br if $printqueries;
721:
722: }
723:
724:
725:
726: if ($hits =~ /1.$/ || $hits =~ /[5-90]$/) {
727: $suffix = 'й';
728: } elsif ($hits =~ /1$/) {
729: $suffix = 'е';
730: } else {
731: $suffix = 'я';
732: }
733:
734: print p({align=>"center"}, "Результаты поиска на " . strong($sstr)
735: . " : $hits попадани$suffix.");
736:
737: if (param('word')) {
738: $sstr = '[ \.\,:;]' . $sstr . '[ \.\,:\;]';
739: }
740:
741: $sstr =~ s/(.)/&NoCase($1)/ge;
742:
743: my @sar;
744: if ($metod ne 'rus')
745: {
746: (@sar) = split(' ', $sstr);
747: $shablon=join "|",@sar;
748: }
749: PrintList($dbh,\@Questions,$shablon,$was);
750: }
751:
752: sub PrintRandom {
753: my ($dbh, $type, $num, $text) = @_;
754: my (@Questions) = &Get12Random($dbh, $type, $num);
755: my ($output, $i) = ('', 0);
756:
757: if ($text) {
758: $output .= " $num случайных вопросов.\n\n";
759: } else {
760: $output .=
761: h2({align=>"center"}, "$num случайных вопросов.");
762: }
763:
764: for ($i = 0; $i <= $#Questions; $i++) {
765: # Passing DB handler, question ID, print answer, question
766: # number, print title, print text/html
767: $output .=
768: &PrintQuestion($dbh, $Questions[$i], 1, $i + 1, 0, $text);
769: }
770: return $output;
771: }
772:
773: sub PrintEditor {
774: my $t=shift; #ссылка на Хэш с полями
775: my $ed=$$t{'Editors'}||'';
776: my $edname=($ed=~/\,/ ) ? "Редакторы" : "Редактор" ;
777: return $ed? h4({align=>"center"},"$edname: $ed" ): '';
778: }
779:
780: sub PrintTournament {
781: my ($dbh, $Id, $answer) = @_;
782: my (%Tournament, @Tours, $i, $list, $qnum, $imgsrc, $alt,
783: $SingleTour);
784: my ($output) = '';
785:
786: %Tournament = &GetTournament($dbh, $Id) if ($Id);
787:
788: my ($URL) = $Tournament{'URL'};
789: my ($Info) = $Tournament{'Info'};
790: my ($Copyright) = $Tournament{'Copyright'};
791: my $fname=$Tournament{'FileName'};
792: @Tours = &GetTours($dbh, $Id);
793: $list='';
794: my $textid;
795: if ($Id) {
796: for ($Tournament{'Type'}) {
797: /Г/ && do {
798: $output .= h2({align=>"center"},
799: "Группа: $Tournament{'Title'} ",
800: "$Tournament{'PlayedAt'}") . p . "\n";
801: last;
802: };
803: /Ч/ && do {
804: return &PrintTour($dbh, $Tours[0], $answer)
805: if ($#Tours == 0);
806:
807: my $title="Пакет: $Tournament{'Title'}";
808: if ($Tournament{'PlayedAt'}) {
809: $title .= " $Tournament{'PlayedAt'}";
810: }
811:
812: $output .= h2({align=>"center"},
813: "$title") . p . "\n";
814: $output.=&PrintEditor(\%Tournament);
815: last;
816: };
817: /Т/ && do {
818: return &PrintTour($dbh, $Id, $answer);
819: };
820: }
821: } else {
822: my ($qnum) = GetQNum($dbh);
823: $output .= h2("Банк Вопросов: $qnum вопрос".&Suffix($qnum))
824: . p . "\n";
825: }
826:
827: for ($i = 0; $i <= $#Tours; $i++) {
828: %Tournament = &GetTournament($dbh, $Tours[$i]);
829:
830: if ($Tournament{'Type'} =~ /Ч/) {
831: $SingleTour = 0;
832: my (@Tours) = &GetTours($dbh, $Tournament{'Id'});
833: $SingleTour = 1
834: if ($#Tours == 0);
835: }
836: if ($Tournament{'QuestionsNum'} > 0) {
837: $qnum = " ($Tournament{'QuestionsNum'} вопрос" .
838: &Suffix($Tournament{'QuestionsNum'}) . ")\n";
839: } else {
840: $qnum = '';
841: }
842: if ($Tournament{'Type'} =~ /Г/) {
843: $SingleTour=0;
844: $imgsrc = "/icons/folder.gif";
845: $alt = "[*]";
846: } else {
847: $imgsrc = "/icons/folder.gif";
848: $alt = "[-]";
849: }
850:
851: my $textid;
852: if ($textid=$Tournament{'FileName'})
853: {
854: $textid=~s/\.txt//;
855: }
856: elsif ($textid=$Tournament{'Number'})
857: {
858: $fname=~s/\.txt//;
859: $textid="$fname.$textid";
860: }
861: else {$textid=$Tournament{'Id'}};
862:
863:
864: if ($SingleTour or $Tournament{'Type'} =~ /Т/) {
865: $list .= dd(img({src=>$imgsrc, alt=>$alt})
866: . " " . $Tournament{'Title'} . " " .
867: $Tournament{'PlayedAt'} . $qnum) .
868: dl(
869: dd("["
870: . a({href=>url . "?tour=$textid&answer=0"},
871: "вопросы") . "] ["
872: . a({href=>url . "?tour=$textid&answer=1"},
873: "вопросы + ответы") . "]")
874: );
875: } else {
876: $list .= dd(#a({href=>url . "?tour=$textid&comp=1"},
877: #img({src=>'/icons/compressed.gif', alt=>'[ZIP]', border=>1})). " " .
878: img({src=>$imgsrc, alt=>$alt})
879: . " " . a({href=>url . "?tour=$textid&answer=0"},
880: $Tournament{'Title'}. " ".
881: $Tournament{'PlayedAt'}) . $qnum);
882: }
883: }
884: $output .= dl($list);
885:
886: if ($URL) {
887: if (url=~/zaba\.ru/ && $URL=~/^\//){$URL="http://info.chgk.info$URL"}
888: $output .=
889: p("Дополнительная информация об этом турнире - по адресу " .
890: a({-'href'=>$URL}, $URL));
891: }
892:
893: if ($Copyright) {
894: $output .= p("Копирайт: " . $Copyright);
895: }
896:
897:
898:
899: if ($Info) {
900: $output .= p($Info);
901: }
902: return $output;
903: }
904:
905: sub Suffix {
906: my ($qnum) = @_;
907: my ($suffix) = 'а' if $qnum =~ /[234]$/;
908: $suffix = '' if $qnum =~ /1$/;
909: $suffix = 'ов' if $qnum =~ /[567890]$/ || $qnum =~ /1.$/;
910: return $suffix;
911: }
912:
913: sub IsTour {
914: my ($dbh, $Id,$n) = @_;
915:
916: my ($sth) ;
917:
918: if (defined $n)
919: { $sth=$dbh->prepare ("select Id FROM Tournaments
920: WHERE ParentId=$Id AND Number=$n");
921: }
922: else
923: {
924: $sth=$dbh->prepare("SELECT Id FROM Tournaments
925: WHERE Id=$Id");
926: }
927: $sth->execute;
928: my $a=($sth->fetchrow)[0];
929: $sth->finish;
930: return $a;
931: }
932:
933: # Gets a DB handler (ofcourse) and a tour Id. Prints all the
934: # question of that tour, according to the options.
935: sub PrintTour {
936: my ($dbh, $Id, $answer) = @_;
937: my ($output, $q, $bottom, $field) = ('', 0, '', '');
938:
939: my (%Tour) = &GetTournament($dbh, $Id);
940: my (@Tours) = &GetTours($dbh, $Tour{'ParentId'});
941: my (%Tournament) = &GetTournament($dbh, $Tour{'ParentId'});
942:
943: return 0
944: if ($Tour{'Type'} !~ /Т/);
945:
946: my ($fname)=$Tournament{'FileName'};
947: $fname=~s/\.txt//;
948: my ($qnum) = $Tour{'QuestionsNum'};
949: my ($suffix) = &Suffix($qnum);
950:
951: $output .= h2({align=>"center"}, $Tournament{"Title"},
952: $Tournament{'PlayedAt'},
953: "<br>", $Tour{"Title"} .
954: " ($qnum вопрос$suffix)\n") . p;
955: $output .=&PrintEditor(\%Tour);
956:
957: my (@Questions) = &GetTourQuestions($dbh, $Id);
958: for ($q = 0; $q <= $#Questions; $q++) {
959: $output .= &PrintQuestion($dbh, $Questions[$q], $answer, 0);
960: }
961:
962: $output .= hr({-'align'=>'center', -'width'=>'80%'});
963:
964: if ($Tournament{'URL'}) {
965: $output .=
966: p("Дополнительная информация об этом турнире - по адресу " .
967: a({-'href'=>$Tournament{'URL'}}, $Tournament{'URL'}));
968: }
969:
970: if ($Tournament{'Copyright'}) {
971: $output .= p("Копирайт: " . $Tournament{'Copyright'});
972: }
973:
974: if ($Tournament{'Info'}) {
975: $output .= p($Tournament{'Info'});
976: }
977:
978: my $n=$Tour{'Number'};
979: if ($answer == 0) {
980: $bottom .=
981: "[" . a({href=>url . "?tour=$fname.$n&answer=1"}, "ответы") . "] " . br;
982: }
983: if ($n>1) {
984: $bottom .=
985: "[" . a({href=>url . "?tour=$fname." . ($n - 1) . "&answer=0"},
986: "предыдущий тур") . "] ";
987: $bottom .=
988: "[" . a({href=>url . "?tour=$fname." . ($n - 1) . "&answer=1"},
989: "предыдущий тур с ответами") . "] " . br;
990: }
991: if (&IsTour($dbh, $Tour{'ParentId'}, $n + 1)) {
992: $bottom .=
993: "[" . a({href=>url . "?tour=$fname." . ($n + 1) . "&answer=0"},
994: "следующий тур") . "] ";
995: $bottom .=
996: "[" . a({href=>url . "?tour=$fname." . ($n + 1) . "&answer=1"},
997: "следующий тур с ответами") . "] ";
998: }
999:
1000: $output .=
1001: p({align=>"center"}, font({size=>-1}, $bottom));
1002:
1003: return $output;
1004: }
1005:
1006: sub PrintField {
1007: my ($header, $value, $text) = @_;
1008: if ($text) {
1009: $value =~ s/<[\/\w]*?>//sg;
1010: } else {
1011: $value =~ s/^\s+/<br> /mg;
1012: $value =~ s/^\|([^\n]*)/<pre>$1<\/pre>/mg;
1013: $value =~ s/\s+-+\s+/ – /mg;
1014: # $value =~ s/(\s)"/$1“/mg;
1015: # $value =~ s/^"/“/mg;
1016: # $value =~ s/"/”/mg;
1017: }
1018:
1019:
1020: return $text ? "$header:\n$value\n\n" :
1021: strong("$header: ") . $value . p . "\n";
1022: }
1023:
1024: # Gets a DB handler (ofcourse) and a question Id. Prints
1025: # that question, according to the options.
1026: sub PrintQuestion {
1027: my ($dbh, $Id, $answer, $qnum, $title, $text) = @_;
1028: my ($output, $titles) = ('', '');
1029: my (%Question) = &GetQuestion($dbh, $Id);
1030: $qnum = $Question{'Number'}
1031: if ($qnum == 0);
1032: if (!$text) {
1033: $output .= hr({width=>"50%"});
1034: if ($title) {
1035: my (%Tour) = GetTournament($dbh, $Question{'ParentId'});
1036: my (%Tournament) = GetTournament($dbh, $Tour{'ParentId'});
1037: my $fname=$Tournament{'FileName'};
1038: $fname=~s/\.txt//;
1039: $titles .=
1040: dd(img({src=>"/icons/folder.open.gif"}) . " " .
1041: a({href=>url . "?tour=$fname"}, $Tournament{'Title'}, $Tournament{'PlayedAt'}));
1042: $titles .=
1043: dl(dd(img({src=>"/icons/folder.open.gif"}) . " " .
1044: a({href=>url . "?tour=$fname.$Tour{Number}#$qnum"}, $Tour{'Title'})));
1045: }
1046: $output .= dl(strong($titles));
1047: }
1048:
1049:
1050: $output.= "<a NAME=\"$qnum\">";
1051:
1052: $output .=
1053: &PrintField("Вопрос $qnum", $Question{'Question'}, $text);
1054:
1055: if ($answer==1) {
1056: $output .=
1057: &PrintField("Ответ", $Question{'Answer'}, $text);
1058:
1059: if ($Question{'Authors'}) {
1060: my $q=$Question{'Authors'};
1061: ###АВТОРА!!
1062: my $sth=$dbh->prepare("select Authors.Id,Name, Surname, Nicks from Authors, A2Q
1063: where Authors.Id=Author And Question=$Id");
1064: $sth->execute;
1065: my ($AuthorId,$Name, $Surname,$other,$Nicks);
1066:
1067: while ((($AuthorId,$Name, $Surname,$Nicks)=$sth->fetchrow),$AuthorId)
1068: {
1069: my ($firstletter)=$Name=~m/^./g;
1070: $Name=~s/\./\\\./g;
1071: my $sha="(?:$Name\\s+$Surname)|(?:$Surname\\s+$Name)|(?:$firstletter\\.\\s*$Surname)|(?:$Surname\\s+$firstletter\\.)|(?:$Surname)|(?:$Name)";
1072: if ($Nicks)
1073: {
1074: $Nicks=~s/^\|//;
1075: foreach (split /\|/, $Nicks)
1076: {
1077: s/\s+/ /g;
1078: s/\s+$//;
1079: s/ /\\s+/g;
1080: s/\./\\\./g;
1081: if (s/>$//) {$sha="$sha|(?:$_)"}
1082: else {$sha="(?:$_)|$sha"}
1083: }
1084: }
1085: $q=~s/($sha)/a({href=>url."?qofauthor=$AuthorId"},$1)/ei;
1086: }
1087:
1088: $output .= &PrintField("Автор(ы)", $q, $text);
1089:
1090: }
1091:
1092: if ($Question{'Sources'}) {
1093: $output .= &PrintField("Источник(и)", $Question{'Sources'}, $text);
1094: }
1095:
1096: if ($Question{'Comments'}) {
1097: $output .= &PrintField("Комментарии", $Question{'Comments'}, $text);
1098: }
1099: }
1100: elsif ($answer==2) {
1101: my $text=$Question{'Answer'};
1102: $text=~s/\n/<option>/mg;
1103: $output.="<select><option selected>Ответ:<option>$text</select>";
1104: $text=$Question{'Comments'}||'';
1105: if ($text) {
1106: $text=~s/\n/<option>/mg;
1107: $output.="<select><option selected>Комментарий:<option>$text</select>"
1108: }
1109: }
1110: elsif ($answer==3) {
1111: $output.= <<EOTT
1112: <div align=right STYLE="cursor:hand;" OnStart="toggle(document.all.HideShow$qnum);" OnClick="toggle(document.all.HideShow$qnum);">
1113: <font size=-2 color=red> Показать/убрать ответ</font></div>
1114: <span style="display:none" id=HideShow$qnum>
1115: EOTT
1116: .&PrintField("Ответ", $Question{'Answer'}, $text);
1117: if ($Question{'Authors'}) {
1118: $output .= &PrintField("Автор(ы)", $Question{'Authors'}, $text);
1119: }
1120: if ($Question{'Sources'}) {
1121: $output .= &PrintField("Источник(и)", $Question{'Sources'}, $text);
1122: }
1123:
1124: if ($Question{'Comments'}) {
1125: $output .= &PrintField("Комментарии", $Question{'Comments'}, $text);
1126: }
1127:
1128:
1129: $output.="</span>"
1130:
1131: }
1132: $output.=br.a({href=> url."?metod=proxy&qid=$Id"}, 'Близкие вопросы').p
1133: if $answer;
1134: return $output;
1135: }
1136:
1137: # Returns the total number of questions currently in the DB.
1138: sub GetQNum {
1139: my ($dbh) = @_;
1140: my ($sth) = $dbh->prepare("SELECT COUNT(*) FROM Questions");
1141: $sth->execute;
1142: my $tmp=($sth->fetchrow)[0];
1143: $sth->finish;
1144: return $tmp;
1145: }
1146: sub GetMaxQId {
1147: my ($dbh) = @_;
1148: my ($sth) = $dbh->prepare("SELECT MAX(QuestionId) FROM Questions");
1149: $sth->execute;
1150: my $tmp=($sth->fetchrow)[0];
1151: $sth->finish;
1152: return $tmp;
1153:
1154: }
1155:
1156: # Returns Id's of 12 random questions
1157: sub Get12Random {
1158: my ($dbh, $type, $num) = @_;
1159: my ($i, @questions, $q, $t, $sth);
1160: my ($qnum) = &GetMaxQId($dbh);
1161: my (%chosen);
1162: srand;
1163:
1164: my $where=0;
1165: my $r=int (rand(10000));
1166:
1167: foreach (split '', $type)
1168: {
1169: $where.= " OR (Type ='$_') OR (Type ='$_Д') ";
1170: }
1171: $where.= "OR (Type='ЧБ')" if ($type=~/Ч|Б/);
1172:
1173: $q="select QuestionId, QuestionId/$r-floor(QuestionId/$r) as val
1174: from Questions where $where order by val limit $num";
1175:
1176: # Когда на куличках появится mysql >=3.23 надо заменить на order by rand();
1177:
1178: $sth=$dbh->prepare($q);
1179: $sth->execute;
1180: while (($i)=$sth->fetchrow)
1181: {
1182: push @questions,$i;
1183: }
1184: $sth->finish;
1185: for ($i=@questions; --$i;){
1186: my $j=rand ($i+1);
1187: @questions[$i,$j]=@questions[$j,$i] unless $i==$j;
1188: }
1189: return @questions;
1190: }
1191:
1192: sub Include_virtual {
1193: my ($fn, $output) = (@_, '');
1194:
1195: open F , $fn
1196: or return; #die "Can't open the file $fn: $!\n";
1197:
1198: while (<F>) {
1199: if (/<!--#include/o) {
1200: s/<!--#include virtual="\/(.*)" -->/&Include_virtual($1)/e;
1201: }
1202: if (/<!--#exec/o) {
1203: s/<!--#exec.*cmd\s*=\s*"([^"]*)".*-->/`$1`/e;
1204: }
1205: $output .= $_;
1206: }
1207: return $output;
1208: }
1209:
1210: sub PrintArchive {
1211: my($dbh, $Id) = @_;
1212: my ($output, @list, $i);
1213:
1214: my (%Tournament) = &GetTournament($dbh, $Id);
1215: my (@Tours) = &GetTours($dbh, $Id);
1216:
1217: if ($Tournament{'Type'} =~ /Г/ || $Id == 0) {
1218: for ($i = 0; $i <= $#Tours; $i++) {
1219: push(@list ,&PrintArchive($dbh, $Tours[$i]));
1220: }
1221: return @list;
1222: }
1223: # return "$SRCPATH/$Tournament{'FileName'} ";
1224: return "$TMPDIR/$Tournament{'FileName'} ";
1225: }
1226:
1227: sub PrintAll {
1228: my ($dbh, $Id,$fname) = @_;
1229: my ($output, $list, $i);
1230:
1231: my (%Tournament) = &GetTournament($dbh, $Id);
1232: my (@Tours) = &GetTours($dbh, $Id);
1233: my ($New) = ($Id and $Tournament{'Type'} eq 'Ч' and
1234: &NewEnough($Tournament{"CreatedAt"})) ?
1235: img({src=>"/znatoki/dimrub/db/new-sml.gif", alt=>"NEW!"}) : "";
1236:
1237: if ($Id == 0) {
1238: $output = h3("Все турниры");
1239: } else {
1240: my $textid;
1241: if ($textid=$Tournament{'FileName'})
1242: {
1243: $textid=~s/\.txt//;
1244: }
1245: elsif ($textid=$Tournament{'Number'})
1246: {
1247: $fname=~s/\.txt//;
1248: $textid="$fname.$textid";
1249: }
1250: else {$textid=$Tournament{'Id'}};
1251:
1252:
1253: $output .= dd(img({src=>"/icons/folder.gif", alt=>"[*]"}) .
1254: " " . a({href=>url . "?tour=$textid&answer=0"},
1255: $Tournament{'Title'}) ." " . $Tournament{'PlayedAt'} . " $New");
1256: }
1257: if ($Id == 0 or $Tournament{'Type'} =~ /Г/ or $Tournament{'Type'} eq '') {
1258: for ($i = 0; $i <= $#Tours; $i++) {
1259: $list .= &PrintAll($dbh, $Tours[$i],$Tournament{'FileName'});
1260: }
1261: $output .= dl($list);
1262: }
1263: return $output;
1264: }
1265:
1266: sub PrintDates {
1267: my ($dbh) = @_;
1268: my ($from) = param('from_year') . "-" . param('from_month') .
1269: "-" . param('from_day');
1270: my ($to) = param('to_year') . "-" . param('to_month') . "-" . param('to_day');
1271: $from = $dbh->quote($from);
1272: $to = $dbh->quote($to);
1273: my ($sth) = $dbh->prepare("
1274: SELECT DISTINCT Id
1275: FROM Tournaments
1276: WHERE PlayedAt >= $from AND PlayedAt <= $to
1277: AND Type = 'Ч'
1278: ");
1279: $sth->execute;
1280: my (%Tournament, @array, $output, $list);
1281:
1282: $output = h3("Список турниров, проходивших между $from и $to.");
1283: while (@array = $sth->fetchrow) {
1284: next
1285: if (!$array[0]);
1286: %Tournament = &GetTournament($dbh, $array[0]);
1287: $list .= dd(img({src=>"/icons/folder.gif", alt=>"[*]"}) .
1288: " " . a({href=>url . "?tour=$Tournament{'Id'}&answer=0"},
1289: $Tournament{'Title'}, $Tournament{'PlayedAt'}));
1290: }
1291: $sth->finish;
1292: $output .= dl($list);
1293: return $output;
1294: }
1295:
1296: sub PrintQOfAuthor
1297: {
1298:
1299: my ($dbh, $id) = @_;
1300: $id=$dbh->quote($id);
1301: my $sth = $dbh->prepare("SELECT Name, Surname FROM Authors WHERE Id=$id");
1302: $sth->execute;
1303: my ($name,$surname)=$sth->fetchrow;
1304:
1305: $sth = $dbh->prepare("SELECT Question FROM A2Q WHERE Author=$id");
1306: $sth->execute;
1307: my $q;
1308: my @Questions;
1309: while (($q)=$sth->fetchrow,$q)
1310: {push @Questions,$q unless $forbidden{$q}}
1311: $sth->finish;
1312:
1313: my ($output, $i, $suffix, $hits) = ('', 0, '', $#Questions + 1);
1314:
1315: if ($hits =~ /1.$/ || $hits =~ /[5-90]$/) {
1316: $suffix = 'й';
1317: } elsif ($hits =~ /1$/) {
1318: $suffix = 'е';
1319: } else {
1320: $suffix = 'я';
1321: }
1322: print h2("Поиск в базе вопросов");
1323: print printform;
1324: print p({align=>"center"}, "Автор ".strong("$name $surname. ")
1325: . " : $hits попадани$suffix.");
1326:
1327:
1328: # for ($i = 0; $i <= $#Questions; $i++) {
1329: # $output = &PrintQuestion($dbh, $Questions[$i], 1, $i + 1, 1);
1330: # print $output;
1331: # }
1332: PrintList($dbh,\@Questions,'gdfgdfgdfgdfg');
1333: }
1334:
1335:
1336: sub PrintAuthors
1337: {
1338: my ($dbh,$sort)=@_;
1339: my($output,$out1,@array,$sth);
1340: if ($sort eq 'surname')
1341: {
1342: $sth =
1343: $dbh->prepare("SELECT Id, Name, Surname, QNumber FROM Authors order by Surname, Name");
1344: }
1345: elsif($sort eq 'name')
1346: {
1347: $sth =
1348: $dbh->prepare("SELECT Id, Name, Surname, QNumber FROM Authors order by Name, Surname");
1349: }
1350: else
1351: {
1352: $sth =
1353: $dbh->prepare("SELECT Id, Name, Surname, QNumber FROM Authors Order by QNumber DESC, Surname");
1354: }
1355:
1356: $output.=h2("Авторы вопросов")."\n";
1357: $output.="<TABLE>";
1358:
1359:
1360: $sth->execute;
1361: $output.=Tr(th[a({href=>url."?authors=name"},"Имя")
1362: .", ".
1363: a({href=>url."?authors=surname"},"фамилия")
1364: , a({href=>url."?authors=kvo"},"Количество вопросов")]);
1365:
1366: $out1='';
1367:
1368: my $ar=$sth->fetchall_arrayref;
1369:
1370: $sth->finish;
1371:
1372:
1373: foreach my $arr(@$ar)
1374: {
1375:
1376: my ($id,$name,$surname,$kvo)=@$arr;
1377: if (!$name || !$surname) {#print "Opanki at $id\n"
1378: } else
1379: {
1380: my $add=Tr(td([a({href=>url."?qofauthor=$id"},"$name $surname"), $kvo]))."\n";
1381: print STDERR $add;
1382: $output.=$add;
1383: }
1384: }
1385: $output.="</TABLE>";
1386: $sth->finish;
1387: return $output;
1388: }
1389:
1390:
1391: sub WriteFile {
1392: my ($dbh,$fname) = @_;
1393: $fname=~s/\.txt$//;
1394: $fname=~s/.*\/(\w+)/$1/;
1395: my $query= "SELECT Id, Title, Copyright, Info, URL,
1396: Editors, EnteredBy, PlayedAt, CreatedAt
1397: from Tournaments where FileName=".$dbh->quote("$fname.txt");
1398: my $sth=$dbh->prepare($query);
1399: my (%Question,%editor,%qnumber,%copyright,%author,%vid,%tourtitle);
1400: $sth->execute;
1401: my ($Id, $Title, $Copyright, $Info, $URL,
1402: $Editors, $EnteredBy, $PlayedAt, $CreatedAt)=
1403: $sth->fetchrow;
1404: return -1 unless $Id;
1405: open (OUT, ">$TMPDIR/$fname.txt");
1406: print OUT "Чемпионат:\n$Title\n\n";
1407: my $date=$PlayedAt;
1408: my ($year,$month,$day)=split /-/, $date;
1409: # $month=0,$date=0 if $year && $month==1 && $day==1;
1410: my $pdate=sprintf("%02d-%3s-%4d",$day,$months[$month],$year);
1411:
1412: print OUT "Дата:\n$pdate\n\n" if $date;
1413:
1414: print OUT "URL:\n$URL\n\n" if $URL;
1415:
1416: print OUT "Инфо:\n$Info\n\n" if $Info;
1417:
1418: print OUT "Копирайт:\n$Copyright\n\n" if $Copyright;
1419:
1420: print OUT "Редактор:\n$Editors\n\n" if $Editors;
1421:
1422:
1423: $query= "SELECT Id, Title, Copyright, Editors from Tournaments where ParentId=$Id order by Id";
1424: $sth=$dbh->prepare($query);
1425: $sth->execute;
1426: my ($tourid,$tourtitle,$cright,$editor,@tours,$vid,$author,$tourauthor);
1427:
1428:
1429: while (($tourid,$tourtitle,$cright,$editor)=$sth->fetchrow,$tourid)
1430: {
1431: # $text{$tourid}="Тур:\n$tourtitle\n\n";
1432: $query= "SELECT * from Questions where ParentId=$tourid order by QuestionId";
1433: my $sth1=$dbh->prepare($query);
1434: $sth1->execute;
1435: push(@tours,$tourid);
1436: $tourtitle{$tourid}=$tourtitle;
1437: $copyright{$tourid}=$cright;
1438: $editor{$tourid}=$editor;
1439: $vid='';
1440: my $author='';
1441: my $eqauthor=1;
1442: my $qnumber=0;
1443: my @arr;
1444: while ( @arr=$sth1->fetchrow, $arr[0])
1445: {
1446: my($i, $name) = 0;
1447: $qnumber++;
1448: foreach $name (@{$sth1->{NAME}}) {
1449: $arr[$i]=~s/^(.*?)\s*$/$1/;
1450: $Question{$tourid}[$qnumber]{$name} = $arr[$i++];
1451: }
1452: if ($vid)
1453: {
1454: if ($vid ne $Question{$tourid}[$qnumber]{'Type'}) {print STDERR "Warning: Different types for Tournament $tourid\n"}
1455: } else
1456: {
1457: $vid=$Question{$tourid}[$qnumber]{'Type'};
1458: }
1459:
1460: if ($author)
1461: {
1462: if ($author ne $Question{$tourid}[$qnumber]{'Authors'})
1463: {
1464: $eqauthor=0;
1465: }
1466: } else
1467: {
1468: $author=$Question{$tourid}[$qnumber]{'Authors'};
1469: $eqauthor=0 unless $author;
1470: }
1471: }
1472: $vid{$tourid}=$vid;
1473: $qnumber{$tourid}=$qnumber;
1474: $author{$tourid}=$eqauthor ? $author : '';
1475: }
1476:
1477:
1478: $vid='';
1479: my $eqvid=1;
1480: my $eqauthor=1;
1481: foreach (@tours)
1482: {
1483: $vid||=$vid{$_};
1484: if ($vid{$_} ne $vid)
1485: {
1486: $eqvid=0;
1487: }
1488: $author||=$author{$_};
1489: if (!$author{$_} || ($author{$_} ne $author))
1490: {
1491: $eqauthor=0;
1492: }
1493: }
1494:
1495: print OUT "Вид:\n$vid\n\n" if $eqvid;
1496: print OUT "Автор:\n$author\n\n" if $eqauthor;
1497:
1498: foreach my $tour(@tours)
1499: {
1500: print OUT "Тур:\n$tourtitle{$tour}\n\n";
1501: print OUT "Вид:\n$vid{$tour}\n\n" if !$eqvid;
1502: print OUT "Копирайт:\n$copyright{$tour}\n\n" if $copyright{$tour} && ($copyright{$tour} ne $Copyright);
1503: print OUT "Редактор:\n$editor{$tour}\n\n" if $editor{$tour} && ($editor{$tour} ne $Editors);
1504: $tourauthor=0;
1505: if (!$eqauthor && $author{$tour})
1506: {
1507: print OUT "Автор:\n$author{$tour}\n\n";
1508: $tourauthor=1;
1509: }
1510: foreach my $q(1..$qnumber{$tour})
1511: {
1512: print OUT "Вопрос $q:\n".$Question{$tour}[$q]{'Question'}."\n\n";
1513: print OUT "Ответ:\n".$Question{$tour}[$q]{'Answer'}."\n\n";
1514: print OUT "Автор:\n".$Question{$tour}[$q]{'Authors'}."\n\n"
1515: if !$tourauthor && !$eqauthor && $Question{$tour}[$q]{'Authors'};
1516: print OUT "Комментарий:\n".$Question{$tour}[$q]{'Comments'}."\n\n"
1517: if $Question{$tour}[$q]{'Comments'};
1518: print OUT "Источник:\n".$Question{$tour}[$q]{'Sources'}."\n\n"
1519: if $Question{$tour}[$q]{'Sources'};
1520: print OUT "Рейтинг:\n".$Question{$tour}[$q]{'Rating'}."\n\n"
1521: if $Question{$tour}[$q]{'Rating'};
1522:
1523: }
1524: }
1525:
1526: close OUT;
1527:
1528:
1529:
1530: }
1531:
1532:
1533: MAIN:
1534: {
1535: setlocale(LC_CTYPE,'russian');
1536: my($i, $tour);
1537: my($text) = (param('text')) ? 1 : 0;
1538:
1539: my($dbh) = DBI->connect("DBI:mysql:chgk", "piataev", "")
1540: or do {
1541: print h1("Временные проблемы") . "База данных временно не
1542: работает. Заходите попозже.";
1543: print &Include_virtual("../dimrub/db/reklama.html");
1544: print end_html;
1545: die "Can't connect to DB chgk\n";
1546: };
1547: if (!param('comp') and !param('sqldump') and !$text) {
1548: print header;
1549: print start_html(-"title"=>'Database of the questions',
1550: -author=>'dimrub@icomverse.com',
1551: -bgcolor=>'#fff0e0',
1552: -vlink=>'#800020');
1553: print &Include_virtual("../dimrub/db/reklama.html");
1554: }
1555:
1556:
1557: if ($^O =~ /win/i) {
1558: $thislocale = "Russian_Russia.20866";
1559: } else {
1560: $thislocale = "ru_RU.KOI8-R";
1561: }
1562: POSIX::setlocale( &POSIX::LC_ALL, $thislocale );
1563:
1564: if ((uc 'а') ne 'А') {print "Koi8-r locale not installed!\n"};
1565:
1566:
1567: if ($text) {
1568: print header('text/plain');
1569: }
1570:
1571: if (param('hideequal')) {
1572: my ($sth)= $dbh -> prepare("select first, second FROM equalto");
1573: $sth -> execute;
1574: while ( my ($first, $second)=$sth -> fetchrow)
1575: {
1576: $forbidden{$first}=1;
1577: }
1578: $sth->finish;
1579: }
1580:
1581:
1582: if (param('rand')) {
1583: my ($type, $qnum) = ('', 12);
1584: $type.=$TypeName{$_} foreach param('type');
1585: # $type .= 'Б' if (param('brain'));
1586: # $type .= 'Ч' if (param('chgk'));
1587: $qnum = param('qnum') if (param('qnum') =~ /^\d+$/);
1588: $qnum = 0 if (!$type);
1589: my $Email;
1590: if (($Email=param('email')) && -x $SENDMAIL &&
1591: open(F, "| $SENDMAIL $Email")) {
1592: my ($mime_type) = $text ? "plain" : "html";
1593: print F <<EOT;
1594: To: $Email
1595: From: olegstepanov\@mail.ru
1596: Subject: Sluchajnij Paket Voprosov "Chto? Gde? Kogda?"
1597: MIME-Version: 1.0
1598: Content-type: text/$mime_type; charset="koi8-r"
1599:
1600: EOT
1601: print F &PrintRandom($dbh, $type, $qnum, $text);
1602: close F;
1603: print "Пакет случайно выбранных вопросов послан по адресу $Email. Нажмите
1604: на <B>Reload</B> для получения еще одного пакета";
1605: } else {
1606: print &PrintRandom($dbh, $type, $qnum, $text);
1607: }
1608: }
1609: elsif (param('authors')){
1610: print &PrintAuthors($dbh,param('authors'));
1611: }
1612: elsif (param('qofauthor')){
1613: &PrintQOfAuthor($dbh,param('qofauthor'));
1614: }
1615: elsif (param('sstr')||param('was')) {
1616: &PrintSearch($dbh, param('sstr'), param('metod'),param('was'));
1617: $dbh->do("delete from lastqueries where
1618: (TO_DAYS(NOW()) - TO_DAYS(t) >= 2) OR
1619: (time_to_sec(now())-time_to_sec(t) >3600)")
1620: }
1621: elsif (param('qid')) {
1622: my $qid=param('qid');
1623: my $query="SELECT Question, Answer from Questions where QuestionId=$qid";
1624: print $query if $printqueries;
1625: my $sth=$dbh->prepare($query);
1626: $sth->execute;
1627: my $sstr= join ' ',$sth->fetchrow;
1628: $sth->finish;
1629: $searchin{'Question'}=1;
1630: $searchin{'Answer'}=1;
1631: $sstr=~tr/ёЁ/еЕ/;
1632: $sstr=~s/[^йцукенгшщзхъфывапролджэячсмитьбюЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮa-zA-Z0-9]/ /gi;
1633: # print &PrintQuestion($dbh,$qid, 1, '!');
1634: &PrintSearch($dbh, $sstr, 'proxy');
1635: }
1636:
1637: elsif (param('all')) {
1638: print &PrintAll($dbh, 0);
1639: } elsif (param('from_year') && param('to_year')) {
1640: print &PrintDates($dbh);
1641: } elsif (param('comp')) {
1642: print header(
1643: -'Content-Type' => 'application/x-zip-compressed; name="db.zip"',
1644: -'Content-Disposition' => 'attachment; filename="db.zip"'
1645: );
1646: $tour = (param('tour')) ? param('tour') : 0;
1647: my (@files) = &PrintArchive($dbh, $tour);
1648: WriteFile($dbh,$_) foreach @files;
1649: open F, "$ZIP -j - $SRCPATH/COPYRIGHT @files |";
1650: print (<F>);
1651: close F;
1652: $dbh->disconnect;
1653: exit;
1654: } elsif (param('sqldump')) {
1655: print header(
1656: -'Content-Type' => 'application/x-zip-compressed; name="dump.zip"',
1657: -'Content-Disposition' => 'attachment; filename="dump.zip"'
1658: );
1659: open F, "$ZIP -j - $DUMPFILE |";
1660: print (<F>);
1661: close F;
1662: $dbh->disconnect;
1663: exit;
1664:
1665: } else {
1666: $tour = (param('tour')) ? param('tour') : 0;
1667: my $sth;
1668: if ($tour !~ /^[0-9]*$/) {
1669: if ($tour=~/\./)
1670: {
1671: my ($fname,$n)= split /\./ , $tour;
1672:
1673: $sth = $dbh->prepare(
1674: "SELECT t2.Id FROM Tournaments as t1,
1675: Tournaments as t2
1676: WHERE t1.FileName = '$fname.txt'
1677: AND t1.Id=t2.ParentId AND t2.Number=$n");
1678: }
1679: else
1680: {
1681: $sth = $dbh->prepare("SELECT Id FROM Tournaments
1682: WHERE FileName = '$tour.txt'");
1683: }
1684: $sth->execute;
1685: $tour = ($sth->fetchrow)[0];
1686: $sth->finish;
1687: }
1688: my $QuestionNumber=0;
1689: my $qnum;
1690: if ($qnum=param('qnumber')){
1691: my ($sth) = $dbh->prepare("SELECT QuestionId FROM Questions
1692: WHERE ParentId=$tour AND Number=$qnum");
1693: $sth->execute;
1694: $QuestionNumber=($sth->fetchrow)[0]||0;
1695: }
1696: if ($QuestionNumber) {
1697: print &PrintQuestion($dbh, $QuestionNumber, param('answer')||0, $qnum, 1);
1698: # $dbh, $Id, $answer, $qnum, $title, $text
1699: } else {
1700: print &PrintTournament($dbh, $tour, param('answer'));
1701: }
1702: }
1703: if (!$text) {
1704: print &Include_virtual("../dimrub/db/footer.html");
1705: print <<EEE
1706: <SCRIPT LANGUAGE="JavaScript">
1707: function toggle(e) {
1708: if (e.style.display == "none") {
1709: e.style.display="";
1710: } else {
1711: e.style.display = "none";
1712: }
1713: }
1714: </SCRIPT>
1715: EEE
1716: ;
1717: print end_html;
1718: }
1719: $dbh->disconnect;
1720: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>