import os import pandas as pd import requests import streamlit as st from dotenv import load_dotenv from modules.utils import set_sidebar load_dotenv() PANTRY_ID = os.environ.get("PANTRY_ID") PANTRY_BASKET = os.environ.get("PANTRY_BASKET") assert ( PANTRY_ID is not None and PANTRY_BASKET is not None ), "Pantry ID and basket name must be set in .env file." PAGE_TITLE = "The Leaderboard" pd.set_option("future.no_silent_downcasting", True) def _user_passed_level(df: pd.DataFrame, name: str, level: str) -> bool: return df.loc[df["Name"] == name, level].values[0] == "✅" def main(): st.set_page_config( page_title=PAGE_TITLE, page_icon="assets/effixis_logo.ico", layout="centered", ) set_sidebar() st.title(PAGE_TITLE) st.markdown( """ ### *Welcome to the leaderboard!* Here you can submit your keys and see how you compare to others! """ ) # Display leaderboard leaderboard_url = ( f"https://getpantry.cloud/apiv1/pantry/{PANTRY_ID}/basket/{PANTRY_BASKET}" ) leaderboard_response = requests.get(leaderboard_url) if leaderboard_response.status_code == 200: leaderboard_json = leaderboard_response.json() print(f"Leaderboard data: {leaderboard_json}") leaderboard_data = ( pd.DataFrame(leaderboard_json) .transpose() .rename( columns={ "level 0": "Level 1", "level 1": "Level 2", "level 2": "Level 3", }, )[["Level 1", "Level 2", "Level 3"]] .fillna(False) .map(lambda x: "✅" if x else "❌") .assign( # Weighted sum of the levels Score=lambda df: df.apply( lambda x: sum( [int(passing == "✅") * (i + 1) for i, passing in enumerate(x)] ), axis=1, ) ) .sort_values(by="Score", ascending=False) .reset_index() .rename(columns={"index": "Name"}) ) st.dataframe(leaderboard_data) else: st.error("An error occurred while fetching the leaderboard.") st.stop() # Submit keys with st.form("leaderboard"): key = st.text_input("Enter your key here:") email = st.text_input("Enter your email here:") display_name = st.text_input("Enter your leaderboard display name here:") st.markdown( "*Note: Your email will not be displayed on the leaderboard, it is only used to contact you if you win!*" ) submit = st.form_submit_button("Submit") if submit and key and email and display_name: if ( display_name in leaderboard_json.keys() and email != leaderboard_json[display_name]["email"] ): st.error( "This display name is already taken, please choose another one." ) else: if key not in { os.environ.get("LEVEL_1_KEY"), os.environ.get("LEVEL_2_KEY"), os.environ.get("LEVEL_3_KEY"), }: st.error("Invalid key!") st.stop() if display_name not in leaderboard_json.keys(): data = { display_name: { "email": email, "level 0": key == os.environ.get("LEVEL_1_KEY"), "level 1": key == os.environ.get("LEVEL_2_KEY"), "level 2": key == os.environ.get("LEVEL_3_KEY"), } } else: data = { display_name: { "email": email, "level 0": ( key == os.environ.get("LEVEL_1_KEY") or _user_passed_level( leaderboard_data, display_name, "Level 1" ) ), "level 1": ( key == os.environ.get("LEVEL_2_KEY") or _user_passed_level( leaderboard_data, display_name, "Level 2" ) ), "level 2": ( key == os.environ.get("LEVEL_3_KEY") or _user_passed_level( leaderboard_data, display_name, "Level 3" ) ), } } try: updated_data = leaderboard_json | data print(f"Updated data: {updated_data}") _ = requests.post(leaderboard_url, json=leaderboard_json | data) st.success( "You should soon be able to see your name and your scores on the leaderboard! 🎉" ) except Exception as e: st.error(f"An error occurred while submitting your key: {e}") if __name__ == "__main__": main()