예제 #1
0
def get_classroom(url_rid, url_semester):
    """教室查询"""
    # decrypt identifier in URL
    try:
        _, room_id = decrypt(url_rid, resource_type='room')
    except ValueError:
        return render_template("common/error.html",
                               message=MSG_INVALID_IDENTIFIER)

    # RPC to get classroom timetable
    with elasticapm.capture_span('rpc_get_classroom_timetable'):
        try:
            room = APIServer.get_classroom_timetable(url_semester, room_id)
        except Exception as e:
            return handle_exception_with_error_page(e)

    with elasticapm.capture_span('process_rpc_result'):
        cards = defaultdict(list)
        for card in room.cards:
            day, time = lesson_string_to_tuple(card.lesson)
            cards[(day, time)].append(card)

    empty_5, empty_6, empty_sat, empty_sun = _empty_column_check(cards)

    available_semesters = semester_calculate(url_semester, room.semesters)

    return render_template('query/room.html',
                           room=room,
                           cards=cards,
                           empty_sat=empty_sat,
                           empty_sun=empty_sun,
                           empty_6=empty_6,
                           empty_5=empty_5,
                           available_semesters=available_semesters,
                           current_semester=url_semester)
예제 #2
0
def get_classroom(url_rid, url_semester):
    """教室查询"""
    from everyclass.server.utils import lesson_string_to_dict
    from everyclass.server.utils import teacher_list_fix
    from everyclass.server.utils import semester_calculate
    from .utils.rpc import HttpRpc

    with elasticapm.capture_span('rpc_query_room'):
        rpc_result = HttpRpc.call_with_error_page('{}/v1/room/{}/{}'.format(
            app.config['API_SERVER_BASE_URL'], url_rid, url_semester),
                                                  params={
                                                      'week_string': 'true',
                                                      'other_semester': 'true'
                                                  },
                                                  retry=True)
        if isinstance(rpc_result, str):
            return rpc_result
        api_response = rpc_result

    if 'name' not in api_response:
        logger.info("Hit classroom 'name' KeyError temporary fix")
        flash("教务数据异常,暂时无法查询本教室。其他教室不受影响。")
        return redirect(url_for("main.main"))

    with elasticapm.capture_span('process_rpc_result'):
        courses = dict()
        for each_class in api_response['course']:
            day, time = lesson_string_to_dict(each_class['lesson'])
            if (day, time) not in courses:
                courses[(day, time)] = list()
            courses[(day, time)].append(
                dict(name=each_class['name'],
                     week=each_class['week_string'],
                     teacher=teacher_list_fix(each_class['teacher']),
                     location=each_class['room'],
                     cid=each_class['cid']))

    empty_5, empty_6, empty_sat, empty_sun = _empty_column_check(courses)

    available_semesters = semester_calculate(
        url_semester, sorted(api_response['semester_list']))

    return render_template('query/room.html',
                           name=api_response['name'],
                           campus=api_response['campus'],
                           building=api_response['building'],
                           rid=url_rid,
                           classes=courses,
                           empty_sat=empty_sat,
                           empty_sun=empty_sun,
                           empty_6=empty_6,
                           empty_5=empty_5,
                           available_semesters=available_semesters,
                           current_semester=url_semester)
예제 #3
0
def get_student(url_sid: str, url_semester: str):
    """学生查询"""
    # decrypt identifier in URL
    try:
        _, student_id = decrypt(url_sid, resource_type='student')
    except ValueError:
        return render_template("common/error.html",
                               message=MSG_INVALID_IDENTIFIER)

    # RPC 获得学生课表
    with elasticapm.capture_span('rpc_get_student_timetable'):
        try:
            student = APIServer.get_student_timetable(student_id, url_semester)
        except Exception as e:
            return handle_exception_with_error_page(e)

    # save sid_orig to session for verifying purpose
    # must be placed before privacy level check. Otherwise a registered user could be redirected to register page.
    session[SESSION_LAST_VIEWED_STUDENT] = StudentSession(
        sid_orig=student.student_id,
        sid=student.student_id_encoded,
        name=student.name)

    # 权限检查,如果没有权限则返回
    has_permission, return_val = check_permission(student)
    if not has_permission:
        return return_val

    with elasticapm.capture_span('process_rpc_result'):
        cards: Dict[Tuple[int, int], List[Dict[str, str]]] = dict()
        for card in student.cards:
            day, time = lesson_string_to_tuple(card.lesson)
            if (day, time) not in cards:
                cards[(day, time)] = list()
            cards[(day, time)].append(card)
        empty_5, empty_6, empty_sat, empty_sun = _empty_column_check(cards)
        available_semesters = semester_calculate(url_semester,
                                                 sorted(student.semesters))

    # 增加访客记录
    Redis.add_visitor_count(student.student_id,
                            session.get(SESSION_CURRENT_USER, None))

    return render_template('query/student.html',
                           student=student,
                           cards=cards,
                           empty_sat=empty_sat,
                           empty_sun=empty_sun,
                           empty_6=empty_6,
                           empty_5=empty_5,
                           available_semesters=available_semesters,
                           current_semester=url_semester)
