Esempio n. 1
0
    async def get(self, *, uid: int):
        is_self_profile = self.has_priv(
            builtin.PRIV_USER_PROFILE) and self.user['_id'] == uid
        udoc = await user.get_by_uid(uid)
        if not udoc:
            raise error.UserNotFoundError(uid)
        dudoc, sdoc = await asyncio.gather(
            domain.get_user(self.domain_id, udoc['_id']),
            token.get_most_recent_session_by_uid(udoc['_id']))

        rdocs = record.get_multi(get_hidden=self.has_priv(
            builtin.PRIV_VIEW_HIDDEN_RECORD),
                                 uid=uid).sort([('_id', -1)])
        rdocs = await rdocs.limit(10).to_list()
        pdict = await problem.get_dict_multi_domain(
            (rdoc['domain_id'], rdoc['pid']) for rdoc in rdocs)

        # check hidden problem
        if not self.has_perm(builtin.PERM_VIEW_PROBLEM_HIDDEN):
            f = {'hidden': False}
        else:
            f = {}
        pdocs = problem.get_multi(domain_id=self.domain_id, owner_uid=uid,
                                  **f).sort([('_id', -1)])
        pcount = await pdocs.count()
        pdocs = await pdocs.limit(10).to_list()

        psdocs = problem.get_multi_solution_by_uid(self.domain_id, uid)
        psdocs_hot = problem.get_multi_solution_by_uid(self.domain_id, uid)
        pscount = await psdocs.count()
        psdocs = await psdocs.limit(10).to_list()
        psdocs_hot = await psdocs_hot.sort([('vote', -1), ('doc_id', -1)]
                                           ).limit(10).to_list()

        if self.has_perm(builtin.PERM_VIEW_DISCUSSION):
            ddocs = discussion.get_multi(self.domain_id, owner_uid=uid)
            dcount = await ddocs.count()
            ddocs = await ddocs.limit(10).to_list()
            vndict = await discussion.get_dict_vnodes(
                self.domain_id, map(discussion.node_id, ddocs))
        else:
            ddocs = []
            vndict = {}
            dcount = 0

        self.render('user_detail.html',
                    is_self_profile=is_self_profile,
                    udoc=udoc,
                    dudoc=dudoc,
                    sdoc=sdoc,
                    rdocs=rdocs,
                    pdict=pdict,
                    pdocs=pdocs,
                    pcount=pcount,
                    psdocs=psdocs,
                    pscount=pscount,
                    psdocs_hot=psdocs_hot,
                    ddocs=ddocs,
                    dcount=dcount,
                    vndict=vndict)
Esempio n. 2
0
File: record.py Progetto: vijos/vj4
async def user_in_problem(uid: int, domain_id: str, pid: document.convert_doc_id):
  psdoc = await document.rev_init_status(domain_id, document.TYPE_PROBLEM, pid, uid)
  rdocs = record.get_multi(uid=uid, domain_id=domain_id, pid=pid,
                           type=constant.record.TYPE_SUBMISSION,
                           fields={'_id': 1, 'uid': 1,
                                   'status': 1, 'score': 1}).sort('_id', 1)
  new_psdoc = {'num_submit': 0, 'status': 0}
  async for rdoc in rdocs:
    new_psdoc['num_submit'] += 1
    if new_psdoc['status'] != constant.record.STATUS_ACCEPTED:
      new_psdoc['status'] = rdoc['status']
      new_psdoc['rid'] = rdoc['_id']
  _logger.info(repr(new_psdoc))
  if await document.rev_set_status(domain_id, document.TYPE_PROBLEM, pid, uid,
                                   psdoc['rev'], **new_psdoc):
    delta_submit = new_psdoc['num_submit'] - psdoc.get('num_submit', 0)
    if new_psdoc['status'] == constant.record.STATUS_ACCEPTED \
       and psdoc.get('status', 0) != constant.record.STATUS_ACCEPTED:
      delta_accept = 1
    elif new_psdoc['status'] != constant.record.STATUS_ACCEPTED \
         and psdoc.get('status', 0) == constant.record.STATUS_ACCEPTED:
      delta_accept = -1
    else:
      delta_accept = 0
    post_coros = []
    if delta_submit != 0:
      post_coros.append(problem.inc(domain_id, pid, 'num_submit', delta_submit))
      post_coros.append(domain.inc_user(domain_id, uid, num_submit=delta_submit))
    if delta_accept != 0:
      post_coros.append(problem.inc(domain_id, pid, 'num_accept', delta_accept))
      post_coros.append(domain.inc_user(domain_id, uid, num_accept=delta_accept))
    if post_coros:
      await asyncio.gather(*post_coros)
