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