1: #!/usr/bin/perl -w
2:
3: use DBI;
4: use CGI ':all';
5: #use strict;
6: my @softfields=("От Олега Степанова");
7: use Time::Local;
8: my $proxyredirect=1;
9: use POSIX qw(locale_h);
10: use locale;
11: use vars qw($opt_z);
12: use Getopt::Std;
13: #my ($dbuser,$dbname,$dbpass,$dbhost);
14: eval {require "dbdefs.pl";} ;
15: my $url=url||'';
16: my @used_stop=();
17: my $showNearQuestions=0;
18: $dbuser||="piataev";
19: $dbname||="chgk";
20: $dbpass||="";
21: $dbhost||="localhost";
22: getopts('z');
23: $opt_z||=param("makehtml");
24: my $timestamp="_timestamp.tmp";
25: my $usehash=0;
26: my $paramtour;
27: my $withanswers=param('answer')||param('answers');
28: open STDERR, ">/var/tmp/errors1";
29: my $newsurl='http://news.chgk.info/';
30: my $reklama="../dimrub/db/reklama.html";
31: my $footer="../dimrub/db/footer.html";
32: $footer="../../chgk/footer.html" if $url=~/zaba/;
33: $reklama="../../chgk/reklama.html" if $url=~/zaba/;
34: my $datefooter="../dimrub/db/date";
35: $datefooter="../../chgk/date" if $url=~/zaba/;
36:
37: my $fname;
38: $reklama="../reklama.html" if $opt_z;
39: $footer="../footer.html" if $opt_z;
40: $datefooter="../date" if $opt_z;
41: my $HTMLDIR="/znatoki/dimrub/db/baza/";
42: $HTMLDIR="/files/";
43: my $realHTMLDIR;
44: if ($^O =~ /win/i) {
45: $realHTMLDIR="/html/znatoki/baza/";
46: } else
47: {
48: $realHTMLDIR="/home/znatoki/chgk-db/public_html/dimrub/db/files/";
49: }
50:
51:
52: my $usehtml=$opt_z||0;
53: $usehtml=1;
54: $usehtml=0 if $url=~/zaba/ || $url=~/localhost/;
55:
56: my $usewas=0;
57: my $cashednumber=500;
58: my $outputnumber=10;
59: my ($proxyptext,$proxysstr);
60: my $printqueries=0;
61: my $qs=query_string;
62: my $globaloutput;
63: my %forbidden=();
64: my $debug=0; #added by R7
65: my $metod=param('metod')||'';
66: my $outputkvo=param('kvo') ||$outputnumber;
67: $outputkvo=100 if $outputkvo>100;
68:
69: if (param('debug')) {$debug=1; $printqueries=1}
70: *STDERR=*STDOUT if $debug;
71: if ($url !~ /db\.chgk\.info/ && $url !~ /localhost/ && $url !~ /bilbo/ && $url !~ /zaba/ && $url !~ /question\.chgk\.info/ ) {
72: my $u="http://db.chgk.info/cgi-bin/db.cgi?$qs";
73: Redirect ($u);
74: exit;
75: }
76:
77: if ($proxyredirect && $metod=~/proxy/ && $url !~ /localhost/ && $url !~ /bilbo/ && $url !~ /zaba/) {
78: my $u="http://chgk.zaba.ru/cgi-bin/db.cgi?$qs";
79: Redirect ($u);
80: exit;
81: }
82:
83: #if (!param('sstr') && param('all')) {
84: # my $destination='http://db.chgk.info/all.html';
85: # Redirect($destination);
86: # exit;
87: #}
88: my $thislocale;
89: if ($^O =~ /win/i) {
90: $thislocale = "Russian_Russia.20866";
91: } else {
92: $thislocale = "ru_RU.KOI8-R";
93: }
94: POSIX::setlocale( &POSIX::LC_ALL, $thislocale );
95:
96: if ((uc 'а') ne 'А') {print STDERR "Koi8-r locale not installed!\n"};
97:
98: my %fieldname= (0,'Question', 1, 'Answer', 2, 'PassCriteria', 3, 'Comments', 4, 'Authors', 5, 'Sources');
99: my %rusfieldname=('Question','Вопрос', 'Answer', 'Ответ', 'PassCriteria','Зачёт',
100: 'Comments', 'Комментарии', 'Authors', 'Автор',
101: 'Sources', 'Источник','old','Старый','rus','Новый',
102: 'chgk', 'ЧГК', 'brain', 'Брейн-ринг','game', 'Своя игра',
103: 'ehruditka', 'Эрудитка', 'beskrylka', 'Бескрылка', 'igp', 'Интернет'
104: );
105: my %searchin;
106: my $rl=qr/[йцукенгшщзхъфывапролджэячсмитьбюё]/;
107: my $RL=qr/[ЙЦУКЕНГШЩЗХЪЭЖДЛОРПАВЫФЯЧСМИТЬБЮЁ]/;
108: my $RLrl=qr/(?:(?:${rl})|(?:${RL}))+/;
109: my $l=qr/(?:(?:${RLrl})|(?:[\w\-]))+/;
110: my $Ll=qr/(?:[A-Z])|(?:${RL})/;
111: my %metodchar=('rus',1,'old',2);
112:
113:
114:
115:
116: $searchin{$_}=1 foreach param('searchin');
117: my %TypeName=('children'=>'Д', 'game'=>'Я', 'igp'=>'И',
118: 'chgk'=>'Ч', 'brain'=>'Б', 'beskrylka'=>'Л','ehruditka'=>'Э');
119:
120:
121: sub countz {
122: my ($dbh,$type)=@_;
123:
124: my $sth=$dbh->prepare("select count(*) from Questions where Type LIKE '%$type%'");
125: $sth->execute();
126: my ($tmp)=$sth->fetchrow();
127: return $tmp;
128: }
129:
130: my $all=param('all');
131: $all=0 if lc $all eq 'no';
132: my ($PWD) = `pwd` if $^O!~/win/i;
133: chomp $PWD if $PWD;
134: my ($SRCPATH) = "/home/db-chgk/public_html/dimrub/src";
135: my ($ZIP) = "/usr/bin/zip";
136: my $DUMPFILE = "/tmp/chgkdump";
137: my ($SENDMAIL) = "/usr/sbin/sendmail";
138: my ($TMPDIR) = "/var/tmp";
139: my ($TMSECS) = 30*24*60*60;
140: my (%RevMonths) =
141: ('Jan', '0', 'Feb', '1', 'Mar', '2', 'Apr', '3', 'May', '4', 'Jun', '5',
142: 'Jul', '6', 'Aug', '7', 'Sep', '8', 'Oct', '9', 'Nov', '10',
143: 'Dec', '11',
144: 'Янв', '0', 'Фев', 1, 'Мар', 2, 'Апр', 3, 'Май', '4',
145: 'Июн', '5', 'Июл', 6, 'Авг', '7', 'Сен', '8',
146: 'Окт', '9', 'Ноя', '19', 'Дек', '11');
147: my @months=('000','Jan',"Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct",
148: "Nov","Dec");
149:
150:
151: # Determine whether the given time is within 2 months from now.
152: sub NewEnough {
153: my ($a) = @_;
154: my ($year, $month, $day) = split('-', $a);
155: $month=1 if ($month<=0);
156: $day=1 if ($day<=0);
157: return (time - timelocal(0, 0, 0, $day, $month -1, $year) < $TMSECS);
158: }
159:
160: # Reads one question from the DB. Gets DB handler and Question ID.
161:
162: sub Redirect {
163: my ($destination) = @_;
164: print header.<<EndOfHTML;
165: <head><meta http-equiv="refresh" content="0; URL=$destination"></head>
166: EndOfHTML
167: ;
168: =head
169:
170: print <<EndOfHTML;
171: Content-type: text/html
172: Location: $destination
173:
174: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
175: <HTML><HEAD><TITLE>Redirection</TITLE></HEAD>
176: <BODY BGCOLOR="#FFFFFF">
177: <H1>Redirection</H1>
178: <P>It appears that your browser cannot handle redirections
179: automatically. You can proceed to the randomly-selected page
180: by clicking <A HREF="$destination">here</A>.</P>
181: </BODY>
182: </HTML>
183: EndOfHTML
184: ;
185: =cut
186: }
187:
188:
189:
190:
191: sub GetTournament {
192: my ($dbh, $Id) = @_;
193: my (%Tournament, $field, @arr);
194:
195: return %Tournament if ($Id == 0);
196:
197: my ($sth) = $dbh->prepare("SELECT * FROM Tournaments WHERE Id=$Id");
198: $sth->execute;
199:
200: @arr = $sth->fetchrow;
201: my($i, $name) = 0;
202: foreach $name (@{$sth->{NAME}}) {
203: $Tournament{$name} = $arr[$i++];
204: }
205: $sth->finish;
206: return %Tournament;
207: }
208:
209: sub fetchquestion {
210: my ($sth,$q,$WithTour)=@_;
211: if ($WithTour) {
212: ($$q{'QuestionId'}, $$q{'Question'},$$q{'Answer'},$$q{'PassCriteria'},$$q{'Comments'},$$q{'Authors'},$$q{'Sources'},
213: $$q{'Number'},
214: $$q{'Title'}, $$q{'TourTitle'}, $$q{'FileName'},$$q{'PlayedAt'},$$q{'TourNumber'}) =
215: $sth->fetchrow;
216: } else {
217: ($$q{'QuestionId'}, $$q{'Question'},$$q{'Answer'},$$q{'PassCriteria'},$$q{'Comments'},$$q{'Authors'},$$q{'Sources'},
218: $$q{'Number'})=
219: $sth->fetchrow;
220: }
221: }
222:
223:
224:
225:
226: sub SelectQuestions {
227: my ($dbh,$q,$WithTour) = @_;
228: my %q=();
229: # $_ = "QuestionId=$_" foreach @$q;
230: # my $where=join " OR ",@$q;
231: my $where=join ',',@$q;
232: $where &&= "QuestionId IN (".(join ',',$where).")";
233: $where||=1;
234: $where="($where) AND Questions.ParentId=t1.Id AND t1.ParentId=t2.Id"
235: if $WithTour;
236:
237: my $query;
238: if ($WithTour) {
239: $query="SELECT QuestionId, Questions.Question, Answer, PassCriteria, Comments, Authors, Sources,
240: Questions.Number
241: , t2.Title, t1.Title, t2.FileName, t2.PlayedAt,t1.Number
242: from Questions,Tournaments as t1, Tournaments as t2
243: WHERE $where";
244: } else {
245: $query="SELECT QuestionId, Questions.Question, Answer, PassCriteria, Comments, Authors, Sources,
246: Questions.Number from Questions
247: WHERE $where";
248: }
249:
250: my $sth;
251: $sth=$dbh->prepare($query);
252: $sth->execute;
253: return $sth;
254: }
255:
256:
257: # Reads one question from the DB. Gets DB handler and Question ID.
258: sub GetQuestion {
259: my ($dbh, $QuestionId) = @_;
260: my (%Question, $field, @arr);
261:
262: my($sth) = $dbh->prepare("
263: SELECT * FROM Questions WHERE QuestionId=$QuestionId
264: ");
265:
266: $sth->execute;
267:
268: @arr = $sth->fetchrow;
269: my($i, $name) = 0;
270: foreach $name (@{$sth->{NAME}}) {
271: $Question{$name} = $arr[$i++];
272: }
273:
274: $sth->finish;
275: return %Question;
276: }
277:
278: sub tourhref {
279: my ($t,$a,$gr)=@_;
280: my $res;
281: if ($usehtml) {
282: $res=$t;
283: $res.=$a?"-a":"-q" unless $gr;
284: $res.=".html";
285: $res=~s/(\#\d+)(.*)$/$2$1/;
286: my $t=$res;
287: $t=~s/\#.*$//;
288: $res=~s/\.1// unless -e "$realHTMLDIR$t";
289: $t=$res;
290: $t=~s/\#.*$//;
291: $res=~s/\.html/-q\.html/ unless -e "$realHTMLDIR$t";
292: $res="$HTMLDIR$res" unless $opt_z;
293: return $res;
294: } else {
295: $res=$url;
296: $res.=$a?"?answers=1&":"?";
297: $res.="tour=$t";
298:
299: return $res;
300: }
301:
302: }
303:
304: # Gets numbers of all the questions from the given tour.
305: sub GetTourQuestions {
306: my ($dbh, $ParentId) = @_;
307: my (@arr, @Questions);
308: my ($sth) = $dbh->prepare("SELECT QuestionId FROM Questions
309: WHERE ParentId=$ParentId order by Number");
310:
311: $sth->execute;
312:
313: while (@arr = $sth->fetchrow) {
314: push @Questions, $arr[0];
315: }
316:
317: $sth->finish;
318: return @Questions;
319: }
320:
321: # Returns list of children of the given tournament.
322: sub GetTours {
323: my ($dbh, $ParentId) = @_;
324: my (@arr, @Tours);
325:
326: my ($sth) = $dbh->prepare("SELECT Id FROM Tournaments
327: WHERE ParentId=$ParentId ORDER BY Id");
328:
329: $sth->execute;
330:
331: while (@arr = $sth->fetchrow) {
332: push @Tours, $arr[0];
333: }
334: $sth->finish;
335: return @Tours;
336: }
337:
338: sub count
339: {
340: my ($dbh,$word)=@_;
341: $word=$dbh->quote(uc $word);
342: my $query="SELECT number from nests,nf where $word=w1 AND w2=nf.id";
343: my $sth=$dbh->prepare($query);
344: $sth->execute;
345: my @a=$sth->fetchrow;
346: $sth->finish;
347: $a[0]||0;
348: }
349:
350:
351: sub printform
352: {
353:
354: my $qnumber=(" "x10)."Выводить по
355: <input type=\"text\" name=\"kvo\" value=$outputkvo size=\"3\" maxlength=\"5\">";
356: #textfield(-name=>'kvo',
357: # -default=>6,
358: # -size=>3,
359: # -maxlength=>5)." вопросов";
360: my $sstr=param('sstr');
361: my @df=keys %searchin;
362: my %checked;
363: $checked{lc $_}="" foreach ('Question','Answer','PassCriteria','Comments','Authors','Sources','old','rus',
364: 'chgk','brain','igp','game','ehruditka','beskrylka');
365: @df=('Question', 'Answer') unless @df;
366: $checked{lc $_}="checked" foreach @df;
367: my $fields=checkbox_group('searchin',['Question','Answer','PassCriteria','Comments','Authors','Sources'], [@df],
368: 'false',\%rusfieldname);
369: @df=param('type');
370: @df=('chgk','brain','igp','game','ehruditka','beskrylka') unless @df;
371: $checked{lc $_}="checked" foreach @df;
372: my $all=param('all') && param('all') eq 'yes';
373:
374: $checked{'all'}=$all?"checked":"";
375: $checked{'any'}=$all?"":"checked";
376: $checked{lc param('metod')}="checked";
377: $checked{'rus'}=1 unless $checked{'rus'} || $checked{'old'};
378:
379: #################################################
380: return
381: <<EOT
382: <form method="get" enctype="application/x-www-form-urlencoded"
383: action="/znatoki/cgi-bin/db.cgi">
384: <h2>Поиск в базе вопросов</h2>
385:
386: <input type="text" name="sstr" value="$sstr" size="30" maxlength="50">
387: <input type="submit" value="Поиск"> $qnumber
388: <p>
389:
390: <table border="1" cellpadding=4 cellspacing=0>
391: <tr>
392: <th align="left" rowspan=3 width="20%"> Вариант поиска:
393: </td><td rowspan=2 colspan=3>
394: <input type="radio" $checked{'old'} name="metod" value="old"> Простой (старый)
395: </td><td>
396: <input type="checkbox" $checked{'chgk'} name="type" value="chgk"> "Что? Где? Когда?"
397: </td><td><nobr>
398: <input type="checkbox" $checked{'brain'} name="type" value="brain"> "Брейн-Ринг"</nobr>
399: </td><td>
400: <input type="checkbox" $checked{'igp'} name="type" value="igp"> "Интернет"
401: </td>
402: </tr><tr>
403: <td>
404: <input type="checkbox" $checked{'game'} name="type" value="game"> "Своя игра"
405: </td><td>
406: <input type="checkbox" $checked{'ehruditka'} name="type" value="ehruditka"> "Эрудитка"
407: </td><td>
408: <input type="checkbox" $checked{'beskrylka'} name="type" value="beskrylka"> "Бескрылка"
409: </td>
410: </tr><tr>
411: <td colspan=6><input type="radio" $checked{'rus'} name="metod" value="rus"> Расширенный (с учетом грамматики, в вопросах всех типов)
412: </td>
413: </tr><tr>
414: <th align="left">Искать:
415: </td><td colspan=3>
416: <input type="radio" $checked{'all'} name="all" value="yes">Все слова
417: </td><td colspan=3>
418: <input type="radio" $checked{'any'} name="all" value="no">Любое слово
419: </td>
420: </tr><tr>
421: <th align="left">Поля для поиска:
422: </td><td width="15%">
423: <input type="checkbox" name="searchin" value="Question" $checked{'question'}>Вопрос
424: </td><td width="15%">
425: <input type="checkbox" name="searchin" value="Answer" $checked{'answer'}>Ответ<br>
426: </td><td width="15%">
427: <input type="checkbox" name="searchin" value="PassCriteria" $checked{'passcriteria'}>Зачёт<br>
428: </td><td width="15%">
429: <input type="checkbox" name="searchin" value="Comments" $checked{'comments'}>Комментарии<br>
430: </td><td width="15%">
431: <input type="checkbox" name="searchin" value="Authors" $checked{'authors'}>Автор<br>
432: </td><td width="15%">
433: <input type="checkbox" name="searchin" value="Sources" $checked{'sources'}>Источник<br>
434: </td>
435: </tr>
436: </table>
437: <!--p><i>Если при попытке поиска выдаётся сообщение об ошибке,
438: попробуйте воспользоваться
439: <a href="http://chgk.zaba.ru/search.html">зеркалом базы</a></i-->
440: </center>
441:
442: EOT
443: .endform
444: .hr
445:
446: }
447:
448: sub proxy
449: {
450: my ($dbh,$ptext,$allnf)=@_;
451: my $sstr=makeproxysstr($dbh,$ptext,$allnf);
452: return russearch($dbh,$sstr,0,$allnf);
453: }
454:
455: sub makeproxysstr {
456: my ($dbh,$ptext)=@_;
457: my $text=$$ptext;
458: POSIX::setlocale( &POSIX::LC_ALL, $thislocale );
459: $text=~tr/ёЁ/еЕ/;
460: $text=~s/(${RLrl})p(${RLrl})/$1p$2/gom;
461: $text=~s/p(${RLrl})/р$1/gom;
462: $text=~s/(${RLrl})p/$1р/gom;
463: $text=~s/\s+/ /gmo;
464: $text=~s/[^йцукенгшщзхъфывапролджэячсмитьбюЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮQWERTYUIOPASDFGHJKLZXCVBNM0-9]/ /g;
465: $text=uc $text;
466: my @list= $text=~m/(?:(?:${RLrl})+)|(?:[A-Za-z0-9]+)/gom;
467:
468: my (%c, %good,$sstr);
469: foreach (@list)
470: {
471: $c{$_}=count($dbh,$_)||10000;
472: }
473: my @words=sort {$c{$a}<=> $c{$b}} @list;
474:
475: # $good{$words[$_]}=1 foreach 0..4;
476: foreach (@words)
477: {
478: $good{$_}=1 if $c{$_}<200 && length $_>2;
479: }
480:
481: $good{$words[$_]}=0 foreach 16..$#words;
482:
483: $sstr.=" $_" foreach grep {$good{$_}} @list;
484: $$ptext=$sstr;
485: return $sstr;
486: }
487:
488:
489: sub russearch {
490: my ($dbh, $sstr, $all,$allnf)=@_;
491: my (@qw,@w,@tasks,$qw,@arr,$nf,$sth,@nf,$w,$where,$e,@where,%good,$i,%where,$from);
492: my($number,@good,$t,$task,@rho,$rank,%rank,$r2,$r1,$word,$n,@last,$good,@words,%number,$taskid);
493: my ($hi, $lo, $wordnumber,$query,$blob,$field,$sf,$ii);
494: my @frequence;
495: my (@arr1,@ar,@sf,@arr2);
496: my %tasks;
497: my $tasks;
498: my @verybad;
499: my %nf;
500: my %tasksof;
501: my %wordsof;
502: my %relevance;
503: my @blob;
504: my %count;
505: my %stop_word;
506: POSIX::setlocale( &POSIX::LC_ALL, $thislocale );
507: $sstr=~tr/йцукенгшщзхъфывапролджэячсмитьбю/ЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮ/;
508: # @qw=@w =split (' ', uc $sstr);
509: my $ts=uc $sstr;
510: @qw=@w= $ts=~m/(?:(?:${RLrl})+)|(?:[A-Za-z0-9]+)/gom;
511: $query="select nf.word from nf where number>=50000";
512: $sth=$dbh->prepare($query);
513: $sth->execute();
514: %stop_word=();
515: while (@arr = $sth->fetchrow)
516: {
517: $stop_word{$arr[0]}=1;
518: }
519: $sth->finish;
520:
521:
522: #-----------
523: foreach $i (0..$#w) # заполняем массив @nf начальных форм
524: # $nf[$i] -- ссылка на массив возможных
525: # начальных форм словоформы $i
526: {
527: (push @used_stop, uc $w[$i]),next if $stop_word{uc $w[$i]};
528: $qw= $dbh->quote (uc $w[$i]);
529:
530: $query=" select distinct w2 from nests
531: where w1=$qw";
532: $sth=$dbh -> prepare($query);
533: $sth -> execute;
534: @{$nf[$i]}=();
535: while (@arr = $sth->fetchrow)
536: {
537: push (@{$nf[$i]},$arr[0])
538: }
539: $sth->finish;
540: }
541:
542:
543: my @bad=grep {!@{$nf[$_]}} 0..$#w; # @bad -- номера словоформ,
544: # которых нет в словаре
545:
546: if (@bad) #есть неопознанные словоформы
547: {
548: require "cw.pl";
549: foreach $i(@bad)
550: {
551: if (@arr=checkword($dbh,$w[$i]))
552: {push (@{$nf[$i]}, @arr);}
553: else
554: {push (@verybad,$i);}
555: }
556: }
557: return () if ($all && @verybad);
558:
559:
560: my $kvo=0;
561: push @$allnf, @{$_} foreach @nf;
562:
563: foreach $i (0..$#w) #запросы в базу...
564: {
565: @arr=@{$nf[$i]} if $nf[$i];
566: @arr2=@arr1=@arr;
567:
568:
569:
570:
571: $_= " word2question.word=$_" foreach @arr;
572: $_= " nf.id=".$_. ' ' foreach @arr1;
573: # @arr=(0) unless @arr;
574: $query="select questions from word2question where (". (join ' OR ', @arr).") ";
575:
576: $sth=$dbh -> prepare($query);
577: $sth->execute;
578:
579: @blob=();
580: while (@arr=$sth->fetchrow)
581: {
582: @blob=(@blob,unpack 'C*',$arr[0]);
583: }
584: $sth->finish;
585: $query="select number from nf where ".(join ' OR ', @arr1);
586: $sth=$dbh -> prepare($query);
587: $sth->execute;
588:
589: while (@arr=$sth->fetchrow)
590: {
591: $frequence[$i]+=$arr[0];
592: }
593: $sth->finish;
594:
595:
596: if (@blob < 4)
597: {
598: $tasksof{$i}=undef;
599: } else
600: {
601: $kvo++;
602: $ii=0;
603: while ($ii<$#blob) # создаём хэш %tasksof, ключи которого --
604: # номера искомых словоформ, а значения --
605: # списки вопросов, в которых есть соответствующа
606: # словоформа.
607: # Каждый список в свою очередь также оформлен в
608: # виде хэша, ключи которого -- номера вопросов,
609: # а значения -- списки номеров вхождений. Вот.
610: {
611: ($field,$lo,$hi,$wordnumber)=@blob[$ii..($ii+3)];
612: $ii+=4;
613: my $addnumber=($field >> 4) << 16;
614: $number=(($field >> 4) << 16)+($hi << 8) + $lo;
615: $field=$fieldname{$field & 0xF};
616: if ($searchin{$field})
617: {
618: push @{$tasksof{$i}{$number}}, $wordnumber;
619: # дополнили в хэше, висящем на
620: # словоформе $i в %tasksof список
621: # вхождений $i в вопрос $number.
622: push @{$wordsof{$number}{$i}}, $wordnumber;
623: # дополнили в хэше, висящем на
624: # вопросе $number в %wordsof список
625: # вхождений $i в вопрос $number.
626:
627:
628: }
629: } #while ($ii<$#blob)
630: }
631: } #foreach $i
632:
633: #Ищем пересечение или объединение списков вопросов (значений %tasksof)
634: foreach $sf (keys %tasksof)
635: {
636: foreach (keys %{$tasksof{$sf}})
637: {
638: next if $forbidden{$_};
639: $count{$_}++
640: }
641:
642: }
643: @tasks= ($all ? (grep {$count{$_}==$kvo} keys %count) :
644: keys %count) ;
645:
646:
647: ############ Сортировка найденных вопросов
648:
649: foreach (keys %wordsof)
650: {
651: $relevance{$_}=&relevance($#w,$wordsof{$_},\@frequence) if $_
652: }
653:
654: @tasks=sort {$relevance{$b}<=>$relevance{$a}} @tasks;
655:
656: ############
657:
658:
659: return @tasks;
660: }
661:
662:
663: sub distance {
664: # на входе -- номера словоформ и ссылки на
665: # списки вхождений. На выходе -- расстояние,
666: # вычисляемое по формуле min(|b-a-pb+pa|)
667: # pb,pa
668: # (pb и pa -- позиции слов b и a)
669: my ($a,$b,$lista,$listb)=@_;
670: my ($pa,$pb,$min,$curmin);
671: $min=10000;
672: foreach $pa (@$lista)
673: {
674: foreach $pb (@$listb)
675: {
676: $curmin=abs($b-$a-$pb+$pa);
677: $min= $curmin if $curmin<$min;
678: }
679: }
680: return $min;
681:
682: }
683:
684: sub relevance {
685: # На входе -- количество искомых словоформ -1 и
686: # ссылка на hash, ключи которого --
687: # номера словоформ, а значения -- списки вхождений
688:
689: my ($n,$words,$frequence)=@_;
690: my $relevance=0;
691: my ($first,$second,$d);
692: foreach $first (0..$n)
693: {
694: $relevance+=scalar @{$$words{$first}}+1000+1000/$$frequence[$first]
695: if $$words{$first};
696: foreach $second ($first+1..$n)
697: {
698: $d=&distance($first,$second,$$words{$first},$$words{$second});
699: $relevance+=($d>10?0:10-$d)*10;
700: }
701: }
702: return $relevance;
703: }
704:
705:
706:
707: # Returns list of QuestionId's, that have the search string in them.
708: sub Search {
709: my ($dbh, $s,$metod,$all,$allnf) = @_;
710: my $sstr=$$s;
711: my (@arr, @Questions, @fields);
712: my (@sar, $i, $sth,$where,$query);
713: if ($metod eq 'rus')
714: {
715: my @tasks=russearch($dbh,$sstr,$all,$allnf);
716: return @tasks
717: }
718: elsif ($metod eq 'proxy')
719: {
720: my @task=proxy($dbh,$s,$allnf);
721: return @task
722: }
723:
724:
725:
726: ###Simple and advanced query processing. Added by R7
727: if ($metod eq 'simple' || $metod eq 'advanced')
728: {
729: foreach (qw/Question Answer PassCriteria Sources Authors Comments/) {
730: if (param($_)) {
731: push @fields, $_;
732: }
733: }
734:
735: @fields=(qw/Question Answer PassCriteria Sources Authors Comments/) unless scalar @fields;
736: my $fields=join ",", @fields;
737: my $q=new Text::Query($sstr,
738: -parse => 'Text::Query::'.
739: (($metod eq 'simple') ? 'ParseSimple':'ParseAdvanced'),
740: -solve => 'Text::Query::SolveSQL',
741: -build => 'Text::Query::BuildSQLMySQL',
742: -fields_searched => $fields);
743:
744: $where= $$q{'matchexp'};
745: $query= "SELECT Questionid FROM Questions
746: WHERE $where";
747:
748: $sth = $dbh->prepare($query);
749: } else
750: ######
751: {
752:
753: foreach (param('searchin')) {
754: # if (param($_)) {
755: push @fields, "IFNULL($_, '')";
756: # }
757: }
758: @sar = split " ", $sstr;
759: for $i (0 .. $#sar) {
760: $sar[$i] = $dbh->quote("%${sar[$i]}%");
761: }
762: $_.=' ' foreach (@fields); # Это чтобы последнее слово поля
763: # не сливалось с первым словом
764: # следующего поля, R7
765: my($f) = "CONCAT(" . join(',', @fields) . ")";
766: if (param('all') eq 'yes') {
767: $sstr = join " AND $f LIKE ", @sar;
768: } else {
769: $sstr = join " OR $f LIKE ", @sar;
770: }
771:
772: my $query;
773: $query="SELECT QuestionId FROM Questions
774: WHERE ($f LIKE $sstr) AND (".&makewhere.") ORDER BY QuestionId";
775:
776:
777: $sth = $dbh->prepare($query)
778: } #else -- processing old-style query (R7)
779:
780: $sth->execute;
781: while (@arr = $sth->fetchrow) {
782: push @Questions, $arr[0] unless $forbidden{$arr[0]};
783: }
784: $sth->finish;
785:
786: return @Questions;
787: }
788:
789: sub makewhere {
790: my @type=param('type');
791: my $type='';
792:
793: $type .= ($_=$TypeName{$_}) foreach @type;
794: my $where=' 0 ';
795: foreach (@type) {
796: $where.= " OR (Type ='$_') OR (Type ='$_Д') OR (Type ='Д$_') ";
797: }
798: $where.= "OR (Type='ЧБ')" if ($type=~/Ч|Б/);
799: return $where;
800: }
801:
802: # Substitute every letter by a pair (for case insensitive search).
803: my (@letters) = qw/аА бБ вВ гГ дД еЕ жЖ зЗ иИ йЙ кК лЛ мМ нН оО
804: пП рР сС тТ уУ фФ хХ цЦ чЧ шШ щЩ ьЬ ыЫ эЭ юЮ яЯ/;
805:
806: sub NoCase {
807: my ($sstr) = shift;
808: my ($res);
809:
810: if (($res) = grep(/$sstr/, @letters)) {
811: return "[$res]";
812: } else {
813: return $sstr;
814: }
815: }
816:
817: sub PrintList {
818: my ($dbh,$Questions,$shablon,$was)=@_;
819: my $Output;
820: my $first=param('first') ||1;
821: $first=$first-($first-1)%$outputkvo;
822: my $fkvo=param('fkvo')||($#$Questions+1);
823: my $last=$first+$outputkvo-1;
824: $last=$fkvo if $fkvo<$last;
825: my($f,$l);
826: my $nav='';
827: my $qs=query_string;
828: $qs=~s/\;/\&/g;
829: $qs=~s/\&first\=[^\&]+//g;
830: my $sstr=param('sstr')||'';
831: $qs=~s/sstr=[^\&]+/sstr=$sstr/;
832: if ($usewas) {
833: $qs=~s/\&was=[^\&]+//;
834: $qs.="&was=$was" if $was;
835: $qs.="&fkvo=$fkvo" if $was;
836: }
837: if ($first>$outputkvo*3+1)
838: {
839: $nav.=
840: (" "x4).
841: a({href=>$url."?".$qs."\&first=1"},"<<").(" "x4).
842: a({href=>($url."?".$qs."\&first=".($first-$outputkvo))},"<").(" "x4)
843: }
844: else {$nav.=' 'x15;}
845:
846: my ($fprint,$lprint);
847: my $llprint=$fkvo- ($fkvo)%$outputkvo+1; #
848: if ($fkvo<=$outputkvo*7)
849: { $fprint=1;
850: $lprint=$llprint;
851: }
852: elsif ($first>$outputkvo*3 && $fkvo-$first>$outputkvo*3)
853: {
854: $fprint=$first-$outputkvo*3;
855: $lprint=$first+$outputkvo*3;
856: }
857: elsif ($first<=$outputkvo*3)
858: {
859: $fprint=1; $lprint=6*$outputkvo+1;
860: }
861: else
862: {
863: $lprint=$llprint;
864: $fprint=$lprint-$outputkvo*6
865: }
866:
867: # my $fprint=($first>$outputkvo*3) ? $first-$outputkvo*3 : 1;
868: # my $lprint=$#$Questions+1-$fprint>$outputkvo*7 ? $outputkvo*7 :$#$Questions+1;
869: # if ($lprint-$fprint<$outputkvo*6 && $fprint>1)
870: # {
871: # $fprint=$lprint-$outputkvo*6;
872: # $fprint=1 if ($fprint<=0)
873: # }
874:
875:
876:
877: for($f=$fprint; $f<=$lprint; $f+=$outputkvo)
878: {
879: # next if $first-$f>$outputkvo*3;
880: $l=$f+$outputkvo-1;
881: $l=$fkvo if $l>$fkvo+1;
882: if ($f==$first) {$nav.="[$f-$l] ";}
883: else {
884: $nav.= "[".a({href=>($url."?".$qs."\&first=$f")},"$f-$l")."] ";}
885: }
886: if ($lprint+$outputkvo<$fkvo)
887: {
888: $nav.=
889: (" "x4).
890: a({href=>($url."?".$qs."\&first=".($first+$outputkvo))},">").(" "x4).
891: a({href=>$url."?".$qs."\&first=$llprint"},">>").(" "x4)
892: }
893: $Output.= "$nav".br."\n";
894: my @q=@$Questions[$first-1..$last-1];
895: my %q=();
896: my $sth=SelectQuestions($dbh,\@q,1);
897: my $qq;
898: my @Q;
899: for (0..$#q) {
900: %{$Q[$_]}=();
901: fetchquestion($sth,$Q[$_],1);
902: $q{$Q[$_]{'QuestionId'}}=$Q[$_];
903: }
904:
905: for (my $i = $first; $i <= $last; $i++) {
906: my $q=$q{$$Questions[$i-1]};
907: my $output;
908: $output = &PrintQuestion($dbh, $q, 1, 0, 1,$text,1 );
909: # if (param('metod') && (param('metod') eq 'rus' || param('metod') eq 'proxy'))
910: {
911: $output=~s/\b($shablon)\b/\<strong\>$1\<\/strong\>/gi;
912: $output=~s/($shablon)/\<strong\>$1\<\/strong\>/gi;
913: }
914: $Output.= $output;
915: }
916: $sth->finish;
917:
918: $Output.= "$nav".br."\n";
919: return $Output;
920: }
921:
922: sub PrintSearch {
923: my $Output='';
924: my ($dbh, $sstr, $metod,$was) = @_;
925: my $t=time;
926: $Output.= printform;
927: my @allnf;
928: my @Questions;
929: $was=0 if $metod eq 'proxy';
930: if ($usewas && $was && ($metod ne 'proxy'))
931: {
932: my $sth=$dbh->prepare ("select sstr,questions,allnf from lastqueries where id=".param('was'));
933: $sth->execute;
934: my ($q,$nf);
935: ($sstr, $q,$nf)=($sth->fetchrow);
936: @Questions=unpack 'L*',$q;
937: @allnf=unpack 'L*',$nf;
938: $sth->finish;
939: }
940: if (!$was || ($metod eq 'proxy') || (param('first')+$outputkvo>$cashednumber))
941: {
942: @Questions=&Search($dbh, \$sstr,$metod,$all,\@allnf);
943: $cashednumber=$#Questions if $cashednumber>$#Questions;
944: my $tmp=$dbh->quote(pack("L*",@Questions[0..$cashednumber]));
945: my $qsstr=$dbh->quote($sstr);
946: my $nf=$dbh->quote(pack("L*", @allnf));
947: my $ss=200;
948: if ($usewas) {
949: do
950: {
951: $was=int rand(32000);
952: }
953: while (--$ss && (!$dbh->do ("insert into lastqueries (id,sstr,questions,allnf)
954: values ($was, $qsstr,$tmp,$nf)")));
955: $Output.= "Something is wrong...".br unless $ss;
956: }
957: }
958:
959:
960:
961: $Output.= p. "Время поиска: " . (time-$t) ." сек.".p;
962: $_="\"$_\"" foreach @used_stop;
963: $Output.= p. (join ', ',@used_stop) ." ignored".p if @used_stop;
964: my ($output, $i, $suffix, $hits) = ('', 0, '', $#Questions + 1);
965:
966: my $shablon;
967: $metod='rus' if $metod eq 'proxy';
968: if ($metod eq 'rus')
969: {
970: my $where='0';
971: $where.= " or w2=$_ " foreach @allnf;
972: my $query="select w1 from nests where $where";
973: my $sth=$dbh->prepare($query);
974:
975: $sth->execute;
976: my @shablon;
977: while (my @arr = $sth->fetchrow)
978: {
979: push @shablon,"(?:$arr[0])";
980: }
981: $sth->finish;
982: $shablon= join "|", @shablon;
983: $shablon=~s/[её]/\[ЕЁ\]/gi;
984: # $shablon=~s/([йцукенгшщзхъфывапролджэячсмитьбюЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮ])/&NoCase($1)/ge;
985: $shablon=qr/$shablon/i;
986:
987: }
988:
989: $hits=param("fkvo")||$hits;
990:
991: if ($hits =~ /1.$/ || $hits =~ /[5-90]$/) {
992: $suffix = 'й';
993: } elsif ($hits =~ /1$/) {
994: $suffix = 'е';
995: } else {
996: $suffix = 'я';
997: }
998:
999: $Output.= p({align=>"center"}, "Результаты поиска на " . strong($sstr)
1000: . " : $hits попадани$suffix.");
1001:
1002: if (param('word')) {
1003: $sstr = '[ \.\,:;]' . $sstr . '[ \.\,:\;]';
1004: }
1005:
1006: # $sstr =~ s/(.)/&NoCase($1)/ge;
1007:
1008: my @sar;
1009: if ($metod ne 'rus')
1010: {
1011: my $ss=$sstr;
1012: (@sar) = split(' ', $ss);
1013: s/(\W)/\\$1/g foreach (@sar);
1014: $shablon=join "|",@sar;
1015: }
1016: $Output.=PrintList($dbh,\@Questions,$shablon,$was);
1017: return $Output;
1018: }
1019:
1020: sub PrintRandom {
1021: my ($dbh, $type, $num, $text) = @_;
1022: my $razd=param('razd');
1023: my %q;
1024: my $answer=$razd?0:1;
1025: my @answers;
1026: #my $t=time;
1027: my (@Questions) = &Get12Random($dbh, $type, $num);
1028:
1029: my ($output, $i) = ('', 0);
1030: #$output.="time=".(time-$t).p;
1031: if ($text) {
1032: $output .= " $num случайных вопросов.\n\n";
1033: } else {
1034: $output .=
1035: h2({align=>"center"}, "$num случайных вопросов.");
1036: }
1037: my $sth=SelectQuestions($dbh,\@Questions,0);
1038: for ($i = 0; $i <= $#Questions; $i++) {
1039: fetchquestion($sth,\%q,0);
1040: $output .=
1041: &PrintQuestion($dbh, \%q, $answer, $i + 1, 0, $text,1);
1042: push @answers, $q{'Answer'};
1043: }
1044: $sth->finish;
1045: unless ($answer )
1046: {
1047: $output.=$text?"\n".('-'x 20)."\nОтветы\n~~~~~~\n\n":h2('Ответы');
1048: $sth=SelectQuestions($dbh,\@Questions,0);
1049: for ($i = 0; $i <= $#Questions; $i++) {
1050: # fetchquestion($sth,\%q,0);
1051: # $output .=
1052: # &PrintQuestion($dbh, \%q, -1, $i + 1, 0, $text,1);
1053: $output.=$text?("Ответ ". ($i+1).": $answers[$i]\n\n"):
1054: b("Ответ ". ($i+1).": "). $answers[$i].p;
1055: }
1056: }
1057:
1058: return $output;
1059: }
1060:
1061: sub PrintEditor {
1062: my $t=shift; #ссылка на Хэш с полями
1063: my $ed=$$t{'Editors'}||'';
1064: my $edname=($ed=~/\,/ ) ? "Редакторы" : "Редактор" ;
1065: return $ed? h4({align=>"center"},"$edname: $ed" ): '';
1066: }
1067:
1068: sub PrintTournament {
1069: my ($dbh, $Id, $answer) = @_;
1070: my (%Tournament, @Tours, $i, $list, $qnum, $imgsrc, $alt,
1071: $SingleTour);
1072: my ($output) = '';
1073:
1074: %Tournament = &GetTournament($dbh, $Id) if ($Id);
1075:
1076: my ($URL) = $Tournament{'URL'}||'';
1077: $URL=~s/http:\/znatoki\/boris\/reports\//$newsurl/ if $url=~/kulichki/ || $url=~/db.chgk.info/;
1078: $URL=~s/\/znatoki\/boris\/reports\//$newsurl/ if url=~/kulichki/ || $url=~/db.chgk.info/;
1079: my ($Info) = $Tournament{'Info'};
1080: my ($Copyright) = $Tournament{'Copyright'};
1081: my $fname=$Tournament{'FileName'};
1082: @Tours = &GetTours($dbh, $Id);
1083: $list='';
1084: my $textid;
1085: if ($Id) {
1086: for ($Tournament{'Type'}) {
1087: /Г/ && do {
1088: $output .= h2({align=>"center"},
1089: "Группа: $Tournament{'Title'} ",
1090: $Tournament{'PlayedAt'}||'') . p . "\n";
1091: last;
1092: };
1093: /Ч/ && do {
1094: return &PrintTour($dbh, $Tours[0], $answer)
1095: if ($#Tours == 0);
1096:
1097: my $title="Пакет: $Tournament{'Title'}";
1098: if ($Tournament{'PlayedAt'}) {
1099: $title .= " $Tournament{'PlayedAt'}";
1100: }
1101:
1102: $output .= h2({align=>"center"},
1103: "$title") . p . "\n";
1104: $output.=&PrintEditor(\%Tournament);
1105: last;
1106: };
1107: /Т/ && do {
1108: return &PrintTour($dbh, $Id, $answer);
1109: };
1110: }
1111: } else {
1112: my ($qnum) = GetQNum($dbh,0);
1113: my ($qnum1) = GetQNum($dbh,1);
1114: $output .= h2("База вопросов").
1115: h3("$qnum запис".&Suffix2($qnum).
1116: " (уникальных $qnum1)");
1117:
1118: # h4("<table>".
1119: # Tr(td("Из них:"), td("Вопросов ЧГК: ".countz($dbh,'Ч'))).
1120: # Tr(td(" "), td("Вопросов для брейна: ".countz($dbh,'Б'))).
1121: # Tr(td(" "), td("Вопросов для ЧГК и брейна: ".countz($dbh,'ЧБ'))).
1122: # Tr(td(" "), td("Интернет-вопросов: ".countz($dbh,'И'))).
1123: # Tr(td(" "), td("Бескрылок: ".countz($dbh,'Л'))).
1124: # Tr(td(" "),td("Заданий для Своей Игры: ".countz($dbh,'Я'))).
1125: # Tr(td(" "),td("Эрудиток: ".countz($dbh,'Э'))))."</table>"
1126: }
1127:
1128: for ($i = 0; $i <= $#Tours; $i++) {
1129: %Tournament = &GetTournament($dbh, $Tours[$i]);
1130:
1131: if ($Tournament{'Type'} =~ /Ч/) {
1132: $SingleTour = 0;
1133: my (@Tours) = &GetTours($dbh, $Tournament{'Id'});
1134: $SingleTour = 1
1135: if ($#Tours == 0);
1136: }
1137: if ($Tournament{'QuestionsNum'} > 0) {
1138: $qnum = " ($Tournament{'QuestionsNum'} вопрос" .
1139: &Suffix($Tournament{'QuestionsNum'}) . ")\n";
1140: } else {
1141: $qnum = '';
1142: }
1143: if ($Tournament{'Type'} !~ /[ТЧ]/) {
1144: $SingleTour=0;
1145: $imgsrc = "/icons/folder.gif";
1146: $alt = "[*]";
1147: } else {
1148: $imgsrc = "/icons/folder.gif";
1149: $alt = "[-]";
1150: }
1151:
1152: my $textid;
1153: if ($textid=$Tournament{'FileName'})
1154: {
1155: $textid=~s/\.txt//;
1156: }
1157: elsif ($textid=$Tournament{'Number'})
1158: {
1159: $fname=~s/\.txt//;
1160: $textid="$fname.$textid";
1161: }
1162: else {$textid=$Tournament{'Id'}};
1163:
1164:
1165: if ($SingleTour or ($Tournament{'Type'} =~ /Т/)) {
1166: $list .= dd(img({src=>$imgsrc, alt=>$alt})
1167: . " " . $Tournament{'Title'} . " " .
1168: ($Tournament{'PlayedAt'}||"") . $qnum) .
1169: dl(
1170: dd("["
1171: . a({href=>tourhref($textid,0)},
1172: "вопросы") . "] ["
1173: . a({href=>tourhref($textid,1)},
1174: "вопросы + ответы") . "]")
1175: );
1176: } else {
1177: $list .= dd(a({href=>
1178: $url . "?tour=$textid&comp=1"},
1179: img({src=>'/icons/compressed.gif', alt=>'[ZIP]', border=>1})) .
1180: " " .
1181: img({src=>$imgsrc, alt=>$alt})
1182: . " " . a({href=>tourhref($textid,0,1)},
1183: $Tournament{'Title'}. " ".
1184: ($Tournament{'PlayedAt'}||'')) . $qnum);
1185: }
1186: }
1187: $output .= dl($list);
1188:
1189: if ($URL) {
1190: if ($url=~/zaba\.ru/ && $URL=~/^\//){$URL="http://info.chgk.info$URL"}
1191: $output .=
1192: p("Дополнительная информация об этом турнире - по адресу " .
1193: a({-'href'=>$URL}, $URL));
1194: }
1195:
1196: if ($Copyright) {
1197: $output .= p("Копирайт: " . $Copyright);
1198: }
1199:
1200:
1201:
1202: if ($Info) {
1203: $output .= p($Info);
1204: }
1205: return $output;
1206: }
1207:
1208: sub Suffix {
1209: my ($qnum) = @_;
1210: my ($suffix) = 'а' if $qnum =~ /[234]$/;
1211: $suffix = '' if $qnum =~ /1$/;
1212: $suffix = 'ов' if $qnum =~ /[567890]$/ || $qnum =~ /1.$/;
1213: return $suffix;
1214: }
1215:
1216:
1217: sub Suffix1 {
1218: my ($qnum) = @_;
1219: my ($suffix) = 'я' if $qnum =~ /[234]$/;
1220: $suffix = 'е' if $qnum =~ /1$/;
1221: $suffix = 'й' if $qnum =~ /[567890]$/ || $qnum =~ /1.$/;
1222: return $suffix;
1223: }
1224:
1225: sub Suffix2 {
1226: my ($qnum) = @_;
1227: my ($suffix) = 'и' if $qnum =~ /[234]$/;
1228: $suffix = 'ь' if $qnum =~ /1$/;
1229: $suffix = 'ей' if $qnum =~ /[567890]$/ || $qnum =~ /1.$/;
1230: return $suffix;
1231: }
1232:
1233: sub IsTour {
1234: my ($dbh, $Id,$n) = @_;
1235:
1236: my ($sth) ;
1237:
1238: if (defined $n)
1239: { $sth=$dbh->prepare ("select Id FROM Tournaments
1240: WHERE ParentId=$Id AND Number=$n");
1241: }
1242: else
1243: {
1244: $sth=$dbh->prepare("SELECT Id FROM Tournaments
1245: WHERE Id=$Id");
1246: }
1247: $sth->execute;
1248: my $a=($sth->fetchrow)[0];
1249: $sth->finish;
1250: return $a;
1251: }
1252:
1253: # Gets a DB handler (ofcourse) and a tour Id. Prints all the
1254: # question of that tour, according to the options.
1255: sub PrintTour {
1256: my ($dbh, $Id, $answer) = @_;
1257: my ($output, $q, $bottom, $field) = ('', 0, '', '');
1258:
1259: my (%Tour) = &GetTournament($dbh, $Id);
1260: my (@Tours) = &GetTours($dbh, $Tour{'ParentId'});
1261: my (%Tournament) = &GetTournament($dbh, $Tour{'ParentId'});
1262: my %q;
1263:
1264: return 0
1265: if ($Tour{'Type'} !~ /Т/);
1266:
1267: my ($fname)=$Tournament{'FileName'};
1268: $fname=~s/\.txt//;
1269: my ($qnum) = $Tour{'QuestionsNum'};
1270: my ($suffix) = &Suffix($qnum);
1271:
1272: $output .= h2({align=>"center"}, $Tournament{"Title"},
1273: $Tournament{'PlayedAt'}||'',
1274: "<br>", $Tour{"Title"} .
1275: " ($qnum вопрос$suffix)\n") . p;
1276: $output .=&PrintEditor(\%Tour);
1277:
1278: my (@Questions) = &GetTourQuestions($dbh, $Id);
1279: my $sth=SelectQuestions($dbh,\@Questions,0);
1280: for ($q = 0; $q <= $#Questions; $q++) {
1281: fetchquestion($sth,\%q,0);
1282: $output .= &PrintQuestion($dbh, \%q, $answer, 0,0,$text,1);
1283: }
1284: $sth->finish;
1285: $output .= hr({-'align'=>'center', -'width'=>'80%'});
1286:
1287: if ($Tournament{'URL'}) {
1288: $output .=
1289: p("Дополнительная информация об этом турнире - по адресу " .
1290: a({-'href'=>$Tournament{'URL'}}, $Tournament{'URL'}));
1291: }
1292:
1293: if ($Tournament{'Copyright'}) {
1294: $output .= p("Копирайт: " . $Tournament{'Copyright'});
1295: }
1296:
1297: if ($Tournament{'Info'}) {
1298: $output .= p($Tournament{'Info'});
1299: }
1300:
1301: my $n=$Tour{'Number'};
1302: if ($answer == 0) {
1303: my $nn=".$n";
1304: $nn="" if ($n==1 && !&IsTour($dbh, $Tour{'ParentId'}, $n + 1));
1305:
1306: $bottom .=
1307: "[" . a({href=>tourhref("$fname$nn",1)},
1308: "ответы") . "] " . br;
1309: }
1310: if ($n>1) {
1311: $bottom .=
1312: "[" . a({href=>tourhref("$fname.".($n-1),0)},
1313: "предыдущий тур") . "] ";
1314: $bottom .=
1315: "[" . a({href=>tourhref("$fname.".($n-1),1)},
1316: "предыдущий тур с ответами") . "] " . br;
1317: }
1318: if (&IsTour($dbh, $Tour{'ParentId'}, $n + 1)) {
1319: $bottom .=
1320: "[" . a({href=>tourhref("$fname.".($n+1),0)},
1321: "следующий тур") . "] ";
1322: $bottom .=
1323: "[" . a({href=>tourhref("$fname.".($n+1),1)},
1324: "следующий тур с ответами") . "] ";
1325: }
1326:
1327: $output .=
1328: p({align=>"center"}, font({size=>-1}, $bottom));
1329:
1330: return $output;
1331: }
1332:
1333: sub PrintField {
1334: my ($header, $value, $text) = @_;
1335: if ($text) {
1336: $value =~ s/<[\/\w]*?>//sg;
1337: } else {
1338: if ($header=~/Комментар/)
1339: {
1340: $value=~s/^\s*$_[\.:]/p."\n".strong("$_").":"/me foreach @softfields;
1341: }
1342:
1343: $value =~ s/^\s+/<br> /mg;
1344: $value =~ s/(\s+)-+(\s+)/$1–$2/mg;
1345: $value =~ s/\s+\–/ \–/mg
1346: if $value !~ /^\|/;
1347: $value =~ s/^\|([^\n]*)/<pre>$1<\/pre>/mg;
1348: $value =~ s/(http:\/\/\S+[^\s\)\(\,\.])/<a href="$1">$1<\/a>/g if $header !~ /^Авто/;
1349: # $value =~ s/(http:\/\/(?:\w+.)+[\w\\\~]+(\?[^\s.]+)?)/<a href="$1">$1<\/a>/g if $header !~ /^Авто/;
1350: # $value =~ s/(\s)"/$1“/mg;
1351: # $value =~ s/^"/“/mg;
1352: # $value =~ s/"/”/mg;
1353: }
1354:
1355: if ($value=~/^\s*(<p.*?>)?\s*<strong/) {
1356: return $text ? "$value\n\n" :
1357: $value . p . "\n";
1358: }
1359: return $text ? "$header:\n$value\n\n" :
1360: strong("$header: ") . $value . p . "\n";
1361: }
1362:
1363: # Gets a DB handler (ofcourse) and a question Id. Prints
1364: # that question, according to the options.
1365: sub PrintQuestion {
1366: my ($dbh, $Id, $answer, $qnum, $title, $text,$h) = @_;
1367: my ($output, $titles) = ('', '');
1368: my $fname;
1369: my (%Question);
1370: if ($h) {
1371: %Question=%$Id;
1372: } else {
1373: %Question = &GetQuestion($dbh, $Id);
1374: if ($title) {
1375: my (%Tour) = GetTournament($dbh, $Question{'ParentId'});
1376: my (%Tournament) = GetTournament($dbh, $Tour{'ParentId'});
1377: $Question{'FileName'}=$Tournament{'FileName'};
1378: $Question{'Title'}=$Tournament{'Title'};
1379: $Question{'PlayedAt'}=$Tournament{'PlayedAt'};
1380: $Question{'TourNumber'}=$Tour{'Number'};
1381: $Question{'TourTitle'}=$Tour{'Title'};
1382: }
1383:
1384: }
1385: $qnum = $Question{'Number'}
1386: if ($qnum == 0);
1387: if (!$text) {
1388: $output .= hr({width=>"50%"}) if $answer>=0;
1389: if ($title) {
1390: $fname=$Question{'FileName'};
1391: $fname=~s/\.txt//;
1392: $titles .=
1393: dd(img({src=>"/icons/folder.open.gif"}) . " " .
1394: a({href=>tourhref($fname,0,1)},
1395: $Question{'Title'}, $Question{'PlayedAt'}||''));
1396: $titles .=
1397: dl(dd(img({src=>"/icons/folder.open.gif"}) . " " .
1398: a({href=>tourhref("$fname.$Question{'TourNumber'}#$qnum",1)},
1399: $Question{'TourTitle'})));
1400: }
1401: $output .= dl(strong($titles));
1402: }
1403:
1404:
1405: $output.= "<a NAME=\"$qnum\">" unless $text;
1406:
1407: if ($answer>=0) {$output .=
1408: &PrintField("Вопрос $qnum", $Question{'Question'}, $text);}
1409: else {$output .="$qnum. "}
1410: if ($answer==1|| $answer==-1) {
1411: $output .=
1412: &PrintField("Ответ", $Question{'Answer'}, $text);
1413: if ($Question{'PassCriteria'} ) {
1414: $output .=
1415: &PrintField("Зачёт", $Question{'PassCriteria'}, $text);
1416: }
1417:
1418: if ($Question{'Authors'} ) {
1419: my $q=$Question{'Authors'};
1420: ###АВТОРА!!
1421: # my $sth=$dbh->prepare("select Authors.CharId,Name, Surname, Nicks from Authors, A2Q
1422: # where Authors.Id=Author And Question=$Id");
1423: # $sth->execute;
1424: # my ($AuthorId,$Name, $Surname,$other,$Nicks);
1425: # if (!$text) {
1426: # while ((($AuthorId,$Name, $Surname,$Nicks)=$sth->fetchrow),$AuthorId)
1427: # {
1428: # my ($firstletter)=$Name=~m/^./g;
1429: # $Name=~s/\./\\\./g;
1430: # $Name=~s/ё/[её]/g;
1431: # $Surname=~s/ё/[её]/g;
1432: # my $sha="(?:$Name\\s+$Surname)|(?:$Surname\\s+$Name)|(?:$firstletter\\.\\s*$Surname)|(?:$Surname\\s+$firstletter\\.)|(?:$Surname)";
1433: # if ($Nicks)
1434: # {
1435: # $Nicks=~s/^\|//;
1436: # foreach (split /\|/, $Nicks)
1437: # {
1438: # s/\s+/ /g;
1439: # s/\s+$//;
1440: # s/ /\\s+/g;
1441: # s/\./\\\./g;
1442: # if (s/>$//) {$sha="$sha|(?:$_)"}
1443: # else {$sha="(?:$_)|$sha"}
1444: # }
1445: # }
1446: # $q=~s/($sha)/a({href=>url."?qofauthor=$AuthorId"},$1)/ei;
1447: # unless ($1)
1448: # {
1449: # $q=~s/$Name/a({href=>url."?qofauthor=$AuthorId"},$1)/ei;
1450: # }
1451: # }
1452: # }
1453: $output .= &PrintField("Автор(ы)", $q, $text);
1454:
1455: }
1456:
1457: if ($Question{'Sources'}) {
1458: $output .= &PrintField("Источник(и)", $Question{'Sources'}, $text);
1459: }
1460:
1461: if ($Question{'Comments'}) {
1462: $output .= &PrintField("Комментарии", $Question{'Comments'}, $text);
1463: }
1464: }
1465: elsif ($answer==2) {
1466: my $text=$Question{'Answer'};
1467: $text=~s/\n/<option>/mg;
1468: $output.="<select><option selected>Ответ:<option>$text</select>";
1469: $text=$Question{'Comments'}||'';
1470: if ($text) {
1471: $text=~s/\n/<option>/mg;
1472: $output.="<select><option selected>Комментарий:<option>$text</select>"
1473: }
1474: }
1475: elsif ($answer==3) {
1476: $output.= <<EOTT
1477: <div align=right STYLE="cursor:hand;" OnStart="toggle(document.all.HideShow$qnum);" OnClick="toggle(document.all.HideShow$qnum);">
1478: <font size=-2 color=red> Показать/убрать ответ</font></div>
1479: <span style="display:none" id=HideShow$qnum>
1480: EOTT
1481: .&PrintField("Ответ", $Question{'Answer'}, $text);
1482: if ($Question{'Authors'}) {
1483: $output .= &PrintField("Автор(ы)", $Question{'Authors'}, $text);
1484: }
1485: if ($Question{'PassCriteria'}) {
1486: $output .= &PrintField("Зачёт", $Question{'PassCriteria'}, $text);
1487: }
1488:
1489: if ($Question{'Sources'}) {
1490: $output .= &PrintField("Источник(и)", $Question{'Sources'}, $text);
1491: }
1492:
1493: if ($Question{'Comments'}) {
1494: $output .= &PrintField("Комментарии", $Question{'Comments'}, $text);
1495: }
1496:
1497:
1498:
1499: $output.="</span>"
1500:
1501: }
1502: $output=~s/\(pic: ([^\)]*)\)/<p><img src="\/znatoki\/images\/db\/$1"><p>/g unless $text;
1503: $output=~s/⌡/\ï/g;
1504: $output=~s/⌠/\Ï/g;
1505:
1506: $paramtour||=param("tour");
1507: $fname=$fname.".$Question{'TourNumber'}" if $fname && $Question{'TourNumber'};
1508: $fname||=param('tour');
1509: my $qid=$fname ? ($fname.".$Question{'Number'}" ): '';
1510:
1511: $output.=br.a({href=> "/search/"."?metod=proxy&
1512: qid=$qid"}, 'Близкие вопросы').p
1513: if $answer>0 && !$text && $qid && $showNearQuestions;
1514: return $output;
1515: }
1516:
1517: # Returns the total number of questions currently in the DB.
1518: sub GetQNum {
1519: my ($dbh,$x) = @_;
1520: my ($sth) = $dbh->prepare("SELECT COUNT(*) FROM Questions");
1521: $sth->execute;
1522: my $tmp=($sth->fetchrow)[0];
1523: $sth->finish;
1524: ($sth)= $dbh -> prepare("select distinct count(first) FROM equalto");
1525: $sth -> execute;
1526: my ($c)=$sth->fetchrow;
1527:
1528: # $i++ while ( my ($first, $second)=$sth -> fetchrow)
1529: # {
1530: # $forbidden{$first}=1;
1531: # }
1532: $sth->finish;
1533:
1534: return $tmp-($x?$c:0);
1535: }
1536: sub GetMaxQId {
1537: my ($dbh) = @_;
1538: my ($sth) = $dbh->prepare("SELECT MAX(QuestionId) FROM Questions");
1539: $sth->execute;
1540: my $tmp=($sth->fetchrow)[0];
1541: $sth->finish;
1542: return $tmp;
1543:
1544: }
1545:
1546: # Returns Id's of 12 random questions
1547: sub Get12Random {
1548: my ($dbh, $type, $num) = @_;
1549: my ($i, @questions, $q, $t, $sth);
1550: my ($qnum) = &GetMaxQId($dbh);
1551: my (%chosen);
1552: srand;
1553: my $where=0;
1554: my $r=int (rand(10000));
1555: my $w1=$r<5000? "QuestionId<50000 ":"QuestionId>=50000";
1556: $w1=1 if $url=~/zaba/;
1557: $w1=1 if $type!~/Ч/;
1558: foreach (split '', $type)
1559: {
1560: $where.= " OR (Type ='$_') OR (Type ='$_Д') ";
1561: }
1562: $where.= "OR (Type='ЧБ')" if ($type=~/Ч|Б/);
1563:
1564: # $q="select QuestionId, QuestionId/$r-floor(QuestionId/$r) as val
1565: # from Questions where $where order by val limit $num";
1566: # Когда на куличках появится mysql >=3.23 надо заменить на order by rand();
1567: $q="select QuestionId from Questions where ($w1) AND ($where) order by rand() limit $num";
1568:
1569:
1570: $sth=$dbh->prepare($q);
1571: $sth->execute;
1572: while (($i)=$sth->fetchrow)
1573: {
1574: push @questions,$i;
1575: }
1576: $sth->finish;
1577: for ($i=@questions; --$i;){
1578: my $j=rand ($i+1);
1579: @questions[$i,$j]=@questions[$j,$i] unless $i==$j;
1580: }
1581: return @questions;
1582: }
1583:
1584: sub Include_virtual {
1585: my ($fn, $output) = (@_, '');
1586: return "\n<!--#include virtual=\"$fn\"-->\n" if ($opt_z);
1587: open F , $fn
1588: or return ""; #die "Can't open the file $fn: $!\n";
1589:
1590: while (<F>) {
1591: if (/<!--#include/o) {
1592: s/<!--#include virtual="\/?([^\/].*)" -->/&Include_virtual($1)/e;
1593: }
1594: if (/<!--#exec/o) {
1595: s/<!--#exec.*cmd\s*=\s*"([^"]*)".*-->/`$1`/e;
1596: }
1597: $output .= $_;
1598: }
1599: return $output||"";
1600: }
1601:
1602: sub PrintArchive {
1603: my($dbh, $Id) = @_;
1604: my ($output, @list, $i);
1605:
1606: my (%Tournament) = &GetTournament($dbh, $Id);
1607: my (@Tours) = &GetTours($dbh, $Id);
1608: if ($Tournament{'Type'} =~ /Г/ || $Id == 0) {
1609: for ($i = 0; $i <= $#Tours; $i++) {
1610: push(@list ,&PrintArchive($dbh, $Tours[$i]));
1611: }
1612: return @list;
1613: }
1614: # return "$SRCPATH/$Tournament{'FileName'} ";
1615: return "$TMPDIR/$Tournament{'FileName'} ";
1616: }
1617:
1618: sub PrintAll {
1619: my ($dbh, $Id,$fname) = @_;
1620: my ($output, $list, $i);
1621:
1622: my (%Tournament) = &GetTournament($dbh, $Id);
1623: my (@Tours) = &GetTours($dbh, $Id);
1624: my $SingleTour = $#Tours == 0;
1625:
1626: my ($New) = ($Id and $Tournament{'Type'} eq 'Ч' and
1627: &NewEnough($Tournament{"CreatedAt"})) ?
1628: img({src=>"/znatoki/dimrub/db/new-sml.gif", alt=>"NEW!"}) : "";
1629:
1630: if ($Id == 0) {
1631: $output = h3("Все турниры");
1632: } else {
1633: my $textid;
1634: if ($textid=$Tournament{'FileName'})
1635: {
1636: $textid=~s/\.txt//;
1637: }
1638: elsif ($textid=$Tournament{'Number'})
1639: {
1640: $fname=~s/\.txt//;
1641: $textid="$fname.$textid";
1642: }
1643: else {$textid=$Tournament{'Id'}};
1644:
1645:
1646: $output .= dd(img({src=>"/icons/folder.gif", alt=>"[*]"}) .
1647: " " . a({href=>tourhref($textid,0,!$SingleTour)},
1648: $Tournament{'Title'}) ." " . ($Tournament{'PlayedAt'}||'') . " $New");
1649: }
1650: if ($Id == 0 or $Tournament{'Type'} =~ /Г/ or $Tournament{'Type'} eq '') {
1651: for ($i = 0; $i <= $#Tours; $i++) {
1652: $list .= &PrintAll($dbh, $Tours[$i],$Tournament{'FileName'});
1653: }
1654: $output .= dl($list);
1655: }
1656: return $output;
1657: }
1658:
1659: sub PrintDates {
1660: my ($dbh) = @_;
1661: my ($from) = param('from_year') . "-" . param('from_month') .
1662: "-" . param('from_day');
1663: my ($to) = param('to_year') . "-" . param('to_month') . "-" . param('to_day');
1664: $from = $dbh->quote($from);
1665: $to = $dbh->quote($to);
1666: my ($sth) = $dbh->prepare("
1667: SELECT DISTINCT Id
1668: FROM Tournaments
1669: WHERE PlayedAt >= $from AND PlayedAt <= $to
1670: AND Type = 'Ч'
1671: ");
1672: $sth->execute;
1673: my (%Tournament, @array, $output, $list);
1674:
1675: $output = h3("Список турниров, проходивших между $from и $to.");
1676: while (@array = $sth->fetchrow) {
1677: next
1678: if (!$array[0]);
1679: %Tournament = &GetTournament($dbh, $array[0]);
1680: my $textid;
1681: if ($textid=$Tournament{'FileName'})
1682: {
1683: $textid=~s/\.txt//;
1684: }
1685: elsif ($textid=$Tournament{'Number'})
1686: {
1687: $fname=~s/\.txt//;
1688: $textid="$fname.$textid";
1689: }
1690: else {$textid=$Tournament{'Id'}};
1691: $list .= dd(img({src=>"/icons/folder.gif", alt=>"[*]"}) .
1692: " " . a({href=>tourhref($textid,0,1)},
1693: $Tournament{'Title'}, $Tournament{'PlayedAt'}||''));
1694: }
1695: $sth->finish;
1696: $output .= dl($list);
1697: return $output;
1698: }
1699:
1700: sub PrintQOfAuthor
1701: {
1702:
1703: my ($dbh, $id) = @_;
1704: my $Output='';
1705: unless ($id=~/^\d+$/) {
1706: $id=$dbh->quote($id);
1707: my $sth = $dbh->prepare("SELECT Id FROM Authors WHERE CharId=$id");
1708: $sth->execute;
1709: ($id)=$sth->fetchrow;
1710: $sth->finish;
1711: }
1712: $id=$dbh->quote($id);
1713:
1714: my $sth = $dbh->prepare("SELECT Name, Surname FROM Authors WHERE Id=$id");
1715: $sth->execute;
1716: my ($name,$surname)=$sth->fetchrow;
1717:
1718: $sth = $dbh->prepare("SELECT Question FROM A2Q WHERE Author=$id");
1719: $sth->execute;
1720: my $q;
1721: my @Questions;
1722: while (($q)=$sth->fetchrow,$q)
1723: {push @Questions,$q unless $forbidden{$q}}
1724: $sth->finish;
1725:
1726: my ($output, $i, $suffix, $hits) = ('', 0, '', $#Questions + 1);
1727:
1728: if ($hits =~ /1.$/ || $hits =~ /[5-90]$/) {
1729: $suffix = 'й';
1730: } elsif ($hits =~ /1$/) {
1731: $suffix = 'е';
1732: } else {
1733: $suffix = 'я';
1734: }
1735: $Output.= printform;
1736: $Output.= p({align=>"center"}, "Автор ".strong("$name $surname ")
1737: . " : $hits попадани$suffix.");
1738:
1739:
1740: # for ($i = 0; $i <= $#Questions; $i++) {
1741: # $output = &PrintQuestion($dbh, $Questions[$i], 1, $i + 1, 1);
1742: # print $output;
1743: # }
1744: $Output.=PrintList($dbh,\@Questions,'gdfgdfgdfgdfg');
1745: }
1746:
1747:
1748: sub PrintAuthors
1749: {
1750: my ($dbh,$sort)=@_;
1751: my($output,$out1,@array,$sth);
1752: if ($sort eq 'surname')
1753: {
1754: $sth =
1755: $dbh->prepare("SELECT Id, Name, Surname, QNumber FROM Authors order by Surname, Name");
1756: }
1757: elsif($sort eq 'name')
1758: {
1759: $sth =
1760: $dbh->prepare("SELECT Id, Name, Surname, QNumber FROM Authors order by Name, Surname");
1761: }
1762: else
1763: {
1764: $sth =
1765: $dbh->prepare("SELECT Id, Name, Surname, QNumber FROM Authors Order by QNumber DESC, Surname");
1766: }
1767:
1768: $output.=h2("Авторы вопросов")."\n";
1769: $output.="<TABLE>";
1770:
1771:
1772: $sth->execute;
1773: $output.=Tr(th[a({href=>$url."?authors=name"},"Имя")
1774: .", ".
1775: a({href=>$url."?authors=surname"},"фамилия")
1776: , a({href=>$url."?authors=kvo"},"Количество вопросов")]);
1777:
1778: $out1='';
1779:
1780: my $ar=$sth->fetchall_arrayref;
1781:
1782: $sth->finish;
1783:
1784:
1785: foreach my $arr(@$ar)
1786: {
1787:
1788: my ($id,$name,$surname,$kvo)=@$arr;
1789: if (!$name || !$surname) {
1790: } else
1791: {
1792: my $add=Tr(td([a({href=>$url."?qofauthor=$id"},"$name $surname"), $kvo]))."\n";
1793: $output.=$add;
1794: }
1795: }
1796: $output.="</TABLE>";
1797: $sth->finish;
1798: return $output;
1799: }
1800:
1801:
1802: sub WriteFile {
1803: my ($dbh,$fname) = @_;
1804: $fname=~s/\s+$//;
1805: $fname=~s/^\s+//;
1806: $fname=~s/\.txt$//;
1807: $fname=~s/.*\/(\w+)/$1/;
1808:
1809: my $query= "SELECT Id, Title, Copyright, Info, URL,
1810: Editors, EnteredBy, PlayedAt, CreatedAt
1811: from Tournaments where FileName=
1812: '$fname' OR FileName=".$dbh->quote("$fname.txt");
1813: my $sth=$dbh->prepare($query);
1814: my (%Question,%editor,%qnumber,%copyright,%author,%vid,%tourtitle);
1815: $sth->execute;
1816: my ($Id, $Title, $Copyright, $Info, $URL,
1817: $Editors, $EnteredBy, $PlayedAt, $CreatedAt)=
1818: $sth->fetchrow;
1819: return -1 unless $Id;
1820: open (OUT, ">$TMPDIR/$fname.txt") || print STDERR "Error in $fname.txt\n";
1821: print OUT "Чемпионат:\n$Title\n\n";
1822: my $date=$PlayedAt||'00-00-00';
1823: my ($year,$month,$day)=split /-/, $date;
1824: # $month=0,$date=0 if $year && $month==1 && $day==1;
1825: my $pdate=sprintf("%02d-%3s-%4d",$day,$months[$month],$year);
1826:
1827: print OUT "Дата:\n$pdate\n\n" if $date;
1828:
1829: print OUT "URL:\n$URL\n\n" if $URL;
1830:
1831: print OUT "Инфо:\n$Info\n\n" if $Info;
1832:
1833: print OUT "Копирайт:\n$Copyright\n\n" if $Copyright;
1834:
1835: print OUT "Редактор:\n$Editors\n\n" if $Editors;
1836:
1837:
1838: $query= "SELECT Id, Title, Copyright, Editors from Tournaments where ParentId=$Id order by Id";
1839: $sth=$dbh->prepare($query);
1840: $sth->execute;
1841: my ($tourid,$tourtitle,$cright,$editor,@tours,$vid,$author,$tourauthor);
1842:
1843:
1844: while (($tourid,$tourtitle,$cright,$editor)=$sth->fetchrow,$tourid)
1845: {
1846: # $text{$tourid}="Тур:\n$tourtitle\n\n";
1847: $query= "SELECT * from Questions where ParentId=$tourid order by QuestionId";
1848: my $sth1=$dbh->prepare($query);
1849: $sth1->execute;
1850: push(@tours,$tourid);
1851: $tourtitle{$tourid}=$tourtitle;
1852: $copyright{$tourid}=$cright;
1853: $editor{$tourid}=$editor;
1854: $vid='';
1855: my $author='';
1856: my $eqauthor=1;
1857: my $qnumber=0;
1858: my @arr;
1859: while ( (@arr=$sth1->fetchrow), $arr[0])
1860: {
1861: my($i, $name);
1862: $i=0;
1863: $qnumber++;
1864: foreach $name (@{$sth1->{NAME}}) {
1865: if ($arr[$i]) {
1866: $arr[$i]=~s/^(.*?)\s*$/$1/;
1867: $Question{$tourid}[$qnumber]{$name} = $arr[$i];
1868: } else {
1869: $Question{$tourid}[$qnumber]{$name} =
1870: ''}
1871: $i++;
1872: }
1873: if ($vid)
1874: {
1875: if ($vid ne $Question{$tourid}[$qnumber]{'Type'}) {print STDERR "Warning: Different types for Tournament $tourid\n"}
1876: } else
1877: {
1878: $vid=$Question{$tourid}[$qnumber]{'Type'};
1879: }
1880:
1881: if ($author)
1882: {
1883: if ($author ne $Question{$tourid}[$qnumber]{'Authors'})
1884: {
1885: $eqauthor=0;
1886: }
1887: } else
1888: {
1889: $author=$Question{$tourid}[$qnumber]{'Authors'};
1890: $eqauthor=0 unless $author;
1891: }
1892: }
1893: $vid{$tourid}=$vid;
1894: $qnumber{$tourid}=$qnumber;
1895: $author{$tourid}=$eqauthor ? $author : '';
1896: }
1897:
1898:
1899: $vid='';
1900: my $eqvid=1;
1901: my $eqauthor=1;
1902: foreach (@tours)
1903: {
1904: $vid||=$vid{$_};
1905: if ($vid{$_} ne $vid)
1906: {
1907: $eqvid=0;
1908: }
1909: $author||=$author{$_};
1910: if (!$author{$_} || ($author{$_} ne $author))
1911: {
1912: $eqauthor=0;
1913: }
1914: }
1915:
1916: print OUT "Вид:\n$vid\n\n" if $eqvid;
1917: print OUT "Автор:\n$author\n\n" if $eqauthor;
1918:
1919: foreach my $tour(@tours)
1920: {
1921: print OUT "Тур:\n$tourtitle{$tour}\n\n";
1922: print OUT "Вид:\n$vid{$tour}\n\n" if !$eqvid;
1923: print OUT "Копирайт:\n$copyright{$tour}\n\n" if $copyright{$tour} && ($copyright{$tour} ne $Copyright);
1924: print OUT "Редактор:\n$editor{$tour}\n\n" if $editor{$tour} && ($editor{$tour} ne $Editors);
1925: $tourauthor=0;
1926: if (!$eqauthor && $author{$tour})
1927: {
1928: print OUT "Автор:\n$author{$tour}\n\n";
1929: $tourauthor=1;
1930: }
1931: foreach my $q(1..$qnumber{$tour})
1932: {
1933: print OUT "Вопрос $q:\n".$Question{$tour}[$q]{'Question'}."\n\n";
1934: print OUT "Ответ:\n".$Question{$tour}[$q]{'Answer'}."\n\n";
1935: print OUT "Зачёт:\n".$Question{$tour}[$q]{'PassCriteria'}."\n\n";
1936: print OUT "Автор:\n".$Question{$tour}[$q]{'Authors'}."\n\n"
1937: if !$tourauthor && !$eqauthor && $Question{$tour}[$q]{'Authors'};
1938: print OUT "Комментарий:\n".$Question{$tour}[$q]{'Comments'}."\n\n"
1939: if $Question{$tour}[$q]{'Comments'};
1940: print OUT "Источник:\n".$Question{$tour}[$q]{'Sources'}."\n\n"
1941: if $Question{$tour}[$q]{'Sources'};
1942: print OUT "Рейтинг:\n".$Question{$tour}[$q]{'Rating'}."\n\n"
1943: if $Question{$tour}[$q]{'Rating'};
1944:
1945: }
1946: }
1947:
1948: close OUT;
1949:
1950:
1951:
1952: }
1953:
1954: sub Bottom
1955: {
1956: my $output.=&Include_virtual("$footer")||"";
1957: $output.=p."<center><font size=-2>Обновление: ".&Include_virtual("$datefooter")."</center></font>";
1958: $output.=<<EEE
1959: <SCRIPT LANGUAGE="JavaScript">
1960: function toggle(e) {
1961: if (e.style.display == "none") {
1962: e.style.display="";
1963: } else {
1964: e.style.display = "none";
1965: }
1966: }
1967: </SCRIPT>
1968: EEE
1969: ;
1970: $output.=end_html;
1971: return $output;
1972: }
1973:
1974:
1975: MAIN:
1976: {
1977:
1978: setlocale(LC_CTYPE,'russian');
1979: POSIX::setlocale( &POSIX::LC_ALL, $thislocale );
1980: my($i, $tour);
1981: my($text) = (param('text')) ? 1 : 0;
1982: $tour = (param('tour')) ? param('tour') : 0;
1983: my $texttour=$tour;
1984: my ($sth,$dbh);
1985: my($dsn) = "DBI:mysql:database=$dbname;host=$dbhost";
1986: $dbh = DBI->connect($dsn, $dbuser, $dbpass)
1987: # $dbh = DBI->connect("DBI:mysql:$dbname", $username, $dbpass)
1988: or do {
1989: print header.h1("Временные проблемы") . "База вопросов временно не
1990: работает. Заходите попозже.";
1991: print &Include_virtual("$reklama") if $url!~/localhost/;
1992: print end_html;
1993: die "Can't connect to DB chgk\n";
1994: };
1995:
1996:
1997: if (param('qid') && (param('qid')=~/^\d+$/) || $tour && $tour=~/^\d+$/) {
1998: # my $destination='http://chgk.zaba.ru/search.html';
1999: # print header (-'Content-Type' => 'text/html',
2000: # -'Location:'=> 'http:\\db.chgk.info');
2001: Redirect($destination);
2002: exit
2003: }
2004:
2005: if (0 && $tour && !param('qnumber') && (!param('answers')||(param('answers')<=1)))
2006: {
2007: my $n=param('tour');
2008: $n=~s/.txt$//;
2009: my $gr=($n=~/^[A-Z]/) || (-e "$realHTMLDIR$n.html");
2010: my $destination=tourhref($tour,param('answers')||0,$gr);
2011: my $d=$destination;
2012: $d=~s/$HTMLDIR/$realHTMLDIR/;
2013: # print header.$destination;
2014: # print header."$d|".(-e "$realHTMLDIR$n.html");
2015: if (-e $d) {
2016: Redirect($destination);
2017: exit
2018: }
2019: $d=~s/\.\d+//;
2020: $destination=~s/\.\d+//;
2021: if (-e $d) {
2022: Redirect($destination);
2023: exit
2024: }
2025:
2026: }
2027:
2028: if ($tour !~ /^[0-9]*$/) {
2029: if ($tour=~/\./)
2030: {
2031: my ($fname,$n)= split /\./ , $tour;
2032:
2033: $sth = $dbh->prepare(
2034: "SELECT t2.Id FROM Tournaments as t1,
2035: Tournaments as t2
2036: WHERE (t1.FileName = '$fname.txt' OR t1.FileName='$fname')
2037: AND t1.Id=t2.ParentId AND t2.Number=$n");
2038: }
2039: else
2040: {
2041: $sth = $dbh->prepare("SELECT Id FROM Tournaments
2042: WHERE FileName = '$tour.txt' OR
2043: FileName = '$tour'");
2044: }
2045: $sth->execute;
2046: $tour = ($sth->fetchrow)[0];
2047: $sth->finish;
2048: }
2049:
2050:
2051: if ($text && !param ('comp')) {
2052: print header('text/plain');
2053: } elsif (!param('comp')) {
2054: print header(-charset =>'koi8-r')}
2055: my $sstr=param('sstr');
2056: $opt_z||=param("makehtml");
2057: if (param('qid')) {
2058: my $sth;
2059: my $qid=param('qid');
2060: # if ($qid !~ /^[0-9]+$/)
2061: {
2062: my ($fname,$t,$n)= split /\./ , $qid;
2063: $n=$t,$t='' unless $n;
2064: $t||=1;
2065: if ($t)
2066: {
2067: $sth = $dbh->prepare(
2068: "SELECT t2.Id FROM Tournaments as t1,
2069: Tournaments as t2
2070: WHERE (t1.FileName = '$fname.txt' OR t1.FileName='$fname')
2071: AND t1.Id=t2.ParentId AND t2.Number=$t");
2072: }
2073: # else
2074: # {
2075: # $sth = $dbh->prepare("SELECT Id FROM Tournaments
2076: # WHERE FileName = '$fname.txt' OR FileName = '$fname'" );
2077: # }
2078: $sth->execute;
2079: $tour = ($sth->fetchrow)[0];
2080: $sth->finish;
2081: $sth = $dbh->prepare(
2082: "SELECT QuestionId FROM
2083: Questions
2084: WHERE ParentId=$tour AND
2085: Questions.Number=$n");
2086: $sth->execute;
2087: $qid = ($sth->fetchrow)[0];
2088: my $query="SELECT Question, Answer from Questions where QuestionId=$qid";
2089: $sth=$dbh->prepare($query);
2090: $sth->execute;
2091: $sstr= join ' ',$sth->fetchrow;
2092: $sth->finish;
2093: $searchin{'Question'}=1;
2094: $searchin{'Answer'}=1;
2095: $sstr=~tr/ёЁ/еЕ/;
2096: $sstr=~s/[^йцукенгшщзхъфывапролджэячсмитьбюЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮa-zA-Z0-9]/ /gi;
2097: $proxysstr=$sstr;
2098: $proxysstr=makeproxysstr($dbh,\$proxysstr);
2099: }
2100:
2101: }
2102:
2103:
2104: if (!param('comp') and !param('sqldump') and !$text) {
2105: my $title="Результаты поиска на \"". ($proxysstr||$sstr) .'"'
2106: if ($proxysstr||$sstr);
2107: $title||="База вопросов";
2108: $globaloutput.=start_html(-"title"=>$title,
2109: -author=>'dimrub@icomverse.com',
2110: -bgcolor=>'#fff0e0',
2111: -vlink=>'#800020');#}
2112: $globaloutput.="<style>
2113: td {font-size: x-small; font-family : sans-serif}
2114: th {font-size: x-small; font-family : sans-serif}
2115: </style>\n";
2116:
2117: $globaloutput.=&Include_virtual("$reklama")||'';
2118: }
2119:
2120: if ($usehash && !$opt_z && length ($qs)<=255 && $qs !~ /(sstr)|(rand)|(comp)|(all=)/i) {
2121: my $sth=$dbh->prepare("SELECT page,times,t from hash where query=".$dbh->quote($qs));
2122: $sth->execute();
2123: my ($p,$times,$t)=$sth->fetchrow();
2124: $sth->finish;
2125: if ($p) {
2126: print ".$p";
2127: $dbh->disconnect;
2128: exit ;
2129: }
2130: }
2131:
2132:
2133:
2134:
2135: if (param('hideequal')) {
2136: my ($sth)= $dbh -> prepare("select first, second FROM equalto");
2137: $sth -> execute;
2138: while ( my ($first, $second)=$sth -> fetchrow)
2139: {
2140: $forbidden{$first}=1;
2141: }
2142: $sth->finish;
2143: }
2144:
2145:
2146:
2147: if (param('rand')) {
2148: my ($type, $qnum) = ('', 12);
2149: $type.=$TypeName{$_} foreach param('type');
2150: # $type .= 'Б' if (param('brain'));
2151: # $type .= 'Ч' if (param('chgk'));
2152: $qnum = param('qnum') if (param('qnum') =~ /^\d+$/);
2153: $qnum = 0 if (!$type);
2154: my $Email;
2155: if (($Email=param('email')) && -x $SENDMAIL &&
2156: open(F, "| $SENDMAIL $Email")) {
2157: my ($mime_type) = $text ? "plain" : "html";
2158: print F <<EOT;
2159: To: $Email
2160: From: olegstepanov\@mail.ru
2161: Subject: Sluchajnij Paket Voprosov "Chto? Gde? Kogda?"
2162: MIME-Version: 1.0
2163: Content-type: text/$mime_type; charset="koi8-r"
2164:
2165: EOT
2166: print F &PrintRandom($dbh, $type, $qnum, $text);
2167: close F;
2168: $globaloutput.= "Пакет случайно выбранных вопросов послан по адресу $Email. Нажмите
2169: на <B>Reload</B> для получения еще одного пакета";
2170: } else {
2171: $globaloutput.= &PrintRandom($dbh, $type, $qnum, $text);
2172: }
2173: }
2174: elsif (param('authors')){
2175: $globaloutput.= &PrintAuthors($dbh,param('authors'));
2176: }
2177: elsif (param('qofauthor')){
2178: $globaloutput.= &PrintQOfAuthor($dbh,param('qofauthor'));
2179: }
2180: elsif (param('sstr')||param('was')) {
2181: $globaloutput.=&PrintSearch($dbh, $sstr||' ', param('metod')||'',param('was'));
2182: $dbh->do("delete from lastqueries where
2183: (TO_DAYS(NOW()) - TO_DAYS(t) >= 2) OR
2184: (time_to_sec(now())-time_to_sec(t) >3600)") if $usewas && random(30)==0;
2185: }
2186: elsif (param('qid')) {
2187: $globaloutput.=&PrintSearch($dbh, $sstr||'', 'proxy');
2188: }
2189: elsif (param('getfile')){
2190: $globaloutput.=&writefile
2191: } elsif (param('all')) {
2192: # my $destination='http://db.chgk.info/all.html';
2193: # Redirect($destination);
2194: # exit;
2195: $globaloutput.=&PrintAll($dbh, 0);
2196: } elsif (param('from_year') && param('to_year')) {
2197: $globaloutput.=&PrintDates($dbh);
2198: } elsif (param('comp')) {
2199: print "Content-Type: application/octet-stream\n";
2200: print "Content-Type: application/force-download\n";
2201: print "Content-Type: application/download\n";
2202: print "Content-Type: application/x-zip-compressed; name=$texttour.zip\n";
2203: print "Content-Disposition: attachment; filename=$texttour.zip \n\n";
2204: $tour ||= 0;
2205: my (@files) = &PrintArchive($dbh, $tour);
2206: WriteFile($dbh,$_) foreach @files;
2207: open F, "$ZIP -j - @files |";
2208: binmode(F);
2209: binmode(STDOUT);
2210: print join "",<F>;
2211: close F;
2212: $dbh->disconnect;
2213: exit;
2214: } elsif (param('sqldump')) {
2215: print header(
2216: -'Content-Type' => 'application/x-zip-compressed; name="dump.zip"',
2217: -'Content-Disposition' => 'attachment; filename="dump.zip"'
2218: );
2219: open F, "$ZIP -j - $DUMPFILE |";
2220: print (<F>);
2221: close F;
2222: $dbh->disconnect;
2223: exit;
2224:
2225: }
2226: elsif (!$opt_z && !param("makehtml")) {
2227: my $QuestionNumber=0;
2228: my $qnum;
2229: if ($qnum=param('qnumber')){
2230: my ($sth) = $dbh->prepare("SELECT QuestionId FROM Questions
2231: WHERE ParentId=$tour AND Number=$qnum");
2232: $sth->execute;
2233: $QuestionNumber=($sth->fetchrow)[0]||0;
2234: }
2235: if ($QuestionNumber) {
2236: $globaloutput.= &PrintQuestion($dbh, $QuestionNumber, $withanswers||0, $qnum, 1,$text,0);
2237: # $dbh, $Id, $answer, $qnum, $title, $text
2238: } else {
2239: $globaloutput.=&PrintTournament($dbh, $tour, $withanswers);
2240: }
2241: }
2242: else {
2243: $opt_z=1;
2244: $url="http://db.chgk.info/cgi-bin/db.cgi";
2245: open TS, $timestamp;
2246: my $d=$dbh->quote(<TS>);
2247: close TS;
2248: open FF, ">${realHTMLDIR}index.html" or die "ERROR! - ${HTMLDIR}index.html\n";
2249: my $o=$globaloutput;
2250: $o.=&PrintTournament($dbh, 0, 0);
2251: $o.=&Bottom;
2252: print FF $o;
2253: close FF;
2254: open FF, ">${realHTMLDIR}all.html" or die "ERROR! - ${HTMLDIR}all.html\n";
2255: $o=$globaloutput;
2256: $o.=&PrintAll($dbh,0);
2257: $o.=&Bottom;
2258: print FF $o;
2259: close FF;
2260:
2261:
2262: # my ($sth) = $dbh->prepare("SELECT t1.Id, t1.FileName, t1.Type,
2263: # count(t2.Id)
2264: # FROM Tournaments as t1, Tournaments as t2
2265: # WHERE t1.CreatedAt>$d AND t2.ParentId=t1.Id GROUP BY t1.Id");
2266: my ($sth) = $dbh->prepare("SELECT t1.Id, t1.FileName, t1.Type, count(t2.Id) FROM Tournaments as t1 LEFT JOIN Tournaments as t2
2267: ON t2.ParentId=t1.id WHERE t1.CreatedAt>=$d GROUP BY t1.Id");
2268: $sth->execute;
2269: my ($Id,$fname,$type,$c);
2270: while (($Id,$fname,$type,$c)=$sth->fetchrow,$Id) {
2271: next unless $fname;
2272: print "$fname\n";
2273: $fname=~s/\.txt$//;
2274: if ($type=~/Т/ || $c<=1)
2275: {
2276: open FF, ">$realHTMLDIR$fname-q.html" or die "ERROR! - $fname-q.html\n";
2277: my $o=$globaloutput;
2278: $paramtour=$fname;
2279: $o.=&PrintTournament($dbh, $Id, 0);
2280: $o.=&Bottom;
2281: print FF $o;
2282: close FF;
2283: open FF, ">$realHTMLDIR$fname-a.html";
2284: $o=$globaloutput;
2285: $o.=&PrintTournament($dbh, $Id, 1);
2286: $o.=&Bottom;
2287: print FF $o;
2288: close FF;
2289: }
2290: else {
2291: open FF, ">$realHTMLDIR$fname.html" or die "ERROR! - $fname-q.html\n";
2292: my $o=$globaloutput;
2293: $o.=&PrintTournament($dbh, $Id, 0);
2294: $o.=&Bottom;
2295: print FF $o;
2296: close FF;
2297:
2298: }
2299: }
2300: }
2301: if (!$text) {
2302: $globaloutput.=&Bottom;
2303: }
2304: if (!$opt_z){
2305: print $globaloutput;
2306: if (($qs!~ /(rand)|(sstr)|(comp)/i) && (length $qs<=255) && $usehash) {
2307: $globaloutput= $dbh->quote($globaloutput);
2308: $dbh->do("insert into hash (query,page) values (".
2309: $dbh->quote($qs).
2310: ",$globaloutput)");
2311: }
2312: }
2313:
2314: $dbh->disconnect;
2315: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>