diff --git a/backend/package.json b/backend/package.json index 203ca684e..f7bf3d90a 100644 --- a/backend/package.json +++ b/backend/package.json @@ -1,6 +1,6 @@ { "name": "sub-store", - "version": "2.14.159", + "version": "2.14.160", "description": "Advanced Subscription Manager for QX, Loon, Surge, Stash and ShadowRocket.", "main": "src/main.js", "scripts": { @@ -17,6 +17,7 @@ "automerge": "1.0.1-preview.7", "body-parser": "^1.19.0", "connect-history-api-fallback": "^2.0.0", + "cron": "^3.1.6", "express": "^4.17.1", "http-proxy-middleware": "^2.0.6", "js-base64": "^3.7.2", diff --git a/backend/pnpm-lock.yaml b/backend/pnpm-lock.yaml index cc7834d03..b2df0694f 100644 --- a/backend/pnpm-lock.yaml +++ b/backend/pnpm-lock.yaml @@ -14,6 +14,9 @@ dependencies: connect-history-api-fallback: specifier: ^2.0.0 version: registry.npmmirror.com/connect-history-api-fallback@2.0.0 + cron: + specifier: ^3.1.6 + version: registry.npmmirror.com/cron@3.1.6 express: specifier: ^4.17.1 version: registry.npmmirror.com/express@4.17.1 @@ -2051,6 +2054,12 @@ packages: '@types/node': registry.npmmirror.com/@types/node@17.0.35 dev: true + registry.npmmirror.com/@types/luxon@3.3.8: + resolution: {integrity: sha512-jYvz8UMLDgy3a5SkGJne8H7VA7zPV2Lwohjx0V8V31+SqAjNmurWMkk9cQhfvlcnXWudBpK9xPM1n4rljOcHYQ==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@types/luxon/-/luxon-3.3.8.tgz} + name: '@types/luxon' + version: 3.3.8 + dev: false + registry.npmmirror.com/@types/minimatch@3.0.5: resolution: {integrity: sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@types/minimatch/-/minimatch-3.0.5.tgz} name: '@types/minimatch' @@ -3691,6 +3700,15 @@ packages: sha.js: registry.npmmirror.com/sha.js@2.4.11 dev: true + registry.npmmirror.com/cron@3.1.6: + resolution: {integrity: sha512-cvFiQCeVzsA+QPM6fhjBtlKGij7tLLISnTSvFxVdnFGLdz+ZdXN37kNe0i2gefmdD17XuZA6n2uPVwzl4FxW/w==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/cron/-/cron-3.1.6.tgz} + name: cron + version: 3.1.6 + dependencies: + '@types/luxon': registry.npmmirror.com/@types/luxon@3.3.8 + luxon: registry.npmmirror.com/luxon@3.4.4 + dev: false + registry.npmmirror.com/cross-spawn@7.0.3: resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/cross-spawn/-/cross-spawn-7.0.3.tgz} name: cross-spawn @@ -6846,6 +6864,13 @@ packages: dependencies: yallist: registry.npmmirror.com/yallist@4.0.0 + registry.npmmirror.com/luxon@3.4.4: + resolution: {integrity: sha512-zobTr7akeGHnv7eBOXcRgMeCP6+uyYsczwmeRCauvpvaAltgNyTbLH/+VaEAPUeWBT+1GuNmz4wC/6jtQzbbVA==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/luxon/-/luxon-3.4.4.tgz} + name: luxon + version: 3.4.4 + engines: {node: '>=12'} + dev: false + registry.npmmirror.com/magic-string@0.23.2: resolution: {integrity: sha512-oIUZaAxbcxYIp4AyLafV6OVKoB3YouZs0UTCJ8mOKBHNyJgGDaMJ4TgA+VylJh6fx7EQCC52XkbURxxG9IoJXA==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/magic-string/-/magic-string-0.23.2.tgz} name: magic-string diff --git a/backend/src/restful/index.js b/backend/src/restful/index.js index 940056a39..c819fab14 100644 --- a/backend/src/restful/index.js +++ b/backend/src/restful/index.js @@ -2,6 +2,7 @@ import express from '@/vendor/express'; import $ from '@/core/app'; import migrate from '@/utils/migration'; import download from '@/utils/download'; +import { syncArtifacts } from '@/restful/sync'; import registerSubscriptionRoutes from './subscriptions'; import registerCollectionRoutes from './collections'; @@ -41,6 +42,28 @@ export default function serve() { $app.start(); if ($.env.isNode) { + const backend_cron = eval('process.env.SUB_STORE_BACKEND_CRON'); + if (backend_cron) { + $.info(`[CRON] ${backend_cron} enabled`); + const { CronJob } = eval(`require("cron")`); + new CronJob( + backend_cron, + async function () { + try { + $.info(`[CRON] ${backend_cron} started`); + await syncArtifacts(); + $.info(`[CRON] ${backend_cron} finished`); + } catch (e) { + $.error( + `[CRON] ${backend_cron} error: ${e.message ?? e}`, + ); + } + }, // onTick + null, // onComplete + true, // start + // 'Asia/Shanghai' // timeZone + ); + } const path = eval(`require("path")`); const fs = eval(`require("fs")`); const data_url = eval('process.env.SUB_STORE_DATA_URL'); diff --git a/backend/src/restful/sync.js b/backend/src/restful/sync.js index 9fb4ef796..9f65781ff 100644 --- a/backend/src/restful/sync.js +++ b/backend/src/restful/sync.js @@ -441,7 +441,7 @@ async function produceArtifact({ } } -async function syncAllArtifacts(_, res) { +async function syncArtifacts() { $.info('开始同步所有远程配置...'); const allArtifacts = $.read(ARTIFACTS_KEY); const files = {}; @@ -480,6 +480,15 @@ async function syncAllArtifacts(_, res) { $.write(allArtifacts, ARTIFACTS_KEY); $.info('全部订阅同步成功!'); + } catch (e) { + $.error(`同步订阅失败,原因:${e.message ?? e}`); + throw e; + } +} +async function syncAllArtifacts(_, res) { + $.info('开始同步所有远程配置...'); + try { + await syncArtifacts(); success(res); } catch (err) { failed( @@ -553,4 +562,4 @@ async function syncArtifact(req, res) { } } -export { produceArtifact }; +export { produceArtifact, syncArtifacts };