예제 #1
0
def get_score_data():
    # todo: 涉及到QuestionModel.index的引用太乱,需检查并改传入参数名为index,或者改参数使用_id
    question_num = request.args.get('questionNum')
    force = util.str_to_bool(request.args.get('force'))
    if force:
        question = QuestionModel.objects.filter(index=question_num).first()
        analysis = Analysis()
        analysis.re_analysis(question)
    print("get_score_data: questionNum: " + str(question_num))
    analysis_list = AnalysisModel.objects(question_num=question_num)
    if len(analysis_list) == 0:
        return jsonify(errors.success(OptimizeConfig.EMPTY_SCORE_DATA))
    data = {
        'key': [],
        'detail': [],
        'total': [],
        'keyStatistic': {},
        'detailStatistic': {},
        'totalStatistic': {}
    }
    for a in analysis_list:
        if a["score_detail"] != 0 or a["score_key"] != 0:
            data['key'].append(a['score_key'])
            data['detail'].append(a['score_detail'])
            data['total'].append(a["score_detail"] *
                                 ExamConfig.detail_percent +
                                 a["score_key"] * ExamConfig.key_percent)
    algorithm = OptimizeAlgorithm()
    data['keyStatistic'] = algorithm.analysis_score(data['key'],
                                                    ExamConfig.full_score)
    data['detailStatistic'] = algorithm.analysis_score(data['detail'],
                                                       ExamConfig.full_score)
    data['totalStatistic'] = algorithm.analysis_score(data['total'],
                                                      ExamConfig.full_score)
    return jsonify(errors.success(data))
예제 #2
0
def start_auto_optimize():
    question_num = request.form.get("questionNum")
    settings = json.loads(request.form.get("settings"))
    print("start_auto_optimize: questionNum: " + str(question_num))
    print(settings)

    # 重新计算某道题目所有人的击中向量
    question = QuestionModel.objects(index=question_num).first()
    if not question:
        return jsonify(errors.Question_not_exist)
    analysis = Analysis()
    analysis.re_analysis(question)
    # 根据击中向量优化参数
    analysis_list = AnalysisModel.objects(question_num=question_num).order_by(
        'score_key')  # !!!从低到高排序
    if len(analysis_list) == 0:
        return jsonify(errors.success(OptimizeConfig.EMPTY_SCORE_DATA))
    key_hit_mat = []
    for a in analysis_list:
        key_hit_mat.append(a['key_hits'])
    detail_hit_mat = []
    analysis_list = analysis_list.order_by('score_detail')  # !!!从低到高排序
    for a in analysis_list:
        detail_hits = reduce(lambda x, y: x + y, a['detail_hits'])
        detail_hit_mat.append(detail_hits)

    algorithm = GradientDescent(
    ) if settings['algorithm'] == 'gradient' else NormalEquation()
    key_y = algorithm.get_gaussian_array(settings['keyMean'],
                                         settings['keySigma'],
                                         len(key_hit_mat))
    detail_y = algorithm.get_gaussian_array(settings['detailMean'],
                                            settings['detailSigma'],
                                            len(detail_hit_mat))
    settings[
        'theta'] = question['weights']['key'] if settings['reuse'] else None
    # 调用优化方法
    key_theta, key_j = algorithm.optimize_param(key_hit_mat, key_y, settings)
    detail_theta, detail_j = algorithm.optimize_param(detail_hit_mat, detail_y,
                                                      settings)
    # 存储优化结果
    question['weights']['key'] = key_theta
    question['weights']['detail'] = detail_theta
    question['last_optimize_time'] = datetime.datetime.utcnow()
    question['auto_optimized'] = True
    question.save()
    # 存储cost
    optimize = OptimizeModel()
    optimize['question_num'] = question_num
    optimize['wordbase'] = question['wordbase']
    optimize['weights'] = question['weights']
    optimize['key_history_cost'] = key_j
    optimize['detail_history_cost'] = detail_j
    optimize['complete_time'] = datetime.datetime.utcnow()
    optimize['finish'] = True
    optimize.save()
    return jsonify(errors.success())
예제 #3
0
def get_weight_data():
    question_num = request.args.get("questionNum")
    print("get_weight_data: questionNum: " + str(question_num))
    question = QuestionModel.objects(index=question_num).first()
    if not question:
        return jsonify(errors.Question_not_exist)
    data = __question2weight(question)
    data['allHitTimes'] = len(AnalysisModel.objects(question_num=question_num))
    # return jsonify(errors.success(mock_data.weight_data))
    print(errors.success(data))
    return jsonify(errors.success(data))