예제 #4
0
def get_teacher(url_tid, url_semester):
    """老师查询"""
    from everyclass.server.utils import lesson_string_to_dict
    from everyclass.server.utils import semester_calculate
    from .utils.rpc import HttpRpc

    with elasticapm.capture_span('rpc_query_student'):
        rpc_result = HttpRpc.call_with_error_page('{}/v1/teacher/{}/{}'.format(
            app.config['API_SERVER_BASE_URL'], url_tid, url_semester),
                                                  params={
                                                      'week_string': 'true',
                                                      'other_semester': 'true'
                                                  },
                                                  retry=True)
        if isinstance(rpc_result, str):
            return rpc_result
        api_response = rpc_result

    with elasticapm.capture_span('process_rpc_result'):
        courses = dict()
        for each_class in api_response['course']:
            day, time = lesson_string_to_dict(each_class['lesson'])
            if (day, time) not in courses:
                courses[(day, time)] = list()
            courses[(day, time)].append(
                dict(name=each_class['name'],
                     week=each_class['week_string'],
                     classroom=each_class['room'],
                     classroom_id=each_class['rid'],
                     cid=each_class['cid']))

    empty_5, empty_6, empty_sat, empty_sun = _empty_column_check(courses)

    available_semesters = semester_calculate(
        url_semester, sorted(api_response['semester_list']))

    return render_template('query/teacher.html',
                           name=api_response['name'],
                           falculty=api_response['unit'],
                           title=api_response['title'],
                           tid=url_tid,
                           classes=courses,
                           empty_sat=empty_sat,
                           empty_sun=empty_sun,
                           empty_6=empty_6,
                           empty_5=empty_5,
                           available_semesters=available_semesters,
                           current_semester=url_semester)
예제 #5
0
def get_teacher(url_tid, url_semester):
    """老师查询"""
    from collections import defaultdict

    from everyclass.server.utils import lesson_string_to_tuple
    from everyclass.server.utils import semester_calculate
    from everyclass.server.rpc.api_server import APIServer
    from everyclass.server.utils.resource_identifier_encrypt import decrypt
    from everyclass.server.consts import MSG_INVALID_IDENTIFIER

    # decrypt identifier in URL
    try:
        _, teacher_id = decrypt(url_tid, resource_type='teacher')
    except ValueError:
        return render_template("common/error.html",
                               message=MSG_INVALID_IDENTIFIER)

    # RPC to get teacher timetable
    with elasticapm.capture_span('rpc_get_teacher_timetable'):
        try:
            teacher = APIServer.get_teacher_timetable(teacher_id, url_semester)
        except Exception as e:
            return handle_exception_with_error_page(e)

    with elasticapm.capture_span('process_rpc_result'):
        cards = defaultdict(list)
        for card in teacher.cards:
            day, time = lesson_string_to_tuple(card.lesson)
            if (day, time) not in cards:
                cards[(day, time)] = list()
            cards[(day, time)].append(card)

    empty_5, empty_6, empty_sat, empty_sun = _empty_column_check(cards)

    available_semesters = semester_calculate(url_semester, teacher.semesters)

    return render_template('query/teacher.html',
                           teacher=teacher,
                           cards=cards,
                           empty_sat=empty_sat,
                           empty_sun=empty_sun,
                           empty_6=empty_6,
                           empty_5=empty_5,
                           available_semesters=available_semesters,
                           current_semester=url_semester)
