mirror of
https://github.com/TeamPiped/Piped-Backend.git
synced 2024-08-14 23:51:41 +00:00
Merge pull request #648 from TeamPiped/dearrow
Implement batched fetching of dearrow content.
This commit is contained in:
commit
68bbf05617
2 changed files with 68 additions and 0 deletions
|
@ -33,6 +33,7 @@ import org.xml.sax.InputSource;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
@ -149,6 +150,23 @@ public class ServerLauncher extends MultithreadedHttpServerLauncher {
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return getErrorResponse(e, request.getPath());
|
return getErrorResponse(e, request.getPath());
|
||||||
}
|
}
|
||||||
|
})).map(GET, "/dearrow", AsyncServlet.ofBlocking(executor, request -> {
|
||||||
|
try {
|
||||||
|
var videoIds = getArray(request.getQueryParameter("videoIds"));
|
||||||
|
|
||||||
|
return getJsonResponse(
|
||||||
|
SponsorBlockUtils.getDeArrowedInfo(List.of(videoIds))
|
||||||
|
.thenApplyAsync(json -> {
|
||||||
|
try {
|
||||||
|
return mapper.writeValueAsBytes(json);
|
||||||
|
} catch (JsonProcessingException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}).get(),
|
||||||
|
"public, max-age=3600");
|
||||||
|
} catch (Exception e) {
|
||||||
|
return getErrorResponse(e, request.getPath());
|
||||||
|
}
|
||||||
})).map(GET, "/streams/:videoId", AsyncServlet.ofBlocking(executor, request -> {
|
})).map(GET, "/streams/:videoId", AsyncServlet.ofBlocking(executor, request -> {
|
||||||
try {
|
try {
|
||||||
return getJsonResponse(StreamHandlers.streamsResponse(request.getPathParameter("videoId")),
|
return getJsonResponse(StreamHandlers.streamsResponse(request.getPathParameter("videoId")),
|
||||||
|
|
|
@ -1,5 +1,10 @@
|
||||||
package me.kavin.piped.utils;
|
package me.kavin.piped.utils;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
|
import com.fasterxml.jackson.databind.node.ArrayNode;
|
||||||
|
import com.fasterxml.jackson.databind.node.NullNode;
|
||||||
|
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||||
|
import com.fasterxml.jackson.databind.node.TextNode;
|
||||||
import me.kavin.piped.consts.Constants;
|
import me.kavin.piped.consts.Constants;
|
||||||
import me.kavin.piped.utils.resp.InvalidRequestResponse;
|
import me.kavin.piped.utils.resp.InvalidRequestResponse;
|
||||||
import me.kavin.piped.utils.resp.SimpleErrorMessage;
|
import me.kavin.piped.utils.resp.SimpleErrorMessage;
|
||||||
|
@ -7,6 +12,9 @@ import org.apache.commons.codec.digest.DigestUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
import static me.kavin.piped.consts.Constants.mapper;
|
import static me.kavin.piped.consts.Constants.mapper;
|
||||||
|
|
||||||
|
@ -46,4 +54,46 @@ public class SponsorBlockUtils {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static CompletableFuture<ObjectNode> getDeArrowedInfo(List<String> videoIds) {
|
||||||
|
ObjectNode objectNode = mapper.createObjectNode();
|
||||||
|
|
||||||
|
var futures = videoIds.stream()
|
||||||
|
.map(id -> getDeArrowedInfo(id).thenAcceptAsync(jsonNode -> objectNode.set(id, jsonNode.orElse(NullNode.getInstance()))))
|
||||||
|
.toArray(CompletableFuture[]::new);
|
||||||
|
|
||||||
|
return CompletableFuture.allOf(futures)
|
||||||
|
.thenApplyAsync(v -> objectNode, Multithreading.getCachedExecutor());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static CompletableFuture<Optional<JsonNode>> getDeArrowedInfo(String videoId) {
|
||||||
|
|
||||||
|
String hash = DigestUtils.sha256Hex(videoId);
|
||||||
|
|
||||||
|
CompletableFuture<Optional<JsonNode>> future = new CompletableFuture<>();
|
||||||
|
|
||||||
|
Multithreading.runAsync(() -> {
|
||||||
|
for (String url : Constants.SPONSORBLOCK_SERVERS)
|
||||||
|
try {
|
||||||
|
Optional<JsonNode> optional = RequestUtils.sendGetJson(url + "/api/branding/" + URLUtils.silentEncode(hash.substring(0, 4)))
|
||||||
|
.thenApplyAsync(json -> json.has(videoId) ? Optional.of(json.get(videoId)) : Optional.<JsonNode>empty())
|
||||||
|
.get();
|
||||||
|
|
||||||
|
optional.ifPresent(jsonNode -> {
|
||||||
|
ArrayNode nodes = (ArrayNode) jsonNode.get("thumbnails");
|
||||||
|
for (JsonNode node : nodes) {
|
||||||
|
((ObjectNode) node).set("thumbnail", new TextNode(URLUtils.rewriteURL("https://dearrow-thumb.ajay.app/api/v1/getThumbnail?videoID=" + videoId + "&time=" + node.get("timestamp").asText())));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
future.complete(optional);
|
||||||
|
return;
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
future.completeExceptionally(new Exception("All SponsorBlock servers are down"));
|
||||||
|
});
|
||||||
|
|
||||||
|
return future;
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue