Example #1
0
async def add_reply(domain_id: str, did: objectid.ObjectId, owner_uid: int,
                    content: str):
    validator.check_content(content)
    coll = db.Collection('discussion')
    coll_reply = db.Collection('discussion.reply')
    drdoc, _ = await asyncio.gather(
        coll_reply.insert_one({
            'domain_id': domain_id,
            'content': content,
            'owner_uid': owner_uid,
            'parent_type': 'discussion',
            'parent_id': did
        }),
        coll.find_one_and_update(filter={
            'domain_id': domain_id,
            '_id': did
        },
                                 update={
                                     '$inc': {
                                         'num_replies': 1
                                     },
                                     '$set': {
                                         'update_at':
                                         datetime.datetime.utcnow()
                                     }
                                 },
                                 return_document=ReturnDocument.AFTER))
    return drdoc
Example #2
0
async def create_indexes():
    coll = db.Collection('problem')
    await coll.create_index([('domain_id', 1),
                             ('_id', 1)], unique=True)
    await coll.create_index([('domain_id', 1),
                             ('owner_uid', 1),
                             ('_id', -1)])
    await coll.create_index([('domain_id', 1),
                             ('category', 1),
                             ('_id', 1)], sparse=True)
    await coll.create_index([('domain_id', 1),
                             ('hidden', 1),
                             ('category', 1),
                             ('_id', 1)], sparse=True)
    await coll.create_index([('domain_id', 1),
                             ('tag', 1),
                             ('_id', 1)], sparse=True)
    await coll.create_index([('domain_id', 1),
                             ('hidden', 1),
                             ('tag', 1),
                             ('_id', 1)], sparse=True)

    status_coll = db.Collection('problem.status')
    await status_coll.create_index([('domain_id', 1),
                                    ('uid', 1),
                                    ('pid', 1)], unique=True)
Example #3
0
async def attend(domain_id: str, tid: int, uid: int):
    #  TODO: check time.
    coll = db.Collection('contest.status')
    try:
        await coll.find_one_and_update(filter={
            'domain_id': domain_id,
            'tid': tid,
            'uid': uid,
            'attend': {
                '$eq': 0
            }
        },
                                       update={'$set': {
                                           'attend': 1
                                       }},
                                       upsert=True,
                                       return_document=ReturnDocument.AFTER)
    except errors.DuplicateKeyError:
        raise error.ContestAlreadyAttendedError(domain_id, tid, uid) from None
    coll = db.Collection('contest')
    return await coll.find_one_and_update(filter={
        'domain_id': domain_id,
        '_id': tid
    },
                                          update={'$inc': {
                                              'attend': 1
                                          }},
                                          return_document=ReturnDocument.AFTER)
Example #4
0
async def create_indexes():
    coll = db.Collection('domain')
    await coll.create_index('owner_uid')
    user_coll = db.Collection('domain.user')
    await user_coll.create_index('uid')
    await user_coll.create_index([('domain_id', 1), ('uid', 1)], unique=True)
    await user_coll.create_index([('domain_id', 1), ('role', 1)], sparse=True)
Example #5
0
async def add_tail_reply(domain_id: str, drid: objectid.ObjectId,
                         owner_uid: int, content: str):
    validator.check_content(content)
    sid = objectid.ObjectId()
    coll = db.Collection('discussion.reply')
    drdoc = await coll.find_one_and_update(
        filter={
            'domain_id': domain_id,
            '_id': drid
        },
        update={
            '$push': {
                'reply': {
                    '_id': sid,
                    'owner_uid': owner_uid,
                    'content': content
                }
            }
        },
        return_document=ReturnDocument.AFTER)
    coll = db.Collection('discussion')
    await coll.find_one_and_update(
        filter={
            'domain_id': domain_id,
            '_id': drdoc['parent_id']
        },
        update={'$set': {
            'update_at': datetime.datetime.utcnow()
        }},
        return_document=ReturnDocument.AFTER)
    return drdoc, sid
Example #6
0
async def delete_roles(domain_id: str, roles):
    roles = list(set(roles))
    for role in roles:
        validator.check_role(role)
    for domain in builtin.DOMAINS:
        if domain['_id'] == domain_id:
            raise error.BuiltinDomainError(domain_id)
    user_coll = db.Collection('domain.user')
    await user_coll.update_many(
        {
            'domain_id': domain_id,
            'role': {
                '$in': list(roles)
            }
        }, {'$unset': {
            'role': ''
        }})
    coll = db.Collection('domain')
    return await coll.find_one_and_update(filter={'_id': domain_id},
                                          update={
                                              '$unset':
                                              dict(('roles.{0}'.format(role),
                                                    '') for role in roles)
                                          },
                                          return_document=True)