예제 #4
0
def wxapp_login():
    if current_user.is_authenticated:
        return jsonify(errors.Already_logged_in)

    code = request.form.get('code')
    nick_name = request.form.get('nick_name')
    if not code:
        return jsonify(errors.Params_error)

    resp = user_client.authenticateWechatUser(
        user_thrift.AuthenticateWechatUserRequest(code=code,
                                                  nickName=nick_name))
    if resp is None:
        return jsonify(errors.Internal_error)
    if resp.statusCode != 0:
        return jsonify(
            errors.error({
                'code': resp.statusCode,
                'msg': resp.statusMsg
            }))

    token = resp.token
    payload = jwt.decode(token, "secret", algorithms="HS256")

    return jsonify(
        errors.success({
            'msg': '登录成功',
            "token": token,
            'name': payload["nick_name"],
        }))
예제 #5
0
def find_left_exam():
    """
    获取未完成考试,(断网续测),返回题号
    """
    # _time1 = datetime.datetime.utcnow()
    # 判断断电续做功能是否开启
    if ExamConfig.detect_left_exam:
        # 首先判断是否有未做完的考试
        test_id = ExamSession.get(current_user.id, 'test_id')
        is_testing = ExamSession.get(current_user.id, 'testing')
        if test_id is not None and is_testing == 'True':
            # _time2 = datetime.datetime.utcnow()
            left_exam = CurrentTestModel.objects(id=test_id).first()
            # _time3 = datetime.datetime.utcnow()
            # current_app.logger.info('[TimeDebug][find_left_exam query-db]%s' % (_time3 - _time2))
            if left_exam and left_exam['test_expire_time'] > datetime.datetime.utcnow():
                # 查找到第一个未做的题目
                for key, value in left_exam['questions'].items():
                    status = value['status']
                    if status in ['none', 'question_fetched', 'url_fetched']:
                        current_app.logger.info("[LeftExamFound][find_left_exam]user name: %s, test_id: %s" %
                                                (current_user.name, left_exam.id))
                        return jsonify(errors.info("有未完成的考试", {"next_q_num": key}))  # info是什么鬼??
    current_app.logger.debug("[NoLeftExamFound][find_left_exam]user name: %s" % current_user.name)
    # _time4 = datetime.datetime.utcnow()
    # current_app.logger.info('[TimeDebug][find_left_exam total]%s' % (_time4 - _time1))
    return jsonify(errors.success({"info": "没有未完成的考试"}))
예제 #6
0
def get_all_questions():
    """获取所有第二种类型的题目

    :return: 所有第二种类型的题目题目,可直接展示
    """
    (page, size) = __get_page_and_size_from_request_args(request.args)
    question_type = request.args.get('type')

    resp = question_client.getQuestionList(
        question_thrift.GetQuestionListRequest(
            questionType=int(question_type)
            if question_type is not None else None,
            page=page,
            pageSize=size))
    if resp is None:
        current_app.logger.error(
            "[get_all_questions] question_client.getQuestionInfo failed")
        return jsonify(errors.Internal_error)
    if resp.statusCode != 0:
        return jsonify(
            errors.error({
                'code': resp.statusCode,
                'msg': resp.statusMsg
            }))

    data = []
    for question in resp.questions:
        data.append(question_item_convert_to_json(question))

    return jsonify(errors.success({"count": resp.total, "questions": data}))
예제 #7
0
def modify_question():
    """修改一个问题

    :return:
    """

    index = request.form.get(
        'id')  # todo: change to REST api and change name 'id' to 'index'
    question_data_raw_text = request.form.get('data[rawText]')

    resp = question_client.saveRetellingQuestion(
        question_thrift.SaveRetellingQuestionRequest(
            newQuestion=question_thrift.RetellingQuestion(
                questionIndex=int(index),
                rawText=question_data_raw_text,
                keywords=json.loads(request.form.get('data[keywords]')),
                detailwords=json.loads(request.form.get('data[detailwords]')),
            )))
    if resp is None:
        current_app.logger.error(
            "[modify_question] question_client.SaveRetellingQuestion failed")
        return jsonify(errors.Internal_error)
    if resp.statusCode != 0:
        return jsonify(
            errors.error({
                'code': resp.statusCode,
                'msg': resp.statusMsg
            }))

    return jsonify(errors.success())
