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