Browse Source

Finish.

pull/6/head
t123yh 7 years ago
parent
commit
72747e50e1
  1. 2
      libs/judger.js
  2. 2
      libs/submissions_process.js
  3. 18
      models/judge_state.js
  4. 12
      modules/api_v2.js
  5. 4
      modules/contest.js
  6. 3
      modules/problem.js
  7. 4
      modules/submission.js
  8. 13
      package-lock.json
  9. 1
      package.json
  10. 12
      views/submission.ejs
  11. 2
      views/submissions.ejs
  12. 4
      views/submissions_item.ejs

2
libs/judger.js

@ -31,7 +31,7 @@ module.exports.judge = async function (judge_state, problem, priority) {
const req = { const req = {
content: { content: {
taskId: judge_state.id, taskId: judge_state.task_id,
testData: problem.id.toString(), testData: problem.id.toString(),
type: type, type: type,
priority: priority, priority: priority,

2
libs/submissions_process.js

@ -5,7 +5,7 @@ const getSubmissionInfo = (s, displayConfig) => ({
problemName: s.problem.title, problemName: s.problem.title,
problemId: s.problem_id, problemId: s.problem_id,
language: displayConfig.showCode ? ((s.language != null && s.language !== '') ? syzoj.config.languages[s.language].show : null) : null, language: displayConfig.showCode ? ((s.language != null && s.language !== '') ? syzoj.config.languages[s.language].show : null) : null,
codeSize: displayConfig.showCode ? syzoj.utils.formatSize(s.code.length) : null, codeSize: displayConfig.showCode ? syzoj.utils.formatSize(s.code_length) : null,
submitTime: syzoj.utils.formatDate(s.submit_time), submitTime: syzoj.utils.formatDate(s.submit_time),
}); });

18
models/judge_state.js

@ -20,6 +20,7 @@
'use strict'; 'use strict';
let Sequelize = require('sequelize'); let Sequelize = require('sequelize');
const randomstring = require('randomstring');
let db = syzoj.db; let db = syzoj.db;
let User = syzoj.model('user'); let User = syzoj.model('user');
@ -36,8 +37,10 @@ let model = db.define('judge_state', {
language: { type: Sequelize.STRING(20) }, language: { type: Sequelize.STRING(20) },
status: { type: Sequelize.STRING(50) }, status: { type: Sequelize.STRING(50) },
task_id: { type: Sequelize.STRING(50) },
score: { type: Sequelize.INTEGER }, score: { type: Sequelize.INTEGER },
total_time: { type: Sequelize.INTEGER }, total_time: { type: Sequelize.INTEGER },
code_length: { type: Sequelize.INTEGER },
pending: { type: Sequelize.BOOLEAN }, pending: { type: Sequelize.BOOLEAN },
max_memory: { type: Sequelize.INTEGER }, max_memory: { type: Sequelize.INTEGER },
@ -82,6 +85,7 @@ class JudgeState extends Model {
static async create(val) { static async create(val) {
return JudgeState.fromRecord(JudgeState.model.build(Object.assign({ return JudgeState.fromRecord(JudgeState.model.build(Object.assign({
code: '', code: '',
code_length: 0,
language: null, language: null,
user_id: 0, user_id: 0,
problem_id: 0, problem_id: 0,
@ -96,7 +100,8 @@ class JudgeState extends Model {
total_time: null, total_time: null,
max_memory: null, max_memory: null,
status: 'Waiting', status: 'Waiting',
result: null result: null,
task_id: randomstring.generate(10)
}, val))); }, val)));
} }
@ -156,14 +161,15 @@ class JudgeState extends Model {
let oldStatus = this.status; let oldStatus = this.status;
this.status = 'Waiting'; this.status = 'Waiting';
this.score = 0; this.score = null;
if (this.language) { if (this.language) {
// language is empty if it's a submit-answer problem // language is empty if it's a submit-answer problem
this.total_time = 0; this.total_time = null;
this.max_memory = 0; this.max_memory = null;
} }
this.pending = true; this.pending = true;
this.result = {}; this.result = {};
this.task_id = randomstring.generate(10);
await this.save(); await this.save();
/* /*
@ -192,7 +198,11 @@ class JudgeState extends Model {
await contest.newSubmission(this); await contest.newSubmission(this);
} }
try {
await Judger.judge(this, this.problem, 1); await Judger.judge(this, this.problem, 1);
} catch (err) {
throw new ErrorMessage("无法开始评测。");
}
}); });
} }

12
modules/api_v2.js

@ -87,7 +87,11 @@ app.apiRouter.post('/api/v2/judge/compiled', async (req, res) => {
let data = req.body; let data = req.body;
let JudgeState = syzoj.model('judge_state'); let JudgeState = syzoj.model('judge_state');
let judge_state = await JudgeState.fromID(req.body.taskId); let judge_state = await JudgeState.findOne({ where: { task_id: req.body.taskId } });
if (!judge_state) {
res.send({ return: 1 }); // The task might have been rejudging.
return;
}
judge_state.compilation = req.body.result; judge_state.compilation = req.body.result;
await judge_state.save(); await judge_state.save();
@ -104,7 +108,11 @@ app.apiRouter.post('/api/v2/judge/finished', async (req, res) => {
let data = req.body; let data = req.body;
let JudgeState = syzoj.model('judge_state'); let JudgeState = syzoj.model('judge_state');
let judge_state = await JudgeState.fromID(req.body.taskId); let judge_state = await JudgeState.findOne({ where: { task_id: req.body.taskId } });
if (!judge_state) {
res.send({ return: 1 }); // The task might have been rejudging.
return;
}
// await judge_state.updateResult(JSON.parse(req.body)); // await judge_state.updateResult(JSON.parse(req.body));
judge_state.score = data.score; judge_state.score = data.score;
judge_state.pending = false; judge_state.pending = false;

4
modules/contest.js

@ -349,7 +349,7 @@ app.get('/contest/:id/submissions', async (req, res) => {
items: judge_state.map(x => ({ items: judge_state.map(x => ({
info: getSubmissionInfo(x, displayConfig), info: getSubmissionInfo(x, displayConfig),
token: (getRoughResult(x, displayConfig) == null) ? jwt.sign({ token: (getRoughResult(x, displayConfig) == null) ? jwt.sign({
taskId: x.id, taskId: x.task_id,
type: pushType, type: pushType,
displayConfig: displayConfig displayConfig: displayConfig
}, syzoj.config.judge_token) : null, }, syzoj.config.judge_token) : null,
@ -404,7 +404,7 @@ app.get('/contest/submission/:id', async (req, res) => {
code: (displayConfig.showCode && judge.problem.type !== 'submit-answer') ? judge.code.toString("utf8") : '', code: (displayConfig.showCode && judge.problem.type !== 'submit-answer') ? judge.code.toString("utf8") : '',
detailResult: processOverallResult(judge.result, displayConfig), detailResult: processOverallResult(judge.result, displayConfig),
socketToken: (displayConfig.showDetailResult && judge.pending) ? jwt.sign({ socketToken: (displayConfig.showDetailResult && judge.pending) ? jwt.sign({
taskId: judge.id, taskId: judge.task_id,
displayConfig: displayConfig, displayConfig: displayConfig,
type: 'detail' type: 'detail'
}, syzoj.config.judge_token) : null, }, syzoj.config.judge_token) : null,

3
modules/problem.js

@ -594,7 +594,7 @@ app.post('/problem/:id/submit', app.multer.fields([{ name: 'answer', maxCount: 1
if (!file.md5) throw new ErrorMessage('上传答案文件失败。'); if (!file.md5) throw new ErrorMessage('上传答案文件失败。');
judge_state = await JudgeState.create({ judge_state = await JudgeState.create({
code: file.md5, code: file.md5,
max_memory: size, code_length: size,
language: null, language: null,
user_id: res.locals.user.id, user_id: res.locals.user.id,
problem_id: req.params.id problem_id: req.params.id
@ -612,6 +612,7 @@ app.post('/problem/:id/submit', app.multer.fields([{ name: 'answer', maxCount: 1
judge_state = await JudgeState.create({ judge_state = await JudgeState.create({
code: code, code: code,
code_length: code.length,
language: req.body.language, language: req.body.language,
user_id: res.locals.user.id, user_id: res.locals.user.id,
problem_id: req.params.id problem_id: req.params.id

4
modules/submission.js

@ -110,7 +110,7 @@ app.get('/submissions', async (req, res) => {
items: judge_state.map(x => ({ items: judge_state.map(x => ({
info: getSubmissionInfo(x, displayConfig), info: getSubmissionInfo(x, displayConfig),
token: (getRoughResult(x, displayConfig) == null) ? jwt.sign({ token: (getRoughResult(x, displayConfig) == null) ? jwt.sign({
taskId: x.id, taskId: x.task_id,
type: 'rough', type: 'rough',
displayConfig: displayConfig displayConfig: displayConfig
}, syzoj.config.judge_token) : null, }, syzoj.config.judge_token) : null,
@ -161,7 +161,7 @@ app.get('/submission/:id', async (req, res) => {
code: (judge.problem.type !== 'submit-answer') ? judge.code.toString("utf8") : '', code: (judge.problem.type !== 'submit-answer') ? judge.code.toString("utf8") : '',
detailResult: processOverallResult(judge.result, displayConfig), detailResult: processOverallResult(judge.result, displayConfig),
socketToken: judge.pending ? jwt.sign({ socketToken: judge.pending ? jwt.sign({
taskId: judge.id, taskId: judge.task_id,
type: 'detail', type: 'detail',
displayConfig: displayConfig displayConfig: displayConfig
}, syzoj.config.judge_token) : null, }, syzoj.config.judge_token) : null,

13
package-lock.json generated

@ -105,6 +105,11 @@
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
"integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
}, },
"array-uniq": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.2.tgz",
"integrity": "sha1-X8w3OSB3VyPP1k1lxkvvU7+eum0="
},
"asn1": { "asn1": {
"version": "0.2.3", "version": "0.2.3",
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz",
@ -2196,6 +2201,14 @@
"resolved": "https://registry.npmjs.org/random-js/-/random-js-1.0.8.tgz", "resolved": "https://registry.npmjs.org/random-js/-/random-js-1.0.8.tgz",
"integrity": "sha1-lo/WiabyXWwKrHZig94vaIycGQo=" "integrity": "sha1-lo/WiabyXWwKrHZig94vaIycGQo="
}, },
"randomstring": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/randomstring/-/randomstring-1.1.5.tgz",
"integrity": "sha1-bfBij3XL1ZMpMNn+OrTpVqGFGMM=",
"requires": {
"array-uniq": "1.0.2"
}
},
"range-parser": { "range-parser": {
"version": "1.2.0", "version": "1.2.0",
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz",

1
package.json

@ -46,6 +46,7 @@
"mysql": "^2.11.1", "mysql": "^2.11.1",
"node-7z": "^0.4.0", "node-7z": "^0.4.0",
"pygmentize-bundled-cached": "^1.1.0", "pygmentize-bundled-cached": "^1.1.0",
"randomstring": "^1.1.5",
"request": "^2.74.0", "request": "^2.74.0",
"request-promise": "^4.1.1", "request-promise": "^4.1.1",
"sendmail": "^1.1.1", "sendmail": "^1.1.1",

12
views/submission.ejs

@ -20,7 +20,7 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr is="submission-item" v-bind:data="roughData" :config="displayConfig" :showRejudge="showRejudge"></tr> <tr is="submission-item" v-bind:data="roughData" :config="displayConfig" :show-rejudge="showRejudge"></tr>
</tbody> </tbody>
</table> </table>
@ -39,7 +39,7 @@
<div class="four wide column"> <div class="four wide column">
<status-label :status="getSubtaskResult(subtask)"></status-label> <status-label :status="getSubtaskResult(subtask)"></status-label>
</div> </div>
<div class="three wide column">得分 <div class="three wide column" v-if="subtask.score != null">得分
<span style="font-weight: normal; ">{{ Math.trunc(subtask.score) }}</span> <span style="font-weight: normal; ">{{ Math.trunc(subtask.score) }}</span>
</div> </div>
</div> </div>
@ -221,13 +221,13 @@ if (token != null) {
socket.on('connect', () => { socket.on('connect', () => {
socket.on('start', () => { socket.on('start', () => {
vueApp.roughData.running = true; vueApp.roughData.running = true;
console.log("Judge start!");
vueApp.detailResult = {}; vueApp.detailResult = {};
}); });
socket.on('update', (p) => { socket.on('update', (p) => {
console.log("Delta: " + JSON.stringify(p)); console.log("Delta: " + JSON.stringify(p));
if (p.from === currentVersion) { if (p.from === currentVersion) {
currentVersion = p.to; currentVersion = p.to;
console.log("Before patching: " + JSON.stringify(vueApp));
jsondiffpatch.patch(vueApp.detailResult, p.delta); jsondiffpatch.patch(vueApp.detailResult, p.delta);
} else { // Some packets are dropped. Let's reset. } else { // Some packets are dropped. Let's reset.
socket.close(); socket.close();
@ -235,13 +235,14 @@ if (token != null) {
} }
}); });
socket.on('finish', (p) => { socket.on('finish', (p) => {
console.log("Finish: " + JSON.stringify(p)); console.log("Judge finished");
vueApp.roughData.running = false; vueApp.roughData.running = false;
vueApp.roughData.result = p.roughResult; vueApp.roughData.result = p.roughResult;
vueApp.detailResult = p.result; vueApp.detailResult = p.result;
socket.close(); socket.close();
}); });
socket.emit('join', token, (data) => { socket.emit('join', token, (data) => {
console.log("join! " + JSON.stringify(data));
if (data && data.ok) { if (data && data.ok) {
if (data.finished) { if (data.finished) {
vueApp.roughData.result = data.roughResult; vueApp.roughData.result = data.roughResult;
@ -252,7 +253,8 @@ if (token != null) {
} else { } else {
if (data.running) { if (data.running) {
vueApp.roughData.running = true; vueApp.roughData.running = true;
vueApp.detailResult = data.current; vueApp.detailResult = data.current.content;
currentVersion = data.current.version;
} }
} }
} else { } else {

2
views/submissions.ejs

@ -95,7 +95,7 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr v-for="item in items" :config="displayConfig" :showRejudge="false" :data="item" is='submission-item'> <tr v-for="item in items" :config="displayConfig" :show-rejudge="false" :data="item" is='submission-item'>
</tr> </tr>
</tbody> </tbody>
</table> </table>

4
views/submissions_item.ejs

@ -67,8 +67,8 @@ Vue.component('submission-item', {
<td>{{ data.info.submitTime }}</td> <td>{{ data.info.submitTime }}</td>
<td v-if="showRejudge"> <td v-if="showRejudge">
<form class="have-csrf" :action="submissionLink + '/rejudge'" method="POST"> <form class="have-csrf" :action="submissionLink + '/rejudge'" method="POST">
<input type="hideen" name="_csrf" value="<%= req.csrfToken() %>" /> <input type="hidden" name="_csrf" value="<%= req.csrfToken() %>" />
<input type="submit" value="rejudge"><i class="repeat icon"></i></input> <button type="submit" style="color: #000; padding: 0; border: none; background: none;" value="rejudge"><i class="repeat icon"></i></button>
</form> </form>
</td> </td>
</tr> </tr>

Loading…
Cancel
Save