예제 #8
0
def wx_get_questions():
    """
    请求参数: nickname, code
    无session,需要返回testID(current记录的id)给前端,之后前端带此testID请求(wx/upload-success)
    """
    nickname = request.args.get("nickname")
    code = request.args.get("code")
    if nickname in ['', None] or code in ['', None]:
        return jsonify(errors.Params_error)
    current_app.logger.info('wx_get_questions: nickname: %s, code: %s, ' %
                            (nickname, code))
    # 使用 code 获取用户的 openid
    err_code, _, openid = wxlp_get_sessionkey_openid(code,
                                                     appid=WxConfig.appid,
                                                     secret=WxConfig.secret)
    # err_code, openid = 0, 'xxx'
    if err_code:
        d = {'err_code': err_code, 'msg': '获取openid出错'}
        return jsonify(errors.error(d))
    current_app.logger.info('wx_get_questions: openid: %s, nickname: %s' %
                            (openid, nickname))

    the_exam = CurrentTestModel.objects(openid=openid).first()  # 因为可能是重复请求
    if the_exam is None or the_exam.questions['9'].status in [
            'handling', 'finished', 'error'
    ]:
        # 创建新的current记录(新的考试)
        current_app.logger.info('wx_get_questions: init exam...')
        the_exam = wx_init_question(openid)
        if not the_exam:
            return jsonify(errors.Init_exam_failed)
    # 按格式包装题目并返回
    context = question_dealer(the_exam)
    return jsonify(errors.success(context))
예제 #9
0
def whoami():
    return jsonify(errors.success({
        'data': {
            'name': current_user.name,
            'email': current_user.email
        }
    }))
예제 #10
0
def get_score_of_specific_questions(index):
    """获取某题目的成绩情况

    :param index: 题号ID
    :return: 该问题的成绩情况
    """
    current_app.logger.info('get_score_of_specific_questions   ' + index)

    cur_question = QuestionModel.objects(index=index).first()
    if not cur_question:
        return jsonify(errors.Score_criteria_not_exist)

    all_answers = AnalysisModel.objects(question_num=index).order_by('date')
    if len(all_answers) == 0:
        return jsonify(errors.Score_no_data)

    mapper = DateMapper()
    result_by_date = __generate_result_from_dict(
        mapper.map_answers(all_answers), 'date')

    result_all = []
    for answer in all_answers:
        result_all.append(
            _generate_total_score(answer['score_key'], answer['score_detail']))

    return jsonify(
        errors.success({
            'resultByDate': result_by_date,
            'allResult': result_all
        }))
예제 #11
0
def get_history_scores(tpl_id="0"):
    resp = exam_client.getExamRecord(
        exam_thrift.GetExamRecordRequest(
            userId=str(current_user.id),
            templateId=tpl_id if tpl_id != "0" else ""))
    if resp is None:
        return jsonify(errors.Internal_error)
    if resp.statusCode != 0:
        return jsonify(
            errors.error({
                'code': resp.statusCode,
                'msg': resp.statusMsg
            }))

    history_scores = []
    for exam_item in resp.examList:
        history_scores.append({
            "test_start_time":
            exam_item.examStartTime,
            "paper_tpl_id":
            exam_item.templateId,
            "test_id":
            exam_item.examId,
            "score_info":
            exam_score_convert_to_json(exam_item.scoreInfo)
        })

    if len(history_scores) == 0:
        return jsonify(errors.No_history)
    return jsonify(errors.success({"history": history_scores}))
예제 #12
0
def admin_get_question():
    question_index = int(request.form.get("questionId"))  # todo: change api and param name
    questions = QuestionModel.objects(index=question_index)
    if len(questions) == 0:
        resp = {"needDisplay": True, "tip": "没有此题号"}
        return jsonify(errors.error(resp))
    question = questions[0]
    if question["q_type"] != 2:
        resp = {"needDisplay": True, "tip": "暂时只支持题型2"}
        return jsonify(errors.error(resp))

    # 生成测试
    test = CurrentTestModel()
    test.user_id = str(current_user.id)
    test.test_start_time = datetime.datetime.utcnow()
    q_current = CurrentQuestionEmbed(q_id=str(question.id), q_type=question.q_type, q_text=question.text,
                                     wav_upload_url='', wav_temp_url='')
    test.questions = {"1": q_current}
    test.save()

    # 保存test id
    # print("[DEBUG] save test id in session when admin get question, test id: %s" % test.id.__str__())
    current_app.logger.debug("save test id in session when admin get question, test id: %s" % test.id.__str__())
    session["test_id"] = test.id.__str__()

    # wrap question
    context = {"questionType": question.q_type,
               "questionNumber": 1,
               "questionLimitTime": ExamConfig.question_limit_time[question.q_type],
               "lastQuestion": True,
               "readLimitTime": ExamConfig.question_prepare_time[question.q_type],
               "questionInfo": QuestionConfig.question_type_tip[question.q_type],
               "questionContent": question.text
               }
    return jsonify(errors.success(json.dumps(context)))
