00f298c3725216e46ede65ca5b987d650795f413
[onis.git] / lib / Onis / Plugins / Bignumbers.pm
1 package Onis::Plugins::Bignumbers;
2
3 use strict;
4 use warnings;
5
6 use Exporter;
7
8 use Onis::Html (qw(get_filehandle));
9 use Onis::Language (qw(translate));
10 use Onis::Data::Core (qw(get_main_nick register_plugin nick_to_name));
11 use Onis::Data::Persistent ();
12 use Onis::Plugins::Core (qw(get_core_nick_counters));
13
14 @Onis::Plugins::Bignumbers::EXPORT_OK = (qw(get_bignumbers));
15 @Onis::Plugins::Bignumbers::ISA = ('Exporter');
16
17 our $BigNumbers = Onis::Data::Persistent->new ('BigNumbers', 'nick', qw(questions uppercase smiley_happy smiley_sad));
18 our $CalcData = {};
19
20 register_plugin ('TEXT', \&add);
21 register_plugin ('ACTION', \&add);
22 register_plugin ('OUTPUT', \&output);
23
24 my $VERSION = '$Id$';
25 print STDERR $/, __FILE__, ": $VERSION" if ($::DEBUG);
26
27 return (1);
28
29 sub add
30 {
31         my $data = shift;
32
33         my $nick = $data->{'nick'};
34         my $text = $data->{'text'};
35
36         my $mod = 0;
37
38         my @nums = $BigNumbers->get ($nick);
39         if (!@nums)
40         {
41                 @nums = (0, 0, 0, 0);
42                 $mod++;
43         }
44
45         if ($text =~ m/\b\?/)
46         {
47                 $nums[0]++;
48                 $mod++;
49         }
50
51         if ((uc ($text) eq $text) and ($text =~ m/[A-Z]/))
52         {
53                 $nums[1]++;
54                 $mod++;
55         }
56
57         if ($text =~ m/( |^)[;:]-?\)( |$)/)
58         {
59                 $nums[2]++;
60                 $mod++;
61         }
62
63         if ($text =~ m/( |^):-?\(( |$)/)
64         {
65                 $nums[3]++;
66                 $mod++;
67         }
68
69         if ($mod)
70         {
71                 $BigNumbers->put ($nick, @nums);
72         }
73
74         return (1);
75 }
76
77 sub calculate
78 {
79         for ($BigNumbers->keys ())
80         {
81                 my $nick = $_;
82                 my $main = get_main_nick ($nick);
83                 my ($questions, $uppercase, $smiley_happy, $smiley_sad) = $BigNumbers->get ($nick);
84
85                 next unless (defined ($smiley_sad));
86                 
87                 if (!defined ($CalcData->{$main}))
88                 {
89                         my $core_data = get_core_nick_counters ($main);
90                         next unless (%$core_data);
91
92                         $CalcData->{$main} =
93                         {
94                                 lines => $core_data->{'lines_total'},
95                                 words => $core_data->{'words_total'},
96                                 chars => $core_data->{'chars_total'},
97                                 questions    => 0,
98                                 uppercase    => 0,
99                                 smiley_happy => 0,
100                                 smiley_sad   => 0
101                         };
102                 }
103
104                 $CalcData->{$main}{'questions'}    += $questions;
105                 $CalcData->{$main}{'uppercase'}    += $uppercase;
106                 $CalcData->{$main}{'smiley_happy'} += $smiley_happy;
107                 $CalcData->{$main}{'smiley_sad'}   += $smiley_sad;
108         }
109 }
110
111 sub output
112 {
113         my $first_nick;
114         my $first_name;
115         my $second_nick;
116         my $second_name;
117         my $trans;
118
119         my $fh = get_filehandle ();
120         
121         $trans = translate ('Big Numbers');
122         print $fh <<EOF;
123 <table class="plugin bignumbers">
124   <tr>
125     <th>$trans</th>
126   </tr>
127 EOF
128         ($first_nick, $second_nick) = sort_by_field ('questions');
129         if ($first_nick)
130         {
131                 my $percent = 100 * $CalcData->{$first_nick}{'questions'} / $CalcData->{$first_nick}{'lines'};
132                 my $trans = translate ('questions0: %s %2.1f%%');
133                 $first_name = nick_to_name ($first_nick) || $first_nick;
134
135                 print $fh "  <tr>\n    <td>";
136                 printf $fh ($trans, $first_name, $percent);
137                 
138                 if ($second_nick)
139                 {
140                         $percent = 100 * $CalcData->{$second_nick}{'questions'} / $CalcData->{$second_nick}{'lines'};
141                         $trans = translate ('questions1: %s %2.1f%%');
142                         $second_name = nick_to_name ($second_nick) || $second_nick;
143
144                         print $fh "<br />\n",
145                         qq#      <span class="small">#;
146                         printf $fh ($trans, $second_name, $percent);
147                         print $fh '</span>';
148                 }
149                 
150                 print $fh "</td>\n  </tr>\n";
151         }
152
153         ($first_nick, $second_nick) = sort_by_field ('uppercase');
154         if ($first_nick)
155         {
156                 my $percent = 100 * $CalcData->{$first_nick}{'uppercase'} / $CalcData->{$first_nick}{'lines'};
157                 my $trans = translate ('yells0: %s %2.1f%%');
158                 $first_name = nick_to_name ($first_nick) || $first_nick;
159
160                 print $fh "  <tr>\n    <td>";
161                 printf $fh ($trans, $first_name, $percent);
162
163                 if ($second_nick)
164                 {
165                         $percent = 100 * $CalcData->{$second_nick}{'uppercase'} / $CalcData->{$second_nick}{'lines'};
166                         $trans = translate ('yells1: %s %2.1f%%');
167                         $second_name = nick_to_name ($second_nick) || $second_nick;
168
169                         print $fh "<br />\n",
170                         qq#      <span class="small">#;
171                         printf $fh ($trans, $second_name, $percent);
172                         print $fh "</span>";
173                 }
174
175                 print $fh "</td>\n  </tr>\n";
176         }
177
178         ($first_nick, $second_nick) = sort_by_field ('smiley_happy');
179         if ($first_nick)
180         {
181                 my $percent = 100 * $CalcData->{$first_nick}{'smiley_happy'} / $CalcData->{$first_nick}{'lines'};
182                 my $trans = translate ('happy0: %s %2.1f%%');
183                 $first_name = nick_to_name ($first_nick) || $first_nick;
184
185                 print $fh "  <tr>\n    <td>";
186                 printf $fh ($trans, $first_name, $percent);
187                 
188                 if ($second_nick)
189                 {
190                         $percent = 100 * $CalcData->{$second_nick}{'smiley_happy'} / $CalcData->{$second_nick}{'lines'};
191                         $trans = translate ('happy1: %s %2.1f%%');
192                         $second_name = nick_to_name ($second_nick) || $second_nick;
193
194                         print $fh "<br />\n",
195                         qq#      <span class="small">#;
196                         printf $fh ($trans, $second_name, $percent);
197                         print $fh "</span>";
198                 }
199                 
200                 print $fh "</td>\n  </tr>\n";
201         }
202
203         ($first_nick, $second_nick) = sort_by_field ('smiley_sad');
204         if ($first_nick)
205         {
206                 my $percent = 100 * $CalcData->{$first_nick}{'smiley_sad'} / $CalcData->{$first_nick}{'lines'};
207                 my $trans = translate ('sad0: %s %2.1f%%');
208                 $first_name = nick_to_name ($first_nick) || $first_nick;
209
210                 print $fh "  <tr>\n    <td>";
211                 printf $fh ($trans, $first_name, $percent);
212                 
213                 if ($second_nick)
214                 {
215                         $percent = 100 * $CalcData->{$second_nick}{'smiley_sad'} / $CalcData->{$second_nick}{'lines'};
216                         $trans = translate ('sad1: %s %2.1f%%');
217                         $second_name = nick_to_name ($second_nick) || $second_nick;
218
219                         print $fh "<br />\n",
220                         qq#      <span class="small">#;
221                         printf $fh ($trans, $second_name, $percent);
222                         print $fh "</span>";
223                 }
224                 
225                 print $fh "</td>\n  </tr>\n";
226         }
227
228         {
229                 my @names = sort_by_field ('chars');
230                 
231                 my $longest = '';
232                 my $longest2 = '';
233                 my $shortest = '';
234                 my $shortest2 = '';
235                 
236                 my $chan_chars = 0;
237                 my $chan_lines = 0;
238                 
239                 for (@names)
240                 {
241                         $chan_chars += $CalcData->{$_}{'chars'} || 0;
242                         $chan_lines += $CalcData->{$_}{'lines'} || 0;
243                 }
244
245                 if (@names)
246                 {
247                         $longest = shift (@names);
248                 }
249                 if (@names)
250                 {
251                         $longest2 = shift (@names);
252                 }
253                 if (@names)
254                 {
255                         $shortest = pop (@names);
256                 }
257                 if (@names)
258                 {
259                         $shortest2 = pop (@names);
260                 }
261                 
262                 if ($longest)
263                 {
264                         my $avg = $CalcData->{$longest}{'chars'} / $CalcData->{$longest}{'lines'};
265                         my $trans = translate ('max chars0: %s %1.1f');
266                         $first_name = nick_to_name ($longest) || $longest;
267                         
268                         print $fh "  <tr>\n    <td>";
269                         printf $fh ($trans, $first_name, $avg);
270                         
271                         if ($longest2)
272                         {
273                                 $avg = $CalcData->{$longest2}{'chars'} / $CalcData->{$longest2}{'lines'};
274                                 $trans = translate ('max chars1: %s %1.1f');
275                                 $second_name = nick_to_name ($longest2) || $longest2;
276
277                                 print $fh "<br />\n",
278                                 qq#      <span class="small">#;
279                                 printf $fh ($trans, $second_name, $avg);
280                                 print $fh "</span>";
281                         }
282
283                         $avg = $chan_chars / $chan_lines;
284                         $trans = translate ('chars avg: %1.1f');
285
286                         print $fh "<br />\n",
287                         qq#      <span class="small">#;
288                         printf $fh ($trans, $avg);
289                         print $fh "</span></td>\n  </tr>\n";
290                 }
291
292                 if ($shortest)
293                 {
294                         my $avg = $CalcData->{$shortest}{'chars'} / $CalcData->{$shortest}{'lines'};
295                         my $trans = translate ('min chars0: %s %1.1f');
296                         $first_name = nick_to_name ($shortest) || $shortest;
297                         
298                         print $fh "  <tr>\n    <td>";
299                         printf $fh ($trans, $first_name, $avg);
300                         
301                         if ($shortest2)
302                         {
303                                 $avg = $CalcData->{$shortest2}{'chars'} / $CalcData->{$shortest2}{'lines'};
304                                 $trans = translate ('min chars1: %s %1.1f');
305                                 $second_name = nick_to_name ($shortest2) || $shortest2;
306
307                                 print $fh "<br />\n",
308                                 qq#      <span class="small">#;
309                                 printf $fh ($trans, $second_name, $avg);
310                                 print $fh "</span>";
311                         }
312                         print $fh "</td>\n  </tr>\n";
313                 }
314         }
315         
316         {
317                 my @names = sort_by_field ('words');
318
319                 $first_nick = '';
320                 $second_nick = '';
321
322                 my $chan_words = 0;
323                 my $chan_lines = 0;
324                 
325                 for (@names)
326                 {
327                         $chan_words += $CalcData->{$_}{'words'} || 0;
328                         $chan_lines += $CalcData->{$_}{'lines'} || 0;
329                 }
330                 
331                 if (@names)
332                 {
333                         $first_nick = shift (@names);
334                 }
335                 if (@names)
336                 {
337                         $second_nick = shift (@names);
338                 }
339
340                 if ($first_nick)
341                 {
342                         my $avg = $CalcData->{$first_nick}{'words'} / $CalcData->{$first_nick}{'lines'};
343                         my $trans = translate ('max words0: %s %1.1f');
344                         $first_name = nick_to_name ($first_nick) || $first_nick;
345                         
346                         print $fh "  <tr>\n    <td>";
347                         printf $fh ($trans, $first_name, $avg);
348
349                         if ($second_nick)
350                         {
351                                 $avg = $CalcData->{$second_nick}{'words'} / $CalcData->{$second_nick}{'lines'};
352                                 $trans = translate ('max words1: %s %1.1f');
353                                 $second_name = nick_to_name ($second_nick) || $second_nick;
354
355                                 print $fh "<br />\n",
356                                 qq#      <span class="small">#;
357                                 printf $fh ($trans, $second_name, $avg);
358                                 print $fh "</span>";
359                         }
360
361                         $avg = $chan_words / $chan_lines;
362                         $trans = translate ('words avg: %1.1f');
363                         
364                         print $fh "<br />\n",
365                         qq#      <span class="small">#;
366                         printf $fh ($trans, $avg);
367                         print $fh "</span></td>\n  </tr>\n";
368                 }
369         }
370
371         print $fh "</table>\n\n";
372 }
373
374 sub sort_by_field
375 {
376         my $field = shift;
377
378         my @retval = sort
379         {
380                 ($CalcData->{$b}{$field} / $CalcData->{$b}{'lines'})
381                 <=>
382                 ($CalcData->{$a}{$field} / $CalcData->{$a}{'lines'})
383         } grep
384         {
385                 defined ($CalcData->{$_}{'lines'})
386                         and ($CalcData->{$_}{'lines'} != 0)
387                         and defined ($CalcData->{$_}{$field})
388         }
389         (keys (%$CalcData));
390         
391         while (scalar (@retval) < 2)
392         {
393                 push (@retval, '');
394         }
395
396         return (@retval);
397 }
398
399 sub get_bignumbers
400 {
401         my $nick = shift;
402
403         if (!defined ($CalcData->{$nick}))
404         {
405                 return ({});
406         }
407
408         return ($CalcData->{$nick});
409 }