First runnable version. Still many bugs. To be continued..
[onis.git] / lib / Onis / Plugins / Interestingnumbers.pm
1 package Onis::Plugins::Interestingnumbers;
2
3 use strict;
4 use warnings;
5
6 use Exporter;
7
8 use Onis::Config (qw(get_config));
9 use Onis::Html (qw(html_escape get_filehandle));
10 use Onis::Language (qw(translate));
11 use Onis::Data::Core (qw(register_plugin));
12 use Onis::Data::Persistent;
13 use Onis::Users (qw(nick_to_name));
14
15 @Onis::Plugins::Interestingnumbers::EXPORT_OK = (qw(get_interestingnumbers));
16 @Onis::Plugins::Interestingnumbers::ISA = ('Exporter');
17
18 register_plugin ('ACTION', \&add_action);
19 register_plugin ('JOIN', \&add_join);
20 register_plugin ('KICK', \&add_kick);
21 register_plugin ('MODE', \&add_mode);
22 register_plugin ('TEXT', \&add_text);
23 register_plugin ('OUTPUT', \&output);
24
25 our $InterestingNumbersCache = Onis::Data::Persistent->new ('InterestingNumbersCache', 'nick',
26         qw(actions joins kicks_given kicks_received ops_given ops_taken soliloquies));
27 our $InterestingNumbersData = {};
28
29 our $SoliloquiesNick = '';
30 our $SoliloquiesCount = 0;
31
32 our $SOLILOQUIES_COUNT = 5;
33 if (get_config ('soliloquies_count'))
34 {
35         my $tmp = get_config ('soliloquies_count');
36         $tmp =~ s/\D//g;
37
38         $SOLILOQUIES_COUNT = $tmp if ($tmp);
39 }
40                 
41 my $VERSION = '$Id$';
42 print STDERR $/, __FILE__, ": $VERSION" if ($::DEBUG);
43
44 return (1);
45
46 sub get_or_empty
47 {
48         my $nick = shift;
49         my @data = $InterestingNumbersCache->get ($nick);
50         @data = (0, 0, 0, 0, 0, 0, 0) unless (@data);
51         return (@data);
52 }
53
54 sub add_action
55 {
56         my $data = shift;
57         my $nick = $data->{'nick'};
58
59         my @data = get_or_empty ($nick);
60         $data[0]++;
61         $InterestingNumbersCache->put ($nick, @data);
62 }
63
64 sub add_join
65 {
66         my $data = shift;
67         my $nick = $data->{'nick'};
68
69         my @data = get_or_empty ($nick);
70         $data[1]++;
71         $InterestingNumbersCache->put ($nick, @data);
72 }
73
74 sub add_kick
75 {
76         my $data = shift;
77
78         my $nick_g = $data->{'nick'};
79         my $nick_r = $data->{'nick_received'};
80
81         my @data = get_or_empty ($nick_g);
82         $data[2]++;
83         $InterestingNumbersCache->put ($nick_g, @data);
84
85         @data = get_or_empty ($nick_r);
86         $data[3]++;
87         $InterestingNumbersCache->put ($nick_r, @data);
88 }
89
90 sub add_mode
91 {
92         my $data = shift;
93
94         my $nick = $data->{'nick'};
95         my $text = $data->{'mode'};
96         
97         my ($mode) = split (m/\s+/, $text);
98         my $modifier = '';
99
100         for (split (m//, $mode))
101         {
102                 my $tmp = $_;
103                 if (($tmp eq '-') or ($tmp eq '+'))
104                 {
105                         $modifier = $tmp;
106                         next;
107                 }
108
109                 next unless ($modifier);
110                 
111                 if ($tmp eq 'o')
112                 {
113                         my @data = get_or_empty ($nick);
114                         if ($modifier eq '-')
115                         {
116                                 $data[5]++;
117                         }
118                         else # ($modifier eq '+')
119                         {
120                                 $data[4]++;
121                         }
122                 }
123         }
124
125         return (1);
126 }
127
128 sub add_text
129 {
130         my $data = shift;
131
132         my $nick = $data->{'nick'};
133
134         if ($nick eq $SoliloquiesNick)
135         {
136                 $SoliloquiesCount++;
137
138                 if ($SoliloquiesCount == $SOLILOQUIES_COUNT)
139                 {
140                         my @data = get_or_empty ($nick);
141                         $data[6]++;
142                         $InterestingNumbersCache->put ($nick, @data);
143                 }
144         }
145         else
146         {
147                 $SoliloquiesNick = $nick;
148                 $SoliloquiesCount = 1;
149         }
150 }
151
152 sub calculate
153 {
154         for ($InterestingNumbersCache->keys ())
155         {
156                 my $nick = $_;
157                 my ($actions, $joins,
158                         $kicks_given, $kicks_received,
159                         $ops_given, $ops_taken,
160                         $soliloquies) = $InterestingNumbersCache->get ($nick);
161                 my $main = get_main_nick ($nick);
162
163                 die unless ($main);
164
165                 if (!defined ($InterestingNumbersData->{$main}))
166                 {
167                         $InterestingNumbersData->{$main} =
168                         {
169                                 actions         => 0,
170                                 joins           => 0,
171                                 kicks_given     => 0,
172                                 kicks_received  => 0,
173                                 ops_given       => 0,
174                                 ops_taken       => 0,
175                                 soliloquies     => 0
176                         };
177                 }
178
179                 $InterestingNumbersData->{$main}{'actions'}        += $actions;
180                 $InterestingNumbersData->{$main}{'joins'}          += $joins;
181                 $InterestingNumbersData->{$main}{'kicks_given'}    += $kicks_given;
182                 $InterestingNumbersData->{$main}{'kicks_received'} += $kicks_received;
183                 $InterestingNumbersData->{$main}{'ops_given'}      += $ops_given;
184                 $InterestingNumbersData->{$main}{'ops_taken'}      += $ops_taken;
185                 $InterestingNumbersData->{$main}{'soliloquies'}    += $soliloquies;
186         }
187 }
188
189
190
191
192 sub output
193 {
194         calculate ();
195         
196         my $first_nick;
197         my $first_name;
198         my $second_nick;
199         my $second_name;
200
201         my $fh = get_filehandle ();
202
203         my $trans = translate ('Interesting Numbers');
204         
205         print $fh <<EOF;
206 <table class="plugin interestingnumbers">
207   <tr>
208     <th>$trans</th>
209   </tr>
210 EOF
211         ($first_nick, $second_nick) = sort_by_field ('kick_received');
212         if ($first_nick)
213         {
214                 my $num = $InterestingNumbersData->{$first_nick}{'kick_received'};
215                 $trans = translate ('kick_received0: %s %u');
216                 $first_name = nick_to_name ($first_nick) || $first_nick;
217
218                 print $fh "  <tr>\n    <td>";
219                 printf $fh ($trans, $first_nick, $num);
220                 
221                 if ($second_nick)
222                 {
223                         $num = $InterestingNumbersData->{$second_nick}{'kick_received'};
224                         $trans = translate ('kick_received1: %s %u');
225                         $second_name = nick_to_name ($second_nick) || $second_nick;
226
227                         print $fh "<br />\n",
228                         qq#      <span class="small">#;
229                         printf $fh ($trans, $second_nick, $num);
230                         print $fh '</span>';
231                 }
232                 
233                 print $fh "</td>\n  </tr>\n";
234         }
235
236         ($first_nick, $second_nick) = sort_by_field ('kick_given');
237         if ($first_nick)
238         {
239                 my $num = $InterestingNumbersData->{$first_nick}{'kick_given'};
240                 $trans = translate ('kick_given0: %s %u');
241                 $first_name = nick_to_name ($first_nick) || $first_nick;
242
243                 print $fh "  <tr>\n    <td>";
244                 printf $fh ($trans, $first_name, $num);
245
246                 if ($second_nick)
247                 {
248                         $num = $InterestingNumbersData->{$second_nick}{'kick_given'};
249                         $trans = translate ('kick_given1: %s %u');
250                         $second_name = nick_to_name ($second_nick) || $second_nick;
251
252                         print $fh "<br />\n",
253                         qq#      <span class="small">#;
254                         printf $fh ($trans, $second_name, $num);
255                         print $fh '</span>';
256                 }
257
258                 print $fh "</td>\n  </tr>\n";
259         }
260
261         ($first_nick, $second_nick) = sort_by_field ('op_given');
262         if ($first_nick)
263         {
264                 my $num = $InterestingNumbersData->{$first_nick}{'op_given'};
265                 $trans = translate ('op_given0: %s %u');
266                 $first_name = nick_to_name ($first_nick) || $first_nick;
267
268                 print $fh "  <tr>\n    <td>";
269                 printf $fh ($trans, $first_name, $num);
270                 
271                 if ($second_nick)
272                 {
273                         $num = $InterestingNumbersData->{$second_nick}{'op_given'};
274                         $trans = translate ('op_given1: %s %u');
275                         $second_name = nick_to_name ($second_nick) || $second_nick;
276
277                         print $fh "<br />\n",
278                         qq#      <span class="small">#;
279                         printf $fh ($trans, $second_name, $num);
280                         print $fh '</span>';
281                 }
282                 
283                 print $fh "</td>\n  </tr>\n";
284         }
285
286         ($first_nick, $second_nick) = sort_by_field ('op_taken');
287         if ($first_nick)
288         {
289                 my $num = $InterestingNumbersData->{$first_nick}{'op_taken'};
290                 $trans = translate ('op_taken0: %s %u');
291                 $first_name = nick_to_name ($first_nick) || $first_nick;
292
293                 print $fh "  <tr>\n    <td>";
294                 printf $fh ($trans, $first_name, $num);
295                 
296                 if ($second_nick)
297                 {
298                         $num = $InterestingNumbersData->{$second_nick}{'op_taken'};
299                         $trans = translate ('op_taken1: %s %u');
300                         $second_name = nick_to_name ($second_nick) || $second_nick;
301
302                         print $fh "<br />\n",
303                         qq#      <span class="small">#;
304                         printf $fh ($trans, $second_name, $num);
305                         print $fh '</span>';
306                 }
307                 
308                 print $fh "</td>\n  </tr>\n";
309         }
310
311         ($first_nick, $second_nick) = sort_by_field ('actions');
312         if ($first_nick)
313         {
314                 my $num = $InterestingNumbersData->{$first_nick}{'actions'};
315                 $trans = translate ('action0: %s %u');
316                 $first_name = nick_to_name ($first_nick) || $first_nick;
317
318                 print $fh "  <tr>\n    <td>";
319                 printf $fh ($trans, $first_name, $num);
320                 
321                 if ($second_nick)
322                 {
323                         $num = $InterestingNumbersData->{$second_nick}{'actions'};
324                         $trans = translate ('action1: %s %u');
325                         $second_name = nick_to_name ($second_nick) || $second_nick;
326
327                         print $fh "<br />\n",
328                         qq#      <span class="small">#;
329                         printf $fh ($trans, $second_name, $num);
330                         print $fh '</span>';
331                 }
332
333                 print $fh "</td>\n  </tr>\n";
334         }
335         
336         ($first_nick, $second_nick) = sort_by_field ('soliloquies');
337         if ($first_nick)
338         {
339                 my $num = $InterestingNumbersData->{$first_nick}{'soliloquies'};
340                 $trans = translate ('soliloquies0: %s %u');
341                 $first_name = nick_to_name ($first_nick) || $first_nick;
342
343                 print $fh "  <tr>\n    <td>";
344                 printf $fh ($trans, $first_name, $num);
345                 
346                 if ($second_nick)
347                 {
348                         $num = $InterestingNumbersData->{$second_nick}{'soliloquies'};
349                         $trans = translate ('soliloquies1: %s %u');
350                         $second_name = nick_to_name ($second_nick) || $second_nick;
351
352                         print $fh "<br />\n",
353                         qq#      <span class="small">#;
354                         printf $fh ($trans, $second_name, $num);
355                         print $fh '</span>';
356                 }
357
358                 print $fh "</td>\n  </tr>\n";
359         }
360         
361         ($first_nick, $second_nick) = sort_by_field ('joins');
362         if ($first_nick)
363         {
364                 my $num = $InterestingNumbersData->{$first_nick}{'joins'};
365                 $trans = translate ('joins0: %s %u');
366                 $first_name = nick_to_name ($first_nick) || $first_nick;
367
368                 print $fh "  <tr>\n    <td>";
369                 printf $fh ($trans, $first_name, $num);
370                 
371                 if ($second_nick)
372                 {
373                         $num = $InterestingNumbersData->{$second_nick}{'joins'};
374                         $trans = translate ('joins1: %s %u');
375                         $second_name = nick_to_name ($second_nick) || $second_nick;
376
377                         print $fh "<br />\n",
378                         qq#      <span class="small">#;
379                         printf $fh ($trans, $second_name, $num);
380                         print $fh '</span>';
381                 }
382
383                 print $fh "</td>\n  </tr>\n";
384         }
385
386         print $fh "</table>\n\n";
387 }
388
389 sub sort_by_field
390 {
391         my $field = shift;
392         
393         my @retval = sort
394         {
395                 $InterestingNumbersData->{$b}{$field}
396                 <=>
397                 $InterestingNumbersData->{$a}{$field}
398         } (keys (%$InterestingNumbersData));
399
400         while (scalar (@retval) < 2)
401         {
402                 push (@retval, '');
403         }
404         
405         return (@retval);
406 }
407
408 sub get_interestingnumbers
409 {
410         my $nick = shift;
411
412         if (defined ($InterestingNumbersData->{$nick}))
413         {
414                 return ({});
415         }
416
417         return ($InterestingNumbersData->{$nick});
418 }