downloadTask.js 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. const cron = require("node-cron");
  2. const axios = require("axios");
  3. const fs = require("fs-extra");
  4. const path = require("path");
  5. const unzipper = require("unzipper");
  6. const time = "0 0 2 * *" //设置时间
  7. // 下载链接
  8. const DOWNLOAD_URL = "https://www.ip2location.com/download/?token=3Fi4pprzwKQUHVgw8F8HOnfWrmLTjpLCvJ9w8E7nzIlm3avAT2aJp8u68VHGiPyb&file=DB1LITEBIN";
  9. // 文件保存路径
  10. const DESTINATION_PATH = path.join(__dirname, "src/db");
  11. const ZIP_FILE_PATH = path.join(DESTINATION_PATH, "db_download.zip"); // 临时 ZIP 文件路径
  12. // 下载文件(带重试机制)
  13. async function downloadFileWithRetry(url, destination, retries = 3) {
  14. for (let attempt = 1; attempt <= retries; attempt++) {
  15. try {
  16. console.log(`📥 尝试下载 (${attempt}/${retries})...`);
  17. const response = await axios({
  18. method: "GET",
  19. url,
  20. responseType: "stream",
  21. });
  22. // 确保目录存在
  23. await fs.ensureDir(path.dirname(destination));
  24. // 保存 ZIP 文件
  25. const writer = fs.createWriteStream(destination);
  26. response.data.pipe(writer);
  27. await new Promise((resolve, reject) => {
  28. writer.on("finish", resolve);
  29. writer.on("error", reject);
  30. });
  31. console.log("✅ ZIP 文件下载成功!");
  32. return true;
  33. } catch (error) {
  34. console.error(`❌ 下载失败 (尝试 ${attempt}/${retries}):`, error.message);
  35. if (attempt === retries) {
  36. console.error("⚠️ 最终下载失败,放弃重试!");
  37. return false;
  38. }
  39. await new Promise((resolve) => setTimeout(resolve, 5000)); // 等待 5 秒再重试
  40. }
  41. }
  42. }
  43. // 解压 ZIP 文件
  44. async function unzipFile(zipPath, extractTo) {
  45. try {
  46. console.log("📂 开始解压 ZIP 文件...");
  47. await fs.ensureDir(extractTo); // 确保解压目录存在
  48. await fs.createReadStream(zipPath)
  49. .pipe(unzipper.Extract({ path: extractTo }))
  50. .promise();
  51. console.log("✅ ZIP 文件解压成功!");
  52. await fs.remove(zipPath); // 删除 ZIP 文件,节省空间
  53. } catch (error) {
  54. console.error("❌ 解压 ZIP 文件时出错:", error.message);
  55. }
  56. }
  57. // 定时任务:每天 16:14 执行
  58. cron.schedule(time, async () => {
  59. console.log("📌 开始下载 IP2Location 数据库...");
  60. const success = await downloadFileWithRetry(DOWNLOAD_URL, ZIP_FILE_PATH);
  61. if (success) {
  62. await unzipFile(ZIP_FILE_PATH, DESTINATION_PATH);
  63. }
  64. });
  65. // 让进程保持运行,防止定时任务停止
  66. process.stdin.resume();