예제 #13
0
def generate_wordbase_by_text():
    """根据原文重新生成关键词和细节词

    :return: 分析后的关键词和细节词
    """
    text = request.form.get('text')
    resp = question_client.generateWordbase(
        question_thrift.GenerateWordbaseRequest(text=text))
    if resp is None:
        current_app.logger.error(
            "[generate_wordbase_by_text] question_client.generateWordbase failed"
        )
        return jsonify(errors.Internal_error)
    if resp.statusCode != 0:
        return jsonify(
            errors.error({
                'code': resp.statusCode,
                'msg': resp.statusMsg
            }))

    return jsonify(
        errors.success({
            "keywords": resp.keywords,
            "detailwords": resp.detailwords
        }))
예제 #14
0
def get_result():
    last_test_id = ExamSession.get(current_user.id, "last_test_id", DefaultValue.test_id)
    if not last_test_id:
        return jsonify(errors.Check_history_results)

    resp = exam_client.getExamResult(exam_thrift.GetExamResultRequest(
        examId=last_test_id
    ))
    if resp is None:
        current_app.logger.error("[get_result] exam_client.getExamResult failed")
        return jsonify(errors.Internal_error)
    if resp.statusCode != 0:
        # 正在处理
        if resp.statusCode == errors.WIP['code']:
            try_times = int(ExamSession.get(current_user.id, "tryTimes", 0)) + 1
            ExamSession.set(current_user.id, 'tryTimes', str(try_times))
            current_app.logger.info("[get_result] handling!!! try times: %s, test_id: %s, user name: %s" %
                                    (str(try_times), last_test_id, current_user.name))
        return jsonify(errors.error({'code': resp.statusCode, 'msg': resp.statusMsg}))

    return jsonify(errors.success({
        "status": "Success",
        "totalScore": format(resp.score.total, ScoreConfig.DEFAULT_NUM_FORMAT),
        "data": exam_score_convert_to_json(resp.score),  # 这个表示成绩信息,为兼容旧系统就不改了...
        "report": exam_report_convert_to_json(resp.report)
    }))
예제 #15
0
def create_user():
    email = request.json.get('email')
    if email is not None:
        user = User.query.filter_by(id=email).first()
        if user:
            return jsonify(errors.User_already_exist)
        # todo: specify ss port ... before this is finished, the api will surely fail

        #     user = User(name='aaa', email='*****@*****.**', password='******', ss_port='8081', ss_pwd='123456')
        #     try:
        #         db.session.add(user)
        #         db.session.commit()
        #     except Exception as e:
        #         return jsonify(errors.exception({
        #             'data': str(e)
        #         }))

        return jsonify(
            errors.success({
                'msg': '创建用户成功',
                'data': {
                    'name': user.name,
                    'email': user.email,
                    'ss_port': user.ss_port
                }
            }))
    return jsonify(errors.Bad_request)
예제 #16
0
def get_last_cost_data():
    question_num = request.args.get("questionNum")
    print("get_last_cost_data: questionNum: " + str(question_num))
    optimize_history = OptimizeModel.objects(
        question_num=question_num).order_by('-complete_time').first()
    if not optimize_history:
        return jsonify(errors.Optimize_not_exist)
    cost_history = []
    n = len(optimize_history['key_history_cost'])
    for i in range(OptimizeConfig.COST_POINT):
        index = int(i * n / OptimizeConfig.COST_POINT)
        cost_history.append({
            "itrTimes":
            index + 1,
            'keyCost':
            optimize_history['key_history_cost'][index],
            'detailCost':
            optimize_history['detail_history_cost'][index],
        })
    data = {
        "date": optimize_history['complete_time'],
        "finish": optimize_history['finish'],
        "costData": cost_history,
    }
    # return jsonify(errors.success(mock_data.cost_data))
    return jsonify(errors.success(data))
