feat(rss feed): add optional query parameter 'filter' ('shorts' or 'videos')

This commit is contained in:
Bnyro 2024-03-15 14:49:02 +01:00
parent 55040de890
commit 30e6bf2a7d
3 changed files with 20 additions and 5 deletions

View File

@ -315,7 +315,8 @@ public class ServerLauncher extends MultithreadedHttpServerLauncher {
} }
})).map(GET, "/feed/rss", AsyncServlet.ofBlocking(executor, request -> { })).map(GET, "/feed/rss", AsyncServlet.ofBlocking(executor, request -> {
try { try {
return getRawResponse(FeedHandlers.feedResponseRSS(request.getQueryParameter("authToken")), return getRawResponse(FeedHandlers.feedResponseRSS(request.getQueryParameter("authToken"),
request.getQueryParameter("filter")),
"application/atom+xml", "public, s-maxage=120"); "application/atom+xml", "public, s-maxage=120");
} catch (Exception e) { } catch (Exception e) {
return getErrorResponse(e, request.getPath()); return getErrorResponse(e, request.getPath());
@ -339,7 +340,8 @@ public class ServerLauncher extends MultithreadedHttpServerLauncher {
})).map(GET, "/feed/unauthenticated/rss", AsyncServlet.ofBlocking(executor, request -> { })).map(GET, "/feed/unauthenticated/rss", AsyncServlet.ofBlocking(executor, request -> {
try { try {
return getRawResponse(FeedHandlers.unauthenticatedFeedResponseRSS( return getRawResponse(FeedHandlers.unauthenticatedFeedResponseRSS(
getArray(request.getQueryParameter("channels")) getArray(request.getQueryParameter("channels")),
request.getQueryParameter("filter")
), "application/atom+xml", "public, s-maxage=120"); ), "application/atom+xml", "public, s-maxage=120");
} catch (Exception e) { } catch (Exception e) {
return getErrorResponse(e, request.getPath()); return getErrorResponse(e, request.getPath());

View File

@ -21,6 +21,7 @@ import org.hibernate.Session;
import org.hibernate.StatelessSession; import org.hibernate.StatelessSession;
import org.schabi.newpipe.extractor.channel.ChannelInfo; import org.schabi.newpipe.extractor.channel.ChannelInfo;
import javax.annotation.Nullable;
import java.io.IOException; import java.io.IOException;
import java.util.*; import java.util.*;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -119,7 +120,7 @@ public class FeedHandlers {
return null; return null;
} }
public static byte[] feedResponseRSS(String session) throws FeedException { public static byte[] feedResponseRSS(String session, @Nullable String filter) throws FeedException {
if (StringUtils.isBlank(session)) if (StringUtils.isBlank(session))
ExceptionHandler.throwErrorResponse(new InvalidRequestResponse("session is a required parameter")); ExceptionHandler.throwErrorResponse(new InvalidRequestResponse("session is a required parameter"));
@ -131,6 +132,7 @@ public class FeedHandlers {
SyndFeed feed = FeedHelpers.createRssFeed(user.getUsername()); SyndFeed feed = FeedHelpers.createRssFeed(user.getUsername());
final List<SyndEntry> entries = FeedHelpers.generateAuthenticatedFeed(s, user.getId(), 100) final List<SyndEntry> entries = FeedHelpers.generateAuthenticatedFeed(s, user.getId(), 100)
.filter(FeedHelpers.createFeedFilter(filter))
.map(video -> { .map(video -> {
var channel = video.getChannel(); var channel = video.getChannel();
return ChannelHelpers.createEntry(video, channel); return ChannelHelpers.createEntry(video, channel);
@ -173,7 +175,7 @@ public class FeedHandlers {
} }
} }
public static byte[] unauthenticatedFeedResponseRSS(String[] channelIds) throws Exception { public static byte[] unauthenticatedFeedResponseRSS(String[] channelIds, @Nullable String filter) throws Exception {
Set<String> filteredChannels = Arrays.stream(channelIds) Set<String> filteredChannels = Arrays.stream(channelIds)
.filter(ChannelHelpers::isValidId) .filter(ChannelHelpers::isValidId)
@ -183,7 +185,9 @@ public class FeedHandlers {
ExceptionHandler.throwErrorResponse(new InvalidRequestResponse("No valid channel IDs provided")); ExceptionHandler.throwErrorResponse(new InvalidRequestResponse("No valid channel IDs provided"));
try (StatelessSession s = DatabaseSessionFactory.createStatelessSession()) { try (StatelessSession s = DatabaseSessionFactory.createStatelessSession()) {
List<Video> videos = FeedHelpers.generateUnauthenticatedFeed(s, filteredChannels, 100).toList(); List<Video> videos = FeedHelpers.generateUnauthenticatedFeed(s, filteredChannels, 100)
.filter(FeedHelpers.createFeedFilter(filter))
.toList();
List<SyndEntry> entries = videos.stream() List<SyndEntry> entries = videos.stream()
.map(video -> ChannelHelpers.createEntry(video, video.getChannel())) .map(video -> ChannelHelpers.createEntry(video, video.getChannel()))

View File

@ -16,6 +16,7 @@ import javax.annotation.Nullable;
import java.util.Comparator; import java.util.Comparator;
import java.util.Date; import java.util.Date;
import java.util.Set; import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Stream; import java.util.stream.Stream;
import static me.kavin.piped.utils.URLUtils.rewriteURL; import static me.kavin.piped.utils.URLUtils.rewriteURL;
@ -79,6 +80,14 @@ public class FeedHelpers {
return feed; return feed;
} }
public static Predicate<Video> createFeedFilter(@Nullable String filter) {
return video -> switch (filter) {
case "shorts" -> video.isShort();
case "videos" -> !video.isShort();
case null, default -> true;
};
}
public static Stream<SubscriptionChannel> generateSubscriptionsList(Stream<Channel> channels) { public static Stream<SubscriptionChannel> generateSubscriptionsList(Stream<Channel> channels) {
return channels.parallel() return channels.parallel()
.filter(channel -> channel.getUploader() != null) .filter(channel -> channel.getUploader() != null)