Fixed major bug in Onis::Data::Core..
[onis.git] / lib / Onis / Plugins / Core.pm
index f3ace5a..ec6dc79 100644 (file)
@@ -46,7 +46,9 @@ our $NickCharsCounter = Onis::Data::Persistent->new ('NickCharsCounter', 'nick',
        )
 );
 
-our $QuoteCache = {}; # Saves per-nick information without any modification
+our $QuoteCache = Onis::Data::Persistent->new ('QuoteCache', 'key', qw(epoch text));
+our $QuotePtr = Onis::Data::Persistent->new ('QuotePtr', 'nick', qw(pointer));
+
 our $QuoteData = {};  # Is generated before output. Nicks are merged according to Data::Core.
 our $NickData = {};  # Same as above, but for nicks rather than quotes.
 our $SortedNicklist = [];
@@ -68,30 +70,69 @@ our $BAR_WIDTH  = 100;
 our $LongLines  = 50;
 our $ShortLines = 10;
 
+=head1 CONFIGURATION OPTIONS
+
+=over 4
+
+=item B<quote_cache_size>: I<10>
+
+Sets how many quotes are cached and, at the end, one is chosen at random.
+
+=cut
+
 if (get_config ('quote_cache_size'))
 {
        my $tmp = get_config ('quote_cache_size');
        $tmp =~ s/\D//g;
        $QuoteCacheSize = $tmp if ($tmp);
 }
+
+=item B<quote_min>: I<30>
+
+Minimum number of characters in a line to be included in the quote-cache.
+
+=cut
+
 if (get_config ('quote_min'))
 {
        my $tmp = get_config ('quote_min');
        $tmp =~ s/\D//g;
        $QuoteMin = $tmp if ($tmp);
 }
+=item B<quote_max>: I<80>
+
+Maximum number of characters in a line to be included in the quote-cache.
+
+=cut
+
 if (get_config ('quote_max'))
 {
        my $tmp = get_config ('quote_max');
        $tmp =~ s/\D//g;
        $QuoteMax = $tmp if ($tmp);
 }
+
+=item B<min_word_length>: I<5>
+
+Sets how many word-characters in a row are considered to be a word. Or, in more
+normal terms: Sets the minimum length for words..
+
+=cut
+
 if (get_config ('min_word_length'))
 {
        my $tmp = get_config ('min_word_length');
        $tmp =~ s/\D//g;
        $WORD_LENGTH = $tmp if ($tmp);
 }
+
+=item B<display_lines>: I<BOTH>
+
+Choses wether to display B<lines> as I<BAR>, I<NUMBER>, I<BOTH> or not at all
+(I<NONE>).
+
+=cut
+
 if (get_config ('display_lines'))
 {
        my $tmp = get_config ('display_lines');
@@ -108,6 +149,13 @@ if (get_config ('display_lines'))
                $/, __FILE__, ": Valid values are ``none'', ``bar'', ``number'' and ``both''. Using default value ``both''.";
        }
 }
+
+=item B<display_words>: I<NONE>
+
+See L<display_lines>
+
+=cut
+
 if (get_config ('display_words'))
 {
        my $tmp = get_config ('display_words');
@@ -124,6 +172,13 @@ if (get_config ('display_words'))
                $/, __FILE__, ": Valid values are ``none'', ``bar'', ``number'' and ``both''. Using default value ``none''.";
        }
 }
+
+=item B<display_chars>: I<NONE>
+
+See L<display_lines>
+
+=cut
+
 if (get_config ('display_chars'))
 {
        my $tmp = get_config ('display_chars');
@@ -140,6 +195,14 @@ if (get_config ('display_chars'))
                $/, __FILE__, ": Valid values are ``none'', ``bar'', ``number'' and ``both''. Using default value ``none''.";
        }
 }
+
+=item B<display_times>: I<false>
+
+Wether or not to display a fixed width bar that shows when a user is most
+active.
+
+=cut
+
 if (get_config ('display_times'))
 {
        my $tmp = get_config ('display_times');
@@ -158,6 +221,13 @@ if (get_config ('display_times'))
                $/, __FILE__, ": Valid values are ``true'' and ``false''. Using default value ``false''.";
        }
 }