예제 #17
0
def wx_get_result():
    """
    请求参数: questionNums(list), testID(str) (json格式)
    获取指定current记录的音频题打分
    """
    questions_nums = [str(s) for s in request.json.get("questionNums")]
    test_id = str(request.json.get("testID"))
    if test_id is None:
        return jsonify(errors.Params_error)
    current_app.logger.info("wx:get_result:current_id: %s" % test_id)

    current_test = CurrentTestModel.objects(id=test_id).first()
    if current_test is None:
        current_app.logger.error(
            "upload_success: ERROR: Test Not Exists!! - test_id: %s" % test_id)
        return jsonify(errors.Exam_not_exist)

    ret = {'questions': {}}
    for q_num in questions_nums:
        try:
            q = current_test.questions.get(q_num)
            status = q.get("status")
        except Exception as e:
            current_app.logger.error(e)
            return jsonify(errors.error({'msg': '题号无效: %s' % q_num}))
        ret['scores'].update({'q_num': {'status': status, 'scores': q.score}})
    return jsonify(errors.success(ret))
예제 #18
0
def next_question_v2(question_num):
    """
    获取下一题
    :param question_num: 完成的题号(原nowQuestionNum),获取第1题时为0
    :return: json格式包装的question,如:
    {
        "code": 0,
        "data": {
            "examLeftTime": 1752.312776,
            "examTime": 1800,
            "lastQuestion": false,
            "questionContent": "表达能力是一种非常有用的技能",
            "questionDbId": "5bcdea7df9438b6e56a32999",
            "questionInfo": {
                "detail": "声音质量测试。点击 “显示题目” 按钮后请先熟悉屏幕上的文字,然后按下 “开始回答” 按钮朗读该段文字。",
                "tip": "为了保证测试准确性,请选择安静环境,并对准麦克风。"
            },
            "questionLimitTime": 60,
            "questionNumber": 1,
            "questionType": 1,
            "readLimitTime": 5
        },
        "msg": "success"
    }
    """
    # 验证参数
    next_question_num = int(question_num) + 1
    if next_question_num <= 0:  # db中题号从1开始
        return jsonify(errors.Params_error)

    # todo: nowQuestionNum: 限制只能获取当前题目
    ExamSession.set(current_user.id, 'question_num', next_question_num)
    test_id = ExamSession.get(current_user.id, "test_id", default=DefaultValue.test_id)  # for production

    resp = exam_client.getQuestionInfo(exam_thrift.GetQuestionInfoRequest(
        examId=test_id,
        questionNum=next_question_num
    ))
    if resp is None:
        current_app.logger.error("[next_question_v2] exam_client.getQuestionInfo failed")
        return jsonify(errors.Internal_error)
    if resp.statusCode != 0:
        if resp.statusCode == errors.Exam_finished["code"]:
            ExamSession.set(current_user.id, 'question_num', 0)
        return jsonify(errors.error({'code': resp.statusCode, 'msg': resp.statusMsg}))

    if not resp.question:
        return jsonify(errors.Get_question_failed)

    # log question id to user's historical questions  todo: change to rpc
    user = UserModel.objects(id=str(current_user.id)).first()
    user.questions_history.update({resp.question.id: datetime.datetime.utcnow()})
    user.save()

    # 判断考试是否超时,若超时则返回错误
    if resp.question.examLeftTime <= 0:
        return jsonify(errors.Test_time_out)

    return jsonify(errors.success(question_info_convert_to_json(resp.question)))
