mirror of
https://github.com/MarginaliaSearch/MarginaliaSearch.git
synced 2025-02-24 13:19:02 +00:00
129 lines
4.7 KiB
Java
129 lines
4.7 KiB
Java
package nu.marginalia.search;
|
|
|
|
import com.google.inject.Inject;
|
|
import io.prometheus.client.Counter;
|
|
import io.prometheus.client.Histogram;
|
|
import nu.marginalia.WebsiteUrl;
|
|
import nu.marginalia.search.svc.*;
|
|
import nu.marginalia.service.server.BaseServiceParams;
|
|
import nu.marginalia.service.server.SparkService;
|
|
import nu.marginalia.service.server.StaticResources;
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
import spark.Request;
|
|
import spark.Response;
|
|
import spark.Route;
|
|
import spark.Spark;
|
|
|
|
import java.net.URLEncoder;
|
|
import java.nio.charset.StandardCharsets;
|
|
|
|
public class SearchService extends SparkService {
|
|
|
|
private final WebsiteUrl websiteUrl;
|
|
private final StaticResources staticResources;
|
|
|
|
private static final Logger logger = LoggerFactory.getLogger(SearchService.class);
|
|
private static final Histogram wmsa_search_service_request_time = Histogram.build()
|
|
.name("wmsa_search_service_request_time")
|
|
.linearBuckets(0.05, 0.05, 15)
|
|
.labelNames("matchedPath", "method")
|
|
.help("Search service request time (seconds)")
|
|
.register();
|
|
private static final Counter wmsa_search_service_error_count = Counter.build()
|
|
.name("wmsa_search_service_error_count")
|
|
.labelNames("matchedPath", "method")
|
|
.help("Search service error count")
|
|
.register();
|
|
|
|
@Inject
|
|
public SearchService(BaseServiceParams params,
|
|
WebsiteUrl websiteUrl,
|
|
StaticResources staticResources,
|
|
SearchFrontPageService frontPageService,
|
|
SearchErrorPageService errorPageService,
|
|
SearchAddToCrawlQueueService addToCrawlQueueService,
|
|
SearchSiteInfoService siteInfoService,
|
|
SearchCrosstalkService crosstalkService,
|
|
SearchQueryService searchQueryService)
|
|
throws Exception
|
|
{
|
|
super(params);
|
|
|
|
this.websiteUrl = websiteUrl;
|
|
this.staticResources = staticResources;
|
|
|
|
Spark.staticFiles.expireTime(600);
|
|
|
|
SearchServiceMetrics.get("/search", searchQueryService::pathSearch);
|
|
|
|
SearchServiceMetrics.get("/", frontPageService::render);
|
|
SearchServiceMetrics.get("/news.xml", frontPageService::renderNewsFeed);
|
|
SearchServiceMetrics.get("/:resource", this::serveStatic);
|
|
|
|
SearchServiceMetrics.post("/site/suggest/", addToCrawlQueueService::suggestCrawling);
|
|
|
|
SearchServiceMetrics.get("/site-search/:site/*", this::siteSearchRedir);
|
|
|
|
SearchServiceMetrics.get("/site/:site", siteInfoService::handle);
|
|
SearchServiceMetrics.post("/site/:site", siteInfoService::handlePost);
|
|
|
|
SearchServiceMetrics.get("/crosstalk/", crosstalkService::handle);
|
|
|
|
Spark.exception(Exception.class, (e,p,q) -> {
|
|
logger.error("Error during processing", e);
|
|
wmsa_search_service_error_count.labels(p.pathInfo(), p.requestMethod()).inc();
|
|
errorPageService.serveError(p, q);
|
|
});
|
|
|
|
Spark.awaitInitialization();
|
|
}
|
|
|
|
|
|
|
|
/** Wraps a route with a timer and a counter */
|
|
private static class SearchServiceMetrics implements Route {
|
|
private final Route delegatedRoute;
|
|
|
|
static void get(String path, Route route) {
|
|
Spark.get(path, new SearchServiceMetrics(route));
|
|
}
|
|
static void post(String path, Route route) {
|
|
Spark.post(path, new SearchServiceMetrics(route));
|
|
}
|
|
|
|
private SearchServiceMetrics(Route delegatedRoute) {
|
|
this.delegatedRoute = delegatedRoute;
|
|
}
|
|
|
|
@Override
|
|
public Object handle(Request request, Response response) throws Exception {
|
|
return wmsa_search_service_request_time
|
|
.labels(request.matchedPath(), request.requestMethod())
|
|
.time(() -> delegatedRoute.handle(request, response));
|
|
}
|
|
}
|
|
|
|
private Object serveStatic(Request request, Response response) {
|
|
String resource = request.params("resource");
|
|
staticResources.serveStatic("search", resource, request, response);
|
|
return "";
|
|
}
|
|
|
|
private Object siteSearchRedir(Request request, Response response) {
|
|
final String site = request.params("site");
|
|
final String searchTerms;
|
|
|
|
if (request.splat().length == 0) searchTerms = "";
|
|
else searchTerms = request.splat()[0];
|
|
|
|
final String query = URLEncoder.encode(String.format("%s site:%s", searchTerms, site), StandardCharsets.UTF_8).trim();
|
|
final String profile = request.queryParamOrDefault("profile", "yolo");
|
|
|
|
response.redirect(websiteUrl.withPath("search?query="+query+"&profile="+profile));
|
|
|
|
return "";
|
|
}
|
|
|
|
}
|