Beispiel #1
0
    def get_visitors(cls, sid_orig: str) -> List[Dict]:
        """获得访客列表"""
        from everyclass.server.rpc.api_server import APIServer

        with pg_conn_context() as conn, conn.cursor() as cursor:
            select_query = """
            SELECT visitor_id, last_visit_time FROM visit_tracks where host_id=%s ORDER BY last_visit_time DESC;
            """
            cursor.execute(select_query, (sid_orig, ))
            result = cursor.fetchall()
            conn.commit()

        visitor_list = []
        for record in result:
            # query api-server
            search_result = APIServer.search(record[0])

            visitor_list.append({
                "name":
                search_result.students[0].name,
                "student_id":
                search_result.students[0].student_id_encoded,
                "last_semester":
                search_result.students[0].semesters[-1],
                "visit_time":
                record[1]
            })
        return visitor_list
Beispiel #2
0
def android_client_get_semester(identifier):
    """android client get a student or teacher's semesters
    """
    from flask import jsonify
    from everyclass.server.rpc.api_server import APIServer

    try:
        search_result = APIServer.search(identifier)
    except Exception as e:
        return handle_exception_with_error_page(e)

    if len(search_result.students) == 1:
        return jsonify({'type'     : 'student',
                        'sid'      : search_result.students[0].student_id_encoded,
                        'semesters': search_result.students[0].semesters})
    if len(search_result.teachers) == 1:
        return jsonify({'type'     : 'teacher',
                        'tid'      : search_result.teachers[0].teacher_id_encoded,
                        'semesters': search_result.teachers[0].semesters})
    return "Bad request (got multiple people)", 400
Beispiel #3
0
def legacy_get_ics(student_id, semester_str):
    """
    早期 iCalendar 订阅端点,出于兼容性考虑保留,仅支持未设定隐私等级的学生,其他情况使用新的日历订阅令牌获得 ics 文件。
    """
    from flask import abort, redirect, url_for

    from everyclass.server.db.dao import PrivacySettings, CalendarToken
    from everyclass.server.rpc.api_server import APIServer
    from everyclass.server.models import Semester

    # fix parameters
    place = student_id.find('-')
    semester_str = student_id[place + 1:len(student_id)] + '-' + semester_str
    student_id = student_id[:place]

    semester = Semester(semester_str)

    search_result = APIServer.search(student_id)

    if len(search_result.students) != 1:
        # bad request
        return abort(400)

    if semester.to_str() not in search_result.students[0].semesters:
        return abort(400)

    with elasticapm.capture_span('get_privacy_settings'):
        privacy_settings = PrivacySettings.get_level(
            search_result.students[0].student_id)

    if privacy_settings != 0:
        # force user to get a calendar token when the user is privacy-protected but accessed through legacy interface
        return "Visit {} to get your calendar".format(
            url_for("main.main", _external=True)), 401
    else:
        token = CalendarToken.get_or_set_calendar_token(
            resource_type="student",
            identifier=search_result.students[0].student_id,
            semester=semester.to_str())
        return redirect(url_for('calendar.ics_download', calendar_token=token))
def query():
    """
    All in one 搜索入口,可以查询学生、老师、教室,然后跳转到具体资源页面

    正常情况应该是 post 方法,但是也兼容 get 防止意外情况,提高用户体验

    埋点:
    - `query_resource_type`, 查询的资源类型: classroom, single_student, single_teacher, multiple_people, or not_exist.
    - `query_type`, 查询方式(姓名、学工号): by_name, by_id, other
    """

    # if under maintenance, return to maintenance.html
    if app.config["MAINTENANCE"]:
        return render_template("maintenance.html")

    keyword = request.values.get('id')

    if not keyword or len(keyword) < 2:
        flash('请输入需要查询的姓名、学号、教工号或教室名称,长度不要小于2个字符')
        return redirect(url_for('main.main'))

    # 调用 api-server 搜索
    with elasticapm.capture_span('rpc_search'):
        try:
            rpc_result = APIServer.search(keyword)
        except Exception as e:
            return handle_exception_with_error_page(e)

    # 不同类型渲染不同模板
    if len(rpc_result.classrooms) >= 1:  # 优先展示教室
        # 我们在 kibana 中使用服务名过滤 apm 文档,所以 tag 不用增加服务名前缀
        elasticapm.tag(query_resource_type='classroom')
        elasticapm.tag(query_type='by_name')

        if len(rpc_result.classrooms) > 1:  # 多个教室选择
            return render_template('query/multipleClassroomChoice.html',
                                   name=keyword,
                                   classrooms=rpc_result.classrooms)
        return redirect('/classroom/{}/{}'.format(
            rpc_result.classrooms[0].room_id_encoded,
            rpc_result.classrooms[0].semesters[-1]))
    elif len(rpc_result.students) == 1 and len(
            rpc_result.teachers) == 0:  # 一个学生
        elasticapm.tag(query_resource_type='single_student')
        if contains_chinese(keyword):
            elasticapm.tag(query_type='by_name')
        else:
            elasticapm.tag(query_type='by_id')

        if len(rpc_result.students[0].semesters) < 1:
            flash('没有可用学期')
            return redirect(url_for('main.main'))

        return redirect('/student/{}/{}'.format(
            rpc_result.students[0].student_id_encoded,
            rpc_result.students[0].semesters[-1]))
    elif len(rpc_result.teachers) == 1 and len(
            rpc_result.students) == 0:  # 一个老师
        elasticapm.tag(query_resource_type='single_teacher')
        if contains_chinese(keyword):
            elasticapm.tag(query_type='by_name')
        else:
            elasticapm.tag(query_type='by_id')

        if len(rpc_result.teachers[0].semesters) < 1:
            flash('没有可用学期')
            return redirect(url_for('main.main'))

        return redirect('/teacher/{}/{}'.format(
            rpc_result.teachers[0].teacher_id_encoded,
            rpc_result.teachers[0].semesters[-1]))
    elif len(rpc_result.teachers) >= 1 or len(rpc_result.students) >= 1:
        # multiple students, multiple teachers, or mix of both
        elasticapm.tag(query_resource_type='multiple_people')
        if contains_chinese(keyword):
            elasticapm.tag(query_type='by_name')
        else:
            elasticapm.tag(query_type='by_id')

        return render_template('query/peopleWithSameName.html',
                               name=keyword,
                               students=rpc_result.students,
                               teachers=rpc_result.teachers)
    else:
        logger.info("No result for user search",
                    {"keyword": request.values.get('id')})
        elasticapm.tag(query_resource_type='not_exist')
        elasticapm.tag(query_type='other')
        flash('没有找到任何有关 {} 的信息,如果你认为这不应该发生,请联系我们。'.format(
            escape(request.values.get('id'))))
        return redirect(url_for('main.main'))