import pandas as pd
import streamlit as st
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 load_options import get_map_week_player_id_option, PlayerOption
from stats import get_stats_map, get_scores_map
POSITION_LABELS = [
"QB-1",
"RB-1",
"RB-2",
"WR-1",
"WR-2",
"TE-1",
"K-1",
"DEF-1",
]
def get_users_df():
columns = ["user_id", "name"]
all_users = pd.DataFrame(get_all_users(columns_included=columns), columns=columns)
return all_users
@st.cache_data(ttl=60 * 60)
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 user_id, position_id, player_id in get_all_rosters():
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
def get_roster_html_str(week: int, user_map: dict[str, PlayerOption]) -> str:
players_str = ""
for pos_label in POSITION_LABELS:
week_pos_label = f"{week}-{pos_label}"
player = user_map.get(week_pos_label, PlayerOption.empty_player(week=week))
player_stats = get_stats_map().get(week, {}).get(player.gsis_id, {})
player_score = get_scores_map().get(week, {}).get(player.gsis_id, 0.0)
players_str += get_player_html_str(player, player_stats, player_score)
roster_str = f"""
{players_str}
"""
return roster_str
def get_player_html_str(player_opt: PlayerOption, player_stats: dict[str, float], score: float) -> str:
# TODO
multiplier = 1
game_status = " "
game_score = " "
player_stats_str = get_player_stats_html_str(player_stats)
player_classes = "player"
if player_opt.team:
player_classes += f" player--{player_opt.team.upper()}"
image_classes = "player__image"
multiplier_classes = "player__multiplier"
if multiplier > 1:
image_classes += f" player__image--{multiplier}"
multiplier_classes += f" player__multiplier--{multiplier}"
if not (player_image_url := player_opt.headshot_url):
player_image_url = "https://static.www.nfl.com/w_200,h_200,c_fill/league/suxzfdslsj5vpwbin5t8"
player_str = f"""
{player_opt.position}
{player_opt.full_name}
{player_opt.team}
{score: .0f}
{multiplier}X
{game_status}
{game_score}
{player_stats_str}
"""
return player_str
def get_stat_list_item_html_str(stat_key: str, stat_value: str | float) -> str:
return f"""
{stat_key}
{stat_value:.0f}
"""
def get_player_stats_html_str(stats_dict: dict[str, float]) -> str:
sorted_stat_tuple = list(
filter(lambda x: x[1] != 0, sorted(list(stats_dict.items()), key=lambda x: x[1], reverse=True))
)
max_stats = 4
stat_items_str = "\n".join([get_stat_list_item_html_str(s, v) for s, v in sorted_stat_tuple[:max_stats]])
stats_str = f"""{stat_items_str}
"""
return stats_str
def get_user_html_str(
week: int, user_name: str, user_map: dict[str, PlayerOption], week_score: float, place: int
) -> str:
user_str = ""
score_type = "Score"
roster_html_str = get_roster_html_str(week, user_map)
user_str += f"""
{place}
{user_name}
{user_name}
{score_type}
{week_score: .0f}
{roster_html_str}
"""
return user_str
def assemble_user_scores(
player_scores_map: dict[int, dict[str, float]], roster_map: dict[int, dict[str, PlayerOption]]
) -> dict[int, dict[int, float]]:
week_user_score_map: dict[int, dict[int, float]] = {w: {} for w in player_scores_map.keys()}
for user_id, user_roster_map in roster_map.items():
user_score = 0.0
for roster_key, player_id in user_roster_map.items():
week = int(roster_key[0])
user_score += player_scores_map.get(week, {}).get(player_id.gsis_id, 0.0)
week_user_score_map[week][user_id] = user_score
return week_user_score_map
def display_masked_rosters(week: int):
rosters = load_masked_rosters()
users = get_users_df()
player_scores = get_scores_map()
user_scores = assemble_user_scores(player_scores, rosters)
scoreboard_str = ""
scoreboard_str += """"""
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)
scoreboard_str += """
"""
st.markdown(scoreboard_str, unsafe_allow_html=True)
def display_rosters():
st.markdown("Rosters
", 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")
common_page_config()
st.title(page_title)
display_rosters()
if __name__ == "__main__":
get_page()