mirror of https://github.com/pragma-/pbot.git
Add SelectHandler class to register callbacks for selecting and reading handles; updating StdinReader to use SelectHandler
This commit is contained in:
parent
1831d0775d
commit
4a110848e9
32
PBot/PBot.pm
32
PBot/PBot.pm
|
@ -21,6 +21,7 @@ STDOUT->autoflush(1);
|
||||||
use Carp ();
|
use Carp ();
|
||||||
use PBot::Logger;
|
use PBot::Logger;
|
||||||
|
|
||||||
|
use PBot::SelectHandler;
|
||||||
use PBot::StdinReader;
|
use PBot::StdinReader;
|
||||||
|
|
||||||
use PBot::IRC;
|
use PBot::IRC;
|
||||||
|
@ -106,8 +107,10 @@ sub initialize {
|
||||||
$self->{commands} = PBot::Commands->new(pbot => $self);
|
$self->{commands} = PBot::Commands->new(pbot => $self);
|
||||||
$self->{timer} = PBot::Timer->new(timeout => 10);
|
$self->{timer} = PBot::Timer->new(timeout => 10);
|
||||||
|
|
||||||
$self->{admins} = PBot::BotAdmins->new(pbot => $self, filename => $admins_file);
|
$self->{select_handler} = PBot::SelectHandler->new(pbot => $self);
|
||||||
|
$self->{stdin_reader} = PBot::StdinReader->new(pbot => $self);
|
||||||
|
|
||||||
|
$self->{admins} = PBot::BotAdmins->new(pbot => $self, filename => $admins_file);
|
||||||
$self->admins->load_admins();
|
$self->admins->load_admins();
|
||||||
$self->admins->add_admin($self->{botnick}, '.*', "$self->{botnick}!stdin\@localhost", 60, 'admin');
|
$self->admins->add_admin($self->{botnick}, '.*', "$self->{botnick}!stdin\@localhost", 60, 'admin');
|
||||||
$self->admins->login($self->{botnick}, "$self->{botnick}!stdin\@localhost", 'admin');
|
$self->admins->login($self->{botnick}, "$self->{botnick}!stdin\@localhost", 'admin');
|
||||||
|
@ -215,8 +218,8 @@ sub do_one_loop {
|
||||||
# process IRC events
|
# process IRC events
|
||||||
$self->irc->do_one_loop();
|
$self->irc->do_one_loop();
|
||||||
|
|
||||||
# process STDIN events
|
# process SelectHandler
|
||||||
$self->check_stdin();
|
$self->{select_handler}->do_select();
|
||||||
}
|
}
|
||||||
|
|
||||||
sub start {
|
sub start {
|
||||||
|
@ -231,29 +234,6 @@ sub start {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub check_stdin {
|
|
||||||
my $self = shift;
|
|
||||||
|
|
||||||
my $input = PBot::StdinReader::check_stdin();
|
|
||||||
|
|
||||||
return if not defined $input;
|
|
||||||
|
|
||||||
$self->logger->log("---------------------------------------------\n");
|
|
||||||
$self->logger->log("Read '$input' from STDIN\n");
|
|
||||||
|
|
||||||
my ($from, $text);
|
|
||||||
|
|
||||||
if($input =~ m/^~([^ ]+)\s+(.*)/) {
|
|
||||||
$from = $1;
|
|
||||||
$text = "$self->{trigger}$2";
|
|
||||||
} else {
|
|
||||||
$from = "$self->{botnick}!stdin\@localhost";
|
|
||||||
$text = "$self->{trigger}$input";
|
|
||||||
}
|
|
||||||
|
|
||||||
return $self->interpreter->process_line($from, $self->{botnick}, "stdin", "localhost", $text);
|
|
||||||
}
|
|
||||||
|
|
||||||
#-----------------------------------------------------------------------------------
|
#-----------------------------------------------------------------------------------
|
||||||
# Getters/Setters
|
# Getters/Setters
|
||||||
#-----------------------------------------------------------------------------------
|
#-----------------------------------------------------------------------------------
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
package PBot::SelectHandler;
|
||||||
|
|
||||||
|
use warnings;
|
||||||
|
use strict;
|
||||||
|
|
||||||
|
use vars qw($VERSION);
|
||||||
|
$VERSION = '1.0.0';
|
||||||
|
|
||||||
|
use IO::Select;
|
||||||
|
use Carp ();
|
||||||
|
|
||||||
|
sub new {
|
||||||
|
if(ref($_[1]) eq 'HASH') {
|
||||||
|
Carp::croak("Options to SelectHandler should be key/value pairs, not hash reference");
|
||||||
|
}
|
||||||
|
|
||||||
|
my ($class, %conf) = @_;
|
||||||
|
|
||||||
|
my $self = bless {}, $class;
|
||||||
|
$self->initialize(%conf);
|
||||||
|
return $self;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub initialize {
|
||||||
|
my ($self, %conf) = @_;
|
||||||
|
|
||||||
|
$self->{pbot} = delete $conf{pbot} // Carp::croak("Missing pbot reference in SelectHandler");
|
||||||
|
$self->{select} = IO::Select->new();
|
||||||
|
$self->{readers} = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
sub add_reader {
|
||||||
|
my ($self, $handle, $sub) = @_;
|
||||||
|
$self->{select}->add($handle);
|
||||||
|
$self->{readers}->{$handle} = $sub;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub do_select {
|
||||||
|
my ($self) = @_;
|
||||||
|
my @ready = $self->{select}->can_read(.5);
|
||||||
|
foreach my $fh (@ready) {
|
||||||
|
my $ret = sysread($fh, my $buf, 4096);
|
||||||
|
|
||||||
|
if(not defined $ret) {
|
||||||
|
$self->{pbot}->logger->log("Error with $fh: $!\n");
|
||||||
|
$self->{select}->remove($fh);
|
||||||
|
delete $self->{readers}->{$fh};
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if($ret == 0) {
|
||||||
|
$self->{pbot}->logger->log("done with $fh\n");
|
||||||
|
$self->{select}->remove($fh);
|
||||||
|
delete $self->{readers}->{$fh};
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
|
||||||
|
chomp $buf;
|
||||||
|
$self->{pbot}->logger->log("read from $fh: [$buf]\n");
|
||||||
|
|
||||||
|
if(not exists $self->{readers}->{$fh}) {
|
||||||
|
$self->{pbot}->logger->log("Error: no reader for $fh\n");
|
||||||
|
} else {
|
||||||
|
$self->{readers}->{$fh}->($buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
|
@ -4,31 +4,56 @@ use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
|
|
||||||
use vars qw($VERSION);
|
use vars qw($VERSION);
|
||||||
|
|
||||||
$VERSION = '1.0.0';
|
$VERSION = '1.0.0';
|
||||||
|
|
||||||
use IO::Select;
|
|
||||||
use POSIX qw(tcgetpgrp getpgrp); # to check whether process is in background or foreground
|
use POSIX qw(tcgetpgrp getpgrp); # to check whether process is in background or foreground
|
||||||
|
use Carp ();
|
||||||
|
|
||||||
# used to listen for STDIN in non-blocking mode
|
sub new {
|
||||||
my $stdin = IO::Select->new();
|
if(ref($_[1]) eq 'HASH') {
|
||||||
$stdin->add(\*STDIN);
|
Carp::croak("Options to StdinReader should be key/value pairs, not hash reference");
|
||||||
|
}
|
||||||
|
|
||||||
|
my ($class, %conf) = @_;
|
||||||
|
my $self = bless {}, $class;
|
||||||
|
$self->initialize(%conf);
|
||||||
|
return $self;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub initialize {
|
||||||
|
my ($self, %conf) = @_;
|
||||||
|
|
||||||
|
$self->{pbot} = delete $conf{pbot} // Carp::croak("Missing pbot reference in StdinReader");
|
||||||
|
|
||||||
# used to check whether process is in background or foreground, for stdin reading
|
# used to check whether process is in background or foreground, for stdin reading
|
||||||
open TTY, "</dev/tty" or die $!;
|
open TTY, "</dev/tty" or die $!;
|
||||||
my $tty_fd = fileno(TTY);
|
$self->{tty_fd} = fileno(TTY);
|
||||||
my $foreground = (tcgetpgrp($tty_fd) == getpgrp()) ? 1 : 0;
|
$self->{foreground} = (tcgetpgrp($self->{tty_fd}) == getpgrp()) ? 1 : 0;
|
||||||
|
|
||||||
sub check_stdin {
|
$self->{pbot}->{select_handler}->add_reader(\*STDIN, sub { $self->stdin_reader(@_) });
|
||||||
# make sure we're in the foreground first
|
|
||||||
$foreground = (tcgetpgrp($tty_fd) == getpgrp()) ? 1 : 0;
|
|
||||||
return if not $foreground;
|
|
||||||
|
|
||||||
if ($stdin->can_read(.5)) {
|
|
||||||
sysread(STDIN, my $input, 1024);
|
|
||||||
chomp $input;
|
|
||||||
return $input;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub stdin_reader {
|
||||||
|
my ($self, $input) = @_;
|
||||||
|
|
||||||
|
# make sure we're in the foreground first
|
||||||
|
$self->{foreground} = (tcgetpgrp($self->{tty_fd}) == getpgrp()) ? 1 : 0;
|
||||||
|
return if not $self->{foreground};
|
||||||
|
|
||||||
|
$self->{pbot}->logger->log("---------------------------------------------\n");
|
||||||
|
$self->{pbot}->logger->log("Read '$input' from STDIN\n");
|
||||||
|
|
||||||
|
my ($from, $text);
|
||||||
|
|
||||||
|
if($input =~ m/^~([^ ]+)\s+(.*)/) {
|
||||||
|
$from = $1;
|
||||||
|
$text = "$self->{pbot}->{trigger}$2";
|
||||||
|
} else {
|
||||||
|
$from = "$self->{pbot}->{botnick}!stdin\@localhost";
|
||||||
|
$text = "$self->{pbot}->{trigger}$input";
|
||||||
|
}
|
||||||
|
|
||||||
|
return $self->{pbot}->interpreter->process_line($from, $self->{pbot}->{botnick}, "stdin", "localhost", $text);
|
||||||
}
|
}
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
|
|
@ -13,7 +13,7 @@ use warnings;
|
||||||
# These are set automatically by the build/commit script
|
# These are set automatically by the build/commit script
|
||||||
use constant {
|
use constant {
|
||||||
BUILD_NAME => "PBot",
|
BUILD_NAME => "PBot",
|
||||||
BUILD_REVISION => 523,
|
BUILD_REVISION => 524,
|
||||||
BUILD_DATE => "2014-03-13",
|
BUILD_DATE => "2014-03-13",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue