Some work on Onis::Plugins::Core to prepare for the new data structures. Far from...
[onis.git] / lib / Onis / Data / Core.pm
index 29a5b4b..6e33224 100644 (file)
@@ -15,9 +15,10 @@ use strict;
 use warnings;
 
 use Exporter;
-use Onis::Config qw#get_config#;
-use Onis::Users qw#host_to_username nick_to_username#;
+use Onis::Config qw(get_config);
+use Onis::Users qw(ident_to_name);
 use Onis::Data::Persistent;
+use Onis::Parser::Persistent qw(get_absolute_time);
 
 =head1 NAMING CONVENTION
 
@@ -37,14 +38,13 @@ our $Nick2Ident   = Onis::Data::Persistent->new ('Nick2Ident', 'nick', 'ident');
 our $ChatterList  = Onis::Data::Persistent->new ('ChatterList', 'chatter', 'counter');
 our $ChannelNames = Onis::Data::Persistent->new ('ChannelNames', 'channel', 'counter');
 
+@Onis::Data::Core::EXPORT_OK =
+qw(
+       store unsharp calculate_nicks 
 
-
-@Onis::Data::Core::EXPORT_OK = qw#get_all_nicks get_channel
-       nick_to_ident
-       ident_to_nick ident_to_name
-       get_main_nick
-       get_total_lines nick_rename print_output
-       register_plugin store get_print_name#;
+       get_all_nicks get_channel get_main_nick nick_to_ident ident_to_nick
+       get_total_lines nick_rename print_output register_plugin merge_idents
+);
 @Onis::Data::Core::ISA = ('Exporter');
 
 our $DATA = init ('$DATA', 'hash');
@@ -53,9 +53,11 @@ our $PluginCallbacks = {};
 our $OUTPUT   = [];
 our @AllNicks = ();
 our @ALLNAMES = ();
-our %NickMap = ();
+
+our %NickToNick = ();
 our %NickToIdent = ();
 our %IdentToNick = ();
+
 our $LASTRUN_DAYS = 0;
 
 
@@ -198,6 +200,11 @@ sub store
                $ChannelNames->put ($chan, $count);
        }
 
+       if (!defined ($data->{'epoch'}))
+       {
+               $data->{'epoch'} = get_absolute_time ();
+       }
+
        if ($::DEBUG & 0x400)
        {
                my @keys = keys (%$data);
@@ -210,6 +217,7 @@ sub store
                }
        }
 
+       # FIXME
        #$DATA->{'total_lines'}++;
 
        if (defined ($PluginCallbacks->{$type}))
