lilalo

annotate l3-frontend @ 101:c41cc9a4b5ea

* Пофиксил ошибку с неправильной кодировкой mywi-хинтов.
* Подготовил к переходу в иерархию /l3/
** Исправил пути для стилей,
** Забацал красивый l3-cgi-lite


l3-cgi-lite пока что не доделан до нужного уровня,
но я его скоро дорисую.
Уже сейчас это намного более качественный скрипт
через уродский l3-cgi

Он, конечно, поработал в свое время,
но лучше его заменить l3-cgi-lite


Из функционала добавилось:
* Кэширование страниц в html
* Навигация по каталогам
* Навигационная строка в журнале сверху
author devi
date Sat Jun 24 22:53:37 2006 +0300 (2006-06-24)
parents 05e99d32f1f5
children 6fce4641575b
rev   line source
devi@23 1 #!/usr/bin/perl -w
devi@23 2
devi@31 3 use IO::Socket;
devi@23 4 use lib '.';
devi@23 5 use l3config;
devi@88 6 use utf8;
devi@23 7
devi@23 8 our @Command_Lines;
devi@31 9 our @Command_Lines_Index;
devi@31 10 our %Commands_Description;
devi@31 11 our %Args_Description;
devi@31 12 our $Mywi_Socket;
devi@32 13 our %Sessions;
devi@89 14
devi@84 15 our %filter;
devi@89 16 our $filter_url;
devi@89 17 sub init_filter;
devi@23 18
devi@69 19 our %Files;
devi@69 20
devi@23 21 # vvv Инициализация переменных выполняется процедурой init_variables
devi@23 22 our @Day_Name;
devi@23 23 our @Month_Name;
devi@23 24 our @Of_Month_Name;
devi@23 25 our %Search_Machines;
devi@23 26 our %Elements_Visibility;
devi@23 27 # ^^^
devi@23 28
devi@31 29 our %Stat;
devi@87 30 our %frequency_of_command; # Сколько раз в журнале встречается какая команда
devi@63 31 our $table_number=1;
devi@31 32
devi@55 33 my %mywi_cache_for; # Кэш для экономии обращений к mywi
devi@55 34
devi@23 35 sub make_comment;
devi@63 36 sub make_new_entries_table;
devi@23 37 sub load_command_lines_from_xml;
devi@32 38 sub load_sessions_from_xml;
devi@31 39 sub sort_command_lines;
devi@31 40 sub process_command_lines;
devi@23 41 sub init_variables;
devi@23 42 sub main;
devi@31 43 sub collapse_list($);
devi@23 44
devi@87 45 sub minutes_passed;
devi@87 46
devi@88 47 sub print_all_txt;
devi@88 48 sub print_all_html;
devi@89 49 sub print_edit_all_html;
devi@88 50 sub print_command_lines_html;
devi@89 51 sub print_command_lines_txt;
devi@88 52 sub print_files_html;
devi@88 53 sub print_stat_html;
devi@88 54 sub print_header_html;
devi@88 55 sub print_footer_html;
devi@56 56
devi@23 57 main();
devi@23 58
devi@23 59 sub main
devi@23 60 {
devi@49 61 $| = 1;
devi@23 62
devi@49 63 init_variables();
devi@49 64 init_config();
devi@68 65 $Config{frontend_ico_path}=$Config{frontend_css};
devi@68 66 $Config{frontend_ico_path}=~s@/[^/]*$@@;
devi@89 67 init_filter();
devi@23 68
devi@49 69 open_mywi_socket();
devi@49 70 load_command_lines_from_xml($Config{"backend_datafile"});
devi@49 71 load_sessions_from_xml($Config{"backend_datafile"});
devi@49 72 sort_command_lines;
devi@49 73 process_command_lines;
devi@89 74 if (defined($filter{action}) && $filter{action} eq "edit") {
devi@89 75 print_edit_all_html($Config{"output"});
devi@89 76 }
devi@89 77 else {
devi@89 78 print_all_html($Config{"output"});
devi@89 79 }
devi@49 80 close_mywi_socket;
devi@23 81 }
devi@23 82
devi@89 83 sub init_filter
devi@89 84 {
devi@89 85 if ($Config{filter}) {
devi@89 86 # Инициализация фильтра
devi@89 87 for (split /&/,$Config{filter}) {
devi@89 88 my ($var, $val) = split /=/;
devi@89 89 $filter{$var} = $val || "";
devi@89 90 }
devi@89 91 }
devi@89 92 $filter_url = join ("&", map("$_=$filter{$_}", keys %filter));
devi@89 93 }
devi@89 94
devi@56 95 # extract_from_cline
devi@23 96
devi@56 97 # In: $what = commands | args
devi@56 98 # Out: return ссылка на хэш, содержащий результаты разбора
devi@56 99 # команда => позиция
devi@23 100
devi@31 101 # Разобрать командную строку $_[1] и возвратить хэш, содержащий
devi@31 102 # номер первого появление команды в строке:
devi@49 103 # команда => первая позиция
devi@56 104 sub extract_from_cline
devi@31 105 {
devi@49 106 my $what = $_[0];
devi@49 107 my $cline = $_[1];
devi@49 108 my @lists = split /\;/, $cline;
devi@49 109
devi@49 110
devi@56 111 my @command_lines = ();
devi@56 112 for my $command_list (@lists) {
devi@56 113 push(@command_lines, split(/\|/, $command_list));
devi@49 114 }
devi@31 115
devi@56 116 my %position_of_command;
devi@56 117 my %position_of_arg;
devi@49 118 my $i=0;
devi@56 119 for my $command_line (@command_lines) {
devi@56 120 $command_line =~ s@^\s*@@;
devi@56 121 $command_line =~ /\s*(\S+)\s*(.*)/;
devi@49 122 if ($1 && $1 eq "sudo" ) {
devi@56 123 $position_of_command{"$1"}=$i++;
devi@56 124 $command_line =~ s/\s*sudo\s+//;
devi@49 125 }
devi@56 126 if ($command_line !~ m@^\s*\S*/etc/@) {
devi@56 127 $command_line =~ s@^\s*\S+/@@;
devi@56 128 }
devi@56 129
devi@56 130 $command_line =~ /\s*(\S+)\s*(.*)/;
devi@56 131 my $command = $1;
devi@56 132 my $args = $2;
devi@56 133 if ($command && !defined $position_of_command{"$command"}) {
devi@56 134 $position_of_command{"$command"}=$i++;
devi@49 135 };
devi@56 136 if ($args) {
devi@49 137 my @args = split (/\s+/, $args);
devi@49 138 for my $a (@args) {
devi@56 139 $position_of_arg{"$a"}=$i++
devi@56 140 if !defined $position_of_arg{"$a"};
devi@49 141 };
devi@49 142 }
devi@49 143 }
devi@31 144
devi@49 145 if ($what eq "commands") {
devi@56 146 return \%position_of_command;
devi@49 147 } else {
devi@56 148 return \%position_of_arg;
devi@49 149 }
devi@49 150
devi@31 151 }
devi@31 152
devi@56 153
devi@56 154
devi@56 155
devi@56 156 #
devi@56 157 # Подпрограммы для работы с mywi
devi@56 158 #
devi@56 159
devi@31 160 sub open_mywi_socket
devi@31 161 {
devi@49 162 $Mywi_Socket = IO::Socket::INET->new(
devi@49 163 PeerAddr => $Config{mywi_server},
devi@49 164 PeerPort => $Config{mywi_port},
devi@49 165 Proto => "tcp",
devi@49 166 Type => SOCK_STREAM);
devi@31 167 }
devi@31 168
devi@31 169 sub close_mywi_socket
devi@31 170 {
devi@52 171 close ($Mywi_Socket) if $Mywi_Socket ;
devi@31 172 }
devi@31 173
devi@31 174
devi@31 175 sub mywi_client
devi@31 176 {
devi@101 177 #return "";
devi@49 178 my $query = $_[0];
devi@49 179 my $mywi;
devi@31 180
devi@49 181 open_mywi_socket;
devi@49 182 if ($Mywi_Socket) {
devi@101 183 binmode ":utf8", $Mywi_Socket;
devi@49 184 local $| = 1;
devi@49 185 local $/ = "";
devi@49 186 print $Mywi_Socket $query."\n";
devi@49 187 $mywi = <$Mywi_Socket>;
devi@101 188 utf8::decode($mywi);
devi@49 189 $mywi = "" if $mywi =~ /nothing app/;
devi@49 190 }
devi@49 191 close_mywi_socket;
devi@49 192 return $mywi;
devi@31 193 }
devi@31 194
devi@23 195 sub make_comment
devi@23 196 {
devi@49 197 my $cline = $_[0];
devi@49 198 #my $files = $_[1];
devi@23 199
devi@55 200 my @comments;
devi@49 201 my @commands = keys %{extract_from_cline("commands", $cline)};
devi@49 202 my @args = keys %{extract_from_cline("args", $cline)};
devi@49 203 return if (!@commands && !@args);
devi@49 204 #return "commands=".join(" ",@commands)."; files=".join(" ",@files);
devi@23 205
devi@49 206 # Commands
devi@49 207 for my $command (@commands) {
devi@49 208 $command =~ s/'//g;
devi@87 209 $frequency_of_command{$command}++;
devi@49 210 if (!$Commands_Description{$command}) {
devi@55 211 $mywi_cache_for{$command} ||= mywi_client ($command) || "";
devi@63 212 my $mywi = join ("\n", grep(/\([18]|sh|script\)/, split(/\n/, $mywi_cache_for{$command})));
devi@49 213 $mywi =~ s/\s+/ /;
devi@49 214 if ($mywi !~ /^\s*$/) {
devi@49 215 $Commands_Description{$command} = $mywi;
devi@49 216 }
devi@49 217 else {
devi@49 218 next;
devi@49 219 }
devi@49 220 }
devi@23 221
devi@49 222 push @comments, $Commands_Description{$command};
devi@49 223 }
devi@49 224 return join("&#10;\n", @comments);
devi@49 225
devi@49 226 # Files
devi@49 227 for my $arg (@args) {
devi@49 228 $arg =~ s/'//g;
devi@49 229 if (!$Args_Description{$arg}) {
devi@49 230 my $mywi;
devi@49 231 $mywi = mywi_client ($arg);
devi@49 232 $mywi = join ("\n", grep(/\([5]\)/, split(/\n/, $mywi)));
devi@49 233 $mywi =~ s/\s+/ /;
devi@49 234 if ($mywi !~ /^\s*$/) {
devi@49 235 $Args_Description{$arg} = $mywi;
devi@49 236 }
devi@49 237 else {
devi@49 238 next;
devi@49 239 }
devi@49 240 }
devi@23 241
devi@49 242 push @comments, $Args_Description{$arg};
devi@49 243 }
devi@23 244
devi@23 245 }
devi@23 246
devi@23 247 =cut
devi@23 248 Процедура load_command_lines_from_xml выполняет загрузку разобранного lab-скрипта
devi@23 249 из XML-документа в переменную @Command_Lines
devi@23 250
devi@56 251 # In: $datafile имя файла
devi@56 252 # Out: @CommandLines загруженные командные строки
devi@56 253
devi@23 254 Предупреждение!
devi@23 255 Процедура не в состоянии обрабатывать XML-документ любой структуры.
devi@23 256 В действительности файл cache из которого загружаются данные
devi@23 257 просто напоминает XML с виду.
devi@23 258 =cut
devi@23 259 sub load_command_lines_from_xml
devi@23 260 {
devi@49 261 my $datafile = $_[0];
devi@23 262
devi@49 263 open (CLASS, $datafile)
devi@81 264 or die "Can't open file with xml lablog ",$datafile,"\n";
devi@49 265 local $/;
devi@89 266 binmode CLASS, ":utf8";
devi@49 267 $data = <CLASS>;
devi@49 268 close(CLASS);
devi@23 269
devi@49 270 for $command ($data =~ m@<command>(.*?)</command>@sg) {
devi@49 271 my %cl;
devi@49 272 while ($command =~ m@<([^>]*?)>(.*?)</\1>@sg) {
devi@49 273 $cl{$1} = $2;
devi@49 274 }
devi@49 275 push @Command_Lines, \%cl;
devi@49 276 }
devi@23 277 }
devi@23 278
devi@32 279 sub load_sessions_from_xml
devi@32 280 {
devi@49 281 my $datafile = $_[0];
devi@32 282
devi@89 283 open (CLASS, $datafile)
devi@81 284 or die "Can't open file with xml lablog ",$datafile,"\n";
devi@49 285 local $/;
devi@89 286 binmode CLASS, ":utf8";
devi@49 287 my $data = <CLASS>;
devi@49 288 close(CLASS);
devi@32 289
devi@84 290 my $i=0;
devi@84 291 for my $session ($data =~ m@<session>(.*?)</session>@msg) {
devi@84 292 my %session_hash;
devi@49 293 while ($session =~ m@<([^>]*?)>(.*?)</\1>@sg) {
devi@84 294 $session_hash{$1} = $2;
devi@49 295 }
devi@84 296 $Sessions{$session_hash{local_session_id}} = \%session_hash;
devi@49 297 }
devi@32 298 }
devi@32 299
devi@32 300
devi@56 301 # sort_command_lines
devi@56 302 # In: @Command_Lines
devi@56 303 # Out: @Command_Lies_Index
devi@32 304
devi@31 305 sub sort_command_lines
devi@31 306 {
devi@31 307
devi@49 308 my @index;
devi@49 309 for (my $i=0;$i<=$#Command_Lines;$i++) {
devi@49 310 $index[$i]=$i;
devi@49 311 }
devi@31 312
devi@49 313 @Command_Lines_Index = sort {
devi@49 314 $Command_Lines[$index[$a]]->{"time"} <=> $Command_Lines[$index[$b]]->{"time"}
devi@49 315 } @index;
devi@31 316
devi@31 317 }
devi@31 318
devi@56 319 ##################
devi@56 320 # process_command_lines
devi@56 321 #
devi@56 322 # Обрабатываются командные строки @Command_Lines
devi@56 323 # Для каждой строки определяется:
devi@56 324 # class класс
devi@56 325 # note комментарий
devi@56 326 #
devi@56 327 # In: @Command_Lines_Index
devi@56 328 # In-Out: @Command_Lines
devi@56 329
devi@31 330 sub process_command_lines
devi@31 331 {
devi@89 332
devi@89 333 COMMAND_LINE_PROCESSING:
devi@49 334 for my $i (@Command_Lines_Index) {
devi@56 335 my $cl = \$Command_Lines[$i];
devi@31 336
devi@56 337 next if !$cl;
devi@31 338
devi@89 339 for my $filter_key (keys %filter) {
devi@89 340 next COMMAND_LINE_PROCESSING
devi@89 341 if defined($$cl->{local_session_id})
devi@89 342 && defined($Sessions{$$cl->{local_session_id}}->{$filter_key})
devi@89 343 && $Sessions{$$cl->{local_session_id}}->{$filter_key} ne $filter{$filter_key};
devi@89 344 }
devi@89 345
devi@73 346 $$cl->{id} = $$cl->{"time"};
devi@73 347
devi@56 348 $$cl->{err} ||=0;
devi@56 349
devi@56 350 # Класс команды
devi@56 351
devi@56 352 $$cl->{"class"} = $$cl->{"err"} eq 130 ? "interrupted"
devi@56 353 : $$cl->{"err"} eq 127 ? "mistyped"
devi@56 354 : $$cl->{"err"} ? "wrong"
devi@57 355 : "normal";
devi@56 356
devi@73 357 if ($$cl->{"cline"} &&
devi@73 358 $$cl->{"cline"} =~ /[^|`]\s*sudo/
devi@57 359 || $$cl->{"uid"} eq 0) {
devi@49 360 $$cl->{"class"}.="_root";
devi@49 361 }
devi@31 362
devi@91 363 my $hint;
devi@91 364 $hint = make_comment($$cl->{"cline"});
devi@91 365 if ($hint) {
devi@91 366 $$cl->{hint} = $hint;
devi@91 367 }