playlists.js 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. 'use strict';
  2. const cache = require('./cache');
  3. const db = require('./db');
  4. const async = require('async');
  5. let initialized = false;
  6. let lockdown = false;
  7. module.exports = {
  8. /**
  9. * Initializes the playlists module, and exits if it is unsuccessful
  10. *
  11. * @param {Function} cb - gets called once we're done initializing
  12. */
  13. init: cb => {
  14. async.waterfall([
  15. (next) => {
  16. cache.hgetall('playlists', next);
  17. },
  18. (playlists, next) => {
  19. if (!playlists) return next();
  20. let playlistIds = Object.keys(playlists);
  21. async.each(playlistIds, (playlistId, next) => {
  22. db.models.playlist.findOne({_id: playlistId}, (err, playlist) => {
  23. if (err) next(err);
  24. else if (!playlist) {
  25. cache.hdel('playlists', playlistId, next);
  26. }
  27. else next();
  28. });
  29. }, next);
  30. },
  31. (next) => {
  32. db.models.playlist.find({}, next);
  33. },
  34. (playlists, next) => {
  35. async.each(playlists, (playlist, next) => {
  36. cache.hset('playlists', playlist._id, cache.schemas.playlist(playlist), next);
  37. }, next);
  38. }
  39. ], (err) => {
  40. if (lockdown) return this._lockdown();
  41. if (err) {
  42. err = utils.getError(err);
  43. cb(err);
  44. } else {
  45. initialized = true;
  46. cb();
  47. }
  48. });
  49. },
  50. /**
  51. * Gets a playlist by id from the cache or Mongo, and if it isn't in the cache yet, adds it the cache
  52. *
  53. * @param {String} playlistId - the id of the playlist we are trying to get
  54. * @param {Function} cb - gets called once we're done initializing
  55. */
  56. getPlaylist: (playlistId, cb) => {
  57. if (lockdown) return cb('Lockdown');
  58. async.waterfall([
  59. (next) => {
  60. cache.hgetall('playlists', next);
  61. },
  62. (playlists, next) => {
  63. if (!playlists) return next();
  64. let playlistIds = Object.keys(playlists);
  65. async.each(playlistIds, (playlistId, next) => {
  66. db.models.playlist.findOne({_id: playlistId}, (err, playlist) => {
  67. if (err) next(err);
  68. else if (!playlist) {
  69. cache.hdel('playlists', playlistId, next);
  70. }
  71. else next();
  72. });
  73. }, next);
  74. },
  75. (next) => {
  76. cache.hget('playlists', playlistId, next);
  77. },
  78. (playlist, next) => {
  79. if (playlist) return next(true, playlist);
  80. db.models.playlist.findOne({ _id: playlistId }, next);
  81. },
  82. (playlist, next) => {
  83. if (playlist) {
  84. cache.hset('playlists', playlistId, playlist, next);
  85. } else next('Playlist not found');
  86. },
  87. ], (err, playlist) => {
  88. if (err && err !== true) return cb(err);
  89. else cb(null, playlist);
  90. });
  91. },
  92. /**
  93. * Gets a playlist from id from Mongo and updates the cache with it
  94. *
  95. * @param {String} playlistId - the id of the playlist we are trying to update
  96. * @param {Function} cb - gets called when an error occurred or when the operation was successful
  97. */
  98. updatePlaylist: (playlistId, cb) => {
  99. if (lockdown) return cb('Lockdown');
  100. async.waterfall([
  101. (next) => {
  102. db.models.playlist.findOne({ _id: playlistId }, next);
  103. },
  104. (playlist, next) => {
  105. if (!playlist) {
  106. cache.hdel('playlists', playlistId);
  107. return next('Playlist not found');
  108. }
  109. cache.hset('playlists', playlistId, playlist, next);
  110. }
  111. ], (err, playlist) => {
  112. if (err && err !== true) return cb(err);
  113. cb(null, playlist);
  114. });
  115. },
  116. /**
  117. * Deletes playlist from id from Mongo and cache
  118. *
  119. * @param {String} playlistId - the id of the playlist we are trying to delete
  120. * @param {Function} cb - gets called when an error occurred or when the operation was successful
  121. */
  122. deletePlaylist: (playlistId, cb) => {
  123. if (lockdown) return cb('Lockdown');
  124. async.waterfall([
  125. (next) => {
  126. db.models.playlist.deleteOne({ _id: playlistId }, next);
  127. },
  128. (res, next) => {
  129. cache.hdel('playlists', playlistId, next);
  130. }
  131. ], (err) => {
  132. if (err && err !== true) return cb(err);
  133. cb(null);
  134. });
  135. },
  136. _lockdown: () => {
  137. lockdown = true;
  138. }
  139. };