mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-20 01:38:19 +08:00
judge: auto-remove extra files (#104)
This commit is contained in:
1 parent
c977a51de9
commit
a7fd32cac9
6 files changed
+26
-2
No files matched your search
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@hydrooj/hydrojudge",
|
"name": "@hydrooj/hydrojudge",
|
||||||
"bin": "bin/hydrojudge.js",
|
"bin": "bin/hydrojudge.js",
|
||||||
"version": "2.5.8",
|
"version": "2.5.9",
|
||||||
"main": "package.json",
|
"main": "package.json",
|
||||||
"author": "undefined <i@undefined.moe>",
|
"author": "undefined <i@undefined.moe>",
|
||||||
"repository": "https://github.com/hydro-dev/Hydro.git",
|
"repository": "https://github.com/hydro-dev/Hydro.git",
|
||||||
|
|||||||
@@ -202,10 +202,15 @@ export default class Hydro {
|
|||||||
} catch (e) { /* ignore */ }
|
} catch (e) { /* ignore */ }
|
||||||
const version = {};
|
const version = {};
|
||||||
const filenames = [];
|
const filenames = [];
|
||||||
|
const allFiles = new Set<string>();
|
||||||
for (const file of files) {
|
for (const file of files) {
|
||||||
|
allFiles.add(file.name);
|
||||||
version[file.name] = file.etag;
|
version[file.name] = file.etag;
|
||||||
if (etags[file.name] !== file.etag) filenames.push(file.name);
|
if (etags[file.name] !== file.etag) filenames.push(file.name);
|
||||||
}
|
}
|
||||||
|
for (const name in etags) {
|
||||||
|
if (!allFiles.has(name)) await fs.rm(path.join(filePath, name));
|
||||||
|
}
|
||||||
if (filenames.length) {
|
if (filenames.length) {
|
||||||
log.info(`Getting problem data: ${this.config.host}/${domainId}/${pid}`);
|
log.info(`Getting problem data: ${this.config.host}/${domainId}/${pid}`);
|
||||||
if (next) next({ judge_text: '正在同步测试数据,请稍后' });
|
if (next) next({ judge_text: '正在同步测试数据,请稍后' });
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ declare module 'hydrooj/dist/interface' {
|
|||||||
'hydrojudge.tmpfs_size': string,
|
'hydrojudge.tmpfs_size': string,
|
||||||
'hydrojudge.retry_delay_sec': number,
|
'hydrojudge.retry_delay_sec': number,
|
||||||
'hydrojudge.sandbox_host': string,
|
'hydrojudge.sandbox_host': string,
|
||||||
|
'hydrojudge.memoryMax': string,
|
||||||
'hydrojudge.testcases_max': number,
|
'hydrojudge.testcases_max': number,
|
||||||
'hydrojudge.total_time_limit': number,
|
'hydrojudge.total_time_limit': number,
|
||||||
'hydrojudge.parallelism': number,
|
'hydrojudge.parallelism': number,
|
||||||
@@ -81,12 +82,17 @@ async function postInit() {
|
|||||||
etags = JSON.parse(fs.readFileSync(path.join(filePath, 'etags')).toString());
|
etags = JSON.parse(fs.readFileSync(path.join(filePath, 'etags')).toString());
|
||||||
} catch (e) { /* ignore */ }
|
} catch (e) { /* ignore */ }
|
||||||
const version = {};
|
const version = {};
|
||||||
|
const filenames = new Set<string>();
|
||||||
for (const file of files) {
|
for (const file of files) {
|
||||||
|
filenames.add(file.name);
|
||||||
version[file.name] = file.etag;
|
version[file.name] = file.etag;
|
||||||
if (etags[file.name] !== file.etag) {
|
if (etags[file.name] !== file.etag) {
|
||||||
await storage.get(`problem/${domainId}/${pid}/testdata/${file.name}`, path.join(filePath, file.name));
|
await storage.get(`problem/${domainId}/${pid}/testdata/${file.name}`, path.join(filePath, file.name));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (const name in etags) {
|
||||||
|
if (!filenames.has(name)) await fs.rm(path.join(filePath, name));
|
||||||
|
}
|
||||||
fs.writeFileSync(path.join(filePath, 'etags'), JSON.stringify(version));
|
fs.writeFileSync(path.join(filePath, 'etags'), JSON.stringify(version));
|
||||||
fs.writeFileSync(path.join(filePath, 'lastUsage'), new Date().getTime().toString());
|
fs.writeFileSync(path.join(filePath, 'lastUsage'), new Date().getTime().toString());
|
||||||
await processData(filePath).catch(noop);
|
await processData(filePath).catch(noop);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "hydrooj",
|
"name": "hydrooj",
|
||||||
"version": "2.23.9",
|
"version": "2.23.10",
|
||||||
"bin": "bin/hydrooj.js",
|
"bin": "bin/hydrooj.js",
|
||||||
"main": "dist/loader.js",
|
"main": "dist/loader.js",
|
||||||
"typings": "dist/loader.d.ts",
|
"typings": "dist/loader.d.ts",
|
||||||
|
|||||||
@@ -394,6 +394,7 @@ export class ProblemFilesHandler extends ProblemDetailHandler {
|
|||||||
async postUploadFile(domainId: string, filename: string, type = 'testdata') {
|
async postUploadFile(domainId: string, filename: string, type = 'testdata') {
|
||||||
if (!this.request.files.file) throw new ValidationError('file');
|
if (!this.request.files.file) throw new ValidationError('file');
|
||||||
if (!filename) filename = this.request.files.file.name || String.random(16);
|
if (!filename) filename = this.request.files.file.name || String.random(16);
|
||||||
|
if (filename.includes('/')) throw new ValidationError('filename', 'Bad filename');
|
||||||
if (this.pdoc.owner !== this.user._id) this.checkPerm(PERM.PERM_EDIT_PROBLEM);
|
if (this.pdoc.owner !== this.user._id) this.checkPerm(PERM.PERM_EDIT_PROBLEM);
|
||||||
if (filename.endsWith('.zip')) {
|
if (filename.endsWith('.zip')) {
|
||||||
const zip = new AdmZip(this.request.files.file.path);
|
const zip = new AdmZip(this.request.files.file.path);
|
||||||
|
|||||||
@@ -115,6 +115,7 @@ class StorageService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async put(target: string, file: string | Buffer | Readable, meta: ItemBucketMetadata = {}) {
|
async put(target: string, file: string | Buffer | Readable, meta: ItemBucketMetadata = {}) {
|
||||||
|
if (target.includes('..') || target.includes('//')) throw new Error('Invalid path');
|
||||||
if (typeof file === 'string') file = createReadStream(file);
|
if (typeof file === 'string') file = createReadStream(file);
|
||||||
try {
|
try {
|
||||||
return await this.client.putObject(this.opts.bucket, target, file, meta);
|
return await this.client.putObject(this.opts.bucket, target, file, meta);
|
||||||
@@ -125,6 +126,7 @@ class StorageService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async get(target: string, path?: string) {
|
async get(target: string, path?: string) {
|
||||||
|
if (target.includes('..') || target.includes('//')) throw new Error('Invalid path');
|
||||||
try {
|
try {
|
||||||
if (path) return await this.client.fGetObject(this.opts.bucket, target, path);
|
if (path) return await this.client.fGetObject(this.opts.bucket, target, path);
|
||||||
return await this.client.getObject(this.opts.bucket, target);
|
return await this.client.getObject(this.opts.bucket, target);
|
||||||
@@ -135,6 +137,13 @@ class StorageService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async del(target: string | string[]) {
|
async del(target: string | string[]) {
|
||||||
|
if (typeof target === 'string') {
|
||||||
|
if (target.includes('..') || target.includes('//')) throw new Error('Invalid path');
|
||||||
|
} else {
|
||||||
|
for (const t of target) {
|
||||||
|
if (t.includes('..') || t.includes('//')) throw new Error('Invalid path');
|
||||||
|
}
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
if (typeof target === 'string') return await this.client.removeObject(this.opts.bucket, target);
|
if (typeof target === 'string') return await this.client.removeObject(this.opts.bucket, target);
|
||||||
return await this.client.removeObjects(this.opts.bucket, target);
|
return await this.client.removeObjects(this.opts.bucket, target);
|
||||||
@@ -145,6 +154,7 @@ class StorageService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async list(target: string, recursive = true) {
|
async list(target: string, recursive = true) {
|
||||||
|
if (target.includes('..') || target.includes('//')) throw new Error('Invalid path');
|
||||||
try {
|
try {
|
||||||
const stream = this.client.listObjects(this.opts.bucket, target, recursive);
|
const stream = this.client.listObjects(this.opts.bucket, target, recursive);
|
||||||
return await new Promise<BucketItem[]>((resolve, reject) => {
|
return await new Promise<BucketItem[]>((resolve, reject) => {
|
||||||
@@ -168,6 +178,7 @@ class StorageService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async getMeta(target: string) {
|
async getMeta(target: string) {
|
||||||
|
if (target.includes('..') || target.includes('//')) throw new Error('Invalid path');
|
||||||
try {
|
try {
|
||||||
const result = await this.client.statObject(this.opts.bucket, target);
|
const result = await this.client.statObject(this.opts.bucket, target);
|
||||||
return { ...result.metaData, ...result };
|
return { ...result.metaData, ...result };
|
||||||
@@ -178,6 +189,7 @@ class StorageService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async signDownloadLink(target: string, filename?: string, noExpire = false, useAlternativeEndpointFor?: 'user' | 'judge'): Promise<string> {
|
async signDownloadLink(target: string, filename?: string, noExpire = false, useAlternativeEndpointFor?: 'user' | 'judge'): Promise<string> {
|
||||||
|
if (target.includes('..') || target.includes('//')) throw new Error('Invalid path');
|
||||||
try {
|
try {
|
||||||
const url = await this.client.presignedGetObject(
|
const url = await this.client.presignedGetObject(
|
||||||
this.opts.bucket,
|
this.opts.bucket,
|
||||||
|
|||||||
Reference in new issue
Block a user