Esempio n. 3
0
File: record.py Progetto: vijos/vj4
async def run(domain_id: str):
  _logger.info('Clearing previous statuses')
  await db.coll('document.status').update_many(
    {'domain_id': domain_id, 'doc_type': document.TYPE_PROBLEM},
    {'$unset': {'journal': '', 'rev': '', 'status': '', 'rid': '',
                'num_submit': '', 'num_accept': ''}})
  pdocs = problem.get_multi(domain_id=domain_id, fields={'_id': 1, 'doc_id': 1}).sort('doc_id', 1)
  dudoc_factory = functools.partial(dict, num_submit=0, num_accept=0)
  dudoc_updates = collections.defaultdict(dudoc_factory)
  status_coll = db.coll('document.status')
  async for pdoc in pdocs:
    _logger.info('Problem {0}'.format(pdoc['doc_id']))
    # TODO(twd2): ignore no effect statuses like system error, ...
    rdocs = record.get_multi(domain_id=domain_id, pid=pdoc['doc_id'],
                             type=constant.record.TYPE_SUBMISSION,
                             fields={'_id': 1, 'uid': 1,
                                     'status': 1, 'score': 1}).sort('_id', 1)
    _logger.info('Reading records, counting numbers, updating statuses')
    factory = functools.partial(dict, num_submit=0, num_accept=0, status=0, rid='')
    psdocs = collections.defaultdict(factory)
    pdoc_update = {'num_submit': 0, 'num_accept': 0}
    async for rdoc in rdocs:
      accept = True if rdoc['status'] == constant.record.STATUS_ACCEPTED else False
      pdoc_update['num_submit'] += 1
      psdocs[rdoc['uid']]['num_submit'] += 1
      dudoc_updates[rdoc['uid']]['num_submit'] += 1
      if psdocs[rdoc['uid']]['status'] != constant.record.STATUS_ACCEPTED:
        psdocs[rdoc['uid']]['status'] = rdoc['status']
        psdocs[rdoc['uid']]['rid'] = rdoc['_id']
        if accept:
          pdoc_update['num_accept'] += 1
          dudoc_updates[rdoc['uid']]['num_accept'] += 1
    status_bulk = status_coll.initialize_unordered_bulk_op()
    execute = False
    for uid, psdoc in psdocs.items():
      execute = True
      (status_bulk.find({'domain_id': domain_id, 'doc_type': document.TYPE_PROBLEM,
                         'doc_id': pdoc['doc_id'], 'uid': uid})
       .upsert().update_one({'$set': {**psdoc}}))
    if execute:
      _logger.info('Committing')
      await status_bulk.execute()
    _logger.info('Updating problem')
    await document.set(domain_id, document.TYPE_PROBLEM, pdoc['doc_id'], **pdoc_update)
  # users' num_submit, num_accept
  execute = False
  user_coll = db.coll('domain.user')
  user_bulk = user_coll.initialize_unordered_bulk_op()
  _logger.info('Updating users')
  for uid, dudoc_update in dudoc_updates.items():
    execute = True
    (user_bulk.find({'domain_id': domain_id, 'uid': uid})
     .upsert().update_one({'$set': dudoc_update}))
  if execute:
    _logger.info('Committing')
    await user_bulk.execute()
Esempio n. 4
0
  async def get(self, *, tid: objectid.ObjectId):
    tdoc, tsdocs = await contest.get_and_list_status(self.domain_id, tid)
    rnames = {}
    for tsdoc in tsdocs:
      for pdetail in tsdoc.get('detail', []):
        rnames[pdetail['rid']] = 'U{}_P{}_R{}'.format(tsdoc['uid'], pdetail['pid'], pdetail['rid'])
    output_buffer = io.BytesIO()
    zip_file = zipfile.ZipFile(output_buffer, 'a', zipfile.ZIP_DEFLATED)
    rdocs = record.get_multi(get_hidden=True, _id={'$in': list(rnames.keys())})
    async for rdoc in rdocs:
      zip_file.writestr(rnames[rdoc['_id']] + '.' + rdoc['lang'], rdoc['code'])
    # mark all files as created in Windows :p
    for zfile in zip_file.filelist:
      zfile.create_system = 0
    zip_file.close()

    await self.binary(output_buffer.getvalue(), 'application/zip')