예제 #6
0
def get_teacher(url_tid, url_semester):
    """老师查询"""

    # decrypt identifier in URL
    try:
        _, teacher_id = decrypt(url_tid, resource_type='teacher')
    except ValueError:
        return render_template("common/error.html",
                               message=MSG_INVALID_IDENTIFIER)

    # RPC to get teacher timetable
    with tracer.trace('rpc_get_teacher_timetable'):
        try:
            teacher = Entity.get_teacher_timetable(teacher_id, url_semester)
        except Exception as e:
            return handle_exception_with_error_page(e)

    with tracer.trace('process_rpc_result'):
        cards = defaultdict(list)
        for card in teacher.cards:
            day, time = lesson_string_to_tuple(card.lesson)
            if (day, time) not in cards:
                cards[(day, time)] = list()
            cards[(day, time)].append(card)

    empty_5, empty_6, empty_sat, empty_sun = _empty_column_check(cards)

    available_semesters = semester_calculate(url_semester, teacher.semesters)

    return render_template('query/teacher.html',
                           teacher=teacher,
                           cards=cards,
                           empty_sat=empty_sat,
                           empty_sun=empty_sun,
                           empty_6=empty_6,
                           empty_5=empty_5,
                           available_semesters=available_semesters,
                           current_semester=url_semester)
예제 #7
0
def get_student(url_sid: str, url_semester: str):
    """学生查询"""
    from everyclass.server.db.dao import PrivacySettings, VisitTrack, Redis
    from everyclass.server.utils import lesson_string_to_tuple
    from everyclass.server.rpc.api_server import APIServer
    from everyclass.server.utils.resource_identifier_encrypt import decrypt
    from everyclass.server.consts import MSG_INVALID_IDENTIFIER
    from everyclass.server.utils import semester_calculate
    from everyclass.server.consts import SESSION_LAST_VIEWED_STUDENT, SESSION_CURRENT_USER

    # decrypt identifier in URL
    try:
        _, student_id = decrypt(url_sid, resource_type='student')
    except ValueError:
        return render_template("common/error.html",
                               message=MSG_INVALID_IDENTIFIER)

    # RPC to get student timetable
    with elasticapm.capture_span('rpc_get_student_timetable'):
        try:
            student = APIServer.get_student_timetable(student_id, url_semester)
        except Exception as e:
            return handle_exception_with_error_page(e)

    # save sid_orig to session for verifying purpose
    # must be placed before privacy level check. Otherwise a registered user could be redirected to register page.
    session[SESSION_LAST_VIEWED_STUDENT] = StudentSession(
        sid_orig=student.student_id,
        sid=student.student_id_encoded,
        name=student.name)

    # get privacy level, if current user has no permission to view, return now
    with elasticapm.capture_span('get_privacy_settings'):
        privacy_level = PrivacySettings.get_level(student.student_id)

    # 仅自己可见、且未登录或登录用户非在查看的用户,拒绝访问
    if privacy_level == 2 and (
            not session.get(SESSION_CURRENT_USER, None)
            or session[SESSION_CURRENT_USER].sid_orig != student.student_id):
        return render_template('query/studentBlocked.html',
                               name=student.name,
                               falculty=student.deputy,
                               class_name=student.klass,
                               level=2)
    # 实名互访
    if privacy_level == 1:
        # 未登录,要求登录
        if not session.get(SESSION_CURRENT_USER, None):
            return render_template('query/studentBlocked.html',
                                   name=student.name,
                                   falculty=student.deputy,
                                   class_name=student.klass,
                                   level=1)
        # 仅自己可见的用户访问实名互访的用户,拒绝,要求调整自己的权限
        if PrivacySettings.get_level(
                session[SESSION_CURRENT_USER].sid_orig) == 2:
            return render_template('query/studentBlocked.html',
                                   name=student.name,
                                   falculty=student.deputy,
                                   class_name=student.klass,
                                   level=3)

    with elasticapm.capture_span('process_rpc_result'):
        cards: Dict[Tuple[int, int], List[Dict[str, str]]] = dict()
        for card in student.cards:
            day, time = lesson_string_to_tuple(card.lesson)
            if (day, time) not in cards:
                cards[(day, time)] = list()
            cards[(day, time)].append(card)
        empty_5, empty_6, empty_sat, empty_sun = _empty_column_check(cards)
        available_semesters = semester_calculate(url_semester,
                                                 sorted(student.semesters))

    # 公开或实名互访模式、已登录、不是自己访问自己,则留下轨迹
    if privacy_level != 2 and \
            session.get(SESSION_CURRENT_USER, None) and \
            session[SESSION_CURRENT_USER].sid_orig != session[SESSION_LAST_VIEWED_STUDENT].sid_orig:
        VisitTrack.update_track(host=student.student_id,
                                visitor=session[SESSION_CURRENT_USER])

    # 增加访客记录
    Redis.add_visitor_count(student.student_id,
                            session.get(SESSION_CURRENT_USER, None))

    return render_template('query/student.html',
                           student=student,
                           cards=cards,
                           empty_sat=empty_sat,
                           empty_sun=empty_sun,
                           empty_6=empty_6,
                           empty_5=empty_5,
                           available_semesters=available_semesters,
                           current_semester=url_semester)
