From 66ab5b1e52ae2dccc693cbf1591ae8534a59b3d6 Mon Sep 17 00:00:00 2001 From: SrGooglo Date: Mon, 17 Apr 2023 21:51:43 +0000 Subject: [PATCH] fix tracks & playlists publish --- .../services/getPlaylistsFromFollowing.js | 6 +- .../services/getPlaylistsFromGlobal.js | 6 +- .../src/controllers/FilesController/index.js | 5 +- .../endpoints/publishPlaylist.js | 34 ------- .../endpoints/putPlaylist.js | 90 +++++++++++++++++++ .../endpoints/updatePlaylist.js | 49 ---------- .../services/publishPlaylist.js | 28 ------ .../TracksController/endpoints/getTrack.js | 2 +- .../endpoints/publishTrack.js | 33 ------- .../TracksController/endpoints/putTrack.js | 15 ++++ .../TracksController/endpoints/updateTrack.js | 47 ---------- .../src/controllers/TracksController/index.js | 2 +- .../services/createOrUpdateTrack.js | 43 +++++++++ .../services/getTrackDataById.js | 2 +- packages/server/src/models/playlist/index.js | 35 ++++++-- packages/server/src/models/track/index.js | 17 +++- 16 files changed, 209 insertions(+), 205 deletions(-) delete mode 100755 packages/server/src/controllers/PlaylistsController/endpoints/publishPlaylist.js create mode 100644 packages/server/src/controllers/PlaylistsController/endpoints/putPlaylist.js delete mode 100755 packages/server/src/controllers/PlaylistsController/endpoints/updatePlaylist.js delete mode 100755 packages/server/src/controllers/PlaylistsController/services/publishPlaylist.js delete mode 100755 packages/server/src/controllers/TracksController/endpoints/publishTrack.js create mode 100755 packages/server/src/controllers/TracksController/endpoints/putTrack.js delete mode 100755 packages/server/src/controllers/TracksController/endpoints/updateTrack.js create mode 100644 packages/server/src/controllers/TracksController/services/createOrUpdateTrack.js diff --git a/packages/server/src/controllers/FeedController/services/getPlaylistsFromFollowing.js b/packages/server/src/controllers/FeedController/services/getPlaylistsFromFollowing.js index 74a67eb1..e889e273 100755 --- a/packages/server/src/controllers/FeedController/services/getPlaylistsFromFollowing.js +++ b/packages/server/src/controllers/FeedController/services/getPlaylistsFromFollowing.js @@ -20,8 +20,12 @@ export default async (payload) => { ...followingUserIds, ] + // firter out the playlists that are not public let playlists = await Playlist.find({ - user_id: { $in: fetchFromUserIds } + user_id: { $in: fetchFromUserIds }, + $or: [ + { public: true }, + ] }) .sort({ created_at: -1 }) .limit(limit) diff --git a/packages/server/src/controllers/FeedController/services/getPlaylistsFromGlobal.js b/packages/server/src/controllers/FeedController/services/getPlaylistsFromGlobal.js index e7a85dee..30274995 100644 --- a/packages/server/src/controllers/FeedController/services/getPlaylistsFromGlobal.js +++ b/packages/server/src/controllers/FeedController/services/getPlaylistsFromGlobal.js @@ -7,7 +7,11 @@ export default async (payload) => { skip = 0, } = payload - let playlists = await Playlist.find() + let playlists = await Playlist.find({ + $or: [ + { public: true }, + ] + }) .sort({ created_at: -1 }) .limit(limit) .skip(skip) diff --git a/packages/server/src/controllers/FilesController/index.js b/packages/server/src/controllers/FilesController/index.js index d8ec2106..5354b9da 100755 --- a/packages/server/src/controllers/FilesController/index.js +++ b/packages/server/src/controllers/FilesController/index.js @@ -165,6 +165,8 @@ export default class FilesController extends Controller { }) } + console.log(req.fileResult) + try { // check if mimetype has transformer if (typeof this.fileTransformer[req.fileResult.mimetype] === "function") { @@ -172,8 +174,9 @@ export default class FilesController extends Controller { } } catch (error) { console.log(error) + return res.status(500).json({ - error: "File upload failed", + error: "File upload failed on transformation", reason: error.message, }) } diff --git a/packages/server/src/controllers/PlaylistsController/endpoints/publishPlaylist.js b/packages/server/src/controllers/PlaylistsController/endpoints/publishPlaylist.js deleted file mode 100755 index 74f15915..00000000 --- a/packages/server/src/controllers/PlaylistsController/endpoints/publishPlaylist.js +++ /dev/null @@ -1,34 +0,0 @@ -import { Schematized } from "@lib" - -import publishPlaylist from "../services/publishPlaylist" - -export default { - method: "POST", - route: "/publish", - middlewares: ["withAuthentication"], - fn: Schematized({ - required: ["title", "list"], - select: ["title", "description", "thumbnail", "list"], - }, async (req, res) => { - if (typeof req.body.list === "undefined") { - return res.status(400).json({ - error: "list is required" - }) - } - - const result = await publishPlaylist({ - user_id: req.user._id.toString(), - ...req.selection - }).catch((err) => { - res.status(500).json({ - error: err.message - }) - - return null - }) - - if (result) { - return res.json(result) - } - }) -} \ No newline at end of file diff --git a/packages/server/src/controllers/PlaylistsController/endpoints/putPlaylist.js b/packages/server/src/controllers/PlaylistsController/endpoints/putPlaylist.js new file mode 100644 index 00000000..6bf537aa --- /dev/null +++ b/packages/server/src/controllers/PlaylistsController/endpoints/putPlaylist.js @@ -0,0 +1,90 @@ +import { Schematized } from "@lib" + +import { Playlist } from "@models" + +import createOrUpdateTrack from "../../TracksController/services/createOrUpdateTrack" + +export default { + method: "PUT", + route: "/", + middlewares: ["withAuthentication"], + fn: Schematized({ + required: ["title", "list"], + }, async (req, res) => { + if (!Array.isArray(req.body.list)) { + return res.status(400).json({ + error: "list must be an array" + }) + } + + let trackList = req.body.list + + trackList = await Promise.all(trackList.map(async (track) => { + if (typeof track !== "object") { + return track + } + + track.user_id = req.user._id.toString() + + const result = await createOrUpdateTrack(track) + + if (result) { + return result._id.toString() + } + })) + + let playlist = null + + // check if body._id exists, if it does, update the playlist + // if it doesn't, create a new playlist + if (req.body._id) { + playlist = await Playlist.findById(req.body._id) + + if (!playlist) { + return res.status(404).json({ + error: "playlist not found" + }) + } + + // check if req.user._id is the same as playlist.user_id + if (playlist.user_id !== req.user._id.toString()) { + return res.status(403).json({ + error: "You don't have permission to edit this playlist" + }) + } + + playlist.title = req.body.title + playlist.description = req.body.description + playlist.thumbnail = req.body.thumbnail + playlist.explicit = req.body.explicit + playlist.public = req.body.visibility ? req.body.visibility === "public" : true + playlist.list = trackList + + playlist = await Playlist.findByIdAndUpdate(req.body._id, playlist) + + if (!playlist) { + return res.status(500).json({ + error: "An error occurred while updating the playlist" + }) + } + + global.eventBus.emit(`playlist.${playlist._id}.updated`, playlist) + } else { + playlist = new Playlist({ + user_id: req.user._id.toString(), + created_at: Date.now(), + title: req.body.title ?? "Untitled", + description: req.body.description, + thumbnail: req.body.thumbnail, + explicit: req.body.explicit, + list: trackList, + }) + + await playlist.save() + + // TODO: use custom event + } + + return res.json(playlist) + }) +} \ No newline at end of file diff --git a/packages/server/src/controllers/PlaylistsController/endpoints/updatePlaylist.js b/packages/server/src/controllers/PlaylistsController/endpoints/updatePlaylist.js deleted file mode 100755 index dbbcac27..00000000 --- a/packages/server/src/controllers/PlaylistsController/endpoints/updatePlaylist.js +++ /dev/null @@ -1,49 +0,0 @@ -import { Playlist } from "@models" - -const allowedUpdateFields = [ - "title", - "description", - "thumbnail", - "list", -] - -export default { - method: "PUT", - route: "/:playlist_id", - middlewares: ["withAuthentication"], - fn: async (req, res) => { - const { payload } = req.body - - if (!payload) { - return res.status(400).json({ - message: "Payload is required" - }) - } - - let playlist = await Playlist.findById(req.params.playlist_id).catch((err) => false) - - if (!playlist) { - return res.status(404).json({ - message: "Playlist not found" - }) - } - - // check if the user is the owner of the playlist - if (req.user._id.toString() !== playlist.user_id.toString()) { - return res.status(403).json({ - message: "You are not the owner of this playlist" - }) - } - - console.log(payload) - - // update the playlist - allowedUpdateFields.forEach((key) => { - playlist[key] = payload[key] || playlist[key] - }) - - await playlist.save() - - return res.json(playlist) - } -} \ No newline at end of file diff --git a/packages/server/src/controllers/PlaylistsController/services/publishPlaylist.js b/packages/server/src/controllers/PlaylistsController/services/publishPlaylist.js deleted file mode 100755 index ff9d1698..00000000 --- a/packages/server/src/controllers/PlaylistsController/services/publishPlaylist.js +++ /dev/null @@ -1,28 +0,0 @@ -import { Playlist } from "@models" - -export default async (payload) => { - const { user_id, title, description, thumbnail, list } = payload - - if (!title) { - throw new Error("Title is required") - } - - if (!Array.isArray(list)) { - throw new Error("list is not an array") - } - - const playlist = new Playlist({ - user_id, - created_at: Date.now(), - title: title ?? "Untitled", - description, - thumbnail, - list, - }) - - await playlist.save() - - global.eventBus.emit("playlist.created", playlist) - - return playlist -} \ No newline at end of file diff --git a/packages/server/src/controllers/TracksController/endpoints/getTrack.js b/packages/server/src/controllers/TracksController/endpoints/getTrack.js index 3b27acd7..eb4ae6e5 100755 --- a/packages/server/src/controllers/TracksController/endpoints/getTrack.js +++ b/packages/server/src/controllers/TracksController/endpoints/getTrack.js @@ -1,8 +1,8 @@ import { Track } from "@models" export default { - route: "/:id", method: "GET", + route: "/:id", middlewares: ["withAuthentication"], fn: async (req, res) => { const track = await Track.findById(req.params.id).catch((err) => false) diff --git a/packages/server/src/controllers/TracksController/endpoints/publishTrack.js b/packages/server/src/controllers/TracksController/endpoints/publishTrack.js deleted file mode 100755 index 5c870625..00000000 --- a/packages/server/src/controllers/TracksController/endpoints/publishTrack.js +++ /dev/null @@ -1,33 +0,0 @@ -import { Track } from "@models" - -export default { - method: "POST", - route: "/publish", - middlewares: ["withAuthentication"], - fn: async (req, res) => { - let { - title, - thumbnail, - metadata, - source, - } = req.body - - if (!title || !source) { - return res.status(400).json({ - error: "title and source are required" - }) - } - - const track = new Track({ - user_id: req.user._id.toString(), - title, - thumbnail, - metadata, - source, - }) - - await track.save() - - return res.json(track) - } -} \ No newline at end of file diff --git a/packages/server/src/controllers/TracksController/endpoints/putTrack.js b/packages/server/src/controllers/TracksController/endpoints/putTrack.js new file mode 100755 index 00000000..6c2c8922 --- /dev/null +++ b/packages/server/src/controllers/TracksController/endpoints/putTrack.js @@ -0,0 +1,15 @@ +import createOrUpdateTrack from "../services/createOrUpdateTrack" + +export default { + method: "POST", + route: "/", + middlewares: ["withAuthentication"], + fn: async (req, res) => { + const result = await createOrUpdateTrack({ + user_id: req.user._id.toString(), + ...req.body, + }) + + return res.json(result) + } +} \ No newline at end of file diff --git a/packages/server/src/controllers/TracksController/endpoints/updateTrack.js b/packages/server/src/controllers/TracksController/endpoints/updateTrack.js deleted file mode 100755 index 71ebf039..00000000 --- a/packages/server/src/controllers/TracksController/endpoints/updateTrack.js +++ /dev/null @@ -1,47 +0,0 @@ -import { Track } from "@models" - -const allowedUpdateFields = [ - "title", - "tags", - "thumbnail", - "source", -] - -export default { - method: "PUT", - route: "/:track_id", - middlewares: ["withAuthentication"], - fn: async (req, res) => { - const { payload } = req.body - - if (!payload) { - return res.status(400).json({ - message: "Payload is required" - }) - } - - let track = await Track.findById(req.params.track_id).catch((err) => false) - - if (!track) { - return res.status(404).json({ - message: "Track not found" - }) - } - - // check if the user is the owner of the track - if (req.user._id.toString() !== track.user_id.toString()) { - return res.status(403).json({ - message: "You are not the owner of this track" - }) - } - - // update the track - allowedUpdateFields.forEach((key) => { - track[key] = payload[key] || track[key] - }) - - await track.save() - - return res.json(track) - } -} \ No newline at end of file diff --git a/packages/server/src/controllers/TracksController/index.js b/packages/server/src/controllers/TracksController/index.js index 94795057..76cfbdc4 100755 --- a/packages/server/src/controllers/TracksController/index.js +++ b/packages/server/src/controllers/TracksController/index.js @@ -3,7 +3,7 @@ import generateEndpointsFromDir from "linebridge/dist/server/lib/generateEndpoin export default class TracksController extends Controller { static refName = "TracksController" - static useRoute = "/tracks" + static useRoute = "/track" httpEndpoints = generateEndpointsFromDir(__dirname + "/endpoints") } \ No newline at end of file diff --git a/packages/server/src/controllers/TracksController/services/createOrUpdateTrack.js b/packages/server/src/controllers/TracksController/services/createOrUpdateTrack.js new file mode 100644 index 00000000..9fe13291 --- /dev/null +++ b/packages/server/src/controllers/TracksController/services/createOrUpdateTrack.js @@ -0,0 +1,43 @@ +import { Track } from "@models" + +const allowedUpdateFields = [ + "title", + "thumbnail", + "album", + "artist", + "explicit", +] + +export default async (payload) => { + if (!payload.title || !payload.source || !payload.user_id) { + throw new Error("title and source and user_id are required") + } + + let track = null + + if (payload._id) { + track = await Track.findById(payload._id) + + if (!track) { + throw new Error("track not found") + } + + allowedUpdateFields.forEach((field) => { + if (typeof payload[field] !== "undefined") { + track[field] = payload[field] + } + }) + + track = await Track.findByIdAndUpdate(payload._id, track) + + if (!track) { + throw new Error("Failed to update track") + } + } else { + track = new Track(payload) + + await track.save() + } + + return track +} \ No newline at end of file diff --git a/packages/server/src/controllers/TracksController/services/getTrackDataById.js b/packages/server/src/controllers/TracksController/services/getTrackDataById.js index 5a1b757a..b4c8e973 100755 --- a/packages/server/src/controllers/TracksController/services/getTrackDataById.js +++ b/packages/server/src/controllers/TracksController/services/getTrackDataById.js @@ -19,7 +19,7 @@ export default async (_id) => { const userData = await User.findById(track.user_id).catch((err) => false) - track.artist = track.metadata?.artist ?? userData?.fullName ?? userData?.username ?? "Unknown artist" + track.artist = track.artist ?? userData?.fullName ?? userData?.username ?? "Unknown artist" return track } \ No newline at end of file diff --git a/packages/server/src/models/playlist/index.js b/packages/server/src/models/playlist/index.js index 3c6b344a..db51f78d 100755 --- a/packages/server/src/models/playlist/index.js +++ b/packages/server/src/models/playlist/index.js @@ -2,12 +2,33 @@ export default { name: "Playlist", collection: "playlists", schema: { - user_id: { type: String, required: true }, - created_at: { type: Date, default: Date.now, required: true }, - type: { type: String, default: "track", required: true }, - title: { type: String, required: true }, - description: { type: String }, - thumbnail: { type: String }, - list: { type: Object, default: [], required: true }, + user_id: { + type: String, + required: true + }, + title: { + type: String, + required: true + }, + description: { + type: String + }, + list: { + type: Object, + default: [], + required: true + }, + thumbnail: { + type: String, + default: "https://storage.ragestudio.net/comty-static-assets/default_song.png" + }, + created_at: { + type: Date, + required: true + }, + public: { + type: Boolean, + default: true, + }, } } \ No newline at end of file diff --git a/packages/server/src/models/track/index.js b/packages/server/src/models/track/index.js index d2ba297d..b497b606 100755 --- a/packages/server/src/models/track/index.js +++ b/packages/server/src/models/track/index.js @@ -10,15 +10,30 @@ export default { type: String, required: true, }, + album: { + type: String, + }, + artist: { + type: String, + }, source: { type: String, required: true, }, metadata: { type: Object, - }, + }, + explicit: { + type: Boolean, + default: false, + }, + public: { + type: Boolean, + default: true, + }, thumbnail: { type: String, + default: "https://storage.ragestudio.net/comty-static-assets/default_song.png" }, } } \ No newline at end of file