Skip to content

Instantly share code, notes, and snippets.

@mustofa-id
Last active April 24, 2024 09:43
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mustofa-id/521232fefbd96546da45193846c272ca to your computer and use it in GitHub Desktop.
Save mustofa-id/521232fefbd96546da45193846c272ca to your computer and use it in GitHub Desktop.
Script to download Quran audio
import { createWriteStream, existsSync, mkdirSync } from "fs";
import { join } from "path";
import { pipeline } from "stream/promises";
/**
* To get `qari_dir`:
* 1. Go to https://quranicaudio.com
* 2. Choose qari
* 3. Hover to the download button, you will see the download link contains qari directory
*
* Run:
* `node download.mjs` or `deno download.js` or `bun download.js`
*/
const qari_dir = `abdurrashid_sufi`; // TODO: use cli args
const base_url = `https://download.quranicaudio.com/quran/${qari_dir}/`;
const task_limit = 17;
const semaphores = [];
const logs = [];
const report_interval = setInterval(report, 500);
const started_at = Date.now();
if (!existsSync(qari_dir)) mkdirSync(qari_dir);
function report() {
const cols = 6;
const clean_logs = logs.filter(Boolean);
console.clear();
for (let i = 0; i < clean_logs.length; i += cols) {
console.log(clean_logs.slice(i, i + cols).join(" | "));
}
}
async function download(name) {
const file = name + ".mp3";
const res = await fetch(base_url + file);
if (!res.ok || !res.body) return `FAIL`;
const stream = createWriteStream(join(qari_dir, file));
await pipeline(res.body, stream);
return `DONE`;
}
await Promise.all(
Array.from({ length: 114 }).map(async (_, index) => {
const curr_index = index % task_limit;
const prev_task = semaphores[curr_index];
semaphores[curr_index] = new Promise(async (resolve) => {
if (prev_task) await prev_task;
const name = String(index + 1).padStart(3, "0");
logs[index] = `${name}.. `;
const result = await download(name);
resolve(result);
logs[index] = `${name}..${result}`;
});
return semaphores[curr_index];
})
);
clearInterval(report_interval);
report();
console.log(`\ncompleted in ${(Date.now() - started_at) / 1_000}s`);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment