123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195 |
- 'use strict';
- const db = require('../db');
- const utils = require('../utils');
- const notifications = require('../notifications');
- const cache = require('../cache');
- const async = require('async');
- const config = require('config');
- const request = require('request');
- notifications.subscribe('queue.newSong', songId => {
- io.to('admin.queue').emit('event:song.new', { songId });
- });
- notifications.subscribe('queue.removedSong', songId => {
- io.to('admin.queue').emit('event:song.removed', { songId });
- });
- notifications.subscribe('queue.updatedSong', songId => {
- //TODO Retrieve new Song object
- io.to('admin.queue').emit('event:song.updated', { songId });
- });
- module.exports = {
- index: (session, cb) => {
- //TODO Require admin/login
- db.models.queueSong.find({}, (err, songs) => {
- if (err) throw err;
- cb(songs);
- });
- },
- update: (session, id, updatedSong, cb) => {
- //TODO Require admin/login
- //TODO Check if id and updatedSong is valid
- db.models.queueSong.findOne({ id }, function(err, queueSong) {
- if (err) throw err;
- // List of properties that are allowed to be changed
- const updatableProperties = ['id', 'title', 'artists', 'genres', 'thumbnail', 'explicit', 'duration', 'skipDuration'];
- //TODO Check if new id, if any, is already in use in queue or on rotation
- let updated = false;
- for (let prop in queueSong) {
- if (updatableProperties.indexOf(prop) !== -1 && updatedSong.hasOwnProperty('prop') && updatedSong[prop] !== queueSong[prop]) {
- queueSong[prop] = updatedSong[prop];
- updated = true;
- }
- }
- if (!updated) return cb({ status: 'failure', message: 'No properties changed' });
- queueSong.save((err) => {
- if (err) return cb({ status: 'failure', message: 'Couldn\'t save to Database' });
- return cb({ status: 'success', message: 'Successfully updated the queueSong object' });
- });
- });
- },
- remove: (session, _id, cb) => {
- // TODO Require admin/login
- db.models.queueSong.find({ _id }).remove().exec();
- cb({ status: 'success', message: 'Song was removed successfully' });
- },
- add: (session, id, cb) => {
- //TODO Require login
- //TODO Check if id is valid
- //TODO Check if id is already in queue/rotation
- // if (!session.logged_in) return cb({ status: 'failure', message: 'You must be logged in to add a song' });
- let requestedAt = Date.now();
- async.waterfall([
- // Get YouTube data from id
- (next) => {
- const youtubeParams = [
- 'part=snippet,contentDetails,statistics,status',
- `id=${encodeURIComponent(id)}`,
- `key=${config.get('apis.youtube.key')}`
- ].join('&');
- request(`https://www.googleapis.com/youtube/v3/videos?${youtubeParams}`, (err, res, body) => {
- if (err) {
- console.error(err);
- return next('Failed to find song from YouTube');
- }
- body = JSON.parse(body);
- //TODO Clean up duration converter
- let dur = body.items[0].contentDetails.duration;
- dur = dur.replace('PT', '');
- let durInSec = 0;
- dur = dur.replace(/([\d]*)H/, function(v, v2) {
- v2 = Number(v2);
- durInSec = (v2 * 60 * 60)
- return '';
- });
- dur = dur.replace(/([\d]*)M/, function(v, v2) {
- v2 = Number(v2);
- durInSec = (v2 * 60)
- return '';
- });
- dur = dur.replace(/([\d]*)S/, function(v, v2) {
- v2 = Number(v2);
- durInSec += v2;
- return '';
- });
- let newSong = {
- _id: body.items[0].id,
- title: body.items[0].snippet.title,
- artists: [],
- genres: [],
- duration: durInSec,
- skipDuration: 0,
- thumbnail: 'default.png',
- explicit: false,
- requestedBy: 'temp',
- requestedAt: requestedAt
- };
- next(null, newSong);
- });
- },
- (newSong, next) => {
- const spotifyParams = [
- `q=${encodeURIComponent(newSong.title)}`,
- `type=track`
- ].join('&');
- request(`https://api.spotify.com/v1/search?${spotifyParams}`, (err, res, body) => {
- if (err) {
- console.error(err);
- return next('Failed to find song from Spotify');
- }
- body = JSON.parse(body);
- durationArtistLoop:
- for (let i in body) {
- let items = body[i].items;
- for (let j in items) {
- let item = items[j];
- let hasArtist = false;
- for (let k = 0; k < item.artists.length; k++) {
- let artist = item.artists[k];
- if (newSong.title.indexOf(artist.name) !== -1) {
- hasArtist = true;
- }
- }
- if (hasArtist && newSong.title.indexOf(item.name) !== -1) {
- newSong.duration = item.duration_ms / 1000;
- newSong.artists = item.artists.map(artist => {
- return artist.name;
- });
- newSong.title = item.name;
- newSong.explicit = item.explicit;
- newSong.thumbnail = item.album.images[1].url;
- break durationArtistLoop;
- }
- }
- }
- next(null, newSong);
- });
- },
- (newSong, next) => {
- const song = new db.models.queueSong(newSong);
- song.save(err => {
- if (err) {
- console.error(err);
- return next('Failed to add song to database');
- }
- //stations.getStation(station).playlist.push(newSong);
- next(null, newSong);
- });
- }
- ],
- (err, newSong) => {
- if (err) return cb({ status: 'error', message: err });
- cache.pub('queue.newSong', newSong._id);
- return cb({ status: 'success', message: 'Successfully added that song to the queue' });
- });
- }
- };
|