mirror of
https://github.com/ragestudio/comty.git
synced 2025-06-10 19:14:16 +00:00
fix tracks & playlists publish
This commit is contained in:
parent
90b2583c79
commit
66ab5b1e52
@ -20,8 +20,12 @@ export default async (payload) => {
|
|||||||
...followingUserIds,
|
...followingUserIds,
|
||||||
]
|
]
|
||||||
|
|
||||||
|
// firter out the playlists that are not public
|
||||||
let playlists = await Playlist.find({
|
let playlists = await Playlist.find({
|
||||||
user_id: { $in: fetchFromUserIds }
|
user_id: { $in: fetchFromUserIds },
|
||||||
|
$or: [
|
||||||
|
{ public: true },
|
||||||
|
]
|
||||||
})
|
})
|
||||||
.sort({ created_at: -1 })
|
.sort({ created_at: -1 })
|
||||||
.limit(limit)
|
.limit(limit)
|
||||||
|
@ -7,7 +7,11 @@ export default async (payload) => {
|
|||||||
skip = 0,
|
skip = 0,
|
||||||
} = payload
|
} = payload
|
||||||
|
|
||||||
let playlists = await Playlist.find()
|
let playlists = await Playlist.find({
|
||||||
|
$or: [
|
||||||
|
{ public: true },
|
||||||
|
]
|
||||||
|
})
|
||||||
.sort({ created_at: -1 })
|
.sort({ created_at: -1 })
|
||||||
.limit(limit)
|
.limit(limit)
|
||||||
.skip(skip)
|
.skip(skip)
|
||||||
|
@ -165,6 +165,8 @@ export default class FilesController extends Controller {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log(req.fileResult)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// check if mimetype has transformer
|
// check if mimetype has transformer
|
||||||
if (typeof this.fileTransformer[req.fileResult.mimetype] === "function") {
|
if (typeof this.fileTransformer[req.fileResult.mimetype] === "function") {
|
||||||
@ -172,8 +174,9 @@ export default class FilesController extends Controller {
|
|||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error)
|
console.log(error)
|
||||||
|
|
||||||
return res.status(500).json({
|
return res.status(500).json({
|
||||||
error: "File upload failed",
|
error: "File upload failed on transformation",
|
||||||
reason: error.message,
|
reason: error.message,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -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)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
@ -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)
|
||||||
|
})
|
||||||
|
}
|
@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
@ -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
|
|
||||||
}
|
|
@ -1,8 +1,8 @@
|
|||||||
import { Track } from "@models"
|
import { Track } from "@models"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
route: "/:id",
|
|
||||||
method: "GET",
|
method: "GET",
|
||||||
|
route: "/:id",
|
||||||
middlewares: ["withAuthentication"],
|
middlewares: ["withAuthentication"],
|
||||||
fn: async (req, res) => {
|
fn: async (req, res) => {
|
||||||
const track = await Track.findById(req.params.id).catch((err) => false)
|
const track = await Track.findById(req.params.id).catch((err) => false)
|
||||||
|
@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
15
packages/server/src/controllers/TracksController/endpoints/putTrack.js
Executable file
15
packages/server/src/controllers/TracksController/endpoints/putTrack.js
Executable file
@ -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)
|
||||||
|
}
|
||||||
|
}
|
@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
@ -3,7 +3,7 @@ import generateEndpointsFromDir from "linebridge/dist/server/lib/generateEndpoin
|
|||||||
|
|
||||||
export default class TracksController extends Controller {
|
export default class TracksController extends Controller {
|
||||||
static refName = "TracksController"
|
static refName = "TracksController"
|
||||||
static useRoute = "/tracks"
|
static useRoute = "/track"
|
||||||
|
|
||||||
httpEndpoints = generateEndpointsFromDir(__dirname + "/endpoints")
|
httpEndpoints = generateEndpointsFromDir(__dirname + "/endpoints")
|
||||||
}
|
}
|
@ -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
|
||||||
|
}
|
@ -19,7 +19,7 @@ export default async (_id) => {
|
|||||||
|
|
||||||
const userData = await User.findById(track.user_id).catch((err) => false)
|
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
|
return track
|
||||||
}
|
}
|
@ -2,12 +2,33 @@ export default {
|
|||||||
name: "Playlist",
|
name: "Playlist",
|
||||||
collection: "playlists",
|
collection: "playlists",
|
||||||
schema: {
|
schema: {
|
||||||
user_id: { type: String, required: true },
|
user_id: {
|
||||||
created_at: { type: Date, default: Date.now, required: true },
|
type: String,
|
||||||
type: { type: String, default: "track", required: true },
|
required: true
|
||||||
title: { type: String, required: true },
|
},
|
||||||
description: { type: String },
|
title: {
|
||||||
thumbnail: { type: String },
|
type: String,
|
||||||
list: { type: Object, default: [], required: true },
|
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,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -10,15 +10,30 @@ export default {
|
|||||||
type: String,
|
type: String,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
|
album: {
|
||||||
|
type: String,
|
||||||
|
},
|
||||||
|
artist: {
|
||||||
|
type: String,
|
||||||
|
},
|
||||||
source: {
|
source: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
metadata: {
|
metadata: {
|
||||||
type: Object,
|
type: Object,
|
||||||
},
|
},
|
||||||
|
explicit: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
public: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
thumbnail: {
|
thumbnail: {
|
||||||
type: String,
|
type: String,
|
||||||
|
default: "https://storage.ragestudio.net/comty-static-assets/default_song.png"
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user