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 get_courses(major_id): active_period = get_app_config("ACTIVE_PERIOD") period = Period.objects(major_id=major_id, name=active_period, is_detail=True).first() if period is None: period = Period.objects(major_id=major_id, name=active_period, is_detail=False).first() return (jsonify(period.serialize()), 200)
def create_period(self, major_id): """Create dummy period with its course and class""" class_obj = Class( name='Anum - A', schedule_items=[ ScheduleItem( day='Senin', start='09.40', end='08.00', room='A6.09 (Ged Baru)', ), ], lecturer=['Nama Dosen 1', 'Nama Dosen 2'], ) course = Course( name=self.COURSE['name'], credit=self.COURSE['credit'], term=self.COURSE['term'], classes=[class_obj], ) period = Period.objects().create( major_id=major_id, name=app.config["ACTIVE_PERIOD"], is_detail=True, courses=[course], ) return period
def process_sso_auth(cls, sso_profile) -> Tuple[dict, int]: user_name = sso_profile["username"] period_name = get_app_config("ACTIVE_PERIOD") user = User.objects(username=user_name).first() if user is None: full_name = sso_profile['attributes']['ldap_cn'] user = User(name=full_name, username=user_name) try: user_npm = sso_profile["attributes"]["npm"] major_name = sso_profile["attributes"]["study_program"] major_kd_org = sso_profile["attributes"]["kd_org"] except KeyError: completion_id = uuid.uuid4() user.completion_id = completion_id user.save() return { 'user_name': user_name, 'full_name': full_name, 'completion_id': str(completion_id) }, 201 user.npm = user_npm user.batch = f"20{user_npm[:2]}" 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() user.major = major user.save() if user.completion_id is not None: return { 'user_name': user.username, 'full_name': user.name, 'completion_id': str(user.completion_id) }, 201 major = user.major period = Period.objects(major_id=major.id, name=period_name, is_detail=True).first() token = generate_token(user.id, user.major.id) result = { "user_id": str(user.id), "major_id": str(user.major.id), "token": token } if period is None: result = {**result, "err": True, "major_name": major.name} return result, 200
def test_period_deletion(self): period = Period.objects().create( major_id=self.generate_random_major_item().save(), name="Period Name Old", is_detail=True, courses=[self.generate_random_course_item()], ) assert len(Period.objects) == 1 assert period in Period.objects period.delete() assert len(Period.objects) == 0 assert period not in Period.objects
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 test_period_creation(self): period = Period.objects().create( major_id=self.generate_random_major_item().save(), name="Period", is_detail=True, courses=[self.generate_random_course_item()], ) periods = Period.objects assert len(periods) == 1 fetched_period = periods().first() assert fetched_period.major_id == period.major_id assert fetched_period.name == "Period" assert fetched_period.is_detail assert fetched_period.courses == period.courses fetched_period.delete()
def test_period_update(self): period = Period.objects().create( major_id=self.generate_random_major_item().save(), name="Period Name Old", is_detail=True, courses=[self.generate_random_course_item()], ) new_major = self.generate_random_major_item().save() period.major_id = new_major period.name = "New Name" period.is_detail = False period.courses = [] period.save() period.reload() assert period.major_id == new_major assert period.name == "New Name" assert not period.is_detail assert period.courses == [] period.delete()
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 process_auth_completion(cls, data: AuthCompletionData) -> dict: user = User.objects(completion_id=data.completion_id).first() period_name = get_app_config("ACTIVE_PERIOD") if user is None: raise UserNotFound() base_kd_org_data = get_app_config("BASE_KD_ORG") try: kd_org_data = base_kd_org_data[data.kd_org] except KeyError: raise KdOrgNotFound() major = Major.objects(kd_org=data.kd_org).first() if major is None: major = Major(name=kd_org_data["study_program"], kd_org=data.kd_org) major.save() user.npm = data.npm user.major = major user.completion_id = None user.batch = f"20{data.npm[:2]}" user.save() period = Period.objects(major_id=major.id, name=period_name, is_detail=True).first() token = generate_token(user.id, user.major.id) result = { "user_id": str(user.id), "major_id": str(major.id), "token": token } if period is None: result = {**result, "err": True, "major_name": major.name} return result
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)