Esempio n. 5
0
async def user_in_problem(uid: int, domain_id: str,
                          pid: document.convert_doc_id):
    psdoc = await document.rev_init_status(domain_id, document.TYPE_PROBLEM,
                                           pid, uid)
    rdocs = record.get_multi(uid=uid,
                             domain_id=domain_id,
                             pid=pid,
                             type=constant.record.TYPE_SUBMISSION,
                             fields={
                                 '_id': 1,
                                 'uid': 1,
                                 'status': 1,
                                 'score': 1
                             }).sort('_id', 1)
    new_psdoc = {'num_submit': 0, 'status': 0}
    async for rdoc in rdocs:
        new_psdoc['num_submit'] += 1
        if new_psdoc['status'] != constant.record.STATUS_ACCEPTED:
            new_psdoc['status'] = rdoc['status']
            new_psdoc['rid'] = rdoc['_id']
    _logger.info(repr(new_psdoc))
    if await document.rev_set_status(domain_id, document.TYPE_PROBLEM, pid,
                                     uid, psdoc['rev'], **new_psdoc):
        delta_submit = new_psdoc['num_submit'] - psdoc.get('num_submit', 0)
        if new_psdoc['status'] == constant.record.STATUS_ACCEPTED \
           and psdoc.get('status', 0) != constant.record.STATUS_ACCEPTED:
            delta_accept = 1
        elif new_psdoc['status'] != constant.record.STATUS_ACCEPTED \
             and psdoc.get('status', 0) == constant.record.STATUS_ACCEPTED:
            delta_accept = -1
        else:
            delta_accept = 0
        post_coros = []
        if delta_submit != 0:
            post_coros.append(
                problem.inc(domain_id, pid, 'num_submit', delta_submit))
            post_coros.append(
                domain.inc_user(domain_id, uid, num_submit=delta_submit))
        if delta_accept != 0:
            post_coros.append(
                problem.inc(domain_id, pid, 'num_accept', delta_accept))
            post_coros.append(
                domain.inc_user(domain_id, uid, num_accept=delta_accept))
        if post_coros:
            await asyncio.gather(*post_coros)
Esempio n. 6
0
File: contest.py Progetto: vijos/vj4
  async def get(self, *, tid: objectid.ObjectId):
    tdoc, tsdocs = await contest.get_and_list_status(self.domain_id, document.TYPE_CONTEST, tid)
    rnames = {}
    for tsdoc in tsdocs:
      for pdetail in tsdoc.get('detail', []):
        rnames[pdetail['rid']] = 'U{}_P{}_R{}'.format(tsdoc['uid'], pdetail['pid'], pdetail['rid'])
    output_buffer = io.BytesIO()
    zip_file = zipfile.ZipFile(output_buffer, 'a', zipfile.ZIP_DEFLATED)
    rdocs = record.get_multi(get_hidden=True, _id={'$in': list(rnames.keys())})
    async for rdoc in rdocs:
      zip_file.writestr(rnames[rdoc['_id']] + '.' + rdoc['lang'], rdoc['code'])
    # mark all files as created in Windows :p
    for zfile in zip_file.filelist:
      zfile.create_system = 0
    zip_file.close()

    await self.binary(output_buffer.getvalue(), 'application/zip',
                      file_name='{}.zip'.format(tdoc['title']))