@@ -329,20 +337,18 @@ only once and so does every nick.
 
 sub calculate_nicks
 {
-       my $nicks  = {};
-       my $idents = {};
+       my $nicks      = {};
+       my $idents     = {};
+       my $name2nick  = {};
+       my $name2ident = {};
        
        for ($ChatterList->keys ())
        {
                my $chatter = shift;
                my ($nick, $ident) = split (m/!/, $chatter);
-               my $name = host_to_username ($chatter);
+               my $name = ident_to_name ($ident);
                my ($counter) = $ChatterList->get ($chatter);
 
-               my $temp = $name ? $name : $ident;
-
-               next if (lc ($name) eq 'ignore');
-
                $nicks->{$nick}{$temp} = 0 unless (defined ($nicks->{$nick}{$temp}));
                $nicks->{$nick}{$temp} += $counter;
        }
@@ -351,29 +357,30 @@ sub calculate_nicks
        {
                my $this_nick = $_;
                my $this_ident = 'unidentified';
+               my $this_name = '';
                my $this_total = 0;
                my $this_max = 0;
-               my $this_ident_is_user = 0;
 
                for (keys %{$nicks->{$this_nick}})
                {
                        my $ident = $_;
+                       my $name = ident_to_name ($ident);
                        my $num = $nicks->{$this_nick}{$ident};
                        
                        $this_total += $num;
 
-                       if ($ident =~ m/@/) # $ident is a (user)name
+                       if ($name)
                        {
-                               if (($num >= $this_max) or !$this_ident_is_user)
+                               if (($num >= $this_max) or !$this_name)
                                {
                                        $this_max = $num;
                                        $this_ident = $ident;
-                                       $this_ident_is_user = 1;
+                                       $this_name = $name;
                                }
                        }
                        else
                        {
-                               if (($num >= $this_max) and !$this_ident_is_user)
+                               if (($num >= $this_max) and !$this_name)
                                {
                                        $this_max = $num;
                                        $this_ident = $ident;
@@ -385,8 +392,19 @@ sub calculate_nicks
 
                if ($this_ident ne 'unidentified')
                {
-                       $idents->{$this_ident}{$this_nick} = 0 unless (defined ($idents->{$this_ident}{$this_nick}));
-                       $idents->{$this_ident}{$this_nick} += $this_total;
+                       if ($name)
+                       {
+                               $name2nick->{$this_name}{$this_nick} = 0 unless (defined ($names->{$this_name}{$this_nick}));
+                               $name2nick->{$this_name}{$this_nick} += $this_total;
+
+                               $name2ident->{$this_name}{$this_ident} = 0 unless (defined ($names->{$this_name}{$this_ident}));
+                               $name2ident->{$this_name}{$this_ident} += $this_total;
+                       }
+                       else
+                       {
+                               $idents->{$this_ident}{$this_nick} = 0 unless (defined ($idents->{$this_ident}{$this_nick}));
+                               $idents->{$this_ident}{$this_nick} += $this_total;
+                       }
                }
                elsif ($::DEBUG & 0x100)
                {
@@ -406,7 +424,7 @@ sub calculate_nicks
                for (@nicks)
                {
                        my $nick = $_;
-                       my $num = $nicks_of_ident->{$this_ident}{$nick};
+                       my $num = $idents->{$this_ident}{$nick};
 
                        if ($num > $this_max)
                        {
@@ -425,13 +443,70 @@ sub calculate_nicks
                for (@other_nicks, $this_nick)
                {
                        push (@AllNicks, $_);
-                       $NickMap{$_} = $this_nick;
-                       # FIXME
+                       $NickToNick{$_} = $this_nick;
                        $NickToIdent{$_} = $this_ident;
                }
 
                $IdentToNick{$this_ident} = $this_nick;
        }
+
+       for (keys %$name2nick)
+       {
+               my $name = $_;
+               my $max_num = 0;
+               my $max_nick = '';
+               my $max_ident = '';
+
+               my @other_nicks = ();
+               my @other_idents = ();
+
+               for (keys %{$name2nick->{$name}})
+               {
+                       my $nick = $_;
+                       my $num = $name2nick->{$name}{$nick};
+
+                       if ($num > $max_num)
+                       {
+                               push (@other_nicks, $max_nick) if ($max_nick);
+                               $max_nick = $nick;
+                               $max_num  = $num;
+                       }
+                       else
+                       {
+                               push (@other_nicks, $nick);
+                       }
+               }
+
+               $max_num = 0;
+               for (keys %{$name2ident->{$name}})
+               {
+                       my $ident = $_;
+                       my $num = $name2ident->{$name}{$ident};
+
+                       if ($num > $max_num)
+                       {
+                               push (@other_idents, $max_ident) if ($max_ident);
+                               $max_ident = $ident;
+                               $max_num  = $num;
+                       }
+                       else
+                       {
+                               push (@other_idents, $ident);
+                       }
+               }
+
+               for (@other_nicks, $max_nick)
+               {
+                       push (@AllNicks, $_);
+                       $NickToNick{$_} = $max_nick;
+                       $NickToIdent{$_} = $max_ident;
+               }
+
+               for (@other_idents, $max_ident)
+               {
+                       $IdentToNick{$_} = $max_nick;
+               }
+       }
 }
 
 =item I<@nicks> = B<get_all_nicks> ()
@@ -453,21 +528,25 @@ Returns the name of the channel we're generating stats for.
 
 sub get_channel
 {
-       my $chan;
+       my $chan = '#unknown'
+       ;
        if (get_config ('channel'))
        {
                $chan = get_config ('channel');
        }
-       elsif (keys (%{$DATA->{'channel'}}))
-       {
-               ($chan) = sort
-               {
-                       $DATA->{'channel'}{$b} <=> $DATA->{'channel'}{$a}
-               } (keys (%{$DATA->{'channel'}}));
-       }
        else
        {
-               $chan = '#unknown';
+               my $max = 0;
+               for ($ChannelNames->keys ())
+               {
+                       my $c = $_;
+                       my ($num) = $ChannelNames->get ($c);
+                       if (defined ($num) and ($num > $max))
+                       {
+                               $max = $num;
+                               $chan = $c;
+                       }
+               }
        }
 
        # Fix network-safe channel named (RFC 2811)
@@ -488,9 +567,9 @@ Returns the main nick for I<$nick> or an empty string if the nick is unknown..
 sub get_main_nick
 {
        my $nick = shift;
-       if (defined ($NickMap{$nick}))
+       if (defined ($NickToNick{$nick}))
        {
-               return ($NickMap{$nick});
+               return ($NickToNick{$nick});
        }
        else
        {
@@ -500,16 +579,29 @@ sub get_main_nick
 
 =item I<$ident> = B<nick_to_ident> (I<$nick>)
 
-Returns the ident for this nick or an empty string if unknown.
+Returns the ident for this nick or an empty string if unknown. Before
+B<calculate_nicks> is run it will use the database to find the most recent
+mapping. After B<calculate_nicks> is run the calculated mapping will be used.
 
 =cut
 
 sub nick_to_ident
 {
        my $nick = shift;
+       my $ident = '';
 
-       my ($ident) = $Nick2Ident->get ($nick);
-       $ident ||= '';
+       if (%NickToIdent)
+       {
+               if (defined ($NickToIdent{$nick}))
+               {
+                       $ident = $NickToIdent{$nick};
+               }
+       }
+       else
+       {
+               ($ident) = $Nick2Ident->get ($nick);
+               $ident ||= '';
+       }
 
        return ($ident);
 }
@@ -524,13 +616,7 @@ sub ident_to_nick
 {
        my $ident = shift;
 
-       if (!defined ($ident)
-                       or (lc ($ident) eq 'ignore')
-                       or (lc ($ident) eq 'unidentified'))
-       {
-               return ('');
-       }
-       elsif (defined ($IdentToNick{$ident}))
+       if (defined ($IdentToNick{$ident}))
        {
                return ($IdentToNick{$ident});
        }
@@ -540,55 +626,6 @@ sub ident_to_nick
        }
 }
 
-=item I<$name> = B<ident_to_name> (I<$ident>)
-
-Returns the printable version of the name for the chatter identified by
-I<$ident>. Returns an empty string if the ident is not known.
-
-=cut
-
-sub ident_to_name
-{
-       my $ident = shift;
-       my $nick = ident_to_nick ($ident);
-       my $name;
-       
-       if (!$nick)
-       {
-               return ('');
-       }
-
-       $name = get_print_name ($nick);
-
-       return ($name);
-}
-
-=item I<$name> = B<get_print_name> (I<$nick>)
-
-Returns the printable version of the name for the nick I<$nick> or I<$nick> if
-unknown.
-
-=cut
-
-sub get_print_name
-{
-       my $nick = shift;
-       my $ident = '';
-       my $name = $nick;
-
-       if (defined ($NickToIdent{$nick}))
-       {
-               $ident = $NickToIdent{$nick};
-       }
-
-       if (($ident !~ m/^[^@]+@.+$/) and $ident)
-       {
-               $name = $ident;
-       }
-
-       return ($name);
-}
-
 =item I<$lines> = B<get_total_lines> ()
 
 Returns the total number of lines parsed so far.
@@ -610,24 +647,13 @@ sub nick_rename
 {
        my $old_nick = shift;
        my $new_nick = shift;
+       my $ident;
 
-       if (defined ($DATA->{'host_cache'}{$old_nick}))
-       {
-               my $host = $DATA->{'host_cache'}{$old_nick};
-               $DATA->{'host_cache'}{$new_nick} = $host;
-
-               if (!defined ($DATA->{'hosts_of_nick'}{$new_nick}{$host}))
-               {
-                       $DATA->{'hosts_of_nick'}{$new_nick}{$host} = 1;
-               }
-       }
+       ($ident) = $Nick2Ident->get ($old_nick);
 
-       if (defined ($DATA->{'byident'}{"$old_nick\@unidentified"}))
+       if (defined ($ident) and ($ident))
        {
-               # Other data may be overwritten, but I don't care here..
-               # This should be a extremely rare case..
-               $DATA->{'byident'}{"$new_nick\@unidentified"} = $DATA->{'byident'}{"$old_nick\@unidentified"};
-               delete ($DATA->{'byident'}{"$old_nick\@unidentified"});
+               $Nick2Ident->put ($new_nick, $ident);
        }
 }
 
@@ -699,8 +725,6 @@ sub register_plugin
        push (@{$PluginCallbacks->{$type}}, $sub_ref);
 
        print STDERR $/, __FILE__, ': ', scalar (caller ()), " registered for ``$type''." if ($::DEBUG & 0x800);
-
-       return ($DATA);
 }
 
 =item B<merge_idents> ()