From ece5efafe576dc778d6850172c04da83e64a93ff Mon Sep 17 00:00:00 2001 From: Paul Sori Date: Sun, 28 Aug 2016 13:04:49 -0400 Subject: [PATCH] Improved everything about playlists --- README.md | 2 +- jplayer/js/mstream.js | 27 ++-- mstream.js | 134 +++++++++--------- package.json | 2 +- public/js/mstream.js | 28 ++-- public/mstream.html | 2 +- .../paper-audio-player.html | 6 + 7 files changed, 102 insertions(+), 99 deletions(-) diff --git a/README.md b/README.md index d25405e..a64a317 100644 --- a/README.md +++ b/README.md @@ -147,7 +147,7 @@ API Calls * GET: /getallplaylists * RETURNS: JSON array of all playlists * GET: /loadplaylist - * PARAM: filename - playlsit filename + * PARAM: playlistname - playlist name * RETURN: JSON array of files in playlist * POST: /download * PARAM: fileArray - JSON array of files to download diff --git a/jplayer/js/mstream.js b/jplayer/js/mstream.js index 4f7953d..397cd5e 100755 --- a/jplayer/js/mstream.js +++ b/jplayer/js/mstream.js @@ -14,7 +14,7 @@ $(document).ready(function(){ auroraFormats: "flac", smoothPlayBar: true, keyEnabled: true, - keyBindings: { + keyBindings: { play: { key: 32, // Spacebar fn: function(f) { @@ -94,7 +94,7 @@ $(document).ready(function(){ $('#playlist li').removeClass('current'); $(this).parent().addClass('current'); - + // Add that URL to jPlayer jPlayerSetMedia(songurl, filetype); @@ -263,7 +263,7 @@ $(document).ready(function(){ for (var i = 0; i < fileExplorerArray.length; i++) { directoryString += fileExplorerArray[i] + "/"; } - + // If the scraper option is checked, then tell dirparer to use getID3 $.post('dirparser', {dir: directoryString, filetypes: filetypes}, function(response) { @@ -326,15 +326,16 @@ $(document).ready(function(){ $('#save_playlist').prop("disabled",true); var playlistElements = $('ul#playlist li'); - var playlistArray = jQuery.makeArray(playlistElements); + var playlistArray = jQuery.makeArray(playlistElements); - var title = $('#playlist_name').val(); + var title = $('#playlist_name').val(); - var stuff = []; + var stuff = []; - // Check for special characters - if(/^[a-zA-Z0-9-_ ]*$/.test(title) == false) { + // Check for special characters + if(/^[a-zA-Z0-9-_ ]*$/.test(title) == false) { console.log('don\'t do that'); + $('#save_playlist').prop("disabled",false); return false; } @@ -399,7 +400,7 @@ $(document).ready(function(){ //parse through the json array and make an array of corresponding divs var playlists = []; $.each(dirty, function() { - playlists.push('
'+this.name+'
'); + playlists.push('
'+this.name+'
'); }); // Ad playlists to the left panel @@ -420,14 +421,14 @@ $(document).ready(function(){ // load up a playlist $("#filelist").on('click', '.playlistz', function() { - var filename = $(this).data('filename'); + var playlistname = $(this).data('playlistname'); var name = $(this).html(); // Make an AJAX call to get the contents of the playlist $.ajax({ type: "GET", url: "loadplaylist", - data: {filename: filename}, + data: {playlistname: playlistname}, dataType: 'json', }) .done(function( msg ) { @@ -775,14 +776,14 @@ $("#filelist").on('click', '.playlistz', function() { var htmlString = ''; - if(parsedMessage.artists.length > 0){ + if(parsedMessage.artists.length > 0){ htmlString += '

Artists

'; $.each(parsedMessage.artists, function(index, value) { htmlString += '
'+value+'
'; }); } - if(parsedMessage.albums.length > 0){ + if(parsedMessage.albums.length > 0){ htmlString += '

Albums

'; $.each(parsedMessage.albums, function(index, value) { htmlString += '
'+value+'
'; diff --git a/mstream.js b/mstream.js index 1a306e1..d57077b 100755 --- a/mstream.js +++ b/mstream.js @@ -43,12 +43,12 @@ var arrayOfSongs = []; if(!program.beetspath){ db.run("CREATE TABLE IF NOT EXISTS items ( id INTEGER PRIMARY KEY AUTOINCREMENT, title varchar DEFAULT NULL, artist varchar DEFAULT NULL, year int DEFAULT NULL, album varchar DEFAULT NULL, path text, format varchar, track INTEGER, disk INTEGER);", function() { // console.log('TABLES CREATED'); - }); + }); } // Create a playlist table -db.run("CREATE TABLE IF NOT EXISTS mstream_playlists ( id INTEGER PRIMARY KEY AUTOINCREMENT, playlist_name varchar, filepath varchar);", function() { - // console.log('TABLES CREATED'); -}); +db.run("CREATE TABLE IF NOT EXISTS mstream_playlists ( id INTEGER PRIMARY KEY AUTOINCREMENT, playlist_name varchar, filepath varchar, created datetime default current_timestamp);", function() { + console.log('PLAYLIST TABLE CREATED'); +}); @@ -81,7 +81,7 @@ function tunnel_uPNP(){ tunnelLibrary = require('nat-upnp'); client = tunnelLibrary.createClient(); - + client.portMapping({ public: port, private: port, @@ -91,7 +91,7 @@ function tunnel_uPNP(){ if (err) { // every service in the list has failed throw err; - } + } }); var getIP = require('external-ip')(); @@ -115,7 +115,7 @@ function tunnel_uPNP(){ } } -function tunnel_NAT_PMP(){ +function tunnel_NAT_PMP(){ try{ console.log('Preparing to tunnel via nat-pmp protocol'); @@ -407,96 +407,98 @@ mstream.post('/dirparser', function (req, res) { // Combine list of directories and mp3s var finalArray = { path:path, contents:filesArray.concat(directories)}; - var returnJSON = JSON.stringify(finalArray); - // Send back some JSON - res.send(returnJSON); + res.send(JSON.stringify(finalArray)); }); function getFileType(filename){ - return filename.split(".").pop(); } -// playlist placeholder functions -// TODO: Change this to store playlists in DB mstream.post('/saveplaylist', function (req, res){ - var title = req.body.title; var songs = req.body.stuff; - try { - fs.mkdirSync('.mstream-playlists'); - } catch(e) { - if ( e.code != 'EEXIST' ) throw e; - } + // Check if this playlist already exists + db.all("SELECT id FROM mstream_playlists WHERE playlist_name = ?;", title, function(err, rows) { - var writeString = ''; + db.serialize(function() { - for(var i = songs.length - 1; i >= 0; i--) { - writeString += songs[i] + os.EOL; - } + // We need to delete anys existing entries + if(rows && rows.length > 0){ + db.run("DELETE FROM mstream_playlists WHERE playlist_name = ?;", title); + } - fs.writeFile('.mstream-playlists/' + title + '.m3u', writeString, function (err) { - if (err) throw err; - - console.log('It\'s saved!'); - res.send(); + // Now we add the new entries + var sql2 = "insert into mstream_playlists (playlist_name, filepath) values "; + var sqlParser = []; + + while(songs.length > 0) { + var song = songs.shift(); + + sql2 += "(?, ?), "; + sqlParser.push(title); + sqlParser.push( fe.join(rootDir, song) ); + } + + sql2 = sql2.slice(0, -2); + sql2 += ";"; + + db.run(sql2, sqlParser, function(){ + res.send('DONE'); + }); + + }); }); }); - mstream.get('/getallplaylists', function (req, res){ - var files = fs.readdirSync('.mstream-playlists/'); - var playlists = []; - // // loop through files - for (var i = 0; i < files.length; i++) { - if(files[i].substr(files[i].length - 3) === 'm3u'){ - playlists.push({file:files[i], name:files[i].slice(0, -4)}); + db.all("SELECT DISTINCT playlist_name FROM mstream_playlists", function(err, rows){ + var playlists = []; + + // loop through files + for (var i = 0; i < rows.length; i++) { + if(rows[i].playlist_name){ + playlists.push({name: rows[i].playlist_name}); + } } - } - res.send(JSON.stringify(playlists)); + res.send(JSON.stringify(playlists)); + }); }); - -// Find all playlists mstream.get('/loadplaylist', function (req, res){ - // TODO: Scrub user input - var playlist = req.query.filename; + var playlist = req.query.playlistname; - var contents = fs.readFileSync('.mstream-playlists/' + playlist, 'utf8'); - var contents = contents.split(os.EOL); + db.all("SELECT * FROM mstream_playlists WHERE playlist_name = ? ORDER BY id COLLATE NOCASE ASC", playlist, function(err, rows){ + var returnThis = []; - var returnThis = []; + for (var i = 0; i < rows.length; i++) { - for (var i = 0; i < contents.length; i++) { - if(contents[i].length == 0){ - continue; + // var tempName = rows[i].filepath.split('/').slice(-1)[0]; + var tempName = fe.basename(rows[i].filepath); + var extension = getFileType(rows[i].filepath); + var filepath = fe.relative(rootDir, rows[i].filepath); + + returnThis.push({name: tempName, file: filepath, filetype: extension }); } - var tempName = contents[i].split('/').slice(-1)[0]; - var extension = getFileType(contents[i]); + res.send(JSON.stringify(returnThis)); + }); - var tempObj = {name: tempName, file: contents[i], filetype: extension }; - - - returnThis.push(tempObj); - } - - - res.send(JSON.stringify(returnThis)); }); + + // Download a zip file of music mstream.post('/download', function (req, res){ var archive = archiver('zip'); @@ -545,7 +547,7 @@ mstream.post('/download', function (req, res){ if(program.beetspath){ const spawn = require('child_process').spawn; - var scanThisDir = program.beetspath; + var scanThisDir = program.beetspath; mstream.get('/db/recursive-scan', function(req,res){ @@ -641,7 +643,7 @@ if(program.beetspath){ console.log('TABLES CREATED'); // var emptypromise = emptyPromise(); // recursiveScanY(startdir, fileTypesArray, emptypromise); // TODO: Can we remove the fileTypesArray? - + parse = parseAllFiles(); parse.next(); @@ -705,7 +707,7 @@ if(program.beetspath){ var file = yetAnotherArrayOfSongs.pop(); var resultX = yield parseFile(file); - + } insertEntries(); @@ -763,7 +765,7 @@ if(program.beetspath){ } - + sql2 = sql2.slice(0, -2); sql2 += ";"; @@ -813,7 +815,7 @@ mstream.post('/db/search', function(req, res){ // TODO: Combine SQL calls into one db.serialize(function() { - + var sqlAlbum = "SELECT DISTINCT album FROM items WHERE items.album LIKE ? ORDER BY album COLLATE NOCASE ASC;"; db.all(sqlAlbum, searchTerm, function(err, rows) { if(err){ @@ -836,7 +838,7 @@ mstream.post('/db/search', function(req, res){ res.status(500).json({ error: 'DB Error' }); return; } - + for (var i = 0; i < rows.length; i++) { if(rows[i].artist){ // rows.splice(i, 1); @@ -978,7 +980,7 @@ function setLocalFileLocation(rows){ // GET DB Status mstream.get('/db/status', function(req, res){ var returnObject = {}; - + returnObject.locked = scanLock; @@ -987,11 +989,11 @@ mstream.get('/db/status', function(req, res){ // Currently we don't support filecount stats when using beets DB if(!program.beetspath){ returnObject.totalFileCount = totalFileCount; - returnObject.filesLeft = yetAnotherArrayOfSongs.length; + returnObject.filesLeft = yetAnotherArrayOfSongs.length; }else{ // Dummy data returnObject.totalFileCount = 0; - returnObject.filesLeft = 0; + returnObject.filesLeft = 0; } diff --git a/package.json b/package.json index 44e85df..35fb8e0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "mstream", - "version": "1.20.0", + "version": "1.21.0", "description": "music streaming server", "main": "mstream.js", "bin": { diff --git a/public/js/mstream.js b/public/js/mstream.js index 62cb04e..434292a 100755 --- a/public/js/mstream.js +++ b/public/js/mstream.js @@ -1,11 +1,8 @@ -document.addEventListener('DOMContentLoaded', function() { -// $(document).ready(function(){ +$(document).ready(function(){ ////////////////////////////// Initialization code - - // Supported file types var filetypes = '["mp3","ogg","wav","m4a","flac"]'; @@ -73,9 +70,6 @@ document.addEventListener('DOMContentLoaded', function() { // Add that URL to jPlayer jPlayerSetMedia(songurl, filetype); - - // TODO: - // $('#jquery_jplayer_1').jPlayer("play"); }); @@ -95,10 +89,9 @@ document.addEventListener('DOMContentLoaded', function() { function jPlayerSetMedia(fileLocation, filetype){ document.getElementById("mplayer").setAttribute("src", fileLocation); document.getElementById("mplayer").setAttribute("title", fileLocation.split('/').pop()); - - } + // Adds file to the now playing playlist // There is no longer addfile1 function addFile2(that){ @@ -283,15 +276,16 @@ document.addEventListener('DOMContentLoaded', function() { $('#save_playlist').prop("disabled",true); var playlistElements = $('ul#playlist li'); - var playlistArray = jQuery.makeArray(playlistElements); + var playlistArray = jQuery.makeArray(playlistElements); - var title = $('#playlist_name').val(); + var title = $('#playlist_name').val(); - var stuff = []; + var stuff = []; - // Check for special characters - if(/^[a-zA-Z0-9-_ ]*$/.test(title) == false) { + // Check for special characters + if(/^[a-zA-Z0-9-_ ]*$/.test(title) == false) { console.log('don\'t do that'); + $('#save_playlist').prop("disabled",false); return false; } @@ -356,7 +350,7 @@ document.addEventListener('DOMContentLoaded', function() { //parse through the json array and make an array of corresponding divs var playlists = []; $.each(dirty, function() { - playlists.push('
'+this.name+'
'); + playlists.push('
'+this.name+'
'); }); // Ad playlists to the left panel @@ -377,14 +371,14 @@ document.addEventListener('DOMContentLoaded', function() { // load up a playlist $("#filelist").on('click', '.playlistz', function() { - var filename = $(this).data('filename'); + var playlistname = $(this).data('playlistname'); var name = $(this).html(); // Make an AJAX call to get the contents of the playlist $.ajax({ type: "GET", url: "loadplaylist", - data: {filename: filename}, + data: {playlistname: playlistname}, dataType: 'json', }) .done(function( msg ) { diff --git a/public/mstream.html b/public/mstream.html index 5e2545d..ab5feac 100755 --- a/public/mstream.html +++ b/public/mstream.html @@ -24,7 +24,7 @@ - + diff --git a/public/paper-player/paper-audio-player/paper-audio-player.html b/public/paper-player/paper-audio-player/paper-audio-player.html index c4f0775..732a46c 100755 --- a/public/paper-player/paper-audio-player/paper-audio-player.html +++ b/public/paper-player/paper-audio-player/paper-audio-player.html @@ -329,6 +329,12 @@ Custom property | Description // SPacebar pause window.addEventListener("keydown", function(event){ + var element = event.target.tagName.toLowerCase(); + + if(element == 'input' || element == 'textarea'){ + return; + } + switch (event.keyCode) { case 32: //SpaceBar player.playPause(event);