async def create_exam_action( request: Request, subjects: Subjects = Depends(deps.get_subjects), current_user: schema.UserPayload = Depends(deps.get_current_user) ) -> Any: form = await request.form() if await apifunc.exam_get_by_tag(form['tag']): return templates.TemplateResponse('manager/create-exam.jinja2', { 'request': request, 'current_user': current_user, 'message': '考试标签重复' }) # start_time = datetime.fromisoformat(form['start_time']) # end_time = datetime.fromisoformat(form['end_time']) start_time = form['start_time_date'] + 'T' + form['start_time_time'] end_time = form['end_time_date'] + 'T' + form['end_time_time'] created_exam = await apifunc.exam_create(title=form['title'], tag=form['tag'], type=form['type'], subject=form['subject'], question_count=int( form['question_count']), start_time=start_time, end_time=end_time, detail=form['detail']) return templates.TemplateResponse( 'manager/create-exam.jinja2', { 'request': request, 'current_user': current_user, 'subjects': subjects, 'created_exam': created_exam })
async def login_action( request: Request, current_user: Optional[UserPayload] = Depends(deps.get_current_user) ) -> Any: if current_user: if current_user.exp > time.time(): return RedirectResponse(request.url_for('index')) form = await request.form() if 'username' not in form and 'password' not in form: return templates.TemplateResponse('login.jinja2', {'request': request}) if not (username := form.get('username', None)): return templates.TemplateResponse('login.jinja2', { 'request': request, 'message': '请输入用户名' })
async def get_answer_random( request: Request, subjects: Subjects = Depends(deps.get_subjects), current_user: schema.UserPayload = Depends(deps.get_current_user) ) -> Any: """ Render answer page according to the answer selected in paper """ form = await request.form() if 'qid' not in form or 'picked' not in form: return RedirectResponse(request.url_for('index')) qid = form['qid'] picked = form['picked'] subject = form['subject'] if picked not in list('ABCD'): raise HTTPException(status_code=400, detail='Bad picked') question = await apifunc.get_answer(qid) await userfunc.create_answer_cache(username=current_user.name, question_id=question['id'], picked=picked, paper_type='random', subject=subject) return templates.TemplateResponse( 'answer/practice_random.jinja2', { 'request': request, 'subjects': subjects, 'current_user': current_user, 'question': question, 'picked': picked, 'subject': subject })
async def exam_entry( request: Request, current_user: schema.UserPayload = Depends(deps.get_current_user) ) -> Any: exams = await apifunc.exam_fetchall() unstarted_exams: list[dict] = [] processing_exams: list[dict] = [] finished_exams: list[dict] = [] for exam in exams: exam['start_time'] = datetime.fromisoformat(exam['start_time']) exam['end_time'] = datetime.fromisoformat(exam['end_time']) if exam['start_time'] > datetime.now(): unstarted_exams.append(exam) if exam['end_time'] < datetime.now(): finished_exams.append(exam) if exam['start_time'] < datetime.now() < exam['end_time']: processing_exams.append(exam) for exam in exams: exam['start_time'] = datetime.strftime(exam['start_time'], '%F %X') exam['end_time'] = datetime.strftime(exam['end_time'], '%F %X') return templates.TemplateResponse( 'exam/entry.jinja2', { 'request': request, 'current_user': current_user, 'unstarted_exams': unstarted_exams, 'processing_exams': processing_exams, 'finished_exams': finished_exams })
async def manage_inspect_user_exam( request: Request, username: str, exam_tag: str, q_num: int, current_user: UserPayload = Depends(deps.get_current_user)) -> Any: user, exam, exam_status = await asyncio.gather( userfunc.get_by_name(username), apifunc.exam_get_by_tag(exam_tag), apifunc.exam_paper_status(username, exam_tag)) if not user: raise HTTPException(status_code=400, detail='Bad username') if not exam: raise HTTPException(status_code=400, detail='Bad exam tag') if not (0 < q_num <= exam['question_count']): raise HTTPException(status_code=404) if not (exam_status or exam_status.get('status') != 2): raise HTTPException(status_code=200, detail='考试未完成,无法查看') exam_records = await apifunc.exam_paper_fetchall(username=username, exam_tag=exam_tag) exam_record = exam_records[q_num - 1] question_list = await apifunc.get_answer_many( [i['question_id'] for i in exam_records]) question = await apifunc.get_answer(question_list[q_num - 1]['question_id'] ) return templates.TemplateResponse( 'answer/exam.jinja2', { 'request': request, 'current_user': current_user, 'question': question, 'question_list': question_list, 'exam': exam, 'exam_records': exam_records, 'picked': exam_record['picked'] })
async def login( request: Request, current_user: Optional[UserPayload] = Depends(deps.get_current_user) ) -> Any: if not current_user: return templates.TemplateResponse('login.jinja2', {'request': request}) if current_user.exp > time.time(): return RedirectResponse(request.url_for('index'))
async def create_exam( request: Request, current_user: schema.UserPayload = Depends(deps.get_current_user) ) -> Any: return templates.TemplateResponse('manager/create-exam.jinja2', { 'request': request, 'current_user': current_user })
async def manage_list_userinfo( request: Request, current_user: UserPayload = Depends(deps.get_current_user) ) -> Any: users = await userfunc.get_all_user() return templates.TemplateResponse('manager/user-statusboard.jinja2', { 'request': request, 'current_user': current_user, 'users': users })
async def delete_exam( request: Request, tag: str, current_user: schema.UserPayload = Depends(deps.get_current_user) ) -> Any: return templates.TemplateResponse( 'manager/check.jinja2', { 'request': request, 'current_user': current_user, 'check_delete_exam': True })
async def change_password( request: Request, username: str, current_user: schema.UserPayload = Depends(deps.get_current_user) ) -> Any: if current_user.name == username: return templates.TemplateResponse( 'user/change-password.jinja2', { 'request': request, 'current_user': current_user } ) return RedirectResponse(request.url_for('homepage'))
async def homepage( request: Request, username: str, current_user: schema.UserDetail = Depends(deps.get_current_user_detail) ) -> Any: if current_user.name == username: return templates.TemplateResponse( 'user/homepage.jinja2', { 'request': request, 'current_user': current_user } ) return RedirectResponse(request.url_for('index'))
async def manage_list_user_exams( request: Request, username: str, subjects: Subjects = Depends(deps.get_subjects), current_user: UserPayload = Depends(deps.get_current_user) ) -> Any: if not await userfunc.get_by_name(username): raise HTTPException(status_code=400, detail='Bad username') userexams = await read_exams(username) return templates.TemplateResponse( 'user/myexams.jinja2', { "request": request, "current_user": current_user, "subjects": subjects, "myexams": userexams })
async def tiku_area_index( request: Request, subjects: Subjects = Depends(deps.get_subjects), current_user: UserPayload = Depends(deps.get_current_user) ) -> Any: """ Render index page, but not the final index page """ return templates.TemplateResponse( 'area/base.jinja2', { 'request': request, 'current_user': current_user, 'subjects': subjects } )
async def my_exams( request: Request, username: str, subjects: Subjects = Depends(deps.get_subjects), current_user: schema.UserPayload = Depends(deps.get_current_user) ) -> Any: if not current_user.name == username: return RedirectResponse(request.url_for('homepage')) myexams = await read_exams(username) return templates.TemplateResponse( 'user/myexams.jinja2', { 'request': request, 'subjects': subjects, 'current_user': current_user, 'myexams': myexams } )
async def read_exam( request: Request, tag: str, subjects: Subjects = Depends(deps.get_subjects), current_user: schema.UserDetail = Depends(deps.get_current_user) ) -> Any: if not await apifunc.exam_get_by_tag(tag=tag): raise HTTPException(status_code=400, detail='无此考试标签') exam = await apifunc.exam_get_by_tag(tag) return templates.TemplateResponse( 'manager/create-exam.jinja2', { 'request': request, 'current_user': current_user, 'subjects': subjects, 'created_exam': exam, 'is_read_exam': True, })
async def tiku_paper_random( request: Request, subject: str, subjects: Subjects = Depends(deps.get_subjects), current_user: UserPayload = Depends(deps.get_current_user) ) -> Any: """ Render random question-select practice page """ if subject not in subjects.aliases: raise HTTPException(status_code=404, detail='Subject not found') question = await apifunc.get_question_by_subject(subject, is_random=True) return templates.TemplateResponse( 'paper/practice_random.jinja2', { 'request': request, 'current_user': current_user, 'question': question, 'subjects': subjects })
async def get_answer_order( request: Request, subjects: Subjects = Depends(deps.get_subjects), current_user: schema.UserPayload = Depends(deps.get_current_user) ) -> Any: """ Render answer page according to the answer selected in paper """ form = await request.form() qid = form['qid'] picked = form['picked'] subject = form['subject'] order = form['order'] if picked not in list('ABCD'): raise HTTPException(status_code=400, detail='Bad picked') await userfunc.create_answer_cache(username=current_user.name, question_id=qid, picked=picked, paper_type='order', subject=subject) question_list, question, answer_records = await asyncio.gather( apifunc.get_question_by_subject(subject, full=True, is_simple=True), apifunc.get_answer(qid), userfunc.read_answer_caches(current_user.name, unique=True)) done_qid_set = set({d['question_id'] for d in answer_records}) for d in question_list: if d['question_id'] in done_qid_set: d.update({ 'picked': i['picked'] for i in answer_records if i['question_id'] == d['question_id'] }) return templates.TemplateResponse( 'answer/practice_order.jinja2', { 'request': request, 'subjects': subjects, 'current_user': current_user, 'question': question, 'picked': picked, 'subject': subjects.get_item(subject), 'question_order': int(order), 'question_list': question_list, 'answer_records': answer_records })
async def update_exam( request: Request, tag: str, subjects: Subjects = Depends(deps.get_subjects), current_user: schema.UserPayload = Depends(deps.get_current_user) ) -> Any: if not await apifunc.exam_get_by_tag(tag=tag): raise HTTPException(status_code=400, detail='无此考试标签') to_update = await apifunc.exam_get_by_tag(tag) to_update['start_time_date'], to_update['start_time_time'] = to_update[ 'start_time'].split('T', 1) to_update['end_time_date'], to_update['end_time_time'] = to_update[ 'end_time'].split('T', 1) return templates.TemplateResponse( 'manager/create-exam.jinja2', { 'request': request, 'current_user': current_user, 'subjects': subjects, 'to_update': to_update })
async def change_password_action( request: Request, username: str, current_user: schema.UserPayload = Depends(deps.get_current_user) ) -> Any: if current_user.name == username: form = await request.form() if form.get('password_new') != form.get('password_new_check'): return templates.TemplateResponse( 'user/change-password.jinja2', { 'request': request, 'current_user': current_user, 'message': '两个密码不同,请重新输入' } ) await userfunc.change_password(current_user.uid, form.get('password_new')) rr = RedirectResponse(request.url_for('login')) rr.set_cookie('jwt', value='deleted', expires=0) return rr return RedirectResponse(request.url_for('homepage'))
async def tiku_area( request: Request, subject: str, subjects: Subjects = Depends(deps.get_subjects), current_user: UserPayload = Depends(deps.get_current_user) ) -> Any: """ Enter the selected subject navigation page """ if subject not in subjects.aliases: raise HTTPException(status_code=404, detail='Subject not found') done_count: dict = await userfunc.read_answered_count(current_user.name) return templates.TemplateResponse( 'area/subject.jinja2', { 'request': request, 'current_user': current_user, 'subjects': subjects, 'done_count': done_count } )
async def exam_answer( request: Request, tag: str, q_num: int, current_user: schema.UserPayload = Depends(deps.get_current_user) ) -> Any: if current_user.is_superuser: raise HTTPException(status_code=200, detail='管理员无法考试') exam, exam_status = await asyncio.gather( apifunc.exam_get_by_tag(tag), apifunc.exam_paper_status(current_user.name, tag)) if not exam: raise HTTPException(status_code=404) if not (0 < q_num <= exam['question_count']): raise HTTPException(status_code=404) if not (exam_status or exam_status.get('status') != 2): return RedirectResponse(request.url_for('exam_paper_answering', tag=tag, q_num=q_num), status_code=303) exam_records = await apifunc.exam_paper_fetchall( username=current_user.name, exam_tag=tag) exam_record = exam_records[q_num - 1] question_list = await apifunc.get_answer_many( [i['question_id'] for i in exam_records]) question = await apifunc.get_answer(question_list[q_num - 1]['question_id'] ) return templates.TemplateResponse( 'answer/exam.jinja2', { 'request': request, 'current_user': current_user, 'question': question, 'question_list': question_list, 'exam': exam, 'exam_records': exam_records, 'picked': exam_record['picked'] })
async def tiku_paper_order( request: Request, subject: str, order: int, subjects: Subjects = Depends(deps.get_subjects), current_user: UserPayload = Depends(deps.get_current_user) ) -> Any: """ order practice page """ if subject not in subjects.aliases: raise HTTPException(status_code=404, detail='Subject not found') subject_dict = subjects.get_item(subject) if not (0 < order <= subject_dict['question_count']): raise HTTPException(status_code=404, detail='Order exceeded') question_list, question, answer_records = await asyncio.gather( apifunc.get_question_by_subject(subject, full=True, is_simple=True), apifunc.get_question_by_order(subject, order), userfunc.read_answer_caches(current_user.name, unique=True)) if len(question_list) < subject_dict['question_count']: raise HTTPException(status_code=200, detail='内部数据校对错误') done_qid_set = set({d['question_id'] for d in answer_records}) for d in question_list: if d['question_id'] in done_qid_set: d.update({ 'picked': i['picked'] for i in answer_records if i['question_id'] == d['question_id'] }) return templates.TemplateResponse( 'paper/practice_order.jinja2', { 'request': request, 'current_user': current_user, 'subjects': subjects, 'question': question, 'question_list': question_list, 'answer_records': answer_records })
async def exam_paper_answering( request: Request, tag: str, q_num: int, current_user: schema.UserPayload = Depends(deps.get_current_user) ) -> Any: """ select question from database according to the question_order column """ if current_user.is_superuser: raise HTTPException(status_code=200, detail='管理员无法考试') exam, exam_status, exam_cache_one = await asyncio.gather( apifunc.exam_get_by_tag(tag), apifunc.exam_paper_status(current_user.name, tag), apifunc.exam_paper_fetchone(username=current_user.name, exam_tag=tag)) if not exam: raise HTTPException(status_code=404) start_time = datetime.fromisoformat(exam['start_time']) end_time = datetime.fromisoformat(exam['end_time']) if not (start_time < datetime.now() < end_time): raise HTTPException(status_code=403, detail='考试尚未开始或已经结束') if q_num > exam['question_count']: raise HTTPException(status_code=404) if exam_status and exam_status.get('status') == 2: return RedirectResponse(request.url_for('exam_answer', tag=tag, q_num=1), status_code=303) if not exam_cache_one: await apifunc.exam_paper_create(username=current_user.name, exam_tag=tag) # update database picked if request.method == 'POST': form = await request.form() await apifunc.exam_paper_update_picked(username=current_user.name, exam_tag=tag, question_id=form['id'], picked=form['picked']) # last question then do nothing if q_num == exam['question_count']: return RedirectResponse(request.url_for('exam_paper_answering', tag=tag, q_num=q_num), status_code=303) return RedirectResponse(request.url_for('exam_paper_answering', tag=tag, q_num=q_num + 1), status_code=303) exam_records = await apifunc.exam_paper_fetchall( username=current_user.name, exam_tag=tag) exam_record = exam_records[q_num - 1] question = await apifunc.get_question_by_id(exam_record['question_id']) return templates.TemplateResponse( 'paper/exam.jinja2', { 'request': request, 'current_user': current_user, 'exam': exam, 'question': question, 'exam_records': exam_records, 'exam_picked': exam_record['picked'] })
if exams: for exam in exams: start_time = datetime.fromisoformat(exam['start_time']) end_time = datetime.fromisoformat(exam['end_time']) exam['start_time'] = exam['start_time'].replace('T', ' ') exam['end_time'] = exam['end_time'].replace('T', ' ') if timenow := datetime.now(): if start_time < timenow < end_time: exam['opening_status'] = '进行中' elif timenow > end_time: exam['opening_status'] = '已结束' else: exam['opening_status'] = '未开始' return templates.TemplateResponse('manager/list-exam.jinja2', { 'request': request, 'current_user': current_user, 'exams': exams, }) @router.get('/{tag}/read') @superuser_required async def read_exam( request: Request, tag: str, subjects: Subjects = Depends(deps.get_subjects), current_user: schema.UserDetail = Depends(deps.get_current_user) ) -> Any: if not await apifunc.exam_get_by_tag(tag=tag): raise HTTPException(status_code=400, detail='无此考试标签') exam = await apifunc.exam_get_by_tag(tag)
) -> Any: if current_user: if current_user.exp > time.time(): return RedirectResponse(request.url_for('index')) form = await request.form() if 'username' not in form and 'password' not in form: return templates.TemplateResponse('login.jinja2', {'request': request}) if not (username := form.get('username', None)): return templates.TemplateResponse('login.jinja2', { 'request': request, 'message': '请输入用户名' }) if not (password := form.get('password', None)): return templates.TemplateResponse('login.jinja2', { 'request': request, 'message': '请输入密码' }) content = await authfunc.access_token(username, password) if isinstance(content, str): return templates.TemplateResponse('login.jinja2', { 'request': request, 'message': content }) rr = RedirectResponse(request.url_for('tiku_area_index'), status_code=303) rr.set_cookie(key='jwt', value=content.access_token, httponly=True, samesite='strict',
def home(request: Request): return templates.TemplateResponse('home.html', {'request': request})