http://www.perlmonks.org?node_id=256311
Category: Miscellaneous/IRC Related
Author/Contact Info Ben Smith defyance
Description: A module to use with perl IRC bots to provide drop in "Seen" functionality. Basically it allows the bot to tell you the last seen action from a particular IRC user. At this point, you have to tell it which events to log, I consider this a feature. MySQL logging functionality is being considered. For now it uses a simple log file and a hash to do the logging. Some may find it pointless, some may find it interesting. I'm mainly looking for input on how to improve my code.
package Seen;

use strict;
use warnings;
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
use Carp;

require Exporter;

@ISA     = qw(Exporter AutoLoader);
@EXPORT  = qw();
$VERSION = '0.01';

# Set us up the bomb
sub new {

    my $class = shift;
    my %args  = @_;
    return bless \%args, $class;

}

# Start things up
# Check for existing seen log
# Load seen info from file if possible
sub _load {

    my $self = shift;
    my %seen = ();

    # Load seen info from previous session.
    if ( -e $self->{'file'} ) {
        open( FILE, $self->{'file'} ) || croak "Cannot Open $self->{'f
+ile'}!";
        %seen = map { chomp; split /\|/; } <FILE>;
        close(FILE) || croak "Cannot Close $self->{'file'}!";
    }
    return %seen;
}

# Dump seen info into file
sub logSeen {

    my ( $self, $who, $message ) = @_;
    my %seen = $self->_load();
    $who     =~ s/\|/<pipe>/g;    # So we don't confuse things :)
    $message =~ s/\|/<pipe>/g;    # Ditto
    $seen{$who} = $message . " on " . scalar(localtime);
    open( FILE, ">>$self->{'file'}" ) || croak "Cannot Open $self->{'f
+ile'}!";
    print FILE "$who|$seen{$who}\n";
    close(FILE) || croak "Cannot Close $self->{'file'}!";

}

# Recieves list of names from your script
# to load current channel users.
# Look at the pod for more info.
sub loadCurrent {

    my $self  = shift;
    my %seen  = $self->_load();
    my $names = shift;
    my @names = split ( / /, $names );
    open( FILE, ">>$self->{'file'}" ) || croak "Cannot Open $self->{'f
+ile'}!";
    foreach my $name (@names) {
        $name =~ s/@//;
        $name =~ s/\|/<pipe>/g;
        $seen{$name} = "On channel as of " . scalar(localtime);
        print FILE "$name|$seen{$name}\n";
    }
    close(FILE) || croak "Cannot Close $self->{'file'}!";

}

# Got a seen request, handle it.
sub getSeen {

    my $self = shift;
    my $nick = shift;
    my %seen = $self->_load();
    $nick =~ s/\|/<pipe>/g;

    my $nick1 = $nick;
    if ( defined $seen{$nick} ) {
        $nick         =~ s/<pipe>/\|/g;
        $seen{$nick1} =~ s/<pipe>/\|/g;
        return "Saw $nick $seen{$nick1}";
    }
    else {
        $nick =~ s/<pipe>/\|/g;
        return "Haven't Seen $nick";
    }

}
# Clear logfile of unwanted seen data
sub clearLog {

    my $self = shift;
    unlink( $self->{'file'} ) || croak "Cannot Unlink $self->{'file'}!
+";

}

sub DESTROY { }

1;
__END__

=head1 NAME

Seen.pm - A module for handling seen requests on IRC.

=head1 SYNOPSIS

  use Seen;
  my $seen = Seen->new( file => '/path/to/seen.log' );

  # later on...

  # Log join event, assuming Poe::Component::IRC use..
  sub on_join {
    my ( $kernel, $who, $where ) = @_[ KERNEL, ARG0, ARG1 ];
    my $nick = ( split /!/, $who )[0];

    # Do Stuff...

    $seen->logSeen( $nick, "Joining $where" );

  }

=head1 DESCRIPTION

Provides seen functionality for an IRC bot.

=head1 METHODS

=over 4

=item 1

B<logSeen()> takes two arguments, stores info into a hash, and logs to
file specified when creating the new object.  Returns nothing.

Use like so:

 $seen->logSeen( $nick, $msg );

=item 2

B<getSeen()> takes a nickname as an argument.  Checks to see if it is
defined in the hash and returns the results.

Use like so:

 $seen->getSeen( $nick );

=item 3

B<loadCurrent()> takes list from irc_353 (names command) as an argumen
+t and
loads it into the hash, and logfile, so current users on the channel a
+re seen.

Use like so:

 $seen->loadCurrent( $names );

=item 4

B<clearLog()> clears the currently loaded log file, takes no args.

=back

=head1 AUTHOR

Benjamin Smith (DeFyance) defyance@just-another.net

=head1 SEE ALSO

POE::Component::IRC

=cut