TrueFrame / app.py
Gaurav-Mhatre's picture
Update app.py
a55b197 verified
import os
import shutil
import certifi
from flask import Flask, request, render_template, redirect, url_for, session, flash
from authlib.integrations.flask_client import OAuth
from flask_pymongo import PyMongo
from werkzeug.security import generate_password_hash, check_password_hash
from frame_extractor import FrameExtractor
# --- IMPORT DETECTORS ---
from video_detect import VideoDeepfakeDetector
from image_detect import ImageDeepfakeDetector
from audio_detect import AudioDeepfakeDetector
from combined_detect import CombinedDeepfakeDetector # πŸ‘ˆ NEW FEATURE
app = Flask(__name__)
app.secret_key = 'super_secret_key_change_this_for_production'
app.config['GOOGLE_CLIENT_ID'] = os.environ.get("GOOGLE_CLIENT_ID")
app.config['GOOGLE_CLIENT_SECRET'] = os.environ.get("GOOGLE_CLIENT_SECRET")
app.config["MONGO_URI"] =os.environ.get("MONGO_URI")
app.config['SESSION_COOKIE_SECURE'] = False
app.config['SESSION_COOKIE_SAMESITE'] = 'Lax'
oauth = OAuth(app)
mongo = PyMongo(app, tls=True, tlsAllowInvalidCertificates=True)
google = oauth.register(
name='google',
client_id=app.config['GOOGLE_CLIENT_ID'],
client_secret=app.config['GOOGLE_CLIENT_SECRET'],
server_metadata_url='https://accounts.google.com/.well-known/openid-configuration',
client_kwargs={'scope': 'openid email profile'},
)
UPLOAD_FOLDER = 'uploads'
if os.path.exists(UPLOAD_FOLDER):
shutil.rmtree(UPLOAD_FOLDER)
os.makedirs(UPLOAD_FOLDER)
# ============================
# ⚑ GLOBALLY LOAD AI MODELS
# ============================
print("⚑ Starting Server & Pre-loading Audio Model...")
audio_detector = AudioDeepfakeDetector()
video_detector = None
image_detector = None
extractor = None
def get_video_detector():
global video_detector, extractor
if video_detector is None:
print("⚑ Loading Video AI Model...")
video_detector = VideoDeepfakeDetector()
extractor = FrameExtractor()
return video_detector, extractor
def get_image_detector():
global image_detector
if image_detector is None:
print("⚑ Loading Image AI Model...")
image_detector = ImageDeepfakeDetector()
return image_detector
# ============================
# πŸ” AUTHENTICATION ROUTES
# ============================
@app.route('/login', methods=['GET', 'POST'])
def login_page():
if session.get('logged_in'): return redirect(url_for('index'))
if request.method == 'POST':
email = request.form.get('email')
password = request.form.get('password')
try:
user = mongo.db.users.find_one({"email": email})
except Exception as e:
return f"❌ Database Connection Error: {e}"
if user and check_password_hash(user['password'], password):
session['logged_in'] = True
session['user_name'] = user['name']
session['user_email'] = user['email']
return redirect(url_for('index'))
else:
flash("Invalid email or password.")
return render_template('login.html')
@app.route('/register', methods=['GET', 'POST'])
def register():
if request.method == 'POST':
name = request.form.get('name')
email = request.form.get('email')
password = request.form.get('password')
try:
existing_user = mongo.db.users.find_one({"email": email})
if existing_user:
flash("Email already registered. Please login.")
return redirect(url_for('login_page'))
hashed_password = generate_password_hash(password)
mongo.db.users.insert_one({
"name": name,
"email": email,
"password": hashed_password,
"auth_type": "manual"
})
except Exception as e:
return f"❌ Database Error: {e}"
flash("Account created! Please login.")
return redirect(url_for('login_page'))
return render_template('register.html')
@app.route('/login/google')
def google_login():
redirect_uri = url_for('authorize', _external=True)
return google.authorize_redirect(redirect_uri)
@app.route('/authorize')
def authorize():
try:
token = google.authorize_access_token()
user_info = token.get('userinfo')
existing_user = mongo.db.users.find_one({"email": user_info['email']})
if not existing_user:
mongo.db.users.insert_one({
"name": user_info['name'],
"email": user_info['email'],
"picture": user_info['picture'],
"auth_type": "google",
"password": ""
})
session['logged_in'] = True
session['user_email'] = user_info['email']
session['user_name'] = user_info['name']
session['profile_pic'] = user_info.get('picture')
return redirect(url_for('index'))
except Exception as e:
return f"Login failed: {e}"
@app.route('/logout')
def logout():
session.clear()
return redirect(url_for('login_page'))
# ============================
# 🏠 MAIN APP ROUTE
# ============================
@app.route('/', methods=['GET', 'POST'])
def index():
if not session.get('logged_in'): return redirect(url_for('login_page'))
user_name = session.get('user_name', 'User')
if request.method == 'POST':
if 'file' not in request.files: return redirect(request.url)
file = request.files['file']
mode = request.form.get('mode')
if file.filename == '': return redirect(request.url)
if mode == 'audio':
filename = "input_audio.mp3"
file_path = os.path.join(UPLOAD_FOLDER, filename)
file.save(file_path)
verdict, confidence = audio_detector.predict(file_path)
css_class = "fake" if verdict == "DEEPFAKE DETECTED" else "real"
return render_template('result.html', result=verdict, css_class=css_class, confidence=f"{confidence*100:.1f}", type="Audio Only", extra_info="<p>Audio Analysis Complete</p>")
elif mode == 'image':
filename = "input_image.jpg"
file_path = os.path.join(UPLOAD_FOLDER, filename)
file.save(file_path)
detector = get_image_detector()
verdict, confidence = detector.predict(file_path)
css_class = "fake" if verdict == "DEEPFAKE DETECTED" else "real"
return render_template('result.html', result=verdict, css_class=css_class, confidence=f"{confidence*100:.1f}", type="Image", extra_info="<p>Image Analysis Complete</p>")
# πŸ‘‡ THE NEW COMBINED ROUTE πŸ‘‡
elif mode == 'combined':
filename = "input_combined.mp4"
video_path = os.path.join(UPLOAD_FOLDER, filename)
file.save(video_path)
v_detector, v_extractor = get_video_detector()
a_detector = audio_detector
combined_detector = CombinedDeepfakeDetector(a_detector, v_detector, v_extractor)
final_result, details = combined_detector.predict(video_path)
css_class = "fake" if final_result == "DEEPFAKE DETECTED" else "real"
return render_template('result.html', result=final_result, css_class=css_class, confidence="N/A", type="Video + Audio Combined", extra_info=details)
else: # Video Only Mode (Frames)
filename = "input_video.mp4"
video_path = os.path.join(UPLOAD_FOLDER, filename)
file.save(video_path)
v_detector, v_extractor = get_video_detector()
image_paths = v_extractor.extract(video_path)
if not image_paths: return "Error: Could not extract frames."
fake_votes = 0
for img_path in image_paths:
result, _ = v_detector.predict(img_path)
if result == "DEEPFAKE DETECTED": fake_votes += 1
final_result = "DEEPFAKE DETECTED" if fake_votes > (len(image_paths) * 0.51) else "REAL"
css_class = "fake" if final_result == "DEEPFAKE DETECTED" else "real"
return render_template('result.html', result=final_result, css_class=css_class, confidence="N/A", type="Video (Frames Only)", extra_info=f"<p>Analyzed {len(image_paths)} visual frames.</p>")
return render_template('index.html', user_name=user_name)
if __name__ == '__main__':
# Binds to 0.0.0.0 and port 7860 for Hugging Face Spaces
app.run(host='0.0.0.0', port=7860)