Some work on Userdetails, minor changes/fixes in Core, Conversations and Bignumbers..
[onis.git] / lib / Onis / Plugins / Userdetails.pm
1 package Onis::Plugins::Userdetails;
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::Users (qw(ident_to_name get_link get_image));
11
12 use Onis::Plugin::Core (qw(get_core_nick_counters));
13 use Onis::Plugin::Conversations (qw(get_conversations));
14
15 our $DISPLAY_IMAGES = 0;
16 our $DEFAULT_IMAGE = '';
17
18 register_plugin ('OUTPUT', \&output);
19
20 our $SORT_BY = 'lines';
21 if (get_config ('sort_by'))
22 {
23         my $tmp = get_config ('sort_by');
24         $tmp = lc ($tmp);
25
26         if (($tmp eq 'lines') or ($tmp eq 'words') or ($tmp eq 'chars'))
27         {
28                 $SORT_BY = $tmp;
29         }
30         else
31         {
32                 # The Core plugin already complained about this..
33         }
34 }
35 our $PLUGIN_MAX = 10;
36 if (get_config ('plugin_max'))
37 {
38         my $tmp = get_config ('plugin_max');
39         $tmp =~ s/\D//g;
40         $PLUGIN_MAX = $tmp if ($tmp);
41 }
42 if (get_config ('display_images'))
43 {
44         my $tmp = get_config ('display_images');
45
46         if ($tmp =~ m/true|on|yes/i)
47         {
48                 $DISPLAY_IMAGES = 1;
49         }
50         elsif ($tmp =~ m/false|off|no/i)
51         {
52                 $DISPLAY_IMAGES = 0;
53         }
54         else
55         {
56                 print STDERR $/, __FILE__, ": ``display_times'' has been set to the invalid value ``$tmp''. ",
57                 $/, __FILE__, ": Valid values are ``true'' and ``false''. Using default value ``false''.";
58         }
59 }
60 if (get_config ('default_image'))
61 {
62         $DEFAULT_IMAGE = get_config ('default_image');
63 }
64
65 our @H_IMAGES = qw#dark-theme/h-red.png dark-theme/h-blue.png dark-theme/h-yellow.png dark-theme/h-green.png#;
66 if (get_config ('horizontal_images'))
67 {
68         my @tmp = get_config ('horizontal_images');
69         my $i;
70         
71         if (scalar (@tmp) != 4)
72         {
73                 # Do nothing:
74                 # The core-pligin already complained about this..
75         }
76
77         for ($i = 0; $i < 4; $i++)
78         {
79                 if (!defined ($tmp[$i]))
80                 {
81                         next;
82                 }
83
84                 $H_IMAGES[$i] = $tmp[$i];
85         }
86 }
87
88 our @V_IMAGES = qw#images/ver0n.png images/ver1n.png images/ver2n.png images/ver3n.png#;
89 if (get_config ('vertical_images'))
90 {
91         my @tmp = get_config ('vertical_images');
92         my $i;
93         
94         if (scalar (@tmp) != 4)
95         {
96                 # Do nothing:
97                 # Hopefully someone complained by now..
98         }
99
100         for ($i = 0; $i < 4; $i++)
101         {
102                 if (!defined ($tmp[$i]))
103                 {
104                         next;
105                 }
106
107                 $V_IMAGES[$i] = $tmp[$i];
108         }
109 }
110
111 our $BAR_HEIGHT = 130;
112 if (get_config ('bar_height'))
113 {
114         my $tmp = get_config ('bar_height');
115         $tmp =~ s/\D//g;
116         $BAR_HEIGHT = $tmp if ($tmp >= 10);
117 }
118 #$BAR_HEIGHT = int ($BAR_HEIGHT / 2);
119
120 our $BAR_WIDTH  = 100;
121 if (get_config ('bar_width'))
122 {
123         my $tmp = get_config ('bar_width');
124         $tmp =~ s/\D//g;
125         $BAR_WIDTH = $tmp if ($tmp >= 10);
126 }
127
128 my $VERSION = '$Id: Userdetails.pm,v 1.5 2005/03/14 18:40:25 octo Exp $';
129 print STDERR $/, __FILE__, ": $VERSION" if ($::DEBUG);
130
131 return (1);
132
133 sub output
134 {
135         my $nicks_ref = get_sorted_nicklist ();
136         
137         my $max = $PLUGIN_MAX;
138         
139         my $fh = get_filehandle ();
140
141         my $trans = translate ('Detailed nick stats');
142         my $num;
143
144         my $max_time = 0;
145         my $max_conv = 0;
146
147         my @nicks = $nicks_ref->[0 .. ($max - 1)];
148         my $nick_data = {};
149
150         for (@nicks)
151         {
152                 my $nick = $_;
153
154                 $nick_data->{$nick} = get_core_nick_counters ($nick);
155                 $nick_data->{$nick}{'conversations'} = get_conversations ($nick);
156                 
157                 if (defined ($DATA->{'byname'}{$name}{'chars_time'}))
158                 {
159                         for (0..23)
160                         {
161                                 next unless (defined ($DATA->{'byname'}{$name}{'chars_time'}{$_}));
162                                 if ($DATA->{'byname'}{$name}{'chars_time'}{$_} > $max_time)
163                                 {
164                                         $max_time = $DATA->{'byname'}{$name}{'chars_time'}{$_};
165                                 }
166                         }
167                 }
168                 if (defined ($DATA->{'byname'}{$name}{'conversations'}))
169                 {
170                         my @others = keys (%{$DATA->{'byname'}{$name}{'conversations'}});
171                         for (@others)
172                         {
173                                 my $o = $_;
174                                 my $num = 0;
175
176                                 for (0..3)
177                                 {
178                                         $num += $DATA->{'byname'}{$name}{'conversations'}{$o}[$_];
179                                 }
180
181                                 if ($num > $max_conv)
182                                 {
183                                         $max_conv = $num;
184                                 }
185                         }
186                 }
187         }
188
189         my $time_factor = 0;
190         my $conv_factor = 0;
191
192         if ($max_time)
193         {
194                 $time_factor = $BAR_HEIGHT / $max_time;
195         }
196
197         if ($max_conv)
198         {
199                 $conv_factor = $BAR_WIDTH / $max_conv;
200         }
201         
202         print $fh qq#<table class="plugin userdetails">\n#,
203         qq#  <tr>\n#,
204         qq#    <th colspan="#, $DISPLAY_IMAGES ? 3 : 2, qq#">$trans</th>\n#,
205         qq#  </tr>\n#;
206
207         for (@names)
208         {
209                 my $name = $_;
210
211                 print $fh qq#  <tr>\n#,
212                 qq#    <th colspan="#, $DISPLAY_IMAGES ? 3 : 2, qq#" class="nick">$name</th>\n#,
213                 qq#  </tr>\n#,
214                 qq#  <tr>\n#;
215
216                 if ($DISPLAY_IMAGES)
217                 {
218                         my $link = get_link ($name);
219                         my $image = get_image ($name);
220                         
221                         if ($DEFAULT_IMAGE and !$image)
222                         {
223                                 $image = $DEFAULT_IMAGE;
224                         }
225
226                         print $fh qq#    <td class="image" rowspan="2">#;
227                         if ($image)
228                         {
229                                 if ($link)
230                                 {
231                                         print $fh qq#<a href="$link">#;
232                                 }
233                                 print $fh qq#<img src="$image" alt="$name" />#;
234                                 if ($link)
235                                 {
236                                         print $fh "</a>";
237                                 }
238                         }
239                         else
240                         {
241                                 print $fh '&nbsp;';
242                         }
243                         print $fh "</td>\n";
244                 }
245
246                 print $fh qq#    <td class="counters">\n#;
247
248                 $num = $DATA->{'byname'}{$name}{'lines'};
249                 $trans = translate ('Has written %u lines');
250                 printf $fh ("      $trans<br />\n", $num);
251
252                 $num = $DATA->{'byname'}{$name}{'words'};
253                 $trans = translate ('Has written %u words');
254                 printf $fh ("      $trans<br />\n", $num);
255
256                 $num = $DATA->{'byname'}{$name}{'chars'};
257                 $trans = translate ('Has written %u chars');
258                 printf $fh ("      $trans<br />\n", $num);
259
260                 if ($DATA->{'byname'}{$name}{'lines'})
261                 {
262                         $num = $DATA->{'byname'}{$name}{'words'} / $DATA->{'byname'}{$name}{'lines'};
263                         $trans = translate ('Has written %.1f words per line');
264                         printf $fh ("      $trans<br />\n", $num);
265
266                         $num = $DATA->{'byname'}{$name}{'chars'} / $DATA->{'byname'}{$name}{'lines'};
267                         $trans = translate ('Has written %.1f characters per line');
268                         printf $fh ("      $trans<br />\n", $num);
269                 }
270
271                 print $fh qq#    </td>\n    <td class="numbers">\n#;
272
273                 if (defined ($DATA->{'byname'}{$name}{'op_given'}))
274                 {
275                         $num = $DATA->{'byname'}{$name}{'op_given'};
276                         $trans = translate ('Has given %u ops');
277
278                         printf $fh ("      $trans<br />\n", $num);
279                 }
280                 
281                 if (defined ($DATA->{'byname'}{$name}{'op_taken'}))
282                 {
283                         $num = $DATA->{'byname'}{$name}{'op_taken'};
284                         $trans = translate ('Has taken %u ops');
285
286                         printf $fh ("      $trans<br />\n", $num);
287                 }
288                 
289                 if (defined ($DATA->{'byname'}{$name}{'kick_given'}))
290                 {
291                         $num = $DATA->{'byname'}{$name}{'kick_given'};
292                         $trans = translate ('Has kicked out %u people');
293
294                         printf $fh ("      $trans<br />\n", $num);
295                 }
296                 
297                 if (defined ($DATA->{'byname'}{$name}{'kick_received'}))
298                 {
299                         $num = $DATA->{'byname'}{$name}{'kick_received'};
300                         $trans = translate ('Has been kicked out %u times');
301
302                         printf $fh ("      $trans<br />\n", $num);
303                 }
304                 
305                 if (defined ($DATA->{'byname'}{$name}{'questions'}))
306                 {
307                         $num = 100 * $DATA->{'byname'}{$name}{'questions'} / $DATA->{'byname'}{$name}{'lines'};
308                         $trans = translate ("Question ratio: %.1f%%");
309
310                         printf $fh ("      $trans<br />\n", $num);
311                 }
312
313                 if (defined ($DATA->{'byname'}{$name}{'topics'}))
314                 {
315                         $num = $DATA->{'byname'}{$name}{'topics'};
316                         $trans = translate ('Has set %u topics');
317
318                         printf $fh ("      $trans<br />\n", $num);
319                 }
320
321                 if (defined ($DATA->{'byname'}{$name}{'actions'}))
322                 {
323                         $num = $DATA->{'byname'}{$name}{'actions'};
324                         $trans = translate ('Has performed %u actions');
325
326                         printf $fh ("      $trans<br />\n", $num);
327                 }
328
329                 # actions # TODO
330                 # exclamation ratio # TODO
331                 # # of nicks
332                 #
333                 # chats with
334                 # lines per day
335
336                 print $fh qq#    </td>\n  </tr>\n  <tr>\n    <td class="houractivity">\n#;
337                 
338                 if (defined ($DATA->{'byname'}{$name}{'chars_time'}))
339                 {
340                         print $fh qq#      <table class="hours_of_day">\n        <tr>\n#;
341                         
342                         for (0..11)
343                         {
344                                 my $hour = 2 * $_;
345                                 my $num = 0;
346
347                                 my $img = $V_IMAGES[int ($hour / 6)];
348                                 my $height;
349
350                                 if (defined ($DATA->{'byname'}{$name}{'chars_time'}{$hour}))
351                                 {
352                                         $num = $DATA->{'byname'}{$name}{'chars_time'}{$hour};
353                                 }
354                                 if (defined ($DATA->{'byname'}{$name}{'chars_time'}{1 + $hour}))
355                                 {
356                                         $num = $DATA->{'byname'}{$name}{'chars_time'}{1 + $hour};
357                                 }
358
359                                 $height = int (0.5 + ($time_factor * $num));
360                                 if (!$height)
361                                 {
362                                         $height = 1;
363                                 }
364
365                                 print $fh qq#          <td><img src="$img" alt="$num chars" #,
366                                 qq#style="height: ${height}px;" /></td>\n#;
367                         }
368
369                         print $fh <<EOF;
370         </tr>
371         <tr class="hour_row">
372           <td colspan="3">0-5</td>
373           <td colspan="3">6-11</td>
374           <td colspan="3">12-17</td>
375           <td colspan="3">18-23</td>
376         </tr>
377       </table>
378 EOF
379                 }
380                 else
381                 {
382                         print $fh '&nbsp;';
383                 }
384
385                 print $fh qq#    </td>\n    <td class="convpartners">\n#;
386                 
387                 if (defined ($DATA->{'byname'}{$name}{'conversations'}))
388                 {
389                         my $i;
390                         my $data = $DATA->{'byname'}{$name}{'conversations'};
391                         my @names = sort
392                         {
393                                 ($data->{$b}[0] + $data->{$b}[1] + $data->{$b}[2] + $data->{$b}[3])
394                                 <=>
395                                 ($data->{$a}[0] + $data->{$a}[1] + $data->{$a}[2] + $data->{$a}[3])
396                         }
397                         keys (%$data);
398
399                         $trans = translate ('Talks to');
400
401                         print $fh <<EOF;
402       <table>
403         <tr>
404           <td colspan="2">$trans:</td>
405         </tr>
406 EOF
407
408                         $i = 0;
409                         for (@names)
410                         {
411                                 my $this_name = $_;
412                                 my $total = 0;
413
414                                 print $fh "        <tr>\n",
415                                 qq#          <td class="nick">$this_name</td>\n#,
416                                 qq#          <td class="bar">#;
417
418                                 for (0..3)
419                                 {
420                                         my $k = $_;
421                                         
422                                         my $img = $H_IMAGES[$k];
423                                         my $width = int (0.5 + ($conv_factor * $data->{$this_name}[$_]));
424                                         if (!$width)
425                                         {
426                                                 $width = 1;
427                                         }
428                                         
429                                         print $fh qq#<img src="$img" alt="" #;
430                                         if ($k == 0)
431                                         {
432                                                 print $fh qq#class="first" #;
433                                         }
434                                         elsif ($k == 3)
435                                         {
436                                                 print $fh qq#class="last" #;
437                                         }
438                                         print $fh qq#style="width: ${width}px;" />#;
439                                 }
440                                 
441                                 print $fh "</td>\n        </tr>\n";
442
443                                 $i++;
444
445                                 if ($i >= $PLUGIN_MAX)
446                                 {
447                                         last;
448                                 }
449                         }
450
451                         print $fh "      </table>\n";
452                 }
453                 else
454                 {
455                         print $fh '&nbsp;';
456                 }
457
458                 $max--;
459                 if ($max <= 0)
460                 {
461                         last;
462                 }
463         }
464
465         print $fh "</table>\n\n";
466 }