Created
July 23, 2017 16:43
-
-
Save adrianseeley/c1abc1705007b1c4ca8006e8124db4c6 to your computer and use it in GitHub Desktop.
iTunes Custom Sort
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const inFile = './Game.xml'; | |
const outFileDiscover = './GameDiscover.xml'; | |
const outFileExploit = './GameExploit.xml'; | |
const fs = require('fs'); | |
const regexIndexOf = (str, regex, end) => { | |
var match = str.match(regex); | |
return match.index + (end ? match[0].length : 0); | |
}; | |
const stringBetween = (str, a, b) => { | |
const start = regexIndexOf(str, a, true); | |
const length = regexIndexOf(str, b) - start; | |
return str.substr(start, length); | |
}; | |
const readTracks = (filename) => { | |
const file = fs.readFileSync(filename, 'utf8'); | |
const trackBody = stringBetween(file, /<key>Tracks<\/key>\s*<dict>/, /<\/dict>\s*<key>Playlists<\/key>/); | |
const dictBodies = trackBody.split('<dict>'); | |
const trackSections = dictBodies.filter(dictBody => { | |
return dictBody.indexOf('Track ID') !== -1; | |
}); | |
const trackObjects = trackSections.map(trackSection => { | |
const trackId = trackSection.split('<key>Track ID</key><integer>')[1].split('</integer>')[0]; | |
const playCount = trackSection.indexOf('<key>Play Count</key><integer>') === -1 ? 0 : trackSection.split('<key>Play Count</key><integer>')[1].split('</integer>')[0]; | |
const skipCount = trackSection.indexOf('<key>Skip Count</key><integer>') === -1 ? 0 : trackSection.split('<key>Skip Count</key><integer>')[1].split('</integer>')[0]; | |
return { | |
trackId: trackId, | |
playCount: playCount, | |
skipCount: skipCount, | |
trueCount: playCount - skipCount | |
}; | |
}); | |
return trackObjects; | |
}; | |
const sortDiscover = (a, b) => { | |
if (a.skipCount == b.skipCount) { | |
return a.playCount - b.playCount; | |
} else { | |
return a.skipCount - b.skipCount; | |
} | |
}; | |
const sortExploit = (a, b) => { | |
return b.trueCount - a.trueCount; | |
}; | |
const generatePlaylistString = (trackObjects, sortLambda) => { | |
trackObjects.sort(sortLambda); | |
const playlistString = trackObjects.reduce((str, trackObject) => { | |
return str + '<dict><key>Track ID</key><integer>' + trackObject.trackId + '</integer></dict>'; | |
}, ''); | |
return playlistString; | |
}; | |
const writePlaylist = (inFile, outFile, playlistString, name) => { | |
const file = fs.readFileSync(inFile, 'utf8'); | |
const nameUpdatedFile = file.split('<key>Name</key><string>Game</string>').join('<key>Name</key><string>' + name + '</string>'); | |
const listRemoved = nameUpdatedFile.split('<key>Playlist Items</key>')[0] + '<key>Playlist Items</key><array>'; | |
const listInjected = listRemoved + playlistString + '</array></dict></array></dict></plist>'; | |
fs.writeFileSync(outFile, listInjected, 'utf8'); | |
}; | |
const trackObjects = readTracks(inFile); | |
const playlistStringDiscover = generatePlaylistString(trackObjects, sortDiscover); | |
writePlaylist(inFile, outFileDiscover, playlistStringDiscover, 'GameDiscover'); | |
const playlistStringExploit = generatePlaylistString(trackObjects, sortExploit); | |
writePlaylist(inFile, outFileExploit, playlistStringExploit, 'GameExploit'); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment