mirror of
https://github.com/pragma-/pbot.git
synced 2024-12-02 00:49:26 +01:00
Quotegrabs.pm now uses quotegrabs_db API for interfacing with storage backend
Two quotegrabs_db backends are now availble: * Quotegrabs_Hashtable.pm: the original hashtable implementation * Quotegrabs_SQLite.pm: the new SQLite implementation Quotegrabs_SQLite.pm is now the default quotegrabs_db backend. This was done to reduce the memory footprint of the bot by not needing to keep the entire quotegrabs table in memory any longer. A similiar change will be coming soon to the Factoids table as well as the MessageHistory table.
This commit is contained in:
parent
2c2b2c2e4b
commit
239e3de8ea
@ -160,6 +160,7 @@ sub ack_die {
|
|||||||
$self->{pbot}->factoids->save_factoids;
|
$self->{pbot}->factoids->save_factoids;
|
||||||
$self->{pbot}->ignorelist->save_ignores;
|
$self->{pbot}->ignorelist->save_ignores;
|
||||||
$self->{pbot}->antiflood->save_message_history;
|
$self->{pbot}->antiflood->save_message_history;
|
||||||
|
$self->{pbot}->{quotegrabs}->{quotegrabs_db}->end();
|
||||||
$self->{pbot}->conn->privmsg($from, "Good-bye.") if defined $from;
|
$self->{pbot}->conn->privmsg($from, "Good-bye.") if defined $from;
|
||||||
$self->{pbot}->conn->quit("Departure requested.");
|
$self->{pbot}->conn->quit("Departure requested.");
|
||||||
exit 0;
|
exit 0;
|
||||||
|
@ -55,7 +55,7 @@ use PBot::Timer;
|
|||||||
|
|
||||||
sub new {
|
sub new {
|
||||||
if(ref($_[1]) eq 'HASH') {
|
if(ref($_[1]) eq 'HASH') {
|
||||||
Carp::croak("Options to Logger should be key/value pairs, not hash reference");
|
Carp::croak("Options to PBot should be key/value pairs, not hash reference");
|
||||||
}
|
}
|
||||||
|
|
||||||
my ($class, %conf) = @_;
|
my ($class, %conf) = @_;
|
||||||
@ -159,9 +159,6 @@ sub initialize {
|
|||||||
export_site => $export_quotegrabs_site,
|
export_site => $export_quotegrabs_site,
|
||||||
);
|
);
|
||||||
|
|
||||||
$self->quotegrabs->add_quotegrab($self->{botnick}, "#pbot2", 0, "pragma_", "Who's a bot?");
|
|
||||||
$self->quotegrabs->load_quotegrabs() if defined $quotegrabs_file;
|
|
||||||
|
|
||||||
$self->timer->start();
|
$self->timer->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,6 +16,9 @@ use Time::Duration;
|
|||||||
use Time::HiRes qw(gettimeofday);
|
use Time::HiRes qw(gettimeofday);
|
||||||
use Getopt::Long qw(GetOptionsFromString);
|
use Getopt::Long qw(GetOptionsFromString);
|
||||||
|
|
||||||
|
use PBot::Quotegrabs_SQLite; # use SQLite backend for quotegrabs database
|
||||||
|
#use PBot::Quotegrabs_Hashtable; # use Perl hashtable backend for quotegrabs database
|
||||||
|
|
||||||
use POSIX qw(strftime);
|
use POSIX qw(strftime);
|
||||||
|
|
||||||
sub new {
|
sub new {
|
||||||
@ -37,7 +40,10 @@ sub initialize {
|
|||||||
$self->{filename} = delete $conf{filename};
|
$self->{filename} = delete $conf{filename};
|
||||||
$self->{export_path} = delete $conf{export_path};
|
$self->{export_path} = delete $conf{export_path};
|
||||||
$self->{export_site} = delete $conf{export_site};
|
$self->{export_site} = delete $conf{export_site};
|
||||||
$self->{quotegrabs} = [];
|
|
||||||
|
$self->{quotegrabs_db} = PBot::Quotegrabs_SQLite->new(pbot => $self->{pbot}, filename => $self->{filename});
|
||||||
|
#$self->{quotegrabs_db} = PBot::Quotegrabs_Hashtable->new(pbot => $self->{pbot}, filename => $self->{filename});
|
||||||
|
$self->{quotegrabs_db}->begin();
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------------
|
||||||
# The following could be in QuotegrabsCommands.pm, or they could be kept in here?
|
# The following could be in QuotegrabsCommands.pm, or they could be kept in here?
|
||||||
@ -51,66 +57,14 @@ sub initialize {
|
|||||||
$self->{pbot}->commands->register(sub { $self->recall_message(@_) }, "recall", 0);
|
$self->{pbot}->commands->register(sub { $self->recall_message(@_) }, "recall", 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
sub load_quotegrabs {
|
|
||||||
my $self = shift;
|
|
||||||
my $filename;
|
|
||||||
|
|
||||||
if(@_) { $filename = shift; } else { $filename = $self->{filename}; }
|
|
||||||
return if not defined $filename;
|
|
||||||
|
|
||||||
$self->{pbot}->logger->log("Loading quotegrabs from $filename ...\n");
|
|
||||||
|
|
||||||
open(FILE, "< $filename") or die "Couldn't open $filename: $!\n";
|
|
||||||
my @contents = <FILE>;
|
|
||||||
close(FILE);
|
|
||||||
|
|
||||||
my $i = 0;
|
|
||||||
foreach my $line (@contents) {
|
|
||||||
chomp $line;
|
|
||||||
$i++;
|
|
||||||
my ($nick, $channel, $timestamp, $grabbed_by, $text) = split(/\s+/, $line, 5);
|
|
||||||
if(not defined $nick || not defined $channel || not defined $timestamp
|
|
||||||
|| not defined $grabbed_by || not defined $text) {
|
|
||||||
die "Syntax error around line $i of $self->{quotegrabs}_file\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
my $quotegrab = {};
|
|
||||||
$quotegrab->{nick} = $nick;
|
|
||||||
$quotegrab->{channel} = $channel;
|
|
||||||
$quotegrab->{timestamp} = $timestamp;
|
|
||||||
$quotegrab->{grabbed_by} = $grabbed_by;
|
|
||||||
$quotegrab->{text} = $text;
|
|
||||||
$quotegrab->{id} = $i + 1;
|
|
||||||
push @{ $self->{quotegrabs} }, $quotegrab;
|
|
||||||
}
|
|
||||||
$self->{pbot}->logger->log(" $i quotegrabs loaded.\n");
|
|
||||||
$self->{pbot}->logger->log("Done.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
sub save_quotegrabs {
|
|
||||||
my $self = shift;
|
|
||||||
my $filename;
|
|
||||||
|
|
||||||
if(@_) { $filename = shift; } else { $filename = $self->{filename}; }
|
|
||||||
return if not defined $filename;
|
|
||||||
|
|
||||||
open(FILE, "> $filename") or die "Couldn't open $filename: $!\n";
|
|
||||||
|
|
||||||
for(my $i = 0; $i <= $#{ $self->{quotegrabs} }; $i++) {
|
|
||||||
my $quotegrab = $self->{quotegrabs}[$i];
|
|
||||||
next if $quotegrab->{timestamp} == 0;
|
|
||||||
print FILE "$quotegrab->{nick} $quotegrab->{channel} $quotegrab->{timestamp} $quotegrab->{grabbed_by} $quotegrab->{text}\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
close(FILE);
|
|
||||||
$self->export_quotegrabs();
|
|
||||||
}
|
|
||||||
|
|
||||||
sub uniq { my %seen; grep !$seen{$_}++, @_ }
|
sub uniq { my %seen; grep !$seen{$_}++, @_ }
|
||||||
|
|
||||||
sub export_quotegrabs() {
|
sub export_quotegrabs {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
return "Not enabled" if not defined $self->{export_path};
|
return "Not enabled" if not defined $self->{export_path};
|
||||||
|
|
||||||
|
my $quotegrabs = $self->{quotegrabs_db}->get_all_quotegrabs();
|
||||||
|
|
||||||
my $text;
|
my $text;
|
||||||
my $table_id = 1;
|
my $table_id = 1;
|
||||||
my $had_table = 0;
|
my $had_table = 0;
|
||||||
@ -124,7 +78,7 @@ sub export_quotegrabs() {
|
|||||||
my $i = 0;
|
my $i = 0;
|
||||||
|
|
||||||
my $last_channel = "";
|
my $last_channel = "";
|
||||||
foreach my $quotegrab (sort { $$a{channel} cmp $$b{channel} or $$a{nick} cmp $$b{nick} } @{ $self->{quotegrabs} }) {
|
foreach my $quotegrab (sort { $$a{channel} cmp $$b{channel} or $$a{nick} cmp $$b{nick} } @$quotegrabs) {
|
||||||
if(not $quotegrab->{channel} =~ /^$last_channel$/i) {
|
if(not $quotegrab->{channel} =~ /^$last_channel$/i) {
|
||||||
print FILE "<a href='#" . $quotegrab->{channel} . "'>" . encode_entities($quotegrab->{channel}) . "</a><br>\n";
|
print FILE "<a href='#" . $quotegrab->{channel} . "'>" . encode_entities($quotegrab->{channel}) . "</a><br>\n";
|
||||||
$last_channel = $quotegrab->{channel};
|
$last_channel = $quotegrab->{channel};
|
||||||
@ -132,7 +86,7 @@ sub export_quotegrabs() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$last_channel = "";
|
$last_channel = "";
|
||||||
foreach my $quotegrab (sort { $$a{channel} cmp $$b{channel} or lc $$a{nick} cmp lc $$b{nick} } @{ $self->{quotegrabs} }) {
|
foreach my $quotegrab (sort { $$a{channel} cmp $$b{channel} or lc $$a{nick} cmp lc $$b{nick} } @$quotegrabs) {
|
||||||
if(not $quotegrab->{channel} =~ /^$last_channel$/i) {
|
if(not $quotegrab->{channel} =~ /^$last_channel$/i) {
|
||||||
print FILE "</tbody>\n</table>\n" if $had_table;
|
print FILE "</tbody>\n</table>\n" if $had_table;
|
||||||
print FILE "<a name='" . $quotegrab->{channel} . "'></a>\n";
|
print FILE "<a name='" . $quotegrab->{channel} . "'></a>\n";
|
||||||
@ -211,7 +165,7 @@ sub grab_quotegrab {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(not defined $arguments or not length $arguments) {
|
if(not defined $arguments or not length $arguments) {
|
||||||
return "Usage: grab <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 grab the 3rd most recent message for nick, use `grab nick 3` or to grab a message containing 'pizza', use `grab 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: grab <nick> [history [channel]] [+ <nick> [history [channel]] ...] -- where [history] is an optional argument that is a regex (without whitespace) of the text within the message; e.g., to grab a message containing 'pizza', use `grab nick pizza`; you can chain grabs with + to grab multiple messages";
|
||||||
}
|
}
|
||||||
|
|
||||||
$arguments = lc $arguments;
|
$arguments = lc $arguments;
|
||||||
@ -323,56 +277,41 @@ sub grab_quotegrab {
|
|||||||
$quotegrab->{timestamp} = gettimeofday;
|
$quotegrab->{timestamp} = gettimeofday;
|
||||||
$quotegrab->{grabbed_by} = "$nick!$user\@$host";
|
$quotegrab->{grabbed_by} = "$nick!$user\@$host";
|
||||||
$quotegrab->{text} = $grab_text;
|
$quotegrab->{text} = $grab_text;
|
||||||
$quotegrab->{id} = $#{ $self->{quotegrabs} } + 2;
|
$quotegrab->{id} = undef;
|
||||||
|
|
||||||
push @{ $self->{quotegrabs} }, $quotegrab;
|
$quotegrab->{id} = $self->{quotegrabs_db}->add_quotegrab($quotegrab);
|
||||||
|
|
||||||
$self->save_quotegrabs();
|
if(not defined $quotegrab->{id}) {
|
||||||
|
return "Failed to grab quote.";
|
||||||
|
}
|
||||||
|
|
||||||
|
$self->export_quotegrabs();
|
||||||
|
|
||||||
my $text = $quotegrab->{text};
|
my $text = $quotegrab->{text};
|
||||||
($grab_nick) = split /\+/, $grab_nicks, 2;
|
($grab_nick) = split /\+/, $grab_nicks, 2;
|
||||||
|
|
||||||
if($text =~ s/^\/me\s+//) {
|
if($text =~ s/^\/me\s+//) {
|
||||||
return "Quote grabbed: " . ($#{ $self->{quotegrabs} } + 1) . ": * $grab_nick $text";
|
return "Quote grabbed: $quotegrab->{id}: * $grab_nick $text";
|
||||||
} else {
|
} else {
|
||||||
return "Quote grabbed: " . ($#{ $self->{quotegrabs} } + 1) . ": <$grab_nick> $text";
|
return "Quote grabbed: $quotegrab->{id}: <$grab_nick> $text";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub add_quotegrab {
|
|
||||||
my ($self, $nick, $channel, $timestamp, $grabbed_by, $text) = @_;
|
|
||||||
|
|
||||||
my $quotegrab = {};
|
|
||||||
$quotegrab->{nick} = $nick;
|
|
||||||
$quotegrab->{channel} = $channel;
|
|
||||||
$quotegrab->{timestamp} = $timestamp;
|
|
||||||
$quotegrab->{grabbed_by} = $grabbed_by;
|
|
||||||
$quotegrab->{text} = $text;
|
|
||||||
$quotegrab->{id} = $#{ $self->{quotegrabs} } + 2;
|
|
||||||
|
|
||||||
push @{ $self->{quotegrabs} }, $quotegrab;
|
|
||||||
}
|
|
||||||
|
|
||||||
sub delete_quotegrab {
|
sub delete_quotegrab {
|
||||||
my ($self, $from, $nick, $user, $host, $arguments) = @_;
|
my ($self, $from, $nick, $user, $host, $arguments) = @_;
|
||||||
|
|
||||||
if($arguments < 1 || $arguments > $#{ $self->{quotegrabs} } + 1) {
|
my $quotegrab = $self->{quotegrabs_db}->get_quotegrab($arguments);
|
||||||
return "/msg $nick Valid range for `getq` is 1 - " . ($#{ $self->{quotegrabs} } + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
my $quotegrab = $self->{quotegrabs}[$arguments - 1];
|
if(not defined $quotegrab) {
|
||||||
|
return "/msg $nick No quotegrab matching id $arguments found.";
|
||||||
|
}
|
||||||
|
|
||||||
if(not $self->{pbot}->admins->loggedin($from, "$nick!$user\@$host") and $quotegrab->{grabbed_by} ne "$nick!$user\@$host") {
|
if(not $self->{pbot}->admins->loggedin($from, "$nick!$user\@$host") and $quotegrab->{grabbed_by} ne "$nick!$user\@$host") {
|
||||||
return "You are not the grabber of this quote.";
|
return "You are not the grabber of this quote.";
|
||||||
}
|
}
|
||||||
|
|
||||||
splice @{ $self->{quotegrabs} }, $arguments - 1, 1;
|
$self->{quotegrabs_db}->delete_quotegrab($arguments);
|
||||||
|
$self->export_quotegrabs();
|
||||||
for(my $i = $arguments - 1; $i <= $#{ $self->{quotegrabs} }; $i++ ) {
|
|
||||||
$self->{quotegrabs}[$i]->{id}--;
|
|
||||||
}
|
|
||||||
|
|
||||||
$self->save_quotegrabs();
|
|
||||||
|
|
||||||
my $text = $quotegrab->{text};
|
my $text = $quotegrab->{text};
|
||||||
|
|
||||||
@ -388,11 +327,12 @@ sub delete_quotegrab {
|
|||||||
sub show_quotegrab {
|
sub show_quotegrab {
|
||||||
my ($self, $from, $nick, $user, $host, $arguments) = @_;
|
my ($self, $from, $nick, $user, $host, $arguments) = @_;
|
||||||
|
|
||||||
if($arguments < 1 || $arguments > $#{ $self->{quotegrabs} } + 1) {
|
my $quotegrab = $self->{quotegrabs_db}->get_quotegrab($arguments);
|
||||||
return "/msg $nick Valid range for !getq is 1 - " . ($#{ $self->{quotegrabs} } + 1);
|
|
||||||
|
if(not defined $quotegrab) {
|
||||||
|
return "/msg $nick No quotegrab matching id $arguments found.";
|
||||||
}
|
}
|
||||||
|
|
||||||
my $quotegrab = $self->{quotegrabs}[$arguments - 1];
|
|
||||||
my $timestamp = $quotegrab->{timestamp};
|
my $timestamp = $quotegrab->{timestamp};
|
||||||
my $ago = ago(gettimeofday - $timestamp);
|
my $ago = ago(gettimeofday - $timestamp);
|
||||||
my $text = $quotegrab->{text};
|
my $text = $quotegrab->{text};
|
||||||
@ -445,44 +385,32 @@ sub show_random_quotegrab {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$nick_search = '.*' if not defined $nick_search;
|
$channel_search = undef if defined $channel_search and $channel_search !~ /^#/;
|
||||||
$channel_search = '.*' if not defined $channel_search or $channel_search !~ /^#/;
|
|
||||||
$text_search = '.*' if not defined $text_search;
|
|
||||||
|
|
||||||
eval {
|
print "nick: [" . (defined $nick_search ? $nick_search : "undef") . "]\n";
|
||||||
for(my $i = 0; $i <= $#{ $self->{quotegrabs} }; $i++) {
|
print "channel: [" . (defined $channel_search ? $channel_search : "undef") . "]\n";
|
||||||
my $hash = $self->{quotegrabs}[$i];
|
print "text: [" . (defined $text_search ? $text_search : "undef") . "]\n";
|
||||||
if($hash->{channel} =~ /$channel_search/i && $hash->{nick} =~ /$nick_search/i && $hash->{text} =~ /$text_search/i) {
|
|
||||||
$hash->{id} = $i + 1;
|
|
||||||
push @quotes, $hash;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if($@) {
|
my $quotegrab = $self->{quotegrabs_db}->get_random_quotegrab($nick_search, $channel_search, $text_search);
|
||||||
$self->{pbot}->logger->log("Error in show_random_quotegrab parameters: $@\n");
|
|
||||||
return "/msg $nick Error in search parameters: $@"
|
|
||||||
}
|
|
||||||
|
|
||||||
if($#quotes < 0) {
|
if(not defined $quotegrab) {
|
||||||
my $result = "No quotes grabbed ";
|
my $result = "No quotes grabbed ";
|
||||||
|
|
||||||
if($nick_search ne '.*') {
|
if(defined $nick_search) {
|
||||||
$result .= "for nick $nick_search ";
|
$result .= "for nick $nick_search ";
|
||||||
}
|
}
|
||||||
|
|
||||||
if($channel_search ne '.*') {
|
if(defined $channel_search) {
|
||||||
$result .= "in channel $channel_search ";
|
$result .= "in channel $channel_search ";
|
||||||
}
|
}
|
||||||
|
|
||||||
if($text_search ne '.*') {
|
if(defined $text_search) {
|
||||||
$result .= "matching text '$text_search' ";
|
$result .= "matching text '$text_search' ";
|
||||||
}
|
}
|
||||||
|
|
||||||
return $result . "yet ($usage).";;
|
return $result . "yet ($usage).";;
|
||||||
}
|
}
|
||||||
|
|
||||||
my $quotegrab = $quotes[int rand($#quotes + 1)];
|
|
||||||
my $text = $quotegrab->{text};
|
my $text = $quotegrab->{text};
|
||||||
my ($first_nick) = split /\+/, $quotegrab->{nick}, 2;
|
my ($first_nick) = split /\+/, $quotegrab->{nick}, 2;
|
||||||
|
|
||||||
|
173
PBot/Quotegrabs_Hashtable.pm
Normal file
173
PBot/Quotegrabs_Hashtable.pm
Normal file
@ -0,0 +1,173 @@
|
|||||||
|
# File: Quotegrabs_Hashtable.pm
|
||||||
|
# Author: pragma_
|
||||||
|
#
|
||||||
|
# Purpose: Hashtable backend for storing and retreiving quotegrabs
|
||||||
|
|
||||||
|
package PBot::Quotegrabs_Hashtable;
|
||||||
|
|
||||||
|
use warnings;
|
||||||
|
use strict;
|
||||||
|
|
||||||
|
use vars qw($VERSION);
|
||||||
|
$VERSION = $PBot::PBot::VERSION;
|
||||||
|
|
||||||
|
use HTML::Entities;
|
||||||
|
use Time::Duration;
|
||||||
|
use Time::HiRes qw(gettimeofday);
|
||||||
|
use Getopt::Long qw(GetOptionsFromString);
|
||||||
|
|
||||||
|
use POSIX qw(strftime);
|
||||||
|
|
||||||
|
sub new {
|
||||||
|
if(ref($_[1]) eq 'HASH') {
|
||||||
|
Carp::croak("Options to " . __FILE__ . " 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 " . __FILE__);
|
||||||
|
$self->{filename} = delete $conf{filename};
|
||||||
|
$self->{quotegrabs} = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
sub begin {
|
||||||
|
my $self = shift;
|
||||||
|
$self->load_quotegrabs;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub end {
|
||||||
|
}
|
||||||
|
|
||||||
|
sub load_quotegrabs {
|
||||||
|
my $self = shift;
|
||||||
|
my $filename;
|
||||||
|
|
||||||
|
if(@_) { $filename = shift; } else { $filename = $self->{filename}; }
|
||||||
|
return if not defined $filename;
|
||||||
|
|
||||||
|
$self->{pbot}->logger->log("Loading quotegrabs from $filename ...\n");
|
||||||
|
|
||||||
|
open(FILE, "< $filename") or die "Couldn't open $filename: $!\n";
|
||||||
|
my @contents = <FILE>;
|
||||||
|
close(FILE);
|
||||||
|
|
||||||
|
my $i = 0;
|
||||||
|
foreach my $line (@contents) {
|
||||||
|
chomp $line;
|
||||||
|
$i++;
|
||||||
|
my ($nick, $channel, $timestamp, $grabbed_by, $text) = split(/\s+/, $line, 5);
|
||||||
|
if(not defined $nick || not defined $channel || not defined $timestamp
|
||||||
|
|| not defined $grabbed_by || not defined $text) {
|
||||||
|
die "Syntax error around line $i of $filename\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
my $quotegrab = {};
|
||||||
|
$quotegrab->{nick} = $nick;
|
||||||
|
$quotegrab->{channel} = $channel;
|
||||||
|
$quotegrab->{timestamp} = $timestamp;
|
||||||
|
$quotegrab->{grabbed_by} = $grabbed_by;
|
||||||
|
$quotegrab->{text} = $text;
|
||||||
|
$quotegrab->{id} = $i + 1;
|
||||||
|
push @{ $self->{quotegrabs} }, $quotegrab;
|
||||||
|
}
|
||||||
|
$self->{pbot}->logger->log(" $i quotegrabs loaded.\n");
|
||||||
|
$self->{pbot}->logger->log("Done.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
sub save_quotegrabs {
|
||||||
|
my $self = shift;
|
||||||
|
my $filename;
|
||||||
|
|
||||||
|
if(@_) { $filename = shift; } else { $filename = $self->{filename}; }
|
||||||
|
return if not defined $filename;
|
||||||
|
|
||||||
|
open(FILE, "> $filename") or die "Couldn't open $filename: $!\n";
|
||||||
|
|
||||||
|
for(my $i = 0; $i <= $#{ $self->{quotegrabs} }; $i++) {
|
||||||
|
my $quotegrab = $self->{quotegrabs}[$i];
|
||||||
|
next if $quotegrab->{timestamp} == 0;
|
||||||
|
print FILE "$quotegrab->{nick} $quotegrab->{channel} $quotegrab->{timestamp} $quotegrab->{grabbed_by} $quotegrab->{text}\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
close(FILE);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub add_quotegrab {
|
||||||
|
my ($self, $quotegrab) = @_;
|
||||||
|
|
||||||
|
push @{ $self->{quotegrabs} }, $quotegrab;
|
||||||
|
$self->save_quotegrabs();
|
||||||
|
return $#{ $self->{quotegrabs} } + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub delete_quotegrab {
|
||||||
|
my ($self, $id) = @_;
|
||||||
|
|
||||||
|
if($id < 1 || $id > $#{ $self->{quotegrabs} } + 1) {
|
||||||
|
return undef;
|
||||||
|
}
|
||||||
|
|
||||||
|
splice @{ $self->{quotegrabs} }, $id - 1, 1;
|
||||||
|
|
||||||
|
for(my $i = $id - 1; $i <= $#{ $self->{quotegrabs} }; $i++ ) {
|
||||||
|
$self->{quotegrabs}[$i]->{id}--;
|
||||||
|
}
|
||||||
|
|
||||||
|
$self->save_quotegrabs();
|
||||||
|
}
|
||||||
|
|
||||||
|
sub get_quotegrab {
|
||||||
|
my ($self, $id) = @_;
|
||||||
|
|
||||||
|
if($id < 1 || $id > $#{ $self->{quotegrabs} } + 1) {
|
||||||
|
return undef;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $self->{quotegrabs}[$id - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
sub get_random_quotegrab {
|
||||||
|
my ($self, $nick, $channel, $text) = @_;
|
||||||
|
|
||||||
|
$nick = '.*' if not defined $nick;
|
||||||
|
$channel = '.*' if not defined $channel;
|
||||||
|
$text = '.*' if not defined $text;
|
||||||
|
|
||||||
|
my @quotes;
|
||||||
|
|
||||||
|
eval {
|
||||||
|
for(my $i = 0; $i <= $#{ $self->{quotegrabs} }; $i++) {
|
||||||
|
my $hash = $self->{quotegrabs}[$i];
|
||||||
|
if($hash->{channel} =~ /$channel/i && $hash->{nick} =~ /$nick/i && $hash->{text} =~ /$text/i) {
|
||||||
|
$hash->{id} = $i + 1;
|
||||||
|
push @quotes, $hash;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if($@) {
|
||||||
|
$self->{pbot}->logger->log("Error in show_random_quotegrab parameters: $@\n");
|
||||||
|
return undef;
|
||||||
|
}
|
||||||
|
|
||||||
|
if($#quotes < 0) {
|
||||||
|
return undef;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $quotes[int rand($#quotes + 1)];
|
||||||
|
}
|
||||||
|
|
||||||
|
sub get_all_quotegrabs {
|
||||||
|
my $self = shift;
|
||||||
|
return $self->{quotegrabs};
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
172
PBot/Quotegrabs_SQLite.pm
Normal file
172
PBot/Quotegrabs_SQLite.pm
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
# File: Quotegrabs_SQLite.pm
|
||||||
|
# Author: pragma_
|
||||||
|
#
|
||||||
|
# Purpose: SQLite back-end for storing and retreiving quotegrabs
|
||||||
|
|
||||||
|
package PBot::Quotegrabs_SQLite;
|
||||||
|
|
||||||
|
use warnings;
|
||||||
|
use strict;
|
||||||
|
|
||||||
|
use vars qw($VERSION);
|
||||||
|
$VERSION = $PBot::PBot::VERSION;
|
||||||
|
|
||||||
|
use DBI;
|
||||||
|
use Carp qw(shortmess);
|
||||||
|
|
||||||
|
sub new {
|
||||||
|
if(ref($_[1]) eq 'HASH') {
|
||||||
|
Carp::croak("Options to " . __FILE__ . " 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 " . __FILE__);
|
||||||
|
$self->{filename} = delete $conf{filename};
|
||||||
|
}
|
||||||
|
|
||||||
|
sub begin {
|
||||||
|
my $self = shift;
|
||||||
|
|
||||||
|
$self->{pbot}->logger->log("Opening quotegrabs SQLite database: $self->{filename}\n");
|
||||||
|
|
||||||
|
$self->{dbh} = DBI->connect("dbi:SQLite:dbname=$self->{filename}", "", "", { RaiseError => 1, PrintError => 0 }) or die $DBI::errstr;
|
||||||
|
|
||||||
|
eval {
|
||||||
|
$self->{dbh}->do(<< 'SQL');
|
||||||
|
CREATE TABLE IF NOT EXISTS Quotegrabs (
|
||||||
|
id INTEGER PRIMARY KEY,
|
||||||
|
nick TEXT,
|
||||||
|
channel TEXT,
|
||||||
|
grabbed_by TEXT,
|
||||||
|
text TEXT,
|
||||||
|
timestamp NUMERIC
|
||||||
|
)
|
||||||
|
SQL
|
||||||
|
};
|
||||||
|
|
||||||
|
$self->{pbot}->logger->log($@) if $@;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub end {
|
||||||
|
my $self = shift;
|
||||||
|
|
||||||
|
$self->{pbot}->logger->log("Closing quotegrabs SQLite database\n");
|
||||||
|
|
||||||
|
if(exists $self->{dbh} and defined $self->{dbh}) {
|
||||||
|
$self->{dbh}->disconnect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub add_quotegrab {
|
||||||
|
my ($self, $quotegrab) = @_;
|
||||||
|
|
||||||
|
my $id = eval {
|
||||||
|
my $sth = $self->{dbh}->prepare('INSERT INTO Quotegrabs VALUES (?, ?, ?, ?, ?, ?)');
|
||||||
|
$sth->bind_param(1, undef);
|
||||||
|
$sth->bind_param(2, $quotegrab->{nick});
|
||||||
|
$sth->bind_param(3, $quotegrab->{channel});
|
||||||
|
$sth->bind_param(4, $quotegrab->{grabbed_by});
|
||||||
|
$sth->bind_param(5, $quotegrab->{text});
|
||||||
|
$sth->bind_param(6, $quotegrab->{timestamp});
|
||||||
|
$sth->execute();
|
||||||
|
|
||||||
|
return $self->{dbh}->sqlite_last_insert_rowid();
|
||||||
|
};
|
||||||
|
|
||||||
|
$self->{pbot}->logger->log($@) if $@;
|
||||||
|
return $id;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub get_quotegrab {
|
||||||
|
my ($self, $id) = @_;
|
||||||
|
|
||||||
|
my $quotegrab = eval {
|
||||||
|
my $sth = $self->{dbh}->prepare('SELECT * FROM Quotegrabs WHERE id == ?');
|
||||||
|
$sth->bind_param(1, $id);
|
||||||
|
$sth->execute();
|
||||||
|
return $sth->fetchrow_hashref();
|
||||||
|
};
|
||||||
|
|
||||||
|
$self->{pbot}->logger->log($@) if $@;
|
||||||
|
return $quotegrab;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub get_random_quotegrab {
|
||||||
|
my ($self, $nick, $channel, $text) = @_;
|
||||||
|
|
||||||
|
$nick =~ s/\.?\*/%/g if defined $nick;
|
||||||
|
$channel =~ s/\.?\*/%/g if defined $channel;
|
||||||
|
$text =~ s/\.?\*/%/g if defined $text;
|
||||||
|
|
||||||
|
my $quotegrab = eval {
|
||||||
|
my $sql = 'SELECT * FROM Quotegrabs ';
|
||||||
|
my @params;
|
||||||
|
my $where = 'WHERE ';
|
||||||
|
my $and = '';
|
||||||
|
|
||||||
|
if(defined $nick) {
|
||||||
|
$sql .= $where . 'nick LIKE ? ';
|
||||||
|
push @params, "%$nick%";
|
||||||
|
$where = '';
|
||||||
|
$and = 'AND ';
|
||||||
|
}
|
||||||
|
|
||||||
|
if(defined $channel) {
|
||||||
|
$sql .= $where . $and . 'channel LIKE ? ';
|
||||||
|
push @params, $channel;
|
||||||
|
$where = '';
|
||||||
|
$and = 'AND ';
|
||||||
|
}
|
||||||
|
|
||||||
|
if(defined $text) {
|
||||||
|
$sql .= $where . $and . 'text LIKE ? ';
|
||||||
|
push @params, "%$text%";
|
||||||
|
}
|
||||||
|
|
||||||
|
$sql .= 'ORDER BY RANDOM() LIMIT 1';
|
||||||
|
|
||||||
|
print "sql: [$sql]\n";
|
||||||
|
my $sth = $self->{dbh}->prepare($sql);
|
||||||
|
$sth->execute(@params);
|
||||||
|
return $sth->fetchrow_hashref();
|
||||||
|
};
|
||||||
|
|
||||||
|
$self->{pbot}->logger->log($@) if $@;
|
||||||
|
return $quotegrab;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub get_all_quotegrabs {
|
||||||
|
my $self = shift;
|
||||||
|
|
||||||
|
my $quotegrabs = eval {
|
||||||
|
my $sth = $self->{dbh}->prepare('SELECT * from Quotegrabs');
|
||||||
|
$sth->execute();
|
||||||
|
return $sth->fetchall_arrayref({});
|
||||||
|
};
|
||||||
|
|
||||||
|
$self->{pbot}->logger->log($@) if $@;
|
||||||
|
return $quotegrabs;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub delete_quotegrab {
|
||||||
|
my ($self, $id) = @_;
|
||||||
|
|
||||||
|
eval {
|
||||||
|
my $sth = $self->{dbh}->prepare('DELETE FROM Quotegrabs WHERE id == ?');
|
||||||
|
$sth->bind_param(1, $id);
|
||||||
|
$sth->execute();
|
||||||
|
};
|
||||||
|
|
||||||
|
$self->{pbot}->logger->log($@) if $@;
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
@ -13,8 +13,8 @@ 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 => 565,
|
BUILD_REVISION => 566,
|
||||||
BUILD_DATE => "2014-05-04",
|
BUILD_DATE => "2014-05-05",
|
||||||
};
|
};
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
@ -336,7 +336,6 @@ twkm ##c 1393837048.42629 dozn!~dozn@24-207-52-240.eastlink.ca you have limited
|
|||||||
edk ##c 1393889567.48333 pragma-!~chaos@unaffiliated/pragmatic-chaos sometimes this channel makes me want to mash my brains into a cheese grater
|
edk ##c 1393889567.48333 pragma-!~chaos@unaffiliated/pragmatic-chaos sometimes this channel makes me want to mash my brains into a cheese grater
|
||||||
Duzz+Chris ##c 1393933389.37563 dozn!~dozn@24-207-52-240.eastlink.ca What is the term for determining instruction rates from benchmark programs? <Chris> divining
|
Duzz+Chris ##c 1393933389.37563 dozn!~dozn@24-207-52-240.eastlink.ca What is the term for determining instruction rates from benchmark programs? <Chris> divining
|
||||||
Teckla ##c 1393949900.2454 aemquo!~UN@unaffiliated/aemquo And the LORD said, "Four spaces shall it be; neither more, nor less. Thine indentation shall not be tabs, as they are an abomination."
|
Teckla ##c 1393949900.2454 aemquo!~UN@unaffiliated/aemquo And the LORD said, "Four spaces shall it be; neither more, nor less. Thine indentation shall not be tabs, as they are an abomination."
|
||||||
Zhivago ##c 1393985619.14992 CaZe!~caze@unaffiliated/caze That's what she said.
|
|
||||||
edk+zid`+zid` ##c 1394473406.13345 rob``!~rob@gtng-4db0408b.pool.mediaWays.net you could always read the fucking man page <zid`> don't google for man abs btw <zid`> you get a lot of half naked men
|
edk+zid`+zid` ##c 1394473406.13345 rob``!~rob@gtng-4db0408b.pool.mediaWays.net you could always read the fucking man page <zid`> don't google for man abs btw <zid`> you get a lot of half naked men
|
||||||
dozn+someHuman+rob`` ##c 1394520942.81382 dozn!~dozn@24-207-52-240.eastlink.ca someHuman, then learn C# <someHuman> What's the difference? <rob``> one semitone
|
dozn+someHuman+rob`` ##c 1394520942.81382 dozn!~dozn@24-207-52-240.eastlink.ca someHuman, then learn C# <someHuman> What's the difference? <rob``> one semitone
|
||||||
CaZe ##c 1394525928.2901 rob``!~rob@gtng-4db0491e.pool.mediaWays.net Sorry I was watching electric eel videos.
|
CaZe ##c 1394525928.2901 rob``!~rob@gtng-4db0491e.pool.mediaWays.net Sorry I was watching electric eel videos.
|
||||||
@ -366,3 +365,11 @@ pragma-+jack_rabbit+pragma- ##c 1397262758.23935 jack_rabbit!~jack_rabb@c-98-253
|
|||||||
Zhivago ##c 1397702764.01239 nitrix!~nitrix@unaffiliated/nitrix It's like training a dog, only less adorable.
|
Zhivago ##c 1397702764.01239 nitrix!~nitrix@unaffiliated/nitrix It's like training a dog, only less adorable.
|
||||||
pragma-+CaZe+pragma- ##c 1398135398.42557 pragma-!~chaos@unaffiliated/pragmatic-chaos some say that the white light you see when you die is actually the birth canal opening as you're born again <CaZe> goatse <pragma-> being born out of an anus would make for a pretty crappy life
|
pragma-+CaZe+pragma- ##c 1398135398.42557 pragma-!~chaos@unaffiliated/pragmatic-chaos some say that the white light you see when you die is actually the birth canal opening as you're born again <CaZe> goatse <pragma-> being born out of an anus would make for a pretty crappy life
|
||||||
nitrix+Chris ##c 1398481252.71708 fisted!~fisted@unaffiliated/fisted Thankfully, I'm more responsible than I'm retarded. <Chris> that's certainly a great deal of responsibility
|
nitrix+Chris ##c 1398481252.71708 fisted!~fisted@unaffiliated/fisted Thankfully, I'm more responsible than I'm retarded. <Chris> that's certainly a great deal of responsibility
|
||||||
|
fisted ##c-unregistered 1398813908.81641 pragma-!~chaos@unaffiliated/pragmatic-chaos can someone explain to me how the sizeof() function works?
|
||||||
|
pragma- ##c-unregistered 1398814181.04319 fisted!~fisted@unaffiliated/fisted I sux.
|
||||||
|
Seabasschan ##c-unregistered 1398815030.73377 pragma-!~chaos@unaffiliated/pragmatic-chaos The temptation to grab myself is becoming quite intense.
|
||||||
|
Chris+Chris ##c 1398905572.56347 pragma-!~chaos@unaffiliated/pragmatic-chaos just write some AI in candide to detect retards <Chris> you'll have to whitelist ops like nitrix
|
||||||
|
pragma- ##c 1399112839.26945 jack_rabbit!~jack_rabb@c-98-253-57-51.hsd1.il.comcast.net I think your view of humanity is weak and pathetic. You should probably be shot to rid your inferior ineffectual notions from the gene pool so that humanity can become stronger.
|
||||||
|
Snowleaksange ##c 1399234646.44097 kate`!~kate@unaffiliated/kate/x-0000001 complying with standard way more trouble than worth
|
||||||
|
BadCodSmell ##c 1399235309.39431 nitrix!~nib@unaffiliated/nitrix Portability is not built into C, that's why your standard exists.
|
||||||
|
Snowleaksange ##c 1399235839.80165 kate`!~kate@unaffiliated/kate/x-0000001 my advice is to ignore kate
|
||||||
|
BIN
data/quotegrabs.sqlite3
Normal file
BIN
data/quotegrabs.sqlite3
Normal file
Binary file not shown.
2
pbot.pl
2
pbot.pl
@ -107,7 +107,7 @@ $config{ignorelist_file} = "$config{config_dir}/ignorelist";
|
|||||||
$config{factoids_file} = "$config{data_dir}/factoids";
|
$config{factoids_file} = "$config{data_dir}/factoids";
|
||||||
|
|
||||||
# Location of file containing channel user quotes
|
# Location of file containing channel user quotes
|
||||||
$config{quotegrabs_file} = "$config{data_dir}/quotegrabs";
|
$config{quotegrabs_file} = "$config{data_dir}/quotegrabs.sqlite3";
|
||||||
|
|
||||||
# Location of file containing message history
|
# Location of file containing message history
|
||||||
$config{message_history_file} = "$config{data_dir}/message_history";
|
$config{message_history_file} = "$config{data_dir}/message_history";
|
||||||
|
Loading…
Reference in New Issue
Block a user