mirror of
https://github.com/TeamPiped/Piped-Backend.git
synced 2024-08-14 23:51:41 +00:00
Speed up playlists and fix adding videos on empty playlists.
This commit is contained in:
parent
99fcaf8733
commit
adfc0850ed
3 changed files with 47 additions and 30 deletions
|
@ -34,7 +34,7 @@ import static me.kavin.piped.utils.URLUtils.rewriteURL;
|
|||
import static me.kavin.piped.utils.URLUtils.substringYouTube;
|
||||
|
||||
public class PlaylistHandlers {
|
||||
public static byte[] playlistResponse(String playlistId) throws ExtractionException, IOException {
|
||||
public static byte[] playlistResponse(String playlistId) throws Exception {
|
||||
|
||||
if (StringUtils.isBlank(playlistId))
|
||||
ExceptionHandler.throwErrorResponse(new InvalidRequestResponse("playlistId is a required parameter"));
|
||||
|
@ -98,7 +98,7 @@ public class PlaylistHandlers {
|
|||
|
||||
}
|
||||
|
||||
public static byte[] playlistRSSResponse(String playlistId) throws ExtractionException, IOException, FeedException {
|
||||
public static byte[] playlistRSSResponse(String playlistId) throws Exception {
|
||||
|
||||
if (StringUtils.isBlank(playlistId))
|
||||
ExceptionHandler.throwErrorResponse(new InvalidRequestResponse("playlistId is a required parameter"));
|
||||
|
|
|
@ -5,16 +5,12 @@ import com.rometools.rome.feed.synd.SyndEntry;
|
|||
import com.rometools.rome.feed.synd.SyndEntryImpl;
|
||||
import com.rometools.rome.feed.synd.SyndFeed;
|
||||
import com.rometools.rome.feed.synd.SyndFeedImpl;
|
||||
import com.rometools.rome.io.FeedException;
|
||||
import com.rometools.rome.io.SyndFeedOutput;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import jakarta.persistence.criteria.JoinType;
|
||||
import me.kavin.piped.consts.Constants;
|
||||
import me.kavin.piped.utils.DatabaseHelper;
|
||||
import me.kavin.piped.utils.DatabaseSessionFactory;
|
||||
import me.kavin.piped.utils.ExceptionHandler;
|
||||
import me.kavin.piped.utils.URLUtils;
|
||||
import me.kavin.piped.utils.*;
|
||||
import me.kavin.piped.utils.obj.ContentItem;
|
||||
import me.kavin.piped.utils.obj.Playlist;
|
||||
import me.kavin.piped.utils.obj.StreamItem;
|
||||
|
@ -43,21 +39,17 @@ import static me.kavin.piped.utils.URLUtils.rewriteURL;
|
|||
import static me.kavin.piped.utils.URLUtils.substringYouTube;
|
||||
|
||||
public class AuthPlaylistHandlers {
|
||||
public static byte[] playlistPipedResponse(String playlistId) throws IOException {
|
||||
public static byte[] playlistPipedResponse(String playlistId) throws Exception {
|
||||
|
||||
if (StringUtils.isBlank(playlistId))
|
||||
ExceptionHandler.throwErrorResponse(new InvalidRequestResponse("playlistId is a required parameter"));
|
||||
|
||||
try (Session s = DatabaseSessionFactory.createSession()) {
|
||||
var cb = s.getCriteriaBuilder();
|
||||
var cq = cb.createQuery(me.kavin.piped.utils.obj.db.Playlist.class);
|
||||
var root = cq.from(me.kavin.piped.utils.obj.db.Playlist.class);
|
||||
root.fetch("videos", JoinType.RIGHT)
|
||||
.fetch("channel", JoinType.INNER);
|
||||
cq.select(root);
|
||||
cq.where(cb.equal(root.get("playlist_id"), UUID.fromString(playlistId)));
|
||||
var query = s.createQuery(cq);
|
||||
var pl = query.uniqueResult();
|
||||
|
||||
var playlistCompletableFuture = Multithreading.supplyAsync(() -> DatabaseHelper.getPlaylistFromId(s, playlistId));
|
||||
var playlistVideosCompletableFuture = Multithreading.supplyAsync(() -> DatabaseHelper.getPlaylistVideosFromPlaylistId(playlistId, true));
|
||||
|
||||
var pl = playlistCompletableFuture.get();
|
||||
|
||||
if (pl == null)
|
||||
return mapper.writeValueAsBytes(mapper.createObjectNode()
|
||||
|
@ -65,7 +57,7 @@ public class AuthPlaylistHandlers {
|
|||
|
||||
final List<ContentItem> relatedStreams = new ObjectArrayList<>();
|
||||
|
||||
var videos = pl.getVideos();
|
||||
var videos = playlistVideosCompletableFuture.get();
|
||||
|
||||
for (var video : videos) {
|
||||
var channel = video.getChannel();
|
||||
|
@ -82,21 +74,16 @@ public class AuthPlaylistHandlers {
|
|||
}
|
||||
|
||||
public static byte[] playlistPipedRSSResponse(String playlistId)
|
||||
throws FeedException {
|
||||
throws Exception {
|
||||
|
||||
if (StringUtils.isBlank(playlistId))
|
||||
ExceptionHandler.throwErrorResponse(new InvalidRequestResponse("playlistId is required parameter"));
|
||||
|
||||
try (Session s = DatabaseSessionFactory.createSession()) {
|
||||
var cb = s.getCriteriaBuilder();
|
||||
var cq = cb.createQuery(me.kavin.piped.utils.obj.db.Playlist.class);
|
||||
var root = cq.from(me.kavin.piped.utils.obj.db.Playlist.class);
|
||||
root.fetch("videos", JoinType.RIGHT)
|
||||
.fetch("channel", JoinType.INNER);
|
||||
cq.select(root);
|
||||
cq.where(cb.equal(root.get("playlist_id"), UUID.fromString(playlistId)));
|
||||
var query = s.createQuery(cq);
|
||||
var pl = query.uniqueResult();
|
||||
var playlistCompletableFuture = Multithreading.supplyAsync(() -> DatabaseHelper.getPlaylistFromId(s, playlistId));
|
||||
var playlistVideosCompletableFuture = Multithreading.supplyAsync(() -> DatabaseHelper.getPlaylistVideosFromPlaylistId(playlistId, true));
|
||||
|
||||
var pl = playlistCompletableFuture.get();
|
||||
|
||||
final List<SyndEntry> entries = new ObjectArrayList<>();
|
||||
|
||||
|
@ -108,7 +95,9 @@ public class AuthPlaylistHandlers {
|
|||
feed.setLink(Constants.FRONTEND_URL + "/playlist?list=" + pl.getPlaylistId());
|
||||
feed.setPublishedDate(new Date());
|
||||
|
||||
for (var video : pl.getVideos()) {
|
||||
var videos = playlistVideosCompletableFuture.get();
|
||||
|
||||
for (var video : videos) {
|
||||
SyndEntry entry = new SyndEntryImpl();
|
||||
entry.setAuthor(video.getChannel().getUploader());
|
||||
entry.setLink(Constants.FRONTEND_URL + "/video?id=" + video.getId());
|
||||
|
@ -223,7 +212,6 @@ public class AuthPlaylistHandlers {
|
|||
var cb = s.getCriteriaBuilder();
|
||||
var query = cb.createQuery(me.kavin.piped.utils.obj.db.Playlist.class);
|
||||
var root = query.from(me.kavin.piped.utils.obj.db.Playlist.class);
|
||||
root.fetch("videos", JoinType.RIGHT);
|
||||
query.where(cb.equal(root.get("playlist_id"), UUID.fromString(playlistId)));
|
||||
var playlist = s.createQuery(query).uniqueResult();
|
||||
|
||||
|
|
|
@ -123,6 +123,12 @@ public class DatabaseHelper {
|
|||
return s.createQuery(cr).uniqueResult();
|
||||
}
|
||||
|
||||
public static Playlist getPlaylistFromId(String id) {
|
||||
try (StatelessSession s = DatabaseSessionFactory.createStatelessSession()) {
|
||||
return getPlaylistFromId(s, id);
|
||||
}
|
||||
}
|
||||
|
||||
public static List<PlaylistVideo> getPlaylistVideosFromIds(SharedSessionContract s, Collection<String> id) {
|
||||
CriteriaBuilder cb = s.getCriteriaBuilder();
|
||||
CriteriaQuery<PlaylistVideo> cr = cb.createQuery(PlaylistVideo.class);
|
||||
|
@ -132,6 +138,29 @@ public class DatabaseHelper {
|
|||
return s.createQuery(cr).list();
|
||||
}
|
||||
|
||||
public static List<PlaylistVideo> getPlaylistVideosFromPlaylistId(SharedSessionContract s, String id, boolean fetchChannel) {
|
||||
CriteriaBuilder cb = s.getCriteriaBuilder();
|
||||
CriteriaQuery<PlaylistVideo> cr = cb.createQuery(PlaylistVideo.class);
|
||||
var root = cr.from(PlaylistVideo.class);
|
||||
root.fetch("channel", JoinType.RIGHT);
|
||||
cr.select(root);
|
||||
var sq = cr.subquery(String.class);
|
||||
{
|
||||
var sqRoot = sq.from(Playlist.class);
|
||||
sq.select(sqRoot.get("videos").get("id"))
|
||||
.where(cb.equal(sqRoot.get("playlist_id"), UUID.fromString(id)));
|
||||
}
|
||||
cr.where(cb.equal(root.get("id"), sq));
|
||||
|
||||
return s.createQuery(cr).list();
|
||||
}
|
||||
|
||||
public static List<PlaylistVideo> getPlaylistVideosFromPlaylistId(String id, boolean fetchChannel) {
|
||||
try (StatelessSession s = DatabaseSessionFactory.createStatelessSession()) {
|
||||
return getPlaylistVideosFromPlaylistId(s, id, fetchChannel);
|
||||
}
|
||||
}
|
||||
|
||||
public static PubSub getPubSubFromId(SharedSessionContract s, String id) {
|
||||
CriteriaBuilder cb = s.getCriteriaBuilder();
|
||||
CriteriaQuery<PubSub> cr = cb.createQuery(PubSub.class);
|
||||
|
|
Loading…
Reference in a new issue