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