mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-20 01:38:19 +08:00
Merge branch 'master' into contest-access-lock
This commit is contained in:
11 files changed
+62
-42
No files matched your search
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@hydrooj/hydrojudge",
|
"name": "@hydrooj/hydrojudge",
|
||||||
"bin": "bin/hydrojudge.js",
|
"bin": "bin/hydrojudge.js",
|
||||||
"version": "3.1.11",
|
"version": "3.1.12",
|
||||||
"main": "package.json",
|
"main": "package.json",
|
||||||
"author": "undefined <i@undefined.moe>",
|
"author": "undefined <i@undefined.moe>",
|
||||||
"repository": "https://github.com/hydro-dev/Hydro.git",
|
"repository": "https://github.com/hydro-dev/Hydro.git",
|
||||||
|
|||||||
@@ -22,6 +22,36 @@ type Checker = (config: CheckConfig) => Promise<{
|
|||||||
message: string,
|
message: string,
|
||||||
}>;
|
}>;
|
||||||
|
|
||||||
|
function parseDiffMsg(msg: string) {
|
||||||
|
try {
|
||||||
|
// Note: we only handle first diff
|
||||||
|
const desc = msg.split('\n')[0];
|
||||||
|
if (desc.includes('d')) return 'User output longer than standard answer.';
|
||||||
|
if (desc.includes('a')) return 'Standard answer longer than user output.';
|
||||||
|
const pt = msg.split('---');
|
||||||
|
// Get the first different line
|
||||||
|
const u = pt[0].split('\n')[1];
|
||||||
|
const t = pt[1].split('\n')[1];
|
||||||
|
// Split by token
|
||||||
|
const usr = u.substring(2).trim().split(' ');
|
||||||
|
const std = t.substring(2).trim().split(' ');
|
||||||
|
if (std.every((x) => !Number.isNaN(+x))) {
|
||||||
|
// Number mode, report length not match
|
||||||
|
if (usr.length > std.length) return 'User output longer than standard answer.';
|
||||||
|
if (usr.length < std.length) return 'Standard answer longer than user output.';
|
||||||
|
}
|
||||||
|
for (let i = 0; i < usr.length; i++) {
|
||||||
|
if (usr[i] === std[i]) continue;
|
||||||
|
const usrString = usr[i].length > 20 ? `${usr[i].substring(0, 16)}...` : usr[i];
|
||||||
|
const stdString = std[i].length > 20 ? `${std[i].substring(0, 16)}...` : std[i];
|
||||||
|
return { message: 'Read {0}, expect {1}.', params: [usrString, stdString] };
|
||||||
|
}
|
||||||
|
throw new Error();
|
||||||
|
} catch (e) {
|
||||||
|
return msg.substring(0, msg.length - 1 <= 30 ? msg.length - 1 : 30);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const checkers: Record<string, Checker> = new Proxy({
|
const checkers: Record<string, Checker> = new Proxy({
|
||||||
async default(config) {
|
async default(config) {
|
||||||
const { stdout } = await run('/usr/bin/diff -BZ usrout answer', {
|
const { stdout } = await run('/usr/bin/diff -BZ usrout answer', {
|
||||||
@@ -35,33 +65,7 @@ const checkers: Record<string, Checker> = new Proxy({
|
|||||||
let message: any = '';
|
let message: any = '';
|
||||||
if (stdout) {
|
if (stdout) {
|
||||||
status = STATUS.STATUS_WRONG_ANSWER;
|
status = STATUS.STATUS_WRONG_ANSWER;
|
||||||
if (config.detail) {
|
if (config.detail) message = parseDiffMsg(stdout);
|
||||||
try {
|
|
||||||
const pt = stdout.split('---');
|
|
||||||
const u = pt[0].split('\n')[1];
|
|
||||||
const usr = u.substring(2).trim().split(' ');
|
|
||||||
const t = pt[1].split('\n')[1];
|
|
||||||
const std = t.substring(2).trim().split(' ');
|
|
||||||
if (usr.length < std.length) message = 'Standard answer longer than user output.';
|
|
||||||
else if (usr.length > std.length) message = 'User output longer than standard answer.';
|
|
||||||
else {
|
|
||||||
let usrString = usr[0];
|
|
||||||
let stdString = std[0];
|
|
||||||
for (const i in usr) {
|
|
||||||
if (usr[i] !== std[i]) {
|
|
||||||
usrString = usr[i];
|
|
||||||
stdString = std[i];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (usrString.length > 20) usrString = `${usrString.substring(0, 16)}...`;
|
|
||||||
if (stdString.length > 20) stdString = `${stdString.substring(0, 16)}...`;
|
|
||||||
message = { message: 'Read {0}, expect {1}.', params: [usrString, stdString] };
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
message = stdout.substring(0, stdout.length - 1 <= 30 ? stdout.length - 1 : 30);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else status = STATUS.STATUS_ACCEPTED;
|
} else status = STATUS.STATUS_ACCEPTED;
|
||||||
if (message.length > 1024000) message = '';
|
if (message.length > 1024000) message = '';
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "hydrooj",
|
"name": "hydrooj",
|
||||||
"version": "4.4.4",
|
"version": "4.4.5",
|
||||||
"bin": "bin/hydrooj.js",
|
"bin": "bin/hydrooj.js",
|
||||||
"main": "src/plugin-api",
|
"main": "src/plugin-api",
|
||||||
"module": "src/plugin-api",
|
"module": "src/plugin-api",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@hydrooj/onlyoffice",
|
"name": "@hydrooj/onlyoffice",
|
||||||
"version": "1.3.0",
|
"version": "1.3.1",
|
||||||
"main": "index.ts",
|
"main": "index.ts",
|
||||||
"repository": "git@github.com:hydro-dev/Hydro.git",
|
"repository": "git@github.com:hydro-dev/Hydro.git",
|
||||||
"author": "undefined <i@undefined.moe>",
|
"author": "undefined <i@undefined.moe>",
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import { i18n, tpl } from 'vj/utils';
|
|||||||
|
|
||||||
const onmessage = (msg) => {
|
const onmessage = (msg) => {
|
||||||
console.log('Received message', msg);
|
console.log('Received message', msg);
|
||||||
if (document.hidden) return false;
|
|
||||||
if (msg.mdoc.flag & FLAG_ALERT) {
|
if (msg.mdoc.flag & FLAG_ALERT) {
|
||||||
// Is alert
|
// Is alert
|
||||||
new InfoDialog({
|
new InfoDialog({
|
||||||
@@ -21,6 +20,7 @@ const onmessage = (msg) => {
|
|||||||
}).open();
|
}).open();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (document.hidden) return false;
|
||||||
// Is message
|
// Is message
|
||||||
new VjNotification({
|
new VjNotification({
|
||||||
...(msg.udoc._id === 1 && msg.mdoc.flag & 4)
|
...(msg.udoc._id === 1 && msg.mdoc.flag & 4)
|
||||||
|
|||||||
+22
-6
@@ -12,12 +12,28 @@ export const AppToaster = Toaster.create({
|
|||||||
className: 'recipe-toaster',
|
className: 'recipe-toaster',
|
||||||
position: Position.LEFT_BOTTOM,
|
position: Position.LEFT_BOTTOM,
|
||||||
usePortal: true,
|
usePortal: true,
|
||||||
}, ToasterContainer);
|
} as any, ToasterContainer);
|
||||||
|
|
||||||
|
interface NotificationOptions {
|
||||||
|
avatar?: string;
|
||||||
|
title?: string;
|
||||||
|
message: string;
|
||||||
|
type?: string;
|
||||||
|
duration?: number;
|
||||||
|
action?: any;
|
||||||
|
}
|
||||||
|
|
||||||
export default class Notification {
|
export default class Notification {
|
||||||
|
type: string;
|
||||||
|
action: any;
|
||||||
|
$dom: JQuery<HTMLElement>;
|
||||||
|
$n: JQuery<HTMLElement>;
|
||||||
|
duration: number;
|
||||||
|
autoHideTimer?: NodeJS.Timeout;
|
||||||
|
|
||||||
constructor({
|
constructor({
|
||||||
avatar, title, message, type = '', duration = 3000, action,
|
avatar, title, message, type = '', duration = 3000, action,
|
||||||
}) {
|
}: NotificationOptions) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
if (avatar) this.type += ' avatar';
|
if (avatar) this.type += ' avatar';
|
||||||
if (title) this.type += ' title';
|
if (title) this.type += ' title';
|
||||||
@@ -49,19 +65,19 @@ export default class Notification {
|
|||||||
setTimeout(() => this.$n.remove(), 200);
|
setTimeout(() => this.$n.remove(), 200);
|
||||||
}
|
}
|
||||||
|
|
||||||
static success(message, duration) {
|
static success(message: string, duration?: number) {
|
||||||
return AppToaster.show({ message, timeout: duration, intent: Intent.SUCCESS });
|
return AppToaster.show({ message, timeout: duration, intent: Intent.SUCCESS });
|
||||||
}
|
}
|
||||||
|
|
||||||
static info(message, duration) {
|
static info(message: string, duration?: number) {
|
||||||
return AppToaster.show({ message, timeout: duration, intent: Intent.PRIMARY });
|
return AppToaster.show({ message, timeout: duration, intent: Intent.PRIMARY });
|
||||||
}
|
}
|
||||||
|
|
||||||
static warn(message, duration) {
|
static warn(message: string, duration?: number) {
|
||||||
return AppToaster.show({ message, timeout: duration, intent: Intent.WARNING });
|
return AppToaster.show({ message, timeout: duration, intent: Intent.WARNING });
|
||||||
}
|
}
|
||||||
|
|
||||||
static error(message, duration) {
|
static error(message: string, duration?: number) {
|
||||||
return AppToaster.show({ message, timeout: duration, intent: Intent.DANGER });
|
return AppToaster.show({ message, timeout: duration, intent: Intent.DANGER });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@hydrooj/ui-default",
|
"name": "@hydrooj/ui-default",
|
||||||
"version": "4.42.21",
|
"version": "4.43.0",
|
||||||
"author": "undefined <i@undefined.moe>",
|
"author": "undefined <i@undefined.moe>",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"main": "index.ts",
|
"main": "index.ts",
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
{% if UserContext %}{% include "partials/header_mobile.html" %}{% endif %}
|
{% if UserContext %}{% include "partials/header_mobile.html" %}{% endif %}
|
||||||
<div class="main">
|
<div class="main">
|
||||||
{% for item in ui.getNodes('Notification').concat(notification or []) %}{% if item.checker(handler) %}
|
{% for item in ui.getNodes('Notification').concat(notification or []) %}{% if item.checker(handler) %}
|
||||||
<div class="row"><blockquote class="{{ item.args.type }}">{{ _(item.name).format(item.args.args or []) }}</blockquote></div>
|
<div class="row typo"><blockquote class="{{ item.args.type }}">{{ _(item.name).format(item.args.args or [])|nl2br|safe }}</blockquote></div>
|
||||||
{% endif %}{% endfor %}
|
{% endif %}{% endfor %}
|
||||||
{% block content %}{% endblock %}
|
{% block content %}{% endblock %}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
{{ set(UiContext, 'udoc', udoc) }}
|
{{ set(UiContext, 'udoc', udoc) }}
|
||||||
<style>
|
<style>
|
||||||
.user-profile-bg {
|
.user-profile-bg {
|
||||||
background-image : url("{{ udoc.backgroundImage }}");
|
background-image: url("{{ udoc.backgroundImage }}"), url("/components/profile/backgrounds/1.jpg");
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@hydrooj/utils",
|
"name": "@hydrooj/utils",
|
||||||
"version": "1.4.4",
|
"version": "1.4.5",
|
||||||
"description": "hydrooj utils",
|
"description": "hydrooj utils",
|
||||||
"main": "lib/utils.ts",
|
"main": "lib/utils.ts",
|
||||||
"repository": "https://github.com/hydro-dev/Hydro.git",
|
"repository": "https://github.com/hydro-dev/Hydro.git",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@hydrooj/vjudge",
|
"name": "@hydrooj/vjudge",
|
||||||
"version": "1.7.0",
|
"version": "1.7.1",
|
||||||
"description": "Submit problems to remote oj",
|
"description": "Submit problems to remote oj",
|
||||||
"main": "package.json",
|
"main": "package.json",
|
||||||
"repository": "https://github.com/hydro-dev/Hydro.git",
|
"repository": "https://github.com/hydro-dev/Hydro.git",
|
||||||
|
|||||||
Reference in new issue
Block a user