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 tracer.trace('rpc_get_classroom_timetable'): try: room = Entity.get_classroom_timetable(url_semester, room_id) except Exception as e: return handle_exception_with_error_page(e) with tracer.trace('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)
def get_card(url_cid: str, url_semester: str): """课程查询""" # decrypt identifier in URL try: _, card_id = decrypt(url_cid, resource_type='klass') except ValueError: return render_template("common/error.html", message=MSG_INVALID_IDENTIFIER) # RPC to get card try: card = entity_service.get_card(url_semester, card_id) except Exception as e: return handle_exception_with_error_page(e) day, time = lesson_string_to_tuple(card.lesson) # cotc_id = COTeachingClass.get_id_by_card(card) # course_review_doc = CourseReview.get_review(cotc_id) return render_template('entity/card.html', card=card, card_day=get_day_chinese(day), card_time=get_time_chinese(time), # cotc_id=cotc_id, # cotc_rating=course_review_doc["avg_rate"], cotc_id=0, cotc_rating=0, current_semester=url_semester )
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)
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) if url_semester == URL_EMPTY_SEMESTER: # RPC to get teacher timetable try: teacher = entity_service.get_teacher(teacher_id) except Exception as e: return handle_exception_with_error_page(e) else: # RPC to get teacher timetable try: teacher = entity_service.get_teacher_timetable(teacher_id, url_semester) except Exception as e: return handle_exception_with_error_page(e) if url_semester != URL_EMPTY_SEMESTER: 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('entity/teacher.html', have_semesters=True, 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) else: # 无学期 return render_template('entity/teacher.html', have_semesters=False, teacher=teacher)
def get_card(url_cid: str, url_semester: str): """课程查询""" # decrypt identifier in URL try: _, card_id = decrypt(url_cid, resource_type='klass') except ValueError: return render_template("common/error.html", message=MSG_INVALID_IDENTIFIER) # RPC to get card with tracer.trace('rpc_get_card'): try: card = Entity.get_card(url_semester, card_id) except Exception as e: return handle_exception_with_error_page(e) day, time = lesson_string_to_tuple(card.lesson) # 给“文化素质类”等加上“课”后缀 if card.type and card.type[-1] != '课': card.type = card.type + '课' # cotc_id = COTeachingClass.get_id_by_card(card) # course_review_doc = CourseReview.get_review(cotc_id) return render_template( 'query/card.html', card=card, card_day=get_day_chinese(day), card_time=get_time_chinese(time), show_union_class=not card.union_name.isdigit(), # 合班名称为数字时不展示合班名称 # cotc_id=cotc_id, # cotc_rating=course_review_doc["avg_rate"], cotc_id=0, cotc_rating=0, current_semester=url_semester)
def ics_download(calendar_token: str): """ iCalendar ics 文件下载 2019-8-25 改为预先缓存文件而非每次动态生成,降低 CPU 压力。如果一小时内两次访问则强刷缓存。 """ import time from everyclass.server import statsd if not is_valid_uuid(calendar_token): return 'invalid calendar token', 404 result = CalendarToken.find_calendar_token(token=calendar_token) if not result: return 'invalid calendar token', 404 CalendarToken.update_last_used_time(calendar_token) cal_dir = calendar_dir() cal_filename = f"{result['type']}_{result['identifier']}_{result['semester']}.ics" cal_full_path = os.path.join(cal_dir, cal_filename) # 有缓存、且缓存时间小于一天,且不用强刷缓存 if os.path.exists(cal_full_path) \ and time.time() - os.path.getmtime(cal_full_path) < SECONDS_IN_ONE_DAY \ and Redis.calendar_token_use_cache(calendar_token): logger.info("ics cache hit") statsd.increment("calendar.ics.cache.hit") return send_from_directory(cal_dir, cal_filename, as_attachment=True, mimetype='text/calendar') statsd.increment("calendar.ics.cache.miss") # 无缓存、或需要强刷缓存 with tracer.trace('rpc'): # 获得原始学号或教工号 if result['type'] == 'student': rpc_result = Entity.get_student_timetable(result['identifier'], result['semester']) else: # teacher rpc_result = Entity.get_teacher_timetable(result['identifier'], result['semester']) semester = Semester(result['semester']) cards: Dict[Tuple[int, int], List[Dict]] = defaultdict(list) for card in rpc_result.cards: cards[lesson_string_to_tuple(card.lesson)].append( dict(name=card.name, teacher=teacher_list_to_name_str(card.teachers), week=card.weeks, week_string=card.week_string, classroom=card.room, cid=card.card_id_encoded)) ics_generator.generate(name=rpc_result.name, cards=cards, semester=semester, filename=cal_filename) return send_from_directory(cal_dir, cal_filename, as_attachment=True, mimetype='text/calendar')
def test_lesson_string_to_tuple(self): from everyclass.common.time import lesson_string_to_tuple self.assertTrue(lesson_string_to_tuple('10102') == (1, 1))