123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260 |
- 'use strict';
- // nodejs modules
- const path = require('path'),
- fs = require('fs'),
- os = require('os'),
- events = require('events');
- // npm modules
- const config = require('config'),
- request = require('request'),
- waterfall = require('async/waterfall'),
- bcrypt = require('bcrypt'),
- passport = require('passport');
- // custom modules
- const globals = require('./globals'),
- stations = require('./stations');
- var eventEmitter = new events.EventEmitter();
- const edmStation = new stations.Station("edm", {
- "genres": ["edm"],
- playlist: [
- 'gCYcHz2k5x0'
- ],
- currentSongIndex: 0,
- paused: false,
- displayName: "EDM",
- description: "EDM Music"
- });
- const chillStation = new stations.Station("chill", {
- "genres": ["chill"],
- playlist: [
- 'gCYcHz2k5x0'
- ],
- currentSongIndex: 0,
- paused: false,
- displayName: "Chill",
- description: "Chill Music"
- });
- stations.addStation(edmStation);
- stations.addStation(chillStation);
- module.exports = {
- // module functions
- on: (name, cb) => eventEmitter.on(name, cb),
- emit: (name, data) => eventEmitter.emit(name, data),
- // core route handlers
- '/users/register': (session, username, email, password, recaptcha, cb) => {
- waterfall([
- // verify the request with google recaptcha
- (next) => {
- request({
- url: 'https://www.google.com/recaptcha/api/siteverify',
- method: 'POST',
- form: {
- 'secret': config.get("apis.recaptcha.secret"),
- 'response': recaptcha
- }
- }, next);
- },
- // check if the response from Google recaptcha is successful
- // if it is, we check if a user with the requested username already exists
- (response, body, next) => {
- let json = JSON.parse(body);
- console.log(json);
- if (json.success !== true) return next('Response from recaptcha was not successful');
- globals.db.models.user.findOne({ 'username': username }, next);
- },
- // if the user already exists, respond with that
- // otherwise check if a user with the requested email already exists
- (user, next) => {
- if (user) return next(true, { status: 'failure', message: 'A user with that username already exists' });
- globals.db.models.user.findOne({ 'email.address': email }, next);
- },
- // if the user already exists, respond with that
- // otherwise, generate a salt to use with hashing the new users password
- (user, next) => {
- if (user) return next(true, { status: 'failure', message: 'A user with that email already exists' });
- bcrypt.genSalt(10, next);
- },
- // hash the password
- (salt, next) => {
- bcrypt.hash(password, salt, next)
- },
- // save the new user to the database
- (hash, next) => {
- globals.db.models.user.create({
- username: username,
- email: {
- address: email,
- verificationToken: globals.utils.generateRandomString(64)
- },
- services: {
- password: {
- password: hash
- }
- }
- }, next);
- },
- // respond with the new user
- (newUser, next) => {
- next(null, { status: 'success', user: newUser })
- }
- ], (err, payload) => {
- // log this error somewhere
- if (err && err !== true) {
- console.error(err);
- return cb({ status: 'error', message: 'An error occurred while registering for an account' });
- }
- // respond with the payload that was passed to us earlier
- cb(payload);
- });
- },
- '/users/logout': (req, cb) => {
- if (!req.user || !req.user.logged_in) return cb({ status: 'failure', message: `You're not currently logged in` });
- req.logout();
- cb({ status: 'success', message: `You've been successfully logged out` });
- },
- '/stations': (session, cb) => {
- cb(stations.getStations().map(station => {
- return {
- id: station.id,
- playlist: station.playlist,
- displayName: station.displayName,
- description: station.description,
- currentSongIndex: station.currentSongIndex,
- users: station.users
- }
- }));
- },
- '/stations/join/:id': (session, id, cb) => {
- let station = stations.getStation(id);
- if (!station) return cb({ status: 'error', message: `Station with id '${id}' does not exist` });
- session.station_id = id;
- station.users++;
- cb({ status: 'success', users: station.users });
- },
- // leaves the users current station
- // returns the count of users that are still in that station
- '/stations/leave': (session, cb) => {
- let station = stations.getStation(session.station_id);
- if (!station) return cb({ status: 'failure', message: `Not currently in a station, or station doesn't exist` });
- session.station_id = "";
- station.users--;
- cb({ status: 'success', users: station.users });
- },
- '/youtube/getVideo/:query': (session, query, cb) => {
- const params = [
- 'part=snippet',
- `q=${encodeURIComponent(query)}`,
- `key=${config.get('apis.youtube.key')}`,
- 'type=video',
- 'maxResults=15'
- ].join('&');
- request(`https://www.googleapis.com/youtube/v3/search?${params}`, (err, res, body) => {
- if (err) {
- console.error(err);
- return cb({ status: 'error', message: 'Failed to search youtube with the requested query' });
- }
- cb({ status: 'success', data: JSON.parse(body) });
- });
- },
- '/stations/add/:song': (session, station, song, cb) => {
- if (!session.logged_in) return cb({ status: 'failure', message: 'You must be logged in to add a song' });
- const params = [
- 'part=snippet,contentDetails,statistics,status',
- `id=${encodeURIComponent(song.id)}`,
- `key=${config.get('apis.youtube.key')}`
- ].join('&');
- request(`https://www.googleapis.com/youtube/v3/videos?${params}`, (err, res, body) => {
- // TODO: Get data from Wikipedia and Spotify
- if (err) {
- console.error(err);
- return cb({ status: 'error', message: 'Failed to find song from youtube' });
- }
- const newSong = new globals.db.models.song({
- id: json.items[0].id,
- title: json.items[0].snippet.title,
- duration: globals.utils.convertTime(json.items[0].contentDetails.duration),
- thumbnail: json.items[0].snippet.thumbnails.high.url
- });
- // save the song to the database
- newSong.save(err => {
- if (err) {
- console.error(err);
- return cb({ status: 'error', message: 'Failed to save song from youtube to the database' });
- }
- stations.getStation(station).playlist.push(newSong);
- cb({ status: 'success', data: stations.getStation(station.playlist) });
- });
- });
- },
- '/songs': (session, cb) => {
- globals.db.models.song.find({}, (err, songs) => {
- if (err) throw err;
- cb(songs);
- });
- },
- '/songs/:song/update': (session, song, cb) => {
- globals.db.models.song.findOneAndUpdate({ id: song.id }, song, { upsert: true }, (err, updatedSong) => {
- if (err) throw err;
- cb(updatedSong);
- });
- },
- '/songs/:song/remove': (session, song, cb) => {
- globals.db.models.song.find({ id: song.id }).remove().exec();
- }
- };
|