Esempio n. 7
0
File: user.py Progetto: vijos/vj4
  async def get(self, *, uid: int):
    is_self_profile = self.has_priv(builtin.PRIV_USER_PROFILE) and self.user['_id'] == uid
    udoc = await user.get_by_uid(uid)
    if not udoc:
      raise error.UserNotFoundError(uid)
    dudoc, sdoc = await asyncio.gather(domain.get_user(self.domain_id, udoc['_id']),
                                       token.get_most_recent_session_by_uid(udoc['_id']))

    rdocs = record.get_multi(get_hidden=self.has_priv(builtin.PRIV_VIEW_HIDDEN_RECORD),
                             uid=uid).sort([('_id', -1)])
    rdocs = await rdocs.limit(10).to_list()
    pdict = await problem.get_dict_multi_domain((rdoc['domain_id'], rdoc['pid']) for rdoc in rdocs)

    # check hidden problem
    if not self.has_perm(builtin.PERM_VIEW_PROBLEM_HIDDEN):
      f = {'hidden': False}
    else:
      f = {}
    pdocs = problem.get_multi(domain_id=self.domain_id, owner_uid=uid, **f).sort([('_id', -1)])
    pcount = await pdocs.count()
    pdocs = await pdocs.limit(10).to_list()

    psdocs = problem.get_multi_solution_by_uid(self.domain_id, uid)
    psdocs_hot = problem.get_multi_solution_by_uid(self.domain_id, uid)
    pscount = await psdocs.count()
    psdocs = await psdocs.limit(10).to_list()
    psdocs_hot = await psdocs_hot.sort([('vote', -1), ('doc_id', -1)]).limit(10).to_list()

    if self.has_perm(builtin.PERM_VIEW_DISCUSSION):
      ddocs = discussion.get_multi(self.domain_id, owner_uid=uid)
      dcount = await ddocs.count()
      ddocs = await ddocs.limit(10).to_list()
      vndict = await discussion.get_dict_vnodes(self.domain_id, map(discussion.node_id, ddocs))
    else:
      ddocs = []
      vndict = {}
      dcount = 0

    self.render('user_detail.html', is_self_profile=is_self_profile,
                udoc=udoc, dudoc=dudoc, sdoc=sdoc,
                rdocs=rdocs, pdict=pdict, pdocs=pdocs, pcount=pcount,
                psdocs=psdocs, pscount=pscount, psdocs_hot=psdocs_hot,
                ddocs=ddocs, dcount=dcount, vndict=vndict)
Esempio n. 8
0
 async def get(self, *, uid: int):
     is_self_profile = self.has_priv(
         builtin.PRIV_USER_PROFILE) and self.user['_id'] == uid
     udoc = await user.get_by_uid(uid)
     if not udoc:
         raise error.UserNotFoundError(uid)
     dudoc, sdoc = await asyncio.gather(
         domain.get_user(self.domain_id, udoc['_id']),
         token.get_most_recent_session_by_uid(udoc['_id']))
     email = self.get_udoc_setting(udoc, 'mail')
     if email:
         email = email.replace('@', random.choice([' [at] ', '#']))
     bg = random.randint(1, 21)
     rdocs = record.get_multi(get_hidden=self.has_priv(
         builtin.PRIV_VIEW_HIDDEN_RECORD),
                              uid=uid).sort([('_id', -1)])
     rdocs = await rdocs.limit(10).to_list(None)
     # TODO(twd2): check status, eg. test, hidden problem, ...
     pdocs = problem.get_multi(domain_id=self.domain_id,
                               owner_uid=uid).sort([('_id', -1)])
     pcount = await pdocs.count()
     pdocs = await pdocs.limit(10).to_list(None)
     psdocs = problem.get_multi_solution_by_uid(self.domain_id, uid)
     pscount = await psdocs.count()
     psdocs = await psdocs.limit(10).to_list(None)
     ddocs = discussion.get_multi(self.domain_id, owner_uid=uid)
     dcount = await ddocs.count()
     ddocs = await ddocs.limit(10).to_list(None)
     self.render('user_detail.html',
                 is_self_profile=is_self_profile,
                 udoc=udoc,
                 dudoc=dudoc,
                 sdoc=sdoc,
                 email=email,
                 bg=bg,
                 rdocs=rdocs,
                 pdocs=pdocs,
                 pcount=pcount,
                 psdocs=psdocs,
                 pscount=pscount,
                 ddocs=ddocs,
                 dcount=dcount)
