X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=lib%2FOnis%2FPlugins%2FCore.pm;h=6babaed760463b917ec967f30d0a8194648fde38;hb=94c475154436950768e3686fa7030ee5fdb23e4e;hp=1b05babbd7c2b5eef2d4ef28ba1c393c0c645a3d;hpb=dbcb0793cb2dd3dc64a445888846d2368b803f5a;p=onis.git diff --git a/lib/Onis/Plugins/Core.pm b/lib/Onis/Plugins/Core.pm index 1b05bab..6babaed 100644 --- a/lib/Onis/Plugins/Core.pm +++ b/lib/Onis/Plugins/Core.pm @@ -17,14 +17,14 @@ complicated plugin so far. =cut -use Onis::Config qw/get_config/; -use Onis::Html qw/html_escape get_filehandle/; -use Onis::Language qw/translate/; -use Onis::Users (qw(get_realname get_link get_image ident_to_name)); -use Onis::Data::Core qw#get_all_nicks nick_to_ident ident_to_nick get_main_nick register_plugin#; -use Onis::Data::Persistent; - -@Onis::Plugins::Core::EXPORT_OK = (qw(get_core_nick_counters get_sorted_nicklist)); +use Onis::Config (qw(get_config)); +use Onis::Html (qw(html_escape get_filehandle)); +use Onis::Language (qw(translate)); +use Onis::Users (qw(get_realname get_link get_image chatter_to_name)); +use Onis::Data::Core (qw(get_all_nicks nick_to_ident ident_to_nick get_main_nick register_plugin)); +use Onis::Data::Persistent (); + +@Onis::Plugins::Core::EXPORT_OK = (qw(get_core_nick_counters get_sorted_nicklist nick_is_in_main_table)); @Onis::Plugins::Core::ISA = ('Exporter'); our $NickLinesCounter = Onis::Data::Persistent->new ('NickLinesCounter', 'nick', @@ -46,11 +46,15 @@ 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 = []; +our $NicksInMainTable = {}; + our @H_IMAGES = qw#dark-theme/h-red.png dark-theme/h-blue.png dark-theme/h-yellow.png dark-theme/h-green.png#; our $QuoteCacheSize = 10; our $QuoteMin = 30; @@ -68,30 +72,69 @@ our $BAR_WIDTH = 100; our $LongLines = 50; our $ShortLines = 10; +=head1 CONFIGURATION OPTIONS + +=over 4 + +=item B: 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: 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: 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: 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: I + +Choses wether to display B as I, I, I or not at all +(I). + +=cut + if (get_config ('display_lines')) { my $tmp = get_config ('display_lines'); @@ -108,6 +151,13 @@ if (get_config ('display_lines')) $/, __FILE__, ": Valid values are ``none'', ``bar'', ``number'' and ``both''. Using default value ``both''."; } } + +=item B: I + +See L + +=cut + if (get_config ('display_words')) { my $tmp = get_config ('display_words'); @@ -124,6 +174,13 @@ if (get_config ('display_words')) $/, __FILE__, ": Valid values are ``none'', ``bar'', ``number'' and ``both''. Using default value ``none''."; } } + +=item B: I + +See L + +=cut + if (get_config ('display_chars')) { my $tmp = get_config ('display_chars'); @@ -140,6 +197,14 @@ if (get_config ('display_chars')) $/, __FILE__, ": Valid values are ``none'', ``bar'', ``number'' and ``both''. Using default value ``none''."; } } + +=item B: I + +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 +223,13 @@ if (get_config ('display_times')) $/, __FILE__, ": Valid values are ``true'' and ``false''. Using default value ``false''."; } } + +=item B: I + +Wether or not to display images in the main ranking. + +=cut + if (get_config ('display_images')) { my $tmp = get_config ('display_images'); @@ -176,10 +248,27 @@ if (get_config ('display_images')) $/, __FILE__, ": Valid values are ``true'' and ``false''. Using default value ``false''."; } } + +=item B: I + +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: I + +Sets by which field the output has to be sorted. This is completely independent +from B, B and B. Valid options are +I, I and I. + +=cut + if (get_config ('sort_by')) { my $tmp = get_config ('sort_by'); @@ -196,6 +285,14 @@ if (get_config ('sort_by')) $/, __FILE__, ": Valid values are ``lines'' and ``words''. Using default value ``lines''."; } } + +=item B: I, I, I, I + +Sets the B 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 +313,55 @@ if (get_config ('horizontal_images')) $H_IMAGES[$i] = $tmp[$i]; } } + +=item B: 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: 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: 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: 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 +428,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 +470,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,7 +482,7 @@ sub calculate $NickData->{$main}{'words'}[$i] += $counter[$i]; $sum += $counter[$i]; } - $NickData->{$main}{'words_total'} = $sum; + $NickData->{$main}{'words_total'} += $sum; } @counter = $NickCharsCounter->get ($nick); @@ -371,18 +494,50 @@ sub calculate $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]; + } } } } @@ -438,14 +593,14 @@ sub activetimes my $header = translate ('When do we actually talk here?'); print $fh "