예제 #19
0
def get_score_of_specific_users(username):
    """获取某用户的成绩情况

    :param username: 用户邮箱
    :return: 该用户的成绩情况
    """
    current_app.logger.info('get_score_of_specific_users   ' + username)

    if '@' in username:
        # 邮箱登录
        email = username
        if not validate_email(email):
            return jsonify(errors.Params_error)
        if ScoreConfig.DEFAULT_USER_EMAIL in username:
            # 默认邮箱,通过主键查询
            user_object_id = username[:-16]
            all_answers = AnalysisModel.objects(
                user=user_object_id).order_by('date')
        else:
            # 真实邮箱
            cur_user = UserModel.objects(email=username).first()
            if not cur_user:
                return jsonify(errors.Score_criteria_not_exist)
            all_answers = AnalysisModel.objects(user=cur_user['id']).\
                fields(voice_features=0, key_hits=0, detail_hits=0).order_by('date')
    else:
        # 手机号登录
        cur_user = UserModel.objects(phone=username).first()
        if not cur_user:
            return jsonify(errors.Score_criteria_not_exist)
        all_answers = AnalysisModel.objects(user=cur_user['id']). \
            fields(voice_features=0, key_hits=0, detail_hits=0).order_by('date')

    if len(all_answers) == 0:
        return jsonify(errors.Score_no_data)

    date_mapper = DateMapper()
    result_by_date = __generate_result_from_dict(
        date_mapper.map_answers(all_answers), 'date')

    question_id_mapper = QuestionNumMapper()
    result_by_qid = __generate_result_from_dict(
        question_id_mapper.map_answers(all_answers), 'questionId')
    # 按照 q_id 排序
    result_by_qid.sort(key=__sort_by_question_id)

    result_all = []
    for answer in result_by_qid:
        result_all.append({
            'questionId': answer['questionId'],
            'totalScore': answer['totalScore']
        })

    return jsonify(
        errors.success({
            'resultByDate': result_by_date,
            'allResult': result_all
        }))
예제 #20
0
def logout():
    _time1 = datetime.datetime.utcnow()
    # current_app.logger.debug('logout request: %s' % request.form.__str__())
    if current_user.is_authenticated:
        current_app.logger.info('user(id:%s) logout' % current_user.id)
        logout_user()
    _time2 = datetime.datetime.utcnow()
    current_app.logger.info('[TimeDebug][logout total]%s' % (_time2 - _time1))
    return jsonify(errors.success())
예제 #21
0
def accounts_invite():
    """批量创建邀请码

    Form-data Args:
        vipStartTime: 评测权限开始时间(时间戳)
        vipEndTime: 评测权限结束时间(时间戳)
        remainingExamNum: 邀请码包含的评测考试权限
        remainingExerciseNum: 邀请码包含的评测练习权限(暂未使用)
        availableTimes: 邀请码可用人数
        codeNum: 创建邀请码个数

    Returns:
        jsonify(errors.success({'msg': '生成邀请码成功', 'invitationCode': [...]}))

    """
    current_app.logger.info('create invitation request: %s' %
                            request.form.__str__())
    # 检验是否有权限申请邀请码
    form = request.form
    try:
        vip_start_time = form.get('vipStartTime').strip()
        vip_end_time = form.get('vipEndTime').strip()
        remaining_exam_num = int(form.get('remainingExamNum').strip())
        remaining_exercise_num = int(form.get('remainingExerciseNum').strip())
        available_times = int(form.get('availableTimes').strip())
        code_num = int(form.get('codeNum').strip())
    except Exception as e:
        current_app.logger.error(
            'Params_error:POST admin/accounts/invite: %s' % e)
        return jsonify(errors.Params_error)

    resp = user_client.createInvitationCode(
        user_thrift.CreateInvitationCodeRequest(
            creator=current_user.name,
            availableTimes=available_times,
            vipStartTime=vip_start_time,
            vipEndTime=vip_end_time,
            remainingExamNum=remaining_exam_num,
            remainingExerciseNum=remaining_exercise_num,
            codeNum=code_num,
        ))
    if resp is None:
        current_app.logger.error(
            "[accounts_invite] user_client.createInvitationCode failed")
        return jsonify(errors.Internal_error)
    if resp.statusCode != 0:
        return jsonify(
            errors.error({
                'code': resp.statusCode,
                'msg': resp.statusMsg
            }))

    return jsonify(
        errors.success({
            'msg': '生成邀请码成功',
            'invitationCode': resp.codeList
        }))
예제 #22
0
def get_pretest_result():
    async_result_id = ExamSession.get(current_user.id, "pretest_result_id", default=None)
    if not async_result_id:
        return jsonify(errors.Internal_error)

    async_result = app.AsyncResult(async_result_id)
    if async_result.ready():
        result = async_result.get()
        if result['status'] != 'error':
            return jsonify(errors.success({
                "qualityIsOk": result['lev_ratio'] >= 0.6,
                "canRcg": True,
                "levRatio": result['lev_ratio']
            }))
        else:
            return jsonify(errors.success({"canRcg": False, "qualityIsOk": False}))
    else:
        return jsonify(errors.WIP)
