SD_Hackathon / src /streamlit_app.py
com3dian's picture
Update src/streamlit_app.py
ac7741f verified
raw
history blame
3.05 kB
import dash
from dash import dcc, html, Input, Output, State, dash_table
import pandas as pd
import os
import datetime
import base64
import io
from google_sheet import fetch_leaderboard
from google_drive import upload_to_drive
# Make sure submissions folder exists
os.makedirs("submissions", exist_ok=True)
app = dash.Dash(__name__)
app.title = "πŸ† Hackathon Leaderboard"
app.layout = html.Div([
html.H2("πŸ† Hackathon Leaderboard"),
dcc.Upload(
id='upload-data',
children=html.Div([
'πŸ“ Drag and drop or click to upload a .zip file'
]),
style={
'width': '50%',
'height': '60px',
'lineHeight': '60px',
'borderWidth': '1px',
'borderStyle': 'dashed',
'borderRadius': '10px',
'textAlign': 'center',
'margin': '20px'
},
multiple=False,
accept='.zip'
),
html.Button('Submit', id='submit-btn', n_clicks=0),
html.Div(id='upload-status', style={'margin': '20px', 'fontWeight': 'bold'}),
html.H3("Leaderboard"),
html.Div(id='leaderboard-table', style={'margin': '20px'})
])
def save_file_and_upload(content, filename):
timestamp = datetime.datetime.now().isoformat().replace(':', '_')
saved_filename = f"{timestamp}_{filename}"
path = os.path.join("submissions", saved_filename)
# Decode and save the file
content_string = content.split(',')[1]
decoded = base64.b64decode(content_string)
with open(path, 'wb') as f:
f.write(decoded)
# Upload to Google Drive
try:
drive_file_id = upload_to_drive(path, saved_filename)
return f"βœ… Uploaded to Google Drive [File ID: {drive_file_id}]"
except Exception as e:
return f"⚠️ Failed to upload to Google Drive: {e}"
def generate_leaderboard():
try:
df = fetch_leaderboard()
if df.empty:
return html.Div("No submissions yet.")
df_sorted = df.sort_values(by="score", ascending=False)
return dash_table.DataTable(
data=df_sorted.to_dict("records"),
columns=[{"name": i, "id": i} for i in df_sorted.columns],
style_table={'overflowX': 'auto'},
style_cell={'textAlign': 'left', 'padding': '5px'},
style_header={'backgroundColor': 'lightgrey', 'fontWeight': 'bold'}
)
except Exception as e:
return html.Div(f"Could not load leaderboard: {e}")
@app.callback(
Output('upload-status', 'children'),
Output('leaderboard-table', 'children'),
Input('submit-btn', 'n_clicks'),
State('upload-data', 'contents'),
State('upload-data', 'filename'),
prevent_initial_call=True
)
def handle_submission(n_clicks, contents, filename):
if contents is None:
return "❌ No file uploaded.", generate_leaderboard()
status = save_file_and_upload(contents, filename)
leaderboard = generate_leaderboard()
return status, leaderboard
if __name__ == '__main__':
app.run(debug=True)