mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-17 09:36:08 +08:00
bug fixes
This commit is contained in:
11 files changed
+45
-19
No files matched your search
@@ -670,7 +670,6 @@ ${c.response.status} ${endTime - startTime}ms ${c.response.length}`);
|
||||
}
|
||||
} catch (e) {
|
||||
// error during initialization (prepare, hooks)
|
||||
logger.error(e);
|
||||
await clean(e);
|
||||
}
|
||||
}
|
||||
|
||||
+5
-3
@@ -195,6 +195,7 @@ const Caddyfile = `\
|
||||
# 仅需将 :80 改为你的域名(如 hydro.ac)后使用 caddy reload 重载配置即可自动签发 ssl 证书。
|
||||
# 填写完整域名,注意区分有无 www (www.hydro.ac 和 hydro.ac 不同,请检查 DNS 设置)
|
||||
# 请注意在防火墙/安全组中放行端口,且部分运营商会拦截未经备案的域名。
|
||||
# 其他需求清参照 https://caddyserver.com/docs/ 说明进行设置。
|
||||
# For more information, refer to caddy v2 documentation.
|
||||
:80 {
|
||||
encode zstd gzip
|
||||
@@ -242,6 +243,7 @@ hosts:
|
||||
uname: judge
|
||||
password: examplepassword
|
||||
detail: true
|
||||
concurrency: 2
|
||||
tmpfs_size: 512m
|
||||
stdio_size: 256m
|
||||
memoryMax: ${Math.min(1024, os.totalmem() / 4)}m
|
||||
@@ -253,7 +255,7 @@ parallelism: ${Math.max(1, Math.floor(cpus().length / 4))}
|
||||
singleTaskParallelism: 2
|
||||
rate: 1.00
|
||||
rerun: 2
|
||||
secret: ${String.random(32)}
|
||||
secret: ${crypto.randomBytes(32).toString('hex')}
|
||||
env: |
|
||||
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
||||
HOME=/w
|
||||
@@ -409,8 +411,8 @@ ${nixConfBase}`);
|
||||
const docker = !exec('docker -v').code;
|
||||
if (!docker) return;
|
||||
const containers = exec('docker ps -a --format json').output?.split('\n')
|
||||
.map((i) => i.trim()).filter((i) => i).map((i) => JSON.parse(i));
|
||||
const uoj = containers?.find((i) => i.Image.toLowerCase() === 'universaloj/uoj-system' && i.State === 'running');
|
||||
.map((i) => i.trim()).filter((i) => i).map((i) => JSON.parse(i)) || [];
|
||||
const uoj = containers.find((i) => i.Image.toLowerCase() === 'universaloj/uoj-system' && i.State === 'running');
|
||||
if (uoj) {
|
||||
log.info('migrate.uojFound');
|
||||
const res = await rl.question('>');
|
||||
|
||||
@@ -59,7 +59,7 @@ const session: Session = {
|
||||
},
|
||||
};
|
||||
|
||||
export async function* apply(ctx: HydroContext) {
|
||||
export async function apply(ctx: HydroContext) {
|
||||
ctx.inject(['check'], (c) => {
|
||||
c.check.addChecker('Judge', async (_ctx, log, warn, error) => {
|
||||
await versionCheck(warn, error);
|
||||
@@ -75,9 +75,7 @@ export async function* apply(ctx: HydroContext) {
|
||||
}
|
||||
await (new JudgeTask(session, JSON.parse(JSON.stringify(Object.assign(rdoc, t))))).handle().catch(logger.error);
|
||||
};
|
||||
const parallelism = Math.max(getConfig('parallelism'), 2);
|
||||
const taskConsumer = TaskModel.consume({ type: 'judge' }, handle, true, parallelism);
|
||||
yield () => taskConsumer.destroy();
|
||||
const parallelism = getConfig('parallelism');
|
||||
async function collectInfo() {
|
||||
const coll = db.collection('status');
|
||||
const compilers = await compilerVersions(langs);
|
||||
@@ -93,11 +91,20 @@ export async function* apply(ctx: HydroContext) {
|
||||
{ upsert: true },
|
||||
);
|
||||
}
|
||||
yield ctx.on('system/setting', () => {
|
||||
taskConsumer.setConcurrency(Math.max(getConfig('parallelism'), 2));
|
||||
collectInfo();
|
||||
ctx.effect(() => {
|
||||
const taskConsumer = TaskModel.consume({ type: 'judge' }, handle, true, parallelism);
|
||||
const dispose = ctx.on('system/setting', () => {
|
||||
taskConsumer.setConcurrency(getConfig('parallelism'));
|
||||
collectInfo();
|
||||
});
|
||||
return () => {
|
||||
taskConsumer.destroy();
|
||||
dispose();
|
||||
};
|
||||
});
|
||||
ctx.effect(() => {
|
||||
const generateConsumer = TaskModel.consume({ type: 'generate' }, handle);
|
||||
return () => generateConsumer.destroy();
|
||||
});
|
||||
collectInfo();
|
||||
const generateConsumer = TaskModel.consume({ type: 'generate' }, handle);
|
||||
yield () => generateConsumer.destroy();
|
||||
}
|
||||
@@ -2,7 +2,6 @@
|
||||
/* eslint-disable no-await-in-loop */
|
||||
import '../lib/index';
|
||||
|
||||
import os from 'os';
|
||||
import path from 'path';
|
||||
import fs from 'fs-extra';
|
||||
import yaml from 'js-yaml';
|
||||
|
||||
@@ -181,7 +181,6 @@ export class HomeHandler extends Handler {
|
||||
class HomeSecurityHandler extends Handler {
|
||||
@requireSudo
|
||||
async get() {
|
||||
const geoip = this.ctx.get('geoip');
|
||||
// TODO(iceboy): pagination? or limit session count for uid?
|
||||
const sessions = await token.getSessionListByUid(this.user._id);
|
||||
for (const session of sessions) {
|
||||
@@ -189,7 +188,7 @@ class HomeSecurityHandler extends Handler {
|
||||
session._id = md5(session._id);
|
||||
const ua = session.updateUa || session.createUa;
|
||||
if (ua) session.updateUaInfo = UAParser(ua);
|
||||
session.updateGeoip = geoip?.lookup?.(
|
||||
session.updateGeoip = this.ctx.geoip?.lookup?.(
|
||||
session.updateIp || session.createIp,
|
||||
this.translate('geoip_locale'),
|
||||
);
|
||||
@@ -202,7 +201,7 @@ class HomeSecurityHandler extends Handler {
|
||||
'credentialID', 'name', 'credentialType', 'credentialDeviceType',
|
||||
'authenticatorAttachment', 'regat', 'fmt',
|
||||
])),
|
||||
geoipProvider: geoip?.provider,
|
||||
geoipProvider: this.ctx.geoip?.provider,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -610,6 +609,7 @@ class HomeMessagesConnectionHandler extends ConnectionHandler {
|
||||
}
|
||||
}
|
||||
|
||||
export const inject = { geoip: { required: false } };
|
||||
export function apply(ctx: Context) {
|
||||
ctx.Route('homepage', '/', HomeHandler);
|
||||
ctx.Route('home_security', '/home/security', HomeSecurityHandler, PRIV.PRIV_USER_PROFILE);
|
||||
|
||||
@@ -16,6 +16,7 @@ declare module '../service/bus' {
|
||||
class I18nService extends Service {
|
||||
constructor(ctx: Context) {
|
||||
super(ctx, 'i18n');
|
||||
this.translate = this.translate.bind(this);
|
||||
this.load('ja', { __flag: '🇯🇵', __id: 'ja', __langname: '日本語' });
|
||||
}
|
||||
|
||||
|
||||
@@ -304,6 +304,7 @@ export default async function (env: { watch?: boolean, production?: boolean, mea
|
||||
}),
|
||||
new webpack.NormalModuleReplacementPlugin(/\/(vscode-)?nls\.js/, require.resolve('../../components/monaco/nls')),
|
||||
new webpack.NormalModuleReplacementPlugin(/^prettier[$/]/, root('../../modules/nop.ts')),
|
||||
new webpack.NormalModuleReplacementPlugin(/^highlightjs[$/]/, root('../../modules/nop.ts')),
|
||||
new webpack.NormalModuleReplacementPlugin(/core-js\/stable/, root('__core-js.js')),
|
||||
new MonacoWebpackPlugin({
|
||||
filename: '[name].[hash:6].worker.js',
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
.decoration-hide
|
||||
color: grey !important
|
||||
background-color: grey !important
|
||||
|
||||
.md-editor-preview code
|
||||
background-color: unset !important
|
||||
color: unset !important
|
||||
|
||||
.md-editor-scrn pre.syntax-hl code
|
||||
padding-left: unset !important
|
||||
@@ -1,4 +1,5 @@
|
||||
import $ from 'jquery';
|
||||
import { debounce } from 'lodash';
|
||||
import { nanoid } from 'nanoid';
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom/client';
|
||||
@@ -156,8 +157,12 @@ export default class Editor extends DOMAttachedObject {
|
||||
const { onChange } = this.options;
|
||||
const { MdEditor } = await import('./mdeditor');
|
||||
|
||||
const debouncedTrigger = debounce(() => {
|
||||
$(document.querySelector('.md-editor-preview')).trigger('vjContentNew');
|
||||
}, 500, { trailing: true });
|
||||
const renderCallback = (ref) => {
|
||||
this.markdownEditor = ref;
|
||||
setTimeout(debouncedTrigger, 200);
|
||||
};
|
||||
|
||||
function EditorComponent() {
|
||||
@@ -169,10 +174,12 @@ export default class Editor extends DOMAttachedObject {
|
||||
codeTheme='github'
|
||||
codeStyleReverse={false}
|
||||
ref={renderCallback}
|
||||
modelValue={val}
|
||||
value={val}
|
||||
theme={getTheme()}
|
||||
noMermaid
|
||||
noPrettier
|
||||
noKatex
|
||||
noHighlight
|
||||
autoDetectCode
|
||||
toolbarsExclude={[
|
||||
// 'bold',
|
||||
@@ -214,6 +221,7 @@ export default class Editor extends DOMAttachedObject {
|
||||
$dom.val(v);
|
||||
$dom.text(v);
|
||||
onChange?.(v);
|
||||
setTimeout(debouncedTrigger, 100);
|
||||
}}
|
||||
onUploadImg={async (files, callback) => {
|
||||
let ext: string;
|
||||
|
||||
@@ -7,6 +7,7 @@ import MergeCells from 'markdown-it-merge-cells';
|
||||
import TOC from 'markdown-it-table-of-contents';
|
||||
import { config, MdEditor } from 'md-editor-rt';
|
||||
import Imsize from '../../backendlib/markdown-it-imsize';
|
||||
import katex from '../../backendlib/markdown-it-katex';
|
||||
import { Media } from '../../backendlib/markdown-it-media';
|
||||
import { xssProtector } from '../../backendlib/markdown-it-xss';
|
||||
|
||||
@@ -28,6 +29,7 @@ config({
|
||||
mdit.use(TOC);
|
||||
mdit.use(MergeCells);
|
||||
mdit.use(xssProtector);
|
||||
mdit.use(katex);
|
||||
if (isProblemPage) {
|
||||
mdit.core.ruler.before('normalize', 'xss', (state) => {
|
||||
state.src = state.src.replace(/file:\/\//g, pagename === 'problem_create' ? `/file/${UserContext._id}/` : './file/');
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
label:'Difficulty',
|
||||
help_text:'From 1-10',
|
||||
name:'difficulty',
|
||||
value:pdoc['difficulty']
|
||||
value:pdoc['difficulty'] or ''
|
||||
}) }}
|
||||
</div>
|
||||
<div class="section__tab-container nojs--hide">
|
||||
|
||||
Reference in new issue
Block a user