lilalo
diff l3-frontend @ 56:43aeb3036aaa
l3-frontend:
Наведение порядка в коде. Пока что, он ещё достаточно сырой
и некрасивый, но это всё же лучше, чем то, что было раньше.
Добавлено:
* команды, набранные с ошибками показываются зачёркнутым текстом
* в статистике подсвечиваются известные/неизвестные команды,
как раньше по тексту
* в названиях программ/скриптов пути, содержащие /etc, не отрезаются
l3-agent:
Неправильно передавался код завершения. Fixed
Код откровенно мерзкий и требует доработок
Наведение порядка в коде. Пока что, он ещё достаточно сырой
и некрасивый, но это всё же лучше, чем то, что было раньше.
Добавлено:
* команды, набранные с ошибками показываются зачёркнутым текстом
* в статистике подсвечиваются известные/неизвестные команды,
как раньше по тексту
* в названиях программ/скриптов пути, содержащие /etc, не отрезаются
l3-agent:
Неправильно передавался код завершения. Fixed
Код откровенно мерзкий и требует доработок
author | devi |
---|---|
date | Wed Dec 28 01:01:00 2005 +0200 (2005-12-28) |
parents | d3fcff5e3757 |
children | 187b6636a3be |
line diff
1.1 --- a/l3-frontend Thu Dec 22 11:56:06 2005 +0200 1.2 +++ b/l3-frontend Wed Dec 28 01:01:00 2005 +0200 1.3 @@ -25,18 +25,21 @@ 1.4 1.5 my %mywi_cache_for; # Кэш для экономии обращений к mywi 1.6 1.7 - 1.8 -sub search_buy; 1.9 sub make_comment; 1.10 sub load_command_lines_from_xml; 1.11 sub load_sessions_from_xml; 1.12 -sub print_command_lines; 1.13 sub sort_command_lines; 1.14 sub process_command_lines; 1.15 sub init_variables; 1.16 sub main; 1.17 sub collapse_list($); 1.18 1.19 +sub print_all; 1.20 +sub print_command_lines; 1.21 +sub print_stat; 1.22 +sub print_header; 1.23 +sub print_footer; 1.24 + 1.25 main(); 1.26 1.27 sub main 1.28 @@ -51,71 +54,75 @@ 1.29 load_sessions_from_xml($Config{"backend_datafile"}); 1.30 sort_command_lines; 1.31 process_command_lines; 1.32 - print_command_lines($Config{"output"}); 1.33 + print_all($Config{"output"}); 1.34 close_mywi_socket; 1.35 } 1.36 1.37 +# extract_from_cline 1.38 1.39 -sub search_by 1.40 -{ 1.41 - my $sm = shift; 1.42 - my $topic = shift; 1.43 - $topic =~ s/ /+/; 1.44 - 1.45 - return "<a href='". $Search_Machines{$sm}->{"query"}."$topic'><img width='16' height='16' src='". 1.46 - $Search_Machines{$sm}->{"icon"}."' border='0'/></a>"; 1.47 -} 1.48 +# In: $what = commands | args 1.49 +# Out: return ссылка на хэш, содержащий результаты разбора 1.50 +# команда => позиция 1.51 1.52 -sub extract_from_cline 1.53 # Разобрать командную строку $_[1] и возвратить хэш, содержащий 1.54 # номер первого появление команды в строке: 1.55 # команда => первая позиция 1.56 +sub extract_from_cline 1.57 { 1.58 my $what = $_[0]; 1.59 my $cline = $_[1]; 1.60 my @lists = split /\;/, $cline; 1.61 1.62 1.63 - my @commands = (); 1.64 - for my $list (@lists) { 1.65 - push @commands, split /\|/, $list; 1.66 + my @command_lines = (); 1.67 + for my $command_list (@lists) { 1.68 + push(@command_lines, split(/\|/, $command_list)); 1.69 } 1.70 1.71 - my %commands; 1.72 - my %args; 1.73 + my %position_of_command; 1.74 + my %position_of_arg; 1.75 my $i=0; 1.76 - for my $command (@commands) { 1.77 - $command =~ s@^\s*\S+/@@; 1.78 - $command =~ /\s*(\S+)\s*(.*)/; 1.79 + for my $command_line (@command_lines) { 1.80 + $command_line =~ s@^\s*@@; 1.81 + $command_line =~ /\s*(\S+)\s*(.*)/; 1.82 if ($1 && $1 eq "sudo" ) { 1.83 - $commands{"$1"}=$i++; 1.84 - $command =~ s/\s*sudo\s+//; 1.85 + $position_of_command{"$1"}=$i++; 1.86 + $command_line =~ s/\s*sudo\s+//; 1.87 } 1.88 - $command =~ s@^\s*\S+/@@; 1.89 - $command =~ /\s*(\S+)\s*(.*)/; 1.90 - if ($1 && !defined $commands{"$1"}) { 1.91 - $commands{"$1"}=$i++; 1.92 + if ($command_line !~ m@^\s*\S*/etc/@) { 1.93 + $command_line =~ s@^\s*\S+/@@; 1.94 + } 1.95 + 1.96 + $command_line =~ /\s*(\S+)\s*(.*)/; 1.97 + my $command = $1; 1.98 + my $args = $2; 1.99 + if ($command && !defined $position_of_command{"$command"}) { 1.100 + $position_of_command{"$command"}=$i++; 1.101 }; 1.102 - if ($2) { 1.103 - my $args = $2; 1.104 + if ($args) { 1.105 my @args = split (/\s+/, $args); 1.106 for my $a (@args) { 1.107 - $args{"$a"}=$i++ 1.108 - if !defined $args{"$a"}; 1.109 + $position_of_arg{"$a"}=$i++ 1.110 + if !defined $position_of_arg{"$a"}; 1.111 }; 1.112 - 1.113 - 1.114 } 1.115 } 1.116 1.117 if ($what eq "commands") { 1.118 - return \%commands; 1.119 + return \%position_of_command; 1.120 } else { 1.121 - return \%args; 1.122 + return \%position_of_arg; 1.123 } 1.124 1.125 } 1.126 1.127 + 1.128 + 1.129 + 1.130 +# 1.131 +# Подпрограммы для работы с mywi 1.132 +# 1.133 + 1.134 sub open_mywi_socket 1.135 { 1.136 $Mywi_Socket = IO::Socket::INET->new( 1.137 @@ -204,6 +211,9 @@ 1.138 Процедура load_command_lines_from_xml выполняет загрузку разобранного lab-скрипта 1.139 из XML-документа в переменную @Command_Lines 1.140 1.141 +# In: $datafile имя файла 1.142 +# Out: @CommandLines загруженные командные строки 1.143 + 1.144 Предупреждение! 1.145 Процедура не в состоянии обрабатывать XML-документ любой структуры. 1.146 В действительности файл cache из которого загружаются данные 1.147 @@ -248,11 +258,12 @@ 1.148 } 1.149 1.150 1.151 +# sort_command_lines 1.152 +# In: @Command_Lines 1.153 +# Out: @Command_Lies_Index 1.154 1.155 sub sort_command_lines 1.156 { 1.157 - # Sort Command_Lines 1.158 - # Write Command_Lines to Command_Lines_Index 1.159 1.160 my @index; 1.161 for (my $i=0;$i<=$#Command_Lines;$i++) { 1.162 @@ -265,99 +276,87 @@ 1.163 1.164 } 1.165 1.166 +################## 1.167 +# process_command_lines 1.168 +# 1.169 +# Обрабатываются командные строки @Command_Lines 1.170 +# Для каждой строки определяется: 1.171 +# class класс 1.172 +# note комментарий 1.173 +# 1.174 +# In: @Command_Lines_Index 1.175 +# In-Out: @Command_Lines 1.176 + 1.177 sub process_command_lines 1.178 { 1.179 for my $i (@Command_Lines_Index) { 1.180 + my $cl = \$Command_Lines[$i]; 1.181 1.182 - my $cl = \$Command_Lines[$i]; 1.183 - #@{${$cl}->{"new_commands"}} =(); 1.184 - #@{${$cl}->{"new_files"}} =(); 1.185 - $$cl->{"class"} = ""; 1.186 + next if !$cl; 1.187 1.188 - if ($$cl->{"err"}) { 1.189 - $$cl->{"class"}="wrong"; 1.190 - $$cl->{"class"}="interrupted" 1.191 - if ($$cl->{"err"} eq 130); 1.192 - } 1.193 + $$cl->{err} ||=0; 1.194 + 1.195 + # Класс команды 1.196 + 1.197 + $$cl->{"class"} = $$cl->{"err"} eq 130 ? "interrupted" 1.198 + : $$cl->{"err"} eq 127 ? "mistyped" 1.199 + : $$cl->{"err"} ? "wrong" 1.200 + : ""; 1.201 + 1.202 if (!$$cl->{"euid"}) { 1.203 $$cl->{"class"}.="_root"; 1.204 } 1.205 - 1.206 -#tab# my @tab_words=split /\s+/, $$cl->{"output"}; 1.207 -#tab# my $last_word= $$cl->{"cline"} =~ /(\S*)$/; 1.208 -#tab# $last_word =~ s@.*/@@; 1.209 -#tab# my $this_is_tab=1; 1.210 -#tab# 1.211 -#tab# if ($last_word && @tab_words >2) { 1.212 -#tab# for my $tab_words (@tab_words) { 1.213 -#tab# if ($tab_words !~ /^$last_word/) { 1.214 -#tab# $this_is_tab=0; 1.215 -#tab# last; 1.216 -#tab# } 1.217 -#tab# } 1.218 -#tab# } 1.219 -#tab# $$cl->{"class"}="tab" if $this_is_tab; 1.220 - 1.221 1.222 -# if ( !$$cl->{"err"}) { 1.223 -# # Command does not contain mistakes 1.224 -# 1.225 -# my %commands = extract_from_cline("commands", ${$cl}->{"cline"}); 1.226 -# my %files = extract_from_cline("files", ${$cl}->{"cline"}); 1.227 -# 1.228 -# # Searching for new commands only 1.229 -# for my $command (keys %commands) { 1.230 -# if (!defined $Commands_Stat{$command}) { 1.231 -# push @{$$cl->{new_commands}}, $command; 1.232 -# } 1.233 -# $Commands_Stat{$command}++; 1.234 -# } 1.235 -# 1.236 -# for my $file (keys %files) { 1.237 -# if (!defined $Files_Stat{$file}) { 1.238 -# push @{$$cl->{new_files}}, $file; 1.239 -# } 1.240 -# $Files_Stat{$file}++; 1.241 -# } 1.242 -# } 1.243 + 1.244 +#Обработка пометок 1.245 +# Если несколько пометок (notes) идут подряд, 1.246 +# они все объединяются 1.247 1.248 if ($$cl->{cline}=~ m@cat[^#]*#([\^=v])\s*(.*)@) { 1.249 - if ($1 eq "=") { 1.250 + 1.251 + my $note_operator = $1; 1.252 + my $note_title = $2; 1.253 + 1.254 + if ($note_operator eq "=") { 1.255 $$cl->{"class"} = "note"; 1.256 $$cl->{"note"} = $$cl->{"output"}; 1.257 $$cl->{"note_title"} = $2; 1.258 } 1.259 else { 1.260 my $j = $i; 1.261 - if ($1 eq "^") { 1.262 + if ($note_operator eq "^") { 1.263 $j--; 1.264 $j-- while ($j >=0 && (!$Command_Lines[$j] || $Command_Lines[$j]->{tty} ne $$cl->{tty})); 1.265 } 1.266 - elsif ($1 eq "v") { 1.267 + elsif ($note_operator eq "v") { 1.268 $j++; 1.269 $j++ while ($j <= @Command_Lines && (!$Command_Lines[$j] || $Command_Lines[$j]->{tty} ne $$cl->{tty})); 1.270 } 1.271 - $Command_Lines[$j]->{note_title}="$2"; 1.272 - $Command_Lines[$j]->{note}=$$cl->{output}; 1.273 + $Command_Lines[$j]->{note_title}=$note_title; 1.274 + $Command_Lines[$j]->{note}.=$$cl->{output}; 1.275 $$cl=0; 1.276 } 1.277 } 1.278 elsif ($$cl->{cline}=~ /#([\^=v])(.*)/) { 1.279 - if ($1 eq "=") { 1.280 + 1.281 + my $note_operator = $1; 1.282 + my $note_text = $2; 1.283 + 1.284 + if ($note_operator eq "=") { 1.285 $$cl->{"class"} = "note"; 1.286 - $$cl->{"note"} = $2; 1.287 + $$cl->{"note"} = $note_text; 1.288 } 1.289 else { 1.290 my $j=$i; 1.291 - if ($1 eq "^") { 1.292 + if ($note_operator eq "^") { 1.293 $j--; 1.294 $j-- while ($j >=0 && (!$Command_Lines[$j] || $Command_Lines[$j]->{tty} ne $$cl->{tty})); 1.295 } 1.296 - elsif ($1 eq "v") { 1.297 + elsif ($note_operator eq "v") { 1.298 $j++; 1.299 $j++ while ($j <= @Command_Lines && $Command_Lines[$j]->{tty} ne $$cl->{tty} || !$Command_Lines[$j]); 1.300 } 1.301 - $Command_Lines[$j]->{note}.="$2\n"; 1.302 + $Command_Lines[$j]->{note}.="$note_text\n"; 1.303 $$cl=0; 1.304 } 1.305 } 1.306 @@ -375,64 +374,74 @@ 1.307 1.308 sub print_command_lines 1.309 { 1.310 - my $output_filename=$_[0]; 1.311 1.312 - my $course_name = $Config{"course-name"}; 1.313 - my $course_code = $Config{"course-code"}; 1.314 - my $course_date = $Config{"course-date"}; 1.315 - my $course_center = $Config{"course-center"}; 1.316 - my $course_trainer = $Config{"course-trainer"}; 1.317 - my $course_student = $Config{"course-student"}; 1.318 - 1.319 - 1.320 - # Результат выполнения процедуры равен 1.321 - # join("", @Result{header,body,stat,help,about,footer}) 1.322 - my %Result; 1.323 - my @toc; # Хранит оглавление 1.324 + my @toc; # Оглавление 1.325 my $note_number=0; 1.326 1.327 - $Result{"body"} = "<table width='100%'>\n"; 1.328 + my $result = q(); 1.329 + my $this_day_resut = q(); 1.330 1.331 my $cl; 1.332 my $last_tty=""; 1.333 - my $last_day=""; 1.334 + my $last_day=q(); 1.335 + my $last_wday=q(); 1.336 my $in_range=0; 1.337 1.338 my $current_command=0; 1.339 1.340 + my %filter; 1.341 + 1.342 + if ($Config{filter}) { 1.343 + # Инициализация фильтра 1.344 + my %filter; 1.345 + for (split /&/,$Config{filter}) { 1.346 + my ($var, $val) = split /=/; 1.347 + $filter{$var} = $val || ""; 1.348 + } 1.349 + } 1.350 + 1.351 + $Stat{LastCommand} ||= 0; 1.352 + $Stat{TotalCommands} ||= 0; 1.353 + $Stat{ErrorCommands} ||= 0; 1.354 + $Stat{MistypedCommands} ||= 0; 1.355 + 1.356 COMMAND_LINE: 1.357 for my $k (@Command_Lines_Index) { 1.358 1.359 my $cl=$Command_Lines[$Command_Lines_Index[$current_command++]]; 1.360 - 1.361 next unless $cl; 1.362 1.363 +# Пропускаем команды, с одинаковым временем 1.364 +# Это не совсем правильно. 1.365 +# Возможно, что это команды, набираемые с помощью <completion> 1.366 +# или запомненные с помощью <ctrl-c> 1.367 1.368 - if ($Config{filter}) { 1.369 - # Инициализация фильтра 1.370 - my %filter; 1.371 - for (split /&/,$Config{filter}) { 1.372 - my ($var, $val) = split /=/; 1.373 - $filter{$var} = $val || ""; 1.374 - } 1.375 + next if $Stat{LastCommand} == $cl->{time}; 1.376 1.377 - for my $filter_key (keys %filter) { 1.378 - next COMMAND_LINE if 1.379 - defined($cl->{local_session_id}) 1.380 - && defined($Sessions{$cl->{local_session_id}}->{$filter_key}) 1.381 - && $Sessions{$cl->{local_session_id}}->{$filter_key} ne $filter{$filter_key}; 1.382 - #print $filter_key,"\n"; 1.383 - } 1.384 +# Набираем статистику 1.385 +# Хэш %Stat 1.386 1.387 - #if ($filter{user}) { 1.388 - # next COMMAND_LINE unless $Sessions{$cl->{local_session_id}}->{user} eq $filter{user}; 1.389 - #} 1.390 + $Stat{FirstCommand} = $cl->{time} unless $Stat{FirstCommand}; 1.391 + if ($cl->{time} - $Stat{LastCommand} < $Config{stat_inactivity_interval}) { 1.392 + $Stat{TotalTime} += $cl->{time} - $Stat{LastCommand} 1.393 + } 1.394 + $Stat{LastCommand} = $cl->{time}; 1.395 + $Stat{TotalCommands}++; 1.396 1.397 - #for my $filter_field (keys %filter) { 1.398 - # next COMMAND_LINE unless $Sessions{$cl->{local_session_id}}->{$filter_field} eq $filter{$filter_field}; 1.399 - #} 1.400 +# Пропускаем строки, которые противоречат фильтру 1.401 +# Если у нас недостаточно информации о том, подходит строка под фильтр или нет, 1.402 +# мы её выводим 1.403 + 1.404 + for my $filter_key (keys %filter) { 1.405 + next COMMAND_LINE if 1.406 + defined($cl->{local_session_id}) 1.407 + && defined($Sessions{$cl->{local_session_id}}->{$filter_key}) 1.408 + && $Sessions{$cl->{local_session_id}}->{$filter_key} ne $filter{$filter_key}; 1.409 } 1.410 1.411 +# Пропускаем строки, выходящие за границу "signature", 1.412 +# при условии, что границы указаны 1.413 +# Пропускаем неправильные/прерванные/другие команды 1.414 if ($Config{"from"} && $cl->{"cline"} =~ /$Config{"signature"}\s*$Config{"from"}/) { 1.415 $in_range=1; 1.416 next; 1.417 @@ -441,25 +450,19 @@ 1.418 $in_range=0; 1.419 next; 1.420 } 1.421 - next if ($Config{"from"} && $Config{"to"} && !$in_range) 1.422 - || 1.423 - ($Config{"skip_empty"} =~ /^y/i && $cl->{"cline"} =~ /^\s*$/ ) 1.424 - || 1.425 - ($Config{"skip_wrong"} =~ /^y/i && $cl->{"err"} != 0) 1.426 - || 1.427 - ($Config{"skip_interrupted"} =~ /^y/i && $cl->{"err"} == 130); 1.428 + next if ($Config{"from"} && $Config{"to"} && !$in_range) 1.429 + || ($Config{"skip_empty"} =~ /^y/i && $cl->{"cline"} =~ /^\s*$/ ) 1.430 + || ($Config{"skip_wrong"} =~ /^y/i && $cl->{"err"} != 0) 1.431 + || ($Config{"skip_interrupted"} =~ /^y/i && $cl->{"err"} == 130); 1.432 1.433 - #my @new_commands=@{$cl->{"new_commands"}}; 1.434 - #my @new_files=@{$cl->{"new_files"}}; 1.435 - 1.436 if ($cl->{class} eq "note") { 1.437 my $note = $cl->{note}; 1.438 $note = join ("\n", map ("<p>$_</p>", split (/-\n/, $note))); 1.439 $note =~ s@(http:[a-zA-Z.0-9/?\_%-]*)@<a href='$1'>$1</a>@g; 1.440 $note =~ s@(www\.[a-zA-Z.0-9/?\_%-]*)@<a href='$1'>$1</a>@g; 1.441 - $Result{"body"} .= "<tr><td colspan='6'>"; 1.442 - $Result{"body"} .= "<h4 id='note$note_number'>".$cl->{note_title}."</h4>" if $cl->{note_title}; 1.443 - $Result{"body"} .= "".$note."<p/><p/></td></td>"; 1.444 + $result .= "<tr><td colspan='6'>"; 1.445 + $result .= "<h4 id='note$note_number'>".$cl->{note_title}."</h4>" if $cl->{note_title}; 1.446 + $result .= "".$note."<p/><p/></td></td>"; 1.447 1.448 if ($cl->{note_title}) { 1.449 push @{$toc[@toc]},"<a href='#note$note_number'>".$cl->{note_title}."</a>"; 1.450 @@ -468,192 +471,343 @@ 1.451 next; 1.452 } 1.453 1.454 - my $cl_class="cline"; 1.455 - my $out_class="output"; 1.456 - if ($cl->{"class"}) { 1.457 - $cl_class = $cl->{"class"}."_".$cl_class; 1.458 - $out_class = $cl->{"class"}."_".$out_class; 1.459 - } 1.460 - 1.461 - my @new_commands; 1.462 - my @new_files; 1.463 - @new_commands = split (/\s+/, $cl->{"new_commands"}) if defined $cl->{"new_commands"}; 1.464 - @new_files = split (/\s+/, $cl->{"new_files"}) if defined $cl->{"new_files"}; 1.465 1.466 my $output=""; 1.467 - if ($Config{"head_lines"} || $Config{"tail_lines"}) { 1.468 - # Partialy output 1.469 - my @lines = split '\n', $cl->{"output"}; 1.470 - # head 1.471 - my $mark=1; 1.472 +# Выводим <head_lines> верхних строк 1.473 +# и <tail_lines> нижних строк, 1.474 +# если эти параметры существуют 1.475 + 1.476 + my @lines = split '\n', $cl->{"output"}; 1.477 + if (($Config{"head_lines"} || $Config{"tail_lines"}) 1.478 + && $#lines > $Config{"head_lines"} + $Config{"tail_lines"} ) { 1.479 + 1.480 for (my $i=0; $i<= $#lines && $i < $Config{"head_lines"}; $i++) { 1.481 $output .= $lines[$i]."\n"; 1.482 } 1.483 - # tail 1.484 - my $start=$#lines-$Config{"tail_lines"}+1; 1.485 - if ($start < 0) { 1.486 - $start=0; 1.487 - $mark=0; 1.488 - } 1.489 - if ($start < $Config{"head_lines"}) { 1.490 - $start=$Config{"head_lines"}; 1.491 - $mark=0; 1.492 - } 1.493 - $output .= $Config{"skip_text"}."\n" if $mark; 1.494 - for ($i=$start; $i<= $#lines; $i++) { 1.495 + $output .= $Config{"skip_text"}."\n"; 1.496 + 1.497 + my $start_line=$#lines-$Config{"tail_lines"}+1; 1.498 + for ($i=$start_line; $i<= $#lines; $i++) { 1.499 $output .= $lines[$i]."\n"; 1.500 } 1.501 } 1.502 else { 1.503 - # Full output 1.504 $output .= $cl->{"output"}; 1.505 } 1.506 - #$output .= "^C\n" if ($cl->{"err"} eq "130"); 1.507 1.508 - # 1.509 - ## 1.510 - ## Начинается собственно вывод 1.511 - ## 1.512 - # 1.513 - 1.514 - # <command> 1.515 +# 1.516 +## 1.517 +## Начинается собственно вывод 1.518 +## 1.519 +# 1.520 1.521 my ($sec,$min,$hour,$day,$mon,$year,$wday,$yday,$isdst) = localtime($cl->{time}); 1.522 - next if $Stat{LastCommand} == $cl->{time}; 1.523 - $Stat{FirstCommand} = $cl->{time} unless $Stat{FirstCommand}; 1.524 - $Stat{LastCommand} = 0 unless defined $Stat{LastCommand}; 1.525 - $Stat{TotalTime} += $cl->{time} - $Stat{LastCommand} 1.526 - if $cl->{time} - $Stat{LastCommand} < $Config{stat_inactivity_interval}; 1.527 - $Stat{LastCommand} = $cl->{time}; 1.528 - $Stat{TotalCommands} = 0 unless $Stat{TotalCommands}; 1.529 - $Stat{TotalCommands}++; 1.530 1.531 # Добавляем спереди 0 для удобочитаемости 1.532 - $min = "0".$min if $min =~ /^.$/; 1.533 + $min = "0".$min if $min =~ /^.$/; 1.534 $hour = "0".$hour if $hour =~ /^.$/; 1.535 - $sec = "0".$sec if $sec =~ /^.$/; 1.536 + $sec = "0".$sec if $sec =~ /^.$/; 1.537 1.538 - $class=$cl->{"out_class"}; 1.539 - $class =~ s/output$//; 1.540 + #my @new_commands; 1.541 + #my @new_files; 1.542 + #@new_commands = split (/\s+/, $cl->{"new_commands"}) if defined $cl->{"new_commands"}; 1.543 + #@new_files = split (/\s+/, $cl->{"new_files"}) if defined $cl->{"new_files"}; 1.544 1.545 - $Stat{ErrorCommands}++ 1.546 - if $class =~ /wrong/; 1.547 + $class=$cl->{"class"}; 1.548 + $Stat{ErrorCommands}++ if $class =~ /wrong/; 1.549 + $Stat{MistypedCommands}++ if $class =~ /mistype/; 1.550 1.551 - $Result{"body"} .= "<tr class='command'>\n"; 1.552 - 1.553 1.554 - # DAY CHANGE 1.555 +# DAY CHANGE 1.556 if ( $last_day ne $day) { 1.557 - #$Result{"body"} .= "<td colspan='6'><p></p><h3>День ",$day,"</h4></td></tr><tr>"; 1.558 - $Result{"body"} .= "<td colspan='6'><p></p><h3 id='day$day'>".$Day_Name[$wday]."</h4></td></tr><tr>"; 1.559 + if ($last_day) { 1.560 + $result .= "<h3 id='day$last_day'>".$Day_Name[$last_wday]."</h3>"; 1.561 + #$result .= "Новые команды<br/>"; 1.562 + $result .= "<table width='100%'>\n"; 1.563 + $result .= $this_day_result; 1.564 + $result .= "</table>"; 1.565 + } 1.566 + 1.567 push @toc, "<a href='#day$day'>".$Day_Name[$wday]."</a>\n"; 1.568 $last_day=$day; 1.569 + $last_wday=$wday; 1.570 + $this_day_result = q(); 1.571 } 1.572 1.573 - # CONSOLE CHANGE 1.574 + $this_day_result .= "<tr class='command'>\n"; 1.575 + 1.576 + 1.577 +# CONSOLE CHANGE 1.578 if ( $last_tty ne $cl->{"tty"}) { 1.579 - my $host; 1.580 - #$host = $Sessions{$cl->{local_session_id}}->{user}."@".$Sessions{$cl->{local_session_id}}->{hostname}; 1.581 - my $body = $cl->{"tty"}; 1.582 - $body .= " \@$host" if $host; 1.583 - $Result{"body"} .= "<td colspan='6'><table><tr><td class='ttychange' width='140' align='center'>".$body."</td></tr></table></td></tr><tr>"; 1.584 + my $tty = $cl->{"tty"}; 1.585 + $this_day_result .= "<td colspan='6'>" 1.586 + ."<table><tr><td class='ttychange' width='140' align='center'>" 1.587 + . $tty 1.588 + ."</td></tr></table>" 1.589 + ."</td></tr><tr>"; 1.590 $last_tty=$cl->{"tty"}; 1.591 } 1.592 1.593 - # TIME 1.594 - if ($Config{"show_time"} =~ /^y/i) { 1.595 - $Result{"body"} .= "<td valign='top' class='time' width='$Config{time_width}'><pre>". 1.596 - $hour. ":". $min. ":". $sec. 1.597 - "</td>"; 1.598 - } else { 1.599 - $Result{"body"} .= "<td width='0'/>" 1.600 - } 1.601 +# TIME 1.602 + $this_day_result .= $Config{"show_time"} =~ /^y/i 1.603 + ? "<td valign='top' class='time' width='$Config{time_width}'>$hour:$min:$sec</td>" 1.604 + : "<td width='0'/>"; 1.605 1.606 - # COMMAND 1.607 - $Result{"body"} .= "<td class='script'>\n"; 1.608 - $Result{"body"} .= "<pre class='${class}cline'>\n"; 1.609 - my $cline = $cl->{"prompt"}.$cl->{"cline"}; 1.610 +# COMMAND 1.611 + my $hint = make_comment($cl->{"cline"}); 1.612 + 1.613 + my $cline; 1.614 + $cline = $cl->{"prompt"}.$cl->{"cline"}; 1.615 $cline =~ s/\n//; 1.616 1.617 - #$cline .= "(".$Sessions{$cl->{local_session_id}}.")"; 1.618 - 1.619 - my $hint = make_comment($cl->{"cline"}); 1.620 $cline = "<span title='$hint' class='with_hint'>$cline</span>" if $hint; 1.621 $cline = "<span class='without_hint'>$cline</span>" if !$hint; 1.622 - $Result{"body"} .= $cline; 1.623 - $Result{"body"} .= "</pre>\n"; 1.624 1.625 + $this_day_result .= "<td class='script'>\n"; 1.626 + $this_day_result .= "<pre class='${class}_cline'>\n" . $cline . "</pre>\n"; 1.627 + 1.628 +# OUTPUT 1.629 my $last_command = $cl->{"last_command"}; 1.630 if (!( 1.631 $Config{"suppress_editors"} =~ /^y/i && grep ($_ eq $last_command, @{$Config{"editors"}}) || 1.632 $Config{"suppress_pagers"} =~ /^y/i && grep ($_ eq $last_command, @{$Config{"pagers"}}) || 1.633 $Config{"suppress_terminal"}=~ /^y/i && grep ($_ eq $last_command, @{$Config{"terminal"}}) 1.634 )) { 1.635 - 1.636 - $Result{"body"} .= "<pre class='".$cl->{out_class}."'>"; 1.637 - $Result{"body"} .= $output; 1.638 - $Result{"body"} .= "</pre>\n"; 1.639 + $this_day_result .= "<pre class='".$class."_output'>" . $output . "</pre>\n"; 1.640 } 1.641 1.642 - # DIFF 1.643 +# DIFF 1.644 if ( $Config{"show_diffs"} =~ /^y/i && $cl->{"diff"}) { 1.645 - $Result{"body"} .= "<table><tr><td width='5'/><td class='diff'><pre>"; 1.646 - $Result{"body"} .= $cl->{"diff"}; 1.647 - $Result{"body"} .= "</pre></td></tr></table>"; 1.648 + $this_day_result .= "<table><tr><td width='5'/><td class='diff'><pre>" 1.649 + . $cl->{"diff"} 1.650 + . "</pre></td></tr></table>"; 1.651 } 1.652 - 1.653 - #NOTES 1.654 + 1.655 +#NOTES 1.656 if ( $Config{"show_notes"} =~ /^y/i && $cl->{"note"}) { 1.657 my $note=$cl->{"note"}; 1.658 $note =~ s/\n/<br\/>\n/msg; 1.659 if (not $note =~ s@(http:[a-zA-Z.0-9/_?%-]*)@<a href='$1'>$1</a>@g) { 1.660 - $note =~ s@(www\.[a-zA-Z.0-9/_?%-]*)@<a href='$1'>$1</a>@g; 1.661 - }; 1.662 + $note =~ s@(www\.[a-zA-Z.0-9/_?%-]*)@<a href='$1'>$1</a>@g; 1.663 + }; 1.664 # Ширину пока не используем 1.665 - # $Result{"body"} .= "<table width='$Config{note_width}' class='note'>"; 1.666 - $Result{"body"} .= "<table class='note'>"; 1.667 - $Result{"body"} .= "<tr><td class='note_title'>".$cl->{note_title}."</td></tr>" if $cl->{note_title}; 1.668 - $Result{"body"} .= "<tr><td width='100%' class='note_text'>".$note."</td></tr>"; 1.669 - $Result{"body"} .= "</table>\n"; 1.670 + # $this_day_result .= "<table width='$Config{note_width}' class='note'>"; 1.671 + $this_day_result .= "<table class='note'>"; 1.672 + $this_day_result .= "<tr><td class='note_title'>".$cl->{note_title}."</td></tr>" if $cl->{note_title}; 1.673 + $this_day_result .= "<tr><td width='100%' class='note_text'>".$note."</td></tr>"; 1.674 + $this_day_result .= "</table>\n"; 1.675 } 1.676 1.677 - # COMMENT 1.678 +# COMMENT 1.679 if ( $Config{"show_comments"} =~ /^y/i) { 1.680 my $comment = make_comment($cl->{"cline"}); 1.681 if ($comment) { 1.682 - $Result{"body"} .= "<table width='$Config{comment_width}'>". 1.683 - "<tr><td width='5'/><td>"; 1.684 - $Result{"body"} .= "<table class='note' width='100%'>"; 1.685 - $Result{"body"} .= $comment; 1.686 - $Result{"body"} .= "</table>\n"; 1.687 - $Result{"body"} .= "</td></tr></table>"; 1.688 + $this_day_result .= "<table width='$Config{comment_width}'><tr><td width='5'/><td>" 1.689 + . "<table class='note' width='100%'>" 1.690 + . $comment 1.691 + . "</table>\n" 1.692 + . "</td></tr></table>"; 1.693 } 1.694 } 1.695 1.696 # Вывод очередной команды окончен 1.697 - $Result{"body"} .= "</td>\n"; 1.698 - $Result{"body"} .= "</tr>\n"; 1.699 + $this_day_result .= "</td>\n"; 1.700 + $this_day_result .= "</tr>\n"; 1.701 } 1.702 1.703 - $Result{"body"} .= "</table>\n"; 1.704 + $result .= "<h3 id='day$last_day'>".$Day_Name[$last_wday]."</h3>"; 1.705 + $result .= "<table width='100%'>\n"; 1.706 + $result .= $this_day_result; 1.707 + $result .= "</table>"; 1.708 1.709 - #$Result{"stat"} = "<hr/>"; 1.710 + return ($result, collapse_list (\@toc)); 1.711 1.712 +} 1.713 + 1.714 + 1.715 + 1.716 + 1.717 +############# 1.718 +# print_all 1.719 +# 1.720 +# 1.721 +# 1.722 +# In: $_[0] output_filename 1.723 +# Out: 1.724 + 1.725 + 1.726 +sub print_all 1.727 +{ 1.728 + my $output_filename=$_[0]; 1.729 + 1.730 + my $result; 1.731 + my ($command_lines,$toc) = print_command_lines; 1.732 + 1.733 + $result = print_header($toc); 1.734 + $result.= "<h2 id='log'>Журнал</h2>" . $command_lines; 1.735 + $result.= "<h2 id='stat'>Статистика</h2>" . print_stat; 1.736 + $result.= "<h2 id='help'>Справка</h2>" . $Html_Help . "<br/>"; 1.737 + $result.= "<h2 id='about'>О программе</h2>". $Html_About. "<br/>"; 1.738 + $result.= print_footer; 1.739 + 1.740 + if ($output_filename eq "-") { 1.741 + print $result; 1.742 + } 1.743 + else { 1.744 + open(OUT, ">", $output_filename) 1.745 + or die "Can't open $output_filename for writing\n"; 1.746 + print OUT $result; 1.747 + close(OUT); 1.748 + } 1.749 +} 1.750 + 1.751 +############# 1.752 +# print_header 1.753 +# 1.754 +# 1.755 +# 1.756 +# In: $_[0] Содержание 1.757 +# Out: Распечатанный заголовок 1.758 + 1.759 +sub print_header 1.760 +{ 1.761 + my $toc = $_[0]; 1.762 + my $course_name = $Config{"course-name"}; 1.763 + my $course_code = $Config{"course-code"}; 1.764 + my $course_date = $Config{"course-date"}; 1.765 + my $course_center = $Config{"course-center"}; 1.766 + my $course_trainer = $Config{"course-trainer"}; 1.767 + my $course_student = $Config{"course-student"}; 1.768 + 1.769 + my $title = "Журнал лабораторных работ"; 1.770 + $title .= " -- ".$course_student if $course_student; 1.771 + if ($course_date) { 1.772 + $title .= " -- ".$course_date; 1.773 + $title .= $course_code ? "/".$course_code 1.774 + : ""; 1.775 + } 1.776 + else { 1.777 + $title .= " -- ".$course_code if $course_code; 1.778 + } 1.779 + 1.780 + # Управляющая форма 1.781 + my $control_form .= "<table id='visibility_form' class='visibility_form'><tr><td>Видимые элементы</TD></tr><tr><td><form>\n"; 1.782 + for my $element (keys %Elements_Visibility) 1.783 + { 1.784 + my @e = split /\s+/, $element; 1.785 + my $showhide = join "", map { "ShowHide('$_');" } @e ; 1.786 + $control_form .= "<input type='checkbox' name='$e[0]' onclick=\"$showhide\" checked>". 1.787 + $Elements_Visibility{$element}. 1.788 + "</input><br>\n"; 1.789 + } 1.790 + $control_form .= "</form></td></tr></table>\n"; 1.791 + 1.792 + my $result; 1.793 + $result = <<HEADER; 1.794 + <html> 1.795 + <head> 1.796 + <meta content='text/html; charset=utf-8' http-equiv='Content-Type' /> 1.797 + <link rel='stylesheet' href='$Config{frontend_css}' type='text/css'/> 1.798 + <title>$title</title> 1.799 + </head> 1.800 + <body> 1.801 + <script> 1.802 + $Html_JavaScript 1.803 + </script> 1.804 + <h1>Журнал лабораторных работ</h1> 1.805 +HEADER 1.806 + if ( $course_student 1.807 + || $course_trainer 1.808 + || $course_name 1.809 + || $course_code 1.810 + || $course_date 1.811 + || $course_center) { 1.812 + $result .= "<p>"; 1.813 + $result .= "Выполнил $course_student<br/>" if $course_student; 1.814 + $result .= "Проверил $course_trainer <br/>" if $course_trainer; 1.815 + $result .= "Курс " if $course_name 1.816 + || $course_code 1.817 + || $course_date; 1.818 + $result .= "$course_name " if $course_name; 1.819 + $result .= "($course_code)" if $course_code; 1.820 + $result .= ", $course_date<br/>" if $course_date; 1.821 + $result .= "Учебный центр $course_center <br/>" if $course_center; 1.822 + $result .= "</p>"; 1.823 + } 1.824 + 1.825 + $result .= <<HEADER; 1.826 + <table width='100%'> 1.827 + <tr> 1.828 + <td width='*'> 1.829 + 1.830 + <table border=0 id='toc' class='toc'> 1.831 + <tr> 1.832 + <td> 1.833 + <div class='toc_title'>Содержание</div> 1.834 + <ul> 1.835 + <li><a href='#log'>Журнал</a></li> 1.836 + <ul>$toc</ul> 1.837 + <li><a href='#stat'>Статистика</a></li> 1.838 + <li><a href='#help'>Справка</a></li> 1.839 + <li><a href='#about'>О программе</a></li> 1.840 + </ul> 1.841 + </td> 1.842 + </tr> 1.843 + </table> 1.844 + 1.845 + </td> 1.846 + <td valign='top' width=200>$control_form</td> 1.847 + </tr> 1.848 + </table> 1.849 +HEADER 1.850 + 1.851 + return $result; 1.852 +} 1.853 + 1.854 + 1.855 +############# 1.856 +# print_footer 1.857 +# 1.858 +# 1.859 +# 1.860 +# 1.861 +# 1.862 + 1.863 +sub print_footer 1.864 +{ 1.865 + return "</body>\n</html>\n"; 1.866 +} 1.867 + 1.868 + 1.869 + 1.870 + 1.871 +############# 1.872 +# print_stat 1.873 +# 1.874 +# 1.875 +# 1.876 +# In: 1.877 +# Out: 1.878 + 1.879 +sub print_stat 1.880 +{ 1.881 %StatNames = ( 1.882 - FirstCommand => "Время первой команды журнала", 1.883 - LastCommand => "Время последней команды журнала", 1.884 - TotalCommands => "Количество командных строк в журнале", 1.885 - ErrorsPercentage => "Процент команд с ненулевым кодом завершения, %", 1.886 - TotalTime => "Суммарное время работы с терминалом <sup><font size='-2'>*</font></sup>, час", 1.887 - CommandsPerTime => "Количество командных строк в единицу времени, команда/мин", 1.888 - CommandsFrequency => "Частота использования команд", 1.889 - RareCommands => "Частота использования этих команд < 0.5%", 1.890 + FirstCommand => "Время первой команды журнала", 1.891 + LastCommand => "Время последней команды журнала", 1.892 + TotalCommands => "Количество командных строк в журнале", 1.893 + ErrorsPercentage => "Процент команд с ненулевым кодом завершения, %", 1.894 + MistypesPercentage => "Процент синтаксически неверное набранных команд, %", 1.895 + TotalTime => "Суммарное время работы с терминалом <sup><font size='-2'>*</font></sup>, час", 1.896 + CommandsPerTime => "Количество командных строк в единицу времени, команда/мин", 1.897 + CommandsFrequency => "Частота использования команд", 1.898 + RareCommands => "Частота использования этих команд < 0.5%", 1.899 ); 1.900 @StatOrder = ( 1.901 FirstCommand, 1.902 LastCommand, 1.903 TotalCommands, 1.904 ErrorsPercentage, 1.905 + MistypesPercentage, 1.906 TotalTime, 1.907 CommandsPerTime, 1.908 CommandsFrequency, 1.909 @@ -671,8 +825,10 @@ 1.910 $Stat{FirstCommand} = sprintf "%02i:%02i:%02i %04i-%2i-%2i", $hour, $min, $sec, $year+1900, $mon+1, $mday; 1.911 ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($Stat{LastCommand} || 0); 1.912 $Stat{LastCommand} = sprintf "%02i:%02i:%02i %04i-%2i-%2i", $hour, $min, $sec, $year+1900, $mon+1, $mday; 1.913 - $Stat{ErrorsPercentage} = sprintf "%5.2f", $Stat{ErrorCommands}*100/$Stat{TotalCommands} 1.914 - if $Stat{TotalCommands}; 1.915 + if ($Stat{TotalCommands}) { 1.916 + $Stat{ErrorsPercentage} = sprintf "%5.2f", $Stat{ErrorCommands}*100/$Stat{TotalCommands}; 1.917 + $Stat{MistypesPercentage} = sprintf "%5.2f", $Stat{MistypedCommands}*100/$Stat{TotalCommands}; 1.918 + } 1.919 $Stat{CommandsPerTime} = sprintf "%5.2f", $Stat{TotalCommands}*60/$Stat{TotalTime} 1.920 if $Stat{TotalTime}; 1.921 $Stat{TotalTime} = sprintf "%5.2f", $Stat{TotalTime}/60/60; 1.922 @@ -688,14 +844,16 @@ 1.923 if ($percentage < 0.5) { 1.924 my $hint = make_comment($command); 1.925 $command_html = "$command"; 1.926 - $command_html = "<span title='$hint' class='hint'>$command_html</span>" if $hint; 1.927 + $command_html = "<span title='$hint' class='with_hint'>$command_html</span>" if $hint; 1.928 + $command_html = "<span class='without_hint'>$command_html</span>" if not $hint; 1.929 my $command_html = "<tt>$command_html</tt>"; 1.930 $Stat{RareCommands} .= $command_html."<sub><font size='-2'>".$CommandsFrequency{$command}."</font></sub> , "; 1.931 } 1.932 else { 1.933 my $hint = make_comment($command); 1.934 $command_html = "$command"; 1.935 - $command_html = "<span title='$hint' class='hint'>$command_html</span>" if $hint; 1.936 + $command_html = "<span title='$hint' class='with_hint'>$command_html</span>" if $hint; 1.937 + $command_html = "<span class='without_hint'>$command_html</span>" if not $hint; 1.938 my $command_html = "<tt>$command_html</tt>"; 1.939 $percentage = sprintf "%5.2f",$percentage; 1.940 $Stat{CommandsFrequency} .= "<tr><td>".$command_html."</td><td>".$CommandsFrequency{$command}."</td>". 1.941 @@ -706,106 +864,20 @@ 1.942 $Stat{RareCommands} =~ s/, $// if $Stat{RareCommands}; 1.943 } 1.944 1.945 - $Result{"stat"} .= "<h2 id='stat'>Статистика</h2>"; 1.946 - $Result{"stat"} .= "<table>"; 1.947 + my $result = q(); 1.948 for my $stat (@StatOrder) { 1.949 - $Result{"stat"} .= "<tr valign='top'><td width='300'>".$StatNames{"$stat"}."</td><td>".$Stat{"$stat"}."</td></tr>" 1.950 - if $Stat{"$stat"}; 1.951 + next unless $Stat{"$stat"}; 1.952 + $result .= "<tr valign='top'><td width='300'>".$StatNames{"$stat"}."</td><td>".$Stat{"$stat"}."</td></tr>" 1.953 } 1.954 - 1.955 - $Result{"stat"} .= "</table>"; 1.956 - $Result{"stat"} .= "<font size='-2'>____<br/>*) Интервалы неактивности длительностью ".($Config{stat_inactivity_interval}/60)." минут и более не учитываются</font></br>"; 1.957 + $result = "<table>$result</table>" 1.958 + . "<font size='-2'>____<br/>*) Интервалы неактивности длительностью " 1.959 + . ($Config{stat_inactivity_interval}/60) 1.960 + . " минут и более не учитываются</font></br>"; 1.961 1.962 - #$Result{"help"} .= "<hr/>"; 1.963 - $Result{"help"} .= "<h2 id='help'>Справка</h2>"; 1.964 - $Result{"help"} .= "$Html_Help<br/>"; 1.965 - #$Result{"about"} .= "<hr/>"; 1.966 - $Result{"about"} .= "<h2 id='about'>О программе</h2>"; 1.967 - $Result{"about"} .= "$Html_About"; 1.968 - $Result{"footer"} .= "</body>\n"; 1.969 - $Result{"footer"} .= "</html>\n"; 1.970 - 1.971 - $Result{"title"} = "Журнал лабораторных работ"; 1.972 - $Result{"title"}.= " -- ".$course_student if $course_student; 1.973 - if ($course_date) { 1.974 - $Result{"title"}.= " -- ".$course_date; 1.975 - $Result{"title"}.= "/".$course_code if $course_code; 1.976 - } 1.977 - else { 1.978 - $Result{"title"}.= " -- ".$course_code if $course_code; 1.979 - } 1.980 - 1.981 - # Заголовок генерируется позже всего 1.982 - # Тогда, когда известно уже, что должно быть написано в 1.983 - # оглавлении 1.984 - $Result{"header"} = <<HEADER; 1.985 - <html> 1.986 - <head> 1.987 - <meta content='text/html; charset=utf-8' http-equiv='Content-Type' /> 1.988 - <link rel='stylesheet' href='$Config{frontend_css}' type='text/css'/> 1.989 - <title>$Result{title}</title> 1.990 - </head> 1.991 - <body> 1.992 - <script> 1.993 - $Html_JavaScript 1.994 - </script> 1.995 - <h1>Журнал лабораторных работ</h1> 1.996 - 1.997 -HEADER 1.998 - $Result{"header"} .= "<p>" if $course_student || $course_trainer || $course_name || $course_code || $course_date || $course_center; 1.999 - $Result{"header"} .= "Выполнил $course_student<br/>" if $course_student; 1.1000 - $Result{"header"} .= "Проверил $course_trainer <br/>" if $course_trainer; 1.1001 - $Result{"header"} .= "Курс " if $course_name || $course_code || $course_date; 1.1002 - $Result{"header"} .= "$course_name " if $course_name; 1.1003 - $Result{"header"} .= "($course_code)" if $course_code; 1.1004 - $Result{"header"} .= ", $course_date<br/>" if $course_date; 1.1005 - $Result{"header"} .= "Учебный центр $course_center <br/>" if $course_center; 1.1006 - $Result{"header"} .= "</p>" if $course_student || $course_trainer || $course_name || $course_code || $course_date || $course_center; 1.1007 - 1.1008 - my $toc = collapse_list (\@toc); 1.1009 - $Result{"header"} .= <<HEADER; 1.1010 - <table border=0 id='toc' class='toc'> 1.1011 - <tr> 1.1012 - <td> 1.1013 - <div class='toc_title'>Содержание</div> 1.1014 - <ul> 1.1015 - <li><a href='#log'>Журнал</a></li> 1.1016 - <ul>$toc</ul> 1.1017 - <li><a href='#stat'>Статистика</a></li> 1.1018 - <li><a href='#help'>Справка</a></li> 1.1019 - <li><a href='#about'>О программе</a></li> 1.1020 - </ul> 1.1021 - </td> 1.1022 - </tr> 1.1023 - </table> 1.1024 - 1.1025 - <h2 id="log">Журнал</h2> 1.1026 -HEADER 1.1027 - $Result{"header"} .= "<table id='visibility_form' class='visibility_form'><tr><td><form>\n"; 1.1028 - for my $element (keys %Elements_Visibility) 1.1029 - { 1.1030 - my @e = split /\s+/, $element; 1.1031 - my $showhide = join "", map { "ShowHide('$_');" } @e ; 1.1032 - $Result{"header"} .= "<input type='checkbox' name='$e[0]' onclick=\"$showhide\" checked>". 1.1033 - $Elements_Visibility{$element}. 1.1034 - "</input><br>\n"; 1.1035 - } 1.1036 - 1.1037 - $Result{"header"} .= "</form></td></tr></table>\n"; 1.1038 - 1.1039 - if ($output_filename eq "-") { 1.1040 - print $Result{"header"}, $Result{"body"}, $Result{"stat"}, $Result{"help"}, $Result{"about"}, $Result{"footer"}; 1.1041 - } 1.1042 - else { 1.1043 - open(OUT, ">", $output_filename) 1.1044 - or die "Can't open $output_filename for writing\n"; 1.1045 - print OUT $Result{"header"}, $Result{"body"}, $Result{"stat"}, $Result{"help"}, $Result{"about"}, $Result{"footer"}; 1.1046 - close(OUT); 1.1047 - } 1.1048 + return $result; 1.1049 } 1.1050 1.1051 1.1052 - 1.1053 sub collapse_list($) 1.1054 { 1.1055 my $res = ""; 1.1056 @@ -831,7 +903,7 @@ 1.1057 всё происходит само собой. 1.1058 Однако, чтобы ведение и последующее использование журналов 1.1059 было как можно более эффективным, желательно иметь в виду следующее: 1.1060 - <ul> 1.1061 + <ol> 1.1062 <li><p> 1.1063 В журнал автоматически попадают все команды, данные в любом терминале системы. 1.1064 </p></li> 1.1065 @@ -1020,7 +1092,7 @@ 1.1066 добавляются точно таким же способом, только вместо симолов #^ или #v 1.1067 нужно использовать символы #= 1.1068 </p></li> 1.1069 -</ul> 1.1070 +</ol> 1.1071 HELP 1.1072 1.1073 $Html_About = <<ABOUT; 1.1074 @@ -1115,3 +1187,20 @@ 1.1075 @Of_Month_Name = qw/ Января Февраля Марта Апреля Мая Июня Июля Августа Сентября Октября Ноября Декабря /; 1.1076 } 1.1077 1.1078 + 1.1079 + 1.1080 + 1.1081 +# Временно удалённый код 1.1082 +# Возможно, он не понадобится уже никогда 1.1083 + 1.1084 + 1.1085 +sub search_by 1.1086 +{ 1.1087 + my $sm = shift; 1.1088 + my $topic = shift; 1.1089 + $topic =~ s/ /+/; 1.1090 + 1.1091 + return "<a href='". $Search_Machines{$sm}->{"query"}."$topic'><img width='16' height='16' src='". 1.1092 + $Search_Machines{$sm}->{"icon"}."' border='0'/></a>"; 1.1093 +} 1.1094 +