Browse Source

Seperate full data zip directory.

master
t123yh 7 years ago
parent
commit
ff2de2c895
  1. 58
      models/problem.js
  2. 4
      modules/problem.js
  3. 24
      package-lock.json
  4. 2
      package.json

58
models/problem.js

@ -202,6 +202,8 @@ let db = syzoj.db;
let User = syzoj.model('user');
let File = syzoj.model('file');
const fs = require('fs-extra');
const path = require('path');
let model = db.define('problem', {
id: { type: Sequelize.INTEGER, primaryKey: true, autoIncrement: true },
@ -318,6 +320,10 @@ class Problem extends Model {
return syzoj.utils.resolvePath(syzoj.config.upload_dir, 'testdata', this.id.toString());
}
getTestdataArchivePath() {
return syzoj.utils.resolvePath(syzoj.config.upload_dir, 'testdata-archive', this.id.toString() + '.zip');
}
async updateTestdata(path, noLimit) {
await syzoj.utils.lock(['Problem::Testdata', this.id], async () => {
let p7zip = new (require('node-7z'));
@ -331,20 +337,18 @@ class Problem extends Model {
if (!noLimit && unzipSize > syzoj.config.limit.testdata) throw new ErrorMessage('数据包太大。');
let dir = this.getTestdataPath();
let fs = Promise.promisifyAll(require('fs-extra'));
await fs.removeAsync(dir);
await fs.ensureDirAsync(dir);
await fs.remove(dir);
await fs.ensureDir(dir);
await p7zip.extract(path, dir);
await fs.moveAsync(path, dir + '.zip', { overwrite: true });
await fs.move(path, this.getTestdataArchivePath(), { overwrite: true });
});
}
async uploadTestdataSingleFile(filename, filepath, size, noLimit) {
await syzoj.utils.lock(['Promise::Testdata', this.id], async () => {
let dir = this.getTestdataPath();
let fs = Promise.promisifyAll(require('fs-extra')), path = require('path');
await fs.ensureDirAsync(dir);
await fs.ensureDir(dir);
let oldSize = 0, list = await this.listTestdata(), replace = false, oldCount = 0;
if (list) {
@ -358,39 +362,36 @@ class Problem extends Model {
if (!noLimit && oldSize + size > syzoj.config.limit.testdata) throw new ErrorMessage('数据包太大。');
if (!noLimit && oldCount + !replace > syzoj.config.limit.testdata_filecount) throw new ErrorMessage('数据包中的文件太多。');
await fs.moveAsync(filepath, path.join(dir, filename), { overwrite: true });
await fs.removeAsync(dir + '.zip');
await fs.move(filepath, path.join(dir, filename), { overwrite: true });
await fs.remove(this.getTestdataArchivePath());
});
}
async deleteTestdataSingleFile(filename) {
await syzoj.utils.lock(['Promise::Testdata', this.id], async () => {
let dir = this.getTestdataPath();
let fs = Promise.promisifyAll(require('fs-extra')), path = require('path');
await fs.removeAsync(path.join(dir, filename));
await fs.removeAsync(dir + '.zip');
await fs.remove(path.join(this.getTestdataPath(), filename));
await fs.remove(this.getTestdataArchivePath());
});
}
async makeTestdataZip() {
await syzoj.utils.lock(['Promise::Testdata', this.id], async () => {
let dir = this.getTestdataPath();
if (await syzoj.utils.isFile(dir + '.zip')) return;
if (!await syzoj.utils.isDir(dir)) throw new ErrorMessage('无测试数据。');
let p7zip = new (require('node-7z'));
let list = await this.listTestdata(), path = require('path'), pathlist = list.files.map(file => path.join(dir, file.filename));
let list = await this.listTestdata(), pathlist = list.files.map(file => path.join(dir, file.filename));
if (!pathlist.length) throw new ErrorMessage('无测试数据。');
await p7zip.add(dir + '.zip', pathlist);
await fs.ensureDir(path.resolve(this.getTestdataArchivePath(), '..'));
await p7zip.add(this.getTestdataArchivePath(), pathlist);
});
}
async hasSpecialJudge() {
try {
let fs = Promise.promisifyAll(require('fs-extra'));
let dir = this.getTestdataPath();
let list = await fs.readdirAsync(dir);
let list = await fs.readdir(dir);
return list.includes('spj.js') || list.find(x => x.startsWith('spj_')) !== undefined;
} catch (e) {
return false;
@ -399,11 +400,10 @@ class Problem extends Model {
async listTestdata() {
try {
let fs = Promise.promisifyAll(require('fs-extra')), path = require('path');
let dir = this.getTestdataPath();
let list = await fs.readdirAsync(dir);
let list = await fs.readdir(dir);
list = await list.mapAsync(async x => {
let stat = await fs.statAsync(path.join(dir, x));
let stat = await fs.stat(path.join(dir, x));
if (!stat.isFile()) return undefined;
return {
filename: x,
@ -419,7 +419,7 @@ class Problem extends Model {
};
try {
let stat = await fs.statAsync(this.getTestdataPath() + '.zip');
let stat = await fs.stat(this.getTestdataArchivePath());
if (stat.isFile()) {
res.zip = {
size: stat.size
@ -629,29 +629,27 @@ class Problem extends Model {
}
}
let oldTestdataDir = this.getTestdataPath(), oldTestdataZip = oldTestdataDir + '.zip';
let oldTestdataDir = this.getTestdataPath(), oldTestdataZip = this.getTestdataArchivePath();
this.id = id;
// Move testdata
let newTestdataDir = this.getTestdataPath(), newTestdataZip = newTestdataDir + '.zip';
let fs = Promise.promisifyAll(require('fs-extra'));
let newTestdataDir = this.getTestdataPath(), newTestdataZip = this.getTestdataArchivePath();
if (await syzoj.utils.isDir(oldTestdataDir)) {
await fs.moveAsync(oldTestdataDir, newTestdataDir);
await fs.move(oldTestdataDir, newTestdataDir);
}
if (await syzoj.utils.isFile(oldTestdataZip)) {
await fs.moveAsync(oldTestdataZip, newTestdataZip);
await fs.move(oldTestdataZip, newTestdataZip);
}
await this.save();
}
async delete() {
let fs = Promise.promisifyAll(require('fs-extra'));
let oldTestdataDir = this.getTestdataPath(), oldTestdataZip = oldTestdataDir + '.zip';
await fs.removeAsync(oldTestdataDir);
await fs.removeAsync(oldTestdataZip);
let oldTestdataDir = this.getTestdataPath(), oldTestdataZip = this.getTestdataPath();
await fs.remove(oldTestdataDir);
await fs.remove(oldTestdataZip);
let JudgeState = syzoj.model('judge_state');
let submissions = await JudgeState.query(null, { problem_id: this.id }), submitCnt = {}, acUsers = new Set();

4
modules/problem.js

@ -757,13 +757,13 @@ app.get('/problem/:id/testdata/download/:filename?', async (req, res) => {
if (!await problem.isAllowedUseBy(res.locals.user)) throw new ErrorMessage('您没有权限进行此操作。');
if (!req.params.filename) {
if (!await syzoj.utils.isFile(problem.getTestdataPath() + '.zip')) {
if (!await syzoj.utils.isFile(problem.getTestdataArchivePath())) {
await problem.makeTestdataZip();
}
}
let path = require('path');
let filename = req.params.filename ? path.join(problem.getTestdataPath(), req.params.filename) : (problem.getTestdataPath() + '.zip');
let filename = req.params.filename ? path.join(problem.getTestdataPath(), req.params.filename) : (problem.getTestdataArchivePath());
if (!await syzoj.utils.isFile(filename)) throw new ErrorMessage('文件不存在。');
res.download(filename, path.basename(filename));
} catch (e) {

24
package-lock.json generated

@ -1056,12 +1056,23 @@
"integrity": "sha1-9HTKXmqSRtb9jglTz6m5yAWvp44="
},
"fs-extra": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-2.1.2.tgz",
"integrity": "sha1-BGxwFjzvmq1GsOSn+kZ/si1x3jU=",
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.1.tgz",
"integrity": "sha1-f8DGyJV/mD9X8waiTlud3Y0N2IA=",
"requires": {
"graceful-fs": "4.1.11",
"jsonfile": "2.4.0"
"jsonfile": "3.0.1",
"universalify": "0.1.1"
},
"dependencies": {
"jsonfile": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-3.0.1.tgz",
"integrity": "sha1-pezG9l9T9mLEQVx2daAzHQmS7GY=",
"requires": {
"graceful-fs": "4.1.11"
}
}
}
},
"generic-pool": {
@ -3849,6 +3860,11 @@
"through": "2.3.8"
}
},
"universalify": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.1.tgz",
"integrity": "sha1-+nG63UQ3r0wUiEHjs7Fl+enlkLc="
},
"unpipe": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",

2
package.json

@ -36,7 +36,7 @@
"express": "^4.14.0",
"express-session": "^1.14.1",
"file-size": "^1.0.0",
"fs-extra": "^2.1.2",
"fs-extra": "^4.0.1",
"gravatar": "^1.5.2",
"js-yaml": "^3.9.0",
"jsonwebtoken": "^7.4.3",

Loading…
Cancel
Save