queueSongs.js 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. 'use strict';
  2. const db = require('../db');
  3. const utils = require('../utils');
  4. const notifications = require('../notifications');
  5. const cache = require('../cache');
  6. const async = require('async');
  7. const config = require('config');
  8. const request = require('request');
  9. const hooks = require('./hooks');
  10. cache.sub('queue.newSong', songId => {
  11. db.models.queueSong.findOne({_id: songId}, (err, song) => {
  12. utils.emitToRoom('admin.queue', 'event:admin.queueSong.added', song);
  13. });
  14. });
  15. cache.sub('queue.removedSong', songId => {
  16. utils.emitToRoom('admin.queue', 'event:admin.queueSong.removed', songId);
  17. });
  18. cache.sub('queue.updatedSong', songId => {
  19. //TODO Retrieve new Song object
  20. utils.emitToRoom('admin.queue', 'event:queueSong.updated', { songId });
  21. });
  22. module.exports = {
  23. /**
  24. * Gets all queuesongs
  25. *
  26. * @param {Object} session - the session object automatically added by socket.io
  27. * @param {Function} cb - gets called with the result
  28. */
  29. index: hooks.adminRequired((session, cb) => {
  30. async.waterfall([
  31. (next) => {
  32. db.models.queueSong.find({}, next);
  33. }
  34. ], (err, songs) => {
  35. if (err) {
  36. logger.log("QUEUE_INDEX", "ERROR", `Indexing queuesongs failed. "${err.message}"`);
  37. return cb({status: 'failure', message: 'Something went wrong.'});
  38. }
  39. logger.log("QUEUE_INDEX", "SUCCESS", `Indexing queuesongs successful.`);
  40. return cb(songs);
  41. });
  42. }),
  43. /**
  44. * Updates a queuesong
  45. *
  46. * @param {Object} session - the session object automatically added by socket.io
  47. * @param {String} songId - the id of the queuesong that gets updated
  48. * @param {Object} updatedSong - the object of the updated queueSong
  49. * @param {Function} cb - gets called with the result
  50. * @param {String} userId - the userId automatically added by hooks
  51. */
  52. update: hooks.adminRequired((session, songId, updatedSong, cb, userId) => {
  53. async.waterfall([
  54. (next) => {
  55. db.models.queueSong.findOne({ songId }, next);
  56. },
  57. (song, next) => {
  58. let updated = false;
  59. let $set = {};
  60. for (let prop in updatedSong) if (updatedSong[prop] !== song[prop]) $set[prop] = updatedSong[prop]; updated = true;
  61. if (!updated) return next('No properties changed');
  62. db.models.queueSong.update({ _id: songId }, {$set}, next);
  63. }
  64. ], (err) => {
  65. if (err) {
  66. let error = 'An error occurred.';
  67. if (typeof err === "string") error = err;
  68. else if (err.message) error = err.message;
  69. logger.log("QUEUE_UPDATE", "ERROR", `Updating queuesong "${songId}" failed for user ${userId}. "${err.message}"`);
  70. return cb({status: 'failure', message: error});
  71. }
  72. cache.pub('queue.updatedSong', songId);
  73. logger.log("QUEUE_UPDATE", "SUCCESS", `User "${userId}" successfully update queuesong "${songId}".`);
  74. return cb({status: 'success', message: 'Successfully updated song.'});
  75. });
  76. }),
  77. /**
  78. * Removes a queuesong
  79. *
  80. * @param {Object} session - the session object automatically added by socket.io
  81. * @param {String} songId - the id of the queuesong that gets removed
  82. * @param {Function} cb - gets called with the result
  83. * @param {String} userId - the userId automatically added by hooks
  84. */
  85. remove: hooks.adminRequired((session, songId, cb, userId) => {
  86. async.waterfall([
  87. (next) => {
  88. db.models.queueSong.remove({ _id: songId }, next);
  89. }
  90. ], (err) => {
  91. if (err) {
  92. let error = 'An error occurred.';
  93. if (typeof err === "string") error = err;
  94. else if (err.message) error = err.message;
  95. logger.log("QUEUE_REMOVE", "ERROR", `Removing queuesong "${songId}" failed for user ${userId}. "${err.message}"`);
  96. return cb({status: 'failure', message: error});
  97. }
  98. cache.pub('queue.removedSong', songId);
  99. logger.log("QUEUE_REMOVE", "SUCCESS", `User "${userId}" successfully removed queuesong "${songId}".`);
  100. return cb({status: 'success', message: 'Successfully updated song.'});
  101. });
  102. }),
  103. /**
  104. * Creates a queuesong
  105. *
  106. * @param {Object} session - the session object automatically added by socket.io
  107. * @param {String} songId - the id of the song that gets added
  108. * @param {Function} cb - gets called with the result
  109. * @param {String} userId - the userId automatically added by hooks
  110. */
  111. add: hooks.loginRequired((session, songId, cb, userId) => {
  112. let requestedAt = Date.now();
  113. async.waterfall([
  114. (next) => {
  115. db.models.queueSong.findOne({_id: songId}, next);
  116. },
  117. (song, next) => {
  118. if (song) return next('This song is already in the queue.');
  119. db.models.song.findOne({_id: songId}, next);
  120. },
  121. // Get YouTube data from id
  122. (song, next) => {
  123. if (song) return next('This song has already been added.');
  124. //TODO Add err object as first param of callback
  125. utils.getSongFromYouTube(songId, (song) => {
  126. song.artists = [];
  127. song.genres = [];
  128. song.skipDuration = 0;
  129. song.thumbnail = 'empty';
  130. song.explicit = false;
  131. song.requestedBy = userId;
  132. song.requestedAt = requestedAt;
  133. next(null, song);
  134. });
  135. },
  136. (newSong, next) => {
  137. //TODO Add err object as first param of callback
  138. utils.getSongFromSpotify(newSong, (song) => {
  139. next(null, song);
  140. });
  141. },
  142. (newSong, next) => {
  143. const song = new db.models.queueSong(newSong);
  144. song.save(err => {
  145. if (err) return next(err);
  146. next(null, newSong);
  147. });
  148. }
  149. ], (err, newSong) => {
  150. if (err) {
  151. let error = 'An error occurred.';
  152. if (typeof err === "string") error = err;
  153. else if (err.message) error = err.message;
  154. return cb({status: 'failure', message: error});
  155. }
  156. cache.pub('queue.newSong', newSong._id);
  157. return cb({ status: 'success', message: 'Successfully added that song to the queue' });
  158. });
  159. })
  160. };