Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| import re | |
| import bcrypt | |
| import numpy as np | |
| import cv2 | |
| from PIL import Image | |
| import os | |
| import warnings | |
| import requests | |
| import json | |
| import torch | |
| from transformers import AutoImageProcessor, SiglipForImageClassification | |
| from pages import about, community, user_guide | |
| # --- Config --- | |
| SUPABASE_URL = "https://fpbuhzbdtzwomjwytqul.supabase.co" | |
| SUPABASE_API_KEY = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImZwYnVoemJkdHp3b21qd3l0cXVsIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTE5NDk3NzYsImV4cCI6MjA2NzUyNTc3Nn0.oAa2TNNPQMyOGk63AOMZ7XKcwYvy5m-xoSWyvMZd6FY" | |
| SUPABASE_TABLE = "user_details" | |
| headers = { | |
| "apikey": SUPABASE_API_KEY, | |
| "Authorization": f"Bearer {SUPABASE_API_KEY}", | |
| "Content-Type": "application/json" | |
| } | |
| # --- Setup --- | |
| os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2' | |
| warnings.filterwarnings("ignore") | |
| np.seterr(all='ignore') | |
| # --- Load Hugging Face Model --- | |
| processor = AutoImageProcessor.from_pretrained("prithivMLmods/deepfake-detector-model-v1") | |
| hf_model = SiglipForImageClassification.from_pretrained("prithivMLmods/deepfake-detector-model-v1") | |
| # --- Helpers --- | |
| def is_valid_email(email): return re.match(r"[^@]+@[^@]+\.[^@]+", email) | |
| def is_valid_phone(phone): return re.match(r"^[0-9]{10}$", phone) | |
| def predict_image(image): | |
| if image is None: | |
| return "Please upload an image first." | |
| image = image.convert("RGB") | |
| inputs = processor(images=image, return_tensors="pt") | |
| with torch.no_grad(): | |
| outputs = hf_model(**inputs) | |
| probs = torch.nn.functional.softmax(outputs.logits, dim=1).squeeze().tolist() | |
| label = "β Real Image" if probs[0] >= probs[1] else "β οΈ Fake Image" | |
| confidence = max(probs) | |
| return f"{label} (Confidence: {confidence:.2%})" | |
| def register_user(name, phone, email, gender, password): | |
| if not all([name, phone, email, gender, password]): | |
| return "β All fields are required for signup." | |
| if not is_valid_email(email): return "β Invalid email format." | |
| if not is_valid_phone(phone): return "β Phone must be 10 digits." | |
| query_url = f"{SUPABASE_URL}/rest/v1/{SUPABASE_TABLE}?email=eq.{email}" | |
| r = requests.get(query_url, headers=headers) | |
| if r.status_code == 200 and len(r.json()) > 0: | |
| return "β οΈ Email already registered." | |
| hashed_pw = bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt()).decode() | |
| data = {"name": name, "phone": phone, "email": email, "gender": gender, "password": hashed_pw} | |
| r = requests.post(f"{SUPABASE_URL}/rest/v1/{SUPABASE_TABLE}", headers=headers, data=json.dumps(data)) | |
| return "β Registration successful! Please log in." if r.status_code == 201 else "β Error during registration." | |
| def login_user(email, password): | |
| url = f"{SUPABASE_URL}/rest/v1/{SUPABASE_TABLE}?email=eq.{email}" | |
| r = requests.get(url, headers=headers) | |
| if r.status_code == 200 and r.json(): | |
| try: | |
| stored_hash = r.json()[0]["password"] | |
| return bcrypt.checkpw(password.encode('utf-8'), stored_hash.encode('utf-8')) | |
| except (IndexError, KeyError): | |
| return False | |
| return False | |
| # --- UI --- | |
| HOME_TAB_NAME = "π Home" | |
| LOGIN_TAB_NAME = "π Login" | |
| DETECT_TAB_NAME = "π§ͺ Detect Deepfake" | |
| ABOUT_TAB_NAME = "βΉοΈ About" | |
| COMMUNITY_TAB_NAME = "π Community" | |
| GUIDE_TAB_NAME = "π User Guide" | |
| with gr.Blocks(theme=gr.themes.Soft(), title="VerifiAI - Deepfake Detector") as demo: | |
| is_logged_in = gr.State(False) | |
| with gr.Tabs(selected=HOME_TAB_NAME) as tabs: | |
| with gr.Tab(HOME_TAB_NAME, id=HOME_TAB_NAME) as home_tab: | |
| with gr.Row(): | |
| with gr.Column(): | |
| gr.Markdown(""" | |
| <div class="home-content"> | |
| <h1>ποΈβπ¨οΈ Welcome to VerifiAI</h1> | |
| <p>Your trusted assistant for detecting deepfakes in images using AI.</p> | |
| <p>π Upload images, analyze authenticity, and learn how deepfakes work.</p> | |
| <p>π Use the tabs above to get started.</p> | |
| </div> | |
| """, elem_id="home-markdown") | |
| with gr.Tab(LOGIN_TAB_NAME, id=LOGIN_TAB_NAME) as login_tab: | |
| with gr.Row(): | |
| with gr.Column(scale=1): | |
| gr.Markdown("## Welcome!", "Login to access the detector, or sign up for a new account.") | |
| with gr.Column(scale=2): | |
| gr.Markdown("### Login or Sign Up") | |
| message_output = gr.Markdown(visible=False) | |
| email_login = gr.Textbox(label="Email") | |
| password_login = gr.Textbox(label="Password", type="password") | |
| login_btn = gr.Button("Login", variant="primary") | |
| with gr.Accordion("New User? Click here to Sign Up", open=False) as signup_accordion: | |
| name_signup = gr.Textbox(label="Name") | |
| phone_signup = gr.Textbox(label="Phone (10 digits)") | |
| email_signup = gr.Textbox(label="Email") | |
| gender_signup = gr.Dropdown(label="Gender", choices=["Male", "Female", "Other"]) | |
| password_signup = gr.Textbox(label="Create Password", type="password") | |
| signup_btn = gr.Button("Sign Up") | |
| with gr.Tab(DETECT_TAB_NAME, id=DETECT_TAB_NAME, visible=False) as detect_tab: | |
| with gr.Row(): | |
| gr.Markdown("## Deepfake Detector") | |
| logout_btn = gr.Button("Logout") | |
| with gr.Row(): | |
| image_input = gr.Image(type="pil", label="Upload Image", scale=1) | |
| with gr.Column(scale=1): | |
| result = gr.Textbox(label="Prediction Result", interactive=False) | |
| predict_btn = gr.Button("Predict", variant="primary") | |
| with gr.Tab(ABOUT_TAB_NAME, id=ABOUT_TAB_NAME): about.layout() | |
| with gr.Tab(COMMUNITY_TAB_NAME, id=COMMUNITY_TAB_NAME): community.layout(is_logged_in) | |
| with gr.Tab(GUIDE_TAB_NAME, id=GUIDE_TAB_NAME): user_guide.layout() | |
| gr.HTML(""" | |
| <style> | |
| #home-markdown { | |
| display: flex; | |
| justify-content: center; | |
| align-items: center; | |
| height: 50vh; | |
| text-align: center; | |
| } | |
| </style> | |
| """) | |
| def update_ui_on_auth_change(logged_in_status): | |
| if logged_in_status: | |
| return ( | |
| gr.update(visible=False), # login_tab | |
| gr.update(visible=True), # detect_tab | |
| gr.update(visible=False), # home_tab | |
| gr.update(value="β Login successful!", visible=True), | |
| gr.update(selected=DETECT_TAB_NAME) | |
| ) | |
| else: | |
| return ( | |
| gr.update(visible=True), | |
| gr.update(visible=False), | |
| gr.update(visible=True), | |
| gr.update(value="", visible=False), | |
| gr.update(selected=HOME_TAB_NAME) | |
| ) | |
| def handle_login(email, password): | |
| if login_user(email, password): | |
| return True, gr.update(value="β Login successful!", visible=True) | |
| else: | |
| return False, gr.update(value="β Invalid email or password.", visible=True) | |
| def handle_logout(): | |
| return False, "", "", None, "" | |
| def handle_signup(name, phone, email, gender, password): | |
| msg = register_user(name, phone, email, gender, password) | |
| if msg.startswith("β "): | |
| return gr.update(value=msg, visible=True), "", "", "", "", "", gr.update(open=False) | |
| else: | |
| return gr.update(value=msg, visible=True), name, phone, email, gender, password, gr.update(open=True) | |
| login_btn.click(fn=handle_login, inputs=[email_login, password_login], outputs=[is_logged_in, message_output]) | |
| logout_btn.click(fn=handle_logout, inputs=[], outputs=[is_logged_in, email_login, password_login, image_input, result]) | |
| is_logged_in.change(fn=update_ui_on_auth_change, inputs=is_logged_in, outputs=[login_tab, detect_tab, home_tab, message_output, tabs]) | |
| signup_btn.click(fn=handle_signup, inputs=[name_signup, phone_signup, email_signup, gender_signup, password_signup], | |
| outputs=[message_output, name_signup, phone_signup, email_signup, gender_signup, password_signup, signup_accordion]) | |
| predict_btn.click(fn=predict_image, inputs=image_input, outputs=result) | |
| demo.load(lambda: False, None, [is_logged_in]) | |
| if __name__ == "__main__": | |
| demo.launch() | |