mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-20 01:38:19 +08:00
core&ui: support file renaming (#688)
Co-authored-by: undefined <i@undefined.moe>
This commit is contained in:
1 parent
746efef9bf
commit
01cb6944b7
19 files changed
+496
-144
No files matched your search
@@ -695,7 +695,7 @@ export class ProblemFilesHandler extends ProblemDetailHandler {
|
||||
const { testdata, additional_file } = this.response.body;
|
||||
const owner = await user.getById(domainId, this.pdoc.owner);
|
||||
const args = {
|
||||
testdata, additional_file, pdoc: this.pdoc, owner_udoc: owner, sidebar,
|
||||
testdata, additional_file, pdoc: this.pdoc, owner_udoc: owner, sidebar, can_edit: true,
|
||||
};
|
||||
const tasks = [];
|
||||
if (d.includes('testdata')) tasks.push(this.renderHTML('partials/problem_files.html', { ...args, filetype: 'testdata' }));
|
||||
@@ -795,6 +795,21 @@ export class ProblemFilesHandler extends ProblemDetailHandler {
|
||||
this.back();
|
||||
}
|
||||
|
||||
@post('files', Types.ArrayOf(Types.Filename))
|
||||
@post('newNames', Types.ArrayOf(Types.Filename))
|
||||
@post('type', Types.Range(['testdata', 'additional_file']), true)
|
||||
async postRenameFiles(domainId: string, files: string[], newNames: string[], type = 'testdata') {
|
||||
if (this.pdoc.reference) throw new ProblemIsReferencedError('rename files');
|
||||
if (files.length !== newNames.length) throw new ValidationError('files', 'newNames');
|
||||
if (!this.user.own(this.pdoc, PERM.PERM_EDIT_PROBLEM_SELF)) this.checkPerm(PERM.PERM_EDIT_PROBLEM);
|
||||
await Promise.all(files.map(async (file, index) => {
|
||||
const newName = newNames[index];
|
||||
if (type === 'testdata') await problem.renameTestdata(domainId, this.pdoc.docId, file, newName, this.user._id);
|
||||
else await problem.renameAdditionalFile(domainId, this.pdoc.docId, file, newName, this.user._id);
|
||||
}));
|
||||
this.back();
|
||||
}
|
||||
|
||||
@post('files', Types.ArrayOf(Types.Filename))
|
||||
@post('type', Types.Range(['testdata', 'additional_file']), true)
|
||||
async postDeleteFiles(domainId: string, files: string[], type = 'testdata') {
|
||||
|
||||
@@ -282,6 +282,22 @@ export class ProblemModel {
|
||||
await bus.emit('problem/addTestdata', domainId, pid, name, payload);
|
||||
}
|
||||
|
||||
static async renameTestdata(domainId: string, pid: number, file: string, newName: string, operator = 1) {
|
||||
if (file === newName) return;
|
||||
const [, sdoc] = await document.getSub(domainId, document.TYPE_PROBLEM, pid, 'data', newName);
|
||||
if (sdoc) await ProblemModel.delTestdata(domainId, pid, newName);
|
||||
const payload = { _id: newName, name: newName, lastModified: new Date() };
|
||||
await Promise.all([
|
||||
storage.rename(
|
||||
`problem/${domainId}/${pid}/testdata/${file}`,
|
||||
`problem/${domainId}/${pid}/testdata/${newName}`,
|
||||
operator,
|
||||
),
|
||||
document.setSub(domainId, document.TYPE_PROBLEM, pid, 'data', file, payload),
|
||||
]);
|
||||
await bus.emit('problem/renameTestdata', domainId, pid, file, newName);
|
||||
}
|
||||
|
||||
static async delTestdata(domainId: string, pid: number, name: string | string[], operator = 1) {
|
||||
const names = (name instanceof Array) ? name : [name];
|
||||
await Promise.all([
|
||||
@@ -307,6 +323,22 @@ export class ProblemModel {
|
||||
await bus.emit('problem/addAdditionalFile', domainId, pid, name, payload);
|
||||
}
|
||||
|
||||
static async renameAdditionalFile(domainId: string, pid: number, file: string, newName: string, operator = 1) {
|
||||
if (file === newName) return;
|
||||
const [, sdoc] = await document.getSub(domainId, document.TYPE_PROBLEM, pid, 'additional_file', newName);
|
||||
if (sdoc) await ProblemModel.delAdditionalFile(domainId, pid, newName);
|
||||
const payload = { _id: newName, name: newName, lastModified: new Date() };
|
||||
await Promise.all([
|
||||
storage.rename(
|
||||
`problem/${domainId}/${pid}/additional_file/${file}`,
|
||||
`problem/${domainId}/${pid}/additional_file/${newName}`,
|
||||
operator,
|
||||
),
|
||||
document.setSub(domainId, document.TYPE_PROBLEM, pid, 'additional_file', file, payload),
|
||||
]);
|
||||
await bus.emit('problem/renameAdditionalFile', domainId, pid, file, newName);
|
||||
}
|
||||
|
||||
static async delAdditionalFile(domainId: string, pid: number, name: MaybeArray<string>, operator = 1) {
|
||||
const names = (name instanceof Array) ? name : [name];
|
||||
await Promise.all([
|
||||
@@ -558,6 +590,15 @@ bus.on('problem/delTestdata', async (domainId, docId, names) => {
|
||||
if (!names.includes('config.yaml')) return;
|
||||
await ProblemModel.edit(domainId, docId, { config: '' });
|
||||
});
|
||||
bus.on('problem/renameTestdata', async (domainId, docId, file, newName) => {
|
||||
if (['config.yaml', 'config.yml', 'Config.yaml', 'Config.yml'].includes(file)) {
|
||||
await ProblemModel.edit(domainId, docId, { config: '' });
|
||||
}
|
||||
if (['config.yaml', 'config.yml', 'Config.yaml', 'Config.yml'].includes(newName)) {
|
||||
const buf = await storage.get(`problem/${domainId}/${docId}/testdata/${newName}`);
|
||||
await ProblemModel.edit(domainId, docId, { config: (await streamToBuffer(buf)).toString() });
|
||||
}
|
||||
});
|
||||
|
||||
global.Hydro.model.problem = ProblemModel;
|
||||
export default ProblemModel;
|
||||
@@ -85,8 +85,10 @@ export interface EventMap extends LifecycleEvents, HandlerEvents {
|
||||
'problem/get': (doc: ProblemDoc, handler: any) => VoidReturn
|
||||
'problem/delete': (domainId: string, docId: number) => VoidReturn
|
||||
'problem/addTestdata': (domainId: string, docId: number, name: string, payload: Omit<FileInfo, '_id'>) => VoidReturn
|
||||
'problem/renameTestdata': (domainId: string, docId: number, name: string, newName: string) => VoidReturn
|
||||
'problem/delTestdata': (domainId: string, docId: number, name: string[]) => VoidReturn
|
||||
'problem/addAdditionalFile': (domainId: string, docId: number, name: string, payload: Omit<FileInfo, '_id'>) => VoidReturn
|
||||
'problem/renameAdditionalFile': (domainId: string, docId: number, name: string, newName: string) => VoidReturn
|
||||
'problem/delAdditionalFile': (domainId: string, docId: number, name: string[]) => VoidReturn
|
||||
|
||||
'contest/before-add': (payload: Partial<Tdoc<30>>) => VoidReturn
|
||||
|
||||
Reference in new issue
Block a user