Ejemplo n.º 1
0
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
        })
Ejemplo n.º 2
0
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': '请输入用户名'
        })
Ejemplo n.º 3
0
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
        })
Ejemplo n.º 4
0
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
        })
Ejemplo n.º 5
0
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']
        })
Ejemplo n.º 6
0
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'))
Ejemplo n.º 7
0
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
    })
Ejemplo n.º 8
0
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
    })
Ejemplo n.º 9
0
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
        })
Ejemplo n.º 10
0
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'))
Ejemplo n.º 11
0
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'))
Ejemplo n.º 12
0
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
        })
Ejemplo n.º 13
0
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
        }
    )
Ejemplo n.º 14
0
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
        }
    )
Ejemplo n.º 15
0
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,
        })
Ejemplo n.º 16
0
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
        })
Ejemplo n.º 17
0
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
        })
Ejemplo n.º 18
0
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
        })
Ejemplo n.º 19
0
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'))
Ejemplo n.º 20
0
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
        }
    )
Ejemplo n.º 21
0
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']
        })
Ejemplo n.º 22
0
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
        })
Ejemplo n.º 23
0
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']
        })
Ejemplo n.º 24
0
    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)
Ejemplo n.º 25
0
) -> 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',
Ejemplo n.º 26
0
def home(request: Request):
    return templates.TemplateResponse('home.html', {'request': request})