core: objective

This commit is contained in:
undefined committed 2021-07-29 00:26:32 +08:00
1 parent de5b908272
commit 47b7866053
14 files changed
+31 -18

No files matched your search

+1 -1
View File
@@ -1,7 +1,7 @@
{ {
"name": "@hydrooj/hydrojudge", "name": "@hydrooj/hydrojudge",
"bin": "bin/hydrojudge.js", "bin": "bin/hydrojudge.js",
"version": "2.8.18", "version": "2.8.19",
"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",
+1 -1
View File
@@ -5,5 +5,5 @@ import * as submit_answer from './submit_answer';
import * as hack from './hack'; import * as hack from './hack';
export = { export = {
default: def, interactive, run, submit_answer, hack, subjective: submit_answer, default: def, interactive, run, submit_answer, hack, objective: submit_answer,
}; };
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "hydrooj", "name": "hydrooj",
"version": "2.29.45", "version": "2.29.46",
"bin": "bin/hydrooj.js", "bin": "bin/hydrooj.js",
"main": "dist/loader.js", "main": "dist/loader.js",
"typings": "dist/loader.d.ts", "typings": "dist/loader.d.ts",
+1 -1
View File
@@ -126,7 +126,7 @@ export enum ProblemType {
Default = 'default', Default = 'default',
SubmitAnswer = 'submit_answer', SubmitAnswer = 'submit_answer',
Interactive = 'interactive', Interactive = 'interactive',
Subjective = 'subjective', Objective = 'objective',
} }
export enum SubtaskType { export enum SubtaskType {
+13
View File
@@ -414,6 +414,19 @@ const scripts: UpgradeScript[] = [
} }
return true; return true;
}, },
async function _37_38() {
const _FRESH_INSTALL_IGNORE = 1;
await iterateAllProblem(['docId', 'domainId', 'config'], async (pdoc) => {
logger.info('%s/%s', pdoc.domainId, pdoc.docId);
if (typeof pdoc.config !== 'string') return;
if (!pdoc.config?.includes('type: subjective')) return;
await problem.addTestdata(
pdoc.domainId, pdoc.docId, 'config.yaml',
Buffer.from(pdoc.config.replace('type: subjective', 'type: objective')),
);
});
return true;
},
]; ];
export default scripts; export default scripts;
@@ -54,7 +54,7 @@ const problemConfigSchema = {
def: problemConfigSchemaDef, def: problemConfigSchemaDef,
properties: { properties: {
key: { type: 'string', pattern: '[0-9a-f]{32}' }, key: { type: 'string', pattern: '[0-9a-f]{32}' },
type: { enum: ['default', 'interactive', 'submit_answer', 'subjective', 'remote_judge'] }, type: { enum: ['default', 'interactive', 'submit_answer', 'objective', 'remote_judge'] },
subType: { type: 'string' }, subType: { type: 'string' },
langs: { type: 'array', items: { type: 'string' } }, langs: { type: 'array', items: { type: 'string' } },
target: { type: 'string' }, target: { type: 'string' },
@@ -2,7 +2,7 @@ import React from 'react';
import { sortBy } from 'lodash'; import { sortBy } from 'lodash';
import request from 'vj/utils/request'; import request from 'vj/utils/request';
export default class SubjectiveContainer extends React.PureComponent { export default class ObjectiveContainer extends React.PureComponent {
constructor(args) { constructor(args) {
super(args); super(args);
this.state = {}; this.state = {};
+1 -1
View File
@@ -28,7 +28,7 @@ problem_type.default: 'Type: Default'
problem_type.fileio: 'Type: FileIO ({0})' problem_type.fileio: 'Type: FileIO ({0})'
problem_type.interactive: 'Type: Interactive' problem_type.interactive: 'Type: Interactive'
problem_type.remote_judge: 'Type: RemoteJudge' problem_type.remote_judge: 'Type: RemoteJudge'
problem_type.subjective: 'Type: Subjective' problem_type.objective: 'Type: Objective'
problem_type.submit_answer: 'Type: SubmitAnswer' problem_type.submit_answer: 'Type: SubmitAnswer'
problem-category-delim: '|' problem-category-delim: '|'
problem-subcategory-delim: ', ' problem-subcategory-delim: ', '
+1 -1
View File
@@ -558,7 +558,7 @@ problem_type.default: 传统题
problem_type.fileio: '文件IO ({0})' problem_type.fileio: '文件IO ({0})'
problem_type.interactive: 交互题 problem_type.interactive: 交互题
problem_type.remote_judge: 远端评测题 problem_type.remote_judge: 远端评测题
problem_type.subjective: 客观题 problem_type.objective: 客观题
problem_type.submit_answer: 提交答案题 problem_type.submit_answer: 提交答案题
problem-category-delim: '|' problem-category-delim: '|'
problem-subcategory-delim: 、 problem-subcategory-delim: 、
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@hydrooj/ui-default", "name": "@hydrooj/ui-default",
"version": "4.13.12", "version": "4.13.13",
"author": "undefined <i@undefined.moe>", "author": "undefined <i@undefined.moe>",
"license": "AGPL-3.0", "license": "AGPL-3.0",
"main": "hydro.js", "main": "hydro.js",
@@ -171,7 +171,7 @@ const page = new NamedPage(['problem_detail', 'contest_detail_problem', 'homewor
unmountReact(); unmountReact();
} }
async function loadSubjective() { async function loadObjective() {
try { try {
let s = ''; let s = '';
try { try {
@@ -189,15 +189,15 @@ const page = new NamedPage(['problem_detail', 'contest_detail_problem', 'homewor
const props = yaml.load(s); const props = yaml.load(s);
if (!(props instanceof Array)) return; if (!(props instanceof Array)) return;
$('.outer-loader-container').show(); $('.outer-loader-container').show();
const [{ default: Subjective }, React, ReactDOM] = await Promise.all([ const [{ default: Objective }, React, ReactDOM] = await Promise.all([
import('vj/components/subjective-question/index'), import('vj/components/objective-question/index'),
import('react'), import('react'),
import('react-dom'), import('react-dom'),
]); ]);
ReactDOM.render( ReactDOM.render(
<div className="section__body typo"> <div className="section__body typo">
<Subjective panel={props} target={UiContext.postSubmitUrl}></Subjective> <Objective panel={props} target={UiContext.postSubmitUrl}></Objective>
</div>, </div>,
$('.problem-content').get(0), $('.problem-content').get(0),
); );
@@ -265,7 +265,7 @@ const page = new NamedPage(['problem_detail', 'contest_detail_problem', 'homewor
$('span.tags').show(); $('span.tags').show();
}); });
$('[name="problem-sidebar__download').on('click', handleClickDownloadProblem); $('[name="problem-sidebar__download').on('click', handleClickDownloadProblem);
if (UiContext.pdoc.config?.type === 'subjective') loadSubjective(); if (UiContext.pdoc.config?.type === 'objective') loadObjective();
if (pagename !== 'contest_detail_problem') initChart(); if (pagename !== 'contest_detail_problem') initChart();
}); });
@@ -41,7 +41,7 @@
<ul class="problem__tags"> <ul class="problem__tags">
<span class="bp3-tag bp3-large bp3-minimal problem__tag-item">{{ _('ID') }}: {{ pdoc.docId }}</span> <span class="bp3-tag bp3-large bp3-minimal problem__tag-item">{{ _('ID') }}: {{ pdoc.docId }}</span>
<span class="bp3-tag bp3-large bp3-minimal problem__tag-item bp3-icon-standard bp3-icon-book">{{ _('problem_type.' + pdoc.config.type).format(pdoc.config.subType) }}</span> <span class="bp3-tag bp3-large bp3-minimal problem__tag-item bp3-icon-standard bp3-icon-book">{{ _('problem_type.' + pdoc.config.type).format(pdoc.config.subType) }}</span>
{% if pdoc.config.type != 'subjective' and pdoc.config.type != 'submit_answer' %} {% if pdoc.config.type != 'objective' and pdoc.config.type != 'submit_answer' %}
<span class="bp3-tag bp3-large bp3-minimal problem__tag-item bp3-icon-standard bp3-icon-stopwatch">{{ pdoc.config.timeMax if pdoc.config.timeMax == pdoc.config.timeMin else pdoc.config.timeMin+'~'+pdoc.config.timeMax }}ms</span> <span class="bp3-tag bp3-large bp3-minimal problem__tag-item bp3-icon-standard bp3-icon-stopwatch">{{ pdoc.config.timeMax if pdoc.config.timeMax == pdoc.config.timeMin else pdoc.config.timeMin+'~'+pdoc.config.timeMax }}ms</span>
<span class="bp3-tag bp3-large bp3-minimal problem__tag-item bp3-icon-standard bp3-icon-comparison">{{ pdoc.config.memoryMax if pdoc.config.memoryMax == pdoc.config.memoryMin else pdoc.config.memoryMin+'~'+pdoc.config.memoryMax }}MiB</span> <span class="bp3-tag bp3-large bp3-minimal problem__tag-item bp3-icon-standard bp3-icon-comparison">{{ pdoc.config.memoryMax if pdoc.config.memoryMax == pdoc.config.memoryMin else pdoc.config.memoryMin+'~'+pdoc.config.memoryMax }}MiB</span>
{% endif %} {% endif %}
+2 -2
View File
@@ -31,7 +31,7 @@ export default async function readYamlCases(cfg: Record<string, any> = {}, check
} else throw new Error('Invalid user_extra_files config.'); } else throw new Error('Invalid user_extra_files config.');
} }
if (cfg.outputs) { if (cfg.outputs) {
config.type = cfg.type || 'subjective'; config.type = cfg.type || 'objective';
} else if (cfg.cases?.length) { } else if (cfg.cases?.length) {
config.subtasks = [{ config.subtasks = [{
score: +cfg.score || Math.floor(100 / cfg.cases.length), score: +cfg.score || Math.floor(100 / cfg.cases.length),
@@ -71,7 +71,7 @@ export default async function readYamlCases(cfg: Record<string, any> = {}, check
} }
if (cfg.time) config.time = parseTimeMS(cfg.time); if (cfg.time) config.time = parseTimeMS(cfg.time);
if (cfg.memory) config.memory = parseMemoryMB(cfg.memory); if (cfg.memory) config.memory = parseMemoryMB(cfg.memory);
if ((config.type === 'subjective' || cfg.type === 'submit_answer') && !cfg.outputs?.length) throw new Error('outputs config not found'); if ((config.type === 'objective' || cfg.type === 'submit_answer') && !cfg.outputs?.length) throw new Error('outputs config not found');
return Object.assign(cfg, config); return Object.assign(cfg, config);
} }
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@hydrooj/utils", "name": "@hydrooj/utils",
"version": "1.0.24", "version": "1.0.26",
"description": "hydrooj utils", "description": "hydrooj utils",
"main": "package.json", "main": "package.json",
"repository": "https://github.com/hydro-dev/Hydro.git", "repository": "https://github.com/hydro-dev/Hydro.git",