Example #7
0
async def create_indexes():
    coll = db.Collection('campaign')
    await coll.create_index('owner_uid')
    await coll.create_index([('begin_at', 1), ('end_at', 1)])
    team_coll = db.Collection('campaign.team')
    await team_coll.create_index([('cid', 1), ('uid', 1)], unique=True)
    await team_coll.create_index([('cid', 1), ('members', 1)], sparse=True)
    await team_coll.create_index([('cid', 1), ('team_name', 1)])
Example #8
0
async def attend(campaign_id: str, uid: int, mail: str, tel: str,
                 team_name: str, is_newbie: bool, members: list):
    validator.check_mail(mail)
    validator.check_tel(tel)
    validator.check_team_name(team_name)
    members = list(OrderedSet(members))
    coll = db.Collection('campaign.team')
    try:
        return await coll.find_one_and_update(
            filter={
                'cid': campaign_id,
                'uid': uid
            },
            update={
                '$set': {
                    'mail': mail,
                    'tel': tel,
                    'team_name': team_name,
                    'is_newbie': is_newbie,
                    'members': members
                }
            },
            upsert=True,
            return_document=ReturnDocument.AFTER)
    except errors.DuplicateKeyError:
        raise error.CampaignTeamAlreadyExistError(members, team_name)
Example #9
0
async def rejudge(record_id: objectid.ObjectId, enqueue: bool = True):
    coll = db.Collection('record')
    doc = await coll.find_one_and_update(
        filter={'_id': record_id},
        update={
            '$unset': {
                'judge_uid': '',
                'judge_at': '',
                'compiler_texts': '',
                'judge_texts': '',
                'cases': ''
            },
            '$set': {
                'status': constant.record.STATUS_WAITING,
                'time_ms': 0,
                'memory_kb': 0,
                'rejudged': True
            }
        },
        return_document=False)
    post_coros = []
    pdoc = await problem.get(doc['domain_id'], doc['pid'])
    if pdoc['judge_mode'] == constant.record.MODE_SUBMIT_ANSWER:
        await judge.judge_answer(doc['domain_id'], record_id, pdoc,
                                 doc['code'])
    else:
        post_coros.append(bus.publish('record_change', doc['_id']))
        if enqueue:
            post_coros.append(queue.publish('judge', rid=doc['_id']))
    await asyncio.gather(*post_coros)
Example #10
0
async def get_by_mail(mail: str, fields=PROJECTION_VIEW):
    mail_lower = mail.strip().lower()
    for user in builtin.USERS:
        if user['mail_lower'] == mail_lower:
            return user
    coll = db.Collection('user')
    return await coll.find_one({'mail_lower': mail_lower}, fields)
Example #11
0
async def set_status_balloon(domain_id: str,
                             tid: int,
                             uid: int,
                             pid: int,
                             balloon: bool = True):
    tdoc = await get(domain_id, tid)
    if pid not in tdoc['pids']:
        raise error.ValidationError('pid')

    coll = db.Collection('contest.status')
    tsdoc = await coll.find_one_and_update(
        filter={
            'domain_id': domain_id,
            'tid': tid,
            'uid': uid,
            'detail.pid': pid
        },
        update={'$set': {
            'detail.$.balloon': balloon
        }},
        return_document=ReturnDocument.AFTER)
    udoc = await user.get_by_uid(uid)
    await bus.publish(
        'balloon_change',
        json.encode({
            'uid': uid,
            'uname': udoc['uname'],
            'nickname': udoc.get('nickname', ''),
            'tid': tid,
            'pid': pid,
            'letter': convert_to_letter(tdoc['pids'], pid),
            'balloon': balloon
        }))
    return tsdoc
Example #12
0
async def get_by_uname(uname: str, fields=PROJECTION_VIEW):
    uname_lower = uname.strip().lower()
    for user in builtin.USERS:
        if user['uname_lower'] == uname_lower:
            return user
    coll = db.Collection('user')
    return await coll.find_one({'uname_lower': uname_lower}, fields)
