mirror of
https://github.com/MarginaliaSearch/MarginaliaSearch.git
synced 2025-02-24 05:18:58 +00:00
(control) Administrative QOL improvement, GUI for banning spam
This commit is contained in:
parent
1b418d77ff
commit
49344d7ea8
@ -45,6 +45,7 @@ dependencies {
|
|||||||
implementation libs.notnull
|
implementation libs.notnull
|
||||||
implementation libs.guice
|
implementation libs.guice
|
||||||
implementation libs.zstd
|
implementation libs.zstd
|
||||||
|
implementation libs.rxjava
|
||||||
|
|
||||||
implementation libs.trove
|
implementation libs.trove
|
||||||
implementation libs.spark
|
implementation libs.spark
|
||||||
|
@ -3,6 +3,7 @@ package nu.marginalia.control;
|
|||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import gnu.trove.list.array.TIntArrayList;
|
import gnu.trove.list.array.TIntArrayList;
|
||||||
|
import nu.marginalia.client.Context;
|
||||||
import nu.marginalia.client.ServiceMonitors;
|
import nu.marginalia.client.ServiceMonitors;
|
||||||
import nu.marginalia.control.actor.Actor;
|
import nu.marginalia.control.actor.Actor;
|
||||||
import nu.marginalia.control.model.*;
|
import nu.marginalia.control.model.*;
|
||||||
@ -10,9 +11,11 @@ import nu.marginalia.control.svc.*;
|
|||||||
import nu.marginalia.db.storage.model.FileStorageId;
|
import nu.marginalia.db.storage.model.FileStorageId;
|
||||||
import nu.marginalia.db.storage.model.FileStorageType;
|
import nu.marginalia.db.storage.model.FileStorageType;
|
||||||
import nu.marginalia.model.EdgeDomain;
|
import nu.marginalia.model.EdgeDomain;
|
||||||
|
import nu.marginalia.model.EdgeUrl;
|
||||||
import nu.marginalia.model.gson.GsonFactory;
|
import nu.marginalia.model.gson.GsonFactory;
|
||||||
import nu.marginalia.renderer.RendererFactory;
|
import nu.marginalia.renderer.RendererFactory;
|
||||||
import nu.marginalia.screenshot.ScreenshotService;
|
import nu.marginalia.screenshot.ScreenshotService;
|
||||||
|
import nu.marginalia.search.client.SearchClient;
|
||||||
import nu.marginalia.service.server.*;
|
import nu.marginalia.service.server.*;
|
||||||
import org.eclipse.jetty.util.StringUtil;
|
import org.eclipse.jetty.util.StringUtil;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@ -38,6 +41,7 @@ public class ControlService extends Service {
|
|||||||
private final DomainComplaintService domainComplaintService;
|
private final DomainComplaintService domainComplaintService;
|
||||||
private final ControlBlacklistService blacklistService;
|
private final ControlBlacklistService blacklistService;
|
||||||
private final RandomExplorationService randomExplorationService;
|
private final RandomExplorationService randomExplorationService;
|
||||||
|
private final SearchClient searchClient;
|
||||||
private final ControlActorService controlActorService;
|
private final ControlActorService controlActorService;
|
||||||
private final StaticResources staticResources;
|
private final StaticResources staticResources;
|
||||||
private final MessageQueueService messageQueueService;
|
private final MessageQueueService messageQueueService;
|
||||||
@ -59,7 +63,8 @@ public class ControlService extends Service {
|
|||||||
ControlBlacklistService blacklistService,
|
ControlBlacklistService blacklistService,
|
||||||
ControlActionsService controlActionsService,
|
ControlActionsService controlActionsService,
|
||||||
ScreenshotService screenshotService,
|
ScreenshotService screenshotService,
|
||||||
RandomExplorationService randomExplorationService
|
RandomExplorationService randomExplorationService,
|
||||||
|
SearchClient searchClient
|
||||||
) throws IOException {
|
) throws IOException {
|
||||||
|
|
||||||
super(params);
|
super(params);
|
||||||
@ -70,6 +75,7 @@ public class ControlService extends Service {
|
|||||||
this.domainComplaintService = domainComplaintService;
|
this.domainComplaintService = domainComplaintService;
|
||||||
this.blacklistService = blacklistService;
|
this.blacklistService = blacklistService;
|
||||||
this.randomExplorationService = randomExplorationService;
|
this.randomExplorationService = randomExplorationService;
|
||||||
|
this.searchClient = searchClient;
|
||||||
|
|
||||||
var indexRenderer = rendererFactory.renderer("control/index");
|
var indexRenderer = rendererFactory.renderer("control/index");
|
||||||
var eventsRenderer = rendererFactory.renderer("control/events");
|
var eventsRenderer = rendererFactory.renderer("control/events");
|
||||||
@ -96,6 +102,7 @@ public class ControlService extends Service {
|
|||||||
|
|
||||||
var actionsViewRenderer = rendererFactory.renderer("control/actions");
|
var actionsViewRenderer = rendererFactory.renderer("control/actions");
|
||||||
var blacklistRenderer = rendererFactory.renderer("control/blacklist");
|
var blacklistRenderer = rendererFactory.renderer("control/blacklist");
|
||||||
|
var searchToBanRenderer = rendererFactory.renderer("control/search-to-ban");
|
||||||
|
|
||||||
this.controlActorService = controlActorService;
|
this.controlActorService = controlActorService;
|
||||||
|
|
||||||
@ -169,6 +176,9 @@ public class ControlService extends Service {
|
|||||||
Spark.get("/public/blacklist", this::blacklistModel, blacklistRenderer::render);
|
Spark.get("/public/blacklist", this::blacklistModel, blacklistRenderer::render);
|
||||||
Spark.post("/public/blacklist", this::updateBlacklist, redirectToBlacklist);
|
Spark.post("/public/blacklist", this::updateBlacklist, redirectToBlacklist);
|
||||||
|
|
||||||
|
Spark.get("/public/search-to-ban", this::searchToBanModel, searchToBanRenderer::render);
|
||||||
|
Spark.post("/public/search-to-ban", this::searchToBanModel, searchToBanRenderer::render);
|
||||||
|
|
||||||
// API Keys
|
// API Keys
|
||||||
|
|
||||||
Spark.get("/public/api-keys", this::apiKeysModel, apiKeysRenderer::render);
|
Spark.get("/public/api-keys", this::apiKeysModel, apiKeysRenderer::render);
|
||||||
@ -242,6 +252,37 @@ public class ControlService extends Service {
|
|||||||
return Map.of("blacklist", blacklistService.lastNAdditions(100));
|
return Map.of("blacklist", blacklistService.lastNAdditions(100));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Object searchToBanModel(Request request, Response response) {
|
||||||
|
String q = request.queryParams("q");
|
||||||
|
|
||||||
|
if (Objects.equals(request.requestMethod(), "POST")) {
|
||||||
|
request.params().forEach((k,v) -> System.out.println(k + " -- " + v));
|
||||||
|
List<String> bannedUrls = new ArrayList<>();
|
||||||
|
|
||||||
|
String query = request.queryParams("query");
|
||||||
|
for (var param : request.queryParams()) {
|
||||||
|
if ("query".equals(param)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
EdgeUrl.parse(param).ifPresent(url ->
|
||||||
|
blacklistService.addToBlacklist(url.domain, query)
|
||||||
|
);
|
||||||
|
bannedUrls.add(param);
|
||||||
|
}
|
||||||
|
|
||||||
|
request.queryParams().forEach(System.out::println);
|
||||||
|
q = query;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (q == null || q.isBlank()) {
|
||||||
|
return Map.of();
|
||||||
|
} else {
|
||||||
|
return searchClient
|
||||||
|
.query(Context.fromRequest(request), q, 200, 5)
|
||||||
|
.blockingFirst();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private Object updateBlacklist(Request request, Response response) {
|
private Object updateBlacklist(Request request, Response response) {
|
||||||
var domain = new EdgeDomain(request.queryParams("domain"));
|
var domain = new EdgeDomain(request.queryParams("domain"));
|
||||||
if ("add".equals(request.queryParams("act"))) {
|
if ("add".equals(request.queryParams("act"))) {
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
<li>Manage</li>
|
<li>Manage</li>
|
||||||
<li><a href="/api-keys" title="Create or remove API keys">API Keys</a></li>
|
<li><a href="/api-keys" title="Create or remove API keys">API Keys</a></li>
|
||||||
<li><a href="/blacklist" title="Add or remove website sanctions">Blacklist</a></li>
|
<li><a href="/blacklist" title="Add or remove website sanctions">Blacklist</a></li>
|
||||||
|
<li><a href="/search-to-ban" title="Search function for easy blacklisting">Blacklist Search</a></li>
|
||||||
<li><a href="/complaints" title="View and act on user complaints">Complaints</a></li>
|
<li><a href="/complaints" title="View and act on user complaints">Complaints</a></li>
|
||||||
<li><a href="/review-random-domains" title="Review random domains list">Random Exploration</a></li>
|
<li><a href="/review-random-domains" title="Review random domains list">Random Exploration</a></li>
|
||||||
<li>System</li>
|
<li>System</li>
|
||||||
|
@ -0,0 +1,37 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Control Service</title>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<link rel="stylesheet" href="/style.css" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
{{> control/partials/nav}}
|
||||||
|
<section>
|
||||||
|
<h1>Search to Ban</h1>
|
||||||
|
<form action="/search-to-ban">
|
||||||
|
<label for="q">Search Query</label><br>
|
||||||
|
<input type="text" value="{{query}}" name="q" id="q" /> <input type="submit" value="Search" />
|
||||||
|
</form>
|
||||||
|
{{#unless results}}
|
||||||
|
<p>This utility lets you use the search engine to find spammy results, and ban them
|
||||||
|
by using the checkbox next to the result. </p>
|
||||||
|
{{/unless}}
|
||||||
|
{{#if results}}
|
||||||
|
<hr>
|
||||||
|
<form action="/search-to-ban" method="post">
|
||||||
|
<input type="submit" value="Blacklist Selected Domains">
|
||||||
|
<input type="hidden" name="query" text="{{query}}" />
|
||||||
|
<table>
|
||||||
|
{{#each results}}
|
||||||
|
<tr><td><input type="checkbox" name="{{url}}"><td>{{title}}</td></tr>
|
||||||
|
<tr><td colspan="2"><a href="{{url}}>{{url}}</a></td></tr>
|
||||||
|
<tr><td colspan="2">{{description}}</td></tr>
|
||||||
|
<tr><td colspan="2"> </td></tr>
|
||||||
|
{{/each}}
|
||||||
|
</table>
|
||||||
|
{{/if}}
|
||||||
|
</form>
|
||||||
|
</section>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -48,6 +48,7 @@ public class SearchApiQueryService {
|
|||||||
case "1" -> SearchProfile.MODERN;
|
case "1" -> SearchProfile.MODERN;
|
||||||
case "2" -> SearchProfile.DEFAULT;
|
case "2" -> SearchProfile.DEFAULT;
|
||||||
case "3" -> SearchProfile.CORPO_CLEAN;
|
case "3" -> SearchProfile.CORPO_CLEAN;
|
||||||
|
case "5" -> SearchProfile.YOLO;
|
||||||
case "blogosphere" -> SearchProfile.BLOGOSPHERE;
|
case "blogosphere" -> SearchProfile.BLOGOSPHERE;
|
||||||
default -> SearchProfile.CORPO_CLEAN;
|
default -> SearchProfile.CORPO_CLEAN;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user