File size: 4,214 Bytes
f8d385e
12c6f3b
9ba222b
12c6f3b
 
f039650
77ab908
 
 
3b6b956
77ab908
 
8b57f56
 
f8d385e
4da5970
f8d385e
 
76138e1
dbf76b6
f8d385e
12c6f3b
 
9ba222b
77ab908
12c6f3b
f8d385e
12c6f3b
9ba222b
77ab908
12c6f3b
 
 
8b57f56
 
12c6f3b
 
8b57f56
77ab908
12c6f3b
 
 
f8d385e
77ab908
12c6f3b
77ab908
f8d385e
12c6f3b
fb5493c
12c6f3b
 
 
 
b8ab640
 
 
 
12c6f3b
 
b8ab640
 
12c6f3b
 
b8ab640
 
12c6f3b
 
b8ab640
7a0e457
 
 
12c6f3b
7a0e457
 
b8ab640
 
 
 
 
 
7a0e457
b8ab640
 
 
 
 
 
7a0e457
b8ab640
 
 
 
 
 
7a0e457
12c6f3b
 
 
7a0e457
12c6f3b
 
 
7a0e457
12c6f3b
 
 
7a0e457
12c6f3b
 
 
 
 
f8842a2
77ab908
12c6f3b
f8d385e
12c6f3b
 
 
 
dcf465d
77ab908
f8d385e
7a0e457
b8ab640
f8d385e
b8ab640
fb5493c
b8ab640
dcf465d
 
f8842a2
61186ad
dcf465d
77ab908
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
import json
import os
import time
from collections import defaultdict
from functools import lru_cache

import argilla as rg
import gradio as gr
import pandas as pd
from dotenv import load_dotenv
from fastapi import FastAPI

from calculate_personal_scores import calculate_personal_scores
from calculate_team_scores import calculate_team_scores

load_dotenv()

# FastAPI app
app = FastAPI()

# Global variables for caching
last_update_time = 0
cached_data = None


def create_leaderboard_ui():
    """Create the leaderboard UI with caching."""
    global cached_data, last_update_time
    current_time = time.time()

    if cached_data is not None and current_time - last_update_time < 300:
        df = cached_data
    else:
        print("Recalculating scores...")
        df = calculate_personal_scores()
        cached_data = df
        last_update_time = current_time
        calculate_team_scores()

    if not df.empty:
        df = df.reset_index(drop=True)
        df.index = df.index + 1
        df = df.rename_axis("Rank").reset_index()

    df_html = df.to_html(classes="leaderboard-table", border=0, index=False)

    return f"""
    <div style="margin: 20px 0;">
        <p>Última Actualización: {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(last_update_time))}</p>
        <style>
            .leaderboard-table {{
                width: 100%;
                border-collapse: collapse;
                font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
                box-shadow: 0 4px 8px rgba(0,0,0,0.1);
                border-radius: 8px;
                overflow: hidden;
            }}
            .leaderboard-table th {{
                background-color: #1a1a2e;
                color: white;
                font-weight: bold;
                text-align: left;
                padding: 14px;
                border-bottom: 2px solid #16213e;
            }}
            .leaderboard-table td {{
                padding: 12px 14px;
                border-bottom: 1px solid #333;
                background-color: #222;
                color: #fff;
            }}
            .leaderboard-table tr:hover td {{
                background-color: #2a2a3a;
            }}
            .leaderboard-table tr:nth-child(1) td:first-child {{
                background-color: #ffd700;
                color: #333;
                font-weight: bold;
                text-align: center;
                border-right: 1px solid #333;
            }}
            .leaderboard-table tr:nth-child(2) td:first-child {{
                background-color: #c0c0c0;
                color: #333;
                font-weight: bold;
                text-align: center;
                border-right: 1px solid #333;
            }}
            .leaderboard-table tr:nth-child(3) td:first-child {{
                background-color: #cd7f32;
                color: #333;
                font-weight: bold;
                text-align: center;
                border-right: 1px solid #333;
            }}
            .leaderboard-table tr:nth-child(1) td:nth-child(2) {{
                font-weight: bold;
                color: #ffd700;
            }}
            .leaderboard-table tr:nth-child(2) td:nth-child(2) {{
                font-weight: bold;
                color: #c0c0c0;
            }}
            .leaderboard-table tr:nth-child(3) td:nth-child(2) {{
                font-weight: bold;
                color: #cd7f32;
            }}
        </style>
        {df_html}
    </div>
    """


def refresh_data():
    """Refresh the leaderboard data."""
    global cached_data, last_update_time
    cached_data = None
    last_update_time = 0
    return create_leaderboard_ui()


# Gradio interface
with gr.Blocks(theme=gr.themes.Default()) as demo:
    with gr.Column(scale=1):
        gr.Markdown("# 🏆 Leaderboard Personal Retos Hackathon 2025")
        leaderboard_html = gr.HTML(create_leaderboard_ui)
        refresh_btn = gr.Button("🔄 Actualizar Datos", variant="primary")
        refresh_btn.click(fn=refresh_data, outputs=leaderboard_html)

gr.mount_gradio_app(app, demo, path="/")

if __name__ == "__main__":
    import uvicorn

    uvicorn.run(app, host="0.0.0.0", port=7860)