package Onis::Plugins::Conversations; use strict; use warnings; use Exporter; use Onis::Config qw(get_config); use Onis::Html qw(get_filehandle); use Onis::Language qw(translate); use Onis::Data::Core qw(register_plugin get_main_nick nick_to_ident nick_to_name); use Onis::Data::Persistent (); =head1 NAME Onis::Plugins::Conversations - Who talks with who =head1 DESCRIPTION This plugins tries to recignise conversations and counts the amount that people talk to each other. =cut @Onis::Plugins::Conversations::EXPORT_OK = (qw(get_conversations)); @Onis::Plugins::Conversations::ISA = ('Exporter'); our $ConversationCache = Onis::Data::Persistent->new ('ConversationCache', 'partners', qw(time0 time1 time2 time3)); our $ConversationData = {}; our @HorizontalImages = qw#dark-theme/h-red.png dark-theme/h-blue.png dark-theme/h-yellow.png dark-theme/h-green.png#; if (get_config ('horizontal_images')) { my @tmp = get_config ('horizontal_images'); my $i; if (scalar (@tmp) != 4) { print STDERR $/, __FILE__, ": The number of horizontal images is not four. The output might look weird.", $/; } for ($i = 0; $i < 4; $i++) { next unless (defined ($tmp[$i])); $HorizontalImages[$i] = $tmp[$i]; } } our $NumConversations = 10; if (get_config ('conversations_number')) { my $tmp = get_config ('conversations_number'); $tmp =~ s/\D//g; $NumConversations = $tmp if ($tmp); } register_plugin ('TEXT', \&add); register_plugin ('OUTPUT', \&output); my $VERSION = '$Id: Conversations.pm,v 1.7 2004/09/15 19:42:04 octo Exp $'; print STDERR $/, __FILE__, ": $VERSION" if ($::DEBUG); return (1); sub add { my $data = shift; my $text = $data->{'text'}; my $nick = $data->{'nick'}; my $ident = $data->{'ident'}; my $time = int ($data->{'hour'} / 6); # my @potential_nicks = split (/[^\w\`\~\^\-\|\[\]]+/, $text); my $talk_to = ''; for (@potential_nicks) { my $other_nick = $_; my $other_ident = nick_to_ident ($other_nick); if ($other_ident) { $talk_to = $other_nick; last; } } # if ($talk_to) { my $key = "$nick:$talk_to"; my @data = $ConversationCache->get ($key); @data = (0, 0, 0, 0) unless (@data); my $chars = length ($text); $data[$time] += $chars; $ConversationCache->put ($key, @data); } } sub calculate { for ($ConversationCache->keys ()) { my $key = $_; my ($nick_from, $nick_to) = split (m/:/, $key); my @data = $ConversationCache->get ($key); $nick_from = get_main_nick ($nick_from); $nick_to = get_main_nick ($nick_to); next if (!$nick_from or !$nick_to); next if ($nick_from eq $nick_to); if (!defined ($ConversationData->{$nick_from}{$nick_to})) { $ConversationData->{$nick_from}{$nick_to} = { total => 0, nicks => { $nick_from => [0, 0, 0, 0], $nick_to => [0, 0, 0, 0] } }; $ConversationData->{$nick_to}{$nick_from} = $ConversationData->{$nick_from}{$nick_to}; } for (my $i = 0; $i < 4; $i++) { $ConversationData->{$nick_from}{$nick_to}{'nicks'}{$nick_from}[$i] += $data[$i]; $ConversationData->{$nick_from}{$nick_to}{'total'} += $data[$i]; } } } sub get_top { my $num = shift; my @data = (); for (keys %$ConversationData) { my $nick0 = $_; for (keys %{$ConversationData->{$nick0}}) { my $nick1 = $_; next unless ($nick0 lt $nick1); push (@data, [$ConversationData->{$nick0}{$nick1}{'total'}, $nick0, $nick1]); } } @data = sort { $b->[0] <=> $a->[0] } (@data); splice (@data, $num) if (scalar (@data) > $num); return (@data); } sub output { calculate (); my $fh = get_filehandle (); my $title = translate ('Conversation partners'); my $max_num = 0; my @data = get_top ($NumConversations); return (undef) unless (@data); for (@data) { my $nick0 = $_->[1]; my $nick1 = $_->[2]; my $rec = $ConversationData->{$nick0}{$nick1}; my $sum0 = 0; my $sum1 = 0; for (my $i = 0; $i < 4; $i++) { $sum0 += $rec->{'nicks'}{$nick0}[$i]; $sum1 += $rec->{'nicks'}{$nick1}[$i]; } $max_num = $sum0 if ($max_num < $sum0); $max_num = $sum1 if ($max_num < $sum1); } print $fh < $title EOF foreach (@data) { my $nick0 = $_->[1]; my $nick1 = $_->[2]; my $name0 = nick_to_name ($nick0) || $nick0; my $name1 = nick_to_name ($nick1) || $nick1; my $rec = $ConversationData->{$nick0}{$nick1}; print $fh < $name0 $name1 EOF print $fh ' '; for (my $i = 3; $i >= 0; $i--) { my $width = sprintf ("%.2f", 95 * $rec->{'nicks'}{$nick0}[$i] / $max_num); my $image = $HorizontalImages[$i]; my $class = ''; if ($i == 3) { $class = qq# class="first"#; } elsif ($i == 0) { $class = qq# class="last"#; } print $fh qq##; } print $fh qq#\n #; for (my $i = 0; $i < 4; $i++) { my $width = sprintf ("%.2f", 95 * $rec->{'nicks'}{$nick1}[$i] / $max_num); my $image = $HorizontalImages[$i]; my $class = ''; if ($i == 0) { $class = qq# class="first"#; } elsif ($i == 3) { $class = qq# class="last"#; } print $fh qq##; } print $fh "\n \n"; } print $fh "\n\n"; } =head1 EXPORTED FUNCTIONS =over 4 =item B (I<$nick>) Returns a hashref to the conversations this nick was involved with. The layout is the following. I<$other> is the nick of the person I<$nick> chattet with. The arrays hold the number of characters written by the nick used as the key. The first field contains the characters for the hours 0-5, the second field holds 6-11 and so on. { $other => { total => 0, nicks => { $nick => [0, 0, 0, 0], $other => [0, 0, 0, 0] } }, ... } =cut sub get_conversations { my $nick = shift; if (!defined ($ConversationData->{$nick})) { return ({}); } else { return ($ConversationData->{$nick}); } } =back =head1 AUTHOR Florian octo Forster, Eocto at verplant.orgE =cut