73 lines
2.6 KiB
JavaScript
73 lines
2.6 KiB
JavaScript
const fs = require("node:fs");
|
|
const path = require("node:path");
|
|
const { Readable } = require("node:stream");
|
|
const { pipeline } = require("node:stream/promises");
|
|
|
|
const DOWNLOAD_DIR = path.resolve(process.env.DOWNLOAD_DIR || "downloads");
|
|
|
|
function getServerCredentials(options = {}) {
|
|
const apiUrl = options.apiUrl || process.env.REINLOOP_API_URL;
|
|
const adminToken = options.adminToken || process.env.B_ADMIN_TOKEN;
|
|
if (!apiUrl) throw new Error("缺少 server API URL");
|
|
if (!adminToken) throw new Error("缺少 Admin Token");
|
|
return { apiUrl, adminToken };
|
|
}
|
|
|
|
async function callServer(payload, options = {}) {
|
|
const { apiUrl, adminToken } = getServerCredentials(options);
|
|
const response = await fetch(apiUrl, {
|
|
method: "POST",
|
|
headers: { "content-type": "application/json" },
|
|
body: JSON.stringify({ ...payload, adminToken })
|
|
});
|
|
let result = null;
|
|
try {
|
|
result = await response.json();
|
|
} catch {
|
|
result = null;
|
|
}
|
|
if (!response.ok) {
|
|
const message = result && typeof result.errMsg === "string" && result.errMsg
|
|
? result.errMsg
|
|
: `server 请求失败: HTTP ${response.status}`;
|
|
throw new Error(message);
|
|
}
|
|
if (!result || typeof result !== "object") {
|
|
throw new Error("server 返回格式无效");
|
|
}
|
|
if (!result.success) throw new Error(result.errMsg || "server 返回失败");
|
|
return result;
|
|
}
|
|
|
|
async function downloadFromUrl(url, fileName, options = {}) {
|
|
await fs.promises.mkdir(DOWNLOAD_DIR, { recursive: true });
|
|
return downloadToPath(url, path.join(DOWNLOAD_DIR, path.basename(fileName)), options);
|
|
}
|
|
|
|
async function downloadToPath(url, destination, options = {}) {
|
|
const response = await fetch(url);
|
|
if (!response.ok || !response.body) {
|
|
throw new Error(`下载失败: HTTP ${response.status}`);
|
|
}
|
|
|
|
await fs.promises.mkdir(path.dirname(destination), { recursive: true });
|
|
const temporary = `${destination}.downloading`;
|
|
|
|
try {
|
|
await pipeline(Readable.fromWeb(response.body), fs.createWriteStream(temporary));
|
|
await fs.promises.rename(temporary, destination);
|
|
} catch (error) {
|
|
await fs.promises.rm(temporary, { force: true });
|
|
throw error;
|
|
}
|
|
|
|
console.log(`[${new Date().toISOString()}] 已下载: ${destination}`);
|
|
return destination;
|
|
}
|
|
|
|
async function downloadFile(fileID, fileName, options = {}) {
|
|
const { url } = await callServer({ type: "downloadModel", fileID }, options);
|
|
return downloadFromUrl(url, fileName, options);
|
|
}
|
|
|
|
module.exports = { callServer, downloadFile, downloadFromUrl, downloadToPath, getServerCredentials }; |