1 # ho_stats_p.pl
  2 #
  3 # $Id: ho_stats_p.pl,v 1.7 2004/09/05 18:48:14 jvunder REL_0_3 $
  4 #
  5 # Part of the Hybrid Oper Script Collection
  6 #
  7 # Reformats /stats p output.
  8 #
  9 
 10 use strict;
 11 use vars qw($VERSION %IRSSI $SCRIPT_NAME);
 12 
 13 use Irssi;
 14 use Irssi::Irc;
 15 use HOSC::again;
 16 use HOSC::again 'HOSC::Base';
 17 use HOSC::again 'HOSC::Tools';
 18 import HOSC::Tools qw(seconds_to_hms);
 19 
 20 # ---------------------------------------------------------------------
 21 
 22 $SCRIPT_NAME = 'Stats p reformat';
 23 ($VERSION) = '$Revision: 1.7 $' =~ / (\d+\.\d+) /;
 24 my ($changed) = '$Id: ho_stats_p.pl,v 1.7 2004/09/05 18:48:14 jvunder REL_0_3 $' =~ / (\d+\/\d+\/\d+ \d+:\d+:\d+) /;
 25 %IRSSI = (
 26     authors     => 'Garion',
 27     contact     => 'garion@efnet.nl',
 28     name        => 'ho_stats_p',
 29     description => 'Reformats stats p',
 30     license     => 'Public Domain',
 31     url         => 'http://www.garion.org/irssi/hosc/',
 32     changed     => $changed,
 33 );
 34 
 35 my %stats_p_data;
 36 my @stats_p_idletimes;
 37 my ($stats_p_num_tcm, $stats_p_num_bopm, $stats_p_num_ddd);
 38 
 39 
 40 # ---------------------------------------------------------------------
 41 # Adds this oper to the stats p data hash.
 42 
 43 sub event_stats_p_line {
 44     my ($server, $data, $servername) = @_;
 45 
 46     my %oper;
 47 
 48     if ($data =~ /\[([OoAa])\](\[.*\])? (.+) \((.+)\) [Ii]dle:? ([0-9]+)/) {
 49         $oper{level}    = $1;
 50         $oper{flags}    = $2;
 51         $oper{nick}     = $3;
 52         $oper{hostmask} = $4;
 53         $oper{idle}     = $5;
 54     } else {
 55         return;
 56     }
 57 
 58     if ($oper{nick} =~ /tcm$/i || $oper{hostmask} =~ /tcm@/i) { 
 59        $oper{tcm} = 1;
 60        $stats_p_num_tcm++;
 61     }
 62 
 63     $oper{bopm} = 0;
 64     if ($oper{nick} =~ /bopm$/i || $oper{hostmask} =~ /bopm@/i) { 
 65         $oper{bopm} = 1;
 66         $stats_p_num_bopm++;
 67     }
 68 
 69     if ($oper{nick} =~ /ddd/i || $oper{hostmask} =~ /ddd@/i) {
 70         $oper{ddd} = 1;
 71         $stats_p_num_ddd++;
 72     }
 73     
 74     $stats_p_data{ $oper{nick} } = \%oper;
 75 
 76     # Check if this idle time is already present in the array with
 77     # idle times; if not, add it.
 78     my $alreadypresent = 0;
 79     for my $idletime (@stats_p_idletimes) {
 80         if ($oper{idle} == $idletime) {
 81             $alreadypresent = 1;
 82             last;
 83         }
 84     }
 85 
 86     push @stats_p_idletimes, $oper{idle} unless $alreadypresent;
 87 
 88     Irssi::signal_stop();
 89 }
 90 
 91 # ---------------------------------------------------------------------
 92 
 93 sub reemit_stats_p_line {
 94     my ($server, $data, $servername) = @_;
 95 
 96     # We need to re-emit this 249 numeric in case it contains data which
 97     # has nothing to do with stats p. Unfortunately, the end of STATS ?
 98     # also uses numeric 249, and we don't want to lose this data.
 99 
100     # For some reason I do not comprehend, Irssi does not display
101     # the first word of $args when re-emitting this signal. Hence
102     # the 'dummy_data' addition.
103     # Perhaps the number of the numeric should be here.
104     # Perhaps there is a rational explanation.
105     # I do not know, but this seems to work properly.
106     Irssi::signal_emit("default event numeric", 
107         $server, "dummy_data " . $data, $servername);
108     Irssi::signal_stop();
109 }
110 
111 # ---------------------------------------------------------------------
112 # Prints the hash of collected stats p data.
113 
114 sub event_stats_end {
115     my ($server, $data, $servername) = @_;
116 
117     return unless $data =~ /p :End of \/STATS report/;
118 
119     Irssi::signal_stop();
120 
121     print_stats_p_data($servername);
122 
123     undef %stats_p_data;
124     undef @stats_p_idletimes;
125     $stats_p_num_tcm = 0;
126     $stats_p_num_bopm = 0;
127 }
128 
129 # ---------------------------------------------------------------------
130 # Prints a list of opers, tcms and bopms, sorted by idle time.
131 
132 sub print_stats_p_data {
133     my ($servername) = @_;
134     my @sorted_idletimes = sort {$a <=> $b} @stats_p_idletimes;
135 
136     Irssi::printformat(MSGLEVEL_CRAP, 'ho_stats_p_begin_report',
137         $servername);
138     Irssi::printformat(MSGLEVEL_CRAP, 'ho_stats_p_head_opers',
139         $servername);
140 
141     # Kind of clumsy way to sort these opers on idle times.
142     # Sort the idle times, then for each idle time value, walk
143     # through the whole hash of opers and print the one(s) with
144     # this idle time.
145     for my $idletime (@sorted_idletimes) {
146         for my $opernick (keys %stats_p_data) {
147             next unless $stats_p_data{$opernick}->{idle} == $idletime;
148 
149             next if $stats_p_data{$opernick}->{tcm} ||
150                     $stats_p_data{$opernick}->{bopm} ||
151                     $stats_p_data{$opernick}->{ddd};
152             
153             print_stats_p_oper($stats_p_data{$opernick});
154         }
155     }
156 
157     # Print the TCM(s)
158     if ($stats_p_num_tcm > 0) { 
159         Irssi::printformat(MSGLEVEL_CRAP, 'ho_stats_p_head_tcm',
160             $servername);
161         for my $opernick (keys %stats_p_data) {
162             if ($stats_p_data{$opernick}->{tcm} == 1) { 
163                 print_stats_p_oper($stats_p_data{$opernick});
164             }
165         }
166     }
167    
168     # Print the BOPM(s)
169     if ($stats_p_num_bopm > 0) { 
170         Irssi::printformat(MSGLEVEL_CRAP, 'ho_stats_p_head_proxy',
171             $servername);
172         foreach my $opernick (keys %stats_p_data) {
173             if ($stats_p_data{$opernick}->{"bopm"} == 1) { 
174                 print_stats_p_oper($stats_p_data{$opernick});
175             }
176         }
177     }
178 
179     # Print the DDD(s)
180     if ($stats_p_num_ddd > 0) {
181             Irssi::printformat(MSGLEVEL_CRAP, 'ho_stats_p_head_ddd',
182                 $servername);
183         for my $opernick (keys %stats_p_data) {
184             if ($stats_p_data{$opernick}->{"ddd"} == 1) {
185                 print_stats_p_oper($stats_p_data{$opernick});
186             }
187         }
188     }
189                                                 
190     Irssi::printformat(MSGLEVEL_CRAP, 'ho_stats_p_end_report',
191         $servername);
192 }
193 
194 # ---------------------------------------------------------------------
195 # Prints a line with idle time, nick and hostmask of this oper.
196  
197 sub print_stats_p_oper {
198     my ($oper) = @_;
199 
200     my ($hours, $mins, $secs) = seconds_to_hms($oper->{idle});
201 
202     Irssi::printformat(MSGLEVEL_CRAP, 'ho_stats_p_line', $oper->{nick},
203         $hours, $mins, $secs, $oper->{hostmask});
204 }
205 
206 # ---------------------------------------------------------------------
207 
208 ho_print_init_begin();
209 
210 #>> :irc.Prison.NET 249 Garion :[O] RFdrone (~asamonte@SanQuentin.Prison.NET) idle 31546s
211 #>> :irc.Prison.NET 219 Garion p :End of /STATS report
212 Irssi::signal_add_first('event 249', 'event_stats_p_line');
213 Irssi::signal_add_last('event 249', 'reemit_stats_p_line');
214 Irssi::signal_add_last('event 219', 'event_stats_end');
215 
216 Irssi::theme_register( [
217     'ho_stats_p_begin_report',
218     '%YSTATS p report%n of $0',
219     
220     'ho_stats_p_head_opers',
221     '* %_Operators%_ on $0:',
222 
223     'ho_stats_p_head_tcm',
224     '* %_TCM bots%_ on $0:',
225 
226     'ho_stats_p_head_proxy',
227     '* %_Proxy monitors%_ on $0:',
228 
229     'ho_stats_p_end_report',
230     '* %_End of report%_ of $0',
231 
232     'ho_stats_p_line',
233     '$[-9]0 $[-3]1:$[-2]2:$[-2]3 ($4)',
234 
235         'ho_stats_p_head_ddd',
236     '* %_DDD bots%_ on $0',
237 ] );
238 
239 ho_print("Output style is determined by ho_stats_p_* formats.");
240 ho_print_init_end();
241 
242 # ---------------------------------------------------------------------


syntax highlighted by Code2HTML, v. 0.9.1