Example #13
0
async def add(domain_id: str,
              title: str,
              content: str,
              owner_uid: int,
              rule: int,
              private: bool,
              begin_at: lambda i: datetime.datetime.utcfromtimestamp(int(i)),
              end_at: lambda i: datetime.datetime.utcfromtimestamp(int(i)),
              pids=[],
              **kwargs):
    validator.check_title(title)
    validator.check_content(content)
    if rule not in RULES:
        raise error.ValidationError('rule')
    if begin_at >= end_at:
        raise error.ValidationError('begin_at', 'end_at')
    # TODO: should we check problem existance here?
    tid = await system.inc_contest_counter()
    coll = db.Collection('contest')
    doc = {
        '_id': tid,
        'domain_id': domain_id,
        'title': title,
        'content': content,
        'owner_uid': owner_uid,
        'rule': rule,
        'private': private,
        'begin_at': begin_at,
        'end_at': end_at,
        'pids': pids,
        'attend': 0,
        **kwargs,
    }
    await coll.insert_one(doc)
    return tid
Example #14
0
async def get_status(domain_id: str, did: objectid.ObjectId, uid: int):
    coll = db.Collection('discussion.status')
    return await coll.find_one({
        'domain_id': domain_id,
        '_id': did,
        'uid': uid
    })
Example #15
0
async def inc(op: str, id: str, period_secs: int, max_operations: int):
    coll = db.Collection('op_count')
    cur_time = int(time.time())
    begin_at = datetime.datetime.utcfromtimestamp(cur_time -
                                                  cur_time % period_secs)
    expire_at = begin_at + datetime.timedelta(seconds=period_secs)
    try:
        doc = await coll.find_one_and_update(filter={
            'id': id,
            'begin_at': begin_at,
            'expire_at': expire_at,
            op: {
                '$not': {
                    '$gte': max_operations
                }
            }
        },
                                             update={'$inc': {
                                                 op: 1
                                             }},
                                             upsert=True,
                                             return_document=True)
        return doc
    except errors.DuplicateKeyError:
        raise error.OpCountExceededError(op, period_secs, max_operations)
Example #16
0
async def unset(domain_id, fields):
    # TODO: check fields.
    coll = db.Collection('domain')
    return await coll.find_one_and_update(
        filter={'_id': domain_id},
        update={'$unset': dict((f, '') for f in set(fields))},
        return_document=True)
Example #17
0
async def delete(fid: objectid.ObjectId):
    doc = await get(fid)
    coll = db.Collection('userfile')
    result = await coll.delete_one({'domain_id': STORE_DOMAIN_ID, '_id': fid})
    result = bool(result.deleted_count)
    if result:
        await fs.unlink(doc['file_id'])
    return result
Example #18
0
async def delete_reply(domain_id: str, drid: objectid.ObjectId):
    drdoc = await get_reply(domain_id, drid)
    if not drdoc:
        return None
    coll = db.Collection('discussion')
    coll_reply = db.Collection('discussion.reply')
    await coll_reply.delete_one({'domain_id': domain_id, '_id': drid})
    await coll.find_one_and_update(filter={
        'domain_id': domain_id,
        'parent_type': drdoc['parent_type'],
        'parent_id': drdoc['parent_id']
    },
                                   update={'$inc': {
                                       'num_replies': -1
                                   }},
                                   return_document=ReturnDocument.AFTER)
    return drdoc
Example #19
0
async def inc_status(domain_id: str, pid: int, uid: int, key: str, value: int):
    coll = db.Collection('problem.status')
    doc = await coll.find_one_and_update(filter={'domain_id': domain_id,
                                                 'pid': pid,
                                                 'uid': uid},
                                         update={'$inc': {key: value}},
                                         return_document=True)
    return doc
Example #20
0
async def rev_init_status(domain_id, pid, uid):
    coll = db.Collection('problem.status')
    return await coll.find_one_and_update(filter={'domain_id': domain_id,
                                                  'pid': pid,
                                                  'uid': uid},
                                          update={'$inc': {'rev': 1}},
                                          upsert=True,
                                          return_document=True)
Example #21
0
async def edit(domain_id: str, did: objectid.ObjectId, **kwargs):
    coll = db.Collection('discussion')
    return await coll.find_one_and_update(filter={
        'domain_id': domain_id,
        '_id': did
    },
                                          update={'$set': kwargs},
                                          return_document=ReturnDocument.AFTER)
Example #22
0
async def get_status(domain_id: str, tid: int, uid: int, projection=None):
    coll = db.Collection('contest.status')
    return await coll.find_one({
        'domain_id': domain_id,
        'tid': tid,
        'uid': uid
    },
                               projection=projection)
