Piped-Backend/src/main/java/me/kavin/piped/ServerLauncher.java
2021-04-22 19:52:32 +05:30

193 lines
8.4 KiB
Java

package me.kavin.piped;
import static io.activej.config.converter.ConfigConverters.ofInetSocketAddress;
import static io.activej.http.HttpHeaders.CACHE_CONTROL;
import static io.activej.http.HttpHeaders.CONTENT_TYPE;
import java.io.ByteArrayInputStream;
import java.net.InetSocketAddress;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.jetbrains.annotations.NotNull;
import org.xml.sax.InputSource;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.rometools.rome.feed.synd.SyndFeed;
import com.rometools.rome.io.SyndFeedInput;
import io.activej.config.Config;
import io.activej.http.AsyncServlet;
import io.activej.http.HttpMethod;
import io.activej.http.HttpResponse;
import io.activej.http.RoutingServlet;
import io.activej.inject.annotation.Provides;
import io.activej.inject.module.AbstractModule;
import io.activej.inject.module.Module;
import io.activej.launchers.http.MultithreadedHttpServerLauncher;
import me.kavin.piped.consts.Constants;
import me.kavin.piped.utils.CustomServletDecorator;
import me.kavin.piped.utils.ResponseHelper;
import me.kavin.piped.utils.SponsorBlockUtils;
import me.kavin.piped.utils.resp.ErrorResponse;
public class ServerLauncher extends MultithreadedHttpServerLauncher {
@Provides
Executor executor() {
return Executors.newCachedThreadPool();
}
@Provides
AsyncServlet mainServlet(Executor executor) {
RoutingServlet router = RoutingServlet.create().map(HttpMethod.GET, "/webhooks/pubsub", request -> {
return HttpResponse.ok200().withPlainText(request.getQueryParameter("hub.challenge"));
}).map(HttpMethod.POST, "/webhooks/pubsub", AsyncServlet.ofBlocking(executor, request -> {
try {
SyndFeed feed = new SyndFeedInput()
.build(new InputSource(new ByteArrayInputStream(request.loadBody().getResult().asArray())));
feed.getEntries().forEach(entry -> {
System.out.println(entry.getLinks().get(0).getHref());
System.out.println(entry.getAuthors().get(0).getUri());
});
return HttpResponse.ofCode(204);
} catch (Exception e) {
return getErrorResponse(e);
}
})).map("/sponsors/:videoId", AsyncServlet.ofBlocking(executor, request -> {
try {
return getJsonResponse(SponsorBlockUtils
.getSponsors(request.getPathParameter("videoId"), request.getQueryParameter("category"))
.getBytes(StandardCharsets.UTF_8), "public, max-age=3600");
} catch (Exception e) {
return getErrorResponse(e);
}
})).map("/streams/:videoId", AsyncServlet.ofBlocking(executor, request -> {
try {
return getJsonResponse(ResponseHelper.streamsResponse(request.getPathParameter("videoId")),
"public, s-maxage=21540");
} catch (Exception e) {
return getErrorResponse(e);
}
})).map("/channels/:channelId", AsyncServlet.ofBlocking(executor, request -> {
try {
return getJsonResponse(ResponseHelper.channelResponse(request.getPathParameter("channelId")),
"public, max-age=600");
} catch (Exception e) {
return getErrorResponse(e);
}
})).map("/nextpage/channels/:channelId", AsyncServlet.ofBlocking(executor, request -> {
try {
return getJsonResponse(
ResponseHelper.channelPageResponse(request.getPathParameter("channelId"),
request.getQueryParameter("url"), request.getQueryParameter("id")),
"public, max-age=3600");
} catch (Exception e) {
return getErrorResponse(e);
}
})).map("/playlists/:playlistId", AsyncServlet.ofBlocking(executor, request -> {
try {
return getJsonResponse(ResponseHelper.playlistResponse(request.getPathParameter("playlistId")),
"public, max-age=600");
} catch (Exception e) {
return getErrorResponse(e);
}
})).map("/nextpage/playlists/:playlistId", AsyncServlet.ofBlocking(executor, request -> {
try {
return getJsonResponse(
ResponseHelper.playlistPageResponse(request.getPathParameter("playlistId"),
request.getQueryParameter("url"), request.getQueryParameter("id")),
"public, max-age=3600");
} catch (Exception e) {
return getErrorResponse(e);
}
})).map("/suggestions", AsyncServlet.ofBlocking(executor, request -> {
try {
return getJsonResponse(ResponseHelper.suggestionsResponse(request.getQueryParameter("query")),
"public, max-age=600");
} catch (Exception e) {
return getErrorResponse(e);
}
})).map("/search", AsyncServlet.ofBlocking(executor, request -> {
try {
return getJsonResponse(ResponseHelper.searchResponse(request.getQueryParameter("q")),
"public, max-age=600");
} catch (Exception e) {
return getErrorResponse(e);
}
})).map("/nextpage/search", AsyncServlet.ofBlocking(executor, request -> {
try {
return getJsonResponse(
ResponseHelper.searchPageResponse(request.getQueryParameter("q"),
request.getQueryParameter("url"), request.getQueryParameter("id")),
"public, max-age=3600");
} catch (Exception e) {
return getErrorResponse(e);
}
})).map("/trending", AsyncServlet.ofBlocking(executor, request -> {
try {
return getJsonResponse(ResponseHelper.trendingResponse(), "public, max-age=3600");
} catch (Exception e) {
return getErrorResponse(e);
}
})).map("/comments/:videoId", AsyncServlet.ofBlocking(executor, request -> {
try {
return getJsonResponse(ResponseHelper.commentsResponse(request.getPathParameter("videoId")),
"public, max-age=1200");
} catch (Exception e) {
return getErrorResponse(e);
}
})).map("/nextpage/comments/:videoId", AsyncServlet.ofBlocking(executor, request -> {
try {
return getJsonResponse(ResponseHelper.commentsPageResponse(request.getPathParameter("videoId"),
request.getQueryParameter("url")), "public, max-age=3600");
} catch (Exception e) {
return getErrorResponse(e);
}
}));
return new CustomServletDecorator(router);
}
@Override
protected Module getOverrideModule() {
return new AbstractModule() {
@Provides
Config config() {
return Config.create()
.with("http.listenAddresses",
Config.ofValue(ofInetSocketAddress(), new InetSocketAddress(PORT)))
.with("workers", Constants.HTTP_WORKERS);
}
};
}
private @NotNull HttpResponse getJsonResponse(byte[] body, String cache) {
return getJsonResponse(200, body, cache);
}
private @NotNull HttpResponse getJsonResponse(int code, byte[] body, String cache) {
return HttpResponse.ofCode(code).withBody(body).withHeader(CONTENT_TYPE, "application/json")
.withHeader(CACHE_CONTROL, cache);
}
private @NotNull HttpResponse getErrorResponse(Exception e) {
e.printStackTrace();
try {
return getJsonResponse(500,
Constants.mapper.writeValueAsBytes(new ErrorResponse(ExceptionUtils.getStackTrace(e))), "private");
} catch (JsonProcessingException ex) {
return HttpResponse.ofCode(500);
}
}
}