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