playlists.js 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. import async from "async";
  2. import CoreClass from "../core";
  3. let PlaylistsModule;
  4. let CacheModule;
  5. let DBModule;
  6. let UtilsModule;
  7. class _PlaylistsModule extends CoreClass {
  8. // eslint-disable-next-line require-jsdoc
  9. constructor() {
  10. super("playlists");
  11. PlaylistsModule = this;
  12. }
  13. /**
  14. * Initialises the playlists module
  15. *
  16. * @returns {Promise} - returns promise (reject, resolve)
  17. */
  18. async initialize() {
  19. this.setStage(1);
  20. CacheModule = this.moduleManager.modules.cache;
  21. DBModule = this.moduleManager.modules.db;
  22. UtilsModule = this.moduleManager.modules.utils;
  23. this.playlistModel = await DBModule.runJob("GET_MODEL", { modelName: "playlist" });
  24. this.playlistSchemaCache = await CacheModule.runJob("GET_SCHEMA", { schemaName: "playlist" });
  25. this.setStage(2);
  26. return new Promise((resolve, reject) =>
  27. async.waterfall(
  28. [
  29. next => {
  30. this.setStage(3);
  31. CacheModule.runJob("HGETALL", { table: "playlists" })
  32. .then(playlists => {
  33. next(null, playlists);
  34. })
  35. .catch(next);
  36. },
  37. (playlists, next) => {
  38. this.setStage(4);
  39. if (!playlists) return next();
  40. const playlistIds = Object.keys(playlists);
  41. return async.each(
  42. playlistIds,
  43. (playlistId, next) => {
  44. PlaylistsModule.playlistModel.findOne({ _id: playlistId }, (err, playlist) => {
  45. if (err) next(err);
  46. else if (!playlist) {
  47. CacheModule.runJob("HDEL", {
  48. table: "playlists",
  49. key: playlistId
  50. })
  51. .then(() => next())
  52. .catch(next);
  53. } else next();
  54. });
  55. },
  56. next
  57. );
  58. },
  59. next => {
  60. this.setStage(5);
  61. PlaylistsModule.playlistModel.find({}, next);
  62. },
  63. (playlists, next) => {
  64. this.setStage(6);
  65. async.each(
  66. playlists,
  67. (playlist, cb) => {
  68. CacheModule.runJob("HSET", {
  69. table: "playlists",
  70. key: playlist._id,
  71. value: PlaylistsModule.playlistSchemaCache(playlist)
  72. })
  73. .then(() => cb())
  74. .catch(next);
  75. },
  76. next
  77. );
  78. }
  79. ],
  80. async err => {
  81. if (err) {
  82. const formattedErr = await UtilsModule.runJob("GET_ERROR", {
  83. error: err
  84. });
  85. reject(new Error(formattedErr));
  86. } else resolve();
  87. }
  88. )
  89. );
  90. }
  91. /**
  92. * Gets a playlist by id from the cache or Mongo, and if it isn't in the cache yet, adds it the cache
  93. *
  94. * @param {object} payload - object that contains the payload
  95. * @param {string} payload.playlistId - the id of the playlist we are trying to get
  96. * @returns {Promise} - returns promise (reject, resolve)
  97. */
  98. GET_PLAYLIST(payload) {
  99. return new Promise((resolve, reject) =>
  100. async.waterfall(
  101. [
  102. next => {
  103. CacheModule.runJob("HGETALL", { table: "playlists" }, this)
  104. .then(playlists => {
  105. next(null, playlists);
  106. })
  107. .catch(next);
  108. },
  109. (playlists, next) => {
  110. if (!playlists) return next();
  111. const playlistIds = Object.keys(playlists);
  112. return async.each(
  113. playlistIds,
  114. (playlistId, next) => {
  115. PlaylistsModule.playlistModel.findOne({ _id: playlistId }, (err, playlist) => {
  116. if (err) next(err);
  117. else if (!playlist) {
  118. CacheModule.runJob(
  119. "HDEL",
  120. {
  121. table: "playlists",
  122. key: playlistId
  123. },
  124. this
  125. )
  126. .then(() => next())
  127. .catch(next);
  128. } else next();
  129. });
  130. },
  131. next
  132. );
  133. },
  134. next => {
  135. CacheModule.runJob(
  136. "HGET",
  137. {
  138. table: "playlists",
  139. key: payload.playlistId
  140. },
  141. this
  142. )
  143. .then(playlist => next(null, playlist))
  144. .catch(next);
  145. },
  146. (playlist, next) => {
  147. if (playlist) return next(true, playlist);
  148. return PlaylistsModule.playlistModel.findOne({ _id: payload.playlistId }, next);
  149. },
  150. (playlist, next) => {
  151. if (playlist) {
  152. CacheModule.runJob(
  153. "HSET",
  154. {
  155. table: "playlists",
  156. key: payload.playlistId,
  157. value: playlist
  158. },
  159. this
  160. )
  161. .then(playlist => {
  162. next(null, playlist);
  163. })
  164. .catch(next);
  165. } else next("Playlist not found");
  166. }
  167. ],
  168. (err, playlist) => {
  169. if (err && err !== true) return reject(new Error(err));
  170. return resolve(playlist);
  171. }
  172. )
  173. );
  174. }
  175. /**
  176. * Gets a playlist from id from Mongo and updates the cache with it
  177. *
  178. * @param {object} payload - object that contains the payload
  179. * @param {string} payload.playlistId - the id of the playlist we are trying to update
  180. * @returns {Promise} - returns promise (reject, resolve)
  181. */
  182. UPDATE_PLAYLIST(payload) {
  183. // playlistId, cb
  184. return new Promise((resolve, reject) =>
  185. async.waterfall(
  186. [
  187. next => {
  188. PlaylistsModule.playlistModel.findOne({ _id: payload.playlistId }, next);
  189. },
  190. (playlist, next) => {
  191. if (!playlist) {
  192. CacheModule.runJob("HDEL", {
  193. table: "playlists",
  194. key: payload.playlistId
  195. });
  196. return next("Playlist not found");
  197. }
  198. return CacheModule.runJob(
  199. "HSET",
  200. {
  201. table: "playlists",
  202. key: payload.playlistId,
  203. value: playlist
  204. },
  205. this
  206. )
  207. .then(playlist => {
  208. next(null, playlist);
  209. })
  210. .catch(next);
  211. }
  212. ],
  213. (err, playlist) => {
  214. if (err && err !== true) return reject(new Error(err));
  215. return resolve(playlist);
  216. }
  217. )
  218. );
  219. }
  220. /**
  221. * Deletes playlist from id from Mongo and cache
  222. *
  223. * @param {object} payload - object that contains the payload
  224. * @param {string} payload.playlistId - the id of the playlist we are trying to delete
  225. * @returns {Promise} - returns promise (reject, resolve)
  226. */
  227. DELETE_PLAYLIST(payload) {
  228. // playlistId, cb
  229. return new Promise((resolve, reject) =>
  230. async.waterfall(
  231. [
  232. next => {
  233. PlaylistsModule.playlistModel.deleteOne({ _id: payload.playlistId }, next);
  234. },
  235. (res, next) => {
  236. CacheModule.runJob(
  237. "HDEL",
  238. {
  239. table: "playlists",
  240. key: payload.playlistId
  241. },
  242. this
  243. )
  244. .then(() => next())
  245. .catch(next);
  246. }
  247. ],
  248. err => {
  249. if (err && err !== true) return reject(new Error(err));
  250. return resolve();
  251. }
  252. )
  253. );
  254. }
  255. }
  256. export default new _PlaylistsModule();