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