core: 支持限制题目的提交语言

This commit is contained in:
undefined committed 2021-05-18 23:38:58 +08:00
1 parent f33d440b68
commit 75429bb43b
10 files changed
+44 -25

No files matched your search

+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "hydrooj",
"version": "2.26.12",
"version": "2.26.13",
"bin": "bin/hydrooj.js",
"main": "dist/loader.js",
"typings": "dist/loader.d.ts",
+4 -1
View File
@@ -4,7 +4,7 @@ import AdmZip from 'adm-zip';
import { isSafeInteger } from 'lodash';
import {
ContestNotLiveError, ValidationError, ProblemNotFoundError,
ContestNotAttendedError, PermissionError,
ContestNotAttendedError, PermissionError, BadRequestError,
} from '../error';
import { ProblemDoc, Tdoc, User } from '../interface';
import paginate from '../lib/paginate';
@@ -344,6 +344,9 @@ class ContestDetailProblemSubmitHandler extends ContestProblemHandler {
@param('lang', Types.Name)
@param('code', Types.Content)
async post(domainId: string, tid: ObjectID, lang: string, code: string) {
if (this.response.body.pdoc.config.langs && !this.response.body.pdoc.config.langs.includes('lang')) {
throw new BadRequestError('Language not allowed.');
}
await this.limitRate('add_record', 60, 10);
const rid = await record.add(domainId, this.pdoc.docId, this.user._id, lang, code, true, {
type: document.TYPE_CONTEST,
+3
View File
@@ -264,6 +264,9 @@ export class ProblemSubmitHandler extends ProblemDetailHandler {
@param('lang', Types.Name)
@param('code', Types.Content)
async post(domainId: string, lang: string, code: string) {
if (this.response.body.pdoc.config.langs && !this.response.body.pdoc.config.langs.includes('lang')) {
throw new BadRequestError('Language not allowed.');
}
await this.limitRate('add_record', 60, 5);
const rid = await record.add(domainId, this.pdoc.docId, this.user._id, lang, code, true);
const [rdoc] = await Promise.all([
+14 -13
View File
@@ -143,19 +143,20 @@ export interface SubtaskConfig {
}
export interface ProblemConfig {
type?: ProblemType,
score?: number,
time?: string,
memory?: string,
filename?: string,
checker_type?: string,
checker?: string,
interactor?: string,
user_extra_files?: string[],
judge_extra_files?: string[],
outputs?: [string, number][],
cases?: TestCaseConfig[],
subtasks?: SubtaskConfig[],
type?: ProblemType;
score?: number;
time?: string;
memory?: string;
filename?: string;
checker_type?: string;
checker?: string;
interactor?: string;
user_extra_files?: string[];
judge_extra_files?: string[];
outputs?: [string, number][];
cases?: TestCaseConfig[];
subtasks?: SubtaskConfig[];
langs?: string[];
}
export interface PlainContentNode {
+7 -5
View File
@@ -3,11 +3,12 @@ import { load } from 'js-yaml';
import type { ProblemConfig } from '../interface';
interface ParseResult {
count: number,
memoryMax: number,
memoryMin: number,
timeMax: number,
timeMin: number,
count: number;
memoryMax: number;
memoryMin: number;
timeMax: number;
timeMin: number;
langs?: string[];
}
export async function parseConfig(config: string | ProblemConfig = {}) {
@@ -40,6 +41,7 @@ export async function parseConfig(config: string | ProblemConfig = {}) {
if (result.timeMax < result.timeMin) {
result.timeMax = result.timeMin = 1000;
}
if (cfg.langs) result.langs = cfg.langs;
return result;
}
+2 -1
View File
@@ -284,7 +284,8 @@ const t = Math.exp(-0.15);
async function updateSort() {
const cursor = document.coll.find({ docType: document.TYPE_DISCUSSION });
while (cursor.hasNext()) {
// eslint-disable-next-line no-await-in-loop
while (await cursor.hasNext()) {
// eslint-disable-next-line no-await-in-loop
const data = await cursor.next();
// eslint-disable-next-line no-await-in-loop
@@ -78,6 +78,11 @@ export default connect(mapStateToProps, mapDispatchToProps)(class ScratchpadTool
}
render() {
const LANGS = {};
for (const key in window.LANGS) {
if (UiContext.pdoc.config.langs && !UiContext.pdoc.config.langs.includes(key)) continue;
LANGS[key] = window.LANGS[key];
}
return (
<Toolbar>
<ToolbarButton
@@ -136,7 +141,7 @@ export default connect(mapStateToProps, mapDispatchToProps)(class ScratchpadTool
value={this.props.editorLang}
onChange={(ev) => this.props.setEditorLanguage(ev.target.value)}
>
{_.map(window.LANGS, (val, key) => (
{_.map(LANGS, (val, key) => (
<option value={key} key={key}>{val.display}</option>
))}
</select>
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@hydrooj/ui-default",
"version": "4.8.25",
"version": "4.8.26",
"author": "undefined <i@undefined.moe>",
"license": "AGPL-3.0",
"main": "hydro.js",
@@ -15,12 +15,13 @@ const page = new NamedPage(['problem_submit', 'contest_detail_problem_submit'],
$('#codelang-main-select').on('change', function () {
const options = {};
for (const key in window.LANGS) {
if (UiContext.pdocConfig.langs && !UiContext.pdocConfig.langs.includes(key)) continue;
if (key.startsWith(`${this.value}.`) && key !== this.value) options[key] = window.LANGS[key].display;
}
if (Object.keys(options).length > 1) {
setOptions($('#codelang-sub-select'), options);
$('#codelang-sub-container').show();
$('[name="codeLang"]').val($('#codelang-sub-container').val());
$('[name="codeLang"]').val($('#codelang-sub-select').val());
} else {
$('#codelang-sub-container').hide();
$('[name="codeLang"]').val(this.value);
@@ -31,6 +32,7 @@ const page = new NamedPage(['problem_submit', 'contest_detail_problem_submit'],
});
const main = {};
for (const key in window.LANGS) {
if (UiContext.pdocConfig.langs && !UiContext.pdocConfig.langs.includes(key)) continue;
if (!key.includes('.')) main[key] = window.LANGS[key].display;
}
setOptions($('#codelang-main-select'), main);
@@ -38,7 +40,8 @@ const page = new NamedPage(['problem_submit', 'contest_detail_problem_submit'],
if (current.includes('.')) {
const [m, s] = current.split('.');
$('#codelang-main-select').val(m);
$('#codelang-sub-select').val(s).show();
$('#codelang-sub-select').val(s);
$('#codelang-sub-container').show();
} else $('#codelang-main-select').val(current);
});
@@ -1,5 +1,6 @@
{% extends "layout/basic.html" %}
{% block content %}
{{ set(UiContext, 'pdocConfig', pdoc.config) }}
<div class="row">
<div class="medium-9 columns">
{% if not tdoc or rdocs.length %}