« get me outta code hell

Change the way playlist updating works, and show track paths when I is pressed - http-music - Command-line music player + utils (not a server!)
about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorliam4 <towerofnix@gmail.com>2017-07-19 12:15:21 -0300
committerliam4 <towerofnix@gmail.com>2017-07-19 12:15:21 -0300
commita1bc37389a063e95328987385fb8b5c77ed05488 (patch)
tree5a3ab4e1890879798140bcc48b4779a5ea116b2e /src
parentb39407787e36128e63cf3387c1cfd9b480af4dfa (diff)
Change the way playlist updating works, and show track paths when I is pressed
Diffstat (limited to 'src')
-rwxr-xr-xsrc/http-music.js1
-rw-r--r--src/loop-play.js15
-rw-r--r--src/playlist-utils.js87
3 files changed, 67 insertions, 36 deletions
diff --git a/src/http-music.js b/src/http-music.js
index 6457ef7..04d1f57 100755
--- a/src/http-music.js
+++ b/src/http-music.js
@@ -368,6 +368,7 @@ Promise.resolve()
 
           // TODO: It would be nice to have this as a method of
           // PlayController.
+          // Double TODO: This doesn't actually work!!
           downloadController.cancel()
           play.startNextDownload()
         }
diff --git a/src/loop-play.js b/src/loop-play.js
index f36f1fb..7457b41 100644
--- a/src/loop-play.js
+++ b/src/loop-play.js
@@ -4,6 +4,7 @@ const { spawn } = require('child_process')
 const FIFO = require('fifo-js')
 const EventEmitter = require('events')
 const { getDownloaderFor } = require('./downloaders')
+const { getItemPathString } = require('./playlist-utils')
 
 class DownloadController extends EventEmitter {
   waitForDownload() {
@@ -228,16 +229,22 @@ class PlayController {
   }
 
   logTrackInfo() {
+    const getMessage = t => {
+      let path = getItemPathString(t)
+
+      return (
+        `\x1b[1m${t.name} \x1b[0m@ ${path} \x1b[2m${t.downloaderArg}\x1b[0m`
+      )
+    }
+
     if (this.currentTrack) {
-      const t = this.currentTrack
-      console.log(`Playing: \x1b[1m${t.name} \x1b[2m${t.downloaderArg}\x1b[0m`)
+      console.log(`Playing: ${getMessage(this.currentTrack)}`)
     } else {
       console.log("No song currently playing.")
     }
 
     if (this.nextTrack) {
-      const t = this.nextTrack
-      console.log(`Up next: \x1b[1m${t.name} \x1b[2m${t.downloaderArg}\x1b[0m`)
+      console.log(`Up next: ${getMessage(this.nextTrack)}`)
     } else {
       console.log("No song up next.")
     }
diff --git a/src/playlist-utils.js b/src/playlist-utils.js
index c1a8193..1a0d7b8 100644
--- a/src/playlist-utils.js
+++ b/src/playlist-utils.js
@@ -1,5 +1,7 @@
 'use strict'
 
+const parentSymbol = Symbol('parent')
+
 // TODO: Use this when loading playlists. Also grab things from http-music.js.
 function updatePlaylistFormat(playlist) {
   const defaultPlaylist = {
@@ -31,19 +33,40 @@ function updatePlaylistFormat(playlist) {
 
   const fullPlaylistObj = Object.assign(defaultPlaylist, playlistObj)
 
-  const handleGroupContents = groupContents => {
-    return groupContents.map(item => {
-      if (Array.isArray(item[1])) {
-        return {name: item[0], items: handleGroupContents(item[1])}
-      } else {
-        return updateTrackFormat(item)
-      }
-    })
+  return updateGroupFormat(fullPlaylistObj)
+}
+
+function updateGroupFormat(group) {
+  const defaultGroup = {
+    name: '',
+    items: []
+  }
+
+  let groupObj = {}
+
+  if (Array.isArray(group[1])) {
+    groupObj = {name: group[0], items: group[1]}
+  } else {
+    groupObj = group
   }
 
-  fullPlaylistObj.items = handleGroupContents(fullPlaylistObj.items)
+  groupObj = Object.assign(defaultGroup, groupObj)
 
-  return fullPlaylistObj
+  groupObj.items = groupObj.items.map(item => {
+    // Theoretically this wouldn't work on downloader-args where the value
+    // isn't a string..
+    if (typeof group[1] === 'string' || item.downloaderArg) {
+      item = updateTrackFormat(item)
+    } else {
+      item = updateGroupFormat(item)
+    }
+
+    item[parentSymbol] = groupObj
+
+    return item
+  })
+
+  return groupObj
 }
 
 function updateTrackFormat(track) {
@@ -67,27 +90,6 @@ function updateTrackFormat(track) {
   return Object.assign(defaultTrack, trackObj)
 }
 
-function updateGroupFormat(group) {
-  const defaultGroup = {
-    name: '',
-    items: []
-  }
-
-  let groupObj
-
-  if (Array.isArray(group)) {
-    if (group.length === 2) {
-      groupObj = {name: group[0], items: group[1]}
-    } else {
-      throw new Error("Unexpected non-length 2 array-format group")
-    }
-  } else {
-    groupObj = group
-  }
-
-  return Object.assign(defaultGroup, groupObj)
-}
-
 function mapGrouplikeItems(grouplike, handleTrack) {
   if (typeof handleTrack === 'undefined') {
     throw new Error("Missing track handler function")
@@ -114,7 +116,9 @@ function flattenGrouplike(grouplike) {
   return {
     items: grouplike.items.map(item => {
       if (isGroup(item)) {
-        return flattenGrouplike(item).items
+        const flat = flattenGrouplike(item).items
+
+        return flat
       } else {
         return [item]
       }
@@ -232,6 +236,23 @@ function getPlaylistTreeString(playlist, showTracks = false) {
   return recursive(playlist)
 }
 
+function getItemPathString(item) {
+  // Gets the playlist path of an item by following its parent chain.
+  // Returns a string in format Foo/Bar/Baz, where Foo and Bar are group
+  // names, and Baz is the name of the item. Unnamed parents (except for the
+  // top one) are considered to have the name '(Unnamed)'.
+
+  if (item[parentSymbol]) {
+    if (item[parentSymbol].name || item[parentSymbol][parentSymbol]) {
+      return getItemPathString(item[parentSymbol]) + '/' + item.name
+    } else {
+      return item.name
+    }
+  } else {
+    return item.name || '(Unnamed)'
+  }
+}
+
 function parsePathString(pathString) {
   const pathParts = pathString.split('/')
   return pathParts
@@ -250,11 +271,13 @@ function isTrack(obj) {
 }
 
 module.exports = {
+  parentSymbol,
   updatePlaylistFormat, updateTrackFormat,
   flattenGrouplike,
   filterPlaylistByPathString, filterGrouplikeByPath,
   removeGroupByPathString, removeGroupByPath,
   getPlaylistTreeString,
+  getItemPathString,
   parsePathString,
   isGroup, isTrack
 }