예제 #8
0
def get_student(url_sid, url_semester):
    """学生查询"""
    from everyclass.server.db.dao import PrivacySettingsDAO, VisitorDAO
    from everyclass.server.utils import lesson_string_to_dict
    from everyclass.server.utils import teacher_list_fix
    from everyclass.server.utils import semester_calculate
    from everyclass.server.utils.rpc import HttpRpc
    from everyclass.server.consts import SESSION_LAST_VIEWED_STUDENT, SESSION_CURRENT_USER

    with elasticapm.capture_span('rpc_query_student'):
        rpc_result = HttpRpc.call_with_error_page('{}/v1/student/{}/{}'.format(
            app.config['API_SERVER_BASE_URL'], url_sid, url_semester),
                                                  params={
                                                      'week_string': 'true',
                                                      'other_semester': 'true'
                                                  },
                                                  retry=True)
        if isinstance(rpc_result, str):
            return rpc_result
        api_response = rpc_result

    # save sid_orig to session for verifying purpose
    # must be placed before privacy level check. Otherwise a registered user could be redirected to register page.
    session[SESSION_LAST_VIEWED_STUDENT] = Student(
        sid_orig=api_response['sid'], sid=url_sid, name=api_response['name'])

    # get privacy level, if current user has no permission to view, return now
    with elasticapm.capture_span('get_privacy_settings'):
        privacy_level = PrivacySettingsDAO.get_level(api_response['sid'])

    # 仅自己可见、且未登录或登录用户非在查看的用户,拒绝访问
    if privacy_level == 2 and (
            not session.get(SESSION_CURRENT_USER, None)
            or session[SESSION_CURRENT_USER].sid_orig != api_response['sid']):
        return render_template('query/studentBlocked.html',
                               name=api_response['name'],
                               falculty=api_response['deputy'],
                               class_name=api_response['class'],
                               sid=url_sid,
                               level=2)
    # 实名互访
    if privacy_level == 1:
        # 未登录,要求登录
        if not session.get(SESSION_CURRENT_USER, None):
            return render_template('query/studentBlocked.html',
                                   name=api_response['name'],
                                   falculty=api_response['deputy'],
                                   class_name=api_response['class'],
                                   sid=url_sid,
                                   level=1)
        # 仅自己可见的用户访问实名互访的用户,拒绝,要求调整自己的权限
        if PrivacySettingsDAO.get_level(
                session[SESSION_CURRENT_USER].sid_orig) == 2:
            return render_template('query/studentBlocked.html',
                                   name=api_response['name'],
                                   falculty=api_response['deputy'],
                                   class_name=api_response['class'],
                                   sid=url_sid,
                                   level=3)

    with elasticapm.capture_span('process_rpc_result'):
        courses = dict()
        for each_class in api_response['course']:
            day, time = lesson_string_to_dict(each_class['lesson'])
            if (day, time) not in courses:
                courses[(day, time)] = list()
            courses[(day, time)].append(
                dict(name=each_class['name'],
                     teacher=teacher_list_fix(each_class['teacher']),
                     week=each_class['week_string'],
                     classroom=each_class['room'],
                     classroom_id=each_class['rid'],
                     cid=each_class['cid']))
        empty_5, empty_6, empty_sat, empty_sun = _empty_column_check(courses)
        available_semesters = semester_calculate(
            url_semester, sorted(api_response['semester_list']))

    # 公开模式或实名互访模式,留下轨迹
    if privacy_level != 2 and \
            session.get(SESSION_CURRENT_USER, None) and \
            session[SESSION_CURRENT_USER] != session[SESSION_LAST_VIEWED_STUDENT]:
        VisitorDAO.update_track(host=api_response['sid'],
                                visitor=session[SESSION_CURRENT_USER])

    return render_template('query/student.html',
                           name=api_response['name'],
                           falculty=api_response['deputy'],
                           class_name=api_response['class'],
                           sid=url_sid,
                           classes=courses,
                           empty_sat=empty_sat,
                           empty_sun=empty_sun,
                           empty_6=empty_6,
                           empty_5=empty_5,
                           available_semesters=available_semesters,
                           current_semester=url_semester)