Bot-BasicBot-Pluggable-Module-Crontab

 view release on metacpan or  search on metacpan

lib/Bot/BasicBot/Pluggable/Module/Crontab.pm  view on Meta::CPAN

#############################################################################

my @crontab;
my $load_time = 0;

#----------------------------------------------------------------------------

#############################################################################
# Public Methods                                                            #
#############################################################################

sub init {
    my $self = shift;

    my $file = $self->store->get( 'crontab', 'file' );
    unless($file) {
        $file = $0;
        $file =~ s/\.pl$/.cron/;
    }

    $self->store->set( 'crontab', 'file', $file );
}
 
sub help {
    return "Posts messages to specific channels based on a crontab.";
}
 
sub tick {
    my $self = shift;

    $self->_load_cron();
    my $wkno = DateTime->now->week_number;

    for my $cron (@crontab) {
        next unless($cron->{tab}->match(time));
        next unless(
                $cron->{weekno} eq '*' 
            || ( $cron->{modulus} && $cron->{result} == ($wkno % $cron->{modulus}) )
            || ( $cron->{weekno} =~ /^\d+$/ && $wkno == $cron->{weekno} )
        );

        $self->say(
            channel => $cron->{channel},
            body    => $cron->{message}
        );
    }

    return 60 - DateTime->now->second; # ensure we are running each minute
}

#############################################################################
# Private Methods                                                           #
#############################################################################

sub _load_cron {
    my $self = shift;

    my $fn = $self->store->get( 'crontab', 'file' ) or return 0;
    return 0 unless(-r $fn); # file must be readable

    my $mod = (stat($fn))[9];
    return 1 if($mod <= $load_time); # don't reload if not modified

    @crontab = ();

    my $fh = IO::File->new($fn,'r') or die "Cannot load file [$fn]: $!\n";
    while(<$fh>) {
        s/\s+$//;
        my $line = $_;
        next unless($line);

        next if($line =~ /^#/); # ignore comment lines
        next if($line =~ /^$/); # ignore blank lines

        my @fields = split(/ /,$line,8);
        my $crontab = join(' ',(@fields)[0..4]);
        my $tab;
        eval { $tab = Time::Crontab->new($crontab) };
        next if($@);

        my ($modulus,$result);
        ($modulus,$result) = split(/\//,$fields[5],2)    if($fields[5] =~ m!^\d+/\d+!);

        push @crontab, {
            tab     => $tab,
            weekno  => $fields[5],
            modulus => $modulus,
            result  => $result,
            channel => $fields[6],
            message => $fields[7]
        };

        print "added $crontab $fields[5] = $fields[6] - $fields[7]\n";
    }

    $fh->close;
    $load_time = $mod;
}
 
 
1;
 
__END__
 
#----------------------------------------------------------------------------

=head1 NAME
 
Bot::BasicBot::Pluggable::Module::Crontab - Provides a crontab-like message service for IRC channels
 
=head1 DESCRIPTION

This module does not respond to user messages, public or private. It is purely
for posting messages to notminated channels as a specifed time.

A crontab like file is used to load instruction sets, which are then acted on
at the designated time.

Examples are:

    +-- minute



( run in 0.732 second using v1.01-cache-2.11-cpan-39bf76dae61 )