mirror of
https://git.mirrors.martin98.com/https://github.com/sub-store-org/Sub-Store.git
synced 2025-06-04 11:13:59 +08:00
feat: 简单实现了 SUB_STORE_MMDB_CRON 定时更新 MMDB. ASN: SUB_STORE_MMDB_ASN_PATH, SUB_STORE_MMDB_ASN_URL. COUNTRY: SUB_STORE_MMDB_COUNTRY_PATH, SUB_STORE_MMDB_COUNTRY_URL; 脚本中新增 ProxyUtils.downloadFile 方便下载二进制文件.
This commit is contained in:
parent
7f691c8511
commit
3b85063f73
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "sub-store",
|
"name": "sub-store",
|
||||||
"version": "2.19.29",
|
"version": "2.19.30",
|
||||||
"description": "Advanced Subscription Manager for QX, Loon, Surge, Stash and Shadowrocket.",
|
"description": "Advanced Subscription Manager for QX, Loon, Surge, Stash and Shadowrocket.",
|
||||||
"main": "src/main.js",
|
"main": "src/main.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { Buffer } from 'buffer';
|
import { Buffer } from 'buffer';
|
||||||
import rs from '@/utils/rs';
|
import rs from '@/utils/rs';
|
||||||
import YAML from '@/utils/yaml';
|
import YAML from '@/utils/yaml';
|
||||||
import download from '@/utils/download';
|
import download, { downloadFile } from '@/utils/download';
|
||||||
import {
|
import {
|
||||||
isIPv4,
|
isIPv4,
|
||||||
isIPv6,
|
isIPv6,
|
||||||
@ -330,6 +330,7 @@ export const ProxyUtils = {
|
|||||||
MMDB,
|
MMDB,
|
||||||
Gist,
|
Gist,
|
||||||
download,
|
download,
|
||||||
|
downloadFile,
|
||||||
isValidUUID,
|
isValidUUID,
|
||||||
doh,
|
doh,
|
||||||
};
|
};
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import express from '@/vendor/express';
|
import express from '@/vendor/express';
|
||||||
import $ from '@/core/app';
|
import $ from '@/core/app';
|
||||||
import migrate from '@/utils/migration';
|
import migrate from '@/utils/migration';
|
||||||
import download from '@/utils/download';
|
import download, { downloadFile } from '@/utils/download';
|
||||||
import { syncArtifacts, produceArtifact } from '@/restful/sync';
|
import { syncArtifacts, produceArtifact } from '@/restful/sync';
|
||||||
import { gistBackupAction } from '@/restful/miscs';
|
import { gistBackupAction } from '@/restful/miscs';
|
||||||
import { TOKENS_KEY } from '@/constants';
|
import { TOKENS_KEY } from '@/constants';
|
||||||
@ -54,8 +54,13 @@ export default function serve() {
|
|||||||
next();
|
next();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const pathname = decodeURIComponent(req._parsedUrl.pathname) || '/';
|
const pathname =
|
||||||
if(be_merge && req.path.startsWith('/share/') && req.query.token){
|
decodeURIComponent(req._parsedUrl.pathname) || '/';
|
||||||
|
if (
|
||||||
|
be_merge &&
|
||||||
|
req.path.startsWith('/share/') &&
|
||||||
|
req.query.token
|
||||||
|
) {
|
||||||
if (req.method.toLowerCase() !== 'get') {
|
if (req.method.toLowerCase() !== 'get') {
|
||||||
res.status(405).send('Method not allowed');
|
res.status(405).send('Method not allowed');
|
||||||
return;
|
return;
|
||||||
@ -74,7 +79,7 @@ export default function serve() {
|
|||||||
}
|
}
|
||||||
if (be_merge && fe_path && req.path.indexOf('/', 1) == -1) {
|
if (be_merge && fe_path && req.path.indexOf('/', 1) == -1) {
|
||||||
if (req.path.indexOf('.') == -1) {
|
if (req.path.indexOf('.') == -1) {
|
||||||
req.url = "/index.html"
|
req.url = '/index.html';
|
||||||
}
|
}
|
||||||
const express_ = eval(`require("express")`);
|
const express_ = eval(`require("express")`);
|
||||||
const mime_ = eval(`require("mime-types")`);
|
const mime_ = eval(`require("mime-types")`);
|
||||||
@ -85,7 +90,7 @@ export default function serve() {
|
|||||||
if (type) {
|
if (type) {
|
||||||
res.set('Content-Type', type);
|
res.set('Content-Type', type);
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
staticFileMiddleware(req, res, next);
|
staticFileMiddleware(req, res, next);
|
||||||
return;
|
return;
|
||||||
@ -230,6 +235,60 @@ export default function serve() {
|
|||||||
// 'Asia/Shanghai' // timeZone
|
// 'Asia/Shanghai' // timeZone
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
const mmdb_cron = eval('process.env.SUB_STORE_MMDB_CRON');
|
||||||
|
const countryFile = eval('process.env.SUB_STORE_MMDB_COUNTRY_PATH');
|
||||||
|
const countryUrl = eval('process.env.SUB_STORE_MMDB_COUNTRY_URL');
|
||||||
|
const asnFile = eval('process.env.SUB_STORE_MMDB_ASN_PATH');
|
||||||
|
const asnUrl = eval('process.env.SUB_STORE_MMDB_ASN_URL');
|
||||||
|
if (mmdb_cron && ((countryFile && countryUrl) || (asnFile && asnUrl))) {
|
||||||
|
$.info(`[MMDB CRON] ${mmdb_cron} enabled`);
|
||||||
|
const { CronJob } = eval(`require("cron")`);
|
||||||
|
new CronJob(
|
||||||
|
mmdb_cron,
|
||||||
|
async function () {
|
||||||
|
try {
|
||||||
|
$.info(`[MMDB CRON] ${mmdb_cron} started`);
|
||||||
|
if (countryFile && countryUrl) {
|
||||||
|
try {
|
||||||
|
$.info(
|
||||||
|
`[MMDB CRON] downloading ${countryUrl} to ${countryFile}`,
|
||||||
|
);
|
||||||
|
await downloadFile(countryUrl, countryFile);
|
||||||
|
} catch (e) {
|
||||||
|
$.error(
|
||||||
|
`[MMDB CRON] ${countryUrl} download failed: ${
|
||||||
|
e.message ?? e
|
||||||
|
}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (asnFile && asnUrl) {
|
||||||
|
try {
|
||||||
|
$.info(
|
||||||
|
`[MMDB CRON] downloading ${asnUrl} to ${asnFile}`,
|
||||||
|
);
|
||||||
|
await downloadFile(asnUrl, asnFile);
|
||||||
|
} catch (e) {
|
||||||
|
$.error(
|
||||||
|
`[MMDB CRON] ${asnUrl} download failed: ${
|
||||||
|
e.message ?? e
|
||||||
|
}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$.info(`[MMDB CRON] ${mmdb_cron} finished`);
|
||||||
|
} catch (e) {
|
||||||
|
$.error(
|
||||||
|
`[MMDB CRON] ${mmdb_cron} error: ${e.message ?? e}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}, // onTick
|
||||||
|
null, // onComplete
|
||||||
|
true, // start
|
||||||
|
// 'Asia/Shanghai' // timeZone
|
||||||
|
);
|
||||||
|
}
|
||||||
const path = eval(`require("path")`);
|
const path = eval(`require("path")`);
|
||||||
const fs = eval(`require("fs")`);
|
const fs = eval(`require("fs")`);
|
||||||
const data_url = eval('process.env.SUB_STORE_DATA_URL');
|
const data_url = eval('process.env.SUB_STORE_DATA_URL');
|
||||||
|
@ -273,3 +273,25 @@ export default async function download(
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function downloadFile(url, file) {
|
||||||
|
const undici = eval("require('undici')");
|
||||||
|
const fs = eval("require('fs')");
|
||||||
|
const { pipeline } = eval("require('stream/promises')");
|
||||||
|
const { Agent, interceptors, request } = undici;
|
||||||
|
$.info(`Downloading file...\nURL: ${url}\nFile: ${file}`);
|
||||||
|
const { body, statusCode } = await request(url, {
|
||||||
|
dispatcher: new Agent().compose(
|
||||||
|
interceptors.redirect({
|
||||||
|
maxRedirections: 3,
|
||||||
|
throwOnRedirect: true,
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
});
|
||||||
|
if (statusCode !== 200)
|
||||||
|
throw new Error(`Failed to download file from ${url}`);
|
||||||
|
const fileStream = fs.createWriteStream(file);
|
||||||
|
await pipeline(body, fileStream);
|
||||||
|
$.info(`File downloaded from ${url} to ${file}`);
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
@ -116,6 +116,7 @@ function operator(proxies = [], targetPlatform, context) {
|
|||||||
// getISO, // 获取 ISO 3166-1 alpha-2 代码
|
// getISO, // 获取 ISO 3166-1 alpha-2 代码
|
||||||
// Gist, // Gist 类
|
// Gist, // Gist 类
|
||||||
// download, // 内部的下载方法, 见 backend/src/utils/download.js
|
// download, // 内部的下载方法, 见 backend/src/utils/download.js
|
||||||
|
// downloadFile, // 下载二进制文件, 见 backend/src/utils/download.js
|
||||||
// MMDB, // Node.js 环境 可用于模拟 Surge/Loon 的 $utils.ipasn, $utils.ipaso, $utils.geoip. 具体见 https://t.me/zhetengsha/1269
|
// MMDB, // Node.js 环境 可用于模拟 Surge/Loon 的 $utils.ipasn, $utils.ipaso, $utils.geoip. 具体见 https://t.me/zhetengsha/1269
|
||||||
// isValidUUID, // 辅助判断是否为有效的 UUID
|
// isValidUUID, // 辅助判断是否为有效的 UUID
|
||||||
// }
|
// }
|
||||||
|
Loading…
x
Reference in New Issue
Block a user