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: my $where=0;
1164: my $r=int (rand(10000));
1165:
1166: foreach (split '', $type)
1167: {
1168: $where.= " OR (Type ='$_') OR (Type ='$_Д') ";
1169: }
1170: $where.= "OR (Type='ЧБ')" if ($type=~/Ч|Б/);
1171:
1172: $q="select QuestionId, QuestionId/$r-floor(QuestionId/$r) as val
1173: from Questions where $where order by val limit $num";
1174: # Когда на куличках появится mysql >=3.23 надо заменить на order by rand();
1175:
1176: $sth=$dbh->prepare($q);
1177: $sth->execute;
1178: while (($i)=$sth->fetchrow)
1179: {
1180: push @questions,$i;
1181: }
1182: $sth->finish;
1183: for ($i=@questions; --$i;){
1184: my $j=rand ($i+1);
1185: @questions[$i,$j]=@questions[$j,$i] unless $i==$j;
1186: }
1187: return @questions;
1188: }
1189:
1190: sub Include_virtual {
1191: my ($fn, $output) = (@_, '');
1192:
1193: open F , $fn
1194: or return; #die "Can't open the file $fn: $!\n";
1195:
1196: while (<F>) {
1197: if (/<!--#include/o) {
1198: s/<!--#include virtual="\/(.*)" -->/&Include_virtual($1)/e;
1199: }
1200: if (/<!--#exec/o) {
1201: s/<!--#exec.*cmd\s*=\s*"([^"]*)".*-->/`$1`/e;
1202: }
1203: $output .= $_;
1204: }
1205: return $output;
1206: }
1207:
1208: sub PrintArchive {
1209: my($dbh, $Id) = @_;
1210: my ($output, @list, $i);
1211:
1212: my (%Tournament) = &GetTournament($dbh, $Id);
1213: my (@Tours) = &GetTours($dbh, $Id);
1214:
1215: if ($Tournament{'Type'} =~ /Г/ || $Id == 0) {
1216: for ($i = 0; $i <= $#Tours; $i++) {
1217: push(@list ,&PrintArchive($dbh, $Tours[$i]));
1218: }
1219: return @list;
1220: }
1221: # return "$SRCPATH/$Tournament{'FileName'} ";
1222: return "$TMPDIR/$Tournament{'FileName'} ";
1223: }
1224:
1225: sub PrintAll {
1226: my ($dbh, $Id,$fname) = @_;
1227: my ($output, $list, $i);
1228:
1229: my (%Tournament) = &GetTournament($dbh, $Id);
1230: my (@Tours) = &GetTours($dbh, $Id);
1231: my ($New) = ($Id and $Tournament{'Type'} eq 'Ч' and
1232: &NewEnough($Tournament{"CreatedAt"})) ?
1233: img({src=>"/znatoki/dimrub/db/new-sml.gif", alt=>"NEW!"}) : "";
1234:
1235: if ($Id == 0) {
1236: $output = h3("Все турниры");
1237: } else {
1238: my $textid;
1239: if ($textid=$Tournament{'FileName'})
1240: {
1241: $textid=~s/\.txt//;
1242: }
1243: elsif ($textid=$Tournament{'Number'})
1244: {
1245: $fname=~s/\.txt//;
1246: $textid="$fname.$textid";
1247: }
1248: else {$textid=$Tournament{'Id'}};
1249:
1250:
1251: $output .= dd(img({src=>"/icons/folder.gif", alt=>"[*]"}) .
1252: " " . a({href=>url . "?tour=$textid&answer=0"},
1253: $Tournament{'Title'}) ." " . $Tournament{'PlayedAt'} . " $New");
1254: }
1255: if ($Id == 0 or $Tournament{'Type'} =~ /Г/ or $Tournament{'Type'} eq '') {
1256: for ($i = 0; $i <= $#Tours; $i++) {
1257: $list .= &PrintAll($dbh, $Tours[$i],$Tournament{'FileName'});
1258: }
1259: $output .= dl($list);
1260: }
1261: return $output;
1262: }
1263:
1264: sub PrintDates {
1265: my ($dbh) = @_;
1266: my ($from) = param('from_year') . "-" . param('from_month') .
1267: "-" . param('from_day');
1268: my ($to) = param('to_year') . "-" . param('to_month') . "-" . param('to_day');
1269: $from = $dbh->quote($from);
1270: $to = $dbh->quote($to);
1271: my ($sth) = $dbh->prepare("
1272: SELECT DISTINCT Id
1273: FROM Tournaments
1274: WHERE PlayedAt >= $from AND PlayedAt <= $to
1275: AND Type = 'Ч'
1276: ");
1277: $sth->execute;
1278: my (%Tournament, @array, $output, $list);
1279:
1280: $output = h3("Список турниров, проходивших между $from и $to.");
1281: while (@array = $sth->fetchrow) {
1282: next
1283: if (!$array[0]);
1284: %Tournament = &GetTournament($dbh, $array[0]);
1285: $list .= dd(img({src=>"/icons/folder.gif", alt=>"[*]"}) .
1286: " " . a({href=>url . "?tour=$Tournament{'Id'}&answer=0"},
1287: $Tournament{'Title'}, $Tournament{'PlayedAt'}));
1288: }
1289: $sth->finish;
1290: $output .= dl($list);
1291: return $output;
1292: }
1293:
1294: sub PrintQOfAuthor
1295: {
1296:
1297: my ($dbh, $id) = @_;
1298: $id=$dbh->quote($id);
1299: my $sth = $dbh->prepare("SELECT Name, Surname FROM Authors WHERE Id=$id");
1300: $sth->execute;
1301: my ($name,$surname)=$sth->fetchrow;
1302:
1303: $sth = $dbh->prepare("SELECT Question FROM A2Q WHERE Author=$id");
1304: $sth->execute;
1305: my $q;
1306: my @Questions;
1307: while (($q)=$sth->fetchrow,$q)
1308: {push @Questions,$q unless $forbidden{$q}}
1309: $sth->finish;
1310:
1311: my ($output, $i, $suffix, $hits) = ('', 0, '', $#Questions + 1);
1312:
1313: if ($hits =~ /1.$/ || $hits =~ /[5-90]$/) {
1314: $suffix = 'й';
1315: } elsif ($hits =~ /1$/) {
1316: $suffix = 'е';
1317: } else {
1318: $suffix = 'я';
1319: }
1320: print h2("Поиск в базе вопросов");
1321: print printform;
1322: print p({align=>"center"}, "Автор ".strong("$name $surname. ")
1323: . " : $hits попадани$suffix.");
1324:
1325:
1326: # for ($i = 0; $i <= $#Questions; $i++) {
1327: # $output = &PrintQuestion($dbh, $Questions[$i], 1, $i + 1, 1);
1328: # print $output;
1329: # }
1330: PrintList($dbh,\@Questions,'gdfgdfgdfgdfg');
1331: }
1332:
1333:
1334: sub PrintAuthors
1335: {
1336: my ($dbh,$sort)=@_;
1337: my($output,$out1,@array,$sth);
1338: if ($sort eq 'surname')
1339: {
1340: $sth =
1341: $dbh->prepare("SELECT Id, Name, Surname, QNumber FROM Authors order by Surname, Name");
1342: }
1343: elsif($sort eq 'name')
1344: {
1345: $sth =
1346: $dbh->prepare("SELECT Id, Name, Surname, QNumber FROM Authors order by Name, Surname");
1347: }
1348: else
1349: {
1350: $sth =
1351: $dbh->prepare("SELECT Id, Name, Surname, QNumber FROM Authors Order by QNumber DESC, Surname");
1352: }
1353:
1354: $output.=h2("Авторы вопросов")."\n";
1355: $output.="<TABLE>";
1356:
1357:
1358: $sth->execute;
1359: $output.=Tr(th[a({href=>url."?authors=name"},"Имя")
1360: .", ".
1361: a({href=>url."?authors=surname"},"фамилия")
1362: , a({href=>url."?authors=kvo"},"Количество вопросов")]);
1363:
1364: $out1='';
1365:
1366: my $ar=$sth->fetchall_arrayref;
1367:
1368: $sth->finish;
1369:
1370:
1371: foreach my $arr(@$ar)
1372: {
1373:
1374: my ($id,$name,$surname,$kvo)=@$arr;
1375: if (!$name || !$surname) {#print "Opanki at $id\n"
1376: } else
1377: {
1378: my $add=Tr(td([a({href=>url."?qofauthor=$id"},"$name $surname"), $kvo]))."\n";
1379: print STDERR $add;
1380: $output.=$add;
1381: }
1382: }
1383: $output.="</TABLE>";
1384: $sth->finish;
1385: return $output;
1386: }
1387:
1388:
1389: sub WriteFile {
1390: my ($dbh,$fname) = @_;
1391: $fname=~s/\.txt$//;
1392: $fname=~s/.*\/(\w+)/$1/;
1393: my $query= "SELECT Id, Title, Copyright, Info, URL,
1394: Editors, EnteredBy, PlayedAt, CreatedAt
1395: from Tournaments where FileName=".$dbh->quote("$fname.txt");
1396: my $sth=$dbh->prepare($query);
1397: my (%Question,%editor,%qnumber,%copyright,%author,%vid,%tourtitle);
1398: $sth->execute;
1399: my ($Id, $Title, $Copyright, $Info, $URL,
1400: $Editors, $EnteredBy, $PlayedAt, $CreatedAt)=
1401: $sth->fetchrow;
1402: return -1 unless $Id;
1403: open (OUT, ">$TMPDIR/$fname.txt");
1404: print OUT "Чемпионат:\n$Title\n\n";
1405: my $date=$PlayedAt;
1406: my ($year,$month,$day)=split /-/, $date;
1407: # $month=0,$date=0 if $year && $month==1 && $day==1;
1408: my $pdate=sprintf("%02d-%3s-%4d",$day,$months[$month],$year);
1409:
1410: print OUT "Дата:\n$pdate\n\n" if $date;
1411:
1412: print OUT "URL:\n$URL\n\n" if $URL;
1413:
1414: print OUT "Инфо:\n$Info\n\n" if $Info;
1415:
1416: print OUT "Копирайт:\n$Copyright\n\n" if $Copyright;
1417:
1418: print OUT "Редактор:\n$Editors\n\n" if $Editors;
1419:
1420:
1421: $query= "SELECT Id, Title, Copyright, Editors from Tournaments where ParentId=$Id order by Id";
1422: $sth=$dbh->prepare($query);
1423: $sth->execute;
1424: my ($tourid,$tourtitle,$cright,$editor,@tours,$vid,$author,$tourauthor);
1425:
1426:
1427: while (($tourid,$tourtitle,$cright,$editor)=$sth->fetchrow,$tourid)
1428: {
1429: # $text{$tourid}="Тур:\n$tourtitle\n\n";
1430: $query= "SELECT * from Questions where ParentId=$tourid order by QuestionId";
1431: my $sth1=$dbh->prepare($query);
1432: $sth1->execute;
1433: push(@tours,$tourid);
1434: $tourtitle{$tourid}=$tourtitle;
1435: $copyright{$tourid}=$cright;
1436: $editor{$tourid}=$editor;
1437: $vid='';
1438: my $author='';
1439: my $eqauthor=1;
1440: my $qnumber=0;
1441: my @arr;
1442: while ( @arr=$sth1->fetchrow, $arr[0])
1443: {
1444: my($i, $name) = 0;
1445: $qnumber++;
1446: foreach $name (@{$sth1->{NAME}}) {
1447: $arr[$i]=~s/^(.*?)\s*$/$1/;
1448: $Question{$tourid}[$qnumber]{$name} = $arr[$i++];
1449: }
1450: if ($vid)
1451: {
1452: if ($vid ne $Question{$tourid}[$qnumber]{'Type'}) {print STDERR "Warning: Different types for Tournament $tourid\n"}
1453: } else
1454: {
1455: $vid=$Question{$tourid}[$qnumber]{'Type'};
1456: }
1457:
1458: if ($author)
1459: {
1460: if ($author ne $Question{$tourid}[$qnumber]{'Authors'})
1461: {
1462: $eqauthor=0;
1463: }
1464: } else
1465: {
1466: $author=$Question{$tourid}[$qnumber]{'Authors'};
1467: $eqauthor=0 unless $author;
1468: }
1469: }
1470: $vid{$tourid}=$vid;
1471: $qnumber{$tourid}=$qnumber;
1472: $author{$tourid}=$eqauthor ? $author : '';
1473: }
1474:
1475:
1476: $vid='';
1477: my $eqvid=1;
1478: my $eqauthor=1;
1479: foreach (@tours)
1480: {
1481: $vid||=$vid{$_};
1482: if ($vid{$_} ne $vid)
1483: {
1484: $eqvid=0;
1485: }
1486: $author||=$author{$_};
1487: if (!$author{$_} || ($author{$_} ne $author))
1488: {
1489: $eqauthor=0;
1490: }
1491: }
1492:
1493: print OUT "Вид:\n$vid\n\n" if $eqvid;
1494: print OUT "Автор:\n$author\n\n" if $eqauthor;
1495:
1496: foreach my $tour(@tours)
1497: {
1498: print OUT "Тур:\n$tourtitle{$tour}\n\n";
1499: print OUT "Вид:\n$vid{$tour}\n\n" if !$eqvid;
1500: print OUT "Копирайт:\n$copyright{$tour}\n\n" if $copyright{$tour} && ($copyright{$tour} ne $Copyright);
1501: print OUT "Редактор:\n$editor{$tour}\n\n" if $editor{$tour} && ($editor{$tour} ne $Editors);
1502: $tourauthor=0;
1503: if (!$eqauthor && $author{$tour})
1504: {
1505: print OUT "Автор:\n$author{$tour}\n\n";
1506: $tourauthor=1;
1507: }
1508: foreach my $q(1..$qnumber{$tour})
1509: {
1510: print OUT "Вопрос $q:\n".$Question{$tour}[$q]{'Question'}."\n\n";
1511: print OUT "Ответ:\n".$Question{$tour}[$q]{'Answer'}."\n\n";
1512: print OUT "Автор:\n".$Question{$tour}[$q]{'Authors'}."\n\n"
1513: if !$tourauthor && !$eqauthor && $Question{$tour}[$q]{'Authors'};
1514: print OUT "Комментарий:\n".$Question{$tour}[$q]{'Comments'}."\n\n"
1515: if $Question{$tour}[$q]{'Comments'};
1516: print OUT "Источник:\n".$Question{$tour}[$q]{'Sources'}."\n\n"
1517: if $Question{$tour}[$q]{'Sources'};
1518: print OUT "Рейтинг:\n".$Question{$tour}[$q]{'Rating'}."\n\n"
1519: if $Question{$tour}[$q]{'Rating'};
1520:
1521: }
1522: }
1523:
1524: close OUT;
1525:
1526:
1527:
1528: }
1529:
1530:
1531: MAIN:
1532: {
1533: setlocale(LC_CTYPE,'russian');
1534: my($i, $tour);
1535: my($text) = (param('text')) ? 1 : 0;
1536:
1537: my($dbh) = DBI->connect("DBI:mysql:chgk", "piataev", "")
1538: or do {
1539: print h1("Временные проблемы") . "База данных временно не
1540: работает. Заходите попозже.";
1541: print &Include_virtual("../dimrub/db/reklama.html");
1542: print end_html;
1543: die "Can't connect to DB chgk\n";
1544: };
1545: if (!param('comp') and !param('sqldump') and !$text) {
1546: print header;
1547: print start_html(-"title"=>'Database of the questions',
1548: -author=>'dimrub@icomverse.com',
1549: -bgcolor=>'#fff0e0',
1550: -vlink=>'#800020');
1551: print &Include_virtual("../dimrub/db/reklama.html");
1552: }
1553:
1554:
1555: if ($^O =~ /win/i) {
1556: $thislocale = "Russian_Russia.20866";
1557: } else {
1558: $thislocale = "ru_RU.KOI8-R";
1559: }
1560: POSIX::setlocale( &POSIX::LC_ALL, $thislocale );
1561:
1562: if ((uc 'а') ne 'А') {print "Koi8-r locale not installed!\n"};
1563:
1564:
1565: if ($text) {
1566: print header('text/plain');
1567: }
1568:
1569: if (param('hideequal')) {
1570: my ($sth)= $dbh -> prepare("select first, second FROM equalto");
1571: $sth -> execute;
1572: while ( my ($first, $second)=$sth -> fetchrow)
1573: {
1574: $forbidden{$first}=1;
1575: }
1576: $sth->finish;
1577: }
1578:
1579:
1580: if (param('rand')) {
1581: my ($type, $qnum) = ('', 12);
1582: $type.=$TypeName{$_} foreach param('type');
1583: # $type .= 'Б' if (param('brain'));
1584: # $type .= 'Ч' if (param('chgk'));
1585: $qnum = param('qnum') if (param('qnum') =~ /^\d+$/);
1586: $qnum = 0 if (!$type);
1587: my $Email;
1588: if (($Email=param('email')) && -x $SENDMAIL &&
1589: open(F, "| $SENDMAIL $Email")) {
1590: my ($mime_type) = $text ? "plain" : "html";
1591: print F <<EOT;
1592: To: $Email
1593: From: olegstepanov\@mail.ru
1594: Subject: Sluchajnij Paket Voprosov "Chto? Gde? Kogda?"
1595: MIME-Version: 1.0
1596: Content-type: text/$mime_type; charset="koi8-r"
1597:
1598: EOT
1599: print F &PrintRandom($dbh, $type, $qnum, $text);
1600: close F;
1601: print "Пакет случайно выбранных вопросов послан по адресу $Email. Нажмите
1602: на <B>Reload</B> для получения еще одного пакета";
1603: } else {
1604: print &PrintRandom($dbh, $type, $qnum, $text);
1605: }
1606: }
1607: elsif (param('authors')){
1608: print &PrintAuthors($dbh,param('authors'));
1609: }
1610: elsif (param('qofauthor')){
1611: &PrintQOfAuthor($dbh,param('qofauthor'));
1612: }
1613: elsif (param('sstr')||param('was')) {
1614: &PrintSearch($dbh, param('sstr'), param('metod'),param('was'));
1615: $dbh->do("delete from lastqueries where
1616: (TO_DAYS(NOW()) - TO_DAYS(t) >= 2) OR
1617: (time_to_sec(now())-time_to_sec(t) >3600)")
1618: }
1619: elsif (param('qid')) {
1620: my $qid=param('qid');
1621: my $query="SELECT Question, Answer from Questions where QuestionId=$qid";
1622: print $query if $printqueries;
1623: my $sth=$dbh->prepare($query);
1624: $sth->execute;
1625: my $sstr= join ' ',$sth->fetchrow;
1626: $sth->finish;
1627: $searchin{'Question'}=1;
1628: $searchin{'Answer'}=1;
1629: $sstr=~tr/ёЁ/еЕ/;
1630: $sstr=~s/[^йцукенгшщзхъфывапролджэячсмитьбюЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮa-zA-Z0-9]/ /gi;
1631: # print &PrintQuestion($dbh,$qid, 1, '!');
1632: &PrintSearch($dbh, $sstr, 'proxy');
1633: }
1634:
1635: elsif (param('all')) {
1636: print &PrintAll($dbh, 0);
1637: } elsif (param('from_year') && param('to_year')) {
1638: print &PrintDates($dbh);
1639: } elsif (param('comp')) {
1640: print header(
1641: -'Content-Type' => 'application/x-zip-compressed; name="db.zip"',
1642: -'Content-Disposition' => 'attachment; filename="db.zip"'
1643: );
1644: $tour = (param('tour')) ? param('tour') : 0;
1645: my (@files) = &PrintArchive($dbh, $tour);
1646: WriteFile($dbh,$_) foreach @files;
1647: open F, "$ZIP -j - $SRCPATH/COPYRIGHT @files |";
1648: print (<F>);
1649: close F;
1650: $dbh->disconnect;
1651: exit;
1652: } elsif (param('sqldump')) {
1653: print header(
1654: -'Content-Type' => 'application/x-zip-compressed; name="dump.zip"',
1655: -'Content-Disposition' => 'attachment; filename="dump.zip"'
1656: );
1657: open F, "$ZIP -j - $DUMPFILE |";
1658: print (<F>);
1659: close F;
1660: $dbh->disconnect;
1661: exit;
1662:
1663: } else {
1664: $tour = (param('tour')) ? param('tour') : 0;
1665: my $sth;
1666: if ($tour !~ /^[0-9]*$/) {
1667: if ($tour=~/\./)
1668: {
1669: my ($fname,$n)= split /\./ , $tour;
1670:
1671: $sth = $dbh->prepare(
1672: "SELECT t2.Id FROM Tournaments as t1,
1673: Tournaments as t2
1674: WHERE t1.FileName = '$fname.txt'
1675: AND t1.Id=t2.ParentId AND t2.Number=$n");
1676: }
1677: else
1678: {
1679: $sth = $dbh->prepare("SELECT Id FROM Tournaments
1680: WHERE FileName = '$tour.txt'");
1681: }
1682: $sth->execute;
1683: $tour = ($sth->fetchrow)[0];
1684: $sth->finish;
1685: }
1686: my $QuestionNumber=0;
1687: my $qnum;
1688: if ($qnum=param('qnumber')){
1689: my ($sth) = $dbh->prepare("SELECT QuestionId FROM Questions
1690: WHERE ParentId=$tour AND Number=$qnum");
1691: $sth->execute;
1692: $QuestionNumber=($sth->fetchrow)[0]||0;
1693: }
1694: if ($QuestionNumber) {
1695: print &PrintQuestion($dbh, $QuestionNumber, param('answer')||0, $qnum, 1);
1696: # $dbh, $Id, $answer, $qnum, $title, $text
1697: } else {
1698: print &PrintTournament($dbh, $tour, param('answer'));
1699: }
1700: }
1701: if (!$text) {
1702: print &Include_virtual("../dimrub/db/footer.html");
1703: print <<EEE
1704: <SCRIPT LANGUAGE="JavaScript">
1705: function toggle(e) {
1706: if (e.style.display == "none") {
1707: e.style.display="";
1708: } else {
1709: e.style.display = "none";
1710: }
1711: }
1712: </SCRIPT>
1713: EEE
1714: ;
1715: print end_html;
1716: }
1717: $dbh->disconnect;
1718: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>