From 9a2256fb0df506e8fdc4334bd4f0b65d201e61ff Mon Sep 17 00:00:00 2001 From: pandadtdyy Date: Fri, 14 Jan 2022 20:14:52 +0800 Subject: [PATCH] core: add daily task: check update (#293) --- packages/hydrooj/package.json | 2 ++ packages/hydrooj/src/entry/common.ts | 1 + packages/hydrooj/src/model/setting.ts | 1 + packages/hydrooj/src/model/task.ts | 3 ++ packages/hydrooj/src/script/checkUpdate.ts | 42 ++++++++++++++++++++++ packages/ui-default/locales/zh.yaml | 2 ++ 6 files changed, 51 insertions(+) create mode 100644 packages/hydrooj/src/script/checkUpdate.ts diff --git a/packages/hydrooj/package.json b/packages/hydrooj/package.json index 9525863de..54a3160de 100644 --- a/packages/hydrooj/package.json +++ b/packages/hydrooj/package.json @@ -42,6 +42,7 @@ "p-queue": "^7.1.0", "reflect-metadata": "^0.1.13", "require-resolve-hook": "^1.1.0", + "semver": "^7.3.5", "serialize-javascript": "^6.0.0", "sockjs": "^0.3.24", "source-map-support": "^0.5.21", @@ -64,6 +65,7 @@ "@types/mongodb": "^3.6.20", "@types/nodemailer": "^6.4.4", "@types/notp": "^2.0.1", + "@types/semver": "^7.3.9", "@types/serialize-javascript": "^5.0.2", "@types/sockjs": "^0.3.33", "@types/source-map-support": "^0.5.4", diff --git a/packages/hydrooj/src/entry/common.ts b/packages/hydrooj/src/entry/common.ts index ac4114852..c89d74b36 100644 --- a/packages/hydrooj/src/entry/common.ts +++ b/packages/hydrooj/src/entry/common.ts @@ -31,6 +31,7 @@ export const builtinHandler = [ export const builtinScript = [ 'rating', 'problemStat', 'blacklist', 'deleteUser', 'storageUsage', + 'checkUpdate', ]; function getFiles(folder: string, base = ''): string[] { diff --git a/packages/hydrooj/src/model/setting.ts b/packages/hydrooj/src/model/setting.ts index c5658a20b..47573a6c9 100644 --- a/packages/hydrooj/src/model/setting.ts +++ b/packages/hydrooj/src/model/setting.ts @@ -202,6 +202,7 @@ SystemSetting( Setting('setting_server', 'server.login', true, 'boolean', 'server.login', 'Allow builtin-login', FLAG_PRO), Setting('setting_server', 'server.message', true, 'boolean', 'server.message', 'Allow users send messages'), Setting('setting_server', 'server.blog', true, 'boolean', 'server.blog', 'Allow users post blog'), + Setting('setting_server', 'server.checkUpdate', true, 'boolean', 'server.checkUpdate', 'Daily update check'), Setting('setting_server', 'server.ignoreUA', ignoreUA, 'textarea', 'server.ignoreUA', 'ignoredUA'), ServerLangSettingNode, Setting('setting_limits', 'limit.problem_files_max', 100, 'number', 'limit.problem_files_max', 'Max files per problem'), diff --git a/packages/hydrooj/src/model/task.ts b/packages/hydrooj/src/model/task.ts index de3b2e11b..19048eb2b 100644 --- a/packages/hydrooj/src/model/task.ts +++ b/packages/hydrooj/src/model/task.ts @@ -140,6 +140,9 @@ Worker.addHandler('task.daily', async () => { await global.Hydro.model.record.coll.deleteMany({ contest: new ObjectID('000000000000000000000000') }); await global.Hydro.script.rp?.run({}, new Logger('task/rp').debug); await global.Hydro.script.problemStat?.run({}, new Logger('task/problem').debug); + if (global.Hydro.model.system.get('server.checkUpdate')) { + await global.Hydro.script.checkVersion?.run({}, new Logger('task/checkUpdate').debug); + } }); bus.on('domain/delete', (domainId) => coll.deleteMany({ domainId })); bus.once('app/started', async () => { diff --git a/packages/hydrooj/src/script/checkUpdate.ts b/packages/hydrooj/src/script/checkUpdate.ts new file mode 100644 index 000000000..c0e7a87ec --- /dev/null +++ b/packages/hydrooj/src/script/checkUpdate.ts @@ -0,0 +1,42 @@ +/* eslint-disable no-await-in-loop */ +import * as semver from 'semver'; +import superagent from 'superagent'; +import MessageModel from '../model/message'; +import * as system from '../model/system'; + +export const description = 'Daily update check'; + +async function getRemoteVersion(id: string) { + try { + const res = await superagent.get(`https://registry.yarnpkg.com/${id}`); + return res.body['dist-tags'].latest; + } catch (e) { + return null; + } +} + +export async function run() { + const current = global.Hydro.version; + const message = ['']; + for (const name in current) { + if (name === 'node') continue; + const id = name === 'hydrooj' ? name : `@hydrooj/${name}`; + const remote = await getRemoteVersion(id); + if (!remote) continue; + const stored = system.get(`checkVersion.${id}`); + if (semver.lt(stored, remote)) { + system.set(`checkVersion.${id}`, remote); + if (semver.lt(current[name], remote)) { + message.push(`${id}\t${current[name]} -> ${remote}`); + } + } + } + if (message.length > 1) { + MessageModel.sendNotification('Packages have new version: {0}', message.join('\n')); + } + return true; +} + +export const validate = {}; + +global.Hydro.script.checkUpdate = { run, description, validate }; diff --git a/packages/ui-default/locales/zh.yaml b/packages/ui-default/locales/zh.yaml index 770e7ea7e..1a7207416 100644 --- a/packages/ui-default/locales/zh.yaml +++ b/packages/ui-default/locales/zh.yaml @@ -38,6 +38,7 @@ __langname: 简体中文 'The value `{1}` of {0} already exists.': '{0} 的值 `{1}` 已经存在。' 'Yes': 是 "Effects only when Difficulty is not 'Use algorithm calculated'.": 仅当难度不为“使用算法计算”时才起效。 +'Packages have new version: {0}': '以下组件有新版本: {0}' "Split by ', '.": 由“, ”或“,”分隔。 "What's file?": 什么是文件? (All Problems): (所有题目) @@ -193,6 +194,7 @@ Current password doesn't match.: 当前密码输入错误。 Current Password: 当前密码 Current Status: 当前状态 currently offline: 目前离线 +Daily update check: 每日自动检查更新 Data of Problem {0} not found.: 题目 {0} 的数据缺失。 Data of problem {1} not found.: 题目 {1} 的数据未找到。 Data of record {0} not found.: 记录 {0} 的数据未找到。