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