Jon Solow
Get a client per session to help with expiry
050fd9f
raw
history blame
5.81 kB
import pandas as pd
import streamlit as st
from postgrest.exceptions import APIError
from config import DEFAULT_ICON
from shared_page import common_page_config
from data_storage import get_all_users, get_all_rosters
from domain.playoffs import CURRENT_PLAYOFF_WEEK, PLAYOFF_WEEK_TO_NAME
from format_player_html import (
get_user_html_str,
)
from load_options import get_map_week_player_id_option, PlayerOption
from stats import get_scores_map
def get_users_df():
columns = ["user_id", "name"]
all_users = pd.DataFrame(get_all_users(st.session_state["db_client"], columns_included=columns), columns=columns)
return all_users
@st.cache_data(ttl=60 * 1)
def load_masked_rosters() -> dict[int, dict[str, PlayerOption]]:
options_map = get_map_week_player_id_option()
roster_user_position_map: dict[int, dict[str, PlayerOption]] = {}
for roster_slot_map in get_all_rosters(st.session_state["db_client"]):
position_id = str(roster_slot_map["position_id"])
player_id = str(roster_slot_map["player_id"])
user_id = int(roster_slot_map["user_id"])
if user_id not in roster_user_position_map:
roster_user_position_map[user_id] = {}
week = int(position_id[0])
player = PlayerOption.empty_player(week=week)
if selected_player := options_map[week].get(player_id):
if selected_player.is_locked():
player = selected_player
else:
player = PlayerOption.hidden_player(week=week, position=selected_player.position)
roster_user_position_map[user_id][position_id] = player
return roster_user_position_map
@st.cache_data(ttl=60 * 1)
def get_roster_multipliers(roster_map: dict[int, dict[str, PlayerOption]]) -> dict[int, dict[int, dict[str, int]]]:
"""Map of user -> week -> player_id -> multiplier"""
multiplier_map: dict[int, dict[int, dict[str, int]]] = {}
for user_id, user_roster_map in roster_map.items():
user_multipliers: dict[int, dict[str, int]] = {}
# iterate through players sorted by week
for position_id, player in sorted(user_roster_map.items(), key=lambda x: x[0][0]):
if not player.gsis_id:
# skip not set players
continue
week = int(position_id.split("-", 1)[0])
if week not in user_multipliers:
user_multipliers[week] = {}
player_previous_multiplier = user_multipliers.get(week - 1, {}).get(player.gsis_id, 0)
player_multiplier = player_previous_multiplier + 1
user_multipliers[week][player.gsis_id] = player_multiplier
multiplier_map[user_id] = user_multipliers
return multiplier_map
def assemble_user_scores(
player_scores_map: dict[int, dict[str, float]],
roster_map: dict[int, dict[str, PlayerOption]],
multiplier_map: dict[int, dict[int, dict[str, int]]],
) -> dict[int, dict[int, float]]:
week_user_score_map: dict[int, dict[int, float]] = {w: {} for w in player_scores_map.keys()}
user_totals: dict[int, float] = {}
for user_id, user_roster_map in roster_map.items():
user_score_map: dict[int, float] = {w: 0.0 for w in player_scores_map.keys()}
for roster_key, player_id in user_roster_map.items():
week = int(roster_key[0])
player_score = player_scores_map.get(week, {}).get(player_id.gsis_id, 0.0)
multiplier = float(multiplier_map.get(user_id, {}).get(week, {}).get(player_id.gsis_id, 1))
user_score_map[week] += round(player_score * multiplier, 0)
for week, week_score in user_score_map.items():
week_user_score_map[week][user_id] = week_score
if user_id not in user_totals:
user_totals[user_id] = 0.0
user_totals[user_id] += week_score
week_user_score_map[5] = user_totals
return week_user_score_map
def display_masked_rosters(week: int):
rosters = load_masked_rosters()
multipliers = get_roster_multipliers(rosters)
users = get_users_df()
player_scores = get_scores_map()
user_scores = assemble_user_scores(player_scores, rosters, multipliers)
scoreboard_str = ""
scoreboard_str += """<div className="scoreboard">"""
sorted_user_rows = sorted(
users.itertuples(),
key=lambda x: user_scores.get(week, {}).get(x.user_id, 0.0),
reverse=True,
)
for i, row in enumerate(sorted_user_rows):
user_score = user_scores.get(week, {}).get(row.user_id, 0.0)
user_roster_map = rosters.get(row.user_id, {})
user_place = i + 1
scoreboard_str += get_user_html_str(
week, row.name, user_roster_map, user_score, user_place, multipliers.get(row.user_id, {})
)
scoreboard_str += """</div>"""
st.markdown(scoreboard_str, unsafe_allow_html=True)
def display_rosters():
st.markdown("<h2>Rosters</h2>", unsafe_allow_html=True)
options = list(PLAYOFF_WEEK_TO_NAME.keys())
default_selection = options.index(CURRENT_PLAYOFF_WEEK)
week_selected = st.selectbox(
"Week",
options=options,
index=default_selection,
key="roster_week_select",
format_func=lambda x: PLAYOFF_WEEK_TO_NAME[x],
)
display_masked_rosters(week_selected)
def get_page():
page_title = "Pool Scoreboard"
st.set_page_config(page_title=page_title, page_icon=DEFAULT_ICON, layout="wide", initial_sidebar_state="collapsed")
common_page_config()
st.title(page_title)
try:
display_rosters()
except APIError:
try:
display_rosters()
except Exception:
st.write("Sorry error occurred loading scoreboard. Please try refreshing page.")
st.stop()
if __name__ == "__main__":
get_page()