|
@@ -1,7 +1,8 @@
|
|
|
import async from "async";
|
|
|
import config from "config";
|
|
|
|
|
|
-import { isAdminRequired, isLoginRequired } from "./hooks";
|
|
|
+import isLoginRequired from "../hooks/loginRequired";
|
|
|
+import { hasPermission, useHasPermission } from "../hooks/hasPermission";
|
|
|
|
|
|
// eslint-disable-next-line
|
|
|
import moduleManager from "../../index";
|
|
@@ -275,107 +276,112 @@ export default {
|
|
|
* @param operator - the operator for queries
|
|
|
* @param cb
|
|
|
*/
|
|
|
- getData: isAdminRequired(async function getSet(session, page, pageSize, properties, sort, queries, operator, cb) {
|
|
|
- async.waterfall(
|
|
|
- [
|
|
|
- next => {
|
|
|
- DBModule.runJob(
|
|
|
- "GET_DATA",
|
|
|
- {
|
|
|
- page,
|
|
|
- pageSize,
|
|
|
- properties,
|
|
|
- sort,
|
|
|
- queries,
|
|
|
- operator,
|
|
|
- modelName: "playlist",
|
|
|
- blacklistedProperties: [],
|
|
|
- specialProperties: {
|
|
|
- totalLength: [
|
|
|
- {
|
|
|
- $addFields: {
|
|
|
- totalLength: { $sum: "$songs.duration" }
|
|
|
+ getData: useHasPermission(
|
|
|
+ "admin.view.playlists",
|
|
|
+ async function getSet(session, page, pageSize, properties, sort, queries, operator, cb) {
|
|
|
+ async.waterfall(
|
|
|
+ [
|
|
|
+ next => {
|
|
|
+ DBModule.runJob(
|
|
|
+ "GET_DATA",
|
|
|
+ {
|
|
|
+ page,
|
|
|
+ pageSize,
|
|
|
+ properties,
|
|
|
+ sort,
|
|
|
+ queries,
|
|
|
+ operator,
|
|
|
+ modelName: "playlist",
|
|
|
+ blacklistedProperties: [],
|
|
|
+ specialProperties: {
|
|
|
+ totalLength: [
|
|
|
+ {
|
|
|
+ $addFields: {
|
|
|
+ totalLength: { $sum: "$songs.duration" }
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
- ],
|
|
|
- songsCount: [
|
|
|
- {
|
|
|
- $addFields: {
|
|
|
- songsCount: { $size: "$songs" }
|
|
|
+ ],
|
|
|
+ songsCount: [
|
|
|
+ {
|
|
|
+ $addFields: {
|
|
|
+ songsCount: { $size: "$songs" }
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
- ],
|
|
|
- createdBy: [
|
|
|
- {
|
|
|
- $addFields: {
|
|
|
- createdByOID: {
|
|
|
- $convert: {
|
|
|
- input: "$createdBy",
|
|
|
- to: "objectId",
|
|
|
- onError: "unknown",
|
|
|
- onNull: "unknown"
|
|
|
+ ],
|
|
|
+ createdBy: [
|
|
|
+ {
|
|
|
+ $addFields: {
|
|
|
+ createdByOID: {
|
|
|
+ $convert: {
|
|
|
+ input: "$createdBy",
|
|
|
+ to: "objectId",
|
|
|
+ onError: "unknown",
|
|
|
+ onNull: "unknown"
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
- }
|
|
|
- },
|
|
|
- {
|
|
|
- $lookup: {
|
|
|
- from: "users",
|
|
|
- localField: "createdByOID",
|
|
|
- foreignField: "_id",
|
|
|
- as: "createdByUser"
|
|
|
- }
|
|
|
- },
|
|
|
- {
|
|
|
- $unwind: {
|
|
|
- path: "$createdByUser",
|
|
|
- preserveNullAndEmptyArrays: true
|
|
|
- }
|
|
|
- },
|
|
|
- {
|
|
|
- $addFields: {
|
|
|
- createdByUsername: {
|
|
|
- $cond: [
|
|
|
- { $eq: ["$createdBy", "Musare"] },
|
|
|
- "Musare",
|
|
|
- { $ifNull: ["$createdByUser.username", "unknown"] }
|
|
|
- ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ $lookup: {
|
|
|
+ from: "users",
|
|
|
+ localField: "createdByOID",
|
|
|
+ foreignField: "_id",
|
|
|
+ as: "createdByUser"
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ $unwind: {
|
|
|
+ path: "$createdByUser",
|
|
|
+ preserveNullAndEmptyArrays: true
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ $addFields: {
|
|
|
+ createdByUsername: {
|
|
|
+ $cond: [
|
|
|
+ { $eq: ["$createdBy", "Musare"] },
|
|
|
+ "Musare",
|
|
|
+ { $ifNull: ["$createdByUser.username", "unknown"] }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ $project: {
|
|
|
+ createdByOID: 0,
|
|
|
+ createdByUser: 0
|
|
|
}
|
|
|
}
|
|
|
- },
|
|
|
- {
|
|
|
- $project: {
|
|
|
- createdByOID: 0,
|
|
|
- createdByUser: 0
|
|
|
- }
|
|
|
- }
|
|
|
- ]
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ specialQueries: {
|
|
|
+ createdBy: newQuery => ({
|
|
|
+ $or: [newQuery, { createdByUsername: newQuery.createdBy }]
|
|
|
+ })
|
|
|
+ }
|
|
|
},
|
|
|
- specialQueries: {
|
|
|
- createdBy: newQuery => ({ $or: [newQuery, { createdByUsername: newQuery.createdBy }] })
|
|
|
- }
|
|
|
- },
|
|
|
- this
|
|
|
- )
|
|
|
- .then(response => {
|
|
|
- next(null, response);
|
|
|
- })
|
|
|
- .catch(err => {
|
|
|
- next(err);
|
|
|
- });
|
|
|
- }
|
|
|
- ],
|
|
|
- async (err, response) => {
|
|
|
- if (err) {
|
|
|
- err = await UtilsModule.runJob("GET_ERROR", { error: err }, this);
|
|
|
- this.log("ERROR", "PLAYLISTS_GET_DATA", `Failed to get data from playlists. "${err}"`);
|
|
|
- return cb({ status: "error", message: err });
|
|
|
+ this
|
|
|
+ )
|
|
|
+ .then(response => {
|
|
|
+ next(null, response);
|
|
|
+ })
|
|
|
+ .catch(err => {
|
|
|
+ next(err);
|
|
|
+ });
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ async (err, response) => {
|
|
|
+ if (err) {
|
|
|
+ err = await UtilsModule.runJob("GET_ERROR", { error: err }, this);
|
|
|
+ this.log("ERROR", "PLAYLISTS_GET_DATA", `Failed to get data from playlists. "${err}"`);
|
|
|
+ return cb({ status: "error", message: err });
|
|
|
+ }
|
|
|
+ this.log("SUCCESS", "PLAYLISTS_GET_DATA", `Got data from playlists successfully.`);
|
|
|
+ return cb({ status: "success", message: "Successfully got data from playlists.", data: response });
|
|
|
}
|
|
|
- this.log("SUCCESS", "PLAYLISTS_GET_DATA", `Got data from playlists successfully.`);
|
|
|
- return cb({ status: "success", message: "Successfully got data from playlists.", data: response });
|
|
|
- }
|
|
|
- );
|
|
|
- }),
|
|
|
+ );
|
|
|
+ }
|
|
|
+ ),
|
|
|
|
|
|
/**
|
|
|
* Searches through all playlists that can be included in a community station
|
|
@@ -431,7 +437,7 @@ export default {
|
|
|
* @param {string} query - the page
|
|
|
* @param {Function} cb - gets called with the result
|
|
|
*/
|
|
|
- searchOfficial: isAdminRequired(async function searchOfficial(session, query, page, cb) {
|
|
|
+ searchOfficial: useHasPermission("playlists.get", async function searchOfficial(session, query, page, cb) {
|
|
|
async.waterfall(
|
|
|
[
|
|
|
next => {
|
|
@@ -811,18 +817,10 @@ export default {
|
|
|
|
|
|
(playlist, next) => {
|
|
|
if (!playlist) return next("Playlist not found");
|
|
|
- if (playlist.privacy !== "public" && playlist.createdBy !== session.userId) {
|
|
|
- if (session)
|
|
|
- // check if user requested to get a playlist is an admin
|
|
|
- return DBModule.runJob("GET_MODEL", { modelName: "user" }, this).then(userModel => {
|
|
|
- userModel.findOne({ _id: session.userId }, (err, user) => {
|
|
|
- if (user && user.role === "admin") return next(null, playlist);
|
|
|
- return next("User unauthorised to view playlist.");
|
|
|
- });
|
|
|
- });
|
|
|
- return next("User unauthorised to view playlist.");
|
|
|
- }
|
|
|
-
|
|
|
+ if (playlist.privacy !== "public" && playlist.createdBy !== session.userId)
|
|
|
+ return hasPermission("playlists.get", session)
|
|
|
+ .then(() => next(null, playlist))
|
|
|
+ .catch(() => next("User unauthorised to view playlist."));
|
|
|
return next(null, playlist);
|
|
|
}
|
|
|
],
|
|
@@ -870,18 +868,10 @@ export default {
|
|
|
|
|
|
(playlist, next) => {
|
|
|
if (!playlist) return next("Playlist not found");
|
|
|
- if (playlist.privacy !== "public" && playlist.createdBy !== session.userId) {
|
|
|
- if (session)
|
|
|
- // check if user requested to get a playlist is an admin
|
|
|
- return DBModule.runJob("GET_MODEL", { modelName: "user" }, this).then(userModel => {
|
|
|
- userModel.findOne({ _id: session.userId }, (err, user) => {
|
|
|
- if (user && user.role === "admin") return next(null, playlist);
|
|
|
- return next("User unauthorised to view playlist.");
|
|
|
- });
|
|
|
- });
|
|
|
- return next("User unauthorised to view playlist.");
|
|
|
- }
|
|
|
-
|
|
|
+ if (playlist.privacy !== "public")
|
|
|
+ return hasPermission("stations.view", session, stationId)
|
|
|
+ .then(() => next(null, playlist))
|
|
|
+ .catch(() => next("User unauthorised to view playlist."));
|
|
|
return next(null, playlist);
|
|
|
}
|
|
|
],
|
|
@@ -1007,14 +997,11 @@ export default {
|
|
|
next => {
|
|
|
PlaylistsModule.runJob("GET_PLAYLIST", { playlistId }, this)
|
|
|
.then(playlist => {
|
|
|
- if (!playlist || playlist.createdBy !== session.userId) {
|
|
|
- return DBModule.runJob("GET_MODEL", { modelName: "user" }, this).then(userModel => {
|
|
|
- userModel.findOne({ _id: session.userId }, (err, user) => {
|
|
|
- if (user && user.role === "admin") return next();
|
|
|
- return next("Something went wrong when trying to get the playlist");
|
|
|
- });
|
|
|
- });
|
|
|
- }
|
|
|
+ if (!playlist) return next("Playlist not found.");
|
|
|
+ if (playlist.createdBy !== session.userId)
|
|
|
+ return hasPermission("playlists.songs.reposition", session)
|
|
|
+ .then(() => next())
|
|
|
+ .catch(() => next("Invalid permissions."));
|
|
|
return next();
|
|
|
})
|
|
|
.catch(next);
|
|
@@ -1098,14 +1085,12 @@ export default {
|
|
|
next => {
|
|
|
PlaylistsModule.runJob("GET_PLAYLIST", { playlistId }, this)
|
|
|
.then(playlist => {
|
|
|
- if (!playlist || playlist.createdBy !== session.userId) {
|
|
|
- DBModule.runJob("GET_MODEL", { modelName: "user" }, this).then(userModel => {
|
|
|
- userModel.findOne({ _id: session.userId }, (err, user) => {
|
|
|
- if (user && user.role === "admin") return next(null, playlist);
|
|
|
- return next("Something went wrong when trying to get the playlist");
|
|
|
- });
|
|
|
- });
|
|
|
- } else next(null, playlist);
|
|
|
+ if (!playlist) return next("Playlist not found.");
|
|
|
+ if (playlist.createdBy !== session.userId)
|
|
|
+ return hasPermission("playlists.songs.add", session)
|
|
|
+ .then(() => next(null, playlist))
|
|
|
+ .catch(() => next("Invalid permissions."));
|
|
|
+ return next(null, playlist);
|
|
|
})
|
|
|
.catch(next);
|
|
|
},
|
|
@@ -1388,15 +1373,11 @@ export default {
|
|
|
|
|
|
(playlist, next) => {
|
|
|
this.publishProgress({ status: "update", message: `Importing YouTube playlist (stage 4)` });
|
|
|
- if (!playlist || playlist.createdBy !== session.userId) {
|
|
|
- return DBModule.runJob("GET_MODEL", { modelName: "user" }, this).then(userModel => {
|
|
|
- userModel.findOne({ _id: session.userId }, (err, user) => {
|
|
|
- if (user && user.role === "admin") return next(null, playlist);
|
|
|
- return next("Something went wrong when trying to get the playlist");
|
|
|
- });
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
+ if (!playlist) return next("Playlist not found.");
|
|
|
+ if (playlist.createdBy !== session.userId)
|
|
|
+ return hasPermission("playlists.songs.add", session)
|
|
|
+ .then(() => next(null, playlist))
|
|
|
+ .catch(() => next("Invalid permissions."));
|
|
|
return next(null, playlist);
|
|
|
}
|
|
|
],
|
|
@@ -1471,14 +1452,11 @@ export default {
|
|
|
next => {
|
|
|
PlaylistsModule.runJob("GET_PLAYLIST", { playlistId }, this)
|
|
|
.then(playlist => {
|
|
|
- if (!playlist || playlist.createdBy !== session.userId) {
|
|
|
- return DBModule.runJob("GET_MODEL", { modelName: "user" }, this).then(userModel => {
|
|
|
- userModel.findOne({ _id: session.userId }, (err, user) => {
|
|
|
- if (user && user.role === "admin") return next(null, playlist);
|
|
|
- return next("Something went wrong when trying to get the playlist");
|
|
|
- });
|
|
|
- });
|
|
|
- }
|
|
|
+ if (!playlist) return next("Playlist not found.");
|
|
|
+ if (playlist.createdBy !== session.userId)
|
|
|
+ return hasPermission("playlists.songs.remove", session)
|
|
|
+ .then(() => next(null, playlist))
|
|
|
+ .catch(() => next("Invalid permissions."));
|
|
|
return next(null, playlist);
|
|
|
})
|
|
|
.catch(next);
|
|
@@ -1790,7 +1768,7 @@ export default {
|
|
|
* @param {string} playlistId - the id of the playlist we are removing
|
|
|
* @param {Function} cb - gets called with the result
|
|
|
*/
|
|
|
- removeAdmin: isAdminRequired(async function removeAdmin(session, playlistId, cb) {
|
|
|
+ removeAdmin: useHasPermission("playlists.removeAdmin", async function removeAdmin(session, playlistId, cb) {
|
|
|
const userModel = await DBModule.runJob("GET_MODEL", { modelName: "user" }, this);
|
|
|
|
|
|
async.waterfall(
|
|
@@ -1944,66 +1922,74 @@ export default {
|
|
|
* @param {string} privacy - what the new privacy of the playlist should be e.g. public
|
|
|
* @param {Function} cb - gets called with the result
|
|
|
*/
|
|
|
- updatePrivacyAdmin: isAdminRequired(async function updatePrivacyAdmin(session, playlistId, privacy, cb) {
|
|
|
- const playlistModel = await DBModule.runJob("GET_MODEL", { modelName: "playlist" }, this);
|
|
|
-
|
|
|
- async.waterfall(
|
|
|
- [
|
|
|
- next => {
|
|
|
- playlistModel.updateOne({ _id: playlistId }, { $set: { privacy } }, { runValidators: true }, next);
|
|
|
- },
|
|
|
+ updatePrivacyAdmin: useHasPermission(
|
|
|
+ "playlists.update.privacy",
|
|
|
+ async function updatePrivacyAdmin(session, playlistId, privacy, cb) {
|
|
|
+ const playlistModel = await DBModule.runJob("GET_MODEL", { modelName: "playlist" }, this);
|
|
|
+
|
|
|
+ async.waterfall(
|
|
|
+ [
|
|
|
+ next => {
|
|
|
+ playlistModel.updateOne(
|
|
|
+ { _id: playlistId },
|
|
|
+ { $set: { privacy } },
|
|
|
+ { runValidators: true },
|
|
|
+ next
|
|
|
+ );
|
|
|
+ },
|
|
|
+
|
|
|
+ (res, next) => {
|
|
|
+ if (res.n === 0) next("No playlist found with that id.");
|
|
|
+ else if (res.nModified === 0) next(`Nothing changed, the playlist was already ${privacy}.`);
|
|
|
+ else {
|
|
|
+ PlaylistsModule.runJob("UPDATE_PLAYLIST", { playlistId }, this)
|
|
|
+ .then(playlist => next(null, playlist))
|
|
|
+ .catch(next);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ async (err, playlist) => {
|
|
|
+ if (err) {
|
|
|
+ err = await UtilsModule.runJob("GET_ERROR", { error: err }, this);
|
|
|
+
|
|
|
+ this.log(
|
|
|
+ "ERROR",
|
|
|
+ "PLAYLIST_UPDATE_PRIVACY_ADMIN",
|
|
|
+ `Updating privacy to "${privacy}" for playlist "${playlistId}" failed for user "${session.userId}". "${err}"`
|
|
|
+ );
|
|
|
|
|
|
- (res, next) => {
|
|
|
- if (res.n === 0) next("No playlist found with that id.");
|
|
|
- else if (res.nModified === 0) next(`Nothing changed, the playlist was already ${privacy}.`);
|
|
|
- else {
|
|
|
- PlaylistsModule.runJob("UPDATE_PLAYLIST", { playlistId }, this)
|
|
|
- .then(playlist => next(null, playlist))
|
|
|
- .catch(next);
|
|
|
+ return cb({ status: "error", message: err });
|
|
|
}
|
|
|
- }
|
|
|
- ],
|
|
|
- async (err, playlist) => {
|
|
|
- if (err) {
|
|
|
- err = await UtilsModule.runJob("GET_ERROR", { error: err }, this);
|
|
|
|
|
|
this.log(
|
|
|
- "ERROR",
|
|
|
- "PLAYLIST_UPDATE_PRIVACY_ADMIN",
|
|
|
- `Updating privacy to "${privacy}" for playlist "${playlistId}" failed for user "${session.userId}". "${err}"`
|
|
|
+ "SUCCESS",
|
|
|
+ "PLAYLIST_UPDATE_PRIVACY_ADMIn",
|
|
|
+ `Successfully updated privacy to "${privacy}" for playlist "${playlistId}" for user "${session.userId}".`
|
|
|
);
|
|
|
|
|
|
- return cb({ status: "error", message: err });
|
|
|
- }
|
|
|
-
|
|
|
- this.log(
|
|
|
- "SUCCESS",
|
|
|
- "PLAYLIST_UPDATE_PRIVACY_ADMIn",
|
|
|
- `Successfully updated privacy to "${privacy}" for playlist "${playlistId}" for user "${session.userId}".`
|
|
|
- );
|
|
|
+ if (playlist.type === "user") {
|
|
|
+ CacheModule.runJob("PUB", {
|
|
|
+ channel: "playlist.updatePrivacy",
|
|
|
+ value: {
|
|
|
+ userId: playlist.createdBy,
|
|
|
+ playlist
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
|
|
|
- if (playlist.type === "user") {
|
|
|
CacheModule.runJob("PUB", {
|
|
|
- channel: "playlist.updatePrivacy",
|
|
|
- value: {
|
|
|
- userId: playlist.createdBy,
|
|
|
- playlist
|
|
|
- }
|
|
|
+ channel: "playlist.updated",
|
|
|
+ value: { playlistId }
|
|
|
});
|
|
|
- }
|
|
|
|
|
|
- CacheModule.runJob("PUB", {
|
|
|
- channel: "playlist.updated",
|
|
|
- value: { playlistId }
|
|
|
- });
|
|
|
-
|
|
|
- return cb({
|
|
|
- status: "success",
|
|
|
- message: "Playlist has been successfully updated"
|
|
|
- });
|
|
|
- }
|
|
|
- );
|
|
|
- }),
|
|
|
+ return cb({
|
|
|
+ status: "success",
|
|
|
+ message: "Playlist has been successfully updated"
|
|
|
+ });
|
|
|
+ }
|
|
|
+ );
|
|
|
+ }
|
|
|
+ ),
|
|
|
|
|
|
/**
|
|
|
* Deletes all orphaned station playlists
|
|
@@ -2011,7 +1997,7 @@ export default {
|
|
|
* @param {object} session - the session object automatically added by socket.io
|
|
|
* @param {Function} cb - gets called with the result
|
|
|
*/
|
|
|
- deleteOrphanedStationPlaylists: isAdminRequired(async function index(session, cb) {
|
|
|
+ deleteOrphanedStationPlaylists: useHasPermission("playlists.deleteOrphaned", async function index(session, cb) {
|
|
|
this.keepLongJob();
|
|
|
this.publishProgress({
|
|
|
status: "started",
|
|
@@ -2071,7 +2057,7 @@ export default {
|
|
|
* @param {object} session - the session object automatically added by socket.io
|
|
|
* @param {Function} cb - gets called with the result
|
|
|
*/
|
|
|
- deleteOrphanedGenrePlaylists: isAdminRequired(async function index(session, cb) {
|
|
|
+ deleteOrphanedGenrePlaylists: useHasPermission("playlists.deleteOrphaned", async function index(session, cb) {
|
|
|
this.keepLongJob();
|
|
|
this.publishProgress({
|
|
|
status: "started",
|
|
@@ -2131,59 +2117,62 @@ export default {
|
|
|
* @param {object} session - the session object automatically added by socket.io
|
|
|
* @param {Function} cb - gets called with the result
|
|
|
*/
|
|
|
- requestOrphanedPlaylistSongs: isAdminRequired(async function index(session, cb) {
|
|
|
- this.keepLongJob();
|
|
|
- this.publishProgress({
|
|
|
- status: "started",
|
|
|
- title: "Request orphaned playlist songs",
|
|
|
- message: "Requesting orphaned playlist songs.",
|
|
|
- id: this.toString()
|
|
|
- });
|
|
|
- await CacheModule.runJob("RPUSH", { key: `longJobs.${session.userId}`, value: this.toString() }, this);
|
|
|
- await CacheModule.runJob(
|
|
|
- "PUB",
|
|
|
- {
|
|
|
- channel: "longJob.added",
|
|
|
- value: { jobId: this.toString(), userId: session.userId }
|
|
|
- },
|
|
|
- this
|
|
|
- );
|
|
|
-
|
|
|
- async.waterfall(
|
|
|
- [
|
|
|
- next => {
|
|
|
- SongsModule.runJob("REQUEST_ORPHANED_PLAYLIST_SONGS", {}, this)
|
|
|
- .then(() => next())
|
|
|
- .catch(next);
|
|
|
- }
|
|
|
- ],
|
|
|
- async err => {
|
|
|
- if (err) {
|
|
|
- err = await UtilsModule.runJob("GET_ERROR", { error: err }, this);
|
|
|
+ requestOrphanedPlaylistSongs: useHasPermission(
|
|
|
+ "playlists.requestOrphanedPlaylistSongs",
|
|
|
+ async function index(session, cb) {
|
|
|
+ this.keepLongJob();
|
|
|
+ this.publishProgress({
|
|
|
+ status: "started",
|
|
|
+ title: "Request orphaned playlist songs",
|
|
|
+ message: "Requesting orphaned playlist songs.",
|
|
|
+ id: this.toString()
|
|
|
+ });
|
|
|
+ await CacheModule.runJob("RPUSH", { key: `longJobs.${session.userId}`, value: this.toString() }, this);
|
|
|
+ await CacheModule.runJob(
|
|
|
+ "PUB",
|
|
|
+ {
|
|
|
+ channel: "longJob.added",
|
|
|
+ value: { jobId: this.toString(), userId: session.userId }
|
|
|
+ },
|
|
|
+ this
|
|
|
+ );
|
|
|
+
|
|
|
+ async.waterfall(
|
|
|
+ [
|
|
|
+ next => {
|
|
|
+ SongsModule.runJob("REQUEST_ORPHANED_PLAYLIST_SONGS", {}, this)
|
|
|
+ .then(() => next())
|
|
|
+ .catch(next);
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ async err => {
|
|
|
+ if (err) {
|
|
|
+ err = await UtilsModule.runJob("GET_ERROR", { error: err }, this);
|
|
|
+ this.log(
|
|
|
+ "ERROR",
|
|
|
+ "REQUEST_ORPHANED_PLAYLIST_SONGS",
|
|
|
+ `Requesting orphaned playlist songs failed. "${err}"`
|
|
|
+ );
|
|
|
+ this.publishProgress({
|
|
|
+ status: "error",
|
|
|
+ message: err
|
|
|
+ });
|
|
|
+ return cb({ status: "error", message: err });
|
|
|
+ }
|
|
|
this.log(
|
|
|
- "ERROR",
|
|
|
+ "SUCCESS",
|
|
|
"REQUEST_ORPHANED_PLAYLIST_SONGS",
|
|
|
- `Requesting orphaned playlist songs failed. "${err}"`
|
|
|
+ "Requesting orphaned playlist songs was successful."
|
|
|
);
|
|
|
this.publishProgress({
|
|
|
- status: "error",
|
|
|
- message: err
|
|
|
+ status: "success",
|
|
|
+ message: "Successfully requested orphaned playlist songs."
|
|
|
});
|
|
|
- return cb({ status: "error", message: err });
|
|
|
+ return cb({ status: "success", message: "Successfully requested orphaned playlist songs." });
|
|
|
}
|
|
|
- this.log(
|
|
|
- "SUCCESS",
|
|
|
- "REQUEST_ORPHANED_PLAYLIST_SONGS",
|
|
|
- "Requesting orphaned playlist songs was successful."
|
|
|
- );
|
|
|
- this.publishProgress({
|
|
|
- status: "success",
|
|
|
- message: "Successfully requested orphaned playlist songs."
|
|
|
- });
|
|
|
- return cb({ status: "success", message: "Successfully requested orphaned playlist songs." });
|
|
|
- }
|
|
|
- );
|
|
|
- }),
|
|
|
+ );
|
|
|
+ }
|
|
|
+ ),
|
|
|
|
|
|
/**
|
|
|
* Clears and refills a station playlist
|
|
@@ -2192,48 +2181,51 @@ export default {
|
|
|
* @param {string} playlistId - the id of the playlist we are clearing and refilling
|
|
|
* @param {Function} cb - gets called with the result
|
|
|
*/
|
|
|
- clearAndRefillStationPlaylist: isAdminRequired(async function index(session, playlistId, cb) {
|
|
|
- async.waterfall(
|
|
|
- [
|
|
|
- next => {
|
|
|
- if (!playlistId) next("Please specify a playlist id");
|
|
|
- else {
|
|
|
- PlaylistsModule.runJob("CLEAR_AND_REFILL_STATION_PLAYLIST", { playlistId }, this)
|
|
|
- .then(() => {
|
|
|
- next();
|
|
|
- })
|
|
|
- .catch(err => {
|
|
|
- next(err);
|
|
|
- });
|
|
|
+ clearAndRefillStationPlaylist: useHasPermission(
|
|
|
+ "playlists.clearAndRefill",
|
|
|
+ async function index(session, playlistId, cb) {
|
|
|
+ async.waterfall(
|
|
|
+ [
|
|
|
+ next => {
|
|
|
+ if (!playlistId) next("Please specify a playlist id");
|
|
|
+ else {
|
|
|
+ PlaylistsModule.runJob("CLEAR_AND_REFILL_STATION_PLAYLIST", { playlistId }, this)
|
|
|
+ .then(() => {
|
|
|
+ next();
|
|
|
+ })
|
|
|
+ .catch(err => {
|
|
|
+ next(err);
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ async err => {
|
|
|
+ if (err) {
|
|
|
+ err = await UtilsModule.runJob("GET_ERROR", { error: err }, this);
|
|
|
+
|
|
|
+ this.log(
|
|
|
+ "ERROR",
|
|
|
+ "PLAYLIST_CLEAR_AND_REFILL_STATION_PLAYLIST",
|
|
|
+ `Clearing and refilling station playlist "${playlistId}" failed for user "${session.userId}". "${err}"`
|
|
|
+ );
|
|
|
+
|
|
|
+ return cb({ status: "error", message: err });
|
|
|
}
|
|
|
- }
|
|
|
- ],
|
|
|
- async err => {
|
|
|
- if (err) {
|
|
|
- err = await UtilsModule.runJob("GET_ERROR", { error: err }, this);
|
|
|
|
|
|
this.log(
|
|
|
- "ERROR",
|
|
|
+ "SUCCESS",
|
|
|
"PLAYLIST_CLEAR_AND_REFILL_STATION_PLAYLIST",
|
|
|
- `Clearing and refilling station playlist "${playlistId}" failed for user "${session.userId}". "${err}"`
|
|
|
+ `Successfully cleared and refilled station playlist "${playlistId}" for user "${session.userId}".`
|
|
|
);
|
|
|
|
|
|
- return cb({ status: "error", message: err });
|
|
|
+ return cb({
|
|
|
+ status: "success",
|
|
|
+ message: "Playlist has been successfully cleared and refilled"
|
|
|
+ });
|
|
|
}
|
|
|
-
|
|
|
- this.log(
|
|
|
- "SUCCESS",
|
|
|
- "PLAYLIST_CLEAR_AND_REFILL_STATION_PLAYLIST",
|
|
|
- `Successfully cleared and refilled station playlist "${playlistId}" for user "${session.userId}".`
|
|
|
- );
|
|
|
-
|
|
|
- return cb({
|
|
|
- status: "success",
|
|
|
- message: "Playlist has been successfully cleared and refilled"
|
|
|
- });
|
|
|
- }
|
|
|
- );
|
|
|
- }),
|
|
|
+ );
|
|
|
+ }
|
|
|
+ ),
|
|
|
|
|
|
/**
|
|
|
* Clears and refills a genre playlist
|
|
@@ -2242,48 +2234,51 @@ export default {
|
|
|
* @param {string} playlistId - the id of the playlist we are clearing and refilling
|
|
|
* @param {Function} cb - gets called with the result
|
|
|
*/
|
|
|
- clearAndRefillGenrePlaylist: isAdminRequired(async function index(session, playlistId, cb) {
|
|
|
- async.waterfall(
|
|
|
- [
|
|
|
- next => {
|
|
|
- if (!playlistId) next("Please specify a playlist id");
|
|
|
- else {
|
|
|
- PlaylistsModule.runJob("CLEAR_AND_REFILL_GENRE_PLAYLIST", { playlistId }, this)
|
|
|
- .then(() => {
|
|
|
- next();
|
|
|
- })
|
|
|
- .catch(err => {
|
|
|
- next(err);
|
|
|
- });
|
|
|
+ clearAndRefillGenrePlaylist: useHasPermission(
|
|
|
+ "playlists.clearAndRefill",
|
|
|
+ async function index(session, playlistId, cb) {
|
|
|
+ async.waterfall(
|
|
|
+ [
|
|
|
+ next => {
|
|
|
+ if (!playlistId) next("Please specify a playlist id");
|
|
|
+ else {
|
|
|
+ PlaylistsModule.runJob("CLEAR_AND_REFILL_GENRE_PLAYLIST", { playlistId }, this)
|
|
|
+ .then(() => {
|
|
|
+ next();
|
|
|
+ })
|
|
|
+ .catch(err => {
|
|
|
+ next(err);
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ async err => {
|
|
|
+ if (err) {
|
|
|
+ err = await UtilsModule.runJob("GET_ERROR", { error: err }, this);
|
|
|
+
|
|
|
+ this.log(
|
|
|
+ "ERROR",
|
|
|
+ "PLAYLIST_CLEAR_AND_REFILL_GENRE_PLAYLIST",
|
|
|
+ `Clearing and refilling genre playlist "${playlistId}" failed for user "${session.userId}". "${err}"`
|
|
|
+ );
|
|
|
+
|
|
|
+ return cb({ status: "error", message: err });
|
|
|
}
|
|
|
- }
|
|
|
- ],
|
|
|
- async err => {
|
|
|
- if (err) {
|
|
|
- err = await UtilsModule.runJob("GET_ERROR", { error: err }, this);
|
|
|
|
|
|
this.log(
|
|
|
- "ERROR",
|
|
|
+ "SUCCESS",
|
|
|
"PLAYLIST_CLEAR_AND_REFILL_GENRE_PLAYLIST",
|
|
|
- `Clearing and refilling genre playlist "${playlistId}" failed for user "${session.userId}". "${err}"`
|
|
|
+ `Successfully cleared and refilled genre playlist "${playlistId}" for user "${session.userId}".`
|
|
|
);
|
|
|
|
|
|
- return cb({ status: "error", message: err });
|
|
|
+ return cb({
|
|
|
+ status: "success",
|
|
|
+ message: "Playlist has been successfully cleared and refilled"
|
|
|
+ });
|
|
|
}
|
|
|
-
|
|
|
- this.log(
|
|
|
- "SUCCESS",
|
|
|
- "PLAYLIST_CLEAR_AND_REFILL_GENRE_PLAYLIST",
|
|
|
- `Successfully cleared and refilled genre playlist "${playlistId}" for user "${session.userId}".`
|
|
|
- );
|
|
|
-
|
|
|
- return cb({
|
|
|
- status: "success",
|
|
|
- message: "Playlist has been successfully cleared and refilled"
|
|
|
- });
|
|
|
- }
|
|
|
- );
|
|
|
- }),
|
|
|
+ );
|
|
|
+ }
|
|
|
+ ),
|
|
|
|
|
|
/**
|
|
|
* Clears and refills all station playlists
|
|
@@ -2291,93 +2286,96 @@ export default {
|
|
|
* @param {object} session - the session object automatically added by socket.io
|
|
|
* @param {Function} cb - gets called with the result
|
|
|
*/
|
|
|
- clearAndRefillAllStationPlaylists: isAdminRequired(async function index(session, cb) {
|
|
|
- this.keepLongJob();
|
|
|
- this.publishProgress({
|
|
|
- status: "started",
|
|
|
- title: "Clear and refill all station playlists",
|
|
|
- message: "Clearing and refilling all station playlists.",
|
|
|
- id: this.toString()
|
|
|
- });
|
|
|
- await CacheModule.runJob("RPUSH", { key: `longJobs.${session.userId}`, value: this.toString() }, this);
|
|
|
- await CacheModule.runJob(
|
|
|
- "PUB",
|
|
|
- {
|
|
|
- channel: "longJob.added",
|
|
|
- value: { jobId: this.toString(), userId: session.userId }
|
|
|
- },
|
|
|
- this
|
|
|
- );
|
|
|
-
|
|
|
- async.waterfall(
|
|
|
- [
|
|
|
- next => {
|
|
|
- PlaylistsModule.runJob("GET_ALL_STATION_PLAYLISTS", {}, this)
|
|
|
- .then(response => {
|
|
|
- next(null, response.playlists);
|
|
|
- })
|
|
|
- .catch(err => {
|
|
|
- next(err);
|
|
|
- });
|
|
|
+ clearAndRefillAllStationPlaylists: useHasPermission(
|
|
|
+ "playlists.clearAndRefillAll",
|
|
|
+ async function index(session, cb) {
|
|
|
+ this.keepLongJob();
|
|
|
+ this.publishProgress({
|
|
|
+ status: "started",
|
|
|
+ title: "Clear and refill all station playlists",
|
|
|
+ message: "Clearing and refilling all station playlists.",
|
|
|
+ id: this.toString()
|
|
|
+ });
|
|
|
+ await CacheModule.runJob("RPUSH", { key: `longJobs.${session.userId}`, value: this.toString() }, this);
|
|
|
+ await CacheModule.runJob(
|
|
|
+ "PUB",
|
|
|
+ {
|
|
|
+ channel: "longJob.added",
|
|
|
+ value: { jobId: this.toString(), userId: session.userId }
|
|
|
},
|
|
|
-
|
|
|
- (playlists, next) => {
|
|
|
- async.eachLimit(
|
|
|
- playlists,
|
|
|
- 1,
|
|
|
- (playlist, next) => {
|
|
|
- this.publishProgress({
|
|
|
- status: "update",
|
|
|
- message: `Clearing and refilling "${playlist._id}"`
|
|
|
+ this
|
|
|
+ );
|
|
|
+
|
|
|
+ async.waterfall(
|
|
|
+ [
|
|
|
+ next => {
|
|
|
+ PlaylistsModule.runJob("GET_ALL_STATION_PLAYLISTS", {}, this)
|
|
|
+ .then(response => {
|
|
|
+ next(null, response.playlists);
|
|
|
+ })
|
|
|
+ .catch(err => {
|
|
|
+ next(err);
|
|
|
});
|
|
|
- PlaylistsModule.runJob(
|
|
|
- "CLEAR_AND_REFILL_STATION_PLAYLIST",
|
|
|
- { playlistId: playlist._id },
|
|
|
- this
|
|
|
- )
|
|
|
- .then(() => {
|
|
|
- next();
|
|
|
- })
|
|
|
- .catch(err => {
|
|
|
- next(err);
|
|
|
+ },
|
|
|
+
|
|
|
+ (playlists, next) => {
|
|
|
+ async.eachLimit(
|
|
|
+ playlists,
|
|
|
+ 1,
|
|
|
+ (playlist, next) => {
|
|
|
+ this.publishProgress({
|
|
|
+ status: "update",
|
|
|
+ message: `Clearing and refilling "${playlist._id}"`
|
|
|
});
|
|
|
- },
|
|
|
- next
|
|
|
- );
|
|
|
- }
|
|
|
- ],
|
|
|
- async err => {
|
|
|
- if (err) {
|
|
|
- err = await UtilsModule.runJob("GET_ERROR", { error: err }, this);
|
|
|
+ PlaylistsModule.runJob(
|
|
|
+ "CLEAR_AND_REFILL_STATION_PLAYLIST",
|
|
|
+ { playlistId: playlist._id },
|
|
|
+ this
|
|
|
+ )
|
|
|
+ .then(() => {
|
|
|
+ next();
|
|
|
+ })
|
|
|
+ .catch(err => {
|
|
|
+ next(err);
|
|
|
+ });
|
|
|
+ },
|
|
|
+ next
|
|
|
+ );
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ async err => {
|
|
|
+ if (err) {
|
|
|
+ err = await UtilsModule.runJob("GET_ERROR", { error: err }, this);
|
|
|
+
|
|
|
+ this.log(
|
|
|
+ "ERROR",
|
|
|
+ "PLAYLIST_CLEAR_AND_REFILL_ALL_STATION_PLAYLISTS",
|
|
|
+ `Clearing and refilling all station playlists failed for user "${session.userId}". "${err}"`
|
|
|
+ );
|
|
|
+ this.publishProgress({
|
|
|
+ status: "error",
|
|
|
+ message: err
|
|
|
+ });
|
|
|
+ return cb({ status: "error", message: err });
|
|
|
+ }
|
|
|
|
|
|
this.log(
|
|
|
- "ERROR",
|
|
|
+ "SUCCESS",
|
|
|
"PLAYLIST_CLEAR_AND_REFILL_ALL_STATION_PLAYLISTS",
|
|
|
- `Clearing and refilling all station playlists failed for user "${session.userId}". "${err}"`
|
|
|
+ `Successfully cleared and refilled all station playlists for user "${session.userId}".`
|
|
|
);
|
|
|
this.publishProgress({
|
|
|
- status: "error",
|
|
|
- message: err
|
|
|
+ status: "success",
|
|
|
+ message: "Playlists have been successfully cleared and refilled."
|
|
|
+ });
|
|
|
+ return cb({
|
|
|
+ status: "success",
|
|
|
+ message: "Playlists have been successfully cleared and refilled"
|
|
|
});
|
|
|
- return cb({ status: "error", message: err });
|
|
|
}
|
|
|
-
|
|
|
- this.log(
|
|
|
- "SUCCESS",
|
|
|
- "PLAYLIST_CLEAR_AND_REFILL_ALL_STATION_PLAYLISTS",
|
|
|
- `Successfully cleared and refilled all station playlists for user "${session.userId}".`
|
|
|
- );
|
|
|
- this.publishProgress({
|
|
|
- status: "success",
|
|
|
- message: "Playlists have been successfully cleared and refilled."
|
|
|
- });
|
|
|
- return cb({
|
|
|
- status: "success",
|
|
|
- message: "Playlists have been successfully cleared and refilled"
|
|
|
- });
|
|
|
- }
|
|
|
- );
|
|
|
- }),
|
|
|
+ );
|
|
|
+ }
|
|
|
+ ),
|
|
|
|
|
|
/**
|
|
|
* Clears and refills all genre playlists
|
|
@@ -2385,7 +2383,7 @@ export default {
|
|
|
* @param {object} session - the session object automatically added by socket.io
|
|
|
* @param {Function} cb - gets called with the result
|
|
|
*/
|
|
|
- clearAndRefillAllGenrePlaylists: isAdminRequired(async function index(session, cb) {
|
|
|
+ clearAndRefillAllGenrePlaylists: useHasPermission("playlists.clearAndRefillAll", async function index(session, cb) {
|
|
|
this.keepLongJob();
|
|
|
this.publishProgress({
|
|
|
status: "started",
|
|
@@ -2479,7 +2477,7 @@ export default {
|
|
|
* @param {object} session - the session object automatically added by socket.io
|
|
|
* @param {Function} cb - gets called with the result
|
|
|
*/
|
|
|
- createMissingGenrePlaylists: isAdminRequired(async function index(session, cb) {
|
|
|
+ createMissingGenrePlaylists: useHasPermission("playlists.createMissing", async function index(session, cb) {
|
|
|
this.keepLongJob();
|
|
|
this.publishProgress({
|
|
|
status: "started",
|