Grow-Kids / app.py
sabahat-shakeel's picture
Update app.py
0c62144 verified
import gradio as gr
import pandas as pd
import os
import cv2
import mediapipe as mp
from datetime import datetime, timedelta
import random
import firebase_admin
from firebase_admin import credentials, firestore
# Firebase Initialization
if not firebase_admin._apps:
try:
cred = credentials.Certificate("active-kids-hub-firebase-adminsdk-n54dr-c3507e5704.json") # Replace with your Firebase credentials JSON file
firebase_admin.initialize_app(cred)
db = firestore.client()
print("Firebase initialized successfully!")
except Exception as e:
print(f"Error initializing Firebase: {e}")
raise e # Reraise to stop further execution if Firebase setup fails
# MediaPipe Pose Detection Setup
mp_pose = mp.solutions.pose
pose = mp_pose.Pose(static_image_mode=False, model_complexity=1, enable_segmentation=True)
mp_drawing = mp.solutions.drawing_utils
def analyze_pose(proof_file, task):
"""Analyze uploaded image/video to detect pose and validate the task."""
try:
if proof_file.name.endswith(('.jpg', '.jpeg', '.png')): # Image proof
image = cv2.imread(proof_file.name)
if image is None:
return "Invalid image file. Please retry."
image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
results = pose.process(image_rgb)
if results.pose_landmarks:
return f"Pose detected successfully for '{task}'! Proof is valid."
else:
return f"No pose detected in the uploaded image for '{task}'. Please retry."
elif proof_file.name.endswith(('.mp4', '.avi', '.mov')): # Video proof
cap = cv2.VideoCapture(proof_file.name)
pose_detected = False
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
image_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
results = pose.process(image_rgb)
if results.pose_landmarks:
pose_detected = True
break
cap.release()
return (
f"Pose detected successfully in video for '{task}'! Proof is valid."
if pose_detected
else f"No pose detected in video for '{task}'. Please retry."
)
else:
return "Invalid file format. Please upload an image or video."
except Exception as e:
print(f"Error in analyze_pose: {e}")
return f"Error analyzing the file: {e}"
def submit_proof(username, task, proof):
"""Submit proof of task completion and validate using pose analysis."""
try:
if not proof:
return "Please upload a valid proof file (Image/Video)."
# Validate if the task exists for the username in Firebase
user_doc = db.collection("users").document(username.lower()).get()
if not user_doc.exists:
return f"User '{username}' not found. Please check the username."
user_data = user_doc.to_dict()
user_tasks = user_data.get("tasks", [])
task_names = [t["task"] for t in user_tasks]
if task not in task_names:
return f"Task '{task}' not found for the user '{username}'. Please check the task name."
# Check if proof has already been uploaded for the task
for t in user_tasks:
if t["task"] == task and t.get("proof_uploaded"):
return f"Proof already uploaded for task '{task}'. Please upload a new proof if necessary."
# Analyze the proof file
analysis_result = analyze_pose(proof, task)
if "successfully" not in analysis_result:
return analysis_result
# Log proof submission in Firebase (without assigning reward)
try:
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
# Update the task status to 'completed' but do not assign a reward here
for t in user_tasks:
if t["task"] == task:
t["status"] = "completed"
t["timestamp"] = timestamp
t["proof_uploaded"] = True # Mark that proof has been uploaded
# Save updated task status in Firebase
db.collection("users").document(username.lower()).set({"tasks": user_tasks}, merge=True)
print(f"Proof for task '{task}' submitted successfully for {username}!")
return f"Task '{task}' completed successfully! Please assign a reward in the 'Progress and Rewards Tracker' tab."
except Exception as e:
print(f"Error logging proof submission in Firebase: {e}")
return f"Error submitting proof to Firebase: {e}"
except Exception as e:
print(f"Error submitting proof: {e}")
return f"Error: {e}"
def generate_fitness_tasks(username, age, fitness_level):
"""Generate a single fitness task based on user's age and fitness level."""
try:
age = int(age) # Convert age to integer
if not (7 <= age <= 14):
return "Age must be between 7 and 14.", "" # Early return on invalid age
if fitness_level not in ["beginner", "intermediate", "advanced"]:
return "Please select a valid fitness level.", "" # Early return on invalid fitness level
# Task definitions based on age and fitness level
tasks = {
(7, 10): {
"beginner": {"task": "Jumping Jacks", "details": "10 reps"},
"intermediate": {"task": "Push-ups", "details": "10 reps"},
"advanced": {"task": "Squats", "details": "10 reps"},
},
(11, 12): {
"beginner": {"task": "Jumping Jacks", "details": "15 reps"},
"intermediate": {"task": "Push-ups", "details": "15 reps"},
"advanced": {"task": "Squats", "details": "15 reps"},
},
(13, 14): {
"beginner": {"task": "Jumping Jacks", "details": "20 reps"},
"intermediate": {"task": "Push-ups", "details": "20 reps"},
"advanced": {"task": "Squats", "details": "20 reps"},
}
}
# Determine the task set based on age and fitness level
for age_range, level_tasks in tasks.items():
if age_range[0] <= age <= age_range[1]:
selected_task = level_tasks[fitness_level]
break
else:
return "Invalid age range. Tasks not available.", ""
# Save the task in Firebase for the user
user_doc = db.collection("users").document(username.lower()).get()
if not user_doc.exists:
return f"User '{username}' not found. Please sign up first.", ""
task_list = [{"task": selected_task["task"], "details": selected_task["details"], "status": "pending", "proof_uploaded": False}]
db.collection("users").document(username.lower()).set({"tasks": task_list}, merge=True)
# Return task and a message
task_display = f"{selected_task['task']} - {selected_task['details']}"
return f"Task generated successfully for {username}.", task_display
except Exception as e:
print(f"Error in generate_fitness_tasks: {e}")
return f"Error generating tasks: {e}", ""
def view_activity_log(username):
"""Retrieve and display user's activity log from Firebase."""
try:
# Fetch user data from Firebase
user_doc = db.collection("users").document(username.lower()).get()
if not user_doc.exists:
return f"User '{username}' not found."
user_data = user_doc.to_dict()
user_tasks = user_data.get("tasks", [])
# Convert task data into a pandas DataFrame for display
tasks_data = [
{
"Task": task["task"],
"Details": task["details"],
"Status": task["status"],
"Timestamp": task.get("timestamp", "Not available"),
"Proof Uploaded": task.get("proof_uploaded", False),
"Reward": task.get("reward", "Not assigned")
}
for task in user_tasks
]
df = pd.DataFrame(tasks_data)
return df
except Exception as e:
print(f"Error fetching activity log: {e}")
return f"Error fetching activity log: {e}"
def assign_reward(username, task, reward):
"""Assign reward to a task for a specific user."""
try:
# Fetch user data from Firebase
user_doc = db.collection("users").document(username.lower()).get()
if not user_doc.exists:
return f"User '{username}' not found."
user_data = user_doc.to_dict()
user_tasks = user_data.get("tasks", [])
# Check if the task exists and is completed
for t in user_tasks:
if t["task"] == task and t.get("status") == "completed":
t["reward"] = reward # Assign the reward
db.collection("users").document(username.lower()).set({"tasks": user_tasks}, merge=True)
return f"Reward '{reward}' assigned to task '{task}' for user '{username}'."
return f"Task '{task}' not completed or not found for user '{username}'."
except Exception as e:
print(f"Error assigning reward: {e}")
return f"Error assigning reward: {e}"
def create_app():
with gr.Blocks() as app:
gr.Markdown("## Fitness Challenge App with Firebase Integration")
# Sign Up / Login
with gr.Tab("Sign Up / Login"):
username_input = gr.Textbox(label="Enter Username")
password_input = gr.Textbox(label="Enter Password", type="password") # Password field
sign_up_login_btn = gr.Button("Sign Up / Login")
sign_up_login_status = gr.Textbox(label="Status")
def handle_sign_up_login(username, password):
try:
user_doc = db.collection("users").document(username.lower()).get()
if user_doc.exists:
stored_password = user_doc.get("password")
if stored_password == password:
return f"Welcome back, {username}!", None # If password matches, login success
else:
return "Incorrect password. Please try again.", None
else:
# If user does not exist, sign up
db.collection("users").document(username.lower()).set({"username": username.lower(), "password": password}, merge=True)
return f"Sign-up successful! Welcome, {username}!", None
except Exception as e:
return f"Error: {e}", None
sign_up_login_btn.click(handle_sign_up_login, [username_input, password_input], sign_up_login_status)
# Generate Tasks
with gr.Tab("Generate Tasks"):
username_gen = gr.Textbox(label="Enter Username")
age = gr.Textbox(label="Enter Age (7-14)", placeholder="E.g., 10")
fitness_level = gr.Radio(["beginner", "intermediate", "advanced"], label="Fitness Level")
generate_btn = gr.Button("Generate Tasks")
task_output = gr.Textbox(label="Task Status")
task_display = gr.Textbox(label="Generated Task", interactive=False)
generate_btn.click(generate_fitness_tasks, [username_gen, age, fitness_level], [task_output, task_display])
# Submit Proof
with gr.Tab("Submit Proof"):
username_proof = gr.Textbox(label="Enter Username")
task_name = gr.Textbox(label="Enter Task Name")
proof_upload = gr.File(label="Upload Proof (Image/Video)")
submit_btn = gr.Button("Submit Proof")
submission_status = gr.Textbox(label="Submission Status")
submit_btn.click(submit_proof, [username_proof, task_name, proof_upload], submission_status)
# Progress and Rewards Tracker
with gr.Tab("Progress and Rewards Tracker"):
username_log = gr.Textbox(label="Enter Username")
log_output = gr.DataFrame(label="Progress and Rewards")
log_btn = gr.Button("View Tracker")
reward_selector = gr.Radio(["Toy", "Little Buck", "Chocolate"], label="Select Reward")
task_to_reward = gr.Textbox(label="Task Name to Assign Reward")
assign_btn = gr.Button("Assign Reward")
reward_status = gr.Textbox(label="Reward Assignment Status")
log_btn.click(view_activity_log, [username_log], log_output)
assign_btn.click(assign_reward, [username_log, task_to_reward, reward_selector], reward_status)
return app
app = create_app()
app.launch()