mirror of
https://github.com/MarginaliaSearch/MarginaliaSearch.git
synced 2025-02-24 21:29:00 +00:00

Look, this will make the git history look funny, but trimming unnecessary depth from the source tree is a very necessary sanity-preserving measure when dealing with a super-modularized codebase like this one. While it makes the project configuration a bit less conventional, it will save you several clicks every time you jump between modules. Which you'll do a lot, because it's *modul*ar. The src/main/java convention makes a lot of sense for a non-modular project though. This ain't that.
169 lines
5.7 KiB
Java
169 lines
5.7 KiB
Java
package nu.marginalia.dating;
|
|
|
|
import com.google.inject.Inject;
|
|
import lombok.SneakyThrows;
|
|
import nu.marginalia.browse.DbBrowseDomainsRandom;
|
|
import nu.marginalia.browse.DbBrowseDomainsSimilarCosine;
|
|
import nu.marginalia.browse.model.BrowseResult;
|
|
import nu.marginalia.db.DomainBlacklist;
|
|
import nu.marginalia.renderer.MustacheRenderer;
|
|
import nu.marginalia.renderer.RendererFactory;
|
|
import nu.marginalia.screenshot.ScreenshotService;
|
|
import nu.marginalia.service.server.*;
|
|
import org.jetbrains.annotations.NotNull;
|
|
import spark.Request;
|
|
import spark.Response;
|
|
import spark.Spark;
|
|
|
|
import java.util.Map;
|
|
import java.util.Optional;
|
|
|
|
public class DatingService extends Service {
|
|
private final DomainBlacklist blacklist;
|
|
private final DbBrowseDomainsSimilarCosine browseSimilarCosine;
|
|
private final DbBrowseDomainsRandom browseRandom;
|
|
private final MustacheRenderer<BrowseResult> datingRenderer;
|
|
private final ScreenshotService screenshotService;
|
|
private final String SESSION_OBJECT_NAME = "so";
|
|
@SneakyThrows
|
|
@Inject
|
|
public DatingService(BaseServiceParams params,
|
|
RendererFactory rendererFactory,
|
|
DomainBlacklist blacklist,
|
|
DbBrowseDomainsSimilarCosine browseSimilarCosine,
|
|
DbBrowseDomainsRandom browseRandom,
|
|
ScreenshotService screenshotService)
|
|
{
|
|
|
|
super(params);
|
|
|
|
this.blacklist = blacklist;
|
|
|
|
datingRenderer = rendererFactory.renderer("dating/dating-view");
|
|
this.browseSimilarCosine = browseSimilarCosine;
|
|
this.browseRandom = browseRandom;
|
|
this.screenshotService = screenshotService;
|
|
|
|
Spark.get("/public/reset", this::getReset);
|
|
Spark.get("/public/", this::getInitSession);
|
|
Spark.get("/public/view", this::getCurrent);
|
|
Spark.get("/public/next", this::getNext);
|
|
Spark.get("/public/similar/:id", this::getSimilar);
|
|
Spark.get("/public/rewind", this::getRewind);
|
|
Spark.get("/public/init", this::getInitSession);
|
|
}
|
|
|
|
private Object getInitSession(Request request, Response response) {
|
|
var sessionObjectOpt = getSession(request);
|
|
if (sessionObjectOpt.isEmpty()) {
|
|
request.session(true).attribute(SESSION_OBJECT_NAME, new DatingSessionObject());
|
|
}
|
|
response.redirect("https://explore.marginalia.nu/view");
|
|
return "";
|
|
}
|
|
|
|
private String getReset(Request request, Response response) {
|
|
var sessionObjectOpt = getSession(request);
|
|
if (sessionObjectOpt.isEmpty()) {
|
|
response.redirect("https://explore.marginalia.nu/");
|
|
return "";
|
|
}
|
|
var session = sessionObjectOpt.get();
|
|
session.resetQueue();
|
|
|
|
return getNext(request, response);
|
|
}
|
|
|
|
private String getCurrent(Request request, Response response) {
|
|
var sessionObjectOpt = getSession(request);
|
|
if (sessionObjectOpt.isEmpty()) {
|
|
response.redirect("https://explore.marginalia.nu/");
|
|
return "";
|
|
}
|
|
var session = sessionObjectOpt.get();
|
|
|
|
var current = session.getCurrent();
|
|
if (current == null) {
|
|
BrowseResult res = session.next(browseRandom, blacklist);
|
|
res = findViableDomain(session, res);
|
|
session.browseForward(res);
|
|
current = session.getCurrent();
|
|
}
|
|
|
|
return datingRenderer.render(current, Map.of("back", session.hasHistory()));
|
|
}
|
|
|
|
private String getNext(Request request, Response response) {
|
|
var sessionObjectOpt = getSession(request);
|
|
if (sessionObjectOpt.isEmpty()) {
|
|
response.redirect("https://explore.marginalia.nu/");
|
|
return "";
|
|
}
|
|
var session = sessionObjectOpt.get();
|
|
|
|
BrowseResult res = session.next(browseRandom, blacklist);
|
|
|
|
res = findViableDomain(session, res);
|
|
|
|
session.browseForward(res);
|
|
|
|
response.redirect("https://explore.marginalia.nu/view");
|
|
return "";
|
|
}
|
|
|
|
private String getRewind(Request request, Response response) {
|
|
var sessionObjectOpt = getSession(request);
|
|
if (sessionObjectOpt.isEmpty()) {
|
|
response.redirect("https://explore.marginalia.nu/");
|
|
return "";
|
|
}
|
|
var session = sessionObjectOpt.get();
|
|
|
|
BrowseResult res = session.takeFromHistory();
|
|
if (res == null) {
|
|
Spark.halt(404);
|
|
return "";
|
|
}
|
|
|
|
session.browseBackward(res);
|
|
|
|
response.redirect("https://explore.marginalia.nu/view");
|
|
return "";
|
|
}
|
|
|
|
|
|
private String getSimilar(Request request, Response response) {
|
|
var sessionObjectOpt = getSession(request);
|
|
if (sessionObjectOpt.isEmpty()) {
|
|
response.redirect("https://explore.marginalia.nu/");
|
|
return "";
|
|
}
|
|
var session = sessionObjectOpt.get();
|
|
|
|
int id = Integer.parseInt(request.params("id"));
|
|
BrowseResult res = session.nextSimilar(id, browseSimilarCosine, blacklist);
|
|
|
|
res = findViableDomain(session, res);
|
|
|
|
session.browseForward(res);
|
|
|
|
response.redirect("https://explore.marginalia.nu/view");
|
|
return "";
|
|
}
|
|
|
|
@NotNull
|
|
private BrowseResult findViableDomain(DatingSessionObject session, BrowseResult res) {
|
|
while (!screenshotService.hasScreenshot(res.domainId()) || session.isRecent(res)) {
|
|
res = session.next(browseRandom, blacklist);
|
|
}
|
|
return res;
|
|
}
|
|
|
|
|
|
private Optional<DatingSessionObject> getSession(Request request) {
|
|
return Optional.ofNullable(request.session(false))
|
|
.map(s -> s.attribute(SESSION_OBJECT_NAME))
|
|
.map(DatingSessionObject.class::cast);
|
|
}
|
|
}
|