sabahat-shakeel commited on
Commit
50480c6
·
verified ·
1 Parent(s): d4f49e1

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +285 -0
app.py ADDED
@@ -0,0 +1,285 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import pandas as pd
3
+ import os
4
+ import cv2
5
+ import mediapipe as mp
6
+ from datetime import datetime, timedelta
7
+ import random
8
+ import firebase_admin
9
+ from firebase_admin import credentials, firestore
10
+
11
+ # Firebase Initialization
12
+ if not firebase_admin._apps:
13
+ try:
14
+ cred = credentials.Certificate("growkids-f8bfe-firebase-adminsdk-koo88-8a3a33da6d") # Replace with your Firebase credentials JSON file
15
+ firebase_admin.initialize_app(cred)
16
+ db = firestore.client()
17
+ print("Firebase initialized successfully!")
18
+ except Exception as e:
19
+ print(f"Error initializing Firebase: {e}")
20
+ raise e # Reraise to stop further execution if Firebase setup fails
21
+
22
+ # MediaPipe Pose Detection Setup
23
+ mp_pose = mp.solutions.pose
24
+ pose = mp_pose.Pose(static_image_mode=False, model_complexity=1, enable_segmentation=True)
25
+ mp_drawing = mp.solutions.drawing_utils
26
+
27
+ def analyze_pose(proof_file, task):
28
+ """Analyze uploaded image/video to detect pose and validate the task."""
29
+ try:
30
+ if proof_file.name.endswith(('.jpg', '.jpeg', '.png')): # Image proof
31
+ image = cv2.imread(proof_file.name)
32
+ if image is None:
33
+ return "Invalid image file. Please retry."
34
+ image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
35
+ results = pose.process(image_rgb)
36
+ if results.pose_landmarks:
37
+ return f"Pose detected successfully for '{task}'! Proof is valid."
38
+ else:
39
+ return f"No pose detected in the uploaded image for '{task}'. Please retry."
40
+ elif proof_file.name.endswith(('.mp4', '.avi', '.mov')): # Video proof
41
+ cap = cv2.VideoCapture(proof_file.name)
42
+ pose_detected = False
43
+ while cap.isOpened():
44
+ ret, frame = cap.read()
45
+ if not ret:
46
+ break
47
+ image_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
48
+ results = pose.process(image_rgb)
49
+ if results.pose_landmarks:
50
+ pose_detected = True
51
+ break
52
+ cap.release()
53
+ return (
54
+ f"Pose detected successfully in video for '{task}'! Proof is valid."
55
+ if pose_detected
56
+ else f"No pose detected in video for '{task}'. Please retry."
57
+ )
58
+ else:
59
+ return "Invalid file format. Please upload an image or video."
60
+ except Exception as e:
61
+ print(f"Error in analyze_pose: {e}")
62
+ return f"Error analyzing the file: {e}"
63
+
64
+ def submit_proof(username, task, proof):
65
+ """Submit proof of task completion and validate using pose analysis."""
66
+ try:
67
+ if not proof:
68
+ return "Please upload a valid proof file (Image/Video)."
69
+
70
+ # Validate if the task exists for the username in Firebase
71
+ user_doc = db.collection("users").document(username.lower()).get()
72
+ if not user_doc.exists:
73
+ return f"User '{username}' not found. Please check the username."
74
+
75
+ user_data = user_doc.to_dict()
76
+ user_tasks = user_data.get("tasks", [])
77
+ task_names = [t["task"] for t in user_tasks]
78
+ if task not in task_names:
79
+ return f"Task '{task}' not found for the user '{username}'. Please check the task name."
80
+
81
+ # Check if proof has already been uploaded for the task
82
+ for t in user_tasks:
83
+ if t["task"] == task and t.get("proof_uploaded"):
84
+ return f"Proof already uploaded for task '{task}'. Please upload a new proof if necessary."
85
+
86
+ # Analyze the proof file
87
+ analysis_result = analyze_pose(proof, task)
88
+ if "successfully" not in analysis_result:
89
+ return analysis_result
90
+
91
+ # Log proof submission in Firebase (without assigning reward)
92
+ try:
93
+ timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
94
+ # Update the task status to 'completed' but do not assign a reward here
95
+ for t in user_tasks:
96
+ if t["task"] == task:
97
+ t["status"] = "completed"
98
+ t["timestamp"] = timestamp
99
+ t["proof_uploaded"] = True # Mark that proof has been uploaded
100
+
101
+ # Save updated task status in Firebase
102
+ db.collection("users").document(username.lower()).set({"tasks": user_tasks}, merge=True)
103
+
104
+ print(f"Proof for task '{task}' submitted successfully for {username}!")
105
+ return f"Task '{task}' completed successfully! Please assign a reward in the 'Progress and Rewards Tracker' tab."
106
+ except Exception as e:
107
+ print(f"Error logging proof submission in Firebase: {e}")
108
+ return f"Error submitting proof to Firebase: {e}"
109
+ except Exception as e:
110
+ print(f"Error submitting proof: {e}")
111
+ return f"Error: {e}"
112
+
113
+ def generate_fitness_tasks(username, age, fitness_level):
114
+ """Generate a single fitness task based on user's age and fitness level."""
115
+ try:
116
+ age = int(age) # Convert age to integer
117
+ if not (7 <= age <= 14):
118
+ return "Age must be between 7 and 14.", "" # Early return on invalid age
119
+
120
+ if fitness_level not in ["beginner", "intermediate", "advanced"]:
121
+ return "Please select a valid fitness level.", "" # Early return on invalid fitness level
122
+
123
+ # Task definitions based on age and fitness level
124
+ tasks = {
125
+ (7, 10): {
126
+ "beginner": {"task": "Jumping Jacks", "details": "10 reps"},
127
+ "intermediate": {"task": "Push-ups", "details": "10 reps"},
128
+ "advanced": {"task": "Squats", "details": "10 reps"},
129
+ },
130
+ (11, 12): {
131
+ "beginner": {"task": "Jumping Jacks", "details": "15 reps"},
132
+ "intermediate": {"task": "Push-ups", "details": "15 reps"},
133
+ "advanced": {"task": "Squats", "details": "15 reps"},
134
+ },
135
+ (13, 14): {
136
+ "beginner": {"task": "Jumping Jacks", "details": "20 reps"},
137
+ "intermediate": {"task": "Push-ups", "details": "20 reps"},
138
+ "advanced": {"task": "Squats", "details": "20 reps"},
139
+ }
140
+ }
141
+
142
+ # Determine the task set based on age and fitness level
143
+ for age_range, level_tasks in tasks.items():
144
+ if age_range[0] <= age <= age_range[1]:
145
+ selected_task = level_tasks[fitness_level]
146
+ break
147
+ else:
148
+ return "Invalid age range. Tasks not available.", ""
149
+
150
+ # Save the task in Firebase for the user
151
+ user_doc = db.collection("users").document(username.lower()).get()
152
+ if not user_doc.exists:
153
+ return f"User '{username}' not found. Please sign up first.", ""
154
+
155
+ task_list = [{"task": selected_task["task"], "details": selected_task["details"], "status": "pending", "proof_uploaded": False}]
156
+ db.collection("users").document(username.lower()).set({"tasks": task_list}, merge=True)
157
+
158
+ # Return task and a message
159
+ task_display = f"{selected_task['task']} - {selected_task['details']}"
160
+ return f"Task generated successfully for {username}.", task_display
161
+ except Exception as e:
162
+ print(f"Error in generate_fitness_tasks: {e}")
163
+ return f"Error generating tasks: {e}", ""
164
+
165
+ def view_activity_log(username):
166
+ """Retrieve and display user's activity log from Firebase."""
167
+ try:
168
+ # Fetch user data from Firebase
169
+ user_doc = db.collection("users").document(username.lower()).get()
170
+ if not user_doc.exists:
171
+ return f"User '{username}' not found."
172
+
173
+ user_data = user_doc.to_dict()
174
+ user_tasks = user_data.get("tasks", [])
175
+
176
+ # Convert task data into a pandas DataFrame for display
177
+ tasks_data = [
178
+ {
179
+ "Task": task["task"],
180
+ "Details": task["details"],
181
+ "Status": task["status"],
182
+ "Timestamp": task.get("timestamp", "Not available"),
183
+ "Proof Uploaded": task.get("proof_uploaded", False),
184
+ "Reward": task.get("reward", "Not assigned")
185
+ }
186
+ for task in user_tasks
187
+ ]
188
+
189
+ df = pd.DataFrame(tasks_data)
190
+ return df
191
+ except Exception as e:
192
+ print(f"Error fetching activity log: {e}")
193
+ return f"Error fetching activity log: {e}"
194
+
195
+ def assign_reward(username, task, reward):
196
+ """Assign reward to a task for a specific user."""
197
+ try:
198
+ # Fetch user data from Firebase
199
+ user_doc = db.collection("users").document(username.lower()).get()
200
+ if not user_doc.exists:
201
+ return f"User '{username}' not found."
202
+
203
+ user_data = user_doc.to_dict()
204
+ user_tasks = user_data.get("tasks", [])
205
+
206
+ # Check if the task exists and is completed
207
+ for t in user_tasks:
208
+ if t["task"] == task and t.get("status") == "completed":
209
+ t["reward"] = reward # Assign the reward
210
+ db.collection("users").document(username.lower()).set({"tasks": user_tasks}, merge=True)
211
+ return f"Reward '{reward}' assigned to task '{task}' for user '{username}'."
212
+
213
+ return f"Task '{task}' not completed or not found for user '{username}'."
214
+
215
+ except Exception as e:
216
+ print(f"Error assigning reward: {e}")
217
+ return f"Error assigning reward: {e}"
218
+
219
+ def create_app():
220
+ with gr.Blocks() as app:
221
+ gr.Markdown("## Fitness Challenge App with Firebase Integration")
222
+
223
+ # Sign Up / Login
224
+ with gr.Tab("Sign Up / Login"):
225
+ username_input = gr.Textbox(label="Enter Username")
226
+ password_input = gr.Textbox(label="Enter Password", type="password") # Password field
227
+ sign_up_login_btn = gr.Button("Sign Up / Login")
228
+ sign_up_login_status = gr.Textbox(label="Status")
229
+
230
+ def handle_sign_up_login(username, password):
231
+ try:
232
+ user_doc = db.collection("users").document(username.lower()).get()
233
+ if user_doc.exists:
234
+ stored_password = user_doc.get("password")
235
+ if stored_password == password:
236
+ return f"Welcome back, {username}!", None # If password matches, login success
237
+ else:
238
+ return "Incorrect password. Please try again.", None
239
+ else:
240
+ # If user does not exist, sign up
241
+ db.collection("users").document(username.lower()).set({"username": username.lower(), "password": password}, merge=True)
242
+ return f"Sign-up successful! Welcome, {username}!", None
243
+ except Exception as e:
244
+ return f"Error: {e}", None
245
+
246
+ sign_up_login_btn.click(handle_sign_up_login, [username_input, password_input], sign_up_login_status)
247
+
248
+ # Generate Tasks
249
+ with gr.Tab("Generate Tasks"):
250
+ username_gen = gr.Textbox(label="Enter Username")
251
+ age = gr.Textbox(label="Enter Age (7-14)", placeholder="E.g., 10")
252
+ fitness_level = gr.Radio(["beginner", "intermediate", "advanced"], label="Fitness Level")
253
+ generate_btn = gr.Button("Generate Tasks")
254
+ task_output = gr.Textbox(label="Task Status")
255
+ task_display = gr.Textbox(label="Generated Task", interactive=False)
256
+
257
+ generate_btn.click(generate_fitness_tasks, [username_gen, age, fitness_level], [task_output, task_display])
258
+
259
+ # Submit Proof
260
+ with gr.Tab("Submit Proof"):
261
+ username_proof = gr.Textbox(label="Enter Username")
262
+ task_name = gr.Textbox(label="Enter Task Name")
263
+ proof_upload = gr.File(label="Upload Proof (Image/Video)")
264
+ submit_btn = gr.Button("Submit Proof")
265
+ submission_status = gr.Textbox(label="Submission Status")
266
+
267
+ submit_btn.click(submit_proof, [username_proof, task_name, proof_upload], submission_status)
268
+
269
+ # Progress and Rewards Tracker
270
+ with gr.Tab("Progress and Rewards Tracker"):
271
+ username_log = gr.Textbox(label="Enter Username")
272
+ log_output = gr.DataFrame(label="Progress and Rewards")
273
+ log_btn = gr.Button("View Tracker")
274
+ reward_selector = gr.Radio(["Toy", "Little Buck", "Chocolate"], label="Select Reward")
275
+ task_to_reward = gr.Textbox(label="Task Name to Assign Reward")
276
+ assign_btn = gr.Button("Assign Reward")
277
+ reward_status = gr.Textbox(label="Reward Assignment Status")
278
+
279
+ log_btn.click(view_activity_log, [username_log], log_output)
280
+ assign_btn.click(assign_reward, [username_log, task_to_reward, reward_selector], reward_status)
281
+
282
+ return app
283
+
284
+ app = create_app()
285
+ app.launch()