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;
|
import static me.kavin.piped.utils.URLUtils.substringYouTube;
|
||||||
|
|
||||||
public class PlaylistHandlers {
|
public class PlaylistHandlers {
|
||||||
public static byte[] playlistResponse(String playlistId) throws ExtractionException, IOException {
|
public static byte[] playlistResponse(String playlistId) throws Exception {
|
||||||
|
|
||||||
if (StringUtils.isBlank(playlistId))
|
if (StringUtils.isBlank(playlistId))
|
||||||
ExceptionHandler.throwErrorResponse(new InvalidRequestResponse("playlistId is a required parameter"));
|
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))
|
if (StringUtils.isBlank(playlistId))
|
||||||
ExceptionHandler.throwErrorResponse(new InvalidRequestResponse("playlistId is a required parameter"));
|
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.SyndEntryImpl;
|
||||||
import com.rometools.rome.feed.synd.SyndFeed;
|
import com.rometools.rome.feed.synd.SyndFeed;
|
||||||
import com.rometools.rome.feed.synd.SyndFeedImpl;
|
import com.rometools.rome.feed.synd.SyndFeedImpl;
|
||||||
import com.rometools.rome.io.FeedException;
|
|
||||||
import com.rometools.rome.io.SyndFeedOutput;
|
import com.rometools.rome.io.SyndFeedOutput;
|
||||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||||
import jakarta.persistence.criteria.JoinType;
|
import jakarta.persistence.criteria.JoinType;
|
||||||
import me.kavin.piped.consts.Constants;
|
import me.kavin.piped.consts.Constants;
|
||||||
import me.kavin.piped.utils.DatabaseHelper;
|
import me.kavin.piped.utils.*;
|
||||||
import me.kavin.piped.utils.DatabaseSessionFactory;
|
|
||||||
import me.kavin.piped.utils.ExceptionHandler;
|
|
||||||
import me.kavin.piped.utils.URLUtils;
|
|
||||||
import me.kavin.piped.utils.obj.ContentItem;
|
import me.kavin.piped.utils.obj.ContentItem;
|
||||||
import me.kavin.piped.utils.obj.Playlist;
|
import me.kavin.piped.utils.obj.Playlist;
|
||||||
import me.kavin.piped.utils.obj.StreamItem;
|
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;
|
import static me.kavin.piped.utils.URLUtils.substringYouTube;
|
||||||
|
|
||||||
public class AuthPlaylistHandlers {
|
public class AuthPlaylistHandlers {
|
||||||
public static byte[] playlistPipedResponse(String playlistId) throws IOException {
|
public static byte[] playlistPipedResponse(String playlistId) throws Exception {
|
||||||
|
|
||||||
if (StringUtils.isBlank(playlistId))
|
if (StringUtils.isBlank(playlistId))
|
||||||
ExceptionHandler.throwErrorResponse(new InvalidRequestResponse("playlistId is a required parameter"));
|
ExceptionHandler.throwErrorResponse(new InvalidRequestResponse("playlistId is a required parameter"));
|
||||||
|
|
||||||
try (Session s = DatabaseSessionFactory.createSession()) {
|
try (Session s = DatabaseSessionFactory.createSession()) {
|
||||||
var cb = s.getCriteriaBuilder();
|
|
||||||
var cq = cb.createQuery(me.kavin.piped.utils.obj.db.Playlist.class);
|
var playlistCompletableFuture = Multithreading.supplyAsync(() -> DatabaseHelper.getPlaylistFromId(s, playlistId));
|
||||||
var root = cq.from(me.kavin.piped.utils.obj.db.Playlist.class);
|
var playlistVideosCompletableFuture = Multithreading.supplyAsync(() -> DatabaseHelper.getPlaylistVideosFromPlaylistId(playlistId, true));
|
||||||
root.fetch("videos", JoinType.RIGHT)
|
|
||||||
.fetch("channel", JoinType.INNER);
|
var pl = playlistCompletableFuture.get();
|
||||||
cq.select(root);
|
|
||||||
cq.where(cb.equal(root.get("playlist_id"), UUID.fromString(playlistId)));
|
|
||||||
var query = s.createQuery(cq);
|
|
||||||
var pl = query.uniqueResult();
|
|
||||||
|
|
||||||
if (pl == null)
|
if (pl == null)
|
||||||
return mapper.writeValueAsBytes(mapper.createObjectNode()
|
return mapper.writeValueAsBytes(mapper.createObjectNode()
|
||||||
|
@ -65,7 +57,7 @@ public class AuthPlaylistHandlers {
|
||||||
|
|
||||||
final List<ContentItem> relatedStreams = new ObjectArrayList<>();
|
final List<ContentItem> relatedStreams = new ObjectArrayList<>();
|
||||||
|
|
||||||
var videos = pl.getVideos();
|
var videos = playlistVideosCompletableFuture.get();
|
||||||
|
|
||||||
for (var video : videos) {
|
for (var video : videos) {
|
||||||
var channel = video.getChannel();
|
var channel = video.getChannel();
|
||||||
|
@ -82,21 +74,16 @@ public class AuthPlaylistHandlers {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] playlistPipedRSSResponse(String playlistId)
|
public static byte[] playlistPipedRSSResponse(String playlistId)
|
||||||
throws FeedException {
|
throws Exception {
|
||||||
|
|
||||||
if (StringUtils.isBlank(playlistId))
|
if (StringUtils.isBlank(playlistId))
|
||||||
ExceptionHandler.throwErrorResponse(new InvalidRequestResponse("playlistId is required parameter"));
|
ExceptionHandler.throwErrorResponse(new InvalidRequestResponse("playlistId is required parameter"));
|
||||||
|
|
||||||
try (Session s = DatabaseSessionFactory.createSession()) {
|
try (Session s = DatabaseSessionFactory.createSession()) {
|
||||||
var cb = s.getCriteriaBuilder();
|
var playlistCompletableFuture = Multithreading.supplyAsync(() -> DatabaseHelper.getPlaylistFromId(s, playlistId));
|
||||||
var cq = cb.createQuery(me.kavin.piped.utils.obj.db.Playlist.class);
|
var playlistVideosCompletableFuture = Multithreading.supplyAsync(() -> DatabaseHelper.getPlaylistVideosFromPlaylistId(playlistId, true));
|
||||||
var root = cq.from(me.kavin.piped.utils.obj.db.Playlist.class);
|
|
||||||
root.fetch("videos", JoinType.RIGHT)
|
var pl = playlistCompletableFuture.get();
|
||||||
.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();
|
|
||||||
|
|
||||||
final List<SyndEntry> entries = new ObjectArrayList<>();
|
final List<SyndEntry> entries = new ObjectArrayList<>();
|
||||||
|
|
||||||
|
@ -108,7 +95,9 @@ public class AuthPlaylistHandlers {
|
||||||
feed.setLink(Constants.FRONTEND_URL + "/playlist?list=" + pl.getPlaylistId());
|
feed.setLink(Constants.FRONTEND_URL + "/playlist?list=" + pl.getPlaylistId());
|
||||||
feed.setPublishedDate(new Date());
|
feed.setPublishedDate(new Date());
|
||||||
|
|
||||||
for (var video : pl.getVideos()) {
|
var videos = playlistVideosCompletableFuture.get();
|
||||||
|
|
||||||
|
for (var video : videos) {
|
||||||
SyndEntry entry = new SyndEntryImpl();
|
SyndEntry entry = new SyndEntryImpl();
|
||||||
entry.setAuthor(video.getChannel().getUploader());
|
entry.setAuthor(video.getChannel().getUploader());
|
||||||
entry.setLink(Constants.FRONTEND_URL + "/video?id=" + video.getId());
|
entry.setLink(Constants.FRONTEND_URL + "/video?id=" + video.getId());
|
||||||
|
@ -223,7 +212,6 @@ public class AuthPlaylistHandlers {
|
||||||
var cb = s.getCriteriaBuilder();
|
var cb = s.getCriteriaBuilder();
|
||||||
var query = cb.createQuery(me.kavin.piped.utils.obj.db.Playlist.class);
|
var query = cb.createQuery(me.kavin.piped.utils.obj.db.Playlist.class);
|
||||||
var root = query.from(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)));
|
query.where(cb.equal(root.get("playlist_id"), UUID.fromString(playlistId)));
|
||||||
var playlist = s.createQuery(query).uniqueResult();
|
var playlist = s.createQuery(query).uniqueResult();
|
||||||
|
|
||||||
|
|
|
@ -123,6 +123,12 @@ public class DatabaseHelper {
|
||||||
return s.createQuery(cr).uniqueResult();
|
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) {
|
public static List<PlaylistVideo> getPlaylistVideosFromIds(SharedSessionContract s, Collection<String> id) {
|
||||||
CriteriaBuilder cb = s.getCriteriaBuilder();
|
CriteriaBuilder cb = s.getCriteriaBuilder();
|
||||||
CriteriaQuery<PlaylistVideo> cr = cb.createQuery(PlaylistVideo.class);
|
CriteriaQuery<PlaylistVideo> cr = cb.createQuery(PlaylistVideo.class);
|
||||||
|
@ -132,6 +138,29 @@ public class DatabaseHelper {
|
||||||
return s.createQuery(cr).list();
|
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) {
|
public static PubSub getPubSubFromId(SharedSessionContract s, String id) {
|
||||||
CriteriaBuilder cb = s.getCriteriaBuilder();
|
CriteriaBuilder cb = s.getCriteriaBuilder();
|
||||||
CriteriaQuery<PubSub> cr = cb.createQuery(PubSub.class);
|
CriteriaQuery<PubSub> cr = cb.createQuery(PubSub.class);
|
||||||
|
|
Loading…
Reference in a new issue