$header

\n", - qq#\n#, - qq# \n#; + qq#
\n#, + qq# \n#; # this for circles through the four colors. Each color represents six hours. # (4 * 6 hours = 24 hours) for (my $i = 0; $i <= 3; $i++) { - for (my $j = 0; $j <= 5; $j++) + for (my $j = 0; $j < 6; $j++) { my $hour = (($i * 6) + $j); if (!defined ($data[$hour])) @@ -453,19 +608,22 @@ sub activetimes $data[$hour] = 0; } - my $percent = 100 * ($data[$hour] / $total); - my $height = int ($data[$hour] * $factor) + 1; - my $img_url = $img_urls[$i]; + my $height = sprintf ("%.2f", 95 * $data[$hour] / $max); + my $img = $img_urls[$i]; - print $fh ' \n#; + print $fh qq# \n#; } } + print $fh qq# \n \n#; + for (my $i = 0; $i < 24; $i++) + { + my $percent = sprintf ("%.1f", 100 * $data[$i] / $total); + print $fh qq# \n#; + } print $fh " \n", - qq# \n#; - print $fh map { " \n" } (0 .. 23); + qq# \n#; + print $fh map { qq# \n# } (0 .. 23); print $fh " \n", "
', sprintf ("%2.1f", $percent), - qq#%
$percent\%
$_
$_
\n\n"; } @@ -535,18 +693,21 @@ EOF } if ($DISPLAY_LINES ne 'NONE') { + my $span = $DISPLAY_LINES eq 'BOTH' ? ' colspan="2"' : ''; $trans = translate ('Number of Lines'); - print $fh " $trans\n"; + print $fh " $trans\n"; } if ($DISPLAY_WORDS ne 'NONE') { + my $span = $DISPLAY_WORDS eq 'BOTH' ? ' colspan="2"' : ''; $trans = translate ('Number of Words'); - print $fh " $trans\n"; + print $fh " $trans\n"; } if ($DISPLAY_CHARS ne 'NONE') { + my $span = $DISPLAY_CHARS eq 'BOTH' ? ' colspan="2"' : ''; $trans = translate ('Number of Characters'); - print $fh " $trans\n"; + print $fh " $trans\n"; } if ($DISPLAY_TIMES) { @@ -569,7 +730,7 @@ EOF { my $nick = $_; my $ident = nick_to_ident ($nick); - my $name = ident_to_name ($ident); + my $name = chatter_to_name ("$nick!$ident"); my $print = $name || $nick; $linescount++; @@ -579,12 +740,15 @@ EOF # our table.. if ($linescount <= $LongLines) { + $NicksInMainTable->{$nick} = $linescount; + my $quote = translate ('-- no quote available --'); if (@{$QuoteData->{$nick}}) { my $num = scalar (@{$QuoteData->{$nick}}); my $rand = int (rand ($num)); + $quote = html_escape ($QuoteData->{$nick}[$rand][1]); } @@ -647,50 +811,44 @@ EOF if ($DISPLAY_LINES ne 'NONE') { - print $fh qq# #; - if (($DISPLAY_LINES eq 'BOTH') or ($DISPLAY_LINES eq 'BAR')) + if (($DISPLAY_LINES eq 'BOTH') or ($DISPLAY_LINES eq 'NUMBER')) { - my $code = bar ($max_lines, $NickData->{$nick}{'lines'}); - print $fh $code; + my $num = $NickData->{$nick}{'lines_total'}; + print $fh qq( $num\n); } - print $fh ' ' if ($DISPLAY_LINES eq 'BOTH'); - if (($DISPLAY_LINES eq 'BOTH') or ($DISPLAY_LINES eq 'NUMBER')) + if (($DISPLAY_LINES eq 'BOTH') or ($DISPLAY_LINES eq 'BAR')) { - print $fh $NickData->{$nick}{'lines_total'}; + my $code = bar ($max_lines, $NickData->{$nick}{'lines'}); + print $fh qq( $code\n); } - print $fh "\n"; } if ($DISPLAY_WORDS ne 'NONE') { - print $fh qq# #; - if (($DISPLAY_WORDS eq 'BOTH') or ($DISPLAY_WORDS eq 'BAR')) + if (($DISPLAY_WORDS eq 'BOTH') or ($DISPLAY_WORDS eq 'NUMBER')) { - my $code = bar ($max_words, $NickData->{$nick}{'words'}); - print $fh $code; + my $num = $NickData->{$nick}{'words_total'}; + print $fh qq( $num\n); } - print $fh ' ' if ($DISPLAY_WORDS eq 'BOTH'); - if (($DISPLAY_WORDS eq 'BOTH') or ($DISPLAY_WORDS eq 'NUMBER')) + if (($DISPLAY_WORDS eq 'BOTH') or ($DISPLAY_WORDS eq 'BAR')) { - print $fh $NickData->{$nick}{'words_total'}; + my $code = bar ($max_words, $NickData->{$nick}{'words'}); + print $fh qq( $code\n); } - print $fh "\n"; } if ($DISPLAY_CHARS ne 'NONE') { - print $fh qq# #; - if (($DISPLAY_CHARS eq 'BOTH') or ($DISPLAY_CHARS eq 'BAR')) + if (($DISPLAY_CHARS eq 'BOTH') or ($DISPLAY_CHARS eq 'NUMBER')) { - my $code = bar ($max_chars, $NickData->{$nick}{'chars'}); - print $fh $code; + my $num = $NickData->{$nick}{'chars_total'}; + print $fh qq( $num\n); } - print $fh ' ' if ($DISPLAY_CHARS eq 'BOTH'); - if (($DISPLAY_CHARS eq 'BOTH') or ($DISPLAY_CHARS eq 'NUMBER')) + if (($DISPLAY_CHARS eq 'BOTH') or ($DISPLAY_CHARS eq 'BAR')) { - print $fh $NickData->{$nick}{'chars_total'}; + my $code = bar ($max_chars, $NickData->{$nick}{'chars'}); + print $fh qq( $code\n); } - print $fh "\n"; } if ($DISPLAY_TIMES) @@ -797,21 +955,16 @@ sub bar confess () unless (ref ($source) eq 'ARRAY'); # BAR_WIDTH is a least 10 - my $max_width = $BAR_WIDTH - 4; - my $factor = 1; my $retval = ''; my $i; my $j; - if (!$max_num) { return ($retval); } - $factor = $max_width / $max_num; - for ($i = 0; $i < 4; $i++) { my $sum = 0; - my $width = 1; my $img = $H_IMAGES[$i]; + my $width; for ($j = 0; $j < 6; $j++) { @@ -819,12 +972,12 @@ sub bar $sum += $source->[$hour]; } - $width += int (0.5 + ($sum * $factor)); + $width = sprintf ("%.2f", 95 * $sum / $max_num); - $retval .= qq#$sum); } return ($retval); @@ -874,10 +1027,24 @@ sub get_sorted_nicklist return ($SortedNicklist); } +=item B (I<$nick>) + +Returns the position of the nick in the main table or zero if it is not in the +main table. + +=cut + +sub nick_is_in_main_table +{ + my $nick = shift; + + return (defined ($NicksInMainTable->{$nick}) ? $NicksInMainTable->{$nick} : 0); +} + =back =head1 AUTHOR -Florian octo Forster, Eocto at verplant.orgE +Florian octo Forster Eocto at verplant.orgE =cut