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