diff options
-rwxr-xr-x | src/http-music.js | 77 | ||||
-rw-r--r-- | todo.txt | 2 |
2 files changed, 63 insertions, 16 deletions
diff --git a/src/http-music.js b/src/http-music.js index 68bfa77..6abda75 100755 --- a/src/http-music.js +++ b/src/http-music.js @@ -17,17 +17,12 @@ const { const readFile = promisify(fs.readFile) -function setupDefaultPlaylist(file) { - return readFile(file, 'utf-8').then( - text => JSON.parse(text), - err => null - ) -} +Promise.resolve() + .then(async () => { + let sourcePlaylist = null + let activePlaylist = null -setupDefaultPlaylist('./playlist.json') - .then(async playlist => { - let sourcePlaylist = playlist - let activePlaylist = playlist + await openPlaylist('./playlist.json') let pickerType = 'shuffle' let downloaderType = 'http' @@ -39,6 +34,57 @@ setupDefaultPlaylist('./playlist.json') let shouldPlay = true let willPlay = null + async function openPlaylist(file, silent = false) { + let playlistText + + try { + playlistText = await readFile(file, 'utf-8') + } catch(err) { + if (silent) { + console.error("Failed to read playlist file: " + file) + } + + return false + } + + const openedPlaylist = JSON.parse(playlistText) + + // Playlists can be in two formats... + if (Array.isArray(openedPlaylist)) { + // ..the first, a simple array of tracks and groups; + + sourcePlaylist = openedPlaylist + activePlaylist = openedPlaylist + } else if (typeof openedPlaylist === 'object') { + // ..or an object including metadata and configuration as well as the + // array described in the first. + + if (!('tracks' in openedPlaylist)) { + throw new Error( + "Trackless object-type playlist (requires 'tracks' property)" + ) + } + + sourcePlaylist = openedPlaylist.tracks + activePlaylist = openedPlaylist.tracks + + // What's handy about the object-type playlist is that you can pass + // options that will be run every time the playlist is opened: + if ('options' in openedPlaylist) { + if (Array.isArray(openedPlaylist.options)) { + processArgv(openedPlaylist.options, optionFunctions) + } else { + throw new Error( + "Invalid 'options' property (expected array): " + file + ) + } + } + } else { + // Otherwise something's gone horribly wrong..! + throw new Error("Invalid playlist file contents: " + file) + } + } + function requiresOpenPlaylist() { if (activePlaylist === null) { throw new Error( @@ -47,7 +93,7 @@ setupDefaultPlaylist('./playlist.json') } } - await processArgv(process.argv, { + const optionFunctions = { '-help': function(util) { // --help (alias: -h, -?) // Presents a help message. @@ -67,10 +113,7 @@ setupDefaultPlaylist('./playlist.json') // Opens a separate playlist file. // This sets the source playlist. - const playlistText = await readFile(util.nextArg(), 'utf-8') - const openedPlaylist = JSON.parse(playlistText) - sourcePlaylist = openedPlaylist - activePlaylist = openedPlaylist + await openPlaylist(util.nextArg()) }, 'o': util => util.alias('-open'), @@ -203,7 +246,9 @@ setupDefaultPlaylist('./playlist.json') console.log(JSON.stringify(activePlaylist, null, 2)) } - }) + } + + await processArgv(process.argv, optionFunctions) if (activePlaylist === null) { throw new Error( diff --git a/todo.txt b/todo.txt index 0054aca..3961c78 100644 --- a/todo.txt +++ b/todo.txt @@ -143,3 +143,5 @@ TODO: Make max download attempts variable by the user (without requiring TODO: Update HTTP crawl man page to include new options, and maybe update the HTTP crawler itself to reveal more options to the command line. + +TODO: Fix the bug in loop-play.js where wasDestroyed doesn't exist! |