Esempio n. 9
0
    async def _post_homework(self,
                             *,
                             ctype: str,
                             tid: objectid.ObjectId,
                             judge_category: str,
                             system_test_new: bool = False):
        tdoc = await contest.get(self.domain_id, document.TYPE_HOMEWORK, tid)
        if not self.own(tdoc, builtin.PERM_EDIT_HOMEWORK_SELF):
            self.check_perm(builtin.PERM_EDIT_HOMEWORK)
        doc_type = constant.contest.CTYPE_TO_DOCTYPE[ctype]
        judge_category = self.split_tags(judge_category)
        tdoc, tsdocs = await contest.get_and_list_status(
            self.domain_id, doc_type, tid)

        for tsdoc in tsdocs:
            # continue if no record found
            if not tsdoc.get('journal'):
                continue

            rids = list(map(lambda x: x['rid'], tsdoc['journal']))
            rdocs = record.get_multi(get_hidden=True, _id={
                '$in': rids
            }).sort([('_id', -1)])

            # find the newest record to be system tested
            async for rdoc in rdocs:
                if system_test_new and sorted(
                        rdoc['judge_category']) == judge_category:
                    # in system test new mode, records with same judge_category are skipped
                    break
                if len(rdoc['judge_category']) > 0:
                    # records with judge_category are not origin records
                    continue
                rid = await record.system_test(rdoc, judge_category)
                await contest.update_status(self.domain_id, rdoc['tid'],
                                            rdoc['uid'], rid, rdoc['pid'],
                                            False, 0)
                break

        self.json_or_redirect(
            self.reverse_url('contest_detail', ctype=ctype, tid=tid))
Esempio n. 10
0
async def run(domain_id: str):
    _logger.info('Clearing previous statuses')
    await db.Collection('document.status').update_many(
        {
            'domain_id': domain_id,
            'doc_type': document.TYPE_PROBLEM
        }, {
            '$unset': {
                'journal': '',
                'rev': '',
                'status': '',
                'rid': '',
                'num_submit': '',
                'num_accept': ''
            }
        })
    pdocs = problem.get_multi(domain_id=domain_id,
                              fields={
                                  '_id': 1,
                                  'doc_id': 1
                              }).sort('doc_id', 1)
    dudoc_factory = functools.partial(dict, num_submit=0, num_accept=0)
    dudoc_updates = collections.defaultdict(dudoc_factory)
    status_coll = db.Collection('document.status')
    async for pdoc in pdocs:
        _logger.info('Problem {0}'.format(pdoc['doc_id']))
        # TODO(twd2): ignore no effect statuses like system error, ...
        rdocs = record.get_multi(domain_id=domain_id,
                                 pid=pdoc['doc_id'],
                                 type=constant.record.TYPE_SUBMISSION,
                                 fields={
                                     '_id': 1,
                                     'uid': 1,
                                     'status': 1,
                                     'score': 1
                                 }).sort('_id', 1)
        _logger.info('Reading records, counting numbers, updating statuses')
        factory = functools.partial(dict,
                                    num_submit=0,
                                    num_accept=0,
                                    status=0,
                                    rid='')
        psdocs = collections.defaultdict(factory)
        pdoc_update = {'num_submit': 0, 'num_accept': 0}
        async for rdoc in rdocs:
            accept = True if rdoc[
                'status'] == constant.record.STATUS_ACCEPTED else False
            pdoc_update['num_submit'] += 1
            psdocs[rdoc['uid']]['num_submit'] += 1
            dudoc_updates[rdoc['uid']]['num_submit'] += 1
            if psdocs[
                    rdoc['uid']]['status'] != constant.record.STATUS_ACCEPTED:
                psdocs[rdoc['uid']]['status'] = rdoc['status']
                psdocs[rdoc['uid']]['rid'] = rdoc['_id']
                if accept:
                    pdoc_update['num_accept'] += 1
                    dudoc_updates[rdoc['uid']]['num_accept'] += 1
        status_bulk = status_coll.initialize_unordered_bulk_op()
        execute = False
        for uid, psdoc in psdocs.items():
            execute = True
            (status_bulk.find({
                'domain_id': domain_id,
                'doc_type': document.TYPE_PROBLEM,
                'doc_id': pdoc['doc_id'],
                'uid': uid
            }).upsert().update_one({'$set': {
                **psdoc
            }}))
        if execute:
            _logger.info('Committing')
            await status_bulk.execute()
        _logger.info('Updating problem')
        await document.set(domain_id, document.TYPE_PROBLEM, pdoc['doc_id'],
                           **pdoc_update)
    # users' num_submit, num_accept
    execute = False
    user_coll = db.Collection('domain.user')
    user_bulk = user_coll.initialize_unordered_bulk_op()
    _logger.info('Updating users')
    for uid, dudoc_update in dudoc_updates.items():
        execute = True
        (user_bulk.find({
            'domain_id': domain_id,
            'uid': uid
        }).upsert().update_one({'$set': dudoc_update}))
    if execute:
        _logger.info('Committing')
        await user_bulk.execute()