quotebot/lib/DB.pm

292 lines
7.1 KiB
Perl

package DB;
use Moose;
use DB::Schema;
use BotConfig;
use Carp qw/confess cluck/;
my $dbconf = BotConfig->instance->db;
my $schema = DB::Schema->connect("dbi:Pg:dbname=" . $dbconf->database . ";host=" . $dbconf->host,
$dbconf->username, $dbconf->password, { RaiseError => 1 });
$schema->storage->sql_maker->quote_char('"');
has schema => (
is => 'ro',
default => sub {
return $schema;
},
isa => 'DB::Schema',
);
sub _quote_to_ret {
my $row = shift;
return map { $row->$_ } qw/quote who qid desc sid/;
}
sub source {
return $_[0]->schema->resultset('Source');
}
sub quote {
return $_[0]->schema->resultset('Quote');
}
sub trigger {
return $_[0]->schema->resultset('Trigger');
}
sub channelsetup {
return $_[0]->schema->resultset('Channelsetup');
}
sub bansource {
return $_[0]->schema->resultset('Bansource');
}
sub quotelist {
return $_[0]->schema->resultset('List');
}
sub ignore {
return $_[0]->schema->resultset('Ignore');
}
sub episodeinfo {
return $_[0]->schema->resultset('Episodeinfo');
}
sub tidsource {
return $_[0]->schema->resultset('Tidsource');
}
sub addquote {
my ($self, $where, $who, $source, $quote) = @_;
my $source_row = $self->source->search({ name => uc $source })->first;
if ($source_row) {
my $counter_row = $self->quote->search({ sid => $source_row->sid },
{ 'select' => [ { 'AVG' => 'counter' } ], 'as' => ['newcount'], 'group_by' => ['me.sid'] })->first;
my $counter = $counter_row ? int($counter_row->get_column('newcount')) || 0 : 0;
my $quote_row = $self->quote->find_or_create({ quote => $quote, sid => $source_row->sid, counter => $counter, who => $who });
}
else {
return "No such source: $source";
}
}
sub getstrip {
my ($self, $channel) = @_;
my $row = $self->channelsetup->search({ channel => lc $channel })->first;
return !$row
? 0
: $row->stripcolors();
}
sub getbyqid {
my ($self, $where, $who, $qid) = @_;
my $row = $self->quotelist->search({ qid => $qid })->first;
if (!$row) {
return "Unable to find quote with $qid, are you sure it exists?";
}
else {
# TODO swap this to local call, rather than through POE
my $banned = $self->isbannedsource($where->[0], $row->sid);
if ($banned) {
return "Unable to find quote with $qid, are you sure it exists?";
}
else {
# TODO this should be a nicer return value
return _quote_to_ret($row);
}
}
}
sub getcid {
my ($self, $where) = @_;
my $row = $self->channelsetup->search({ channel => lc $where })->first;
return $row ? $row->cid : undef;
}
sub isbannedsource {
my ($self, $where, $sid) = @_;
my $row = $self->bansource->search({ 'me.sid' => $sid, 'channelsetup.channel' => lc $where }, { join => 'channelsetup' })->first;
return $row ? 1 : 0;
}
sub deletequote {
my ($self, $where, $who, $qid) = @_;
$self->quote->find({ qid => $qid })->update({ deleted => 1 });
}
sub addsource {
my ($self, $where, $who, $source, $desc) = @_;
my $row = $self->source->find_or_create({ name => uc $source, desc => $desc });
}
sub addtrigger {
my ($self, $where, $who, $trig) = @_;
my $row = $self->trigger->find_or_create({ trigger => uc $trig });
}
sub getquote {
my ($self, $what, $where) = @_;
$self->trigger->search({ trigger => uc $what })->update({ counter => \'counter + 1' });
# grab the bottom 15 rows by counter+random(), do the final selection in perl
my @rows =
$self->quotelist->search({ trigger => uc $what }, { order_by => { '-asc' => [ 'me.counter', \'RANDOM()' ] }, rows => 15 })->all;
my $final_row = $rows[ rand @rows ];
return "" unless $final_row;
my $qid = $final_row->qid;
my $quote_row = $self->quote->find({ qid => $qid });
$quote_row->update({ counter => \'counter + 1' });
my $banned = $self->isbannedsource($where->[0], $final_row->sid);
if ($banned) {
print "GETQUOTE: failed check\n";
return ("", "", 0, "");
}
else {
return _quote_to_ret($final_row);
}
}
sub getlastquote {
my ($self) = @_;
my $row = $self->quotelist->search({}, { order_by => { '-desc' => 'me.qid' } })->first;
return _quote_to_ret($row) if $row;
return ("", "", 0, "");
}
sub listtriggers {
my ($self, $what) = @_;
my @triggers = map { uc $_->trigger } $self->trigger->search({ tid => { '>' => 0 } })->all;
my $string = join ', ', @triggers;
return $string;
}
sub listsources {
my ($self, $what) = @_;
my @sources = map { uc $_->name } $self->source->search({ sid => { '>' => 0 } })->all;
my $string = join ', ', @sources;
return $string;
}
sub whatistrigger {
my ($self, $where, $who, $what) = @_;
my $trig = $self->trigger->search({ trigger => uc $what })->first;
unless ($trig) { #no rows found
return "Unable to find trigger, $what";
}
my @sources = map { $_->source } $trig->tidsources->all;
my $string = join ', ', map { $_->name } @sources;
return $string;
}
sub appendtotrigger {
my ($self, $where, $who, $source, $trigger) = @_;
my $source_row = $self->source->find({ name => uc $source });
my $trigger_row = $self->trigger->find({ trigger => uc $trigger });
unless ($source_row && $source_row->sid > 0) {
return "Unable to find source, $source";
}
unless ($trigger_row && $trigger_row->tid > 0) {
return "Unable to find trigger, $trigger";
}
# add the source to the trigger
$trigger_row->tidsources->find_or_create({ sid => $source_row->sid });
}
sub removefromtrigger {
my ($self, $where, $who, $source, $trigger) = @_;
my $source_row = $self->source->find({ name => uc $source });
my $trigger_row = $self->trigger->find({ trigger => uc $trigger });
unless ($source_row && $source_row->sid > 0) {
return "Unable to find source, $source";
}
unless ($trigger_row && $trigger_row->tid > 0) {
return "Unable to find trigger, $trigger";
}
$trigger_row->tidsources->search({ sid => $source_row->sid })->delete();
}
sub updatebotlist {
my ($self, $eid, $botlist) = @_;
$self->episodeinfo->search({ eid => $eid })->update({ botlisting => $botlist });
}
sub updatecrc {
my ($self, $eid, $crc) = @_;
$self->episodeinfo->search({ eid => $eid })->update({ fcrc => $crc });
}
sub updategroup {
my ($self, $eid, $group) = @_;
$self->episodeinfo->search({ eid => $eid })->update({ group => $group });
}
sub updatesize {
my ($self, $eid, $size) = @_;
$self->episodeinfo->search({ eid => $eid })->update({ fsize => $size });
}
sub updatemu {
my ($self, $eid, $mu) = @_;
$self->episodeinfo->search({ eid => $eid })->update({ filelink => $mu });
}
sub getignoredmsg {
my ($self, $nick) = @_;
my $row = $self->ignore->search({ nick => lc $nick })->first;
return $row ? $row->message : undef;
}
sub isignored {
my ($self, $nick) = @_;
my $row = $self->ignore->search({ nick => lc $nick })->first;
return !!$row;
}
1;