playlists.js 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. 'use strict';
  2. const db = require('../db');
  3. const io = require('../io');
  4. const cache = require('../cache');
  5. const utils = require('../utils');
  6. const hooks = require('./hooks');
  7. const async = require('async');
  8. const playlists = require('../playlists');
  9. const songs = require('../songs');
  10. let lib = {
  11. indexForUser: (session, createdBy, cb) => {
  12. db.models.playlist.find({ createdBy }, (err, playlists) => {
  13. if (err) throw err;
  14. cb({
  15. status: 'success',
  16. data: playlists
  17. });
  18. });
  19. },
  20. create: (session, data, cb) => {
  21. async.waterfall([
  22. (next) => {
  23. return (data) ? next() : cb({ 'status': 'failure', 'message': 'Invalid data' });
  24. },
  25. (next) => {
  26. const { name, displayName, songs, createdBy } = data;
  27. db.models.playlist.create({
  28. displayName,
  29. songs,
  30. createdBy,
  31. createdAt: Date.now()
  32. }, next);
  33. }
  34. ], (err, playlist) => {
  35. if (err) return cb({ 'status': 'failure', 'message': 'Something went wrong'});
  36. cache.pub('playlist.create', data._id);
  37. return cb({ 'status': 'success', 'message': 'Successfully created playlist' });
  38. });
  39. },
  40. getPlaylist: (session, id, cb) => {
  41. playlists.getPlaylist(id, (err, playlist) => {
  42. if (err == null) return cb({
  43. status: 'success',
  44. data: playlist
  45. });
  46. });
  47. },
  48. update: (session, _id, playlist, cb) => {
  49. db.models.playlist.findOneAndUpdate({ _id }, playlist, { upsert: true }, (err, data) => {
  50. if (err) throw err;
  51. return cb({ status: 'success', message: 'Playlist has been successfully updated', data });
  52. });
  53. },
  54. addSongToPlaylist: (session, songId, playlistId, cb) => {
  55. async.waterfall([
  56. (next) => {
  57. songs.getSong(songId, (err, song) => {
  58. if (err) {
  59. utils.getSongFromYouTube(songId, (song) => {
  60. next(null, song);
  61. });
  62. } else {
  63. next(null, {_id: songId, title: song.title, duration: song.duration});
  64. }
  65. });
  66. },
  67. (newSong, next) => {
  68. db.models.playlist.findOne({ _id: playlistId }, (err, playlist) => {
  69. if (err) throw err;
  70. playlist.songs.push(newSong);
  71. playlist.save(err => {
  72. if (err) {
  73. console.error(err);
  74. return next('Failed to add song to playlist');
  75. }
  76. cache.hset('playlists', playlistId, playlist);
  77. next(null, playlist);
  78. });
  79. });
  80. }
  81. ],
  82. (err, playlist) => {
  83. if (err) return cb({ status: 'error', message: err });
  84. else return cb({ status: 'success', message: 'Song has been successfully added to the playlist', data: playlist.songs });
  85. });
  86. },
  87. addSetToPlaylist: (session, url, playlistId, cb) => {
  88. async.waterfall([
  89. (next) => {
  90. utils.getPlaylistFromYouTube(url, songs => {
  91. next(null, songs);
  92. });
  93. },
  94. (songs, next) => {
  95. for (let s = 0; s < songs.length; s++) {
  96. lib.addSongToPlaylist(session, songs[s].contentDetails.videoId, playlistId, (res) => {});
  97. }
  98. next(null);
  99. },
  100. (next) => {
  101. db.models.playlist.findOne({ _id: playlistId }, (err, playlist) => {
  102. if (err) console.error(err);
  103. next(null, playlist);
  104. });
  105. }
  106. ],
  107. (err, playlist) => {
  108. if (err) return cb({ status: 'error', message: err });
  109. else if (playlist.songs) return cb({ status: 'success', message: 'Playlist has been successfully added', data: playlist.songs });
  110. });
  111. },
  112. removeSongFromPlaylist: (session, songId, playlistId, cb) => {
  113. db.models.playlist.findOne({ _id: playlistId }, (err, playlist) => {
  114. if (err) console.error(err);
  115. for (let z = 0; z < playlist.songs.length; z++) {
  116. if (playlist.songs[z]._id == songId) playlist.songs.shift(playlist.songs[z]);
  117. }
  118. playlist.save(err => {
  119. if (err) {
  120. console.error(err);
  121. return next('Failed to remove song to playlist');
  122. }
  123. cache.hset('playlists', playlistId, playlist);
  124. return cb({ status: 'success', message: 'Song has been successfully removed from playlist', data: playlist.songs });
  125. });
  126. });
  127. },
  128. updateDisplayName: (session, _id, displayName, cb) => {
  129. db.models.playlist.findOneAndUpdate({ _id }, { displayName }, { upsert: true }, (err, res) => {
  130. if (err) console.error(err);
  131. cache.hset('playlists', _id, res);
  132. return cb({ status: 'success', message: 'Playlist has been successfully updated' });
  133. });
  134. },
  135. promoteSong: (session, playlistId, fromIndex, cb) => {
  136. db.models.playlist.findOne({ _id: playlistId }, (err, playlist) => {
  137. if (err) console.error(err);
  138. let song = playlist.songs[fromIndex];
  139. playlist.songs.splice(fromIndex, 1);
  140. playlist.songs.splice((fromIndex + 1), 0, song);
  141. playlist.save(err => {
  142. if (err) {
  143. console.error(err);
  144. return next('Failed to promote song');
  145. }
  146. cache.hset('playlists', playlistId, playlist);
  147. return cb({ status: 'success', data: playlist.songs });
  148. });
  149. });
  150. },
  151. demoteSong: (session, playlistId, fromIndex, cb) => {
  152. db.models.playlist.findOne({ _id: playlistId }, (err, playlist) => {
  153. if (err) console.error(err);
  154. let song = playlist.songs[fromIndex];
  155. playlist.songs.splice(fromIndex, 1);
  156. playlist.songs.splice((fromIndex - 1), 0, song);
  157. playlist.save(err => {
  158. if (err) {
  159. console.error(err);
  160. return next('Failed to demote song');
  161. }
  162. cache.hset('playlists', playlistId, playlist);
  163. return cb({ status: 'success', data: playlist.songs });
  164. });
  165. });
  166. },
  167. remove: (session, _id, cb) => {
  168. db.models.playlist.remove({ _id }).exec(err => {
  169. if (err) console.error(err);
  170. cache.hdel('playlists', _id, () => {
  171. return cb({ status: 'success', message: 'Playlist successfully removed' });
  172. });
  173. });
  174. }
  175. };
  176. module.exports = lib;