MCPcopy Index your code
hub / github.com/hydro-dev/Hydro / ProblemDetailHandler

Class ProblemDetailHandler

packages/hydrooj/src/handler/problem.ts:295–460  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

293}
294
295export class ProblemDetailHandler extends ContestDetailBaseHandler {
296 pdoc: ProblemDoc;
297 udoc: User;
298 psdoc: ProblemStatusDoc;
299
300 @route('pid', Types.ProblemId, true)
301 @query('tid', Types.ObjectId, true)
302 async _prepare(domainId: string, pid: number | string, tid?: ObjectId) {
303 this.pdoc = await problem.get(domainId, pid);
304 if (!this.pdoc) throw new ProblemNotFoundError(domainId, pid);
305 if (tid) {
306 if (!this.tdoc?.pids?.includes(this.pdoc.docId)) throw new ContestNotFoundError(domainId, tid);
307 if (contest.isNotStarted(this.tdoc)) throw new ContestNotLiveError(tid);
308 if (!contest.isDone(this.tdoc, this.tsdoc) && (!this.tsdoc?.attend || !this.tsdoc.startAt)) throw new ContestNotAttendedError(tid);
309 // Delete problem-related info in contest mode
310 if (this.pdoc.tag) this.pdoc.tag.length = 0;
311 delete this.pdoc.nAccept;
312 delete this.pdoc.nSubmit;
313 delete this.pdoc.difficulty;
314 delete this.pdoc.stats;
315 } else if (!problem.canViewBy(this.pdoc, this.user)) {
316 throw new PermissionError(PERM.PERM_VIEW_PROBLEM_HIDDEN);
317 }
318 let ddoc = this.domain;
319 if (this.pdoc.reference) {
320 ddoc = await domain.get(this.pdoc.reference.domainId);
321 const pdoc = await problem.get(this.pdoc.reference.domainId, this.pdoc.reference.pid);
322 if (!ddoc || !pdoc) throw new ProblemNotFoundError(this.pdoc.reference.domainId, this.pdoc.reference.pid);
323 this.pdoc.config = pdoc.config;
324 this.pdoc.additional_file = pdoc.additional_file;
325 }
326 if (typeof this.pdoc.config !== 'string') {
327 let baseLangs;
328 const t = [];
329 if (this.pdoc.config.langs) t.push(this.pdoc.config.langs);
330 if (ddoc.langs) t.push(ddoc.langs.split(',').map((i) => i.trim()).filter((i) => i));
331 if (this.domain.langs) t.push(this.domain.langs.split(',').map((i) => i.trim()).filter((i) => i));
332 if (this.tdoc?.langs?.length) t.push(this.tdoc.langs);
333 if (this.pdoc.config.type === 'remote_judge') {
334 const p = this.pdoc.config.subType;
335 const dl = Object.keys(setting.langs).filter((i) => i.startsWith(`${p}.`) || setting.langs[i].validAs[p]);
336 if (setting.langs[p]) dl.push(p);
337 baseLangs = dl;
338 } else {
339 const needHiddenLangs = flattenDeep(t).length;
340 baseLangs = Object.keys(setting.langs).filter((i) =>
341 (needHiddenLangs ? !setting.langs[i].remote : !setting.langs[i].remote && !setting.langs[i].hidden));
342 }
343 this.pdoc.config.langs = ['objective', 'submit_answer'].includes(this.pdoc.config.type) ? ['_'] : intersection(baseLangs, ...t);
344 }
345 await this.ctx.parallel('problem/get', this.pdoc, this);
346 [this.psdoc, this.udoc] = await Promise.all([
347 problem.getStatus(domainId, this.pdoc.docId, this.user._id),
348 user.getById(domainId, this.pdoc.owner),
349 ]);
350 const [scnt, dcnt] = await Promise.all([
351 solution.count(domainId, { parentId: this.pdoc.docId }),
352 discussion.count(domainId, { parentId: this.pdoc.docId }),

Callers

nothing calls this directly

Calls 3

routeFunction · 0.85
paramFunction · 0.85
queryFunction · 0.50

Tested by

no test coverage detected