9564ae690b87d84817f32c1cea06e74cab5a826f
[spider.git] / perl / DXLogPrint.pm
1 #
2 # Log Printing routines
3 #
4 # Copyright (c) - 1998 Dirk Koopman G1TLH
5 #
6 #
7 #
8
9 package DXLog;
10
11 use 5.10.1;
12
13 use IO::File;
14 use DXVars;
15 use DXDebug qw(dbg isdbg);
16 use DXUtil;
17 use DXLog;
18 use Julian;
19
20
21 our $readback = `which tac`;
22 chomp $readback;
23
24 use strict;
25
26 use vars qw($maxmonths);
27 $maxmonths = 36;
28
29 #
30 # print some items from the log backwards in time
31 #
32 # This command outputs a list of n lines starting from time t with $pattern tags
33 #
34 sub print
35 {
36         my $fcb = $DXLog::log;
37         my $from = shift || 0;
38         my $to = shift || 10;
39         my $jdate = $fcb->unixtoj(shift);
40         my $pattern = shift;
41         my $who = shift;
42         my $search;
43         my @in;
44         my @out = ();
45         my $eval;
46         my $tot = $from + $to;
47         my $hint = "";
48             
49         $who = uc $who if defined $who;
50
51         if ($pattern) {
52                 $hint = q{m{\Q$pattern\E}i};
53         } else {
54                 $hint = q{!m{\^(?:ann|rcmd|talk|chat)\^}};
55         }
56         if ($who) {
57                 $hint .= ' && ' if $hint;
58                 $hint .= q{m{\Q$who\E}oi};
59         } 
60         $hint = "next unless $hint" if $hint;
61         $hint .= "; next unless m{^\\d+\\^$pattern\\^}" if $pattern;
62         $hint ||= "";
63         
64         $eval = qq(while (<\$fh>) {
65                                    $hint;
66                                    chomp;
67                    # say "line: \$_";
68                                    push \@in, \$_;
69                    last L1 if \@in >= $tot;
70                            } );
71         
72         if (isdbg('search')) {
73                 dbg("sh/log hint: $hint");
74                 dbg("sh/log eval: $eval");
75         }
76         
77         $fcb->close;                                      # close any open files
78
79         my $months;
80         my $fh;
81         if ($readback) {
82                 my $fn = $fcb->fn($jdate);
83                 $fh = IO::File->new("$readback $fn |");
84         } else {
85                 $fh = $fcb->open($jdate);       
86         }
87  L1: for ($months = 0; $fh && $months < $maxmonths && @in < $tot; $months++) {
88                 my $ref;
89
90                 if ($fh) {
91                         my @tmp;
92                         eval $eval;               # do the search on this file
93                         return ("Log search error", $@) if $@;
94                 }
95
96                 if ($readback) {
97                         my $fn = $fcb->fn($jdate->sub(1));
98                         $fh = IO::File->new("$readback $fn |");
99                 } else {
100                         $fh = $fcb->openprev();      # get the next file
101                 }
102         }
103
104         unless (@in) {
105                 my $name = $pattern ? $pattern : "log";
106                 my $s = "$who "|| '';
107                 return "show/$name: ${s}not found";
108         } 
109
110         for (reverse @in) {
111                 my @line = split /\^/ ;
112                 push @out, print_item(\@line);
113         
114         }
115         return @out;
116 }
117
118
119 #
120 # the standard log printing interpreting routine.
121 #
122 # every line that is printed should call this routine to be actually visualised
123 #
124 # Don't really know whether this is the correct place to put this stuff, but where
125 # else is correct?
126 #
127 # I get a reference to an array of items
128 #
129 sub print_item
130 {
131         my $r = shift;
132         my $d = atime($r->[0]);
133         my $s = 'undef';
134         
135         if ($r->[1] eq 'rcmd') {
136                 $r->[6] ||= 'Unknown';
137                 if ($r->[2] eq 'in') {
138                         $r->[5] ||= "";
139                         $s = "in: $r->[4] ($r->[6] priv: $r->[3]) rcmd: $r->[5]";
140                 } else {
141                         $r->[4] ||= "";
142                         $s = "$r->[3] $r->[6] reply: $r->[4]";
143                 }
144         } elsif ($r->[1] eq 'talk') {
145                 $r->[5] ||= "";
146                 $s = "$r->[3] -> $r->[2] ($r->[4]) $r->[5]";
147         } elsif ($r->[1] eq 'ann' || $r->[1] eq 'chat') {
148                 $r->[4] ||= "";
149                 $r->[4] =~ s/^\#\d+ //;
150                 $s = "$r->[3] -> $r->[2] $r->[4]";
151         } else {
152                 $r->[2] ||= "";
153                 $s = "$r->[2]";
154         }
155         return "$d $s";
156 }
157
158 1;