import gradio as gr from utils.logger import Logger from utils.database import get_db from data.repository.annotator_repo import AnnotatorRepo from data.repository.annotator_workload_repo import AnnotatorWorkloadRepo from utils.security import verify_password log = Logger() class AuthService: """ Authenticate users against DB and drive Gradio UI states. """ # ───────────── LOGIN ───────────── # @staticmethod def login(username: str, password: str, session: dict): """ خروجی‌ها (به همین ترتیب در LoginPage ثبت شده است): 0) message (Markdown داخل فرم لاگین) 1) login_container (پنهان/نمایان شدن فرم لاگین) 2) dashboard_container (نمایش داشبورد) 3) header_welcome (پیام خوش‌آمد در هدر) 4) items_state (لیست رکوردها) 5) idx_state (اندیس فعلی) 6-11) شش فیلد نمایشی (id, filename, sentence, ann_sentence, ann_at, validated) """ # ---------- اعتبارسنجی ---------- # log.info(f"Login attempt: username={username}") with get_db() as db: repo = AnnotatorRepo(db) annotator = repo.get_annotator_by_name(username) # ⬇️ توابع کمکی برای تولید خروجی خالی (درصورت خطا) def empty_dashboard_outputs_for_ui(): # Renamed and adjusted for UI outputs return ( [], # items_state 0, # idx_state "", # tts_id "", # filename "", # sentence "", # ann_sentence ) # --- کاربر موجود نیست / غیر فعال if annotator is None or not annotator.is_active: log.warning("Failed login (not found / inactive)") return ( "❌ Wrong username or password!", # message gr.update(), # login_container (no change) gr.update(visible=False), # dashboard_container gr.update(value=""), # header_welcome *empty_dashboard_outputs_for_ui(), # items_state, idx_state, and 4 UI textboxes ) # --- رمز عبور اشتباه if not verify_password(password, annotator.password): log.warning("Failed login (bad password)") return ( "❌ Wrong username or password!", # message gr.update(), # login_container (no change) gr.update(visible=False), # dashboard_container gr.update(value=""), # header_welcome *empty_dashboard_outputs_for_ui(), # items_state, idx_state, and 4 UI textboxes ) # ---------- ورود موفق ---------- # session["user_id"] = annotator.id session["username"] = annotator.name # بارگذاری داده‌های داشبورد workload_repo = AnnotatorWorkloadRepo(db) raw_items = workload_repo.get_tts_data_with_annotations(username) dashboard_items = [ { "id": row["tts_data"].id, "filename": row["tts_data"].filename, "sentence": row["tts_data"].sentence, "annotated_sentence": ( row["annotation"].annotated_sentence if row["annotation"] else "" ), "annotated_at": ( row["annotation"].annotated_at.isoformat() if row["annotation"] and row["annotation"].annotated_at else "" ), "validated": ( row["annotation"].validated if row["annotation"] is not None else False ), } for row in raw_items ] session["dashboard_items"] = dashboard_items # مقداردهی فیلدهای رکورد اول (یا مقادیر تهی) if dashboard_items: first = dashboard_items[0] # Only take the first 4 values needed for the 4 textboxes # tts_id, filename, sentence, ann_sentence first_vals_for_ui = ( first["id"], first["filename"], first["sentence"], first["annotated_sentence"], ) else: first_vals_for_ui = ("", "", "", "") log.info(f"User '{username}' logged in successfully.") # ---------- خروجی نهایی برای Gradio ---------- # return ( None, # 0: پیام خطا وجود ندارد gr.update(visible=False), # 1: فرم لاگین را مخفی کن gr.update(visible=True), # 2: داشبورد را نشان بده gr.update(value=f"👋 Welcome, {annotator.name}!"), # 3 dashboard_items, # 4: items_state 0, # 5: idx_state *first_vals_for_ui, # 6-9: چهار فیلد نخست برای UI ) # ───────────── LOGOUT ───────────── # @staticmethod def logout(session: dict): username = session.get("username", "unknown") session.clear() log.info(f"User '{username}' logged out.") return ( gr.update(visible=True), # 1 → login_page.container gr.update(visible=False), # 2 → dashboard_page.container gr.update(value=""), # 3 → self.welcome gr.update(value=""), # 4 → login_page.message )