Spaces:
Sleeping
Sleeping
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() | |