MCPcopy Create free account
hub / github.com/hydro-dev/Hydro / postUploadFile

Method postUploadFile

packages/hydrooj/src/handler/problem.ts:712–768  ·  view source on GitHub ↗
(domainId: string, filename: string, type = 'testdata')

Source from the content-addressed store, hash-verified

710 @post('filename', Types.Filename, true)
711 @post('type', Types.Range(['testdata', 'additional_file']), true)
712 async postUploadFile(domainId: string, filename: string, type = 'testdata') {
713 const file = this.request.files.file;
714 if (!file) throw new ValidationError('file');
715 filename ||= file.originalFilename || randomstring(16);
716 const files = [];
717 if (filename.endsWith('.zip') && type === 'testdata') {
718 const zip = new ZipReader(Readable.toWeb(createReadStream(file.filepath)));
719 let entries: Entry[];
720 try {
721 entries = await zip.getEntries();
722 } catch (e) {
723 throw new ValidationError('zip', null, e.message);
724 }
725 for (const entry of entries) {
726 if (!entry.filename || entry.directory === true) continue;
727 files.push({
728 type,
729 name: sanitize(entry.filename),
730 size: entry.uncompressedSize,
731 data: () => {
732 const pass = new PassThrough();
733 entry.getData(Writable.toWeb(pass));
734 return pass;
735 },
736 });
737 }
738 } else {
739 files.push({
740 type,
741 name: filename,
742 size: file.size,
743 data: () => file.filepath,
744 });
745 }
746 if (!this.user.hasPriv(PRIV.PRIV_EDIT_SYSTEM)) {
747 if ((this.pdoc.data?.length || 0)
748 + (this.pdoc.additional_file?.length || 0)
749 + files.length
750 >= this.ctx.setting.get('limit.problem_files_max')) {
751 throw new FileLimitExceededError('count');
752 }
753 const size = Math.sum(
754 (this.pdoc.data || []).map((i) => i.size),
755 (this.pdoc.additional_file || []).map((i) => i.size),
756 files.map((i) => i.size),
757 );
758 if (size >= this.ctx.setting.get('limit.problem_files_max_size')) {
759 throw new FileLimitExceededError('size');
760 }
761 }
762 for (const entry of files) {
763 const method = entry.type === 'testdata' ? 'addTestdata' : 'addAdditionalFile';
764 // eslint-disable-next-line no-await-in-loop
765 await problem[method](domainId, this.pdoc.docId, entry.name, entry.data(), this.user._id);
766 }
767 this.back();
768 }
769

Callers

nothing calls this directly

Calls 7

randomstringFunction · 0.90
sanitizeFunction · 0.85
getDataMethod · 0.80
hasPrivMethod · 0.80
backMethod · 0.80
pushMethod · 0.45
getMethod · 0.45

Tested by

no test coverage detected