async def post(self, *, tid: objectid.ObjectId, pid: document.convert_doc_id, lang: str, code: str): tdoc, pdoc = await asyncio.gather( contest.get(self.domain_id, document.TYPE_HOMEWORK, tid), problem.get(self.domain_id, pid)) tsdoc = await contest.get_status(self.domain_id, document.TYPE_HOMEWORK, tdoc['doc_id'], self.user['_id']) if not tsdoc or tsdoc.get('attend') != 1: raise error.HomeworkNotAttendedError(tdoc['doc_id']) if not self.is_ongoing(tdoc): raise error.HomeworkNotLiveError(tdoc['doc_id']) if pid not in tdoc['pids']: raise error.ProblemNotFoundError(self.domain_id, pid, tdoc['doc_id']) rid = await record.add(self.domain_id, pdoc['doc_id'], constant.record.TYPE_SUBMISSION, self.user['_id'], lang, code, ttype=document.TYPE_HOMEWORK, tid=tdoc['doc_id'], hidden=True) await contest.update_status(self.domain_id, document.TYPE_HOMEWORK, tdoc['doc_id'], self.user['_id'], rid, pdoc['doc_id'], False, 0) if not self.can_show_record(tdoc): self.json_or_redirect( self.reverse_url('homework_detail', tid=tdoc['doc_id'])) else: self.json_or_redirect(self.reverse_url('record_detail', rid=rid))
async def post(self, *, title: str, content: str, rule: int, begin_at_date: str, begin_at_time: str, duration: float, pids: str): try: begin_at = datetime.datetime.strptime(begin_at_date + ' ' + begin_at_time, '%Y-%m-%d %H:%M') begin_at = self.timezone.localize(begin_at).astimezone(pytz.utc).replace(tzinfo=None) end_at = begin_at + datetime.timedelta(hours=duration) except ValueError as e: raise error.ValidationError('begin_at_date', 'begin_at_time') if begin_at <= self.now: raise error.ValidationError('begin_at_date', 'begin_at_time') if begin_at >= end_at: raise error.ValidationError('duration') pids = list(set(map(document.convert_doc_id, pids.split(',')))) pdocs = await problem.get_multi(domain_id=self.domain_id, doc_id={'$in': pids}, fields={'doc_id': 1}) \ .sort('doc_id', 1) \ .to_list() exist_pids = [pdoc['doc_id'] for pdoc in pdocs] if len(pids) != len(exist_pids): for pid in pids: if pid not in exist_pids: raise error.ProblemNotFoundError(self.domain_id, pid) tid = await contest.add(self.domain_id, title, content, self.user['_id'], rule, begin_at, end_at, pids) for pid in pids: await problem.set_hidden(self.domain_id, pid, True) self.json_or_redirect(self.reverse_url('contest_detail', tid=tid))
async def get(self, *, tid: objectid.ObjectId, pid: document.convert_doc_id): uid = self.user['_id'] if self.has_priv( builtin.PRIV_USER_PROFILE) else None tdoc, pdoc = await asyncio.gather( contest.get(self.domain_id, document.TYPE_HOMEWORK, tid), problem.get(self.domain_id, pid, uid)) tsdoc, udoc, dudoc = await asyncio.gather( contest.get_status(self.domain_id, document.TYPE_HOMEWORK, tdoc['doc_id'], self.user['_id']), user.get_by_uid(tdoc['owner_uid']), domain.get_user(domain_id=self.domain_id, uid=tdoc['owner_uid'])) attended = tsdoc and tsdoc.get('attend') == 1 if not self.is_done(tdoc): if not attended: raise error.HomeworkNotAttendedError(tdoc['doc_id']) if not self.is_ongoing(tdoc): raise error.HomeworkNotLiveError(tdoc['doc_id']) if pid not in tdoc['pids']: raise error.ProblemNotFoundError(self.domain_id, pid, tdoc['doc_id']) path_components = self.build_path( (self.translate('homework_main'), self.reverse_url('homework_main')), (tdoc['title'], self.reverse_url('homework_detail', tid=tid)), (pdoc['title'], None)) self.render('problem_detail.html', tdoc=tdoc, pdoc=pdoc, tsdoc=tsdoc, udoc=udoc, attended=attended, dudoc=dudoc, page_title=pdoc['title'], path_components=path_components)
async def post(self, *, tid: objectid.ObjectId, pid: document.convert_doc_id, lang: str, code: str): await opcount.inc(**opcount.OPS['run_code'], ident=opcount.PREFIX_USER + str(self.user['_id'])) tdoc, pdoc = await asyncio.gather(contest.get(self.domain_id, tid), problem.get(self.domain_id, pid)) tsdoc = await contest.get_status(self.domain_id, tdoc['doc_id'], self.user['_id']) if not tsdoc or tsdoc.get('attend') != 1: raise error.ContestNotAttendedError(tdoc['doc_id']) if not self.is_live(tdoc): raise error.ContestNotLiveError(tdoc['doc_id']) if pid not in tdoc['pids']: raise error.ProblemNotFoundError(self.domain_id, pid, tdoc['doc_id']) rid = await record.add(self.domain_id, pdoc['doc_id'], constant.record.TYPE_SUBMISSION, self.user['_id'], lang, code, tid=tdoc['doc_id'], hidden=True) await contest.update_status(self.domain_id, tdoc['doc_id'], self.user['_id'], rid, pdoc['doc_id'], False, 0) if not self.can_show_record(tdoc): self.json_or_redirect( self.reverse_url('contest_detail', tid=tdoc['doc_id'])) else: self.json_or_redirect(self.reverse_url('record_detail', rid=rid))
async def post(self, *, tid: objectid.ObjectId, title: str, content: str, dag: str): tdoc = await training.get(self.domain_id, tid) if not self.own(tdoc, builtin.PERM_EDIT_TRAINING_SELF): self.check_perm(builtin.PERM_EDIT_TRAINING) dag = _parse_dag_json(dag) pids = self.get_pids({'dag': dag}) if not pids: # empty plan raise error.ValidationError('dag') pdocs = await problem.get_multi(domain_id=self.domain_id, doc_id={'$in': pids}, fields={'doc_id': 1, 'hidden': 1}) \ .sort('doc_id', 1) \ .to_list(None) exist_pids = [pdoc['doc_id'] for pdoc in pdocs] if len(pids) != len(exist_pids): for pid in pids: if pid not in exist_pids: raise error.ProblemNotFoundError(self.domain_id, pid) for pdoc in pdocs: if pdoc.get('hidden', False): self.check_perm(builtin.PERM_VIEW_PROBLEM_HIDDEN) await training.edit(self.domain_id, tdoc['doc_id'], title=title, content=content, dag=dag) self.json_or_redirect(self.reverse_url('training_detail', tid=tid))
async def post(self, *, title: str, content: str, dag: str, desc: str): dag = _parse_dag_json(dag) pids = self.get_pids({'dag': dag}) if not pids: # empty plan raise error.ValidationError('dag') pdocs = await problem.get_multi(domain_id=self.domain_id, doc_id={'$in': pids}, fields={'doc_id': 1, 'hidden': 1}) \ .sort('doc_id', 1) \ .to_list() exist_pids = [pdoc['doc_id'] for pdoc in pdocs] if len(pids) != len(exist_pids): for pid in pids: if pid not in exist_pids: raise error.ProblemNotFoundError(self.domain_id, pid) for pdoc in pdocs: if pdoc.get('hidden', False): self.check_perm(builtin.PERM_VIEW_PROBLEM_HIDDEN) tid = await training.add(self.domain_id, title, content, self.user['_id'], dag=dag, desc=desc) self.json_or_redirect(self.reverse_url('training_detail', tid=tid))
async def get(self, *, tid: objectid.ObjectId, pid: document.convert_doc_id): uid = self.user['_id'] if self.has_priv(builtin.PRIV_USER_PROFILE) else None tdoc, pdoc = await asyncio.gather(contest.get(self.domain_id, tid), problem.get(self.domain_id, pid, uid)) tsdoc = await contest.get_status(self.domain_id, tdoc['doc_id'], self.user['_id']) if not tsdoc or tsdoc.get('attend') != 1: raise error.ContestNotAttendedError(tdoc['doc_id']) if not self.is_live(tdoc): raise error.ContestNotLiveError(tdoc['doc_id']) if pid not in tdoc['pids']: raise error.ProblemNotFoundError(self.domain_id, pid, tdoc['doc_id']) tsdoc, udoc = await asyncio.gather( contest.get_status(self.domain_id, tdoc['doc_id'], self.user['_id']), user.get_by_uid(tdoc['owner_uid'])) attended = tsdoc and tsdoc.get('attend') == 1 if (contest.RULES[tdoc['rule']].show_func(tdoc, self.now) or self.has_perm(builtin.PERM_VIEW_CONTEST_HIDDEN_STATUS)): rdocs = await record.get_user_in_problem_multi(uid, self.domain_id, pdoc['doc_id']) \ .sort([('_id', -1)]) \ .limit(10) \ .to_list() else: rdocs = [] if not self.prefer_json: path_components = self.build_path( (self.translate('contest_main'), self.reverse_url('contest_main')), (tdoc['title'], self.reverse_url('contest_detail', tid=tid)), (pdoc['title'], self.reverse_url('contest_detail_problem', tid=tid, pid=pid)), (self.translate('contest_detail_problem_submit'), None)) self.render('problem_submit.html', tdoc=tdoc, pdoc=pdoc, rdocs=rdocs, tsdoc=tsdoc, udoc=udoc, attended=attended, page_title=pdoc['title'], path_components=path_components) else: self.json({'rdocs': rdocs})
async def get(self, *, tid: objectid.ObjectId, pid: document.convert_doc_id): uid = self.user['_id'] if self.has_priv(builtin.PRIV_USER_PROFILE) else None tdoc, pdoc = await asyncio.gather(contest.get(self.domain_id, document.TYPE_HOMEWORK, tid), problem.get(self.domain_id, pid, uid)) tsdoc, udoc = await asyncio.gather( contest.get_status(self.domain_id, document.TYPE_HOMEWORK, tdoc['doc_id'], self.user['_id']), user.get_by_uid(tdoc['owner_uid'])) attended = tsdoc and tsdoc.get('attend') == 1 if not attended: raise error.HomeworkNotAttendedError(tdoc['doc_id']) if not self.is_ongoing(tdoc): raise error.HomeworkNotLiveError(tdoc['doc_id']) if pid not in tdoc['pids']: raise error.ProblemNotFoundError(self.domain_id, pid, tdoc['doc_id']) if self.can_show_record(tdoc): rdocs = await record.get_user_in_problem_multi(uid, self.domain_id, pdoc['doc_id'], get_hidden=True) \ .sort([('_id', -1)]) \ .limit(10) \ .to_list() else: rdocs = [] if not self.prefer_json: path_components = self.build_path( (self.translate('homework_main'), self.reverse_url('homework_main')), (tdoc['title'], self.reverse_url('homework_detail', tid=tid)), (pdoc['title'], self.reverse_url('homework_detail_problem', tid=tid, pid=pid)), (self.translate('homework_detail_problem_submit'), None)) self.render('problem_submit.html', tdoc=tdoc, pdoc=pdoc, rdocs=rdocs, tsdoc=tsdoc, udoc=udoc, attended=attended, page_title=pdoc['title'], path_components=path_components) else: self.json({'rdocs': rdocs})
async def get_pid(domain_id, key): if objectid.ObjectId.is_valid(key): pdoc = await get(domain_id, TYPE_PROBLEM, objectid.ObjectId(key)) try: key = int(key) pdoc = await get(domain_id, TYPE_PROBLEM, key) except ValueError: pdoc = await get_by_pname(domain_id, TYPE_PROBLEM, key) if not pdoc: raise error.ProblemNotFoundError(domain_id, key) return pdoc['doc_id']
async def verify_problems(self, pids): pdocs = await problem.get_multi(domain_id=self.domain_id, doc_id={'$in': pids}, fields={'doc_id': 1}) \ .sort('doc_id', 1) \ .to_list() exist_pids = [pdoc['doc_id'] for pdoc in pdocs] if len(pids) != len(exist_pids): for pid in pids: if pid not in exist_pids: raise error.ProblemNotFoundError(self.domain_id, pid) return pids
async def get(domain_id: str, pid: document.convert_doc_id, uid: int = None): pdoc = await document.get(domain_id, document.TYPE_PROBLEM, pid) if not pdoc: raise error.ProblemNotFoundError(domain_id, pid) # TODO(twd2): move out: if uid is not None: pdoc['psdoc'] = await document.get_status(domain_id, document.TYPE_PROBLEM, doc_id=pid, uid=uid) else: pdoc['psdoc'] = None return pdoc
async def post(self, *, src_domain_id: str, src_pids: str, numeric_pid: bool = False, hidden: bool = False): src_ddoc, src_dudoc = await asyncio.gather( domain.get(src_domain_id), domain.get_user(src_domain_id, self.user['_id'])) if not src_dudoc: src_dudoc = {} if not self.dudoc_has_perm(ddoc=src_ddoc, dudoc=src_dudoc, udoc=self.user, perm=builtin.PERM_VIEW_PROBLEM): # TODO: This is the source domain's PermissionError. raise error.PermissionError(builtin.PERM_VIEW_PROBLEM) src_pids = misc.dedupe( map(document.convert_doc_id, src_pids.replace('\r\n', '\n').split('\n'))) if len(src_pids) > self.MAX_PROBLEMS_PER_REQUEST: raise error.BatchCopyLimitExceededError( self.MAX_PROBLEMS_PER_REQUEST, len(src_pids)) pdocs = await problem.get_multi(domain_id=src_domain_id, doc_id={'$in': src_pids}) \ .sort('doc_id', 1) \ .to_list() exist_pids = [pdoc['doc_id'] for pdoc in pdocs] if len(src_pids) != len(exist_pids): for pid in src_pids: if pid not in exist_pids: raise error.ProblemNotFoundError(src_domain_id, pid) for pdoc in pdocs: if pdoc.get('hidden', False): if not self.dudoc_has_perm( ddoc=src_ddoc, dudoc=src_dudoc, udoc=self.user, perm=builtin.PERM_VIEW_PROBLEM_HIDDEN): # TODO: This is the source domain's PermissionError. raise error.PermissionError( builtin.PERM_VIEW_PROBLEM_HIDDEN) for pdoc in pdocs: pid = None if numeric_pid: pid = await domain.inc_pid_counter(self.domain_id) await problem.copy(pdoc, self.domain_id, self.user['_id'], pid, hidden) self.redirect(self.reverse_url('problem_main'))
async def post(self, *, ctype: str, tid: objectid.ObjectId, pid: document.convert_doc_id, lang: str, code: objectid.ObjectId): doc_type = constant.contest.CTYPE_TO_DOCTYPE[ctype] # TODO(iceboy): rate limit base on ip. tdoc, pdoc = await asyncio.gather( contest.get(self.domain_id, doc_type, tid), problem.get(self.domain_id, pid)) tsdoc = await contest.get_status(self.domain_id, doc_type, tdoc['doc_id'], self.user['_id']) if not tsdoc or tsdoc.get('attend') != 1: if ctype == 'contest': raise error.ContestNotAttendedError(tdoc['doc_id']) elif ctype == 'homework': raise error.HomeworkNotAttendedError(tdoc['doc_id']) else: raise error.InvalidArgumentError('ctype') if not self.is_ongoing(tdoc): if ctype == 'contest': raise error.ContestNotLiveError(tdoc['doc_id']) elif ctype == 'homework': raise error.HomeworkNotLiveError(tdoc['doc_id']) else: raise error.InvalidArgumentError('ctype') if pid not in tdoc['pids']: raise error.ProblemNotFoundError(self.domain_id, pid, tdoc['doc_id']) # TODO(tc-imba): only constant.record.CODE_TYPE_TAR is supported now rid = await record.add(self.domain_id, pdoc['doc_id'], constant.record.TYPE_SUBMISSION, self.user['_id'], lang, code, tid=tdoc['doc_id'], hidden=False, code_type=constant.record.CODE_TYPE_TAR) await contest.update_status(self.domain_id, tdoc['doc_id'], self.user['_id'], rid, pdoc['doc_id'], False, 0) if not self.can_show_record(tdoc): self.json_or_redirect( self.reverse_url('contest_detail', ctype=ctype, tid=tdoc['doc_id'])) else: self.json_or_redirect(self.reverse_url('record_detail', rid=rid))
async def post(self, *, tid: objectid.ObjectId, title: str, content: str, rule: int, begin_at_date: str=None, begin_at_time: str=None, duration: float, pids: str): tdoc = await contest.get(self.domain_id, tid) if not self.own(tdoc, builtin.PERM_EDIT_CONTEST_SELF): self.check_perm(builtin.PERM_EDIT_CONTEST) if self.is_live(tdoc) or self.is_done(tdoc): if begin_at_date: raise error.ValidationError('begin_at_date') if begin_at_time: raise error.ValidationError('begin_at_time') begin_at = tdoc['begin_at'] else: try: begin_at = datetime.datetime.strptime(begin_at_date + ' ' + begin_at_time, '%Y-%m-%d %H:%M') begin_at = self.timezone.localize(begin_at).astimezone(pytz.utc).replace(tzinfo=None) except ValueError as e: raise error.ValidationError('begin_at_date', 'begin_at_time') end_at = begin_at + datetime.timedelta(hours=duration) if begin_at >= end_at: raise error.ValidationError('duration') # not allow removing existing problems pid_set = set(map(document.convert_doc_id, pids.split(','))) if self.is_live(tdoc) or self.is_done(tdoc): old_set = set(tdoc['pids']) if not old_set <= pid_set: raise error.ValidationError('pids') pids = list(pid_set) pdocs = await problem.get_multi(domain_id=self.domain_id, doc_id={'$in': pids}, fields={'doc_id': 1}) \ .sort('doc_id', 1) \ .to_list() exist_pids = [pdoc['doc_id'] for pdoc in pdocs] if len(pids) != len(exist_pids): for pid in pids: if pid not in exist_pids: raise error.ProblemNotFoundError(self.domain_id, pid) # TODO(twd2): further checks for editing? await contest.edit(self.domain_id, tdoc['doc_id'], title=title, content=content, rule=rule, begin_at=begin_at, end_at=end_at, pids=pids) for pid in pids: await problem.set_hidden(self.domain_id, pid, True) self.json_or_redirect(self.reverse_url('contest_detail', tid=tdoc['doc_id']))
async def get(self, *, ctype: str, tid: objectid.ObjectId, pid: document.convert_doc_id): doc_type = constant.contest.CTYPE_TO_DOCTYPE[ctype] uid = self.user['_id'] if self.has_priv( builtin.PRIV_USER_PROFILE) else None tdoc, pdoc = await asyncio.gather( contest.get(self.domain_id, doc_type, tid), problem.get(self.domain_id, pid, uid)) tsdoc, udoc = await asyncio.gather( contest.get_status(self.domain_id, doc_type, tdoc['doc_id'], self.user['_id']), user.get_by_uid(tdoc['owner_uid'])) attended = tsdoc and tsdoc.get('attend') == 1 if not self.is_finished(tdoc): if not attended: if ctype == 'contest': raise error.ContestNotAttendedError(tdoc['doc_id']) elif ctype == 'homework': raise error.HomeworkNotAttendedError(tdoc['doc_id']) else: raise error.InvalidArgumentError('ctype') if not self.is_ongoing(tdoc): if ctype == 'contest': raise error.ContestNotLiveError(tdoc['doc_id']) elif ctype == 'homework': raise error.HomeworkNotLiveError(tdoc['doc_id']) else: raise error.InvalidArgumentError('ctype') if pid not in tdoc['pids']: raise error.ProblemNotFoundError(self.domain_id, pid, tdoc['doc_id']) path_components = self.build_path( (self.translate('page.contest_main.{0}.title'.format(ctype)), self.reverse_url('contest_main', ctype=ctype)), (tdoc['title'], self.reverse_url('contest_detail', ctype=ctype, tid=tid)), (pdoc['title'], None)) self.render('problem_detail.html', tdoc=tdoc, pdoc=pdoc, tsdoc=tsdoc, udoc=udoc, attended=attended, page_title=pdoc['title'], path_components=path_components)
async def get(self, *, ctype: str, tid: objectid.ObjectId, pid: document.convert_doc_id): doc_type = constant.contest.CTYPE_TO_DOCTYPE[ctype] uid = self.user['_id'] if self.has_priv( builtin.PRIV_USER_PROFILE) else None tdoc, pdoc = await asyncio.gather( contest.get(self.domain_id, doc_type, tid), problem.get(self.domain_id, pid, uid)) tsdoc, udoc = await asyncio.gather( contest.get_status(self.domain_id, doc_type, tdoc['doc_id'], self.user['_id']), user.get_by_uid(tdoc['owner_uid'])) attended = tsdoc and tsdoc.get('attend') == 1 if not attended: if ctype == 'contest': raise error.ContestNotAttendedError(tdoc['doc_id']) elif ctype == 'homework': raise error.HomeworkNotAttendedError(tdoc['doc_id']) else: raise error.InvalidArgumentError('ctype') if not self.is_ongoing(tdoc): if ctype == 'contest': raise error.ContestNotLiveError(tdoc['doc_id']) elif ctype == 'homework': raise error.HomeworkNotLiveError(tdoc['doc_id']) else: raise error.InvalidArgumentError('ctype') if pid not in tdoc['pids']: raise error.ProblemNotFoundError(self.domain_id, pid, tdoc['doc_id']) if self.can_show_record(tdoc): rdocs = await record.get_user_in_problem_multi(uid, self.domain_id, pdoc['doc_id'], get_hidden=True) \ .sort([('_id', -1)]) \ .limit(10) \ .to_list() else: rdocs = [] if not self.prefer_json: path_components = self.build_path( (self.translate('page.contest_main.{0}.title'.format(ctype)), self.reverse_url('contest_main', ctype=ctype)), (tdoc['title'], self.reverse_url('contest_detail', ctype=ctype, tid=tid)), (pdoc['title'], self.reverse_url( 'contest_detail_problem', ctype=ctype, tid=tid, pid=pid)), (self.translate('page.contest_detail_problem_submit.{0}.title'. format(ctype)), None)) languages = filter_language(pdoc.get('languages') or []) default_lang = len(languages) and list(languages.keys())[0] or '' self.render('problem_submit.html', tdoc=tdoc, pdoc=pdoc, rdocs=rdocs, tsdoc=tsdoc, udoc=udoc, attended=attended, page_title=pdoc['title'], path_components=path_components, languages=languages, default_lang=default_lang) else: self.json({'rdocs': rdocs})