mirror of
https://github.com/pragma-/pbot.git
synced 2024-11-20 02:49:49 +01:00
Add countertrigger command to Counter plugin
This commit is contained in:
parent
d8c2084587
commit
d251d0ac7a
@ -4,6 +4,9 @@ package PBot::Plugins::Counter;
|
|||||||
use warnings;
|
use warnings;
|
||||||
use strict;
|
use strict;
|
||||||
|
|
||||||
|
use feature 'switch';
|
||||||
|
no if $] >= 5.018, warnings => "experimental::smartmatch";
|
||||||
|
|
||||||
use Carp ();
|
use Carp ();
|
||||||
use DBI;
|
use DBI;
|
||||||
use Time::Duration qw/duration/;
|
use Time::Duration qw/duration/;
|
||||||
@ -22,11 +25,14 @@ sub initialize {
|
|||||||
|
|
||||||
$self->{pbot} = delete $conf{pbot} // Carp::croak("Missing pbot reference to " . __FILE__);
|
$self->{pbot} = delete $conf{pbot} // Carp::croak("Missing pbot reference to " . __FILE__);
|
||||||
|
|
||||||
$self->{pbot}->{commands}->register(sub { $self->counteradd(@_) }, 'counteradd', 0);
|
$self->{pbot}->{commands}->register(sub { $self->counteradd(@_) }, 'counteradd', 0);
|
||||||
$self->{pbot}->{commands}->register(sub { $self->counterdel(@_) }, 'counterdel', 0);
|
$self->{pbot}->{commands}->register(sub { $self->counterdel(@_) }, 'counterdel', 0);
|
||||||
$self->{pbot}->{commands}->register(sub { $self->counterreset(@_) }, 'counterreset', 0);
|
$self->{pbot}->{commands}->register(sub { $self->counterreset(@_) }, 'counterreset', 0);
|
||||||
$self->{pbot}->{commands}->register(sub { $self->countershow(@_) }, 'countershow', 0);
|
$self->{pbot}->{commands}->register(sub { $self->countershow(@_) }, 'countershow', 0);
|
||||||
$self->{pbot}->{commands}->register(sub { $self->counterlist(@_) }, 'counterlist', 0);
|
$self->{pbot}->{commands}->register(sub { $self->counterlist(@_) }, 'counterlist', 0);
|
||||||
|
$self->{pbot}->{commands}->register(sub { $self->countertrigger(@_) }, 'countertrigger', 0);
|
||||||
|
|
||||||
|
$self->{pbot}->{event_dispatcher}->register_handler('irc.public', sub { $self->on_public(@_) });
|
||||||
|
|
||||||
$self->{filename} = $self->{pbot}->{registry}->get_value('general', 'data_dir') . '/counters.sqlite3';
|
$self->{filename} = $self->{pbot}->{registry}->get_value('general', 'data_dir') . '/counters.sqlite3';
|
||||||
|
|
||||||
@ -41,6 +47,7 @@ sub unload {
|
|||||||
$self->{pbot}->{commands}->unregister('counterreset');
|
$self->{pbot}->{commands}->unregister('counterreset');
|
||||||
$self->{pbot}->{commands}->unregister('countershow');
|
$self->{pbot}->{commands}->unregister('countershow');
|
||||||
$self->{pbot}->{commands}->unregister('counterlist');
|
$self->{pbot}->{commands}->unregister('counterlist');
|
||||||
|
$self->{pbot}->{commands}->unregister('countertrigger');
|
||||||
}
|
}
|
||||||
|
|
||||||
sub create_database {
|
sub create_database {
|
||||||
@ -56,6 +63,14 @@ CREATE TABLE IF NOT EXISTS Counters (
|
|||||||
description TEXT,
|
description TEXT,
|
||||||
timestamp NUMERIC
|
timestamp NUMERIC
|
||||||
)
|
)
|
||||||
|
SQL
|
||||||
|
|
||||||
|
$self->{dbh}->do(<<SQL);
|
||||||
|
CREATE TABLE IF NOT EXISTS Triggers (
|
||||||
|
channel TEXT,
|
||||||
|
trigger TEXT,
|
||||||
|
target TEXT,
|
||||||
|
)
|
||||||
SQL
|
SQL
|
||||||
|
|
||||||
$self->{dbh}->disconnect;
|
$self->{dbh}->disconnect;
|
||||||
@ -91,12 +106,19 @@ sub add_counter {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
my $sth = $self->{dbh}->prepare('INSERT INTO Counters (channel, name, description, timestamp) VALUES (?, ?, ?, ?)');
|
eval {
|
||||||
$sth->bind_param(1, lc $channel);
|
my $sth = $self->{dbh}->prepare('INSERT INTO Counters (channel, name, description, timestamp) VALUES (?, ?, ?, ?)');
|
||||||
$sth->bind_param(2, lc $name);
|
$sth->bind_param(1, lc $channel);
|
||||||
$sth->bind_param(3, $description);
|
$sth->bind_param(2, lc $name);
|
||||||
$sth->bind_param(4, scalar gettimeofday);
|
$sth->bind_param(3, $description);
|
||||||
$sth->execute();
|
$sth->bind_param(4, scalar gettimeofday);
|
||||||
|
$sth->execute();
|
||||||
|
};
|
||||||
|
|
||||||
|
if ($@) {
|
||||||
|
$self->{pbot}->{logger}->log("Add counter failed: $@");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -109,11 +131,18 @@ sub reset_counter {
|
|||||||
return (undef, undef);
|
return (undef, undef);
|
||||||
}
|
}
|
||||||
|
|
||||||
my $sth = $self->{dbh}->prepare('UPDATE Counters SET timestamp = ? WHERE channel = ? AND name = ?');
|
eval {
|
||||||
$sth->bind_param(1, scalar gettimeofday);
|
my $sth = $self->{dbh}->prepare('UPDATE Counters SET timestamp = ? WHERE channel = ? AND name = ?');
|
||||||
$sth->bind_param(2, lc $channel);
|
$sth->bind_param(1, scalar gettimeofday);
|
||||||
$sth->bind_param(3, lc $name);
|
$sth->bind_param(2, lc $channel);
|
||||||
$sth->execute();
|
$sth->bind_param(3, lc $name);
|
||||||
|
$sth->execute();
|
||||||
|
};
|
||||||
|
|
||||||
|
if ($@) {
|
||||||
|
$self->{pbot}->{logger}->log("Reset counter failed: $@");
|
||||||
|
return (undef, undef);
|
||||||
|
}
|
||||||
|
|
||||||
return ($description, $timestamp);
|
return ($description, $timestamp);
|
||||||
}
|
}
|
||||||
@ -126,10 +155,18 @@ sub delete_counter {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
my $sth = $self->{dbh}->prepare('DELETE FROM Counters WHERE channel = ? AND name = ?');
|
eval {
|
||||||
$sth->bind_param(1, lc $channel);
|
my $sth = $self->{dbh}->prepare('DELETE FROM Counters WHERE channel = ? AND name = ?');
|
||||||
$sth->bind_param(2, lc $name);
|
$sth->bind_param(1, lc $channel);
|
||||||
$sth->execute();
|
$sth->bind_param(2, lc $name);
|
||||||
|
$sth->execute();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
if ($@) {
|
||||||
|
$self->{pbot}->{logger}->log("Delete counter failed: $@");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -145,7 +182,7 @@ sub list_counters {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if ($@) {
|
if ($@) {
|
||||||
$self->{pbot}->{logger}->log("Get counter failed: $@");
|
$self->{pbot}->{logger}->log("List counters failed: $@");
|
||||||
}
|
}
|
||||||
|
|
||||||
return map { $_->[0] } @$counters;
|
return map { $_->[0] } @$counters;
|
||||||
@ -171,6 +208,83 @@ sub get_counter {
|
|||||||
return ($description, $time);
|
return ($description, $time);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub add_trigger {
|
||||||
|
my ($self, $channel, $trigger, $target) = @_;
|
||||||
|
|
||||||
|
my $exists = $self->get_trigger($channel, $trigger);
|
||||||
|
if (defined $exists) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
eval {
|
||||||
|
my $sth = $self->{dbh}->prepare('INSERT INTO Triggers (channel, trigger, target) VALUES (?, ?, ?)');
|
||||||
|
$sth->bind_param(1, lc $channel);
|
||||||
|
$sth->bind_param(2, lc $trigger);
|
||||||
|
$sth->bind_param(3, lc $target);
|
||||||
|
$sth->execute();
|
||||||
|
};
|
||||||
|
|
||||||
|
if ($@) {
|
||||||
|
$self->{pbot}->{logger}->log("Add trigger failed: $@");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub delete_trigger {
|
||||||
|
my ($self, $channel, $trigger) = @_;
|
||||||
|
|
||||||
|
my $target = $self->get_trigger($channel, $trigger);
|
||||||
|
if (not defined $target) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
my $sth = $self->{dbh}->prepare('DELETE FROM Triggers WHERE channel = ? AND trigger = ?');
|
||||||
|
$sth->bind_param(1, lc $channel);
|
||||||
|
$sth->bind_param(2, lc $trigger);
|
||||||
|
$sth->execute();
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub list_triggers {
|
||||||
|
my ($self, $channel) = @_;
|
||||||
|
|
||||||
|
my $triggers = eval {
|
||||||
|
my $sth = $self->{dbh}->prepare('SELECT trigger, target FROM Triggers WHERE channel = ?');
|
||||||
|
$sth->bind_param(1, lc $channel);
|
||||||
|
$sth->execute();
|
||||||
|
return $sth->fetchall_arrayref({});
|
||||||
|
};
|
||||||
|
|
||||||
|
if ($@) {
|
||||||
|
$self->{pbot}->{logger}->log("List triggers failed: $@");
|
||||||
|
}
|
||||||
|
|
||||||
|
return @$triggers;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub get_trigger {
|
||||||
|
my ($self, $channel, $trigger) = @_;
|
||||||
|
|
||||||
|
my $target = eval {
|
||||||
|
my $sth = $self->{dbh}->prepare('SELECT target FROM Triggers WHERE channel = ? AND trigger = ?');
|
||||||
|
$sth->bind_param(1, lc $channel);
|
||||||
|
$sth->bind_param(2, lc $trigger);
|
||||||
|
$sth->execute();
|
||||||
|
my $row = $sth->fetchrow_hashref();
|
||||||
|
return $row->{target};
|
||||||
|
};
|
||||||
|
|
||||||
|
if ($@) {
|
||||||
|
$self->{pbot}->{logger}->log("Get trigger failed: $@");
|
||||||
|
return undef;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $target;
|
||||||
|
}
|
||||||
|
|
||||||
sub counteradd {
|
sub counteradd {
|
||||||
my ($self, $from, $nick, $user, $host, $arguments) = @_;
|
my ($self, $from, $nick, $user, $host, $arguments) = @_;
|
||||||
|
|
||||||
@ -263,7 +377,7 @@ sub counterreset {
|
|||||||
my ($description, $timestamp) = $self->reset_counter($channel, $name);
|
my ($description, $timestamp) = $self->reset_counter($channel, $name);
|
||||||
if (defined $description) {
|
if (defined $description) {
|
||||||
my $ago = duration gettimeofday - $timestamp;
|
my $ago = duration gettimeofday - $timestamp;
|
||||||
$result = "It had been $ago since $description.";
|
$result = "It had been $ago since $description. Not any more.";
|
||||||
} else {
|
} else {
|
||||||
$result = "No such counter.";
|
$result = "No such counter.";
|
||||||
}
|
}
|
||||||
@ -343,4 +457,159 @@ sub counterlist {
|
|||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub countertrigger {
|
||||||
|
my ($self, $from, $nick, $user, $host, $arguments) = @_;
|
||||||
|
|
||||||
|
if (not $self->dbi_begin) {
|
||||||
|
return "Internal error.";
|
||||||
|
}
|
||||||
|
|
||||||
|
my $command;
|
||||||
|
($command, $arguments) = split / /, $arguments, 2;
|
||||||
|
|
||||||
|
my ($channel, $result);
|
||||||
|
|
||||||
|
given ($command) {
|
||||||
|
when ('list') {
|
||||||
|
if ($from =~ m/^#/) {
|
||||||
|
$channel = $from;
|
||||||
|
} else {
|
||||||
|
($channel) = split / /, $arguments, 1;
|
||||||
|
if ($channel !~ m/^#/) {
|
||||||
|
$self->dbi_end;
|
||||||
|
return "Usage from private message: countertrigger list <channel>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
my @triggers = $self->list_triggers($channel);
|
||||||
|
|
||||||
|
if (not @triggers) {
|
||||||
|
$result = "No counter triggers set for $channel.";
|
||||||
|
} else {
|
||||||
|
$result = "Triggers for $channel: ";
|
||||||
|
my $comma = '';
|
||||||
|
foreach my $trigger (@triggers) {
|
||||||
|
$result .= "$comma$trigger->{trigger} -> $trigger->{target}";
|
||||||
|
$comma = ', ';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
when ('add') {
|
||||||
|
if ($from =~ m/^#/) {
|
||||||
|
$channel = $from;
|
||||||
|
} else {
|
||||||
|
($channel, $arguments) = split / /, $arguments, 2;
|
||||||
|
if ($channel !~ m/^#/) {
|
||||||
|
$self->dbi_end;
|
||||||
|
return "Usage from private message: countertrigger add <channel> <regex> <target>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
my ($trigger, $target) = split / /, $arguments, 2;
|
||||||
|
|
||||||
|
if (not defined $trigger or not defined $target) {
|
||||||
|
if ($from !~ m/^#/) {
|
||||||
|
$result = "Usage from private message: countertrigger add <channel> <regex> <target>";
|
||||||
|
} else {
|
||||||
|
$result = "Usage: countertrigger add <regex> <target>";
|
||||||
|
}
|
||||||
|
$self->dbi_end;
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
my $exists = $self->get_trigger($channel, $trigger);
|
||||||
|
|
||||||
|
if (defined $exists) {
|
||||||
|
$self->dbi_end;
|
||||||
|
return "Trigger already exists.";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($self->add_trigger($channel, $trigger, $target)) {
|
||||||
|
$result = "Trigger added.";
|
||||||
|
} else {
|
||||||
|
$result = "Failed to add trigger.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
when ('delete') {
|
||||||
|
if ($from =~ m/^#/) {
|
||||||
|
$channel = $from;
|
||||||
|
} else {
|
||||||
|
($channel, $arguments) = split / /, $arguments, 2;
|
||||||
|
if ($channel !~ m/^#/) {
|
||||||
|
$self->dbi_end;
|
||||||
|
return "Usage from private message: countertrigger delete <channel> <regex>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
my ($trigger) = split / /, $arguments, 1;
|
||||||
|
|
||||||
|
if (not defined $trigger) {
|
||||||
|
if ($from !~ m/^#/) {
|
||||||
|
$result = "Usage from private message: countertrigger delete <channel> <regex>";
|
||||||
|
} else {
|
||||||
|
$result = "Usage: countertrigger delete <regex>";
|
||||||
|
}
|
||||||
|
$self->dbi_end;
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
my $target = $self->get_trigger($channel, $trigger);
|
||||||
|
|
||||||
|
if (not defined $target) {
|
||||||
|
$result = "No such trigger.";
|
||||||
|
} else {
|
||||||
|
$self->delete_trigger($channel, $trigger);
|
||||||
|
$result = "Trigger deleted.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
default {
|
||||||
|
$result = "Usage: countertrigger <list/add/delete> [arguments]";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$self->dbi_end;
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub on_public {
|
||||||
|
my ($self, $event_type, $event) = @_;
|
||||||
|
my ($nick, $user, $host, $msg) = ($event->{event}->nick, $event->{event}->user, $event->{event}->host, $event->{event}->args);
|
||||||
|
my $channel = $event->{event}->{to}[0];
|
||||||
|
|
||||||
|
if (not $self->dbi_begin) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
my @triggers = $self->list_triggers($channel);
|
||||||
|
|
||||||
|
my $message = "$nick!$user\@$host $msg";
|
||||||
|
|
||||||
|
eval {
|
||||||
|
foreach my $trigger (@triggers) {
|
||||||
|
if ($message =~ m/$trigger->{trigger}/i) {
|
||||||
|
my ($desc, $timestamp) = $self->reset_counter($channel, $trigger->{target});
|
||||||
|
|
||||||
|
if (defined $desc) {
|
||||||
|
if (gettimeofday - $timestamp >= 60 * 60) {
|
||||||
|
my $ago = duration gettimeofday - $timestamp;
|
||||||
|
$event->{conn}->privmsg($channel, "It had been $ago since $desc. Not any more.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if ($@) {
|
||||||
|
$self->{pbot}->{logger}->log("Error in counter trigger: $@");
|
||||||
|
}
|
||||||
|
|
||||||
|
$self->dbi_end;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
Loading…
Reference in New Issue
Block a user