예제 #23
0
def wechat_login():
    if current_user.is_authenticated:
        return jsonify(errors.Already_logged_in)
    code = request.form.get('code')
    if not code:
        return jsonify(errors.Params_error)
    err_code, user_info = wx_get_user_info(code,
                                           current_app.config['WX_APPID'],
                                           current_app.config['WX_SECRET'])
    if err_code:
        return jsonify(
            errors.error({
                'code': int(err_code),
                'msg': 'invalid wechat code'
            }))
    wx_union_id = user_info.get('unionid')
    check_user = UserModel.objects(wx_id=wx_union_id).first()
    if not check_user:
        session['wx_union_id'] = wx_union_id
        # data = {'msg': '用户尚未绑定微信,前端请指引用户补充填写信息,进行绑定'}
        # data.update({'userInfo': user_info})
        # return jsonify(errors.error(data))
        headimgurl = user_info.get('headimgurl')
        nickname = user_info.get('nickname').encode('ISO-8859-1').decode(
            'utf-8')  # 要转码
        return jsonify(
            errors.success({
                'msg': '未绑定用户',
                'headimgurl': headimgurl,
                'nickname': nickname,
            }))
    session['wx_nickname'] = user_info.get('nickname')
    login_user(check_user)
    check_user.last_login_time = datetime.datetime.utcnow()
    check_user.save()
    current_app.logger.info('login from wechat: %s, id: %s' %
                            (check_user.name, check_user.id))
    return jsonify(
        errors.success({
            'msg': '已绑定用户,自动登录',
            'uuid': str(check_user.id),
            'name': str(check_user.name),
        }))
예제 #24
0
def retrieve_user():
    user_id = request.args.get('id')
    if user_id is not None:
        user = User.query.filter_by(id=user_id).first()
        # user1 = User.query.filter(User.id == user_id).first() 亦可
        if user:
            return jsonify(errors.success(user.to_dict()))
        else:
            return jsonify(errors.User_not_exist)
    return jsonify(errors.Bad_request)
예제 #25
0
def upload_test_wav_success():
    file_path = request.form.get('filePath')
    std_text = request.form.get('stdText')
    result_id, err = MyCelery.put_task('pretest', std_text=std_text, file_path=file_path)
    if err is not None:
        current_app.logger.error("[upload_test_wav_success] put task into celery failed. exception: " + str(err))
        return jsonify(errors.Internal_error)
    ExamSession.set(current_user.id, 'pretest_result_id', result_id, ex=300)
    current_app.logger.info("[upload_test_wav_success] put task into celery successful. "
                            "AsyncResult id: %s, user name: %s" % (result_id, current_user.name))
    return jsonify(errors.success())
예제 #26
0
def get_question_num_of_tpl(paper_tpl_id):
    resp = exam_client.getPaperTemplate(exam_thrift.GetPaperTemplateRequest(
        templateId=paper_tpl_id
    ))
    if resp is None:
        current_app.logger.error("[get_question_num_of_tpl] exam_client.getPaperTemplate failed")
        return jsonify(errors.Internal_error)
    if resp.statusCode != 0:
        return jsonify(errors.error({'code': resp.statusCode, 'msg': resp.statusMsg}))

    return jsonify(errors.success({'total': resp.templateList[0].questionCount}))
