mourningdove/cgi-bin/DW/Controller/Support/Search.pm

117 lines
3.2 KiB
Perl
Raw Normal View History

2026-05-24 01:03:05 +00:00
#!/usr/bin/perl
#
# DW::Controller::Support::Search
#
# The search controller for support.
#
# Authors:
# Mark Smith <mark@dreamwidth.org>
#
# Copyright (c) 2013 by Dreamwidth Studios, LLC.
#
# This program is free software; you may redistribute it and/or modify it under
# the same terms as Perl itself. For a copy of the license, please reference
# 'perldoc perlartistic' or 'perldoc perlgpl'.
#
package DW::Controller::Support::Search;
use strict;
use DW::Routing;
use DW::Request;
use DW::Controller;
use Storable;
DW::Routing->register_string( "/support/search", \&search_handler, app => 1 );
sub search_handler {
my ( $ok, $rv ) = controller( authas => 1, form_auth => 0 );
return $rv unless $ok;
my $remote = $rv->{remote};
my $r = DW::Request->get;
return DW::Template->render_template('support/search.tt')
unless $r->did_post;
# POST logic, for doing the actual search.
my $args = $r->post_args;
die "Invalid form auth.\n"
unless LJ::check_form_auth( $args->{lj_form_auth} );
$rv = do_search(
remoteid => $remote->id,
query => $args->{query},
offset => $args->{offset}
);
return DW::Template->render_template( 'support/search.tt', $rv );
}
# helper subroutine that can be called from other contexts
sub do_search {
my %args = @_;
my $remoteid = delete $args{remoteid} or die "No remoteid";
my $q = LJ::strip_html( LJ::trim( delete $args{query} ) );
my $offset = ( delete $args{offset} // 0 ) + 0;
die "Unknown opts to do_search" if %args;
my $gc = LJ::gearman_client();
die "Sorry, content searching is not configured on this server.\n"
unless $gc && @LJ::SPHINX_SEARCHD;
my $error = sub { return { query => $q, error => $_[0] } };
my $ok = sub {
return {
query => $q,
offset => $offset,
result => $_[0]
};
};
return $error->("Please specify a shorter search string.")
if length $q > 255;
return $error->("Please specify a search string.")
unless length $q > 0;
return $error->("Offset must be between 0 and 1000.")
unless $offset >= 0 && $offset <= 1000;
# Gearman worker takes a blob, we send it a frozen hash.
my $search_args = {
remoteid => $remoteid,
query => $q,
offset => $offset,
support => 1
};
my $arg = Storable::nfreeze($search_args);
# Build the actual task we're sending to Gearman for searching.
my $result;
my $task = Gearman::Task->new(
'sphinx_search',
\$arg,
{
uniq => '-',
on_complete => sub {
my $res = $_[0] or return undef;
$result = Storable::thaw($$res);
},
}
);
# Fire the job and wait a bit. Times out if we don't get a response.
my $ts = $gc->new_task_set();
$ts->add_task($task);
$ts->wait( timeout => 20 );
return $error->("Sorry, the request timed out or search is down.")
unless ref $result eq 'HASH';
return $error->("Sorry, there were no results found for that search.")
if $result->{total} <= 0;
return $ok->($result);
}
1;