102 lines
2.8 KiB
TypeScript
102 lines
2.8 KiB
TypeScript
import fs from "fs";
|
||
import randomstring from "randomstring";
|
||
|
||
const TEMP_DIR = "./temp-tts";
|
||
const FAILED_LOG = TEMP_DIR + "/failed.log";
|
||
|
||
const sub_name = randomstring.generate({ length: 5, charset: "alphanumeric" });
|
||
const HOST = "http://85.31.224.193:4000";
|
||
|
||
// tidur
|
||
const sleep = (ms: number) => new Promise((res) => setTimeout(res, ms));
|
||
|
||
// cek apakah file sudah ada
|
||
function fileExists(path: string) {
|
||
return fs.existsSync(path) && fs.statSync(path).size > 44;
|
||
}
|
||
|
||
// tulis log gagal
|
||
function logFail(msg: string) {
|
||
fs.appendFileSync(FAILED_LOG, msg + "\n");
|
||
}
|
||
|
||
async function downloadWithRetry(jobId: string, outFile: string) {
|
||
const MAX_RETRY = 5;
|
||
|
||
// jika sebelumnya sudah ada → skip
|
||
if (fileExists(outFile)) {
|
||
console.log(` 🔁 Resume: file sudah ada → ${outFile}`);
|
||
return true;
|
||
}
|
||
|
||
for (let attempt = 1; attempt <= MAX_RETRY; attempt++) {
|
||
try {
|
||
console.log(` ⏳ Download ${jobId} (try ${attempt}/${MAX_RETRY})...`);
|
||
const res = await fetch(`${HOST}/file/${jobId}`);
|
||
|
||
if (!res.ok) {
|
||
throw new Error(`Status ${res.status}`);
|
||
}
|
||
|
||
const buf = Buffer.from(await res.arrayBuffer());
|
||
|
||
// pastikan ukurannya wajar
|
||
if (buf.length < 44) {
|
||
throw new Error("File terlalu kecil (korup?)");
|
||
}
|
||
|
||
fs.writeFileSync(outFile, buf);
|
||
console.log(` ✓ Success → ${outFile}`);
|
||
return true;
|
||
} catch (err: any) {
|
||
console.error(` ❌ Error: ${err.message}`);
|
||
if (attempt < MAX_RETRY) {
|
||
console.log(" 🔄 Retry dalam 2s...");
|
||
await sleep(2000);
|
||
}
|
||
}
|
||
}
|
||
|
||
console.error(` ❌ Gagal total untuk ${jobId}`);
|
||
logFail(jobId);
|
||
return false;
|
||
}
|
||
|
||
async function main() {
|
||
const jobsPath = TEMP_DIR + "/jobs.json";
|
||
if (!fs.existsSync(jobsPath)) {
|
||
console.error("❌ jobs.json not found");
|
||
process.exit(1);
|
||
}
|
||
|
||
const jobs = JSON.parse(fs.readFileSync(jobsPath, "utf-8"));
|
||
console.log(`📦 Total jobs: ${jobs.length}`);
|
||
|
||
const resultFiles: string[] = [];
|
||
|
||
for (let i = 0; i < jobs.length; i++) {
|
||
const jobId = jobs[i];
|
||
const outFile = `${TEMP_DIR}/${jobId}_${sub_name}_${(i + 1)
|
||
.toString()
|
||
.padStart(4, "0")}.wav`;
|
||
|
||
console.log(`\n▶️ Job ${i + 1}/${jobs.length} → ${jobId}`);
|
||
|
||
const success = await downloadWithRetry(jobId, outFile);
|
||
|
||
if (success) {
|
||
resultFiles.push(outFile);
|
||
}
|
||
}
|
||
|
||
console.log("\n🎉 DONE!");
|
||
console.log("Result files:", resultFiles);
|
||
return resultFiles;
|
||
}
|
||
|
||
if (import.meta.main) {
|
||
main().then((files) => {
|
||
console.log("\n📁 Final:", files.length, "file tersimpan.");
|
||
});
|
||
}
|