def list_timetable(bot, message: Message): # Fetch all periods collection unsorted_periods = Period().all() sorted_periods = Period().sort_by_weekday(unsorted_periods) periods_output = "" # foreach group in grouped results for weekday in sorted_periods: periods = sorted_periods[weekday] period_table = format_periods(periods, weekday) periods_output += f"```{period_table.get_string()}```" message.reply_text(periods_output,parse_mode='markdown')
def process_sso_profile(sso_profile): period_name = app.config["ACTIVE_PERIOD"] user_npm = sso_profile["attributes"]["npm"] major_name = sso_profile["attributes"]["study_program"] major_kd_org = sso_profile["attributes"]["kd_org"] major = Major.objects(kd_org=major_kd_org).first() if major is None: major = Major(name=major_name, kd_org=major_kd_org) major.save() period_detail = Period.objects( major_id=major.id, name=period_name, is_detail=True).first() period_not_detail = Period.objects( major_id=major.id, name=period_name, is_detail=False).first() if period_detail is None: if period_not_detail is None: courses, is_detail = scrape_courses(major_kd_org, period_name) if not courses: result = { "err": True, "major_name": major_name } return result else: courses, is_detail = scrape_courses( major_kd_org, period_name, skip_not_detail=True) if courses: period = Period( major_id=major.id, name=period_name, courses=courses, is_detail=is_detail ) period.save() user = User.objects(npm=user_npm).first() if user is None: user = User( name=sso_profile["attributes"]["ldap_cn"], username=sso_profile["username"], npm=user_npm, batch=f"20{user_npm[:2]}", major=major, ) user.save() token = generate_token(user.id, user.major.id) result = { "user_id": str(user.id), "major_id": str(user.major.id), "token": token } return result
def test_serialize_with_empty_courses(self): period = Period( major_id=None, name="Period B", is_detail=True, courses=[], ) serialized_period = period.serialize() assert serialized_period["name"] == period.name assert serialized_period["is_detail"] == period.is_detail assert serialized_period["courses"] == []
def test_serialization_contains_required_keys(self): period = Period( major_id=None, name="Period A", is_detail=True, courses=[], ) serialized_period = period.serialize() self.assert_serialization_contains_keys( keys=["name", "is_detail", "courses"], serialized_object=serialized_period )
def test_serialize_with_courses(self): period = Period( major_id=None, name="Period C", is_detail=True, courses=[self.generate_random_course_item() for _ in range(5)], ) serialized_period = period.serialize() assert serialized_period["name"] == period.name assert serialized_period["is_detail"] == period.is_detail for i in range(len(serialized_period["courses"])): assert serialized_period["courses"][i] == period.courses[i].serialize()
def test_period_fields_validation(self): course = self.generate_random_course_item() test_cases = [ {"major_id": course, "name": "Name", "courses": [course]}, {"major_id": course, "name": "Name" * 10, "courses": [course]}, {"major_id": course, "name": "Name" * 10, "courses": [course]}, {"major_id": course, "name": "Name" * 10, "courses": "Courses"}, ] for case in test_cases: with pytest.raises(ValidationError): Period( major_id=case["major_id"], name=case["name"], courses=case["courses"], ).save()
def callback(ch, method, properties, body): data = json.loads(body) now = datetime.datetime.utcnow() username = data['username'] password = data['password'] major_id = data['major_id'] period = Period.objects(major_id=major_id, name=active_period, is_detail=True).first() if period is None: period = Period( major_id=major_id, is_detail=True, name=active_period, ) if period.last_update_at: time_difference = now - period.last_update_at if time_difference.seconds < 300: return courses = scrape_courses_with_credentials(active_period, username, password) period.courses = courses period.last_update_at = now period.save() app.logger.info(f"Done scrapping kd_org: {method.routing_key}; period: {active_period}; at: {now} UTC")
def update_courses(): period_name = app.config["ACTIVE_PERIOD"] majors = Major.objects.all() for major in majors: major_kd_org = major.kd_org period_detail = Period.objects(major_id=major.id, name=period_name, is_detail=True).first() if period_detail is None: period_not_detail = Period.objects(major_id=major.id, name=period_name, is_detail=False).first() if period_not_detail is None: continue courses, is_detail = scrape_courses(major_kd_org, period_name) if courses: if is_detail: period = Period(major_id=major.id, name=period_name, courses=courses, is_detail=True) period.save() else: period_not_detail.courses = courses period_not_detail.save() continue courses, is_detail = scrape_courses(major_kd_org, period_name, skip_not_detail=True) if courses: period_detail.courses = courses period_detail.save()
def list_today_timetable(bot, message: Message): today = date.today().strftime('%A') periods = Period().today() period_table = format_periods(periods, today) message.reply_text(f"```{period_table.get_string()}```",parse_mode='markdown')
def upload(profile): if request.method == "POST": if "file" not in request.files: flash("File error.") return redirect(url_for_custom("router_uploader.upload")) file_ = request.files["file"] if file_.filename == "": flash("File kosong.") return redirect(url_for_custom("router_uploader.upload")) if file_ and allowed_file(file_.filename): if not os.path.isdir(app.config["UPLOAD_FOLDER"]): os.mkdir(app.config["UPLOAD_FOLDER"]) html = file_.read() period, kd_org = get_period_and_kd_org(html) role = check_uploader(profile["npm"]) if (period == app.config["ACTIVE_PERIOD"]) and ( kd_org == profile["kd_org"] or role == "admin"): courses = create_courses(html, is_detail=True) if not courses: flash("Error, hubungi admin. Sertakan file ini.") return redirect(url_for_custom("router_uploader.upload")) major = Major.objects(kd_org=kd_org).first() if major is None: flash("Login susun jadwal beneran dulu ya.") return redirect(url_for_custom("router_uploader.upload")) instance = Period.objects(major_id=major.id, name=period, is_detail=True).first() if instance: instance.courses = courses else: instance = Period(major_id=major.id, name=period, courses=courses, is_detail=True) instance.save() timestamp = int(time.time()) filename = f"{kd_org}_{timestamp}_{secure_filename(file_.filename)}" file_.save(os.path.join(app.config["UPLOAD_FOLDER"], filename)) else: flash("Periode salah atau jurusan tidak sesuai.") return redirect(url_for_custom("router_uploader.upload")) flash("Berhasil..!!") return redirect(url_for_custom("router_uploader.upload")) flash("Gagal. File salah atau hubungi admin.") return redirect(url_for_custom("router_uploader.upload")) return render_template("upload.html", profile=profile)