Skip to content

Commit

Permalink
feat(online_judge): 比赛管理
Browse files Browse the repository at this point in the history
  • Loading branch information
XYCode-Kerman committed Apr 15, 2024
1 parent 882c497 commit ede3426
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 3 deletions.
59 changes: 57 additions & 2 deletions online_judge/contests.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,70 @@
import json
import uuid
from datetime import datetime
from pathlib import Path
from typing import *

import fastapi
from fastapi import APIRouter, HTTPException
from fastapi import APIRouter, Body, Depends, HTTPException
from tinydb import Query

import ccf_parser

from .auth import require_role
from .oj_models import OJContest
from .utils import contestscol
from .utils.dependencies import require_ccf_file

router = APIRouter(prefix='/contests', tags=['比赛'])


@router.get('/', name='获取注册在 OJ 中的比赛', response_model=List[OJContest])
async def get_contests():
pass
return contestscol.all()


@router.post('/', name='在 OJ 中注册一个已存在的比赛', response_model=OJContest, dependencies=[Depends(require_role('admin'))])
async def register_contest_to_oj(
start_time: Annotated[datetime, Body()],
end_time: Annotated[datetime, Body()],
ccf_file: Path = Depends(require_ccf_file)
):
oj_contest = OJContest(
contest_id=uuid.uuid4(),
ccf_file=ccf_file,
start_time=start_time,
end_time=end_time
)

doc_id = contestscol.insert(oj_contest.model_dump(mode='json'))

query = Query()
return contestscol.get(doc_id=doc_id)


@router.put('/{contest_id}', name='更新 OJ 中已注册的比赛', response_model=OJContest, dependencies=[Depends(require_role('admin'))])
async def update_contest_in_oj(contest_id: str, contest: OJContest):
query = Query()

doc_id = contestscol.upsert(
contest.model_dump(mode='json'),
query.contest_id == contest_id
)[0]

return contestscol.get(doc_id=doc_id)


@router.delete('/{contest_id}', name='删除 OJ 中已注册的比赛', dependencies=[Depends(require_role('admin'))], responses={
200: {
'description': '成功删除',
'content': {'application/json': {'example': {'status': True}}}
}
})
async def delete_contest_in_oj(contest_id: str):
query = Query()

contestscol.remove(query.contest_id == contest_id)

return {
'status': True
}
2 changes: 1 addition & 1 deletion online_judge/utils/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
from .database import db, usercol
from .database import contestscol, db, usercol
1 change: 1 addition & 0 deletions online_judge/utils/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@
db = TinyDB('./assets/oj_db.json', indent=4,
ensure_ascii=False, sort_keys=True)
usercol = db.table('users')
contestscol = db.table('contests')
1 change: 1 addition & 0 deletions online_judge/utils/dependencies/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from .base import require_ccf_file
25 changes: 25 additions & 0 deletions online_judge/utils/dependencies/base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
from pathlib import Path

import pydantic
from fastapi import HTTPException

from ccf_parser import CCF


def require_ccf_file(ccf_file: Path) -> Path:
if ccf_file.name != "ccf.json":
raise HTTPException(status_code=400, detail="不是一个 CCF 文件")

if not ccf_file.exists():
raise HTTPException(status_code=404, detail="CCF 文件不存在")

if not ccf_file.is_file():
raise HTTPException(status_code=400, detail="不是一个有效的文件")

try:
ccf = CCF.model_validate_json(ccf_file.read_text('utf-8'))
except pydantic.ValidationError as e:
raise HTTPException(
status_code=400, detail=f"CCF 文件格式错误: {e.errors()}")

return ccf_file

0 comments on commit ede3426

Please sign in to comment.