+
+=item B<display_images>: I<false>
+
+Wether or not to display images in the main ranking.
+
+=cut
+
 if (get_config ('display_images'))
 {
        my $tmp = get_config ('display_images');
@@ -176,10 +246,27 @@ if (get_config ('display_images'))
                $/, __FILE__, ": Valid values are ``true'' and ``false''. Using default value ``false''.";
        }
 }
+
+=item B<default_image>: I<http://www.url.org/image.png>
+
+Sets the URL to the default image. This is included as-is in the HTML. You have
+to take care of (absolute) paths yourself.
+
+=cut
+
 if (get_config ('default_image'))
 {
        $DEFAULT_IMAGE = get_config ('default_image');
 }
+
+=item B<sort_by>: I<LINES>
+
+Sets by which field the output has to be sorted. This is completely independent
+from B<display_lines>, B<display_words> and B<display_chars>. Valid options are
+I<LINES>, I<WORDS> and I<CHARS>.
+
+=cut
+
 if (get_config ('sort_by'))
 {
        my $tmp = get_config ('sort_by');
@@ -196,6 +283,14 @@ if (get_config ('sort_by'))
                $/, __FILE__, ": Valid values are ``lines'' and ``words''. Using default value ``lines''.";
        }
 }
+
+=item B<horizontal_images>: I<image1>, I<image2>, I<image3>, I<image4>
+
+Sets the B<four> images used for horizontal bars/graphs. As above: You have to
+take care of correctness of paths yourself.
+
+=cut
+
 if (get_config ('horizontal_images'))
 {
        my @tmp = get_config ('horizontal_images');
@@ -216,24 +311,55 @@ if (get_config ('horizontal_images'))
                $H_IMAGES[$i] = $tmp[$i];
        }
 }
+
+=item B<bar_height>: I<130>
+
+Sets the height (in pixels) of the highest vertical graph.
+
+=cut
+
 if (get_config ('bar_height'))
 {
        my $tmp = get_config ('bar_height');
        $tmp =~ s/\D//g;
        $BAR_HEIGHT = $tmp if ($tmp >= 10);
 }
+
+=item B<bar_width>: I<100>
+
+Sets the width (in pixels) of the widest horizontal graph.
+
+=cut
+
 if (get_config ('bar_width'))
 {
        my $tmp = get_config ('bar_width');
        $tmp =~ s/\D//g;
        $BAR_WIDTH = $tmp if ($tmp >= 10);
 }
+
+=item B<longlines>: I<50>
+
+Sets the number of rows of the main ranking table.
+
+=cut
+
 if (get_config ('longlines'))
 {
        my $tmp = get_config ('longlines');
        $tmp =~ s/\D//g;
        $LongLines = $tmp if ($tmp);
 }
+
+=item B<shortlines>: I<10>
+
+Sets the number of rows of the "they didn't write so much" table. There are six
+persons per line; you set the number of lines.
+
+=over
+
+=cut
+
 if (get_config ('shortlines'))
 {
        my $tmp = get_config ('shortlines');
@@ -300,21 +426,16 @@ sub add
        if ((length ($text) >= $QuoteMin)
                                and (length ($text) <= $QuoteMax))
        {
-               if (!defined ($QuoteCache->{$nick}))
-               {
-                       $QuoteCache->{$nick} = [];
-               }
-               push (@{$QuoteCache->{$nick}}, [$time, $text]);
-       }
+               my ($pointer) = $QuotePtr->get ($nick);
+               $pointer ||= 0;
 
-       if (defined ($QuoteCache->{$nick}))
-       {
-               while (scalar (@{$QuoteCache->{$nick}}) > $QuoteCacheSize)
-               {
-                       shift (@{$QuoteCache->{$nick}});
-               }
-       }
+               my $key = sprintf ("%s:%02i", $nick, $pointer);
 
+               $QuoteCache->put ($key, $time, $text);
+
+               $pointer = ($pointer + 1) % $QuoteCacheSize;
+               $QuotePtr->put ($nick, $pointer);
+       }
        return (1);
 }
 
@@ -347,7 +468,7 @@ sub calculate
                                $NickData->{$main}{'lines'}[$i] += $counter[$i];
                                $sum += $counter[$i];
                        }
-                       $NickData->{$main}{'lines_total'} = $sum;
+                       $NickData->{$main}{'lines_total'} += $sum;
                }
 
                @counter = $NickWordsCounter->get ($nick);
@@ -359,30 +480,62 @@ sub calculate
                                $NickData->{$main}{'words'}[$i] += $counter[$i];
                                $sum += $counter[$i];
                        }
