mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-20 01:38:19 +08:00
core&ui: add auto organize input option to hack (#780)
Co-authored-by: undefined <i@undefined.moe>
This commit is contained in:
1 parent
42569783f9
commit
ffe06804a7
7 files changed
+41
-5
No files matched your search
@@ -72,6 +72,7 @@ problem_create: Problem Create
|
|||||||
problem_detail: Problem Detail
|
problem_detail: Problem Detail
|
||||||
problem_edit: Problem Edit
|
problem_edit: Problem Edit
|
||||||
problem_files: Problem Files
|
problem_files: Problem Files
|
||||||
|
problem_hack: Hack
|
||||||
problem_import: Import Problem
|
problem_import: Import Problem
|
||||||
problem_main: Problem Set
|
problem_main: Problem Set
|
||||||
problem_solution: Problem Solution
|
problem_solution: Problem Solution
|
||||||
@@ -109,5 +110,6 @@ user_login: Login
|
|||||||
user_logout: Logout
|
user_logout: Logout
|
||||||
user_lostpass: Lost Password
|
user_lostpass: Lost Password
|
||||||
user_register: Register
|
user_register: Register
|
||||||
|
user_sudo: Entering Sudo Mode
|
||||||
wiki_about: About
|
wiki_about: About
|
||||||
wiki_help: Help
|
wiki_help: Help
|
||||||
@@ -36,6 +36,7 @@ __langname: 简体中文
|
|||||||
'The value `{1}` of {0} already exists.': '{0} 的值 `{1}` 已经存在。'
|
'The value `{1}` of {0} already exists.': '{0} 的值 `{1}` 已经存在。'
|
||||||
'Yes': 是
|
'Yes': 是
|
||||||
"Effects only when Difficulty is not 'Use algorithm calculated'.": 仅当难度不为“使用算法计算”时才起效。
|
"Effects only when Difficulty is not 'Use algorithm calculated'.": 仅当难度不为“使用算法计算”时才起效。
|
||||||
|
"Or upload a file:": 或者上传一个文件:
|
||||||
"Split by ',' '.'": 由“, ”或“,”分隔。
|
"Split by ',' '.'": 由“, ”或“,”分隔。
|
||||||
"What's file?": 什么是文件?
|
"What's file?": 什么是文件?
|
||||||
(All Problems): (所有题目)
|
(All Problems): (所有题目)
|
||||||
@@ -87,7 +88,9 @@ Attend Contest: 参加比赛
|
|||||||
Attend contests: 参加比赛
|
Attend contests: 参加比赛
|
||||||
Attended: 已参加
|
Attended: 已参加
|
||||||
author: 作者
|
author: 作者
|
||||||
|
Auto adjust the format of line breaks and remove unnecessary whitespace characters.: 自动调整换行符格式,并移除不必要的空白字符。
|
||||||
Auto format code: 自动格式化代码
|
Auto format code: 自动格式化代码
|
||||||
|
Auto organize input: 自动整理输入
|
||||||
Avatar: 头像
|
Avatar: 头像
|
||||||
Back to contest list: 返回比赛列表
|
Back to contest list: 返回比赛列表
|
||||||
Be Copied: 被复制
|
Be Copied: 被复制
|
||||||
@@ -281,6 +284,7 @@ Domain: 域
|
|||||||
Don't have an account?: 还没有账户?
|
Don't have an account?: 还没有账户?
|
||||||
Done: 已结束
|
Done: 已结束
|
||||||
Download Dataset: 下载数据集
|
Download Dataset: 下载数据集
|
||||||
|
Download Hack Input: 下载 Hack 输入
|
||||||
Download link copied to clipboard!: 下载链接已复制到剪贴板。
|
Download link copied to clipboard!: 下载链接已复制到剪贴板。
|
||||||
Download: 下载
|
Download: 下载
|
||||||
Downvote: 差评
|
Downvote: 差评
|
||||||
@@ -603,6 +607,7 @@ problem_create: 创建题目
|
|||||||
problem_detail: 题目详情
|
problem_detail: 题目详情
|
||||||
problem_edit: 编辑题目
|
problem_edit: 编辑题目
|
||||||
problem_files: 题目文件
|
problem_files: 题目文件
|
||||||
|
problem_hack: Hack
|
||||||
problem_import: 导入题目
|
problem_import: 导入题目
|
||||||
problem_main: 题库
|
problem_main: 题库
|
||||||
problem_solution: 题解
|
problem_solution: 题解
|
||||||
@@ -858,6 +863,7 @@ user_logout: 登出
|
|||||||
user_lostpass: 忘记密码
|
user_lostpass: 忘记密码
|
||||||
user_register_mail_sent: 注册邮件已发送
|
user_register_mail_sent: 注册邮件已发送
|
||||||
user_register: 注册
|
user_register: 注册
|
||||||
|
user_sudo: 用户安全授权
|
||||||
User-defined role: 用户定义的角色
|
User-defined role: 用户定义的角色
|
||||||
User: 用户
|
User: 用户
|
||||||
Username / UID: 用户名或 UID
|
Username / UID: 用户名或 UID
|
||||||
|
|||||||
@@ -587,8 +587,9 @@ export class ProblemHackHandler extends ProblemDetailHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@param('input', Types.String, true)
|
@param('input', Types.String, true)
|
||||||
|
@param('autoOrganizeInput', Types.Boolean, true)
|
||||||
@param('tid', Types.ObjectId, true)
|
@param('tid', Types.ObjectId, true)
|
||||||
async post(domainId: string, input = '', tid?: ObjectId) {
|
async post(domainId: string, input = '', autoOrganizeInput = false, tid?: ObjectId) {
|
||||||
await this.limitRate('add_record', 60, system.get('limit.submission_user'), true);
|
await this.limitRate('add_record', 60, system.get('limit.submission_user'), true);
|
||||||
await this.limitRate('add_record', 60, system.get('limit.submission'), false);
|
await this.limitRate('add_record', 60, system.get('limit.submission'), false);
|
||||||
const id = `${this.user._id}/${nanoid()}`;
|
const id = `${this.user._id}/${nanoid()}`;
|
||||||
@@ -597,12 +598,18 @@ export class ProblemHackHandler extends ProblemDetailHandler {
|
|||||||
if (!file || file.size > 128 * 1024 * 1024) throw new ValidationError('input');
|
if (!file || file.size > 128 * 1024 * 1024) throw new ValidationError('input');
|
||||||
await storage.put(`submission/${id}`, file.filepath, this.user._id);
|
await storage.put(`submission/${id}`, file.filepath, this.user._id);
|
||||||
} else if (input) {
|
} else if (input) {
|
||||||
|
if (autoOrganizeInput) input = input.replace(/\s+\n/g, '\n').replace(/\s+ /g, ' ');
|
||||||
await storage.put(`submission/${id}`, Buffer.from(input), this.user._id);
|
await storage.put(`submission/${id}`, Buffer.from(input), this.user._id);
|
||||||
}
|
}
|
||||||
const rid = await record.add(
|
const rid = await record.add(
|
||||||
domainId, this.pdoc.docId, this.user._id,
|
domainId, this.pdoc.docId, this.user._id,
|
||||||
this.rdoc.lang, this.rdoc.code, true,
|
this.rdoc.lang, this.rdoc.code, true,
|
||||||
{ contest: tid, type: 'hack', files: { hack: `${id}#input.txt` } },
|
{
|
||||||
|
contest: tid,
|
||||||
|
type: 'hack',
|
||||||
|
hackTarget: this.rdoc._id,
|
||||||
|
files: { hack: `${id}#input.txt` },
|
||||||
|
},
|
||||||
);
|
);
|
||||||
// TODO contest: update status;
|
// TODO contest: update status;
|
||||||
this.response.body = { rid };
|
this.response.body = { rid };
|
||||||
|
|||||||
@@ -329,8 +329,10 @@ export interface RecordDoc {
|
|||||||
judgeAt: Date;
|
judgeAt: Date;
|
||||||
status: number;
|
status: number;
|
||||||
progress?: number;
|
progress?: number;
|
||||||
/** pretest & hack */
|
/** pretest */
|
||||||
input?: string;
|
input?: string;
|
||||||
|
/** hack target rid */
|
||||||
|
hackTarget?: ObjectId;
|
||||||
/** 0 if pretest&script */
|
/** 0 if pretest&script */
|
||||||
contest?: ObjectId;
|
contest?: ObjectId;
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ export default class RecordModel {
|
|||||||
'_id', 'score', 'time', 'memory', 'lang',
|
'_id', 'score', 'time', 'memory', 'lang',
|
||||||
'uid', 'pid', 'rejudged', 'progress', 'domainId',
|
'uid', 'pid', 'rejudged', 'progress', 'domainId',
|
||||||
'contest', 'judger', 'judgeAt', 'status', 'source',
|
'contest', 'judger', 'judgeAt', 'status', 'source',
|
||||||
'files',
|
'files', 'hackTarget',
|
||||||
];
|
];
|
||||||
|
|
||||||
static STAT_QUERY = {
|
static STAT_QUERY = {
|
||||||
@@ -122,6 +122,7 @@ export default class RecordModel {
|
|||||||
contest?: ObjectId,
|
contest?: ObjectId,
|
||||||
input?: string,
|
input?: string,
|
||||||
files?: Record<string, string>,
|
files?: Record<string, string>,
|
||||||
|
hackTarget?: ObjectId,
|
||||||
type: 'judge' | 'rejudge' | 'pretest' | 'hack' | 'generate',
|
type: 'judge' | 'rejudge' | 'pretest' | 'hack' | 'generate',
|
||||||
} = { type: 'judge' },
|
} = { type: 'judge' },
|
||||||
) {
|
) {
|
||||||
@@ -146,6 +147,7 @@ export default class RecordModel {
|
|||||||
let isContest = !!args.contest;
|
let isContest = !!args.contest;
|
||||||
if (args.contest) data.contest = args.contest;
|
if (args.contest) data.contest = args.contest;
|
||||||
if (args.files) data.files = args.files;
|
if (args.files) data.files = args.files;
|
||||||
|
if (args.hackTarget) data.hackTarget = args.hackTarget;
|
||||||
if (args.type === 'rejudge') {
|
if (args.type === 'rejudge') {
|
||||||
args.type = 'judge';
|
args.type = 'judge';
|
||||||
data.rejudged = true;
|
data.rejudged = true;
|
||||||
|
|||||||
@@ -16,6 +16,16 @@
|
|||||||
<br />
|
<br />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="row"><div class="columns">
|
||||||
|
<label>
|
||||||
|
{{ _('Auto organize input') }}
|
||||||
|
<br />
|
||||||
|
<label class="checkbox">
|
||||||
|
<input type="checkbox" name="autoOrganizeInput" class="checkbox">
|
||||||
|
{{ _('Auto adjust the format of line breaks and remove unnecessary whitespace characters.') }}
|
||||||
|
</label>
|
||||||
|
</label>
|
||||||
|
</div></div>
|
||||||
<div class="row"><div class="columns">
|
<div class="row"><div class="columns">
|
||||||
<input type="submit" class="rounded primary button" value="{{ _('Submit') }}">
|
<input type="submit" class="rounded primary button" value="{{ _('Submit') }}">
|
||||||
</div></div>
|
</div></div>
|
||||||
|
|||||||
@@ -14,7 +14,10 @@
|
|||||||
<div class="section__header">
|
<div class="section__header">
|
||||||
<h1 class="section__title">{{ _('Code') }}</h1>
|
<h1 class="section__title">{{ _('Code') }}</h1>
|
||||||
<div class="section__tools">
|
<div class="section__tools">
|
||||||
<a class="primary rounded button" href="?download=true"><span class="icon icon-download"></span> {{ _('Download') }}</a>
|
<a class="primary rounded button" href="?download=true">
|
||||||
|
<span class="icon icon-download"></span>
|
||||||
|
{% if rdoc.files.hack %}{{ _('Download Hack Input') }}{% else %}{{ _('Download') }}{% endif %}
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="section__body">
|
<div class="section__body">
|
||||||
@@ -63,6 +66,10 @@
|
|||||||
<dl class="large horizontal">
|
<dl class="large horizontal">
|
||||||
<dt>{{ _('Submit By') }}</dt>
|
<dt>{{ _('Submit By') }}</dt>
|
||||||
<dd>{{ user.render_inline(udoc, modbadge=false) }}</dd>
|
<dd>{{ user.render_inline(udoc, modbadge=false) }}</dd>
|
||||||
|
{% if rdoc.hackTarget %}
|
||||||
|
<dt>{{ _('Hacked') }}</dt>
|
||||||
|
<dd><a href="{{ url('record_detail', rid=rdoc.hackTarget) }}">{{ rdoc.hackTarget }}</a></dd>
|
||||||
|
{% endif %}
|
||||||
{% if pdoc %}
|
{% if pdoc %}
|
||||||
<dt>{{ _('Problem') }}</dt>
|
<dt>{{ _('Problem') }}</dt>
|
||||||
<dd>
|
<dd>
|
||||||
|
|||||||
Reference in new issue
Block a user