7e3793518782e08dab3f55cabf4ccc05fb2ebdde
[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                 require Data::Dumper;
110                 print STDOUT Data::Dumper->Dump ([$CalcData->{$main}], ["CalcData->{$main}"]);
111         }
112 }
113
114 sub output
115 {
116         calculate ();
117
118         my $first_nick;
119         my $first_name;
120         my $second_nick;
121         my $second_name;
122         my $trans;
123
124         my $fh = get_filehandle ();
125         
126         $trans = translate ('Big Numbers');
127         print $fh <<EOF;
128 <table class="plugin bignumbers">
129   <tr>
130     <th>$trans</th>
131   </tr>
132 EOF
133         ($first_nick, $second_nick) = sort_by_field ('questions');
134         if ($first_nick)
135         {
136                 my $percent = 100 * $CalcData->{$first_nick}{'questions'} / $CalcData->{$first_nick}{'lines'};
137                 my $trans = translate ('questions0: %s %2.1f%%');
138                 $first_name = nick_to_name ($first_nick) || $first_nick;
139
140                 print $fh "  <tr>\n    <td>";
141                 printf $fh ($trans, $first_name, $percent);
142                 
143                 if ($second_nick)
144                 {
145                         $percent = 100 * $CalcData->{$second_nick}{'questions'} / $CalcData->{$second_nick}{'lines'};
146                         $trans = translate ('questions1: %s %2.1f%%');
147                         $second_name = nick_to_name ($second_nick) || $second_nick;
148
149                         print $fh "<br />\n",
150                         qq#      <span class="small">#;
151                         printf $fh ($trans, $second_name, $percent);
152                         print $fh '</span>';
153                 }
154                 
155                 print $fh "</td>\n  </tr>\n";
156         }
157
158         ($first_nick, $second_nick) = sort_by_field ('uppercase');
159         if ($first_nick)
160         {
161                 my $percent = 100 * $CalcData->{$first_nick}{'uppercase'} / $CalcData->{$first_nick}{'lines'};
162                 my $trans = translate ('yells0: %s %2.1f%%');
163                 $first_name = nick_to_name ($first_nick) || $first_nick;
164
165                 print $fh "  <tr>\n    <td>";
166                 printf $fh ($trans, $first_name, $percent);
167
168                 if ($second_nick)
169                 {
170                         $percent = 100 * $CalcData->{$second_nick}{'uppercase'} / $CalcData->{$second_nick}{'lines'};
171                         $trans = translate ('yells1: %s %2.1f%%');
172                         $second_name = nick_to_name ($second_nick) || $second_nick;
173
174                         print $fh "<br />\n",
175                         qq#      <span class="small">#;
176                         printf $fh ($trans, $second_name, $percent);
177                         print $fh "</span>";
178                 }
179
180                 print $fh "</td>\n  </tr>\n";
181         }
182
183         ($first_nick, $second_nick) = sort_by_field ('smiley_happy');
184         if ($first_nick)
185         {
186                 my $percent = 100 * $CalcData->{$first_nick}{'smiley_happy'} / $CalcData->{$first_nick}{'lines'};
187                 my $trans = translate ('happy0: %s %2.1f%%');
188                 $first_name = nick_to_name ($first_nick) || $first_nick;
189
190                 print $fh "  <tr>\n    <td>";
191                 printf $fh ($trans, $first_name, $percent);
192                 
193                 if ($second_nick)
194                 {
195                         $percent = 100 * $CalcData->{$second_nick}{'smiley_happy'} / $CalcData->{$second_nick}{'lines'};
196                         $trans = translate ('happy1: %s %2.1f%%');
197                         $second_name = nick_to_name ($second_nick) || $second_nick;
198
199                         print $fh "<br />\n",
200                         qq#      <span class="small">#;
201                         printf $fh ($trans, $second_name, $percent);
202                         print $fh "</span>";
203                 }
204                 
205                 print $fh "</td>\n  </tr>\n";
206         }
207
208         ($first_nick, $second_nick) = sort_by_field ('smiley_sad');
209         if ($first_nick)
210         {
211                 my $percent = 100 * $CalcData->{$first_nick}{'smiley_sad'} / $CalcData->{$first_nick}{'lines'};
212                 my $trans = translate ('sad0: %s %2.1f%%');
213                 $first_name = nick_to_name ($first_nick) || $first_nick;
214
215                 print $fh "  <tr>\n    <td>";
216                 printf $fh ($trans, $first_name, $percent);
217                 
218                 if ($second_nick)
219                 {
220                         $percent = 100 * $CalcData->{$second_nick}{'smiley_sad'} / $CalcData->{$second_nick}{'lines'};
221                         $trans = translate ('sad1: %s %2.1f%%');
222                         $second_name = nick_to_name ($second_nick) || $second_nick;
223
224                         print $fh "<br />\n",
225                         qq#      <span class="small">#;
226                         printf $fh ($trans, $second_name, $percent);
227                         print $fh "</span>";
228                 }
229                 
230                 print $fh "</td>\n  </tr>\n";
231         }
232
233         {
234                 my @names = sort_by_field ('chars');
235                 
236                 my $longest = '';
237                 my $longest2 = '';
238                 my $shortest = '';
239                 my $shortest2 = '';
240                 
241                 my $chan_chars = 0;
242                 my $chan_lines = 0;
243                 
244                 for (@names)
245                 {
246                         $chan_chars += $CalcData->{$_}{'chars'} || 0;
247                         $chan_lines += $CalcData->{$_}{'lines'} || 0;
248                 }
249
250                 if (@names)
251                 {
252                         $longest = shift (@names);
253                 }
254                 if (@names)
255                 {
256                         $longest2 = shift (@names);
257                 }
258                 if (@names)
259                 {
260                         $shortest = pop (@names);
261                 }
262                 if (@names)
263                 {
264                         $shortest2 = pop (@names);
265                 }
266                 
267                 if ($longest)
268                 {
269                         my $avg = $CalcData->{$longest}{'chars'} / $CalcData->{$longest}{'lines'};
270                         my $trans = translate ('max chars0: %s %1.1f');
271                         $first_name = nick_to_name ($longest) || $longest;
272                         
273                         print $fh "  <tr>\n    <td>";
274                         printf $fh ($trans, $first_name, $avg);
275                         
276                         if ($longest2)
277                         {
278                                 $avg = $CalcData->{$longest2}{'chars'} / $CalcData->{$longest2}{'lines'};
279                                 $trans = translate ('max chars1: %s %1.1f');
280                                 $second_name = nick_to_name ($longest2) || $longest2;
281
282                                 print $fh "<br />\n",
283                                 qq#      <span class="small">#;
284                                 printf $fh ($trans, $second_name, $avg);
285                                 print $fh "</span>";
286                         }
287
288                         $avg = $chan_chars / $chan_lines;
289                         $trans = translate ('chars avg: %1.1f');
290
291                         print $fh "<br />\n",
292                         qq#      <span class="small">#;
293                         printf $fh ($trans, $avg);
294                         print $fh "</span></td>\n  </tr>\n";
295                 }
296
297                 if ($shortest)
298                 {
299                         my $avg = $CalcData->{$shortest}{'chars'} / $CalcData->{$shortest}{'lines'};
300                         my $trans = translate ('min chars0: %s %1.1f');
301                         $first_name = nick_to_name ($shortest) || $shortest;
302                         
303                         print $fh "  <tr>\n    <td>";
304                         printf $fh ($trans, $first_name, $avg);
305                         
306                         if ($shortest2)
307                         {
308                                 $avg = $CalcData->{$shortest2}{'chars'} / $CalcData->{$shortest2}{'lines'};
309                                 $trans = translate ('min chars1: %s %1.1f');
310                                 $second_name = nick_to_name ($shortest2) || $shortest2;
311
312                                 print $fh "<br />\n",
313                                 qq#      <span class="small">#;
314                                 printf $fh ($trans, $second_name, $avg);
315                                 print $fh "</span>";
316                         }
317                         print $fh "</td>\n  </tr>\n";
318                 }
319         }
320         
321         {
322                 my @names = sort_by_field ('words');
323
324                 $first_nick = '';
325                 $second_nick = '';
326
327                 my $chan_words = 0;
328                 my $chan_lines = 0;
329                 
330                 for (@names)
331                 {
332                         $chan_words += $CalcData->{$_}{'words'} || 0;
333                         $chan_lines += $CalcData->{$_}{'lines'} || 0;
334                 }
335                 
336                 if (@names)
337                 {
338                         $first_nick = shift (@names);
339                 }
340                 if (@names)
341                 {
342                         $second_nick = shift (@names);
343                 }
344
345                 if ($first_nick)
346                 {
347                         my $avg = $CalcData->{$first_nick}{'words'} / $CalcData->{$first_nick}{'lines'};
348                         my $trans = translate ('max words0: %s %1.1f');
349                         $first_name = nick_to_name ($first_nick) || $first_nick;
350                         
351                         print $fh "  <tr>\n    <td>";
352                         printf $fh ($trans, $first_name, $avg);
353
354                         if ($second_nick)
355                         {
356                                 $avg = $CalcData->{$second_nick}{'words'} / $CalcData->{$second_nick}{'lines'};
357                                 $trans = translate ('max words1: %s %1.1f');
358                                 $second_name = nick_to_name ($second_nick) || $second_nick;
359
360                                 print $fh "<br />\n",
361                                 qq#      <span class="small">#;
362                                 printf $fh ($trans, $second_name, $avg);
363                                 print $fh "</span>";
364                         }
365
366                         $avg = $chan_words / $chan_lines;
367                         $trans = translate ('words avg: %1.1f');
368                         
369                         print $fh "<br />\n",
370                         qq#      <span class="small">#;
371                         printf $fh ($trans, $avg);
372                         print $fh "</span></td>\n  </tr>\n";
373                 }
374         }
375
376         print $fh "</table>\n\n";
377 }
378
379 sub sort_by_field
380 {
381         my $field = shift;
382
383         my @retval = sort
384         {
385                 ($CalcData->{$b}{$field} / $CalcData->{$b}{'lines'})
386                 <=>
387                 ($CalcData->{$a}{$field} / $CalcData->{$a}{'lines'})
388         } grep
389         {
390                 defined ($CalcData->{$_}{'lines'})
391                         and ($CalcData->{$_}{'lines'} != 0)
392                         and defined ($CalcData->{$_}{$field})
393         }
394         (keys (%$CalcData));
395         
396         while (scalar (@retval) < 2)
397         {
398                 push (@retval, '');
399         }
400
401         return (@retval);
402 }
403
404 sub get_bignumbers
405 {
406         my $nick = shift;
407
408         if (!defined ($CalcData->{$nick}))
409         {
410                 return ({});
411         }
412
413         return ($CalcData->{$nick});
414 }