Browse Source

Make error message more friendly

master
Menci 8 years ago
parent
commit
7d95cc3007
  1. 2
      models/contest.js
  2. 2
      models/problem.js
  3. 30
      modules/api.js
  4. 16
      modules/contest.js
  5. 26
      modules/discussion.js
  6. 2
      modules/index.js
  7. 105
      modules/problem.js
  8. 6
      modules/problem_tag.js
  9. 6
      modules/submission.js
  10. 20
      modules/user.js
  11. 14
      utility.js
  12. 38
      views/error.ejs
  13. 30
      views/problem.ejs
  14. 16
      views/problems.ejs
  15. 2
      views/sign_up.ejs
  16. 6
      views/user_edit.ejs

2
models/contest.js

@ -112,7 +112,7 @@ class Contest extends Model {
async newSubmission(judge_state) { async newSubmission(judge_state) {
let problems = await this.getProblems(); let problems = await this.getProblems();
if (!problems.includes(judge_state.problem_id)) throw 'No such problem in contest.'; if (!problems.includes(judge_state.problem_id)) throw new ErrorMessage('当前比赛中无此题目。');
let player = await ContestPlayer.findInContest({ let player = await ContestPlayer.findInContest({
contest_id: this.id, contest_id: this.id,

2
models/problem.js

@ -246,7 +246,7 @@ class Problem extends Model {
let buf = await fs.readFileAsync(path); let buf = await fs.readFileAsync(path);
if (buf.length > syzoj.config.limit.data_size) throw 'Testdata too large.' if (buf.length > syzoj.config.limit.data_size) throw new ErrorMessage('测试数据太大。');
let key = syzoj.utils.md5(buf); let key = syzoj.utils.md5(buf);
await fs.moveAsync(path, TestData.resolvePath(key), { overwrite: true }); await fs.moveAsync(path, TestData.resolvePath(key), { overwrite: true });

30
modules/api.js

@ -83,36 +83,6 @@ app.post('/api/markdown', async (req, res) => {
} }
}); });
// Set problem public
async function setPublic(req, res, is_public) {
try {
let id = parseInt(req.params.id);
let problem = await Problem.fromID(id);
if (!problem) throw 'No such problem';
let allowedEdit = await problem.isAllowedEditBy(res.locals.user);
if (!allowedEdit) throw 'Permission denied';
problem.is_public = is_public;
await problem.save();
res.send({});
} catch (e) {
syzoj.log(e);
res.render('error', {
err: e
});
}
}
app.post('/api/problem/:id/public', async (req, res) => {
await setPublic(req, res, true);
});
app.delete('/api/problem/:id/public', async (req, res) => {
await setPublic(req, res, false);
});
// APIs for judge client // APIs for judge client
app.get('/api/waiting_judge', async (req, res) => { app.get('/api/waiting_judge', async (req, res) => {
try { try {

16
modules/contest.js

@ -47,7 +47,7 @@ app.get('/contests', async (req, res) => {
app.get('/contest/:id/edit', async (req, res) => { app.get('/contest/:id/edit', async (req, res) => {
try { try {
if (!res.locals.user || !res.locals.user.is_admin) throw 'Permission denied.'; if (!res.locals.user || !res.locals.user.is_admin) throw new ErrorMessage('您没有权限进行此操作。');
let contest_id = parseInt(req.params.id); let contest_id = parseInt(req.params.id);
let contest = await Contest.fromID(contest_id); let contest = await Contest.fromID(contest_id);
@ -73,7 +73,7 @@ app.get('/contest/:id/edit', async (req, res) => {
app.post('/contest/:id/edit', async (req, res) => { app.post('/contest/:id/edit', async (req, res) => {
try { try {
if (!res.locals.user || !res.locals.user.is_admin) throw 'Permission denied.'; if (!res.locals.user || !res.locals.user.is_admin) throw new ErrorMessage('您没有权限进行此操作。');
let contest_id = parseInt(req.params.id); let contest_id = parseInt(req.params.id);
let contest = await Contest.fromID(contest_id); let contest = await Contest.fromID(contest_id);
@ -110,7 +110,7 @@ app.get('/contest/:id', async (req, res) => {
let contest_id = parseInt(req.params.id); let contest_id = parseInt(req.params.id);
let contest = await Contest.fromID(contest_id); let contest = await Contest.fromID(contest_id);
if (!contest) throw 'No such contest.'; if (!contest) throw new ErrorMessage('无此比赛。');
contest.allowedEdit = await contest.isAllowedEditBy(res.locals.user); contest.allowedEdit = await contest.isAllowedEditBy(res.locals.user);
contest.running = await contest.isRunning(); contest.running = await contest.isRunning();
@ -163,9 +163,9 @@ app.get('/contest/:id/ranklist', async (req, res) => {
try { try {
let contest_id = parseInt(req.params.id); let contest_id = parseInt(req.params.id);
let contest = await Contest.fromID(contest_id); let contest = await Contest.fromID(contest_id);
if (!contest) throw 'No such contest.'; if (!contest) throw new ErrorMessage('无此比赛。');
if (!await contest.isAllowedSeeResultBy(res.locals.user)) throw 'Permission denied'; if (!await contest.isAllowedSeeResultBy(res.locals.user)) throw new ErrorMessage('您没有权限进行此操作。');
await contest.loadRelationships(); await contest.loadRelationships();
@ -207,7 +207,7 @@ app.get('/contest/:id/submissions', async (req, res) => {
let contest_id = parseInt(req.params.id); let contest_id = parseInt(req.params.id);
let contest = await Contest.fromID(contest_id); let contest = await Contest.fromID(contest_id);
if (!contest) throw 'No such contest.'; if (!contest) throw new ErrorMessage('无此比赛。');
contest.ended = await contest.isEnded(); contest.ended = await contest.isEnded();
@ -268,12 +268,12 @@ app.get('/contest/:id/:pid', async (req, res) => {
let contest = await Contest.fromID(contest_id); let contest = await Contest.fromID(contest_id);
contest.ended = await contest.isEnded(); contest.ended = await contest.isEnded();
if (!(await contest.isRunning() || contest.ended)) throw 'The contest has not started.' if (!(await contest.isRunning() || contest.ended)) throw new ErrorMessage('比赛尚未开始或已结束。');
let problems_id = await contest.getProblems(); let problems_id = await contest.getProblems();
let pid = parseInt(req.params.pid); let pid = parseInt(req.params.pid);
if (!pid || pid < 1 || pid > problems_id.length) throw 'No such problem.'; if (!pid || pid < 1 || pid > problems_id.length) throw new ErrorMessage('无此题目。');
let problem_id = problems_id[pid - 1]; let problem_id = problems_id[pid - 1];
let problem = await Problem.fromID(problem_id); let problem = await Problem.fromID(problem_id);

26
modules/discussion.js

@ -46,7 +46,7 @@ app.get('/article/:id', async (req, res) => {
try { try {
let id = parseInt(req.params.id); let id = parseInt(req.params.id);
let article = await Article.fromID(id); let article = await Article.fromID(id);
if (!article) throw 'No such article'; if (!article) throw new ErrorMessage('无此帖子。');
await article.loadRelationships(); await article.loadRelationships();
article.allowedEdit = await article.isAllowedEditBy(res.locals.user); article.allowedEdit = await article.isAllowedEditBy(res.locals.user);
@ -80,7 +80,7 @@ app.get('/article/:id', async (req, res) => {
app.get('/article/:id/edit', async (req, res) => { app.get('/article/:id/edit', async (req, res) => {
try { try {
if (!res.locals.user) throw 'Please login.'; if (!res.locals.user) throw new ErrorMessage('请登录后继续。', { '登录': syzoj.utils.makeUrl(['login'], { 'url': req.originalUrl }) });
let id = parseInt(req.params.id); let id = parseInt(req.params.id);
let article = await Article.fromID(id); let article = await Article.fromID(id);
@ -106,7 +106,7 @@ app.get('/article/:id/edit', async (req, res) => {
app.post('/article/:id/edit', async (req, res) => { app.post('/article/:id/edit', async (req, res) => {
try { try {
if (!res.locals.user) throw 'Please login.'; if (!res.locals.user) throw new ErrorMessage('请登录后继续。', { '登录': syzoj.utils.makeUrl(['login'], { 'url': req.originalUrl }) });
let id = parseInt(req.params.id); let id = parseInt(req.params.id);
let article = await Article.fromID(id); let article = await Article.fromID(id);
@ -117,7 +117,7 @@ app.post('/article/:id/edit', async (req, res) => {
article.user_id = res.locals.user.id; article.user_id = res.locals.user.id;
article.public_time = article.sort_time = time; article.public_time = article.sort_time = time;
} else { } else {
if (!await article.isAllowedEditBy(res.locals.user)) throw 'Permission denied.'; if (!await article.isAllowedEditBy(res.locals.user)) throw new ErrorMessage('您没有权限进行此操作。');
} }
article.title = req.body.title; article.title = req.body.title;
@ -137,15 +137,15 @@ app.post('/article/:id/edit', async (req, res) => {
app.get('/article/:id/delete', async (req, res) => { app.get('/article/:id/delete', async (req, res) => {
try { try {
if (!res.locals.user) throw 'Please login.'; if (!res.locals.user) throw new ErrorMessage('请登录后继续。', { '登录': syzoj.utils.makeUrl(['login'], { 'url': req.originalUrl }) });
let id = parseInt(req.params.id); let id = parseInt(req.params.id);
let article = await Article.fromID(id); let article = await Article.fromID(id);
if (!article) { if (!article) {
throw 'No such article.'; throw new ErrorMessage('无此帖子。');
} else { } else {
if (!await article.isAllowedEditBy(res.locals.user)) throw 'Permission denied.'; if (!await article.isAllowedEditBy(res.locals.user)) throw new ErrorMessage('您没有权限进行此操作。');
} }
await article.destroy(); await article.destroy();
@ -161,15 +161,15 @@ app.get('/article/:id/delete', async (req, res) => {
app.post('/article/:id/comment', async (req, res) => { app.post('/article/:id/comment', async (req, res) => {
try { try {
if (!res.locals.user) throw 'Please login.'; if (!res.locals.user) throw new ErrorMessage('请登录后继续。', { '登录': syzoj.utils.makeUrl(['login'], { 'url': req.originalUrl }) });
let id = parseInt(req.params.id); let id = parseInt(req.params.id);
let article = await Article.fromID(id); let article = await Article.fromID(id);
if (!article) { if (!article) {
throw 'No such article.'; throw new ErrorMessage('无此帖子。');
} else { } else {
if (!await article.isAllowedCommentBy(res.locals.user)) throw 'Permission denied.'; if (!await article.isAllowedCommentBy(res.locals.user)) throw new ErrorMessage('您没有权限进行此操作。');
} }
let comment = await ArticleComment.create({ let comment = await ArticleComment.create({
@ -192,15 +192,15 @@ app.post('/article/:id/comment', async (req, res) => {
app.get('/article/:article_id/comment/:id/delete', async (req, res) => { app.get('/article/:article_id/comment/:id/delete', async (req, res) => {
try { try {
if (!res.locals.user) throw 'Please login.'; if (!res.locals.user) throw new ErrorMessage('请登录后继续。', { '登录': syzoj.utils.makeUrl(['login'], { 'url': req.originalUrl }) });
let id = parseInt(req.params.id); let id = parseInt(req.params.id);
let comment = await ArticleComment.fromID(id); let comment = await ArticleComment.fromID(id);
if (!comment) { if (!comment) {
throw 'No such comment.'; throw new ErrorMessage('无此评论。');
} else { } else {
if (!await comment.isAllowedEditBy(res.locals.user)) throw 'Permission denied.'; if (!await comment.isAllowedEditBy(res.locals.user)) throw new ErrorMessage('您没有权限进行此操作。');
} }
await comment.destroy(); await comment.destroy();

2
modules/index.js

@ -33,7 +33,7 @@ app.get('/', async (req, res) => {
if (notice.type === 'link') return notice; if (notice.type === 'link') return notice;
else if (notice.type === 'article') { else if (notice.type === 'article') {
let article = await Article.fromID(notice.id); let article = await Article.fromID(notice.id);
if (!article) throw `No such article ${notice.id}`; if (!article) throw new ErrorMessage(`无此帖子:${notice.id}`);
return { return {
title: article.title, title: article.title,
url: syzoj.utils.makeUrl(['article', article.id]), url: syzoj.utils.makeUrl(['article', article.id]),

105
modules/problem.js

@ -130,10 +130,10 @@ app.get('/problem/:id', async (req, res) => {
try { try {
let id = parseInt(req.params.id); let id = parseInt(req.params.id);
let problem = await Problem.fromID(id); let problem = await Problem.fromID(id);
if (!problem) throw 'No such problem.'; if (!problem) throw new ErrorMessage('无此题目。');
if (!await problem.isAllowedUseBy(res.locals.user)) { if (!await problem.isAllowedUseBy(res.locals.user)) {
throw 'Permission denied.'; throw new ErrorMessage('您没有权限进行此操作。');
} }
problem.allowedEdit = await problem.isAllowedEditBy(res.locals.user); problem.allowedEdit = await problem.isAllowedEditBy(res.locals.user);
@ -141,7 +141,7 @@ app.get('/problem/:id', async (req, res) => {
if (problem.is_public || problem.allowedEdit) { if (problem.is_public || problem.allowedEdit) {
await syzoj.utils.markdown(problem, [ 'description', 'input_format', 'output_format', 'example', 'limit_and_hint' ]); await syzoj.utils.markdown(problem, [ 'description', 'input_format', 'output_format', 'example', 'limit_and_hint' ]);
} else { } else {
throw 'Permission denied'; throw new ErrorMessage('您没有权限进行此操作。');
} }
let state = await problem.getJudgeState(res.locals.user, false); let state = await problem.getJudgeState(res.locals.user, false);
@ -164,7 +164,7 @@ app.get('/problem/:id/export', async (req, res) => {
try { try {
let id = parseInt(req.params.id); let id = parseInt(req.params.id);
let problem = await Problem.fromID(id); let problem = await Problem.fromID(id);
if (!problem || !problem.is_public) throw 'No such problem.'; if (!problem || !problem.is_public) throw new ErrorMessage('无此题目。');
let obj = { let obj = {
title: problem.title, title: problem.title,
@ -198,14 +198,14 @@ app.get('/problem/:id/edit', async (req, res) => {
let problem = await Problem.fromID(id); let problem = await Problem.fromID(id);
if (!problem) { if (!problem) {
if (!res.locals.user) throw 'Permission denied.'; if (!res.locals.user) throw new ErrorMessage('请登录后继续。', { '登录': syzoj.utils.makeUrl(['login'], { 'url': req.originalUrl }) });
problem = await Problem.create(); problem = await Problem.create();
problem.id = id; problem.id = id;
problem.allowedEdit = true; problem.allowedEdit = true;
problem.tags = []; problem.tags = [];
problem.new = true; problem.new = true;
} else { } else {
if (!await problem.isAllowedUseBy(res.locals.user)) throw 'Permission denied.'; if (!await problem.isAllowedUseBy(res.locals.user)) throw new ErrorMessage('您没有权限进行此操作。');
problem.allowedEdit = await problem.isAllowedEditBy(res.locals.user); problem.allowedEdit = await problem.isAllowedEditBy(res.locals.user);
problem.tags = await problem.getTags(); problem.tags = await problem.getTags();
} }
@ -226,23 +226,25 @@ app.post('/problem/:id/edit', async (req, res) => {
let id = parseInt(req.params.id) || 0; let id = parseInt(req.params.id) || 0;
let problem = await Problem.fromID(id); let problem = await Problem.fromID(id);
if (!problem) { if (!problem) {
if (!res.locals.user) throw new ErrorMessage('请登录后继续。', { '登录': syzoj.utils.makeUrl(['login'], { 'url': req.originalUrl }) });
problem = await Problem.create(); problem = await Problem.create();
let customID = parseInt(req.body.id); let customID = parseInt(req.body.id);
if (customID) { if (customID) {
if (await Problem.fromID(customID)) throw 'The ID has been used.'; if (await Problem.fromID(customID)) throw new ErrorMessage('ID 已被使用。');
problem.id = customID; problem.id = customID;
} else if (id) problem.id = id; } else if (id) problem.id = id;
problem.user_id = res.locals.user.id; problem.user_id = res.locals.user.id;
} else { } else {
if (!await problem.isAllowedUseBy(res.locals.user)) throw 'Permission denied.'; if (!await problem.isAllowedUseBy(res.locals.user)) throw new ErrorMessage('您没有权限进行此操作。');
if (!await problem.isAllowedEditBy(res.locals.user)) throw 'Permission denied.'; if (!await problem.isAllowedEditBy(res.locals.user)) throw new ErrorMessage('您没有权限进行此操作。');
if (res.locals.user.is_admin) { if (res.locals.user.is_admin) {
let customID = parseInt(req.body.id); let customID = parseInt(req.body.id);
if (customID && customID !== id) { if (customID && customID !== id) {
if (await Problem.fromID(customID)) throw 'The ID has been used.'; if (await Problem.fromID(customID)) throw new ErrorMessage('ID 已被使用。');
await problem.changeID(customID); await problem.changeID(customID);
} }
} }
@ -280,14 +282,17 @@ app.get('/problem/:id/import', async (req, res) => {
try { try {
let id = parseInt(req.params.id) || 0; let id = parseInt(req.params.id) || 0;
let problem = await Problem.fromID(id); let problem = await Problem.fromID(id);
if (!problem) { if (!problem) {
if (!res.locals.user) throw new ErrorMessage('请登录后继续。', { '登录': syzoj.utils.makeUrl(['login'], { 'url': req.originalUrl }) });
problem = await Problem.create(); problem = await Problem.create();
problem.id = id; problem.id = id;
problem.new = true; problem.new = true;
problem.user_id = res.locals.user.id; problem.user_id = res.locals.user.id;
} else { } else {
if (!await problem.isAllowedUseBy(res.locals.user)) throw 'Permission denied.'; if (!await problem.isAllowedUseBy(res.locals.user)) throw new ErrorMessage('您没有权限进行此操作。');
if (!await problem.isAllowedEditBy(res.locals.user)) throw 'Permission denied.'; if (!await problem.isAllowedEditBy(res.locals.user)) throw new ErrorMessage('您没有权限进行此操作。');
} }
res.render('problem_import', { res.render('problem_import', {
@ -306,18 +311,20 @@ app.post('/problem/:id/import', async (req, res) => {
let id = parseInt(req.params.id) || 0; let id = parseInt(req.params.id) || 0;
let problem = await Problem.fromID(id); let problem = await Problem.fromID(id);
if (!problem) { if (!problem) {
if (!res.locals.user) throw new ErrorMessage('请登录后继续。', { '登录': syzoj.utils.makeUrl(['login'], { 'url': req.originalUrl }) });
problem = await Problem.create(); problem = await Problem.create();
let customID = parseInt(req.body.id); let customID = parseInt(req.body.id);
if (customID) { if (customID) {
if (await Problem.fromID(customID)) throw 'The ID has been used.'; if (await Problem.fromID(customID)) throw new ErrorMessage('ID 已被使用。');
problem.id = customID; problem.id = customID;
} else if (id) problem.id = id; } else if (id) problem.id = id;
problem.user_id = res.locals.user.id; problem.user_id = res.locals.user.id;
} else { } else {
if (!await problem.isAllowedUseBy(res.locals.user)) throw 'Permission denied.'; if (!await problem.isAllowedUseBy(res.locals.user)) throw new ErrorMessage('您没有权限进行此操作。');
if (!await problem.isAllowedEditBy(res.locals.user)) throw 'Permission denied.'; if (!await problem.isAllowedEditBy(res.locals.user)) throw new ErrorMessage('您没有权限进行此操作。');
} }
let request = require('request-promise'); let request = require('request-promise');
@ -329,7 +336,7 @@ app.post('/problem/:id/import', async (req, res) => {
json: true json: true
}); });
if (!json.success) throw `Failed to load problem: ${json.error}`; if (!json.success) throw new ErrorMessage('题目加载失败。', null, json.error);
problem.title = json.obj.title; problem.title = json.obj.title;
problem.description = json.obj.description; problem.description = json.obj.description;
@ -344,7 +351,7 @@ app.post('/problem/:id/import', async (req, res) => {
problem.file_io_output_name = json.obj.file_io_output_name; problem.file_io_output_name = json.obj.file_io_output_name;
let validateMsg = await problem.validate(); let validateMsg = await problem.validate();
if (validateMsg) throw 'Invalid problem: ' + validateMsg; if (validateMsg) throw new ErrorMessage('无效的题目数据配置。', null, validateMsg);
await problem.save(); await problem.save();
@ -378,8 +385,8 @@ app.get('/problem/:id/data', async (req, res) => {
let id = parseInt(req.params.id); let id = parseInt(req.params.id);
let problem = await Problem.fromID(id); let problem = await Problem.fromID(id);
if (!problem) throw 'No such problem'; if (!problem) throw new ErrorMessage('无此题目。');
if (!await problem.isAllowedEditBy(res.locals.user)) throw 'Permission denied'; if (!await problem.isAllowedEditBy(res.locals.user)) throw new ErrorMessage('您没有权限进行此操作。');
await problem.loadRelationships(); await problem.loadRelationships();
@ -399,8 +406,8 @@ app.post('/problem/:id/data', app.multer.single('testdata'), async (req, res) =>
let id = parseInt(req.params.id); let id = parseInt(req.params.id);
let problem = await Problem.fromID(id); let problem = await Problem.fromID(id);
if (!problem) throw 'No such problem'; if (!problem) throw new ErrorMessage('无此题目。');
if (!await problem.isAllowedEditBy(res.locals.user)) throw 'Permission denied'; if (!await problem.isAllowedEditBy(res.locals.user)) throw new ErrorMessage('您没有权限进行此操作。');
await problem.loadRelationships(); await problem.loadRelationships();
@ -411,7 +418,7 @@ app.post('/problem/:id/data', app.multer.single('testdata'), async (req, res) =>
problem.file_io_output_name = req.body.file_io_output_name; problem.file_io_output_name = req.body.file_io_output_name;
let validateMsg = await problem.validate(); let validateMsg = await problem.validate();
if (validateMsg) throw 'Invalid problem: ' + validateMsg; if (validateMsg) throw new ErrorMessage('无效的题目数据配置。', null, validateMsg);
if (req.file) { if (req.file) {
await problem.updateTestdata(req.file.path); await problem.updateTestdata(req.file.path);
@ -428,14 +435,44 @@ app.post('/problem/:id/data', app.multer.single('testdata'), async (req, res) =>
} }
}); });
// Set problem public
async function setPublic(req, res, is_public) {
try {
let id = parseInt(req.params.id);
let problem = await Problem.fromID(id);
if (!problem) throw new ErrorMessage('无此题目。');
let allowedEdit = await problem.isAllowedEditBy(res.locals.user);
if (!allowedEdit) throw new ErrorMessage('您没有权限进行此操作。');
problem.is_public = is_public;
await problem.save();
res.redirect(syzoj.utils.makeUrl(['problem', id]));
} catch (e) {
syzoj.log(e);
res.render('error', {
err: e
});
}
}
app.get('/problem/:id/public', async (req, res) => {
await setPublic(req, res, true);
});
app.get('/problem/:id/dis_public', async (req, res) => {
await setPublic(req, res, false);
});
app.post('/problem/:id/submit', async (req, res) => { app.post('/problem/:id/submit', async (req, res) => {
try { try {
let id = parseInt(req.params.id); let id = parseInt(req.params.id);
let problem = await Problem.fromID(id); let problem = await Problem.fromID(id);
if (!problem) throw 'No such problem.'; if (!problem) throw new ErrorMessage('无此题目。');
if (!syzoj.config.languages[req.body.language]) throw 'No such language.' if (!syzoj.config.languages[req.body.language]) throw new ErrorMessage('不支持该语言。');
if (!res.locals.user) throw 'Please login.'; if (!res.locals.user) throw new ErrorMessage('请登录后继续。', { '登录': syzoj.utils.makeUrl(['login'], { 'url': req.originalUrl }) });
let judge_state = await JudgeState.create({ let judge_state = await JudgeState.create({
code: req.body.code, code: req.body.code,
@ -447,16 +484,16 @@ app.post('/problem/:id/submit', async (req, res) => {
let contest_id = parseInt(req.query.contest_id); let contest_id = parseInt(req.query.contest_id);
if (contest_id) { if (contest_id) {
let contest = await Contest.fromID(contest_id); let contest = await Contest.fromID(contest_id);
if (!contest) throw 'No such contest.'; if (!contest) throw new ErrorMessage('无此比赛。');
let problems_id = await contest.getProblems(); let problems_id = await contest.getProblems();
if (!problems_id.includes(id)) throw 'No such problem.'; if (!problems_id.includes(id)) throw new ErrorMessage('无此题目。');
judge_state.type = 1; judge_state.type = 1;
judge_state.type_info = contest_id; judge_state.type_info = contest_id;
await judge_state.save(); await judge_state.save();
} else { } else {
if (!await problem.isAllowedUseBy(res.locals.user)) throw 'Permission denied.'; if (!await problem.isAllowedUseBy(res.locals.user)) throw new ErrorMessage('您没有权限进行此操作。');
judge_state.type = problem.is_public ? 0 : 2; judge_state.type = problem.is_public ? 0 : 2;
await judge_state.save(); await judge_state.save();
} }
@ -486,12 +523,12 @@ app.get('/problem/:id/download', async (req, res) => {
let id = parseInt(req.params.id); let id = parseInt(req.params.id);
let problem = await Problem.fromID(id); let problem = await Problem.fromID(id);
if (!problem) throw 'No such problem'; if (!problem) throw new ErrorMessage('无此题目。');
if (!await problem.isAllowedUseBy(res.locals.user)) throw 'Permission denied'; if (!await problem.isAllowedUseBy(res.locals.user)) throw new ErrorMessage('您没有权限进行此操作。');
await problem.loadRelationships(); await problem.loadRelationships();
if (!problem.testdata) throw 'No testdata'; if (!problem.testdata) throw new ErrorMessage('无测试数据。');
res.download(problem.testdata.getPath(), `testdata_${id}.zip`); res.download(problem.testdata.getPath(), `testdata_${id}.zip`);
} catch (e) { } catch (e) {
@ -508,11 +545,11 @@ app.get('/problem/:id/statistics/:type', async (req, res) => {
let id = parseInt(req.params.id); let id = parseInt(req.params.id);
let problem = await Problem.fromID(id); let problem = await Problem.fromID(id);
if (!problem) throw 'No such problem'; if (!problem) throw new ErrorMessage('无此题目。');
if (!await problem.isAllowedUseBy(res.locals.user)) throw 'Permission denied'; if (!await problem.isAllowedUseBy(res.locals.user)) throw new ErrorMessage('您没有权限进行此操作。');
let count = await problem.countStatistics(req.params.type); let count = await problem.countStatistics(req.params.type);
if (count === null) throw 'No such type'; if (count === null) throw new ErrorMessage('无此统计类型。');
let paginate = syzoj.utils.paginate(count, req.query.page, syzoj.config.page.problem_statistics); let paginate = syzoj.utils.paginate(count, req.query.page, syzoj.config.page.problem_statistics);
let statistics = await problem.getStatistics(req.params.type, paginate); let statistics = await problem.getStatistics(req.params.type, paginate);

6
modules/problem_tag.js

@ -23,7 +23,7 @@ let ProblemTag = syzoj.model('problem_tag');
app.get('/problems/tag/:id/edit', async (req, res) => { app.get('/problems/tag/:id/edit', async (req, res) => {
try { try {
if (!res.locals.user && !res.locals.user.is_admin) throw 'Permission denied.'; if (!res.locals.user && !res.locals.user.is_admin) throw new ErrorMessage('您没有权限进行此操作。');
let id = parseInt(req.params.id) || 0; let id = parseInt(req.params.id) || 0;
let tag = await ProblemTag.fromID(id); let tag = await ProblemTag.fromID(id);
@ -46,7 +46,7 @@ app.get('/problems/tag/:id/edit', async (req, res) => {
app.post('/problems/tag/:id/edit', async (req, res) => { app.post('/problems/tag/:id/edit', async (req, res) => {
try { try {
if (!res.locals.user || !res.locals.user.is_admin) throw 'Permission denied.'; if (!res.locals.user || !res.locals.user.is_admin) throw new ErrorMessage('您没有权限进行此操作。');
let id = parseInt(req.params.id) || 0; let id = parseInt(req.params.id) || 0;
let tag = await ProblemTag.fromID(id); let tag = await ProblemTag.fromID(id);
@ -59,7 +59,7 @@ app.post('/problems/tag/:id/edit', async (req, res) => {
req.body.name = req.body.name.trim(); req.body.name = req.body.name.trim();
if (tag.name !== req.body.name) { if (tag.name !== req.body.name) {
if (await ProblemTag.findOne({ where: { name: req.body.name } })) { if (await ProblemTag.findOne({ where: { name: req.body.name } })) {
throw 'There is already a tag with that name.'; throw new ErrorMessage('标签名称已被使用。');
} }
} }

6
modules/submission.js

@ -71,7 +71,7 @@ app.get('/submissions', async (req, res) => {
app.get('/submissions/:id/ajax', async (req, res) => { app.get('/submissions/:id/ajax', async (req, res) => {
try { try {
let judge_state = await JudgeState.fromID(req.params.id); let judge_state = await JudgeState.fromID(req.params.id);
if (!judge_state) throw 'No such judge state'; if (!judge_state) throw new ErrorMessage('无此提交记录。');
await judge_state.loadRelationships(); await judge_state.loadRelationships();
@ -162,12 +162,12 @@ app.get('/submission/:id/rejudge', async (req, res) => {
let id = parseInt(req.params.id); let id = parseInt(req.params.id);
let judge = await JudgeState.fromID(id); let judge = await JudgeState.fromID(id);
if (judge.pending) throw 'Can\'t rejudge a pending submission'; if (judge.pending && !req.query.force) throw new ErrorMessage('无法重新评测一个评测中的提交。');
await judge.loadRelationships(); await judge.loadRelationships();
let allowedRejudge = await judge.problem.isAllowedEditBy(res.locals.user); let allowedRejudge = await judge.problem.isAllowedEditBy(res.locals.user);
if (!allowedRejudge) throw 'Permission denied'; if (!allowedRejudge) throw new ErrorMessage('您没有权限进行此操作。');
await judge.rejudge(); await judge.rejudge();

20
modules/user.js

@ -43,7 +43,7 @@ app.get('/ranklist', async (req, res) => {
app.get('/find_user', async (req, res) => { app.get('/find_user', async (req, res) => {
try { try {
let user = await User.fromName(req.query.nickname); let user = await User.fromName(req.query.nickname);
if (!user) throw `Can't find user ${req.query.nickname}`; if (!user) throw new ErrorMessage('无此用户。');
res.redirect(syzoj.utils.makeUrl(['user', user.id])); res.redirect(syzoj.utils.makeUrl(['user', user.id]));
} catch (e) { } catch (e) {
syzoj.log(e); syzoj.log(e);
@ -57,7 +57,7 @@ app.get('/find_user', async (req, res) => {
app.get('/login', async (req, res) => { app.get('/login', async (req, res) => {
if (res.locals.user) { if (res.locals.user) {
res.render('error', { res.render('error', {
err: 'Please logout first' err: new ErrorMessage('您已经登录了,请先注销。', { '注销': syzoj.utils.makeUrl(['logout'], { 'url': req.originalUrl }) })
}); });
} else { } else {
res.render('login'); res.render('login');
@ -68,7 +68,7 @@ app.get('/login', async (req, res) => {
app.get('/sign_up', async (req, res) => { app.get('/sign_up', async (req, res) => {
if (res.locals.user) { if (res.locals.user) {
res.render('error', { res.render('error', {
err: 'Please logout first' err: new ErrorMessage('您已经登录了,请先注销。', { '注销': syzoj.utils.makeUrl(['logout'], { 'url': req.originalUrl }) })
}); });
} else { } else {
res.render('sign_up'); res.render('sign_up');
@ -109,11 +109,11 @@ app.get('/user/:id/edit', async (req, res) => {
try { try {
let id = parseInt(req.params.id); let id = parseInt(req.params.id);
let user = await User.fromID(id); let user = await User.fromID(id);
if (!user) throw 'No such user.'; if (!user) throw new ErrorMessage('无此用户。');
let allowedEdit = await user.isAllowedEditBy(res.locals.user); let allowedEdit = await user.isAllowedEditBy(res.locals.user);
if (!allowedEdit) { if (!allowedEdit) {
throw 'Permission denied'; throw new ErrorMessage('您没有权限进行此操作。');
} }
res.render('user_edit', { res.render('user_edit', {
@ -135,15 +135,15 @@ app.post('/user/:id/edit', async (req, res) => {
user = await User.fromID(id); user = await User.fromID(id);
let allowedEdit = await user.isAllowedEditBy(res.locals.user); let allowedEdit = await user.isAllowedEditBy(res.locals.user);
if (!allowedEdit) throw 'Permission denied.'; if (!allowedEdit) throw new ErrorMessage('您没有权限进行此操作。');
if (req.body.old_password && req.body.new_password) { if (req.body.old_password && req.body.new_password) {
if (user.password !== req.body.old_password && !res.locals.user.is_admin) throw 'Old password wrong.'; if (user.password !== req.body.old_password && !res.locals.user.is_admin) throw new ErrorMessage('旧密码错误。');
user.password = req.body.new_password; user.password = req.body.new_password;
} }
if (res.locals.user.is_admin) { if (res.locals.user.is_admin) {
if (!syzoj.utils.isValidUsername(req.body.username)) throw 'Invalid username.'; if (!syzoj.utils.isValidUsername(req.body.username)) throw new ErrorMessage('无效的用户名。');
user.username = req.body.username; user.username = req.body.username;
} }
@ -157,12 +157,12 @@ app.post('/user/:id/edit', async (req, res) => {
res.render('user_edit', { res.render('user_edit', {
edited_user: user, edited_user: user,
error_info: 'Success' error_info: ''
}); });
} catch (e) { } catch (e) {
res.render('user_edit', { res.render('user_edit', {
edited_user: user, edited_user: user,
error_info: e error_info: e.message
}); });
} }
}); });

14
utility.js

@ -28,6 +28,14 @@ Array.prototype.filterAsync = async function (fn) {
return this.filter((x, i) => a[i]); return this.filter((x, i) => a[i]);
}; };
global.ErrorMessage = class ErrorMessage {
constructor(message, nextUrls, details) {
this.message = message;
this.nextUrls = nextUrls || {};
this.details = details;
}
};
let path = require('path'); let path = require('path');
let util = require('util'); let util = require('util');
let renderer = require('moemark-renderer'); let renderer = require('moemark-renderer');
@ -210,7 +218,7 @@ module.exports = {
} else { } else {
let lines = zip.readAsText('data_rule.txt').split('\r').join('').split('\n').filter(x => x.length !== 0); let lines = zip.readAsText('data_rule.txt').split('\r').join('').split('\n').filter(x => x.length !== 0);
if (lines.length < 3) throw 'Invalid data_rule.txt'; if (lines.length < 3) throw '无效的数据配置文件(data_rule.txt)。';
let input = lines[lines.length - 2]; let input = lines[lines.length - 2];
let output = lines[lines.length - 1]; let output = lines[lines.length - 1];
@ -234,8 +242,8 @@ module.exports = {
output: output.replace('#', i) output: output.replace('#', i)
}; };
if (!list.includes(testcase.input)) throw `Can't find file ${testcase.input}`; if (!list.includes(testcase.input)) throw `找不到文件 ${testcase.input}`;
if (!list.includes(testcase.output)) throw `Can't find file ${testcase.output}`; if (!list.includes(testcase.output)) throw `找不到文件 ${testcase.output}`;
res[s].cases.push(testcase); res[s].cases.push(testcase);
} }
} }

38
views/error.ejs

@ -1,21 +1,27 @@
<% this.title = '错误' %> <% this.title = '错误' %>
<% include header %> <% include header %>
<style type="text/css">
.down{
margin-top: 150px;
font-size:2em;
}
</style>
<div class="am-container down">
<p><%= err %></p>
</div>
<% if (typeof next !== 'undefined') { %> <%
<script type="text/javascript"> if (!(err instanceof ErrorMessage)) {
$(document).ready(function() { err = new ErrorMessage(err.toString());
setTimeout("window.location.href='<%- next %>'", 2000); }
}); %>
</script> <div class="ui negative icon message">
<% } %> <i class="remove icon"></i>
<div class="content">
<div class="header" style="margin-bottom: 10px; ">
错误:<%= err.message %>
</div>
<% if (err.details) { %>
<p><%= err.details %></p>
<% } %>
<p>
<% for (let text in err.nextUrls) { %>
<a href="<%= err.nextUrls[text] %>" style="margin-right: 5px; "><%= text %></a>
<% } %>
<a href="javascript:history.go(-1)">返回上一页</a>
</p>
</div>
</div>
<% include footer %> <% include footer %>

30
views/problem.ejs

@ -68,9 +68,9 @@ if (contest) {
<% } %> <% } %>
<% if (user && user.is_admin) { %> <% if (user && user.is_admin) { %>
<% if (problem.is_public) { %> <% if (problem.is_public) { %>
<button class="small ui button" id="dis_public">取消公开</button> <a class="small ui button" id="dis_public" href="<%= syzoj.utils.makeUrl(['problem', problem.id, 'dis_public']) %>">取消公开</a>
<% } else { %> <% } else { %>
<button class="small ui button" id="public">公开</button> <a class="small ui button" id="public" href="<%= syzoj.utils.makeUrl(['problem', problem.id, 'public']) %>">公开</a>
<% } %> <% } %>
<% } %> <% } %>
</div> </div>
@ -221,31 +221,5 @@ $(function () {
editor.getSession().setMode("ace/mode/" + $(this).data('mode')); editor.getSession().setMode("ace/mode/" + $(this).data('mode'));
}); });
}); });
<% if (!contest) { %>
function public_problem() {
$.ajax({
url: '<%= syzoj.utils.makeUrl(['api', 'problem', problem.id, 'public']) %>',
type: 'POST',
complete: function () { location.reload(true) },
async: true
});
}
function dis_public_problem() {
$.ajax({
url: '<%= syzoj.utils.makeUrl(['api', 'problem', problem.id, 'public']) %>',
type: 'DELETE',
complete: function () { location.reload(true) },
async: true
});
}
$(document).ready(function(){
$("#public").click(function(){
public_problem();
});
$("#dis_public").click(function(){
dis_public_problem();
});
});
<% } %>
</script> </script>
<% include footer %> <% include footer %>

16
views/problems.ejs

@ -69,16 +69,14 @@ if (typeof tags !== 'undefined') tagIDs = tags.map(x => x.id);
<% } %> <% } %>
<a style="margin-left: 10px; " href="<%= syzoj.utils.makeUrl(['problems', 'tag', 0, 'edit']) %>" class="ui labeled icon mini green button"><i class="plus icon"></i> 添加标签</a> <a style="margin-left: 10px; " href="<%= syzoj.utils.makeUrl(['problems', 'tag', 0, 'edit']) %>" class="ui labeled icon mini green button"><i class="plus icon"></i> 添加标签</a>
<% } %> <% } %>
<% if (user) { %> <div style="margin-left: 10px; " class="ui mini buttons">
<div style="margin-left: 10px; " class="ui mini buttons"> <div class="ui labeled icon mini dropdown button" id="add_problem_dropdown"><i class="plus icon"></i> 添加题目
<div class="ui labeled icon mini dropdown button" id="add_problem_dropdown"><i class="plus icon"></i> 添加题目 <div class="menu">
<div class="menu"> <a class="item" href="<%= syzoj.utils.makeUrl(['problem', 0, 'edit']) %>"><i class="file icon"></i> 新建题目</a>
<a class="item" href="<%= syzoj.utils.makeUrl(['problem', 0, 'edit']) %>"><i class="file icon"></i> 新建题目</a> <a class="item" href="<%= syzoj.utils.makeUrl(['problem', 0, 'import']) %>"><i class="cloud download icon"></i> 导入题目</a>
<a class="item" href="<%= syzoj.utils.makeUrl(['problem', 0, 'import']) %>"><i class="cloud download icon"></i> 导入题目</a>
</div>
</div>
</div> </div>
<% } %> </div>
</div>
</div> </div>
</div> </div>
</div> </div>

2
views/sign_up.ejs

@ -1,7 +1,7 @@
<% this.title = '注册' %> <% this.title = '注册' %>
<% include header %> <% include header %>
<h1>注册</h1>
<div class="padding"> <div class="padding">
<h1>注册</h1>
<div class="ui error message" id="error" data-am-alert hidden> <div class="ui error message" id="error" data-am-alert hidden>
<p id="error_info"></p> <p id="error_info"></p>
</div> </div>

6
views/user_edit.ejs

@ -1,9 +1,9 @@
<% this.title = '修改资料'; %> <% this.title = '修改资料'; %>
<% include header %> <% include header %>
<div class="padding"> <div class="padding">
<div class="ui <% if (error_info == 'Success') { %>success<% } else { %>error<% } %> message" id="error" <% if (!error_info) { %>hidden<% } %>> <div class="ui <% if (error_info === '') { %>success<% } else { %>error<% } %> message" id="error" <% if (error_info === null) { %>hidden<% } %>>
<% if (error_info) { <% if (error_info !== null) {
if (error_info == 'Success') error_info = '修改成功'; if (error_info === '') error_info = '修改成功';
%> %>
<p id="error_info"><%= error_info %></p> <p id="error_info"><%= error_info %></p>
<% } %> <% } %>

Loading…
Cancel
Save