-                       $NickData->{$main}{'words_total'} = $sum;
+                       $NickData->{$main}{'words_total'} += $sum;
                }
 
-               @counter = $NickWordsCounter->get ($nick);
+               @counter = $NickCharsCounter->get ($nick);
                if (@counter)
                {
                        my $sum = 0;
                        for (my $i = 0; $i < 24; $i++)
                        {
-                               $NickData->{$main}{'words'}[$i] += $counter[$i];
+                               $NickData->{$main}{'chars'}[$i] += $counter[$i];
                                $sum += $counter[$i];
                        }
-                       $NickData->{$main}{'chars_total'} = $sum;
+                       $NickData->{$main}{'chars_total'} += $sum;
                }
 
                if (!defined ($QuoteData->{$main}))
                {
                        $QuoteData->{$main} = [];
                }
-               if (defined ($QuoteCache->{$nick}))
+       }
+
+       for ($QuoteCache->keys ())
+       {
+               my $key = $_;
+               my ($nick, $num) = split (m/:/, $key);
+               my $main = get_main_nick ($nick);
+
+               my ($epoch, $text) = $QuoteCache->get ($key);
+               die unless (defined ($text));
+
+               if (!defined ($QuoteData->{$main}))
+               {
+                       die;
+               }
+               elsif (scalar (@{$QuoteData->{$main}}) < $QuoteCacheSize)
                {
-                       my @new = sort (sub { $b->[0] <=> $a->[0] }, @{$QuoteCache->{$nick}}, @{$QuoteData->{$main}});
-                       splice (@new, $QuoteCacheSize) if (scalar (@new) > $QuoteCacheSize);
-                       $QuoteData->{$main} = \@new;
+                       push (@{$QuoteData->{$main}}, [$epoch, $text]);
+               }
+               else
+               {
+                       my $insert = -1;
+                       my $min = $epoch;
+
+                       for (my $i = 0; $i < $QuoteCacheSize; $i++)
+                       {
+                               if ($QuoteData->{$main}[$i][0] < $min)
+                               {
+                                       $insert = $i;
+                                       $min = $QuoteData->{$main}[$i][0];
+                               }
+                       }
+
+                       if ($insert != -1)
+                       {
+                               $QuoteData->{$main}[$insert] = [$epoch, $text];
+                       }
                }
        }
 }
@@ -570,6 +723,7 @@ EOF
                my $nick = $_;
                my $ident = nick_to_ident ($nick);
                my $name  = ident_to_name ($ident);
+               my $print = $name || $nick;
 
                $linescount++;
 
@@ -580,11 +734,12 @@ EOF
                {
                        my $quote = translate ('-- no quote available --');
 
-                       if (defined ($QuoteData->{$nick}))
+                       if (@{$QuoteData->{$nick}})
                        {
                                my $num = scalar (@{$QuoteData->{$nick}});
                                my $rand = int (rand ($num));
-                               $quote = html_escape ($QuoteData->{$nick}[$rand]);
+
+                               $quote = html_escape ($QuoteData->{$nick}[$rand][1]);
                        }
 
                        my $link = '';
@@ -637,11 +792,11 @@ EOF
 
                        if ($link)
                        {
-                               print $fh qq#<a href="$link">$name</a></td>\n#
+                               print $fh qq#<a href="$link">$print</a></td>\n#
                        }
                        else
                        {
-                               print $fh qq#$name</td>\n#;
+                               print $fh qq#$print</td>\n#;
                        }
                
                        if ($DISPLAY_LINES ne 'NONE')
@@ -751,7 +906,7 @@ EOF
                                qq#  <tr>\n#;
                        }
                        
-                       print $fh qq#    <td title="$title">$name ($total)</td>\n#;
+                       print $fh qq#    <td title="$title">$print ($total)</td>\n#;
                        
                        if ($row_in_this_table == $ShortLines and $col_in_this_table == 5)
                        {
@@ -823,7 +978,7 @@ sub bar
                $retval .= qq#<img src="$img" style="width: # . $width . q#px"#;
                if ($i == 0) { $retval .= qq# class="first"#; }
                elsif ($i == 3) { $retval .= qq# class="last"#; }
-               $retval .= ' alt="" />';
+               $retval .= qq( alt="$sum" />);
        }
 
        return ($retval);