Spaces:
Sleeping
Sleeping
| 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 | |
| # ============================ | |
| 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') | |
| 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') | |
| def google_login(): | |
| redirect_uri = url_for('authorize', _external=True) | |
| return google.authorize_redirect(redirect_uri) | |
| 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}" | |
| def logout(): | |
| session.clear() | |
| return redirect(url_for('login_page')) | |
| # ============================ | |
| # π MAIN APP ROUTE | |
| # ============================ | |
| 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) |