Example #1
0
 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))
Example #2
0
 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))
Example #3
0
 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)
Example #4
0
 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))
Example #5
0
 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))
Example #6
0
 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))
Example #7
0
 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})
Example #8
0
 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})
Example #9
0
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']
Example #10
0
 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
Example #11
0
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
Example #12
0
    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'))
Example #13
0
 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))
Example #14
0
 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']))
Example #15
0
 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)
Example #16
0
 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})