def get_visitors(cls, sid_orig: str) -> List[Dict]: """获得访客列表""" from everyclass.rpc.entity import Entity 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 = Entity.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
def legacy_get_ics(student_id, semester_str): """ 早期 iCalendar 订阅端点,出于兼容性考虑保留,仅支持未设定隐私等级的学生,其他情况使用新的日历订阅令牌获得 ics 文件。 """ # 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 = Entity.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 tracer.trace('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 android_client_get_semester(identifier): """android client get a student or teacher's semesters """ try: search_result = Entity.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
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 tracer.trace('rpc_search'): try: rpc_result = Entity.search(keyword) except Exception as e: return handle_exception_with_error_page(e) # 不同类型渲染不同模板 if len(rpc_result.classrooms) >= 1: # 优先展示教室 # 我们在 kibana 中使用服务名过滤 apm 文档,所以 tag 不用增加服务名前缀 tracer.current_root_span().set_tag("query_resource_type", "classroom") tracer.current_root_span().set_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: # 一个学生 tracer.current_root_span().set_tag("query_resource_type", "single_student") if contains_chinese(keyword): tracer.current_root_span().set_tag("query_type", "by_name") else: tracer.current_root_span().set_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: # 一个老师 tracer.current_root_span().set_tag("query_resource_type", "single_teacher") if contains_chinese(keyword): tracer.current_root_span().set_tag("query_type", "by_name") else: tracer.current_root_span().set_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 tracer.current_root_span().set_tag("query_resource_type", "multiple_people") if contains_chinese(keyword): tracer.current_root_span().set_tag("query_type", "by_name") else: tracer.current_root_span().set_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", extra={"keyword": request.values.get('id')}) tracer.current_root_span().set_tag("query_resource_type", "not_exist") tracer.current_root_span().set_tag("query_type", "other") flash('没有找到任何有关 {} 的信息,如果你认为这不应该发生,请联系我们。'.format( escape(request.values.get('id')))) return redirect(url_for('main.main'))
def search(keyword: str) -> SearchResult: return Entity.search(keyword)