diff options
-rw-r--r-- | man/http-music-crawl-http.1 | 4 | ||||
-rw-r--r-- | man/http-music-crawl-local.1 | 21 | ||||
-rwxr-xr-x | src/crawl-http.js | 2 | ||||
-rwxr-xr-x | src/crawl-local.js | 63 | ||||
-rw-r--r-- | todo.txt | 5 |
5 files changed, 80 insertions, 15 deletions
diff --git a/man/http-music-crawl-http.1 b/man/http-music-crawl-http.1 index 62bbc24..9202c65 100644 --- a/man/http-music-crawl-http.1 +++ b/man/http-music-crawl-http.1 @@ -54,10 +54,10 @@ http://example.com/ ]}, {name: 'Bad News', [ {name: 'Bad News - Single', items: [ - ['Bad News', 'http://example.com/Bad%20News/Bad%20News%20-%20Single/Bad%20News.mp3'] + {name: 'Bad News', downloaderArg: 'http://example.com/Bad%20News/Bad%20News%20-%20Single/Bad%20News.mp3'} ]}, {name: 'Irony', items: [ - ['Rahhhh!!', 'http://example.com/Bad%20News/Irony/Rahhhh!!.mp3'] + {name: 'Rahhhh!!', downloaderArg: 'http://example.com/Bad%20News/Irony/Rahhhh!!.mp3'} ]} ]} ]} diff --git a/man/http-music-crawl-local.1 b/man/http-music-crawl-local.1 new file mode 100644 index 0000000..4949d98 --- /dev/null +++ b/man/http-music-crawl-local.1 @@ -0,0 +1,21 @@ +.TH http-music-crawl-local 1 + +.SH NAME +http-music-crawl-local - create a playlist from files on your own computer + +.SH SYNOPSIS +.B http-music-crawl-local +<path to top music directory> +[opts...] + +.SH DESCRIPTION +\fBhttp-music-crawl-local\fR is a command line utility which recursively crawls a given directory and creates a playlist from found items (with groups determined by crawled directories). +It attempts to only add music files (mp3, ogg, etc) to the playlist (see \fB--extensions\fR). + +.SH OPTIONS +.TP +.BR -e ", " --extensions ", " --exts +Sets file extensions that are considered music tracks to be added to the result playlist. +\fB<extensions>\fR is a comma-separated list of extensions, not including the "dots"; e.g. \fR'mp3,wav'\fB. +A default list of extensions exists but is not *extremely* extensive. +Use --extensions when needed! diff --git a/src/crawl-http.js b/src/crawl-http.js index ad3b776..826e4d5 100755 --- a/src/crawl-http.js +++ b/src/crawl-http.js @@ -153,7 +153,7 @@ async function main(args) { return } - let url = args[0] + const url = args[0] let maxDownloadAttempts = 5 let verbose = false diff --git a/src/crawl-local.js b/src/crawl-local.js index d4176ed..134a574 100755 --- a/src/crawl-local.js +++ b/src/crawl-local.js @@ -5,12 +5,18 @@ const fs = require('fs') const path = require('path') const naturalSort = require('node-natural-sort') +const processArgv = require('./process-argv') const { promisify } = require('util') const readDir = promisify(fs.readdir) const stat = promisify(fs.stat) -function crawl(dirPath) { +function crawl(dirPath, extensions = [ + // This list isn't very extensive, and can be customized via the + // --extensions (or --exts, -e) option. + 'ogg', 'oga', + 'wav', 'mp3', 'mp4', 'm4a', 'aac' +]) { return readDir(dirPath).then(items => { items.sort(naturalSort()) @@ -19,26 +25,59 @@ function crawl(dirPath) { return stat(itemPath).then(stats => { if (stats.isDirectory()) { - return crawl(itemPath) - .then(group => Object.assign(group, {name: item})) + return crawl(itemPath, extensions) + .then(group => Object.assign({name: item}, group)) } else if (stats.isFile()) { - const track = {name: item, downloaderArg: itemPath} - return track + // Extname returns a string starting with a dot; we don't want the + // dot, so we slice it off of the front. + const ext = path.extname(item).slice(1) + + if (extensions.includes(ext)) { + const track = {name: item, downloaderArg: itemPath} + return track + } else { + return null + } } }) })) - }).then(items => ({items})) + }).then(items => items.filter(Boolean)) + .then(filteredItems => ({items: filteredItems})) } async function main(args) { if (args.length === 0) { - console.log("Usage: crawl-local /example/path") - } else { - const path = args[0] - - const res = await crawl(path) - console.log(JSON.stringify(res, null, 2)) + console.log("Usage: crawl-local /example/path [opts]") + return } + + const path = args[0] + + let extensions + + await processArgv(args.slice(1), { + '-extensions': function(util) { + // --extensions <extensions> (alias: --exts, -e) + // Sets file extensions that are considered music tracks to be added to + // the result playlist. + // <extensions> is a comma-separated list of extensions, not including + // the "dots"; e.g. 'mp3,wav'. + // A default list of extensions exists but is not *extremely* extensive. + // (Use --extensions when needed!) + + extensions = util.nextArg().split(',') + + // *Somebody*'s going to start the extensions with dots; may as well be + // careful for that! + extensions = extensions.map(e => e.startsWith('.') ? e.slice(1) : e) + }, + + '-exts': util => util.alias('-extensions'), + 'e': util => util.alias('-extensions') + }) + + const res = await crawl(path, extensions) + console.log(JSON.stringify(res, null, 2)) } module.exports = {main, crawl} diff --git a/todo.txt b/todo.txt index 9239493..d3ddeb1 100644 --- a/todo.txt +++ b/todo.txt @@ -255,3 +255,8 @@ TODO: Markdown documentation? Man pages are nice, but aren't really all that user-friendly (citation needed); for example you can't easily read them online. (Whereas Markdown documents are easily viewed online, and aren't hard to read by hand, e.g. with `less doc/foo.md`.) + +TODO: Handle avconv failing (probably handle downloader rejections from within + DownloadController). Less important now that only music file extensions + are loaded, but still relevant (for old playlists which may contain + .DS_Stores or album cover arts, etc). |