File size: 8,525 Bytes
5116eef
40f9579
 
 
 
 
 
 
1e390f9
 
ea96e7c
 
1b19f08
ea2016f
 
 
dbaa416
01fa9a7
1e390f9
 
 
 
 
 
 
dbaa416
ea2016f
52452fe
40f9579
 
 
ea96e7c
 
 
317097d
ea2016f
317097d
 
 
 
ea96e7c
 
 
 
 
 
 
c1ad074
ea96e7c
317097d
 
81e11bb
 
ea2016f
 
81e11bb
ea2016f
 
 
 
 
ea96e7c
ea2016f
 
81e11bb
 
 
 
 
6de7783
 
 
 
 
81e11bb
 
ea2016f
b3b3474
 
ea2016f
b3b3474
 
 
 
ea2016f
81e11bb
ea2016f
6de7783
 
ea2016f
 
 
 
 
 
 
 
 
 
 
6de7783
ea2016f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6de7783
ea2016f
 
 
 
 
 
 
 
 
6de7783
cc7ab7a
6de7783
ea2016f
 
 
 
 
 
 
92d3f30
ea2016f
 
 
 
 
 
 
 
 
 
 
6de7783
ea96e7c
ea2016f
 
 
ea96e7c
 
 
6de7783
ea96e7c
ea2016f
 
25ce2ec
d90562a
ea2016f
 
 
d90562a
ea2016f
5067008
ea96e7c
d90562a
 
 
 
ea2016f
 
 
 
ea96e7c
 
ea2016f
5a53f13
f9bb946
ea2016f
81cd1ed
40f9579
ea96e7c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
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()