diff --git a/libs/judger.js b/libs/judger.js index a047925..93bec16 100644 --- a/libs/judger.js +++ b/libs/judger.js @@ -66,7 +66,7 @@ async function connect() { waitingForTask = true; - winston.verbose(`Judge client ${socket.id} emitted waitForTask.`); + winston.warn(`Judge client ${socket.id} emitted waitForTask.`); // Poll the judge queue, timeout = 10s. let obj; @@ -80,9 +80,11 @@ async function connect() { return; } + winston.warn(`Judge task ${obj.data.content.taskId} poped from queue.`); + // Re-push to queue if got task but judge client already disconnected. if (socket.disconnected) { - winston.warn(`Judge client ${socket.id} got task but disconnected re-pushing task to queue.`); + winston.warn(`Judge client ${socket.id} got task but disconnected re-pushing task ${obj.data.content.taskId} to queue.`); judgeQueue.push(obj.data, obj.priority); return; } @@ -90,10 +92,10 @@ async function connect() { // Send task to judge client, and wait for ack. const task = obj.data; pendingAckTaskObj = obj; - winston.verbose(`Sending task ${task.content.taskId} to judge client ${socket.id}.`); + winston.warn(`Sending task ${task.content.taskId} to judge client ${socket.id}.`); socket.emit('onTask', msgPack.encode(task), () => { // Acked. - winston.verbose(`Judge client ${socket.id} acked task ${task.content.taskId}.`); + winston.warn(`Judge client ${socket.id} acked task ${task.content.taskId}.`); pendingAckTaskObj = null; waitingForTask = false; }); @@ -232,6 +234,8 @@ module.exports.judge = async function (judge_state, problem, priority) { content: content, extraData: extraData }, priority); + + winston.warn(`Judge task ${content.taskId} enqueued.`); } module.exports.getCachedJudgeState = taskId => judgeStateCache.get(taskId); diff --git a/libs/submissions_process.js b/libs/submissions_process.js index 910f70b..79f4642 100644 --- a/libs/submissions_process.js +++ b/libs/submissions_process.js @@ -66,6 +66,7 @@ const processOverallResult = (source, config) => { score: st.score, cases: st.cases.map(cs => ({ status: cs.status, + errorMessage: cs.errorMessage, result: cs.result && { type: cs.result.type, time: config.showUsage ? cs.result.time : undefined, diff --git a/models/problem.js b/models/problem.js index a7ab9b7..822a1cb 100644 --- a/models/problem.js +++ b/models/problem.js @@ -58,15 +58,15 @@ SELECT \ `id` \ FROM `judge_state` `inner_table` \ WHERE `problem_id` = `outer_table`.`problem_id` AND `user_id` = `outer_table`.`user_id` AND `status` = "Accepted" AND `type` = 0 \ - ORDER BY LENGTH(`code`) ASC \ + ORDER BY `code_length` ASC \ LIMIT 1 \ ) AS `id`, \ ( \ SELECT \ - LENGTH(`code`) \ + `code_length` \ FROM `judge_state` `inner_table` \ WHERE `problem_id` = `outer_table`.`problem_id` AND `user_id` = `outer_table`.`user_id` AND `status` = "Accepted" AND `type` = 0 \ - ORDER BY LENGTH(`code`) ASC \ + ORDER BY `code_length` ASC \ LIMIT 1 \ ) AS `code_length` \ FROM `judge_state` `outer_table` \ @@ -83,15 +83,15 @@ SELECT \ `id` \ FROM `judge_state` `inner_table` \ WHERE `problem_id` = `outer_table`.`problem_id` AND `user_id` = `outer_table`.`user_id` AND `status` = "Accepted" AND `type` = 0 \ - ORDER BY LENGTH(`code`) DESC \ + ORDER BY `code_length` DESC \ LIMIT 1 \ ) AS `id`, \ ( \ SELECT \ - LENGTH(`code`) \ + `code_length` \ FROM `judge_state` `inner_table` \ WHERE `problem_id` = `outer_table`.`problem_id` AND `user_id` = `outer_table`.`user_id` AND `status` = "Accepted" AND `type` = 0 \ - ORDER BY LENGTH(`code`) DESC \ + ORDER BY `code_length` DESC \ LIMIT 1 \ ) AS `code_length` \ FROM `judge_state` `outer_table` \ diff --git a/modules/problem.js b/modules/problem.js index 84df7e2..d93cec2 100644 --- a/modules/problem.js +++ b/modules/problem.js @@ -257,6 +257,7 @@ app.get('/problem/:id/export', async (req, res) => { limit_and_hint: problem.limit_and_hint, time_limit: problem.time_limit, memory_limit: problem.memory_limit, + have_additional_file: problem.additional_file_id != null, file_io: problem.file_io, file_io_input_name: problem.file_io_input_name, file_io_output_name: problem.file_io_output_name, @@ -465,6 +466,11 @@ app.post('/problem/:id/import', async (req, res) => { let data = await download(req.body.url + (req.body.url.endsWith('/') ? 'testdata/download' : '/testdata/download')); await fs.writeFileAsync(tmpFile.path, data); await problem.updateTestdata(tmpFile.path, await res.locals.user.hasPrivilege('manage_problem')); + if (json.obj.have_additional_file) { + let additional_file = await download(req.body.url + (req.body.url.endsWith('/') ? 'download/additional_file' : '/download/additional_file')); + await fs.writeFileAsync(tmpFile.path, additional_file); + await problem.updateFile(tmpFile.path, 'additional_file', await res.locals.user.hasPrivilege('manage_problem')); + } } catch (e) { syzoj.log(e); } diff --git a/modules/socketio.js b/modules/socketio.js index 7acc982..420441e 100644 --- a/modules/socketio.js +++ b/modules/socketio.js @@ -14,6 +14,7 @@ const finishedJudgeList = {}; const compiledList = []; const clientDetailProgressList = {}; const clientDisplayConfigList = {}; +const debug = false; function processOverallResult(source, config) { if (source == null) @@ -75,25 +76,25 @@ function forAllClients(ns, taskId, exec) { }); } else { - winston.warn(`Error while listing socketio clients in ${taskId}`, err); + if (debug) winston.warn(`Error while listing socketio clients in ${taskId}`, err); } }); } function initializeSocketIO(s) { ioInstance = socketio(s); const initializeNamespace = (name, exec) => { - winston.debug('initializing socketIO', name); + if (debug) winston.debug('initializing socketIO', name); const newNamespace = ioInstance.of('/' + name); newNamespace.on('connection', (socket) => { socket.on('disconnect', () => { - winston.info(`Client ${socket.id} disconnected.`); + if (debug) winston.info(`Client ${socket.id} disconnected.`); delete clientDisplayConfigList[socket.id]; if (clientDetailProgressList[socket.id]) { delete clientDetailProgressList[socket.id]; } }); socket.on('join', (reqJwt, cb) => { - winston.info(`Client ${socket.id} connected.`); + if (debug) winston.info(`Client ${socket.id} connected.`); let req; try { req = jwt.verify(reqJwt, syzoj.config.session_secret); @@ -102,12 +103,12 @@ function initializeSocketIO(s) { } clientDisplayConfigList[socket.id] = req.displayConfig; const taskId = req.taskId; - winston.verbose(`A client trying to join ${name} namespace for ${taskId}.`); + if (debug) winston.verbose(`A client trying to join ${name} namespace for ${taskId}.`); socket.join(taskId.toString()); exec(req, socket).then(x => cb(x), err => cb({ ok: false, message: err.toString() })); } catch (err) { - winston.info('Error while joining.'); + if (debug) winston.info('Error while joining.'); cb({ ok: false, message: err.toString() @@ -121,7 +122,7 @@ function initializeSocketIO(s) { detailProgressNamespace = initializeNamespace('detail', async (req, socket) => { const taskId = req.taskId; if (finishedJudgeList[taskId]) { - winston.debug(`Judge task #${taskId} has been finished, ${JSON.stringify(currentJudgeList[taskId])}`); + if (debug) winston.debug(`Judge task #${taskId} has been finished, ${JSON.stringify(currentJudgeList[taskId])}`); return { ok: true, running: false, @@ -131,7 +132,7 @@ function initializeSocketIO(s) { }; } else { - winston.debug(`Judge task #${taskId} has not been finished`); + if (debug) winston.debug(`Judge task #${taskId} has not been finished`); if (currentJudgeList[taskId]) { clientDetailProgressList[socket.id] = { version: 0, @@ -208,7 +209,7 @@ function initializeSocketIO(s) { } exports.initializeSocketIO = initializeSocketIO; function createTask(taskId) { - winston.debug(`Judge task #${taskId} has started`); + if (debug) winston.debug(`Judge task #${taskId} has started`); currentJudgeList[taskId] = {}; finishedJudgeList[taskId] = null; forAllClients(detailProgressNamespace, taskId, (clientId) => { @@ -223,7 +224,7 @@ function createTask(taskId) { } exports.createTask = createTask; function updateCompileStatus(taskId, result) { - winston.debug(`Updating compilation status for #${taskId}`); + if (debug) winston.debug(`Updating compilation status for #${taskId}`); compiledList[taskId] = { result: result.status === interfaces.TaskStatus.Done ? 'Submitted' : 'Compile Error' }; compileProgressNamespace.to(taskId.toString()).emit('finish', { taskId: taskId, @@ -232,7 +233,7 @@ function updateCompileStatus(taskId, result) { } exports.updateCompileStatus = updateCompileStatus; function updateProgress(taskId, data) { - winston.verbose(`Updating progress for #${taskId}`); + if (debug) winston.verbose(`Updating progress for #${taskId}`); currentJudgeList[taskId] = data; const finalResult = judgeResult.convertResult(taskId, data); const roughResult = { @@ -243,7 +244,7 @@ function updateProgress(taskId, data) { }; forAllClients(detailProgressNamespace, taskId, (client) => { try { - winston.debug(`Pushing progress update to ${client}`); + if (debug) winston.debug(`Pushing progress update to ${client}`); if (clientDetailProgressList[client] && clientDisplayConfigList[client]) { const original = clientDetailProgressList[client].content; const updated = processOverallResult(currentJudgeList[taskId], clientDisplayConfigList[client]); @@ -283,7 +284,7 @@ function updateResult(taskId, data) { }; finishedJudgeList[taskId] = roughResult; forAllClients(roughProgressNamespace, taskId, (client) => { - winston.debug(`Pushing rough result to ${client}`); + if (debug) winston.debug(`Pushing rough result to ${client}`); roughProgressNamespace.sockets[client].emit('finish', { taskId: taskId, result: processRoughResult(finishedJudgeList[taskId], clientDisplayConfigList[client]) @@ -291,7 +292,7 @@ function updateResult(taskId, data) { }); forAllClients(detailProgressNamespace, taskId, (client) => { if (clientDisplayConfigList[client]) { - winston.debug(`Pushing detail result to ${client}`); + if (debug) winston.debug(`Pushing detail result to ${client}`); detailProgressNamespace.sockets[client].emit('finish', { taskId: taskId, result: processOverallResult(currentJudgeList[taskId], clientDisplayConfigList[client]), diff --git a/views/contest.ejs b/views/contest.ejs index 8ee23a5..2de9aa9 100644 --- a/views/contest.ejs +++ b/views/contest.ejs @@ -75,8 +75,10 @@ <% if (typeof problem.status === 'string') { %> + <%= problem.feedback || problem.status %> + <% } else if (typeof problem.status === 'object') { %> <% if (problem.status.accepted) { %> diff --git a/views/problem.ejs b/views/problem.ejs index ceb3df4..e2332dc 100644 --- a/views/problem.ejs +++ b/views/problem.ejs @@ -41,8 +41,8 @@ div[class*=ace_br] { <% if (problem.type === 'interaction') { %> 题目类型:交互 <% } else if (problem.file_io) { %> - 输入文件: <%= problem.file_io_input_name %> - 输出文件: <%= problem.file_io_output_name %> + 输入文件:<%= problem.file_io_input_name %> + 输出文件:<%= problem.file_io_output_name %> <% } else { %> 标准输入输出 <% } %> diff --git a/views/statistics.ejs b/views/statistics.ejs index 05d2481..8166f12 100644 --- a/views/statistics.ejs +++ b/views/statistics.ejs @@ -71,19 +71,21 @@ function getColorOfScore(score) { <% for (let judge of statistics.judge_state) { %> <% include util %> - #<%= judge.id %> - #<%= judge.problem_id %>. <%= judge.problem.title %> + #<%= judge.id %> + #<%= judge.problem_id %>. <%= judge.problem.title %> + <%= judge.status %> + <%= judge.score %> <% if (problem.type !== 'submit-answer') { %> <%= judge.total_time %> ms <%= parseInt(judge.max_memory) || 0 %> K - <%= syzoj.languages[judge.language].show %> / <%= syzoj.utils.formatSize(judge.code.length) %> + <%= syzoj.languages[judge.language].show %> / <%= syzoj.utils.formatSize(judge.code.length) %> <% } else { %> <%= syzoj.utils.formatSize(judge.max_memory) %> <% } %> diff --git a/views/submission.ejs b/views/submission.ejs index 23a6a4f..7fdffc2 100644 --- a/views/submission.ejs +++ b/views/submission.ejs @@ -85,7 +85,7 @@