Browse Source

Restored routes and added sockets to them.

The IO object is passed when the route is required, making for a
clunky, yet structure preserving, solution.
Josh Bicking 6 years ago
parent
commit
e61e1448da
8 changed files with 739 additions and 546 deletions
  1. 71 0
      app.js
  2. 90 0
      bin/www
  3. 0 243
      index.js
  4. 352 297
      package-lock.json
  5. 9 6
      package.json
  6. 190 0
      routes/index.js
  7. 18 0
      routes/player-demo.js
  8. 9 0
      routes/users.js

+ 71 - 0
app.js

@@ -0,0 +1,71 @@
+// express and http
+var express = require('express');
+var app = express();
+// Create the server here, so socket.io can control it.
+var server = require('http').Server(app);
+
+var io = require('socket.io')(server);
+
+// view engine setup
+var path = require('path');
+app.set('views', path.join(__dirname, 'views'));
+app.set('view engine', 'hbs');
+
+// logging
+var logger = require('morgan');
+app.use(logger('dev'));
+
+var routes = require('./routes/index')(io);
+
+// Unused (for now) cookies and favicons
+//var favicon = require('serve-favicon');
+//var cookieParser = require('cookie-parser');
+// uncomment after placing your favicon in /public
+//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
+//app.use(cookieParser());
+app.use(express.static(path.join(__dirname, 'public')));
+
+// // Add socket.io to res in the event loop.
+// app.use(function(req, res, next){
+//   res.io = io;
+//   next();
+// });
+
+// Add the route.
+app.use('/', routes);
+
+
+// catch 404 and forward to error handler
+app.use(function(req, res, next) {
+  var err = new Error('Not Found');
+  err.status = 404;
+  next(err);
+});
+
+// error handlers
+
+// development error handler
+// will print stacktrace
+if (app.get('env') === 'development') {
+  app.use(function(err, req, res, next) {
+    res.status(err.status || 500);
+    res.render('error', {
+      message: err.message,
+      error: err
+    });
+  });
+}
+
+// production error handler
+// no stacktraces leaked to user
+app.use(function(err, req, res, next) {
+  res.status(err.status || 500);
+  res.render('error', {
+    message: err.message,
+    error: {}
+  });
+});
+
+// Export the server to bin/www, since we're creating it here.
+module.exports = {app: app, server: server, io: io};
+

+ 90 - 0
bin/www

@@ -0,0 +1,90 @@
+#!/usr/bin/env node
+
+/**
+ * Module dependencies.
+ */
+
+var app = require('../app').app;
+var debug = require('debug')('lan-jukebox:server');
+var http = require('http');
+
+/**
+ * Get port from environment and store in Express.
+ */
+
+var port = normalizePort(process.env.PORT || '3000');
+app.set('port', port);
+
+/**
+ * Create HTTP server.
+ */
+
+var server = require('../app').server;
+
+/**
+ * Listen on provided port, on all network interfaces.
+ */
+
+server.listen(port);
+server.on('error', onError);
+server.on('listening', onListening);
+
+/**
+ * Normalize a port into a number, string, or false.
+ */
+
+function normalizePort(val) {
+  var port = parseInt(val, 10);
+
+  if (isNaN(port)) {
+    // named pipe
+    return val;
+  }
+
+  if (port >= 0) {
+    // port number
+    return port;
+  }
+
+  return false;
+}
+
+/**
+ * Event listener for HTTP server "error" event.
+ */
+
+function onError(error) {
+  if (error.syscall !== 'listen') {
+    throw error;
+  }
+
+  var bind = typeof port === 'string'
+    ? 'Pipe ' + port
+    : 'Port ' + port;
+
+  // handle specific listen errors with friendly messages
+  switch (error.code) {
+    case 'EACCES':
+      console.error(bind + ' requires elevated privileges');
+      process.exit(1);
+      break;
+    case 'EADDRINUSE':
+      console.error(bind + ' is already in use');
+      process.exit(1);
+      break;
+    default:
+      throw error;
+  }
+}
+
+/**
+ * Event listener for HTTP server "listening" event.
+ */
+
+function onListening() {
+  var addr = server.address();
+  var bind = typeof addr === 'string'
+    ? 'pipe ' + addr
+    : 'port ' + addr.port;
+  debug('Listening on ' + bind);
+}

+ 0 - 243
index.js

