mirror of
https://github.com/perlbot/perlbuut
synced 2025-06-07 16:55:42 -04:00
Now has full FTS search
This commit is contained in:
parent
9393348dae
commit
7ff04815ee
6 changed files with 145 additions and 34 deletions
|
@ -51,6 +51,19 @@ server "*" {
|
|||
plugin "deparse" {addressed: false; }
|
||||
}
|
||||
}
|
||||
server "discord.gg" {
|
||||
channel "*" {
|
||||
plugin "eval" {addressed: false; }
|
||||
}
|
||||
}
|
||||
server "matrix.org" {
|
||||
channel "#DYJOMClZbVOMHnzPQt:matrix.org" {
|
||||
plugin "eval" {addressed: false}
|
||||
}
|
||||
channel "#rAnyijhRxzFRfdjSHl:matrix.org" {
|
||||
plugin "eval" {addressed: false}
|
||||
}
|
||||
}
|
||||
server "*.freenode.net" {
|
||||
channel "#perlbot" {
|
||||
plugin "factoids" {
|
||||
|
|
|
@ -81,18 +81,21 @@ sub get_plugin {
|
|||
$filtered = $self->_filter_plugin_list($said, $filtered) if ($said);
|
||||
|
||||
for my $plugin ( @{$filtered} ) {
|
||||
warn "Checking plugin: $plugin->{name}\n";
|
||||
if( $name eq $plugin->{name} ) {
|
||||
return $plugin;
|
||||
}
|
||||
|
||||
if ( $plugin->{alias_re} ) {
|
||||
return $plugin if $name =~ $plugin->{alias_re};
|
||||
} elsif( $plugin->{aliases} ) {
|
||||
if( $plugin->{aliases} ) {
|
||||
for my $alias ( @{ $plugin->{aliases} } ) {
|
||||
return $plugin if $name eq $alias;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( $plugin->{alias_re} ) {
|
||||
warn "re: $plugin->{alias_re}\n";
|
||||
return $plugin if $name =~ /^\s*$plugin->{alias_re}/;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -383,7 +386,8 @@ sub _parse_for_commands {
|
|||
|
||||
my $found_command = $+{command};
|
||||
my $args = $+{args};
|
||||
my $command = $self->get_plugin($found_command, $said); #$commands->{ $found_command };
|
||||
my $command = #$self->get_plugin($found_command, $said);
|
||||
$commands->{ $found_command } // $self->get_plugin($found_command, $said);
|
||||
|
||||
warn "found $found_command - $args\n";
|
||||
|
||||
|
|
|
@ -56,9 +56,9 @@ sub display_page {
|
|||
|
||||
warn "Display Page Activating: $req - $resp - $output\n";
|
||||
|
||||
if ($said->{addressed} || $output !~ /^\s*$/) {
|
||||
$output = sprintf '@%s %s', $said->{name}, $output;
|
||||
}
|
||||
# if ($said->{addressed} || $output !~ /^\s*$/) {
|
||||
# $output = sprintf '@%s %s', $said->{name}, $output;
|
||||
# }
|
||||
|
||||
$resp->code(RC_OK);
|
||||
$resp->content_type("application/json");
|
||||
|
@ -87,7 +87,11 @@ sub handle_request {
|
|||
|
||||
if ($input =~ /^\@?perlbot/i) {
|
||||
$addressed = 1;
|
||||
$input =~ s/^\@?perlbot\b//i;
|
||||
$input =~ s/^\@?perlbot\b[:,;]?\s*//i;
|
||||
}
|
||||
|
||||
if ($data->{addressed}) {
|
||||
$addressed = 1;
|
||||
}
|
||||
|
||||
# This is obviously silly but I'm unable to figure out
|
||||
|
@ -103,7 +107,7 @@ sub handle_request {
|
|||
ircname => $name // "ERROR",
|
||||
host => '*special', #TODO fix this to be an actual hostname!
|
||||
# Make sure it isn't messed up by the alias feature..
|
||||
server => '*special',
|
||||
server => $data->{server} // '*special',
|
||||
nolearn => 1,
|
||||
};
|
||||
|
||||
|
@ -119,7 +123,8 @@ sub plugin_output {
|
|||
|
||||
my $name = $said->{name};
|
||||
|
||||
$output =~ s/^\s*$name:/\@$name/; # Clear the response name
|
||||
$said->{should_mention} = $output =~ s/^\s*$name://; # Clear the response name
|
||||
$said->{should_mention} += 0+$said->{addressed};
|
||||
|
||||
my $resp = delete $RESP_MAP{ $said->{pci_id} };
|
||||
|
||||
|
|
|
@ -13,14 +13,26 @@ sub {
|
|||
$wordnr = $1;
|
||||
|
||||
my %auxfield_abbrev = (qw"
|
||||
macro_arg macro_arg arg macro_arg a macro_arg
|
||||
name name nick name n name
|
||||
ircname ircname username ircname r ircname
|
||||
host host h host
|
||||
sender_raw sender_raw u sender_raw
|
||||
channel channel c channel
|
||||
by_chan_op by_chan_op o by_chan_op
|
||||
server server s server network server
|
||||
macro_arg macro_arg
|
||||
arg macro_arg
|
||||
a macro_arg
|
||||
name name
|
||||
nick name
|
||||
n name
|
||||
ircname ircname
|
||||
username ircname
|
||||
r ircname
|
||||
host host
|
||||
h host
|
||||
sender_raw sender_raw
|
||||
u sender_raw
|
||||
channel channel
|
||||
c channel
|
||||
by_chan_op by_chan_op
|
||||
o by_chan_op
|
||||
server server
|
||||
s server
|
||||
network server
|
||||
captured captured
|
||||
");
|
||||
my $f = $auxfield_abbrev{$auxfield};
|
||||
|
@ -33,6 +45,7 @@ sub {
|
|||
}
|
||||
|
||||
print Bot::BB3::MacroQuote::quote($quotemode, $str);
|
||||
return "FOO";
|
||||
};
|
||||
|
||||
__DATA__
|
||||
|
|
|
@ -48,6 +48,7 @@ my %commandhash = (
|
|||
"revert" => \&get_fact_revert,
|
||||
"revisions" => \&get_fact_revisions,
|
||||
"search" => \&get_fact_search,
|
||||
"oldsearch" => \&get_fact_oldsearch,
|
||||
"protect" => \&get_fact_protect,
|
||||
"unprotect" => \&get_fact_unprotect,
|
||||
"substitute" => \&get_fact_substitute,
|
||||
|
@ -225,6 +226,8 @@ sub handle ($self, $said, $pm) {
|
|||
my $prefix = $conf->{command_prefix};
|
||||
return unless $prefix;
|
||||
|
||||
$said->{nosuggest} = 1;
|
||||
|
||||
# TODO make this channel configurable and make it work properly to learn shit with colors later.
|
||||
$said->{body} = strip_formatting strip_color $said->{body};
|
||||
|
||||
|
@ -336,8 +339,8 @@ sub _insert_factoid ($self, $author, $subject, $copula, $predicate, $compose_mac
|
|||
|
||||
$dbh->do(
|
||||
"INSERT INTO factoid
|
||||
(original_subject,subject,copula,predicate,author,modified_time,metaphone,compose_macro,protected, namespace, server, deleted)
|
||||
VALUES (?,?,?,?,?,?,?,?,?,?,?,?)",
|
||||
(original_subject,subject,copula,predicate,author,modified_time,metaphone,compose_macro,protected, namespace, server, deleted,last_rendered)
|
||||
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)",
|
||||
undef,
|
||||
$key,
|
||||
$subject,
|
||||
|
@ -350,9 +353,12 @@ sub _insert_factoid ($self, $author, $subject, $copula, $predicate, $compose_mac
|
|||
$protected || 0,
|
||||
$namespace,
|
||||
$server,
|
||||
$deleted
|
||||
$deleted,
|
||||
$predicate
|
||||
);
|
||||
|
||||
# TODO trigger FTS update?
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -435,7 +441,7 @@ sub _fact_literal_format($r, $aliasserver, $aliasnamespace) {
|
|||
# <server:namespace>
|
||||
#
|
||||
|
||||
(($aliasserver eq $r->{server} && $aliasnamespace eq $r->{namespace}) ? "" : sprintf("<%s:%s> ", $r->{generated_server}||"*", $r->{generated_namespace}||"##NULL"))
|
||||
(($aliasserver eq ($r->{generated_server}||"*") && $aliasnamespace eq ($r->{generated_namespace}||"##NULL")) ? "" : sprintf("<%s:%s> ", $r->{generated_server}||"*", $r->{generated_namespace}||"##NULL"))
|
||||
. ($r->{deleted} ? "[REDACTED]" :
|
||||
(
|
||||
($r->{protected} ? "P:" : "")
|
||||
|
@ -639,19 +645,71 @@ sub get_fact_learn ($self, $body, $name, $said, $subject=undef, $predicate=undef
|
|||
return "Stored $subject as $predicate";
|
||||
}
|
||||
|
||||
sub get_fact_search ($self, $body, $name, $said) {
|
||||
print STDERR "Inside search\n";
|
||||
# TODO replace this with FTS
|
||||
|
||||
sub get_fact_search($self, $body, $name, $said) {
|
||||
my ($aliasserver, $aliasnamespace) = $self->get_alias_namespace($said);
|
||||
my ($server, $namespace) = $self->get_namespace($said);
|
||||
|
||||
$body =~ s/^\s*for\s*//; #remove the for from searches
|
||||
|
||||
# TODO queries need the CTE
|
||||
|
||||
my $results = $self->dbh->selectall_arrayref("
|
||||
WITH RECURSIVE factoid_lookup_order_inner (depth, namespace, server, alias_namespace, alias_server, parent_namespace, parent_server, recursive, gen_server, gen_namespace) AS (
|
||||
SELECT 0 AS depth, namespace, server, alias_namespace, alias_server, parent_namespace, parent_server, recursive, generated_server, generated_namespace
|
||||
FROM factoid_config
|
||||
WHERE namespace = ? AND server = ?
|
||||
UNION ALL
|
||||
SELECT p.depth+1 AS depth, m.namespace, m.server, m.alias_namespace, m.alias_server, m.parent_namespace, m.parent_server, m.recursive, m.generated_server, m.generated_namespace
|
||||
FROM factoid_config m
|
||||
INNER JOIN factoid_lookup_order_inner p
|
||||
ON m.namespace = p.parent_namespace AND m.server = p.parent_server AND p.recursive
|
||||
),
|
||||
factoid_lookup_order (depth, namespace, server, alias_namespace, alias_server, parent_namespace, parent_server, recursive, gen_server, gen_namespace) AS (
|
||||
SELECT * FROM factoid_lookup_order_inner
|
||||
UNION ALL
|
||||
SELECT 0, '', '', NULL, NULL, NULL, NULL, false, '', '' WHERE NOT EXISTS (table factoid_lookup_order_inner)
|
||||
),
|
||||
get_factoid_search (depth, factoid_id, subject, copula, predicate, author, modified_time, compose_macro, protected, original_subject, deleted, server, namespace, full_document_tsvector, last_rendered) AS (
|
||||
SELECT DISTINCT ON (original_subject) lo.depth, factoid_id, subject,
|
||||
copula, predicate, author, modified_time, compose_macro, protected,
|
||||
original_subject, f.deleted, f.server, f.namespace, f.full_document_tsvector, f.last_rendered
|
||||
FROM factoid f
|
||||
INNER JOIN factoid_lookup_order lo
|
||||
ON f.generated_server = lo.gen_server
|
||||
AND f.generated_namespace = lo.gen_namespace
|
||||
WHERE NOT deleted
|
||||
ORDER BY original_subject ASC, depth ASC, factoid_id DESC
|
||||
)
|
||||
SELECT ts_rank(full_document_tsvector, websearch_to_tsquery(?)) AS rank, * FROM get_factoid_search ORDER BY 1 DESC LIMIT 10
|
||||
",
|
||||
{ Slice => {} },
|
||||
$namespace, $server,
|
||||
$body,
|
||||
);
|
||||
|
||||
if ($results and @$results) {
|
||||
my $ret_string;
|
||||
for (@$results) {
|
||||
|
||||
#i want a better string here, i'll probably go with just the subject, XXX TODO
|
||||
$ret_string .= "[" . _fact_literal_format($_, $aliasserver, $aliasnamespace) . "]\n"
|
||||
if ($_->{predicate} !~ /^\s*$/);
|
||||
}
|
||||
|
||||
return $ret_string;
|
||||
} else {
|
||||
return "No matches.";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
sub get_fact_oldsearch ($self, $body, $name, $said) {
|
||||
my ($aliasserver, $aliasnamespace) = $self->get_alias_namespace($said);
|
||||
my ($server, $namespace) = $self->get_namespace($said);
|
||||
|
||||
$body =~ s/^\s*for\s*//; #remove the for from searches
|
||||
|
||||
my $results;
|
||||
print STDERR "Checking body for regex\n";
|
||||
|
||||
if ($body =~ m|^\s*m?/(.*)/\s*$|) {
|
||||
my $search = $1;
|
||||
|
@ -891,6 +949,8 @@ sub basic_get_fact ($self, $pm, $said, $subject, $name, $call_only) {
|
|||
use Data::Dumper;
|
||||
print $fh Dumper({ key => $key, arg => $arg, fact => $fact, ret => $ret });
|
||||
|
||||
$self->set_last_rendered($fact, $ret);
|
||||
|
||||
$ret = "\x00$ret" if ($key eq "tell");
|
||||
|
||||
return $ret;
|
||||
|
@ -911,7 +971,7 @@ sub basic_get_fact ($self, $pm, $said, $subject, $name, $call_only) {
|
|||
|
||||
push @{ $said->{suggestion_matches} }, @$matches;
|
||||
|
||||
if (($matches and @$matches) && (!$said->{backdressed})) {
|
||||
if (!$said->{nosuggest} && ($matches and @$matches) && (!$said->{backdressed})) {
|
||||
return "No factoid found. Did you mean one of these: " . join " ", map "[$_]", @$matches;
|
||||
} else {
|
||||
return;
|
||||
|
@ -966,6 +1026,18 @@ $subject, $subject, $subject, $subject, $subject, $subject, $threshold
|
|||
return [grep {$_} map {$_->[2]} @$rows ];
|
||||
}
|
||||
|
||||
sub set_last_rendered($self, $fact, $ret) {
|
||||
my $factoid_id = $fact->{factoid_id};
|
||||
|
||||
my $dbh = $self->dbh;
|
||||
|
||||
$dbh->do("UPDATE factoid SET last_rendered = ? WHERE factoid_id = ?", undef,
|
||||
$ret, $factoid_id
|
||||
);
|
||||
|
||||
# TODO trigger FTS update?
|
||||
}
|
||||
|
||||
no warnings 'void';
|
||||
"Bot::BB3::Plugin::Factoids";
|
||||
__DATA__
|
||||
|
|
|
@ -84,12 +84,12 @@ sub new {
|
|||
my $perlcommand_re = $perlcommand_ra->re;
|
||||
|
||||
my $othercommand_ra = Regexp::Assemble->new();
|
||||
$othercommand_ra->add(qw/jseval rkeval coboleval cbeval basheval r concise/);
|
||||
$othercommand_ra->add(qw/jseval rkeval coboleval cbeval basheval r concise eval/);
|
||||
my $othercommand_re = $othercommand_ra->re;
|
||||
|
||||
my $newversion_re = Regexp::Optimizer->new->optimize($version_re);
|
||||
|
||||
my $complete_re = qr/${strict_re}${perlcommand_re}${newversion_re}${suffix_re}|${othercommand_re}/;
|
||||
my $complete_re = qr/^(?:${strict_re}${perlcommand_re}${newversion_re}|${othercommand_re})${suffix_re}/;
|
||||
|
||||
$self->{alias_re} = $complete_re;
|
||||
|
||||
|
@ -110,7 +110,8 @@ sub command {
|
|||
my $pbflag = ($postflags =~ /pb/i);
|
||||
$type =~ s/\Q$postflags\E$//;
|
||||
$type =~ s/^\s*(\w+?)?eval(.*?)?/$1$2/i;
|
||||
warn "Initial type: $type\n";
|
||||
use JSON::MaybeXS qw/encode_json/;
|
||||
warn "Initial type: $type $command ".encode_json($said)."\n";
|
||||
|
||||
my %translations = (
|
||||
concise => 'concise',
|
||||
|
@ -173,6 +174,8 @@ sub command {
|
|||
return ("handled", "");
|
||||
}
|
||||
|
||||
warn "CODE CHECK $code\n";
|
||||
|
||||
if ($code !~ /\S/) {
|
||||
return ("handled", "");
|
||||
}
|
||||
|
@ -306,6 +309,7 @@ sub command {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
return( 'handled', $resultstr);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue