queueSongs.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. 'use strict';
  2. const db = require('../db');
  3. const utils = require('../utils');
  4. const async = require('async');
  5. module.exports = {
  6. index: (session, cb) => {
  7. //TODO Require admin/login
  8. db.models.song.find({}, (err, songs) => {
  9. if (err) throw err;
  10. cb(songs);
  11. });
  12. },
  13. update: (session, id, song, cb) => {
  14. //TODO Require admin/login
  15. db.models.song.findOneAndUpdate({ id: id }, song, { upsert: true }, (err, updatedSong) => {
  16. if (err) throw err;
  17. cb(updatedSong);
  18. });
  19. },
  20. remove: (session, id, cb) => {
  21. //TODO Require admin/login
  22. db.models.song.find({ id: song.id }).remove().exec();
  23. },
  24. add: (session, id, cb) => {
  25. //TODO Require login
  26. //TODO Check if id is valid
  27. //TODO Check if id is duplicate
  28. // if (!session.logged_in) return cb({ status: 'failure', message: 'You must be logged in to add a song' });
  29. let requestedAt = Date.now();
  30. async.waterfall([
  31. // Get YouTube data from id
  32. (next) => {
  33. const youtubeParams = [
  34. 'part=snippet,contentDetails,statistics,status',
  35. `id=${encodeURIComponent(id)}`,
  36. `key=${config.get('apis.youtube.key')}`
  37. ].join('&');
  38. request(`https://www.googleapis.com/youtube/v3/videos?${youtubeParams}`, (err, res, body) => {
  39. if (err) {
  40. console.error(err);
  41. return next('Failed to find song from YouTube');
  42. }
  43. body = JSON.parse(body);
  44. //TODO Clean up duration converter
  45. let dur = body.items[0].contentDetails.duration;
  46. dur = dur.replace("PT", "");
  47. let durInSec = 0;
  48. dur = dur.replace(/([\d]*)H/, function(v, v2) {
  49. v2 = Number(v2);
  50. durInSec = (v2 * 60 * 60)
  51. return "";
  52. });
  53. dur = dur.replace(/([\d]*)M/, function(v, v2) {
  54. v2 = Number(v2);
  55. durInSec = (v2 * 60)
  56. return "";
  57. });
  58. dur = dur.replace(/([\d]*)S/, function(v, v2) {
  59. v2 = Number(v2);
  60. durInSec += v2;
  61. return "";
  62. });
  63. let newSong = {
  64. id: body.items[0].id,
  65. title: body.items[0].snippet.title,
  66. artists: [],
  67. genres: [],
  68. duration: durInSec,
  69. skipDuration: 0,
  70. thumbnail: '',
  71. requestedBy: '',
  72. requestedAt: requestedAt
  73. };
  74. next(null, newSong);
  75. });
  76. },
  77. (newSong, next) => {
  78. const spotifyParams = [
  79. `q=${encodeURIComponent(newSong.title)}`,
  80. `type=track`
  81. ].join('&');
  82. request(`https://api.spotify.com/v1/search?${spotifyParams}`, (err, res, body) => {
  83. if (err) {
  84. console.error(err);
  85. return next('Failed to find song from Spotify');
  86. }
  87. body = JSON.parse(body);
  88. durationArtistLoop:
  89. for (let i in body) {
  90. let items = body[i].items;
  91. for (let j in items) {
  92. let item = items[j];
  93. let hasArtist = false;
  94. for (let k = 0; k < item.artists.length; k++) {
  95. let artist = item.artists[k];
  96. if (newSong.title.indexOf(artist.name) !== -1) {
  97. hasArtist = true;
  98. }
  99. }
  100. if (hasArtist && newSong.title.indexOf(item.name) !== -1) {
  101. newSong.duration = item.duration_ms / 1000;
  102. newSong.artists = item.map(function (artist) {
  103. return artist.name;
  104. });
  105. newSong.title = item.name;
  106. break durationArtistLoop;
  107. }
  108. }
  109. }
  110. next(null, newSong);
  111. });
  112. },
  113. (newSong, next) => {
  114. const song = new db.models.song(newSong);
  115. song.save(err => {
  116. if (err) {
  117. console.error(err);
  118. return next('Failed to add song to database.');
  119. }
  120. //stations.getStation(station).playlist.push(newSong);
  121. next(null);
  122. });
  123. }
  124. ],
  125. (err) => {
  126. if (err) {
  127. return cb({ status: 'failure', message: err });
  128. }
  129. return cb({ status: 'success', message: 'Successfully added that song to the queue.' });
  130. });
  131. }
  132. };