- Added minor check for very silent persons in lib/Onis/Plugins/Interestingnumbers.pm
[onis.git] / lib / Onis / Plugins / Interestingnumbers.pm
1 package Onis::Plugins::Interestingnumbers;
2
3 use strict;
4 use warnings;
5
6 use Exporter;
7
8 use Onis::Config (qw(get_config));
9 use Onis::Html (qw(html_escape get_filehandle));
10 use Onis::Language (qw(translate));
11 use Onis::Data::Core (qw(register_plugin get_main_nick nick_to_name));
12 use Onis::Data::Persistent;
13
14 @Onis::Plugins::Interestingnumbers::EXPORT_OK = (qw(get_interestingnumbers));
15 @Onis::Plugins::Interestingnumbers::ISA = ('Exporter');
16
17 register_plugin ('ACTION', \&add_action);
18 register_plugin ('JOIN', \&add_join);
19 register_plugin ('KICK', \&add_kick);
20 register_plugin ('MODE', \&add_mode);
21 register_plugin ('TEXT', \&add_text);
22 register_plugin ('OUTPUT', \&output);
23
24 our $InterestingNumbersCache = Onis::Data::Persistent->new ('InterestingNumbersCache', 'nick',
25         qw(actions joins kick_given kick_received op_given op_taken soliloquies));
26 our $InterestingNumbersData = {};
27
28 our $SoliloquiesNick = '';
29 our $SoliloquiesCount = 0;
30
31 our $SOLILOQUIES_COUNT = 5;
32 if (get_config ('soliloquies_count'))
33 {
34         my $tmp = get_config ('soliloquies_count');
35         $tmp =~ s/\D//g;
36
37         $SOLILOQUIES_COUNT = $tmp if ($tmp);
38 }
39                 
40 my $VERSION = '$Id$';
41 print STDERR $/, __FILE__, ": $VERSION" if ($::DEBUG);
42
43 return (1);
44
45 sub get_or_empty
46 {
47         my $nick = shift;
48         my @data = $InterestingNumbersCache->get ($nick);
49         @data = (0, 0, 0, 0, 0, 0, 0) unless (@data);
50         return (@data);
51 }
52
53 sub add_action
54 {
55         my $data = shift;
56         my $nick = $data->{'nick'};
57
58         my @data = get_or_empty ($nick);
59         $data[0]++;
60         $InterestingNumbersCache->put ($nick, @data);
61 }
62
63 sub add_join
64 {
65         my $data = shift;
66         my $nick = $data->{'nick'};
67
68         my @data = get_or_empty ($nick);
69         $data[1]++;
70         $InterestingNumbersCache->put ($nick, @data);
71 }
72
73 sub add_kick
74 {
75         my $data = shift;
76
77         my $nick_g = $data->{'nick'};
78         my $nick_r = $data->{'nick_received'};
79
80         my @data = get_or_empty ($nick_g);
81         $data[2]++;
82         $InterestingNumbersCache->put ($nick_g, @data);
83
84         @data = get_or_empty ($nick_r);
85         $data[3]++;
86         $InterestingNumbersCache->put ($nick_r, @data);
87 }
88
89 sub add_mode
90 {
91         my $data = shift;
92
93         my $nick = $data->{'nick'};
94         my $text = $data->{'mode'};
95         
96         my ($mode) = split (m/\s+/, $text);
97         my $modifier = '';
98
99         for (split (m//, $mode))
100         {
101                 my $tmp = $_;
102                 if (($tmp eq '-') or ($tmp eq '+'))
103                 {
104                         $modifier = $tmp;
105                         next;
106                 }
107
108                 next unless ($modifier);
109                 
110                 if ($tmp eq 'o')
111                 {
112                         my @data = get_or_empty ($nick);
113                         if ($modifier eq '-')
114                         {
115                                 $data[5]++;
116                         }
117                         else # ($modifier eq '+')
118                         {
119                                 $data[4]++;
120                         }
121                 }
122         }
123
124         return (1);
125 }
126
127 sub add_text
128 {
129         my $data = shift;
130
131         my $nick = $data->{'nick'};
132
133         if ($nick eq $SoliloquiesNick)
134         {
135                 $SoliloquiesCount++;
136
137                 if ($SoliloquiesCount == $SOLILOQUIES_COUNT)
138                 {
139                         my @data = get_or_empty ($nick);
140                         $data[6]++;
141                         $InterestingNumbersCache->put ($nick, @data);
142                 }
143         }
144         else
145         {
146                 $SoliloquiesNick = $nick;
147                 $SoliloquiesCount = 1;
148         }
149 }
150
151 sub calculate
152 {
153         for ($InterestingNumbersCache->keys ())
154         {
155                 my $nick = $_;
156                 my ($actions, $joins,
157                         $kick_given, $kick_received,
158                         $op_given, $op_taken,
159                         $soliloquies) = $InterestingNumbersCache->get ($nick);
160                 my $main = get_main_nick ($nick);
161
162                 next unless ($main);
163                 next unless (defined ($soliloquies)); # Person has not written a single line, eg. bots..
164
165                 if (!defined ($InterestingNumbersData->{$main}))
166                 {
167                         $InterestingNumbersData->{$main} =
168                         {
169                                 actions         => 0,
170                                 joins           => 0,
171                                 kick_given      => 0,
172                                 kick_received   => 0,
173                                 op_given        => 0,
174                                 op_taken        => 0,
175                                 soliloquies     => 0
176                         };
177                 }
178
179                 $InterestingNumbersData->{$main}{'actions'}        += $actions;
180                 $InterestingNumbersData->{$main}{'joins'}          += $joins;
181                 $InterestingNumbersData->{$main}{'kick_given'}     += $kick_given;
182                 $InterestingNumbersData->{$main}{'kick_received'}  += $kick_received;
183                 $InterestingNumbersData->{$main}{'op_given'}       += $op_given;
184                 $InterestingNumbersData->{$main}{'op_taken'}       += $op_taken;
185                 $InterestingNumbersData->{$main}{'soliloquies'}    += $soliloquies;
186         }
187 }
188
189
190
191
192 sub output
193 {
194         calculate ();
195         
196         my $first_nick;
197         my $first_name;
198         my $second_nick;
199         my $second_name;
200
201         my $fh = get_filehandle ();
202
203         my $trans = translate ('Interesting Numbers');
204         
205         print $fh <<EOF;
206 <table class="plugin interestingnumbers">
207   <tr>
208     <th>$trans</th>
209   </tr>
210 EOF
211         ($first_nick, $second_nick) = sort_by_field ('kick_received');
212         if ($first_nick)
213         {
214                 my $num = $InterestingNumbersData->{$first_nick}{'kick_received'};
215                 $trans = translate ('kick_received0: %s %u');
216                 $first_name = nick_to_name ($first_nick) || $first_nick;
217
218                 print $fh "  <tr>\n    <td>";
219                 printf $fh ($trans, $first_nick, $num);
220                 
221                 if ($second_nick)
222                 {
223                         $num = $InterestingNumbersData->{$second_nick}{'kick_received'};
224                         $trans = translate ('kick_received1: %s %u');
225                         $second_name = nick_to_name ($second_nick) || $second_nick;
226
227                         print $fh "<br />\n",
228                         qq#      <span class="small">#;
229                         printf $fh ($trans, $second_nick, $num);
230                         print $fh '</span>';
231                 }
232                 
233                 print $fh "</td>\n  </tr>\n";
234         }
235
236         ($first_nick, $second_nick) = sort_by_field ('kick_given');
237         if ($first_nick)
238         {
239                 my $num = $InterestingNumbersData->{$first_nick}{'kick_given'};
240                 $trans = translate ('kick_given0: %s %u');
241                 $first_name = nick_to_name ($first_nick) || $first_nick;
242
243                 print $fh "  <tr>\n    <td>";
244                 printf $fh ($trans, $first_name, $num);
245
246                 if ($second_nick)
247                 {
248                         $num = $InterestingNumbersData->{$second_nick}{'kick_given'};
249                         $trans = translate ('kick_given1: %s %u');
250                         $second_name = nick_to_name ($second_nick) || $second_nick;
251
252                         print $fh "<br />\n",
253                         qq#      <span class="small">#;
254                         printf $fh ($trans, $second_name, $num);
255                         print $fh '</span>';
256                 }
257
258                 print $fh "</td>\n  </tr>\n";
259         }
260
261         ($first_nick, $second_nick) = sort_by_field ('op_given');
262         if ($first_nick)
263         {
264                 my $num = $InterestingNumbersData->{$first_nick}{'op_given'};
265                 $trans = translate ('op_given0: %s %u');
266                 $first_name = nick_to_name ($first_nick) || $first_nick;
267
268                 print $fh "  <tr>\n    <td>";
269                 printf $fh ($trans, $first_name, $num);
270                 
271                 if ($second_nick)
272                 {
273                         $num = $InterestingNumbersData->{$second_nick}{'op_given'};
274                         $trans = translate ('op_given1: %s %u');
275                         $second_name = nick_to_name ($second_nick) || $second_nick;
276
277                         print $fh "<br />\n",
278                         qq#      <span class="small">#;
279                         printf $fh ($trans, $second_name, $num);
280                         print $fh '</span>';
281                 }
282                 
283                 print $fh "</td>\n  </tr>\n";
284         }
285
286         ($first_nick, $second_nick) = sort_by_field ('op_taken');
287         if ($first_nick)
288         {
289                 my $num = $InterestingNumbersData->{$first_nick}{'op_taken'};
290                 $trans = translate ('op_taken0: %s %u');
291                 $first_name = nick_to_name ($first_nick) || $first_nick;
292
293                 print $fh "  <tr>\n    <td>";
294                 printf $fh ($trans, $first_name, $num);
295                 
296                 if ($second_nick)
297                 {
298                         $num = $InterestingNumbersData->{$second_nick}{'op_taken'};
299                         $trans = translate ('op_taken1: %s %u');
300                         $second_name = nick_to_name ($second_nick) || $second_nick;
301
302                         print $fh "<br />\n",
303                         qq#      <span class="small">#;
304                         printf $fh ($trans, $second_name, $num);
305                         print $fh '</span>';
306                 }
307                 
308                 print $fh "</td>\n  </tr>\n";
309         }
310
311         ($first_nick, $second_nick) = sort_by_field ('actions');
312         if ($first_nick)
313         {
314                 my $num = $InterestingNumbersData->{$first_nick}{'actions'};
315                 $trans = translate ('action0: %s %u');
316                 $first_name = nick_to_name ($first_nick) || $first_nick;
317
318                 print $fh "  <tr>\n    <td>";
319                 printf $fh ($trans, $first_name, $num);
320                 
321                 if ($second_nick)
322                 {
323                         $num = $InterestingNumbersData->{$second_nick}{'actions'};
324                         $trans = translate ('action1: %s %u');
325                         $second_name = nick_to_name ($second_nick) || $second_nick;
326
327                         print $fh "<br />\n",
328                         qq#      <span class="small">#;
329                         printf $fh ($trans, $second_name, $num);
330                         print $fh '</span>';
331                 }
332
333                 print $fh "</td>\n  </tr>\n";
334         }
335         
336         ($first_nick, $second_nick) = sort_by_field ('soliloquies');
337         if ($first_nick)
338         {
339                 my $num = $InterestingNumbersData->{$first_nick}{'soliloquies'};
340                 $trans = translate ('soliloquies0: %s %u');
341                 $first_name = nick_to_name ($first_nick) || $first_nick;
342
343                 print $fh "  <tr>\n    <td>";
344                 printf $fh ($trans, $first_name, $num);
345                 
346                 if ($second_nick)
347                 {
348                         $num = $InterestingNumbersData->{$second_nick}{'soliloquies'};
349                         $trans = translate ('soliloquies1: %s %u');
350                         $second_name = nick_to_name ($second_nick) || $second_nick;
351
352                         print $fh "<br />\n",
353                         qq#      <span class="small">#;
354                         printf $fh ($trans, $second_name, $num);
355                         print $fh '</span>';
356                 }
357
358                 print $fh "</td>\n  </tr>\n";
359         }
360         
361         ($first_nick, $second_nick) = sort_by_field ('joins');
362         if ($first_nick)
363         {
364                 my $num = $InterestingNumbersData->{$first_nick}{'joins'};
365                 $trans = translate ('joins0: %s %u');
366                 $first_name = nick_to_name ($first_nick) || $first_nick;
367
368                 print $fh "  <tr>\n    <td>";
369                 printf $fh ($trans, $first_name, $num);
370                 
371                 if ($second_nick)
372                 {
373                         $num = $InterestingNumbersData->{$second_nick}{'joins'};
374                         $trans = translate ('joins1: %s %u');
375                         $second_name = nick_to_name ($second_nick) || $second_nick;
376
377                         print $fh "<br />\n",
378                         qq#      <span class="small">#;
379                         printf $fh ($trans, $second_name, $num);
380                         print $fh '</span>';
381                 }
382
383                 print $fh "</td>\n  </tr>\n";
384         }
385
386         print $fh "</table>\n\n";
387 }
388
389 sub sort_by_field
390 {
391         my $field = shift;
392         
393         my @retval = sort
394         {
395                 $InterestingNumbersData->{$b}{$field}
396                 <=>
397                 $InterestingNumbersData->{$a}{$field}
398         } (keys (%$InterestingNumbersData));
399
400         while (scalar (@retval) < 2)
401         {
402                 push (@retval, '');
403         }
404         
405         return (@retval);
406 }
407
408 sub get_interestingnumbers
409 {
410         my $nick = shift;
411
412         if (!defined ($InterestingNumbersData->{$nick}))
413         {
414                 return ({});
415         }
416
417         return ($InterestingNumbersData->{$nick});
418 }