(domainId: string, lang: string, code: string, pretest = false, input: string[] = [], tid?: ObjectId)
| 486 | @param('input', Types.ArrayOf(Types.String, true), true) |
| 487 | @param('tid', Types.ObjectId, true) |
| 488 | async post(domainId: string, lang: string, code: string, pretest = false, input: string[] = [], tid?: ObjectId) { |
| 489 | const config = this.pdoc.config; |
| 490 | if (typeof config === 'string' || config === null) throw new ProblemConfigError(); |
| 491 | if (['submit_answer', 'objective'].includes(config.type)) { |
| 492 | lang = '_'; |
| 493 | } else if ((config.langs && !config.langs.includes(lang)) || !setting.langs[lang] || setting.langs[lang].disabled) { |
| 494 | throw new ProblemNotAllowLanguageError(); |
| 495 | } |
| 496 | if (pretest) { |
| 497 | if (setting.langs[lang]?.pretest) lang = setting.langs[lang].pretest as string; |
| 498 | if (!['default', 'remote_judge'].includes(this.response.body.pdoc.config?.type)) { |
| 499 | throw new ProblemNotAllowPretestError('type'); |
| 500 | } |
| 501 | if (!input.length) throw new ValidationError('input'); |
| 502 | input = input.map((i) => i || ''); |
| 503 | } |
| 504 | await this.limitRate('add_record', 60, system.get('limit.submission_user'), '{{user}}'); |
| 505 | await this.limitRate('add_record', 60, pretest ? system.get('limit.pretest') : system.get('limit.submission')); |
| 506 | const files: Record<string, string> = {}; |
| 507 | const lengthLimit = system.get('limit.codelength') || 128 * 1024; |
| 508 | if (!code) { |
| 509 | const file = this.request.files?.file; |
| 510 | if (!file || file.size === 0) throw new ValidationError('code'); |
| 511 | const sizeLimit = config.type === 'submit_answer' ? 128 * 1024 * 1024 : lengthLimit; |
| 512 | if (file.size > sizeLimit) throw new FileTooLargeError('file'); |
| 513 | const shouldReadFile = () => { |
| 514 | if (config.type === 'objective') return true; |
| 515 | if (lang === '_') return false; |
| 516 | return file.size < lengthLimit && !file.filepath.endsWith('.zip') && !setting.langs[lang].isBinary; |
| 517 | }; |
| 518 | if (shouldReadFile()) code = await readFile(file.filepath, 'utf-8'); |
| 519 | else { |
| 520 | const id = nanoid(); |
| 521 | await storage.put(`submission/${this.user._id}/${id}`, file.filepath, this.user._id); |
| 522 | files.code = `${this.user._id}/${id}#${file.originalFilename}`; |
| 523 | } |
| 524 | } else { |
| 525 | code = code.replace(/\r\n/g, '\n'); |
| 526 | if (code.length > lengthLimit) throw new ValidationError('code'); |
| 527 | } |
| 528 | const rid = await record.add( |
| 529 | domainId, this.pdoc.docId, this.user._id, lang, code, true, |
| 530 | pretest ? { input, type: 'pretest' } : { contest: tid, files, type: 'judge' }, |
| 531 | ); |
| 532 | if (!pretest) { |
| 533 | await Promise.all([ |
| 534 | problem.inc(domainId, this.pdoc.docId, 'nSubmit', 1), |
| 535 | domain.incUserInDomain(domainId, this.user._id, 'nSubmit'), |
| 536 | tid && contest.updateStatus(domainId, tid, this.user._id, rid, this.pdoc.docId), |
| 537 | ]); |
| 538 | } |
| 539 | if (tid && !pretest && !contest.canShowSelfRecord.call(this, this.tdoc)) { |
| 540 | this.response.body = { tid }; |
| 541 | this.response.redirect = this.url(this.tdoc.rule === 'homework' ? 'homework_detail' : 'contest_problemlist', { tid }); |
| 542 | } else { |
| 543 | this.response.body = { rid }; |
| 544 | this.response.redirect = this.url('record_detail', { rid }); |
| 545 | } |
nothing calls this directly
no test coverage detected