This commit is contained in:
Stian Lund 2022-07-07 11:55:55 +02:00
parent f5159640f5
commit 227fca2217
1 changed files with 26 additions and 13 deletions

View File

@ -13,7 +13,8 @@ function usage(exitCode) {
'Valid options are:\n' +
'\t-h|--help\t\tGet this message\n' +
'\t-d|--debug\t\tPrint stack trace on error\n' +
'\t-s NUMBER\t\tNumber of tracks to be downloaded simultaneously (default: 5)'
'\t-s NUMBER\t\tNumber of tracks to be downloaded simultaneously (default: 5)\n' +
'\t-t NUMBER\t\tDownload specific track number (useful if some track failed to download)'
);
process.exit(exitCode);
}
@ -22,13 +23,15 @@ const argv = parseArgs(process.argv.slice(2), {
alias: {
help: 'h',
debug: 'd',
sim: 's'
sim: 's',
trackID: 't'
},
default: {
help: false,
debug: false,
sim: 5
sim: 5,
trackID: false
},
boolean: ['help', 'debug'],
@ -51,8 +54,9 @@ function processArgs(argv) {
const domain = url.parse(albumURL).hostname;
const parallelDownloads = argv.sim;
const isDebugMode = argv.debug;
const trackID = argv.trackID;
return { albumURL, domain, parallelDownloads, isDebugMode };
return { albumURL, domain, parallelDownloads, isDebugMode, trackID };
}
function getLinksAndTags(html, domain) {
@ -92,7 +96,7 @@ function getLinksAndTags(html, domain) {
return { tracksData, coverURL };
}
function executeInChunks(array, callback, queueSize = 5) {
function executeInChunks(callbackArgs, callback, queueSize = 5) {
const execWith = async (element, index) => {
await callback(element);
return index;
@ -100,15 +104,15 @@ function executeInChunks(array, callback, queueSize = 5) {
// Form initial queue consisting of promises, which resolve with
// their index number in the queue array.
const queueArray = array.splice(0, queueSize).map(execWith);
const queueArray = callbackArgs.splice(0, queueSize).map(execWith);
// Recursively get rid of resolved promises in the queue.
// Add new promises preventing queue from emptying.
const keepQueueSize = async () => {
if (array.length) {
if (callbackArgs.length) {
try {
const index = await Promise.race(queueArray);
queueArray.splice(index, 1, execWith(array.shift(), index));
queueArray.splice(index, 1, execWith(callbackArgs.shift(), index));
keepQueueSize();
} catch (error) {
console.log('Cannot assemble another chunk');
@ -129,7 +133,7 @@ function downloadFile(url, filename) {
unpromisifiedRequest({
url,
headers: {
'User-Agent': 'request'
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.88 Safari/537.36'
}
})
.on('error', reject)
@ -194,20 +198,29 @@ async function downloadCover(coverURL, albumDir) {
}
(async () => {
const { albumURL, domain, parallelDownloads, isDebugMode } = processArgs(
argv
);
const {
albumURL,
domain,
parallelDownloads,
isDebugMode,
trackID
} = processArgs(argv);
try {
const body = await request({
url: albumURL,
headers: {
'User-Agent': 'request'
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.88 Safari/537.36'
}
});
const { tracksData, coverURL } = getLinksAndTags(body, domain);
const albumDir = await prepareAlbumDir(tracksData);
if (trackID) {
executeInChunks(tracksData.slice(trackID - 1, trackID), downloadTrack, 1);
return;
}
await downloadCover(coverURL, albumDir);
await executeInChunks(tracksData, downloadTrack, parallelDownloads);
} catch (error) {