import gradio as gr import time from PIL import Image, ImageDraw, ImageFont import ssl # Asegura que el módulo ssl está disponible assert ssl, "El módulo ssl es necesario para ejecutar esta app." # Variables globales t1_time = 0 t2_time = 0 start_time = None active_team = None team1_stats = {"amarillas": 0, "rojas": 0, "corners": 0} team2_stats = {"amarillas": 0, "rojas": 0, "corners": 0} t1_name = "Equipo 1" t2_name = "Equipo 2" t1_logo = None t2_logo = None historial = [] cronometro = "00:00" # Cronómetro tipo ajedrez def start_possession(team): global start_time, active_team if active_team and start_time: elapsed = time.time() - start_time if active_team == t1_name: globals()['t1_time'] += elapsed elif active_team == t2_name: globals()['t2_time'] += elapsed start_time = time.time() active_team = team historial.append(f"{team} inicia posesión") return update_summary() def switch_possession(): global t1_time, t2_time, start_time, active_team if active_team and start_time: elapsed = time.time() - start_time if active_team == t1_name: t1_time += elapsed elif active_team == t2_name: t2_time += elapsed start_time = time.time() active_team = t1_name if active_team == t2_name else t2_name historial.append(f"Cambio de posesión: {active_team}") return update_summary() def show_stats(): if active_team and start_time: elapsed = time.time() - start_time temp_t1 = t1_time + (elapsed if active_team == t1_name else 0) temp_t2 = t2_time + (elapsed if active_team == t2_name else 0) else: temp_t1 = t1_time temp_t2 = t2_time total = temp_t1 + temp_t2 p1 = round((temp_t1 / total) * 100, 2) if total > 0 else 0 p2 = 100 - p1 if total > 0 else 0 mins = int(total) // 60 secs = int(total) % 60 globals()['cronometro'] = f"{mins:02}:{secs:02}" return f"{t1_name}: {p1}%", f"{t2_name}: {p2}%", generate_possession_bar(p1, p2), cronometro def add_stat(team, stat): if team == "1": team1_stats[stat] += 1 historial.append(f"{t1_name} - {stat.upper()} +1") else: team2_stats[stat] += 1 historial.append(f"{t2_name} - {stat.upper()} +1") return update_summary() def update_summary(): sum1 = f"{t1_name} - 🟨 {team1_stats['amarillas']} | 🔵 {team1_stats['rojas']} | ⚽ {team1_stats['corners']}" sum2 = f"{t2_name} - 🟨 {team2_stats['amarillas']} | 🔵 {team2_stats['rojas']} | ⚽ {team2_stats['corners']}" return sum1, sum2, "\n".join(historial) def set_team_info(name1, name2, logo1, logo2): global t1_name, t2_name, t1_logo, t2_logo t1_name = name1 t2_name = name2 t1_logo = logo1 t2_logo = logo2 return update_summary() def generate_possession_bar(p1, p2): bar = Image.new('RGB', (400, 40), color='black') draw = ImageDraw.Draw(bar) draw.rectangle([0, 0, int(p1 * 4), 40], fill='blue') draw.rectangle([int(p1 * 4), 0, 400, 40], fill='red') return bar def export_image(): img = Image.new('RGB', (800, 400), color='#001845') draw = ImageDraw.Draw(img) font = ImageFont.load_default() draw.text((20, 20), f"{t1_name} vs {t2_name}", font=font, fill='white') draw.text((20, 50), f"🟨 {team1_stats['amarillas']} 🔵 {team1_stats['rojas']} ⚽ {team1_stats['corners']}", font=font, fill='blue') draw.text((20, 70), f"🟨 {team2_stats['amarillas']} 🔵 {team2_stats['rojas']} ⚽ {team2_stats['corners']}", font=font, fill='red') p1_out, p2_out, _, tiempo = show_stats() draw.text((20, 120), f"Posesión: {p1_out} - {p2_out}", font=font, fill='white') draw.text((20, 140), f"Tiempo total: {tiempo}", font=font, fill='white') draw.text((20, 160), "Historial:", font=font, fill='yellow') for i, ev in enumerate(historial[-10:]): draw.text((40, 180 + i * 20), ev, font=font, fill='white') return img with gr.Blocks(css=""" body { background-color: #001845; color: white; font-family: sans-serif; } button, .gr-button { background-color: #003566; color: white; border-radius: 8px; font-size: 16px; padding: 10px; } input, textarea, .gr-textbox { border-radius: 8px; font-size: 16px; } .image-preview, .gr-image { border-radius: 8px; border: 2px solid #003566; } .textbox-label, .gr-textbox label { color: white; } """) as demo: gr.Markdown("## 🏆 Medidor de Posesión y Estadísticas Estilo Champions League") with gr.Row(): name1 = gr.Textbox(value="Equipo 1", label="Nombre Equipo 1") name2 = gr.Textbox(value="Equipo 2", label="Nombre Equipo 2") logo1 = gr.Image(type="pil", label="Escudo 1") logo2 = gr.Image(type="pil", label="Escudo 2") gr.Button("✅ Establecer Equipos").click(set_team_info, inputs=[name1, name2, logo1, logo2], outputs=[]) resumen1 = gr.Textbox(label="Resumen Equipo 1") resumen2 = gr.Textbox(label="Resumen Equipo 2") log_box = gr.Textbox(label="Historial del partido", lines=10) with gr.Row(): gr.Button("🕒 Iniciar Posesión Equipo 1").click(lambda: start_possession(t1_name), outputs=[resumen1, resumen2, log_box]) gr.Button("🕒 Iniciar Posesión Equipo 2").click(lambda: start_possession(t2_name), outputs=[resumen1, resumen2, log_box]) gr.Button("🔁 Cambiar Posesión").click(switch_possession, outputs=[resumen1, resumen2, log_box]) with gr.Row(): btn_stats = gr.Button("📊 Mostrar posesión") p1_out = gr.Textbox(label="Posesión Equipo 1") p2_out = gr.Textbox(label="Posesión Equipo 2") bar = gr.Image(label="Barra 3D de posesión") tiempo_total = gr.Textbox(label="⏱ Tiempo total") btn_stats.click(show_stats, outputs=[p1_out, p2_out, bar, tiempo_total]) with gr.Row(): gr.Button("🟨 Amarilla Equipo 1").click(lambda: add_stat("1", "amarillas"), outputs=[resumen1, resumen2, log_box]) gr.Button("🔵 Roja Equipo 1").click(lambda: add_stat("1", "rojas"), outputs=[resumen1, resumen2, log_box]) gr.Button("⚽ Córner Equipo 1").click(lambda: add_stat("1", "corners"), outputs=[resumen1, resumen2, log_box]) with gr.Row(): gr.Button("🟨 Amarilla Equipo 2").click(lambda: add_stat("2", "amarillas"), outputs=[resumen1, resumen2, log_box]) gr.Button("🔵 Roja Equipo 2").click(lambda: add_stat("2", "rojas"), outputs=[resumen1, resumen2, log_box]) gr.Button("⚽ Córner Equipo 2").click(lambda: add_stat("2", "corners"), outputs=[resumen1, resumen2, log_box]) demo.load(update_summary, outputs=[resumen1, resumen2, log_box]) gr.Button("🖼 Exportar Imagen Final").click(export_image, outputs=gr.Image(type="pil")) if __name__ == "__main__": demo.launch()