Ejemplo n.º 1
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)

    if url_semester == URL_EMPTY_SEMESTER:
        try:
            student = entity_service.get_student(student_id)
        except Exception as e:
            return handle_exception_with_error_page(e)
    else:
        # RPC 获得学生课表
        try:
            student = entity_service.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

    if url_semester != URL_EMPTY_SEMESTER:
        with tracer.trace('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))

        return render_template('entity/student.html',
                               have_semesters=True,
                               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)
    else:
        # 无学期
        return render_template('entity/student.html',
                               have_semesters=False,
                               student=student)
Ejemplo n.º 2
0
def android_client_get_ics(resource_type, identifier, semester):
    """
    android client get a student or teacher's ics file

    If the student does not have privacy mode, anyone can use student number to subscribe his calendar.
    If the privacy mode is on and there is no HTTP basic authentication, return a 401(unauthorized)
    status code and the Android client ask user for password to try again.
    """
    # 检查 URL 参数
    try:
        res_type, res_id = decrypt(identifier)
    except ValueError:
        return "Invalid identifier", 400
    if resource_type not in ('student',
                             'teacher') or resource_type != res_type:
        return "Unknown resource type", 400

    if resource_type == 'teacher':
        try:
            teacher = entity_service.get_teacher_timetable(res_id, semester)
        except Exception as e:
            return handle_exception_with_error_page(e)

        cal_token = calendar_service.get_calendar_token(
            resource_type=resource_type,
            identifier=teacher.teacher_id,
            semester=semester)
        return redirect(
            url_for('calendar.ics_download', calendar_token=cal_token))
    else:  # student
        try:
            student = entity_service.get_student_timetable(res_id, semester)
        except Exception as e:
            return handle_exception_with_error_page(e)

        with tracer.trace('get_privacy_settings'):
            privacy_level = user_service.get_privacy_level(student.student_id)

        # get authorization from HTTP header and verify password if privacy is on
        if privacy_level != 0:
            if not request.authorization:
                return "Unauthorized (privacy on)", 401
            username, password = request.authorization
            if not user_service.check_password(username, password):
                return "Unauthorized (password wrong)", 401
            if student.student_id != username:
                return "Unauthorized (username mismatch)", 401

        cal_token = calendar_service.get_calendar_token(
            resource_type=resource_type,
            identifier=student.student_id,
            semester=semester)
        return redirect(
            url_for('calendar.ics_download', calendar_token=cal_token))
    def __init__(self, people: List[str], date: datetime.date, current_user: str):
        """多人日程展示。输入学号或教工号列表及日期,输出多人在当天的日程"""
        from everyclass.server import logger
        from everyclass.server.entity import service
        from everyclass.server.user import service as user_service
        from everyclass.server.entity import service as entity_service

        accessible_people_ids = []
        accessible_people = []
        inaccessible_people = []

        for identifier in people:
            if user_service.has_access(identifier, current_user)[0]:
                accessible_people_ids.append(identifier)
            else:
                inaccessible_people.append(People(entity_service.get_student(identifier).name, encrypt(RTYPE_STUDENT, identifier)))
        self.schedules = list()

        for identifier in accessible_people_ids:
            is_student, people_info = service.get_people_info(identifier)

            accessible_people.append(
                People(people_info.name, encrypt(RTYPE_STUDENT, identifier) if is_student else encrypt(RTYPE_TEACHER, identifier)))

            semester, week, day = domain.get_semester_date(date)
            if is_student:
                cards = service.get_student_timetable(identifier, semester).cards
            else:
                cards = service.get_teacher_timetable(identifier, semester).cards

            cards = filter(lambda c: week in c.weeks and c.lesson[0] == str(day), cards)  # 用日期所属的周次和星期过滤card

            event_dict = {}
            for card in cards:
                time = card.lesson[1:5]  # "10102" -> "0102"
                if time not in event_dict:
                    event_dict[time] = Event(name=card.name, room=card.room)
                else:
                    # 课程重叠
                    logger.warning("time of card overlapped", extra={'people_identifier': identifier,
                                                                     'date': date})

            # 给没课的位置补充None
            for i in range(1, 10, 2):
                key = f"{i:02}{i + 1:02}"
                if key not in event_dict:
                    event_dict[key] = None

            self.schedules.append(event_dict)
        self.inaccessible_people = inaccessible_people
        self.accessible_people = accessible_people
Ejemplo n.º 4
0
def cal_page(url_res_type: str, url_res_identifier: str, url_semester: str):
    """课表导出页面视图函数"""
    # 检查 URL 参数
    try:
        res_type, res_id = decrypt(url_res_identifier)
    except ValueError:
        return render_template("common/error.html",
                               message=MSG_INVALID_IDENTIFIER)
    if url_res_type not in ('student', 'teacher') or url_res_type != res_type:
        return render_template("common/error.html", message=MSG_400)

    if url_res_type == 'student':
        try:
            student = entity_service.get_student_timetable(
                res_id, url_semester)
        except Exception as e:
            return handle_exception_with_error_page(e)

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

        token = calendar_service.get_calendar_token(
            resource_type=url_res_type,
            identifier=student.student_id,
            semester=url_semester)
    else:
        try:
            teacher = entity_service.get_teacher_timetable(
                res_id, url_semester)
        except Exception as e:
            return handle_exception_with_error_page(e)

        token = calendar_service.get_calendar_token(
            resource_type=url_res_type,
            identifier=teacher.teacher_id,
            semester=url_semester)

    ics_url = url_for('calendar.ics_download',
                      calendar_token=token,
                      _external=True)
    ics_webcal = ics_url.replace('https', 'webcal').replace('http', 'webcal')

    return render_template('calendarSubscribe.html',
                           ics_url=ics_url,
                           ics_webcal=ics_webcal,
                           android_client_url=app.config['ANDROID_CLIENT_URL'])
Ejemplo n.º 5
0
def is_taking(cotc: Dict) -> bool:
    """检查当前用户是否选了这门课"""
    user_is_taking = False

    if session.get(SESSION_CURRENT_USER, None):
        # 检查当前用户是否选了这门课
        student = entity_service.get_student(session[SESSION_CURRENT_USER].identifier)
        for semester in sorted(student.semesters, reverse=True):  # 新学期可能性大,学期从新到旧查找
            timetable = entity_service.get_student_timetable(session[SESSION_CURRENT_USER].identifier, semester)
            for card in timetable.cards:
                if card.course_id == cotc["course_id"] and cotc["teacher_id_str"] == teacher_list_to_tid_str(
                        card.teachers):
                    user_is_taking = True
                    break
            if user_is_taking:
                break
    return user_is_taking
Ejemplo n.º 6
0
def get_calendar_token(id_sec: str, semester: str):
    """

    :param id_sec: 加密后的学号或教工号
    :param semester: 学期,如 2018-2019-1

    错误码:
    4000 请求无效
    4003 无权访问
    """
    try:
        res_type, res_id = encryption.decrypt(id_sec)
    except ValueError:
        return generate_error_response(None, api_helpers.STATUS_CODE_INVALID_REQUEST, '用户ID无效')

    if res_type == encryption.RTYPE_STUDENT:
        if not user_service.has_access(res_id, g.username)[0]:
            return generate_error_response(None, api_helpers.STATUS_CODE_PERMISSION_DENIED, '无权访问该用户课表')
        student = entity_service.get_student_timetable(res_id, semester)
        if not student:
            return generate_error_response(None, api_helpers.STATUS_CODE_INVALID_REQUEST, '学生不存在')
        token = calendar_service.get_calendar_token(resource_type=res_type,
                                                    identifier=student.student_id,
                                                    semester=semester)
    else:
        teacher = entity_service.get_teacher_timetable(res_id, semester)
        if not teacher:
            return generate_error_response(None, api_helpers.STATUS_CODE_INVALID_REQUEST, '教师不存在')
        token = calendar_service.get_calendar_token(resource_type=res_type,
                                                    identifier=teacher.teacher_id,
                                                    semester=semester)

    ics_url = url_for('calendar.ics_download', calendar_token=token, _external=True)
    ics_webcal = ics_url.replace('https', 'webcal').replace('http', 'webcal')
    return generate_success_response({'token': token,
                                      'ics_url': ics_url,
                                      'ics_url_webcal': ics_webcal})