@@ -1,243 +0,0 @@
-// Express and http
-var express = require('express');
-var app = express();
-var http = require('http').Server(app);
-
-// view engine setup
-var path = require('path');
-app.set('views', path.join(__dirname, 'views'));
-app.set('view engine', 'hbs');
-
-// logging
-var logger = require('morgan');
-app.use(logger('dev'));
-
-
-// Body parsing and validating
-var bodyParser = require('body-parser');
-app.use(bodyParser.urlencoded({extended: true}));
-app.use(bodyParser.json());
-
-var expressValidator = require('express-validator');
-app.use(expressValidator());
-
-// Sockets
-var io = require('socket.io').listen(http);
-
-// Unused (for now) cookies and favicons
-//var favicon = require('serve-favicon');
-//var cookieParser = require('cookie-parser');
-// uncomment after placing your favicon in /public
-//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
-//app.use(cookieParser());
-app.use(express.static(path.join(__dirname, 'public')));
-
-// Child process, for spawning youtube-dl
-var child_process = require('child_process');
-
-// The location of the youtube-dl executable
-var YOUTUBE_DL_LOC = '/usr/bin/youtube-dl'
-
-// Keep track of music to play, playing, and played
-var playlist = [];
-var playing = 'None';
-var played = [];
-
-// Player module
-var Player = require('player');
-
-// Create a player with the proper error handling.
-function playerCreator(song) {
-    if (song)
-	return new Player(song)
-	.on('error', function(err) {playerHandleError(playlist, played)})
-    return new Player()
-	.on('error', function(err) {playerHandleError(playlist, played)})
-}
-
-player = playerCreator();
-
-// Player functionality
-
-// Songs move from playlist (if nothing is playing presently), to playing, to played.
-
-// TODO check if song already exists in played.
-
-// event: on error (No next song was found).
-function playerHandleError(playlist, played) {
-
-    // TODO Workaround for a bug in player: wait a couple seconds so the
-    // songs don't overlap.
-
-    // Move the recently playing song to played.
-    played.push(playing);
-
-    if (playlist.length != 0) {
-	// Play the next song.
-	player = playerCreator(playlist[0]);
-	player.play();
-
-	// Remove the added song.
-	playing = playlist[0];
-	playlist.shift();
-    } else {
-	// Reset the object, resetting its playlist.
-	player = playerCreator();
-	playing = 'None';
-    }
-}
-
-// Add a song and start the playlist, if it's empty.
-function playerAddSong(song) {
-    if (player.list.length == 0) {
-	// If this is the player's first song, start it.
-	player = playerCreator(song);
-	player.play();
-	playing = song;
-    } else {
-	// Otherwise add it to the queue
-	playlist.push(song);
-    }
-
-}
-
-
-/* GET home page. */
-app.get('/', function(req, res, next) {
-    var playlist_view;
-    if(playlist.length) {
-	playlist_view = '<p>Playlist:</p><ul>';
-	for(var i=0; i < playlist.length; i++) {
-	    playlist_view +=
-		'<li>' +
-		playlist[i].replace(/^\.\/downloads\//, '') .replace(/\.mp3$/, '') +
-		'</li>';
-	}
-	playlist_view += '</ul>';
-    } else {
-	playlist_view = '<p>No songs in playlist.</p>';
-    }
-    var playing_view = '<p>Now playing: ' + playing.replace(/^\.\/downloads\//, '') .replace(/\.mp3$/, '') + '</p>';
-    var played_view;
-    if(played.length) {
-	played_view = '<p>Played:</p><ul>';
-	for(var i=0; i < played.length; i++) {
-	    played_view +=
-		'<li>' +
-		played[i].replace(/^\.\/downloads\//, '') .replace(/\.mp3$/, '') +
-		'</li>';
-	}
-	played_view += '</ul>';
-    } else {
-	played_view = '<p>No played songs.</p>';
-    }
-    res.render('index', { playlist_view: playlist_view,
-			  playing_view: playing_view,
-			  played_view: played_view });
-});
-
-app.get('/youtube', function(req, res, next) {
-  res.render('youtube');
-});
-
-app.use(expressValidator({
-    customValidators: {
-	dlSuccess: function(video) {
-	    // Test if the requested video is available.
-	    // TODO make this non-blocking so music doesn't stop
-	    var youtube_dl = child_process.spawnSync(YOUTUBE_DL_LOC, ['-s', video]);
-
-	    // DEBUG: for when I forget to change the var
-	    if(youtube_dl.stderr == null) {
-		console.log("Your youtube-dl location is probably invalid.");
-	    }
-
-	    if (youtube_dl.stderr.toString()) {
-		return false;
-	    }
-	    return true;
-	}
-    }
- }
-));
-
-app.post('/youtube', function(req, res) {
-    var video = req.body.video;
-
-    req.checkBody('video', 'URL is not valid.').dlSuccess();
-
-    var errors = req.validationErrors();
-
-    if(errors){
-	res.render('youtube', {
-	    errors:errors
-	});
-    } else {
-	var youtube_dl = child_process.spawn(YOUTUBE_DL_LOC, ['-x', '--audio-format', 'mp3', '-o', 'downloads/%(title)s.%(ext)s', video]);
-	youtube_dl.on('close', (code) => {
-	    console.log("Done getting " + video);
-	    var error;
-	    youtube_dl.stderr.on('data', (data) => {
-		error = data;
-		console.log(`Error getting video: ${data}`);
-		// TODO give error to user when they return to /
-	    });
-
-	    if(!error) {
-		var youtube_dl_get_title = child_process.spawnSync(YOUTUBE_DL_LOC, ['--get-title', video]);
-		console.log(youtube_dl_get_title.stdout.toString());
-		playerAddSong('./downloads/' + youtube_dl_get_title.stdout.toString()
-			      .replace('\n', '')
-			      .replace(new RegExp('"', 'g'), '\'')
-			      + ".mp3");
-	    }
-	    res.redirect('/');
-	});
-    }
-});
-
-app.get('/file', function(req, res, next) {
-  res.render('file');
-});
-
-
-// error handlers
-
-// catch 404 and forward to error handler
-app.use(function(req, res, next) {
-  var err = new Error('Not Found');
-  err.status = 404;
-  next(err);
-});
-
-// error handlers
-
-// development error handler
-// will print stacktrace
-if (app.get('env') === 'development') {
-  app.use(function(err, req, res, next) {
-    res.status(err.status || 500);
-    res.render('error', {
-      message: err.message,
-      error: err
-    });
-  });
-}
-
-// production error handler
-// no stacktraces leaked to user
-app.use(function(err, req, res, next) {
-  res.status(err.status || 500);
-  res.render('error', {
-    message: err.message,
-    error: {}
-  });
-});
-
-io.on('connection', function(socket){
-  console.log('a user connected');
-});
-
-http.listen(3000, function(){
-      console.log('listening on *:3000');
-});

File diff suppressed because it is too large
+ 352 - 297
package-lock.json


+ 9 - 6
package.json

@@ -1,17 +1,20 @@
 {
   "name": "lan-jukebox",
   "version": "0.0.0",
+  "private": true,
   "scripts": {
-    "start": "node ./index.js"
+    "start": "node ./bin/www"
   },
   "dependencies": {
-    "body-parser": "^1.17.2",
-    "express": "^4.15.3",
+    "body-parser": "~1.15.1",
+    "cookie-parser": "~1.4.3",
+    "debug": "^2.6.8",
+    "express": "~4.13.4",
     "express-validator": "^3.2.1",
-    "hbs": "^4.0.1",
-    "morgan": "^1.8.2",
+    "hbs": "~4.0.0",
+    "morgan": "~1.7.0",
     "player": "^0.6.1",
-    "serve-favicon": "^2.4.3",
+    "serve-favicon": "~2.3.0",
     "socket.io": "^2.0.3"
   }
 }

+ 190 - 0
routes/index.js

@@ -0,0 +1,190 @@
+module.exports = function (io) {
+    var app = require('express')();
+
+    // Body parsing
+    var bodyParser = require('body-parser');
+    app.use(bodyParser.urlencoded({extended: true}));
+    app.use(bodyParser.json());
+
+    // Validation
+    var expressValidator = require('express-validator');
+    app.use(expressValidator());
+
+    // Child process, for spawning youtube-dl
+    var child_process = require('child_process');
+
+    // The location of the youtube-dl executable
+    var YOUTUBE_DL_LOC = '/usr/bin/youtube-dl'
+
+    // Keep track of music to play, playing, and played
+    var playlist = [];
+    var playing = 'None';
+    var played = [];
+
+    var Player = require('player');
+
+    io.on('connection', function (socket) {
+	console.log('a user connected');
+    });
+
+    // Create a player with the proper error handling.
+    function playerCreator(song) {
+	if (song)
+	    return new Player(song)
+	    .on('error', function(err) {playerHandleError(playlist, played)})
+	return new Player()
+	    .on('error', function(err) {playerHandleError(playlist, played)})
+    }
+
+    player = playerCreator();
+
+    // Player functionality
+
+    // Songs move from playlist (if nothing is playing presently), to playing, to played.
+
+    // TODO check if song already exists in played.
+
+    // event: on error (No next song was found).
+    function playerHandleError(playlist, played) {
+
+	// TODO Workaround for a bug in player: wait a couple seconds so the
+	// songs don't overlap.
+	
+	// Move the recently playing song to played.
+	played.push(playing);
+
+	if (playlist.length != 0) {
+	    // Play the next song.
+	    player = playerCreator(playlist[0]);
+	    player.play();
+
+	    // Remove the added song.
+	    playing = playlist[0];
+	    playlist.shift();
+	} else {
+	    // Reset the object, resetting its playlist.
+	    player = playerCreator();
+	    playing = 'None';
+	}
+    }
+
+    // Add a song and start the playlist, if it's empty.
+    function playerAddSong(song) {
+	if (player.list.length == 0) {
+	    // If this is the player's first song, start it.
+	    player = playerCreator(song);
+	    player.play();
+	    playing = song;
+	} else { 
+	    // Otherwise add it to the queue
+	    playlist.push(song);
+	}
+
+    }
+
+
+    /* GET home page. */
+    app.get('/', function(req, res, next) {
+
+	var playlist_view;
+	if(playlist.length) {
+	    playlist_view = '<p>Playlist:</p><ul>';
+	    for(var i=0; i < playlist.length; i++) {
+		playlist_view +=
+		    '<li>' +
+		    playlist[i].replace(/^\.\/downloads\//, '') .replace(/\.mp3$/, '') +
+		    '</li>';
+	    }
+	    playlist_view += '</ul>';
+	} else {
+	    playlist_view = '<p>No songs in playlist.</p>';
+	}
+	var playing_view = '<p>Now playing: ' + playing.replace(/^\.\/downloads\//, '') .replace(/\.mp3$/, '') + '</p>';
+	var played_view;
+	if(played.length) {
+	    played_view = '<p>Played:</p><ul>';
+	    for(var i=0; i < played.length; i++) {
+		played_view +=
+		    '<li>' +
+		    played[i].replace(/^\.\/downloads\//, '') .replace(/\.mp3$/, '') +
+		    '</li>';
+	    }
+	    played_view += '</ul>';
+	} else {
+	    played_view = '<p>No played songs.</p>';
+	}
+	res.render('index', { playlist_view: playlist_view,
+			      playing_view: playing_view,
+			      played_view: played_view });
+    });
+
+    app.get('/youtube', function(req, res, next) {
+	res.render('youtube');
+    });
+
+    app.use(expressValidator({
+	customValidators: {
+	    dlSuccess: function(video) {
+		// Test if the requested video is available.
+		// TODO make this non-blocking so music doesn't stop
+		var youtube_dl = child_process.spawnSync(YOUTUBE_DL_LOC, ['-s', video]);
+
+		// DEBUG: for when I forget to change the var
+		if(youtube_dl.stderr == null) {
+		    console.log("Your youtube-dl location is probably invalid.");
+		}
+
+		if (youtube_dl.stderr.toString()) {
+		    return false;
+		}
+		return true;
+	    }
+	}
+    }
+			    ));
+
+    app.post('/youtube', function(req, res) {
+	var video = req.body.video;
+	
+	req.checkBody('video', 'URL is not valid.').dlSuccess();
+	
+	var errors = req.validationErrors();
+	
+	if(errors){
+	    res.render('youtube', {
+		errors:errors
+	    });
+	} else {
+	    var youtube_dl = child_process.spawn(YOUTUBE_DL_LOC, ['-x', '--audio-format', 'mp3', '-o', 'downloads/%(title)s.%(ext)s', video]);
+	    youtube_dl.on('close', (code) => {
+		console.log("Done getting " + video);
+		var error;
+		youtube_dl.stderr.on('data', (data) => {
+		    error = data;
+		    console.log(`Error getting video: ${data}`);
+		    // TODO give error to user when they return to /
+		});
+
+		if(!error) {
+		    var youtube_dl_get_title = child_process.spawnSync(YOUTUBE_DL_LOC, ['--get-title', video]);
+		    console.log(youtube_dl_get_title.stdout.toString());
+		    playerAddSong('./downloads/' + youtube_dl_get_title.stdout.toString()
+				  .replace('\n', '')
+				  .replace(new RegExp('"', 'g'), '\'')
+				  + ".mp3");
+		}
+		res.redirect('/');
+	    });
+	}
+    });
+
+    app.get('/file', function(req, res, next) {
+	res.render('file');
+    });
+
+    // Return the router.
+    return app;
+
+    // module.exports = app;
+
+};

+ 18 - 0
routes/player-demo.js

@@ -0,0 +1,18 @@
+var Player = require('player');
+var player = new Player();
+
+playerAddSong('./downloads/\'IS THAT A MAN RIDING A SHRIMP\'.mp3');
+
+// event: on error (No next song was found)
+player.on('error', function(err){
+  // Reset the object, resetting the playlist.
+  player = new Player();
+});
+
+// Add a song and start the playlist, if it's empty
+function playerAddSong(song) {
+    player.add(song);
+  if (player.list.length == 1) {
+    player.play();
+  }
+}

+ 9 - 0
routes/users.js

@@ -0,0 +1,9 @@
+var express = require('express');
+var router = express.Router();
+
+/* GET users listing. */
+router.get('/', function(req, res, next) {
+  res.send('respond with a resource');
+});
+
+module.exports = router;

Some files were not shown because too many files changed in this diff