Example #23
0
async def create_indexes():
    coll = db.Collection('contest')
    await coll.create_index([('domain_id', 1), ('_id', 1)], unique=True)
    await coll.create_index([('domain_id', 1), ('pids', 1)], sparse=True)
    await coll.create_index([('domain_id', 1), ('rule', 1), ('_id', -1)],
                            sparse=True)
    status_coll = db.Collection('contest.status')
    await status_coll.create_index([('domain_id', 1), ('uid', 1), ('tid', 1)],
                                   unique=True)
    await status_coll.create_index([('domain_id', 1), ('tid', 1),
                                    ('accept', -1), ('time', 1)],
                                   sparse=True)
    await status_coll.create_index([('domain_id', 1), ('tid', 1),
                                    ('detail.accept', 1),
                                    ('detail.balloon', -1)])
    await status_coll.create_index([('domain_id', 1), ('tid', 1), ('uid', 1),
                                    ('detail.pid', 1)],
                                   sparse=True)
Example #24
0
async def add(uname: str,
              password: str,
              mail: str,
              reg_ip: str = '',
              uid: int = None,
              priv: int = builtin.DEFAULT_PRIV,
              **kwargs):
    # Add a user.
    validator.check_uname(uname)
    # TODO: Filter name by keywords
    validator.check_password(password)
    validator.check_mail(mail)

    uname_lower = uname.strip().lower()
    mail_lower = mail.strip().lower()
    if not uid:
        uid = await system.inc_user_counter()

    for user in builtin.USERS:
        if user['_id'] == uid or user['uname_lower'] == uname_lower or user[
                'mail_lower'] == mail_lower:
            raise error.UserAlreadyExistError(uname)

    salt = pwhash.gen_salt()
    coll = db.Collection('user')
    try:
        return (await coll.insert_one({
            '_id':
            uid,
            'uname':
            uname,
            'uname_lower':
            uname_lower,
            'mail':
            mail,
            'mail_lower':
            mail_lower,
            'salt':
            salt,
            'hash':
            pwhash.hash_password(password, salt),
            'reg_at':
            datetime.datetime.utcnow(),
            'reg_ip':
            reg_ip,
            'priv':
            priv,
            'login_at':
            datetime.datetime.utcnow(),
            'login_ip':
            reg_ip,
            'gravatar':
            mail,
            **kwargs
        })).inserted_id
    except errors.DuplicateKeyError:
        raise error.UserAlreadyExistError(uid, uname, mail) from None
Example #25
0
async def remove_status(domain_id: str, tid: int, uid: int):
    tsdoc = await get_status(domain_id, tid, uid)
    if not tsdoc:
        raise error.UserNotFoundError(uid)
    for j in tsdoc['journal']:
        await record.remove_property(j['rid'], 'tid')
    coll = db.Collection('contest.status')
    await coll.delete_one({'domain_id': domain_id, 'tid': tid, 'uid': uid})
    return tsdoc
Example #26
0
async def edit(domain_id: str, did: objectid.ObjectId, **kwargs):
    coll = db.Collection('testdata')
    doc = await coll.find_one_and_update(filter={
        'domain_id': domain_id,
        '_id': did
    },
                                         update={'$set': kwargs},
                                         return_document=True)
    return doc
Example #27
0
async def set_status(domain_id, pid, uid, **kwargs):
    coll = db.Collection('problem.status')
    doc = await coll.find_one_and_update(filter={'domain_id': domain_id,
                                                 'pid': pid,
                                                 'uid': uid},
                                         update={'$set': kwargs},
                                         upsert=True,
                                         return_document=True)
    return doc
Example #28
0
async def rev_set_status(domain_id, pid, uid, rev, **kwargs):
    coll = db.Collection('problem.status')
    return await coll.find_one_and_update(filter={'domain_id': domain_id,
                                                  'pid': pid,
                                                  'uid': uid,
                                                  'rev': rev},
                                          update={'$set': kwargs,
                                                  '$inc': {'rev': 1}},
                                          return_document=True)
Example #29
0
async def unlink(file_id: objectid.ObjectId):
    """Unlink a file."""
    coll = db.Collection('fs.files')
    doc = await coll.find_one_and_update(filter={'_id': file_id},
                                         update={'$inc': {'metadata.link': -1}},
                                         return_document=True)
    if not doc['metadata']['link']:
        fs = db.GridFS('fs')
        await fs.delete(file_id)
Example #30
0
async def inc_user(domain_id, uid, **kwargs):
    coll = db.Collection('domain.user')
    return await coll.find_one_and_update(filter={
        'domain_id': domain_id,
        'uid': uid
    },
                                          update={'$inc': kwargs},
                                          upsert=True,
                                          return_document=True)