faryalnimra commited on
Commit
cca30a6
·
verified ·
1 Parent(s): 8c7c767

Upload folder using huggingface_hub

Browse files
.idea/.gitignore ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ # Default ignored files
2
+ /shelf/
3
+ /workspace.xml
.idea/backend.iml ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <module type="PYTHON_MODULE" version="4">
3
+ <component name="NewModuleRootManager">
4
+ <content url="file://$MODULE_DIR$" />
5
+ <orderEntry type="inheritedJdk" />
6
+ <orderEntry type="sourceFolder" forTests="false" />
7
+ </component>
8
+ </module>
.idea/inspectionProfiles/profiles_settings.xml ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ <component name="InspectionProjectProfileManager">
2
+ <settings>
3
+ <option name="USE_PROJECT_PROFILE" value="false" />
4
+ <version value="1.0" />
5
+ </settings>
6
+ </component>
.idea/misc.xml ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="Black">
4
+ <option name="sdkName" value="Python 3.8 (predict sales-20240912T033332Z-001)" />
5
+ </component>
6
+ <component name="ProjectRootManager" version="2" project-jdk-name="Python 3.8 (predict sales-20240912T033332Z-001)" project-jdk-type="Python SDK" />
7
+ </project>
.idea/modules.xml ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="ProjectModuleManager">
4
+ <modules>
5
+ <module fileurl="file://$PROJECT_DIR$/.idea/backend.iml" filepath="$PROJECT_DIR$/.idea/backend.iml" />
6
+ </modules>
7
+ </component>
8
+ </project>
.idea/workspace.xml ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="ChangeListManager">
4
+ <list default="true" id="853fda89-837b-4955-a3c2-fb7c30d78d57" name="Changes" comment="" />
5
+ <option name="SHOW_DIALOG" value="false" />
6
+ <option name="HIGHLIGHT_CONFLICTS" value="true" />
7
+ <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
8
+ <option name="LAST_RESOLUTION" value="IGNORE" />
9
+ </component>
10
+ <component name="FileTemplateManagerImpl">
11
+ <option name="RECENT_TEMPLATES">
12
+ <list>
13
+ <option value="Python Script" />
14
+ </list>
15
+ </option>
16
+ </component>
17
+ <component name="ProjectColorInfo"><![CDATA[{
18
+ "associatedIndex": 4
19
+ }]]></component>
20
+ <component name="ProjectId" id="2xXey8EmVFqrSUWnQ8gkJgeV09q" />
21
+ <component name="ProjectViewState">
22
+ <option name="autoscrollToSource" value="true" />
23
+ <option name="hideEmptyMiddlePackages" value="true" />
24
+ <option name="showLibraryContents" value="true" />
25
+ </component>
26
+ <component name="PropertiesComponent"><![CDATA[{
27
+ "keyToString": {
28
+ "RunOnceActivity.OpenProjectViewOnStart": "true",
29
+ "RunOnceActivity.ShowReadmeOnStart": "true",
30
+ "last_opened_file_path": "C:/Users/PMLS/Desktop/backend"
31
+ }
32
+ }]]></component>
33
+ <component name="SharedIndexes">
34
+ <attachedChunks>
35
+ <set>
36
+ <option value="bundled-python-sdk-67fca87a943a-d3b881c8e49f-com.jetbrains.pycharm.community.sharedIndexes.bundled-PC-233.11799.259" />
37
+ </set>
38
+ </attachedChunks>
39
+ </component>
40
+ <component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
41
+ <component name="TaskManager">
42
+ <task active="true" id="Default" summary="Default task">
43
+ <changelist id="853fda89-837b-4955-a3c2-fb7c30d78d57" name="Changes" comment="" />
44
+ <created>1748089096862</created>
45
+ <option name="number" value="Default" />
46
+ <option name="presentableId" value="Default" />
47
+ <updated>1748089096862</updated>
48
+ </task>
49
+ <servers />
50
+ </component>
51
+ </project>
app.py ADDED
@@ -0,0 +1,307 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from flask import Flask, request, jsonify, render_template, url_for
2
+ from flask_cors import CORS # Import CORS
3
+ import torch
4
+ import torch.nn as nn
5
+ from torchvision import models, transforms
6
+ from PIL import Image
7
+ from huggingface_hub import hf_hub_download # Make sure this import is included
8
+ import os
9
+ from mtcnn import MTCNN
10
+ import cv2
11
+ from flask_bcrypt import generate_password_hash, check_password_hash
12
+ from flask_cors import CORS
13
+ from pymongo import MongoClient
14
+ import numpy as np
15
+ from flask import Flask, request, jsonify
16
+ from werkzeug.security import generate_password_hash, check_password_hash
17
+ from pymongo import MongoClient
18
+ import logging
19
+ from flask import Flask, request, jsonify, url_for
20
+ from flask_cors import CORS
21
+ from werkzeug.utils import secure_filename
22
+ import os
23
+ from PIL import Image
24
+ import matplotlib.pyplot as plt
25
+ import numpy as np
26
+ import seaborn as sns
27
+ import matplotlib.pyplot as plt
28
+
29
+
30
+ # Setup logging
31
+ logging.basicConfig(level=logging.INFO)
32
+
33
+
34
+ app = Flask(__name__, template_folder="templates", static_folder="static")
35
+ CORS(app) # Enable CORS for the Flask app
36
+
37
+ device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
38
+ UPLOAD_FOLDER = "static/uploads"
39
+ os.makedirs(UPLOAD_FOLDER, exist_ok=True)
40
+
41
+ # Load Model Function
42
+ def load_model_from_hf(repo_id, filename, num_classes):
43
+ model_path = hf_hub_download(repo_id=repo_id, filename=filename)
44
+ model = models.convnext_tiny(weights=None)
45
+ in_features = model.classifier[2].in_features
46
+ model.classifier[2] = nn.Linear(in_features, num_classes)
47
+ model.load_state_dict(torch.load(model_path, map_location=device))
48
+ model.to(device)
49
+ model.eval()
50
+ return model
51
+
52
+ # Load Models
53
+ deepfake_model = load_model_from_hf("faryalnimra/DFDC-detection-model", "DFDC.pth", 2)
54
+ cheapfake_model = load_model_from_hf("faryalnimra/ORIG-TAMP", "ORIG-TAMP.pth", 1)
55
+ realfake_model = load_model_from_hf("faryalnimra/RealFake", "real_fake.pth", 1) # New model added (only loaded, not used)
56
+
57
+ # Image Preprocessing
58
+ transform = transforms.Compose([
59
+ transforms.ToTensor(),
60
+ transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
61
+ ])
62
+
63
+ face_detector = MTCNN()
64
+
65
+ def detect_face(image_path):
66
+ image = cv2.imread(image_path)
67
+ image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
68
+ faces = face_detector.detect_faces(image_rgb)
69
+ face_count = sum(1 for face in faces if face.get("confidence", 0) > 0.90 and face.get("box", [0, 0, 0, 0])[2] > 30)
70
+ return face_count
71
+
72
+ @app.route("/predict", methods=["POST"])
73
+ def predict():
74
+ if "file" not in request.files:
75
+ return jsonify({"error": "No file uploaded"}), 400
76
+
77
+ file = request.files["file"]
78
+ filename = os.path.join(UPLOAD_FOLDER, file.filename)
79
+ file.save(filename)
80
+
81
+ try:
82
+ image = Image.open(filename).convert("RGB")
83
+ image_tensor = transform(image).unsqueeze(0).to(device)
84
+ except Exception as e:
85
+ return jsonify({"error": "Error processing image", "details": str(e)}), 500
86
+
87
+ with torch.no_grad():
88
+ deepfake_probs = torch.softmax(deepfake_model(image_tensor), dim=1)[0]
89
+ deepfake_confidence_before = deepfake_probs[1].item() * 100
90
+ cheapfake_confidence_before = torch.sigmoid(cheapfake_model(image_tensor)).item() * 100
91
+
92
+ face_count = detect_face(filename)
93
+ face_factor = min(face_count / 2, 1)
94
+
95
+ if deepfake_confidence_before <= cheapfake_confidence_before:
96
+ adjusted_deepfake_confidence = deepfake_confidence_before * (1 + 0.3 * face_factor)
97
+ adjusted_cheapfake_confidence = cheapfake_confidence_before * (1 - 0.3 * face_factor)
98
+ else:
99
+ adjusted_deepfake_confidence = deepfake_confidence_before
100
+ adjusted_cheapfake_confidence = cheapfake_confidence_before
101
+
102
+ fake_type = "Deepfake" if adjusted_deepfake_confidence > adjusted_cheapfake_confidence else "Cheapfake"
103
+ # Print the result to the terminal
104
+ print(f"Prediction: Fake")
105
+ print(f"Fake Type: {fake_type}")
106
+ print(f"Deepfake Confidence Before: {deepfake_confidence_before:.2f}%")
107
+ print(f"Deepfake Confidence Adjusted: {adjusted_deepfake_confidence:.2f}%")
108
+ print(f"Cheapfake Confidence Before: {cheapfake_confidence_before:.2f}%")
109
+ print(f"Cheapfake Confidence Adjusted: {adjusted_cheapfake_confidence:.2f}%")
110
+ print(f"Faces Detected: {face_count}")
111
+ print(f"Image URL: {url_for('static', filename=f'uploads/{file.filename}')}")
112
+
113
+ return jsonify({
114
+ "prediction": "Fake",
115
+ "fake_type": fake_type,
116
+ "deepfake_confidence_before": f"{deepfake_confidence_before:.2f}%",
117
+ "deepfake_confidence_adjusted": f"{adjusted_deepfake_confidence:.2f}%",
118
+ "cheapfake_confidence_before": f"{cheapfake_confidence_before:.2f}%",
119
+ "cheapfake_confidence_adjusted": f"{adjusted_cheapfake_confidence:.2f}%",
120
+ "faces_detected": face_count,
121
+ "image_url": url_for("static", filename=f"uploads/{file.filename}")
122
+ })
123
+
124
+ HEATMAP_FOLDER = "static/heatmaps"
125
+ os.makedirs(HEATMAP_FOLDER, exist_ok=True)
126
+
127
+
128
+ ALLOWED_EXTENSIONS = {"png", "jpg", "jpeg"} # Allow these extensions
129
+ UPLOAD_FOLDER = "static/uploads"
130
+ HEATMAP_FOLDER = "static/heatmaps"
131
+
132
+ os.makedirs(UPLOAD_FOLDER, exist_ok=True)
133
+ os.makedirs(HEATMAP_FOLDER, exist_ok=True)
134
+
135
+ # Check if the uploaded file has an allowed extension
136
+ def allowed_file(filename):
137
+ return "." in filename and filename.rsplit(".", 1)[1].lower() in ALLOWED_EXTENSIONS
138
+
139
+ # ✨ Heatmap generator (Grid based)
140
+ def generate_heatmap(original_image_path, heatmap_save_path):
141
+ try:
142
+ print(f"Opening image: {original_image_path}") # Debug print
143
+ img = Image.open(original_image_path).convert("L") # Convert to Grayscale
144
+ print(f"Image opened successfully: {original_image_path}") # Debug print
145
+
146
+ img = img.resize((20, 20)) # Resize to small grid (adjust as needed)
147
+ print(f"Image resized to: {img.size}") # Debug print
148
+
149
+ img_array = np.array(img)
150
+
151
+ plt.figure(figsize=(10, 8))
152
+ sns.heatmap(img_array, cmap="coolwarm", cbar=True, square=True, linewidths=0.5)
153
+
154
+ plt.axis('off') # Hide axis if you want
155
+ plt.savefig(heatmap_save_path, bbox_inches='tight', pad_inches=0)
156
+ plt.close()
157
+ print(f"Heatmap saved to: {heatmap_save_path}") # Debug print
158
+ except Exception as e:
159
+ print(f"Heatmap generation failed for {original_image_path}: {e}") # Print specific error
160
+
161
+ @app.route("/generate_heatmap", methods=["POST"])
162
+ def generate_heatmap_api():
163
+ if "file" not in request.files:
164
+ return jsonify({"error": "No file uploaded"}), 400
165
+
166
+ file = request.files["file"]
167
+
168
+ if file.filename == "" or not allowed_file(file.filename):
169
+ return jsonify({"error": "Invalid file type. Allowed types are .png, .jpg, .jpeg, .tif, .tiff"}), 400
170
+
171
+ filename = secure_filename(file.filename)
172
+ original_image_path = os.path.join(UPLOAD_FOLDER, filename)
173
+
174
+ try:
175
+ file.save(original_image_path)
176
+ print(f"File saved to: {original_image_path}") # Debug print
177
+ except Exception as e:
178
+ print(f"Error saving file: {e}")
179
+ return jsonify({"error": "Failed to save the file"}), 500
180
+
181
+ heatmap_filename = f"heatmap_{filename}"
182
+ heatmap_path = os.path.join(HEATMAP_FOLDER, heatmap_filename)
183
+
184
+ generate_heatmap(original_image_path, heatmap_path)
185
+
186
+ return jsonify({
187
+ "original_image_url": url_for("static", filename=f"uploads/{filename}", _external=True),
188
+ "heatmap_image_url": url_for("static", filename=f"heatmaps/{heatmap_filename}", _external=True)
189
+ })
190
+
191
+
192
+ #MongoDB Atlantis from flask import Flask, request, jsonify
193
+
194
+
195
+ # MongoDB connection
196
+ client = MongoClient('mongodb+srv://fakecatcherai:sX_W9!SUigNS.ww@cluster0.pwyazjb.mongodb.net/?retryWrites=true&w=majority&appName=Cluster0')
197
+ db = client['fakecatcherDB']
198
+ users_collection = db['users']
199
+ contacts_collection = db['contacts']
200
+
201
+ def is_valid_password(password):
202
+ if (len(password) < 8 or
203
+ not re.search(r'[A-Z]', password) or
204
+ not re.search(r'[a-z]', password) or
205
+ not re.search(r'[0-9]', password) or
206
+ not re.search(r'[!@#$%^&*(),.?":{}|<>]', password)):
207
+ return False
208
+ return True
209
+
210
+ @app.route('/Register', methods=['POST'])
211
+ def register():
212
+ data = request.get_json()
213
+ first_name = data.get('firstName')
214
+ last_name = data.get('lastName')
215
+ email = data.get('email')
216
+ password = data.get('password')
217
+
218
+ if users_collection.find_one({'email': email}):
219
+ logging.warning(f"Attempted register with existing email: {email}")
220
+ return jsonify({'message': 'Email already exists!'}), 400
221
+
222
+ # ✅ Password constraints check
223
+ if not is_valid_password(password):
224
+ return jsonify({'message': 'Password must be at least 8 characters long and include uppercase, lowercase, number, and special character.'}), 400
225
+
226
+ hashed_pw = generate_password_hash(password)
227
+ users_collection.insert_one({
228
+ 'first_name': first_name,
229
+ 'last_name': last_name,
230
+ 'email': email,
231
+ 'password': hashed_pw
232
+ })
233
+
234
+ logging.info(f"New user registered: {first_name} {last_name}, Email: {email}")
235
+ return jsonify({'message': 'Registration successful!'}), 201
236
+
237
+ # 🔵 Login Route
238
+ @app.route('/Login', methods=['POST'])
239
+ def login():
240
+ data = request.get_json()
241
+ email = data.get('email')
242
+ password = data.get('password')
243
+
244
+ # Check if the user exists
245
+ user = users_collection.find_one({'email': email})
246
+ if not user or not check_password_hash(user['password'], password):
247
+ logging.warning(f"Failed login attempt for email: {email}")
248
+ return jsonify({'message': 'Invalid email or password!'}), 401
249
+
250
+ logging.info(f"User logged in successfully: {email}")
251
+ return jsonify({'message': 'Login successful!'}), 200
252
+ @app.route('/ForgotPassword', methods=['POST'])
253
+ def forgot_password():
254
+ data = request.get_json()
255
+ email = data.get('email')
256
+ new_password = data.get('newPassword')
257
+ confirm_password = data.get('confirmPassword')
258
+
259
+ # Check if passwords match
260
+ if new_password != confirm_password:
261
+ logging.warning(f"Password reset failed. Passwords do not match for email: {email}")
262
+ return jsonify({'message': 'Passwords do not match!'}), 400
263
+
264
+ # Check if the user exists
265
+ user = users_collection.find_one({'email': email})
266
+ if not user:
267
+ logging.warning(f"Password reset attempt for non-existent email: {email}")
268
+ return jsonify({'message': 'User not found!'}), 404
269
+
270
+ # Hash the new password and update it
271
+ hashed_pw = generate_password_hash(new_password)
272
+ users_collection.update_one({'email': email}, {'$set': {'password': hashed_pw}})
273
+
274
+ logging.info(f"Password successfully reset for email: {email}")
275
+ return jsonify({'message': 'Password updated successfully!'}), 200
276
+
277
+
278
+
279
+
280
+
281
+
282
+ # 🟣 Contact Form Route (React Page: Contact)
283
+ @app.route('/Contact', methods=['POST'])
284
+ def contact():
285
+ data = request.get_json()
286
+ email = data.get('email')
287
+ query = data.get('query')
288
+ message = data.get('message')
289
+
290
+ # Check if all fields are provided
291
+ if not email or not query or not message:
292
+ logging.warning(f"Incomplete contact form submission from email: {email}")
293
+ return jsonify({'message': 'All fields are required!'}), 400
294
+
295
+ # Insert the contact data
296
+ contact_data = {
297
+ 'email': email,
298
+ 'query': query,
299
+ 'message': message
300
+ }
301
+ contacts_collection.insert_one(contact_data)
302
+
303
+ logging.info(f"Contact form submitted successfully from email: {email}")
304
+ return jsonify({'message': 'Your message has been sent successfully.'}), 200
305
+
306
+ if __name__ == '__main__':
307
+ app.run(debug=True)
requirements.txt ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Deep learning
2
+ torch==2.2.2
3
+ torchvision
4
+ facenet-pytorch
5
+
6
+ # Flask & Web
7
+ Flask
8
+ Flask-Bcrypt
9
+ Flask-Cors
10
+ Werkzeug
11
+ Jinja2
12
+ itsdangerous
13
+
14
+ # Image, ML, and Data
15
+ opencv-python
16
+ opencv-contrib-python
17
+ pillow
18
+ numpy
19
+ scikit-learn
20
+ pandas
21
+ matplotlib
22
+ seaborn
23
+ mediapipe
24
+ mtcnn
25
+ retina-face
26
+ transformers
27
+ huggingface-hub
28
+ gdown
29
+
30
+ # Utility & Auth
31
+ requests
32
+ requests-oauthlib
33
+ google-auth
34
+ google-auth-oauthlib
35
+ PyQt5
36
+ fpdf
37
+ bcrypt
38
+ dnspython
39
+ pymongo
40
+
41
+ # Logging & Plotting
42
+ tensorboard
43
+
44
+ # Environment
45
+ virtualenv
46
+ gunicorn
test.py ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ from huggingface_hub import HfApi
2
+
3
+ api = HfApi()
4
+
5
+ api.upload_folder(
6
+ folder_path=r"C:\Users\PMLS\Desktop\backend",
7
+ repo_id="faryalnimra/backend",
8
+ repo_type="space"
9
+ )