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