Change tag parser for better file support
Should support mp3, ogg, wav, flac and more.
This commit is contained in:
parent
09fa089cfe
commit
15483c0354
20
.vscode/launch.json
vendored
Normal file
20
.vscode/launch.json
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "Organise",
|
||||
"args": ["${workspaceFolder}/src/cli.js", "organise", "test", "out"],
|
||||
"console": "integratedTerminal",
|
||||
"skipFiles": [
|
||||
"${workspaceRoot}/node_modules/**/*.js",
|
||||
"<node_internals>/**/*.js"
|
||||
],
|
||||
"env": {
|
||||
"DEBUG": "publikator:*",
|
||||
"DEBUG_COLORS": "1"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,10 +1,10 @@
|
|||
{
|
||||
"name": "publikator",
|
||||
"version": "0.1.0",
|
||||
"version": "0.2.0",
|
||||
"main": "index.js",
|
||||
"repository": "https://github.com/aengl/publikator.git",
|
||||
"author": "Lynn Smeria <ae@cephea.de>",
|
||||
"license": "MIT",
|
||||
"license": "Unlicense",
|
||||
"bin": {
|
||||
"publikator": "publikator.js"
|
||||
},
|
||||
|
@ -16,8 +16,8 @@
|
|||
"debug": "3.1.0",
|
||||
"fs-extra": "7.0.0",
|
||||
"js-yaml": "3.12.0",
|
||||
"jsmediatags": "3.8.1",
|
||||
"lodash": "4.17.10",
|
||||
"music-metadata": "2.6.0",
|
||||
"sanitize-filename": "1.6.1",
|
||||
"walkdir": "0.0.12"
|
||||
},
|
||||
|
|
|
@ -18,17 +18,10 @@ module.exports = {
|
|||
'track-count': tracks.length,
|
||||
tracks: tracks.map((track, i) => ({
|
||||
path: track.path,
|
||||
size: track.size,
|
||||
position: i,
|
||||
...tags.getTags(track, [
|
||||
'title',
|
||||
'artist',
|
||||
'album',
|
||||
'year',
|
||||
'comment',
|
||||
'track',
|
||||
'genre',
|
||||
]),
|
||||
common: track.common,
|
||||
format: track.format,
|
||||
...tags.getTags(track, ['foo']),
|
||||
})),
|
||||
};
|
||||
})
|
||||
|
|
|
@ -5,9 +5,10 @@ const sanitize = require('sanitize-filename');
|
|||
const debug = require('debug')('publikator:organise');
|
||||
const tags = require('./tags');
|
||||
|
||||
const getFolderName = file => `${file.tags.artist} - ${file.tags.album}`;
|
||||
const getArtists = file => file.common.artist || file.common.artists.join(', ');
|
||||
const getFolderName = file => `${getArtists(file)} - ${file.common.album}`;
|
||||
const getFileName = file =>
|
||||
`${file.tags.track} - ${file.tags.title}${path.extname(file.path)}`;
|
||||
`${file.common.track.no} - ${file.common.title}${path.extname(file.path)}`;
|
||||
|
||||
module.exports = {
|
||||
/**
|
||||
|
@ -22,7 +23,12 @@ module.exports = {
|
|||
*/
|
||||
byAlbum: async (root, taggedFiles) => {
|
||||
const files = taggedFiles.filter(file =>
|
||||
tags.hasTags(file, ['artist', 'album', 'track', 'title'])
|
||||
tags.hasTags(file, [
|
||||
'common.artists',
|
||||
'common.album',
|
||||
'common.track',
|
||||
'common.title',
|
||||
])
|
||||
);
|
||||
|
||||
debug(`grouping tracks by album`);
|
||||
|
|
|
@ -22,7 +22,7 @@ module.exports = {
|
|||
|
||||
/**
|
||||
* Reads ID3 tags from all files and returns an array in the form of:
|
||||
* [{ path, size, tags }, ...]
|
||||
* [{ path, common, format, native }, ...]
|
||||
*/
|
||||
readTags: files => {
|
||||
debug(`reading tags from ${files.length} file(s)`);
|
||||
|
@ -31,8 +31,7 @@ module.exports = {
|
|||
const info = await tags.readTags(file);
|
||||
return {
|
||||
path: file,
|
||||
size: info.size,
|
||||
tags: info.tags,
|
||||
...info,
|
||||
};
|
||||
})
|
||||
);
|
||||
|
|
25
src/tags.js
25
src/tags.js
|
@ -1,4 +1,5 @@
|
|||
const jsmediatags = require('jsmediatags');
|
||||
const _ = require('lodash');
|
||||
const mm = require('music-metadata');
|
||||
const debug = require('debug')('publikator:tags');
|
||||
|
||||
module.exports = {
|
||||
|
@ -6,24 +7,17 @@ module.exports = {
|
|||
* Reads tags from a track.
|
||||
*/
|
||||
readTags: file =>
|
||||
new Promise((resolve, reject) => {
|
||||
jsmediatags.read(file, {
|
||||
onSuccess: info => {
|
||||
resolve(info);
|
||||
},
|
||||
onError: error => {
|
||||
debug(error.type);
|
||||
debug(error.info);
|
||||
reject(error);
|
||||
},
|
||||
});
|
||||
mm.parseFile(file, {
|
||||
duration: true,
|
||||
native: true,
|
||||
skipCovers: false,
|
||||
}),
|
||||
|
||||
/**
|
||||
* Returns true if a file has all required tags.
|
||||
*/
|
||||
hasTags: (taggedFile, tags) => {
|
||||
if (tags.some(tag => taggedFile.tags[tag] === undefined)) {
|
||||
if (tags.some(tag => _.get(taggedFile, tag) === undefined)) {
|
||||
debug(`track'${taggedFile.path}' is missing one or more required tags`);
|
||||
return false;
|
||||
}
|
||||
|
@ -35,8 +29,9 @@ module.exports = {
|
|||
*/
|
||||
getTags: (taggedFile, tags) =>
|
||||
tags.reduce((all, tag) => {
|
||||
if (taggedFile.tags[tag] !== undefined) {
|
||||
all[tag] = taggedFile.tags[tag]; // eslint-disable-line
|
||||
const value = _.get(taggedFile, tag);
|
||||
if (value !== undefined) {
|
||||
all[tag] = value; // eslint-disable-line
|
||||
}
|
||||
return all;
|
||||
}, {}),
|
||||
|
|
102
yarn.lock
102
yarn.lock
|
@ -21,13 +21,13 @@ ajv-keywords@^3.0.0:
|
|||
resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.2.0.tgz#e86b819c602cf8821ad637413698f1dec021847a"
|
||||
|
||||
ajv@^6.0.1, ajv@^6.5.0:
|
||||
version "6.5.2"
|
||||
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.5.2.tgz#678495f9b82f7cca6be248dd92f59bff5e1f4360"
|
||||
version "6.5.3"
|
||||
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.5.3.tgz#71a569d189ecf4f4f321224fecb166f071dd90f9"
|
||||
dependencies:
|
||||
fast-deep-equal "^2.0.1"
|
||||
fast-json-stable-stringify "^2.0.0"
|
||||
json-schema-traverse "^0.4.1"
|
||||
uri-js "^4.2.1"
|
||||
uri-js "^4.2.2"
|
||||
|
||||
ansi-align@^2.0.0:
|
||||
version "2.0.0"
|
||||
|
@ -150,8 +150,8 @@ async@~1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/async/-/async-1.0.0.tgz#f8fc04ca3a13784ade9e1641af98578cfbd647a9"
|
||||
|
||||
atob@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.1.tgz#ae2d5a729477f289d60dd7f96a6314a22dd6c22a"
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9"
|
||||
|
||||
axobject-query@^2.0.1:
|
||||
version "2.0.1"
|
||||
|
@ -326,9 +326,9 @@ chownr@^1.0.1:
|
|||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.0.1.tgz#e2a75042a9551908bebd25b8523d5f9769d79181"
|
||||
|
||||
ci-info@^1.0.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.2.0.tgz#8d1e9cb4051482ff70cd52a89b4b095a8fb635f6"
|
||||
ci-info@^1.3.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.4.0.tgz#4841d53cad49f11b827b648ebde27a6e189b412f"
|
||||
|
||||
circular-json@^0.3.1:
|
||||
version "0.3.3"
|
||||
|
@ -510,11 +510,10 @@ deep-is@~0.1.3:
|
|||
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34"
|
||||
|
||||
define-properties@^1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.2.tgz#83a73f2fea569898fb737193c8f873caf6d45c94"
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1"
|
||||
dependencies:
|
||||
foreach "^2.0.5"
|
||||
object-keys "^1.0.8"
|
||||
object-keys "^1.0.12"
|
||||
|
||||
define-property@^0.2.5:
|
||||
version "0.2.5"
|
||||
|
@ -610,6 +609,10 @@ es-to-primitive@^1.1.1:
|
|||
is-date-object "^1.0.1"
|
||||
is-symbol "^1.0.1"
|
||||
|
||||
es6-promise@^4.2.4:
|
||||
version "4.2.4"
|
||||
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.4.tgz#dc4221c2b16518760bd8c39a52d8f356fc00ed29"
|
||||
|
||||
escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
|
||||
|
@ -886,6 +889,10 @@ file-entry-cache@^2.0.0:
|
|||
flat-cache "^1.2.1"
|
||||
object-assign "^4.0.1"
|
||||
|
||||
file-type@9:
|
||||
version "9.0.0"
|
||||
resolved "https://registry.yarnpkg.com/file-type/-/file-type-9.0.0.tgz#a68d5ad07f486414dfb2c8866f73161946714a18"
|
||||
|
||||
fill-range@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7"
|
||||
|
@ -921,10 +928,6 @@ for-in@^1.0.2:
|
|||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80"
|
||||
|
||||
foreach@^2.0.5:
|
||||
version "2.0.5"
|
||||
resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99"
|
||||
|
||||
fragment-cache@^0.2.1:
|
||||
version "0.2.1"
|
||||
resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19"
|
||||
|
@ -1234,10 +1237,10 @@ is-callable@^1.1.1, is-callable@^1.1.3:
|
|||
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75"
|
||||
|
||||
is-ci@^1.0.10:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.1.0.tgz#247e4162e7860cebbdaf30b774d6b0ac7dcfe7a5"
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.2.0.tgz#3f4a08d6303a09882cef3f0fb97439c5f5ce2d53"
|
||||
dependencies:
|
||||
ci-info "^1.0.0"
|
||||
ci-info "^1.3.0"
|
||||
|
||||
is-data-descriptor@^0.1.4:
|
||||
version "0.1.4"
|
||||
|
@ -1417,12 +1420,6 @@ js-yaml@3.12.0, js-yaml@^3.11.0:
|
|||
argparse "^1.0.7"
|
||||
esprima "^4.0.0"
|
||||
|
||||
jsmediatags@3.8.1:
|
||||
version "3.8.1"
|
||||
resolved "https://registry.yarnpkg.com/jsmediatags/-/jsmediatags-3.8.1.tgz#e27d26e957b0b330c28f9762c82940c4dcc64720"
|
||||
dependencies:
|
||||
xhr2 "^0.1.4"
|
||||
|
||||
json-schema-traverse@^0.4.1:
|
||||
version "0.4.1"
|
||||
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
|
||||
|
@ -1567,6 +1564,10 @@ map-visit@^1.0.0:
|
|||
dependencies:
|
||||
object-visit "^1.0.0"
|
||||
|
||||
media-typer@^0.3.0:
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
|
||||
|
||||
micromatch@^3.1.4:
|
||||
version "3.1.10"
|
||||
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23"
|
||||
|
@ -1639,6 +1640,18 @@ ms@2.0.0:
|
|||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
|
||||
|
||||
music-metadata@2.6.0:
|
||||
version "2.6.0"
|
||||
resolved "https://registry.yarnpkg.com/music-metadata/-/music-metadata-2.6.0.tgz#a913a3a1de73b965158c243a5e188be9ec901ff9"
|
||||
dependencies:
|
||||
debug "^3.1.0"
|
||||
es6-promise "^4.2.4"
|
||||
file-type "9"
|
||||
media-typer "^0.3.0"
|
||||
strtok3 "^1.5.3"
|
||||
then-read-stream "^1.2.1"
|
||||
token-types "^0.9.4"
|
||||
|
||||
mute-stream@0.0.6:
|
||||
version "0.0.6"
|
||||
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.6.tgz#48962b19e169fd1dfc240b3f1e7317627bbc47db"
|
||||
|
@ -1791,7 +1804,7 @@ object-copy@^0.1.0:
|
|||
define-property "^0.2.5"
|
||||
kind-of "^3.0.3"
|
||||
|
||||
object-keys@^1.0.11, object-keys@^1.0.8:
|
||||
object-keys@^1.0.11, object-keys@^1.0.12:
|
||||
version "1.0.12"
|
||||
resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.12.tgz#09c53855377575310cca62f55bb334abff7b3ed2"
|
||||
|
||||
|
@ -2107,8 +2120,8 @@ remove-trailing-separator@^1.0.1:
|
|||
resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef"
|
||||
|
||||
repeat-element@^1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a"
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce"
|
||||
|
||||
repeat-string@^1.6.1:
|
||||
version "1.6.1"
|
||||
|
@ -2206,8 +2219,8 @@ semver-diff@^2.0.0:
|
|||
semver "^5.0.3"
|
||||
|
||||
"semver@2 || 3 || 4 || 5", semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@^5.5.0:
|
||||
version "5.5.0"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab"
|
||||
version "5.5.1"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.1.tgz#7dfdd8814bdb7cabc7be0fb1d734cfb66c940477"
|
||||
|
||||
set-blocking@~2.0.0:
|
||||
version "2.0.0"
|
||||
|
@ -2417,13 +2430,22 @@ strip-json-comments@^2.0.1, strip-json-comments@~2.0.1:
|
|||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
|
||||
|
||||
strtok3@^1.5.3:
|
||||
version "1.5.3"
|
||||
resolved "https://registry.yarnpkg.com/strtok3/-/strtok3-1.5.3.tgz#a788ce5b43cd5365d61ae9c7620113b2c94c068f"
|
||||
dependencies:
|
||||
debug "^3.1.0"
|
||||
es6-promise "^4.2.4"
|
||||
then-read-stream "^1.2.1"
|
||||
token-types "^0.9.4"
|
||||
|
||||
supports-color@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
|
||||
|
||||
supports-color@^5.2.0, supports-color@^5.3.0:
|
||||
version "5.4.0"
|
||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.4.0.tgz#1c6b337402c2137605efe19f10fec390f6faab54"
|
||||
version "5.5.0"
|
||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
|
||||
dependencies:
|
||||
has-flag "^3.0.0"
|
||||
|
||||
|
@ -2477,6 +2499,12 @@ text-table@^0.2.0:
|
|||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
|
||||
|
||||
then-read-stream@^1.2.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/then-read-stream/-/then-read-stream-1.2.1.tgz#9baddcb8a4ebc8a6fb36436985d24c36f7908829"
|
||||
dependencies:
|
||||
es6-promise "^4.2.4"
|
||||
|
||||
through@2, through@^2.3.6, through@~2.3, through@~2.3.1:
|
||||
version "2.3.8"
|
||||
resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
|
||||
|
@ -2519,6 +2547,10 @@ to-regex@^3.0.1, to-regex@^3.0.2:
|
|||
regex-not "^1.0.2"
|
||||
safe-regex "^1.1.0"
|
||||
|
||||
token-types@^0.9.4:
|
||||
version "0.9.4"
|
||||
resolved "https://registry.yarnpkg.com/token-types/-/token-types-0.9.4.tgz#ea24c5c3fc577292a1d362a252e348a0016361ad"
|
||||
|
||||
touch@^3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/touch/-/touch-3.1.0.tgz#fe365f5f75ec9ed4e56825e0bb76d24ab74af83b"
|
||||
|
@ -2596,7 +2628,7 @@ update-notifier@^2.3.0:
|
|||
semver-diff "^2.0.0"
|
||||
xdg-basedir "^3.0.0"
|
||||
|
||||
uri-js@^4.2.1:
|
||||
uri-js@^4.2.2:
|
||||
version "4.2.2"
|
||||
resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0"
|
||||
dependencies:
|
||||
|
@ -2690,10 +2722,6 @@ xdg-basedir@^3.0.0:
|
|||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4"
|
||||
|
||||
xhr2@^0.1.4:
|
||||
version "0.1.4"
|
||||
resolved "https://registry.yarnpkg.com/xhr2/-/xhr2-0.1.4.tgz#7f87658847716db5026323812f818cadab387a5f"
|
||||
|
||||
yallist@^2.1.2:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52"
|
||||
|
|
Loading…
Reference in a new issue