diff options
author | Liam <towerofnix@gmail.com> | 2017-07-13 14:34:11 +0000 |
---|---|---|
committer | Liam <towerofnix@gmail.com> | 2017-07-13 14:34:11 +0000 |
commit | d25c15797741e92e35ad3f43b8b827811e6d4ca7 (patch) | |
tree | 71879c23e2b554770ef3ee5cde3392d2cf812dff /src | |
parent | c52550d2b448eeaab098525ec431e341f8a97b29 (diff) | |
parent | 27704d39664b711ae110f9beb708afb7dcaf4dc5 (diff) |
Merge branch 'master' of https://github.com/liam4/http-music
Diffstat (limited to 'src')
-rw-r--r-- | src/crawl-itunes.js | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/src/crawl-itunes.js b/src/crawl-itunes.js new file mode 100644 index 0000000..ec6c3ec --- /dev/null +++ b/src/crawl-itunes.js @@ -0,0 +1,103 @@ + +const fs = require('fs') +const path = require('path') +const xmldoc = require('xmldoc') + +const { promisify } = require('util') +const readFile = promisify(fs.readFile) + +function getDictValue(dict, key) { + if (dict.name !== 'dict') { + throw new Error("Not a dict: " + dict.name) + } + + for (let i = 0; i < dict.children.length; i++) { + const child = dict.children[i] + if (child.name === 'key') { + if (child.val === key) { + return dict.children.slice(i + 1).find(item => !item.text) + } + } + } + + return null +} + +async function crawl(libraryXML) { + const document = new xmldoc.XmlDocument(libraryXML) + + const libraryDict = document.children.find(child => child.name === 'dict') + + const tracksDict = getDictValue(libraryDict, 'Tracks') + + const trackDicts = tracksDict.children.filter(child => child.name === 'dict') + + const result = [] + + for (let trackDict of trackDicts) { + let kind = getDictValue(trackDict, 'Kind') + kind = kind && kind.val + kind = kind || '' + + if (!kind.includes('audio file')) { + continue + } + + let location = getDictValue(trackDict, 'Location') + location = location && location.val + location = location || '' + + if (!location) { + continue + } + + let name = getDictValue(trackDict, 'Name') + name = name && name.val + name = name || 'Unknown Name' + + let album = getDictValue(trackDict, 'Album') + album = album && album.val + album = album || 'Unknown Album' + + let artist = getDictValue(trackDict, 'Artist') + artist = artist && artist.val + artist = artist || 'Unknown Artist' + + // console.log(`${artist} - ${name} (${album})`) + + const group = (arr, title) => arr.find(g => g[0] === title) + + let artistGroup = group(result, artist) + + if (!artistGroup) { + artistGroup = [artist, []] + result.push(artistGroup) + } + + let albumGroup = group(artistGroup[1], album) + + if (!albumGroup) { + albumGroup = [album, []] + artistGroup[1].push(albumGroup) + } + + albumGroup[1].push([name, location]) + } + + return result +} + +async function main() { + const libraryPath = process.argv[2] || ( + `${process.env.HOME}/Music/iTunes/iTunes Music Library.xml` + ) + + const library = await readFile(libraryPath) + + const playlist = await crawl(library) + + console.log(JSON.stringify(playlist, null, 2)) +} + +main() + .catch(err => console.error(err)) |