예제 #27
0
def get_upload_url_v2_bt(question_num):
    specified_path = request.args.get('givenUrl')
    test_id = ExamSession.get(current_user.id, "test_id",
                              default=DefaultValue.test_id)  # for production
    # get test
    current_test = CurrentTestModel.objects(id=test_id).first()
    if current_test is None:
        current_app.logger.error(
            "[TestNotFound][get_upload_url_v2]username: %s, test_id: %s" % (current_user.name, test_id))
        return jsonify(errors.Exam_not_exist)

    # get question
    user_id = str(current_user.id)
    current_app.logger.debug("[DEBUG][get_upload_url_v2]question_num: %s, user_name: %s"
                             % (question_num, current_user.name))
    try:
        question = current_test.questions[question_num]
    except Exception as e:
        current_app.logger.error("[GetEmbeddedQuestionException][get_upload_url_v2]question_num: "
                                 "%s, user_name: %s. exception:\n%s"
                                 % (question_num, current_user.name, e))
        return jsonify(errors.Get_question_failed)

    # sts = auth.get_sts_from_redis()  # a to--do

    """generate file path
    upload file path: 相对目录(audio)/日期/用户id/时间戳+后缀(.wav)
    temp path for copy: 相对目录(temp_audio)/用户id/文件名(同上)
    """

    # 如果数据库没有该题的url,创建url,存数据库 ,然后返回
    # 如果数据库里已经有这题的url,说明是重复请求,不用再创建
    if not question.wav_upload_url:
        file_dir = '/'.join((PathConfig.audio_save_basedir, get_server_date_str('-'), user_id))
        _temp_str = "%sr%s" % (int(time.time()), random.randint(100, 1000))
        file_name = "%s%s" % (_temp_str, PathConfig.audio_extension)
        # question.wav_upload_url = file_dir + '/' + file_name
        question.wav_upload_url = specified_path

        # -------- 压测: 使用指定路径进行覆盖,只供压测使用,否则将导致灾难性后果!
        # question.wav_upload_url = request.args.get('givenUrl')
        # -----------------------------------------------------------

        question.file_location = 'BOS'
        question.status = 'url_fetched'
        current_test.save()
        current_app.logger.info("[NewUploadUrl][get_upload_url]user_id:%s, url:%s"
                                % (current_user.id, question.wav_upload_url))
        current_app.logger.info("[INFO][get_upload_url_v2]new url: " + question.wav_upload_url)

    context = {"fileLocation": "BOS", "url": question.wav_upload_url}
    return jsonify(errors.success(context))
예제 #28
0
def get_info():
    resp = user_client.getUserInfo(
        user_thrift.GetUserInfoRequest(userId=str(current_user.id)))
    if resp is None:
        current_app.logger.error("[get_info] user_client.getUserInfo failed")
        return jsonify(errors.Internal_error)
    if resp.statusCode != 0:
        return jsonify(
            errors.error({
                'code': resp.statusCode,
                'msg': resp.statusMsg
            }))

    return jsonify(errors.success(user_info_convert_to_json(resp.userInfo)))
def wxbt_upload_success():
    """
    请求参数:questionNum, testID (json)
    上传音频完成,告知后端可以进行处理
    """
    q_num = str(request.json.get("questionNum"))
    test_id = str(request.json.get("testID"))
    if q_num is None or test_id is None:
        return jsonify(errors.Params_error)
    current_app.logger.info(
        "wx:upload_success:question_num: %s, current_id: %s" %
        (str(q_num), test_id))

    current_test = BtCurrentTestModel.objects(id=test_id).first()
    if current_test is None:
        current_app.logger.error(
            "upload_success: ERROR: Test Not Exists!! - test_id: %s" % test_id)
        return jsonify(errors.Exam_not_exist)

    q = current_test.questions.get(q_num)
    if q is None:
        return jsonify(errors.error({'msg': '题号无效'}))
    upload_url = q['wav_upload_url']
    current_app.logger.info("upload_success: upload_url: " + upload_url)

    # change question status to handling
    q.status = 'handling'
    q['analysis_start_time'] = datetime.datetime.utcnow()
    current_test.save()

    task_id, err = MyCelery.put_task(q.q_type,
                                     current_test.id,
                                     q_num,
                                     use_lock=False)
    if err:
        current_app.logger.error(
            '[PutTaskException][wxbt_upload_success]q_type:%s, test_id:%s,'
            'exception:\n%s' %
            (q.q_type, current_test.id, traceback.format_exc()))
        return jsonify(errors.exception({'Exception': str(err)}))
    current_app.logger.info("[PutTaskSuccess][wxbt_upload_success]dataID: %s" %
                            str(current_test.id))
    resp = {
        "status": "Success",
        "desc": "添加任务成功,等待服务器处理",
        "dataID": str(current_test.id),
        "taskID": task_id
    }
    return jsonify(errors.success(resp))
예제 #30
0
def get_test_wav_url():
    resp = exam_client.getFileUploadPath(exam_thrift.GetFileUploadPathRequest(
        userId=str(current_user.id),
        type=exam_thrift.ExamType.AudioTest
    ))
    if resp is None:
        current_app.logger.error("[get_test_wav_url] exam_client.getFileUploadPath failed")
        return jsonify(errors.Internal_error)
    if resp.statusCode != 0:
        return jsonify(errors.error({'code': resp.statusCode, 'msg': resp.statusMsg}))

    return jsonify(errors.success({
        "fileLocation": "BOS",
        "url": resp.path,
    }))