mirror of
https://github.com/TeamPiped/Piped-Backend.git
synced 2024-08-14 23:51:41 +00:00
Support region localization for trending
This commit is contained in:
parent
1af5754f18
commit
616de20f5b
2 changed files with 98 additions and 105 deletions
|
@ -1,26 +1,8 @@
|
||||||
package me.kavin.piped;
|
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.ExecutionException;
|
|
||||||
import java.util.concurrent.Executor;
|
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.exception.ExceptionUtils;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.schabi.newpipe.extractor.exceptions.AgeRestrictedContentException;
|
|
||||||
import org.schabi.newpipe.extractor.exceptions.ContentNotAvailableException;
|
|
||||||
import org.xml.sax.InputSource;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
import com.rometools.rome.feed.synd.SyndFeed;
|
import com.rometools.rome.feed.synd.SyndFeed;
|
||||||
import com.rometools.rome.io.SyndFeedInput;
|
import com.rometools.rome.io.SyndFeedInput;
|
||||||
|
|
||||||
import io.activej.config.Config;
|
import io.activej.config.Config;
|
||||||
import io.activej.http.AsyncServlet;
|
import io.activej.http.AsyncServlet;
|
||||||
import io.activej.http.HttpMethod;
|
import io.activej.http.HttpMethod;
|
||||||
|
@ -35,6 +17,22 @@ import me.kavin.piped.utils.CustomServletDecorator;
|
||||||
import me.kavin.piped.utils.ResponseHelper;
|
import me.kavin.piped.utils.ResponseHelper;
|
||||||
import me.kavin.piped.utils.SponsorBlockUtils;
|
import me.kavin.piped.utils.SponsorBlockUtils;
|
||||||
import me.kavin.piped.utils.resp.ErrorResponse;
|
import me.kavin.piped.utils.resp.ErrorResponse;
|
||||||
|
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.schabi.newpipe.extractor.exceptions.AgeRestrictedContentException;
|
||||||
|
import org.schabi.newpipe.extractor.exceptions.ContentNotAvailableException;
|
||||||
|
import org.xml.sax.InputSource;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
|
||||||
|
import static io.activej.config.converter.ConfigConverters.ofInetSocketAddress;
|
||||||
|
import static io.activej.http.HttpHeaders.CACHE_CONTROL;
|
||||||
|
import static io.activej.http.HttpHeaders.CONTENT_TYPE;
|
||||||
|
|
||||||
public class ServerLauncher extends MultithreadedHttpServerLauncher {
|
public class ServerLauncher extends MultithreadedHttpServerLauncher {
|
||||||
|
|
||||||
|
@ -147,7 +145,7 @@ public class ServerLauncher extends MultithreadedHttpServerLauncher {
|
||||||
}
|
}
|
||||||
})).map("/trending", AsyncServlet.ofBlocking(executor, request -> {
|
})).map("/trending", AsyncServlet.ofBlocking(executor, request -> {
|
||||||
try {
|
try {
|
||||||
return getJsonResponse(ResponseHelper.trendingResponse(), "public, max-age=3600");
|
return getJsonResponse(ResponseHelper.trendingResponse(request.getQueryParameter("region")), "public, max-age=3600");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return getErrorResponse(e);
|
return getErrorResponse(e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,37 @@
|
||||||
package me.kavin.piped.utils;
|
package me.kavin.piped.utils;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.github.benmanes.caffeine.cache.Caffeine;
|
||||||
|
import com.github.benmanes.caffeine.cache.LoadingCache;
|
||||||
|
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||||
|
import me.kavin.piped.consts.Constants;
|
||||||
|
import me.kavin.piped.ipfs.IPFS;
|
||||||
|
import me.kavin.piped.utils.obj.*;
|
||||||
|
import me.kavin.piped.utils.obj.search.SearchChannel;
|
||||||
|
import me.kavin.piped.utils.obj.search.SearchItem;
|
||||||
|
import me.kavin.piped.utils.obj.search.SearchPlaylist;
|
||||||
|
import me.kavin.piped.utils.obj.search.SearchStream;
|
||||||
|
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
import org.schabi.newpipe.extractor.InfoItem;
|
||||||
|
import org.schabi.newpipe.extractor.ListExtractor.InfoItemsPage;
|
||||||
|
import org.schabi.newpipe.extractor.Page;
|
||||||
|
import org.schabi.newpipe.extractor.channel.ChannelInfo;
|
||||||
|
import org.schabi.newpipe.extractor.channel.ChannelInfoItem;
|
||||||
|
import org.schabi.newpipe.extractor.comments.CommentsInfo;
|
||||||
|
import org.schabi.newpipe.extractor.comments.CommentsInfoItem;
|
||||||
|
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||||
|
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||||
|
import org.schabi.newpipe.extractor.kiosk.KioskExtractor;
|
||||||
|
import org.schabi.newpipe.extractor.kiosk.KioskInfo;
|
||||||
|
import org.schabi.newpipe.extractor.kiosk.KioskList;
|
||||||
|
import org.schabi.newpipe.extractor.localization.ContentCountry;
|
||||||
|
import org.schabi.newpipe.extractor.playlist.PlaylistInfo;
|
||||||
|
import org.schabi.newpipe.extractor.playlist.PlaylistInfoItem;
|
||||||
|
import org.schabi.newpipe.extractor.search.SearchInfo;
|
||||||
|
import org.schabi.newpipe.extractor.stream.StreamInfo;
|
||||||
|
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
@ -12,47 +44,6 @@ import java.util.List;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import org.apache.commons.lang3.exception.ExceptionUtils;
|
|
||||||
import org.json.JSONObject;
|
|
||||||
import org.schabi.newpipe.extractor.InfoItem;
|
|
||||||
import org.schabi.newpipe.extractor.ListExtractor.InfoItemsPage;
|
|
||||||
import org.schabi.newpipe.extractor.Page;
|
|
||||||
import org.schabi.newpipe.extractor.channel.ChannelInfo;
|
|
||||||
import org.schabi.newpipe.extractor.channel.ChannelInfoItem;
|
|
||||||
import org.schabi.newpipe.extractor.comments.CommentsInfo;
|
|
||||||
import org.schabi.newpipe.extractor.comments.CommentsInfoItem;
|
|
||||||
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
|
||||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
|
||||||
import org.schabi.newpipe.extractor.kiosk.KioskInfo;
|
|
||||||
import org.schabi.newpipe.extractor.playlist.PlaylistInfo;
|
|
||||||
import org.schabi.newpipe.extractor.playlist.PlaylistInfoItem;
|
|
||||||
import org.schabi.newpipe.extractor.search.SearchInfo;
|
|
||||||
import org.schabi.newpipe.extractor.stream.StreamInfo;
|
|
||||||
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
|
||||||
import com.github.benmanes.caffeine.cache.Caffeine;
|
|
||||||
import com.github.benmanes.caffeine.cache.LoadingCache;
|
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
|
||||||
import me.kavin.piped.consts.Constants;
|
|
||||||
import me.kavin.piped.ipfs.IPFS;
|
|
||||||
import me.kavin.piped.utils.obj.Channel;
|
|
||||||
import me.kavin.piped.utils.obj.ChapterSegment;
|
|
||||||
import me.kavin.piped.utils.obj.Comment;
|
|
||||||
import me.kavin.piped.utils.obj.CommentsPage;
|
|
||||||
import me.kavin.piped.utils.obj.PipedStream;
|
|
||||||
import me.kavin.piped.utils.obj.Playlist;
|
|
||||||
import me.kavin.piped.utils.obj.SearchResults;
|
|
||||||
import me.kavin.piped.utils.obj.StreamItem;
|
|
||||||
import me.kavin.piped.utils.obj.Streams;
|
|
||||||
import me.kavin.piped.utils.obj.StreamsPage;
|
|
||||||
import me.kavin.piped.utils.obj.Subtitle;
|
|
||||||
import me.kavin.piped.utils.obj.search.SearchChannel;
|
|
||||||
import me.kavin.piped.utils.obj.search.SearchItem;
|
|
||||||
import me.kavin.piped.utils.obj.search.SearchPlaylist;
|
|
||||||
import me.kavin.piped.utils.obj.search.SearchStream;
|
|
||||||
|
|
||||||
public class ResponseHelper {
|
public class ResponseHelper {
|
||||||
|
|
||||||
public static final LoadingCache<String, CommentsInfo> commentsCache = Caffeine.newBuilder()
|
public static final LoadingCache<String, CommentsInfo> commentsCache = Caffeine.newBuilder()
|
||||||
|
@ -201,13 +192,17 @@ public class ResponseHelper {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final byte[] trendingResponse() throws ParsingException, ExtractionException, IOException {
|
public static final byte[] trendingResponse(String region) throws ParsingException, ExtractionException, IOException {
|
||||||
|
|
||||||
|
region = (region == null || region.isEmpty()) ? "US" : region;
|
||||||
|
|
||||||
final List<StreamItem> relatedStreams = new ObjectArrayList<>();
|
final List<StreamItem> relatedStreams = new ObjectArrayList<>();
|
||||||
|
|
||||||
String url = Constants.YOUTUBE_SERVICE.getKioskList().getListLinkHandlerFactoryByType("Trending")
|
KioskList kioskList = Constants.YOUTUBE_SERVICE.getKioskList();
|
||||||
.getUrl("Trending");
|
kioskList.forceContentCountry(new ContentCountry(region));
|
||||||
KioskInfo info = KioskInfo.getInfo(Constants.YOUTUBE_SERVICE, url);
|
KioskExtractor extractor = kioskList.getDefaultKioskExtractor();
|
||||||
|
extractor.fetchPage();
|
||||||
|
KioskInfo info = KioskInfo.getInfo(extractor);
|
||||||
|
|
||||||
info.getRelatedItems().forEach(o -> {
|
info.getRelatedItems().forEach(o -> {
|
||||||
StreamInfoItem item = o;
|
StreamInfoItem item = o;
|
||||||
|
@ -296,26 +291,26 @@ public class ResponseHelper {
|
||||||
|
|
||||||
info.getRelatedItems().forEach(item -> {
|
info.getRelatedItems().forEach(item -> {
|
||||||
switch (item.getInfoType()) {
|
switch (item.getInfoType()) {
|
||||||
case STREAM:
|
case STREAM:
|
||||||
StreamInfoItem stream = (StreamInfoItem) item;
|
StreamInfoItem stream = (StreamInfoItem) item;
|
||||||
items.add(new SearchStream(item.getName(), rewriteURL(item.getThumbnailUrl()),
|
items.add(new SearchStream(item.getName(), rewriteURL(item.getThumbnailUrl()),
|
||||||
item.getUrl().substring(23), stream.getTextualUploadDate(), stream.getUploaderName(),
|
item.getUrl().substring(23), stream.getTextualUploadDate(), stream.getUploaderName(),
|
||||||
optionalSubstring(stream.getUploaderUrl(), 23), stream.getViewCount(), stream.getDuration(),
|
optionalSubstring(stream.getUploaderUrl(), 23), stream.getViewCount(), stream.getDuration(),
|
||||||
stream.isUploaderVerified()));
|
stream.isUploaderVerified()));
|
||||||
break;
|
break;
|
||||||
case CHANNEL:
|
case CHANNEL:
|
||||||
ChannelInfoItem channel = (ChannelInfoItem) item;
|
ChannelInfoItem channel = (ChannelInfoItem) item;
|
||||||
items.add(new SearchChannel(item.getName(), rewriteURL(item.getThumbnailUrl()),
|
items.add(new SearchChannel(item.getName(), rewriteURL(item.getThumbnailUrl()),
|
||||||
item.getUrl().substring(23), channel.getDescription(), channel.getSubscriberCount(),
|
item.getUrl().substring(23), channel.getDescription(), channel.getSubscriberCount(),
|
||||||
channel.getStreamCount(), channel.isVerified()));
|
channel.getStreamCount(), channel.isVerified()));
|
||||||
break;
|
break;
|
||||||
case PLAYLIST:
|
case PLAYLIST:
|
||||||
PlaylistInfoItem playlist = (PlaylistInfoItem) item;
|
PlaylistInfoItem playlist = (PlaylistInfoItem) item;
|
||||||
items.add(new SearchPlaylist(item.getName(), rewriteURL(item.getThumbnailUrl()),
|
items.add(new SearchPlaylist(item.getName(), rewriteURL(item.getThumbnailUrl()),
|
||||||
item.getUrl().substring(23), playlist.getUploaderName(), playlist.getStreamCount()));
|
item.getUrl().substring(23), playlist.getUploaderName(), playlist.getStreamCount()));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -339,26 +334,26 @@ public class ResponseHelper {
|
||||||
|
|
||||||
pages.getItems().forEach(item -> {
|
pages.getItems().forEach(item -> {
|
||||||
switch (item.getInfoType()) {
|
switch (item.getInfoType()) {
|
||||||
case STREAM:
|
case STREAM:
|
||||||
StreamInfoItem stream = (StreamInfoItem) item;
|
StreamInfoItem stream = (StreamInfoItem) item;
|
||||||
items.add(new SearchStream(item.getName(), rewriteURL(item.getThumbnailUrl()),
|
items.add(new SearchStream(item.getName(), rewriteURL(item.getThumbnailUrl()),
|
||||||
item.getUrl().substring(23), stream.getTextualUploadDate(), stream.getUploaderName(),
|
item.getUrl().substring(23), stream.getTextualUploadDate(), stream.getUploaderName(),
|
||||||
optionalSubstring(stream.getUploaderUrl(), 23), stream.getViewCount(), stream.getDuration(),
|
optionalSubstring(stream.getUploaderUrl(), 23), stream.getViewCount(), stream.getDuration(),
|
||||||
stream.isUploaderVerified()));
|
stream.isUploaderVerified()));
|
||||||
break;
|
break;
|
||||||
case CHANNEL:
|
case CHANNEL:
|
||||||
ChannelInfoItem channel = (ChannelInfoItem) item;
|
ChannelInfoItem channel = (ChannelInfoItem) item;
|
||||||
items.add(new SearchChannel(item.getName(), rewriteURL(item.getThumbnailUrl()),
|
items.add(new SearchChannel(item.getName(), rewriteURL(item.getThumbnailUrl()),
|
||||||
item.getUrl().substring(23), channel.getDescription(), channel.getSubscriberCount(),
|
item.getUrl().substring(23), channel.getDescription(), channel.getSubscriberCount(),
|
||||||
channel.getStreamCount(), channel.isVerified()));
|
channel.getStreamCount(), channel.isVerified()));
|
||||||
break;
|
break;
|
||||||
case PLAYLIST:
|
case PLAYLIST:
|
||||||
PlaylistInfoItem playlist = (PlaylistInfoItem) item;
|
PlaylistInfoItem playlist = (PlaylistInfoItem) item;
|
||||||
items.add(new SearchPlaylist(item.getName(), rewriteURL(item.getThumbnailUrl()),
|
items.add(new SearchPlaylist(item.getName(), rewriteURL(item.getThumbnailUrl()),
|
||||||
item.getUrl().substring(23), playlist.getUploaderName(), playlist.getStreamCount()));
|
item.getUrl().substring(23), playlist.getUploaderName(), playlist.getStreamCount()));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -430,7 +425,7 @@ public class ResponseHelper {
|
||||||
String lbryId = new JSONObject(Constants.h2client.send(HttpRequest
|
String lbryId = new JSONObject(Constants.h2client.send(HttpRequest
|
||||||
.newBuilder(URI.create("https://api.lbry.com/yt/resolve?video_ids=" + URLUtils.silentEncode(videoId)))
|
.newBuilder(URI.create("https://api.lbry.com/yt/resolve?video_ids=" + URLUtils.silentEncode(videoId)))
|
||||||
.setHeader("User-Agent", Constants.USER_AGENT).build(), BodyHandlers.ofString()).body())
|
.setHeader("User-Agent", Constants.USER_AGENT).build(), BodyHandlers.ofString()).body())
|
||||||
.getJSONObject("data").getJSONObject("videos").optString(videoId);
|
.getJSONObject("data").getJSONObject("videos").optString(videoId);
|
||||||
|
|
||||||
if (!lbryId.isEmpty())
|
if (!lbryId.isEmpty())
|
||||||
new JSONObject(Constants.h2client.send(HttpRequest
|
new JSONObject(Constants.h2client.send(HttpRequest
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue