mirror of
https://github.com/pragma-/pbot.git
synced 2025-02-02 15:34:05 +01:00
Improve recall
command with better capabilities
The nick field is now optional and Getopt::Long is used to accept targeted options for channel/history, allowing recalls by text/channel for any nick which is useful when you know what text the message contained but not who said it.
This commit is contained in:
parent
dad69fb0c8
commit
92b4ef00cf
@ -12,6 +12,7 @@ package PBot::MessageHistory;
|
||||
use warnings;
|
||||
use strict;
|
||||
|
||||
use Getopt::Long qw(GetOptionsFromString);
|
||||
use Time::HiRes qw(gettimeofday tv_interval);
|
||||
use Time::Duration;
|
||||
use Carp ();
|
||||
@ -62,50 +63,110 @@ sub recall_message {
|
||||
return "";
|
||||
}
|
||||
|
||||
my $usage = 'Usage: recall [nick [history [channel]]] [-c,channel <channel>] [-t,text,h,history <history>] [+ ...]';
|
||||
|
||||
if(not defined $arguments or not length $arguments) {
|
||||
return "Usage: recall <nick> [history [channel]] -- where [history] is an optional argument that is either an integral number of recent messages or a regex (without whitespace) of the text within the message; e.g., to recall the 3rd most recent message for nick, use `recall nick 3` or to recall a message containing 'pizza', use `recall nick pizza`; and [channel] is an optional channel, so you can use it from /msg (you will need to also specify [history] in this case)";
|
||||
return $usage;
|
||||
}
|
||||
|
||||
$arguments = lc $arguments;
|
||||
|
||||
my @recalls = split /\s\+\s/, $arguments;
|
||||
|
||||
my ($recall_nick, $recall_history, $channel, $recall_nicks, $recall_text);
|
||||
my $getopt_error;
|
||||
local $SIG{__WARN__} = sub {
|
||||
$getopt_error = shift;
|
||||
chomp $getopt_error;
|
||||
};
|
||||
|
||||
my $recall_text;
|
||||
|
||||
foreach my $recall (@recalls) {
|
||||
($recall_nick, $recall_history, $channel) = split(/\s+/, $recall, 3);
|
||||
my ($recall_nick, $recall_history, $recall_channel);
|
||||
|
||||
$recall_history = $nick eq $recall_nick ? 2 : 1 if not defined $recall_history; # skip recall command if recalling self without arguments
|
||||
$channel = $from if not defined $channel;
|
||||
my ($ret, $args) = GetOptionsFromString($recall,
|
||||
'channel|c=s' => \$recall_channel,
|
||||
'text|t|history|h=s' => \$recall_history);
|
||||
|
||||
my ($account, $found_nick) = $self->{database}->find_message_account_by_nick($recall_nick);
|
||||
return "$getopt_error -- $usage" if defined $getopt_error;
|
||||
|
||||
my $channel_arg = 1 if defined $recall_channel;
|
||||
my $history_arg = 1 if defined $recall_history;
|
||||
|
||||
$recall_nick = shift @$args;
|
||||
$recall_history = shift @$args if not defined $recall_history;
|
||||
$recall_channel = shift @$args if not defined $recall_channel;
|
||||
|
||||
# swap nick and channel if recall nick looks like channel and channel wasn't specified
|
||||
if(not $channel_arg and $recall_nick =~ m/^#/) {
|
||||
my $temp = $recall_nick;
|
||||
$recall_nick = $recall_channel;
|
||||
$recall_channel = $temp;
|
||||
}
|
||||
|
||||
# swap history and channel if history looks like a channel and neither history or channel were specified
|
||||
if(not $channel_arg and not $history_arg and $recall_history =~ m/^#/) {
|
||||
my $temp = $recall_history;
|
||||
$recall_history = $recall_channel;
|
||||
$recall_channel = $temp;
|
||||
}
|
||||
|
||||
# skip recall command if recalling self without arguments
|
||||
$recall_history = $nick eq $recall_nick ? 2 : 1 if defined $recall_nick and not defined $recall_history;
|
||||
|
||||
# set history to most recent message if not specified
|
||||
$recall_history = '1' if not defined $recall_history;
|
||||
|
||||
# set channel to current channel if not specified
|
||||
$recall_channel = $from if not defined $recall_channel;
|
||||
|
||||
my ($account, $found_nick);
|
||||
|
||||
if(defined $recall_nick) {
|
||||
($account, $found_nick) = $self->{database}->find_message_account_by_nick($recall_nick);
|
||||
|
||||
if(not defined $account) {
|
||||
return "I don't know anybody named $recall_nick.";
|
||||
}
|
||||
}
|
||||
|
||||
my $message;
|
||||
|
||||
if($recall_history =~ /^\d+$/) {
|
||||
# integral history
|
||||
my $max_messages = $self->{database}->get_max_messages($account, $channel);
|
||||
if(defined $account) {
|
||||
my $max_messages = $self->{database}->get_max_messages($account, $recall_channel);
|
||||
if($recall_history < 1 || $recall_history > $max_messages) {
|
||||
return "Please choose a history between 1 and $max_messages";
|
||||
}
|
||||
}
|
||||
|
||||
$recall_history--;
|
||||
|
||||
$message = $self->{database}->recall_message_by_count($account, $channel, $recall_history, 'recall');
|
||||
} else {
|
||||
# regex history
|
||||
$message = $self->{database}->recall_message_by_text($account, $channel, $recall_history, 'recall');
|
||||
$message = $self->{database}->recall_message_by_count($account, $recall_channel, $recall_history, 'recall');
|
||||
|
||||
if(not defined $message) {
|
||||
return "No such message for nick $found_nick in channel $channel containing text '$recall_history'";
|
||||
return "No message found at index $recall_history in channel $recall_channel.";
|
||||
}
|
||||
} else {
|
||||
# regex history
|
||||
$message = $self->{database}->recall_message_by_text($account, $recall_channel, $recall_history, 'recall');
|
||||
|
||||
if(not defined $message) {
|
||||
if(defined $account) {
|
||||
return "No such message for nick $found_nick in channel $recall_channel containing text '$recall_history'";
|
||||
} else {
|
||||
return "No such message in channel $recall_channel containing text '$recall_history'";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$self->{pbot}->logger->log("$nick ($from) recalled <$recall_nick/$channel> $message->{msg}\n");
|
||||
if(defined $message->{id}) {
|
||||
my $hostmask = $self->{database}->find_most_recent_hostmask($message->{id});
|
||||
($found_nick) = $hostmask =~ m/^([^!]+)/;
|
||||
$recall_nick = $found_nick;
|
||||
}
|
||||
|
||||
$self->{pbot}->logger->log("$nick ($from) recalled <$recall_nick/$recall_channel> $message->{msg}\n");
|
||||
|
||||
my $text = $message->{msg};
|
||||
my $ago = ago(gettimeofday - $message->{timestamp});
|
||||
|
@ -409,7 +409,10 @@ SQL
|
||||
sub recall_message_by_count {
|
||||
my ($self, $id, $channel, $count, $ignore_command) = @_;
|
||||
|
||||
my $messages = eval {
|
||||
my $messages;
|
||||
|
||||
if(defined $id) {
|
||||
$messages = eval {
|
||||
my $sth = $self->{dbh}->prepare('SELECT msg, mode, timestamp FROM Messages WHERE id = ? AND channel = ? ORDER BY timestamp DESC LIMIT 10 OFFSET ?');
|
||||
$sth->bind_param(1, $id);
|
||||
$sth->bind_param(2, $channel);
|
||||
@ -417,6 +420,15 @@ sub recall_message_by_count {
|
||||
$sth->execute();
|
||||
return $sth->fetchall_arrayref({});
|
||||
};
|
||||
} else {
|
||||
$messages = eval {
|
||||
my $sth = $self->{dbh}->prepare('SELECT id, msg, mode, timestamp FROM Messages WHERE channel = ? ORDER BY timestamp DESC LIMIT 10 OFFSET ?');
|
||||
$sth->bind_param(1, $channel);
|
||||
$sth->bind_param(2, $count);
|
||||
$sth->execute();
|
||||
return $sth->fetchall_arrayref({});
|
||||
};
|
||||
}
|
||||
|
||||
$self->{pbot}->logger->log($@) if $@;
|
||||
|
||||
@ -438,7 +450,10 @@ sub recall_message_by_text {
|
||||
$text =~ s/\*/%/g;
|
||||
$text =~ s/\?/_/g;
|
||||
|
||||
my $messages = eval {
|
||||
my $messages;
|
||||
|
||||
if(defined $id) {
|
||||
$messages = eval {
|
||||
my $sth = $self->{dbh}->prepare('SELECT msg,mode,timestamp FROM Messages WHERE id = ? AND channel = ? AND msg LIKE ? ORDER BY timestamp DESC LIMIT 10');
|
||||
$sth->bind_param(1, $id);
|
||||
$sth->bind_param(2, $channel);
|
||||
@ -446,6 +461,15 @@ sub recall_message_by_text {
|
||||
$sth->execute();
|
||||
return $sth->fetchall_arrayref({});
|
||||
};
|
||||
} else {
|
||||
$messages = eval {
|
||||
my $sth = $self->{dbh}->prepare('SELECT id, msg, mode, timestamp FROM Messages WHERE channel = ? AND msg LIKE ? ORDER BY timestamp DESC LIMIT 10');
|
||||
$sth->bind_param(1, $channel);
|
||||
$sth->bind_param(2, "%$text%");
|
||||
$sth->execute();
|
||||
return $sth->fetchall_arrayref({});
|
||||
};
|
||||
}
|
||||
|
||||
$self->{pbot}->logger->log($@) if $@;
|
||||
|
||||
|
@ -315,7 +315,7 @@ sub show_random_quotegrab {
|
||||
return "";
|
||||
}
|
||||
|
||||
my $usage = 'Usage: rq [nick regex] [-c,--channel <channel regex>] [-t,--text <text regex>]';
|
||||
my $usage = 'Usage: rq [nick [channel [text]]] [-c,--channel <channel>] [-t,--text <text>]';
|
||||
|
||||
if(defined $arguments) {
|
||||
my $getopt_error;
|
||||
|
@ -13,8 +13,8 @@ use warnings;
|
||||
# These are set automatically by the build/commit script
|
||||
use constant {
|
||||
BUILD_NAME => "PBot",
|
||||
BUILD_REVISION => 572,
|
||||
BUILD_DATE => "2014-05-13",
|
||||
BUILD_REVISION => 573,
|
||||
BUILD_DATE => "2014-05-14",
|
||||
};
|
||||
|
||||
1;
|
||||
|
Loading…
Reference in New Issue
Block a user