diff --git a/src/main/java/me/kavin/piped/ServerLauncher.java b/src/main/java/me/kavin/piped/ServerLauncher.java index 4572eda..00120cb 100644 --- a/src/main/java/me/kavin/piped/ServerLauncher.java +++ b/src/main/java/me/kavin/piped/ServerLauncher.java @@ -300,6 +300,15 @@ public class ServerLauncher extends MultithreadedHttpServerLauncher { } catch (Exception e) { return getErrorResponse(e, request.getPath()); } + })).map(POST, "/user/playlists/remove", AsyncServlet.ofBlocking(executor, request -> { + try { + var json = Constants.mapper.readTree(request.loadBody().getResult().asArray()); + var playlistId = json.get("playlistId").asText(); + var index = json.get("index").asInt(); + return getJsonResponse(ResponseHelper.removeFromPlaylistResponse(request.getHeader(AUTHORIZATION), playlistId, index), "private"); + } catch (Exception e) { + return getErrorResponse(e, request.getPath()); + } })).map(GET, "/registered/badge", AsyncServlet.ofBlocking(executor, request -> { try { return HttpResponse.ofCode(302).withHeader(LOCATION, ResponseHelper.registeredBadgeRedirect()) diff --git a/src/main/java/me/kavin/piped/utils/ResponseHelper.java b/src/main/java/me/kavin/piped/utils/ResponseHelper.java index bfb013c..fab5d2c 100644 --- a/src/main/java/me/kavin/piped/utils/ResponseHelper.java +++ b/src/main/java/me/kavin/piped/utils/ResponseHelper.java @@ -296,7 +296,8 @@ public class ResponseHelper { 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.LEFT); + root.fetch("videos") + .fetch("channel", JoinType.LEFT); root.fetch("owner", JoinType.LEFT); cq.select(root); cq.where(cb.equal(root.get("playlist_id"), UUID.fromString(playlistId))); @@ -1072,6 +1073,44 @@ public class ResponseHelper { } } + public static byte[] removeFromPlaylistResponse(String session, String playlistId, int index) throws IOException { + + if (StringUtils.isBlank(playlistId)) + return Constants.mapper.writeValueAsBytes(new InvalidRequestResponse()); + + try (Session s = DatabaseSessionFactory.createSession()) { + 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.LEFT); + root.fetch("owner", JoinType.LEFT); + query.where(cb.equal(root.get("playlist_id"), UUID.fromString(playlistId))); + var playlist = s.createQuery(query).uniqueResult(); + + if (playlist == null) + return Constants.mapper.writeValueAsBytes(Constants.mapper.createObjectNode() + .put("error", "Playlist not found")); + + if (playlist.getOwner().getId() != DatabaseHelper.getUserFromSession(session).getId()) + return Constants.mapper.writeValueAsBytes(Constants.mapper.createObjectNode() + .put("error", "You are not the owner this playlist")); + + if (index < 0 || index >= playlist.getVideos().size()) + return Constants.mapper.writeValueAsBytes(Constants.mapper.createObjectNode() + .put("error", "Video Index out of bounds")); + + playlist.getVideos().remove(index); + + s.update(playlist); + + if (!s.getTransaction().isActive()) + s.getTransaction().begin(); + s.getTransaction().commit(); + + return Constants.mapper.writeValueAsBytes(new AcceptedResponse()); + } + } + public static String registeredBadgeRedirect() { try (Session s = DatabaseSessionFactory.createSession()) { long registered = (Long) s.createQuery("select count(*) from User").uniqueResult(); diff --git a/src/main/java/me/kavin/piped/utils/obj/db/Playlist.java b/src/main/java/me/kavin/piped/utils/obj/db/Playlist.java index 3948c19..5447998 100644 --- a/src/main/java/me/kavin/piped/utils/obj/db/Playlist.java +++ b/src/main/java/me/kavin/piped/utils/obj/db/Playlist.java @@ -43,8 +43,8 @@ public class Playlist { private User owner; @ElementCollection(fetch = FetchType.LAZY) - @OneToMany(targetEntity = PlaylistVideo.class) @Column(name = "videos") + @OrderColumn(name = "videos_order") private List videos; public long getId() { diff --git a/testing/api-test.sh b/testing/api-test.sh index fe17f34..e02703c 100755 --- a/testing/api-test.sh +++ b/testing/api-test.sh @@ -101,3 +101,6 @@ curl ${CURLOPTS[@]} $HOST/playlists/$PLAYLIST_ID || exit 1 # Add to Playlist Test curl ${CURLOPTS[@]} $HOST/user/playlists/add -X POST -H "Content-Type: application/json" -H "Authorization: $AUTH_TOKEN" -d $(jq -n --compact-output --arg videoId "BtN-goy9VOY" --arg playlistId $PLAYLIST_ID '{"videoId": $videoId, "playlistId": $playlistId}') || exit 1 + +# Remove from Playlist Test +curl ${CURLOPTS[@]} $HOST/user/playlists/remove -X POST -H "Content-Type: application/json" -H "Authorization: $AUTH_TOKEN" -d $(jq -n --compact-output --arg index "0" --arg playlistId $PLAYLIST_ID '{"index": $index, "playlistId": $playlistId}') || exit 1