2023-03-04 12:19:01 +00:00
|
|
|
package nu.marginalia.dating;
|
2022-05-19 15:45:26 +00:00
|
|
|
|
|
|
|
import com.google.inject.Inject;
|
2023-03-04 12:19:01 +00:00
|
|
|
import nu.marginalia.browse.DbBrowseDomainsRandom;
|
|
|
|
import nu.marginalia.browse.DbBrowseDomainsSimilarCosine;
|
|
|
|
import nu.marginalia.browse.model.BrowseResult;
|
2023-03-25 14:26:17 +00:00
|
|
|
import nu.marginalia.db.DomainBlacklist;
|
2023-03-04 12:19:01 +00:00
|
|
|
import nu.marginalia.renderer.MustacheRenderer;
|
|
|
|
import nu.marginalia.renderer.RendererFactory;
|
|
|
|
import nu.marginalia.screenshot.ScreenshotService;
|
2024-11-11 20:14:38 +00:00
|
|
|
import nu.marginalia.service.server.BaseServiceParams;
|
2024-12-10 18:13:13 +00:00
|
|
|
import nu.marginalia.service.server.SparkService;
|
2022-05-19 15:45:26 +00:00
|
|
|
import org.jetbrains.annotations.NotNull;
|
|
|
|
import spark.Request;
|
|
|
|
import spark.Response;
|
|
|
|
import spark.Spark;
|
|
|
|
|
|
|
|
import java.util.Map;
|
|
|
|
import java.util.Optional;
|
|
|
|
|
2024-12-10 18:13:13 +00:00
|
|
|
public class DatingService extends SparkService {
|
2023-03-11 12:48:40 +00:00
|
|
|
private final DomainBlacklist blacklist;
|
2023-03-04 12:19:01 +00:00
|
|
|
private final DbBrowseDomainsSimilarCosine browseSimilarCosine;
|
|
|
|
private final DbBrowseDomainsRandom browseRandom;
|
2022-05-19 15:45:26 +00:00
|
|
|
private final MustacheRenderer<BrowseResult> datingRenderer;
|
|
|
|
private final ScreenshotService screenshotService;
|
|
|
|
private final String SESSION_OBJECT_NAME = "so";
|
2024-11-11 20:14:38 +00:00
|
|
|
|
2022-05-19 15:45:26 +00:00
|
|
|
@Inject
|
2023-07-03 08:40:32 +00:00
|
|
|
public DatingService(BaseServiceParams params,
|
2022-05-19 15:45:26 +00:00
|
|
|
RendererFactory rendererFactory,
|
2023-03-11 12:48:40 +00:00
|
|
|
DomainBlacklist blacklist,
|
2023-03-04 12:19:01 +00:00
|
|
|
DbBrowseDomainsSimilarCosine browseSimilarCosine,
|
|
|
|
DbBrowseDomainsRandom browseRandom,
|
2023-07-03 08:40:32 +00:00
|
|
|
ScreenshotService screenshotService)
|
2024-11-11 20:14:38 +00:00
|
|
|
throws Exception
|
2023-07-03 08:40:32 +00:00
|
|
|
{
|
2022-05-19 15:45:26 +00:00
|
|
|
|
2023-07-03 08:40:32 +00:00
|
|
|
super(params);
|
2022-05-19 15:45:26 +00:00
|
|
|
|
|
|
|
this.blacklist = blacklist;
|
|
|
|
|
|
|
|
datingRenderer = rendererFactory.renderer("dating/dating-view");
|
2023-03-04 12:19:01 +00:00
|
|
|
this.browseSimilarCosine = browseSimilarCosine;
|
|
|
|
this.browseRandom = browseRandom;
|
2022-05-19 15:45:26 +00:00
|
|
|
this.screenshotService = screenshotService;
|
|
|
|
|
2024-04-30 12:46:18 +00:00
|
|
|
Spark.get("/reset", this::getReset);
|
|
|
|
Spark.get("/", this::getInitSession);
|
|
|
|
Spark.get("/view", this::getCurrent);
|
|
|
|
Spark.get("/next", this::getNext);
|
|
|
|
Spark.get("/similar/:id", this::getSimilar);
|
|
|
|
Spark.get("/rewind", this::getRewind);
|
|
|
|
Spark.get("/init", this::getInitSession);
|
2022-05-19 15:45:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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) {
|
2023-03-04 12:19:01 +00:00
|
|
|
BrowseResult res = session.next(browseRandom, blacklist);
|
2022-05-19 15:45:26 +00:00
|
|
|
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();
|
|
|
|
|
2023-03-04 12:19:01 +00:00
|
|
|
BrowseResult res = session.next(browseRandom, blacklist);
|
2022-05-19 15:45:26 +00:00
|
|
|
|
|
|
|
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"));
|
2023-08-24 15:46:02 +00:00
|
|
|
BrowseResult res = session.nextSimilar(id, browseSimilarCosine, blacklist);
|
2022-05-19 15:45:26 +00:00
|
|
|
|
|
|
|
res = findViableDomain(session, res);
|
|
|
|
|
|
|
|
session.browseForward(res);
|
|
|
|
|
|
|
|
response.redirect("https://explore.marginalia.nu/view");
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
|
|
|
@NotNull
|
|
|
|
private BrowseResult findViableDomain(DatingSessionObject session, BrowseResult res) {
|
2023-08-24 15:46:02 +00:00
|
|
|
while (!screenshotService.hasScreenshot(res.domainId()) || session.isRecent(res)) {
|
2023-03-04 12:19:01 +00:00
|
|
|
res = session.next(browseRandom, blacklist);
|
2022-05-19 15:45:26 +00:00
|
|
|
}
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|