Пример #1
0
    def map_data_to_base(self, base_league_class):
        logger.debug("Mapping ESPN data to base objects.")

        league = base_league_class(self.week_for_report, self.league_id,
                                   self.config, self.data_dir, self.save_data,
                                   self.dev_offline)  # type: BaseLeague

        league.name = self.league_settings.name
        league.week = int(self.current_week)
        league.season = self.season
        league.num_teams = int(self.league_settings.team_count)
        league.num_playoff_slots = int(self.num_playoff_slots)
        league.num_regular_season_weeks = int(self.num_regular_season_weeks)
        league.num_divisions = self.num_divisions
        if league.num_divisions > 0:
            league.has_divisions = True
        league.has_median_matchup = self.has_median_matchup
        league.median_score = 0
        # use hijacked raw json since acquisition settings are not exposed in the API wrapper
        league.is_faab = bool(
            self.league_settings_json.get("acquisitionSettings").get(
                "isUsingAcquisitionBudget"))
        if league.is_faab:
            league.faab_budget = int(
                self.league_settings_json.get("acquisitionSettings").get(
                    "acquisitionBudget", 0))
        # league.url = self.league.ENDPOINT
        league.url = "https://fantasy.espn.com/football/league?leagueId={0}".format(
            self.league_id)

        # TODO: set up with ESPN player endpoint
        # league.player_data_by_week_function = self.league.player_map
        # league.player_data_by_week_key = "player_points_value"

        league.bench_positions = [
            "BN", "IR"
        ]  # ESPN uses "BE" for the bench slot, but this app adjusts it to "BN"

        for position, count in self.roster_positions.items():
            pos_name = deepcopy(position)

            if pos_name == "BE":
                pos_name = "BN"

            if pos_name == "RB/WR":
                league.flex_positions_rb_wr = ["RB", "WR"]
                pos_name = "FLEX_RB_WR"
            if pos_name == "WR/TE":
                league.flex_positions_te_wr = ["TE", "WR"]
                pos_name = "FLEX_TE_WR"
            if pos_name == "RB/WR/TE":
                league.flex_positions_rb_te_wr = ["RB", "TE", "WR"]
                pos_name = "FLEX_RB_TE_WR"
            if pos_name == "QB/RB/WR/TE":
                league.flex_positions_qb_rb_te_wr = ["QB", "RB", "TE", "WR"]
                pos_name = "FLEX_OFFENSIVE_PLAYER"
            if pos_name == "OP":
                league.flex_positions_offensive_player = [
                    "QB", "RB", "WR", "TE"
                ]
                pos_name = "FLEX_OFFENSIVE_PLAYER"
            if pos_name == "DP":
                league.flex_positions_idp = [
                    "CB", "DB", "DE", "DL", "DT", "EDR", "LB", "S"
                ]
                pos_name = "FLEX_IDP"

            pos_counter = deepcopy(int(count))
            while pos_counter > 0:
                if pos_name not in league.bench_positions:
                    league.active_positions.append(pos_name)
                pos_counter -= 1

            league.roster_positions.append(pos_name)
            league.roster_position_counts[pos_name] = int(count)

        league_median_records_by_team = {}
        for week, matchups in self.matchups_by_week.items():
            league.teams_by_week[str(week)] = {}
            league.matchups_by_week[str(week)] = []
            for matchup in matchups:  # type: BoxScore
                base_matchup = BaseMatchup()

                base_matchup.week = int(week)
                base_matchup.complete = True if int(week) != int(
                    self.current_week) else False
                base_matchup.tied = True if (matchup.home_score
                                             == matchup.away_score) else False

                matchup_teams = {
                    "home": matchup.home_team,
                    "away": matchup.away_team
                }
                for key, matchup_team in matchup_teams.items():
                    team_json = self.teams_json[str(matchup_team.team_id)]
                    base_team = BaseTeam()

                    opposite_key = "away" if key == "home" else "home"
                    team_division = matchup_team.division_id if self.num_divisions > 0 else None
                    opponent_division = matchup_teams[
                        opposite_key].division_id if self.num_divisions > 0 else None
                    if team_division and opponent_division and team_division == opponent_division:
                        base_matchup.division_matchup = True

                    base_team.week = int(week)
                    base_team.name = matchup_team.team_name
                    base_team.num_moves = team_json["transactionCounter"].get(
                        "acquisitions", 0)
                    base_team.num_trades = team_json["transactionCounter"].get(
                        "trades", 0)

                    if isinstance(matchup_team.owner, list):
                        team_managers = matchup_team.owner
                    else:
                        team_managers = [matchup_team.owner]

                    for manager in team_managers:
                        base_manager = BaseManager()

                        base_manager.manager_id = None
                        base_manager.email = None
                        base_manager.name = re.sub(r"\W+", " ", manager)

                        base_team.managers.append(base_manager)

                    base_team.manager_str = ", ".join(
                        [manager.name_str for manager in base_team.managers])
                    base_team.team_id = str(matchup_team.team_id)

                    team_is_home = False
                    if int(base_team.team_id) == int(
                            matchup.home_team.team_id):
                        team_is_home = True
                        base_team.home_field_advantage = self.home_field_advantage
                        base_team.points = float(
                            matchup.home_score +
                            base_team.home_field_advantage)
                    else:
                        base_team.points = float(matchup.away_score)

                    base_team.projected_points = None
                    base_team.waiver_priority = team_json["waiverRank"]
                    league.has_waiver_priorities = base_team.waiver_priority > 0
                    if league.is_faab:
                        base_team.faab = int(league.faab_budget) - int(
                            team_json["transactionCounter"].get(
                                "acquisitionBudgetSpent", 0))
                    base_team.url = "https://fantasy.espn.com/football/team?leagueId=48153503&teamId={0}".format(
                        base_team.team_id)

                    if matchup_team.streak_type == "WIN":
                        streak_type = "W"
                    elif matchup_team.streak_type == "LOSS":
                        streak_type = "L"
                    else:
                        streak_type = "T"

                    if team_json["record"]["division"].get(
                            "streakType") == "WIN":
                        division_streak_type = "W"
                    elif team_json["record"]["division"].get(
                            "streakType") == "LOSS":
                        division_streak_type = "L"
                    else:
                        division_streak_type = "T"

                    base_team.division = team_division
                    base_team.current_record = BaseRecord(
                        wins=int(matchup_team.wins),
                        losses=int(matchup_team.losses),
                        ties=int(team_json["record"]["overall"].get("ties",
                                                                    0)),
                        percentage=round(
                            float(team_json["record"]["overall"].get(
                                "percentage", 0)), 3),
                        points_for=float(matchup_team.points_for),
                        points_against=float(matchup_team.points_against),
                        streak_type=streak_type,
                        streak_len=int(matchup_team.streak_length),
                        team_id=matchup_team.team_id,
                        team_name=matchup_team.team_name,
                        rank=int(matchup_team.standing),
                        division=base_team.division,
                        division_wins=int(team_json["record"]["division"].get(
                            "wins", 0)),
                        division_losses=int(
                            team_json["record"]["division"].get("losses", 0)),
                        division_ties=int(team_json["record"]["division"].get(
                            "ties", 0)),
                        division_percentage=round(
                            float(team_json["record"]["division"].get(
                                "percentage", 0)), 3),
                        division_streak_type=division_streak_type,
                        division_streak_len=int(
                            team_json["record"]["division"].get(
                                "streakLength", 0)))
                    base_team.streak_str = base_team.current_record.get_streak_str(
                    )
                    if base_matchup.division_matchup:
                        base_team.division_streak_str = base_team.current_record.get_division_streak_str(
                        )

                    # get median for week
                    week_median = self.median_score_by_week.get(str(week))

                    median_record = league_median_records_by_team.get(
                        str(base_team.team_id))  # type: BaseRecord
                    if not median_record:
                        median_record = BaseRecord(
                            team_id=base_team.team_id,
                            team_name=base_team.name,
                            points_for=(base_team.points - week_median),
                            points_against=week_median)
                        league_median_records_by_team[str(
                            base_team.team_id)] = median_record

                    if week_median:
                        # use this if you want the tie-break to be season total points over/under median score
                        median_record.add_points_for(base_team.points -
                                                     week_median)
                        # use this if you want the tie-break to be current week points over/under median score
                        # median_record.add_points_for(
                        #     (median_record.get_points_for() * -1) + (base_team.points - week_median))
                        median_record.add_points_against(
                            (median_record.get_points_against() * -1) +
                            week_median)
                        if base_team.points > week_median:
                            median_record.add_win()
                        elif base_team.points < week_median:
                            median_record.add_loss()
                        else:
                            median_record.add_tie()

                        base_team.current_median_record = median_record

                    # add team to matchup teams
                    base_matchup.teams.append(base_team)

                    # add team to league teams by week
                    league.teams_by_week[str(week)][str(
                        base_team.team_id)] = base_team

                    # no winner/loser if matchup is tied
                    if team_is_home:
                        if (matchup.home_score + self.home_field_advantage
                            ) > matchup.away_score:
                            base_matchup.winner = base_team
                        elif (matchup.home_score +
                              self.home_field_advantage) < matchup.away_score:
                            base_matchup.loser = base_team
                    else:
                        if (matchup.home_score + self.home_field_advantage
                            ) > matchup.away_score:
                            base_matchup.loser = base_team
                        elif (matchup.home_score +
                              self.home_field_advantage) < matchup.away_score:
                            base_matchup.winner = base_team

                # add matchup to league matchups by week
                league.matchups_by_week[str(week)].append(base_matchup)

        for week, rosters in self.rosters_by_week.items():
            league.players_by_week[str(week)] = {}
            for team_id, roster in rosters.items():
                team_json = self.rosters_json_by_week[str(week)][int(team_id)]
                league_team = league.teams_by_week.get(str(week)).get(
                    str(team_id))  # type: BaseTeam

                for player in roster:  # type: BoxPlayer

                    player_json = {}
                    for league_player_json in team_json:
                        if player.playerId == league_player_json["playerId"]:
                            player_json = league_player_json[
                                "playerPoolEntry"]["player"]

                    base_player = BasePlayer()

                    base_player.week_for_report = int(week)
                    base_player.player_id = str(player.playerId)
                    # TODO: missing bye
                    base_player.bye_week = None
                    base_player.display_position = player.position
                    base_player.nfl_team_id = player_json["proTeamId"]
                    # TODO: change back once ESPN fixes their API to not use "WSH"" instead of "WAS" for the
                    #  Washington Football Team
                    # base_player.nfl_team_abbr = player.proTeam
                    base_player.nfl_team_abbr = player.proTeam if player.proTeam != "WSH" else "WAS"
                    base_player.nfl_team_name = player.proTeam

                    if base_player.display_position == "D/ST":
                        # TODO: change back once ESPN fixes their API to not use "WSH"" instead of "WAS" for the
                        #  Washington Football Team
                        # base_player.first_name = player_json["firstName"]
                        base_player.first_name = player_json["firstName"] if player_json["firstName"] != "Washington" \
                            else "Football Team"
                        base_player.full_name = base_player.first_name
                        base_player.nfl_team_name = base_player.first_name
                        base_player.headshot_url = \
                            "https://a.espncdn.com/combiner/i?img=/i/teamlogos/nfl/500/{0}.png".format(
                                base_player.nfl_team_abbr)
                    else:
                        base_player.first_name = player_json["firstName"]
                        base_player.last_name = player_json["lastName"]
                        base_player.full_name = player.name
                        base_player.headshot_url = "https://a.espncdn.com/i/headshots/nfl/players/full/{0}.png".format(
                            player.playerId)
                    base_player.owner_team_id = None
                    base_player.owner_team_name = league_team.manager_str
                    # TODO: missing percent owned
                    base_player.percent_owned = None
                    base_player.points = float(player.points)
                    base_player.projected_points = float(
                        player.projected_points)

                    base_player.position_type = "O" if base_player.display_position in self.offensive_positions \
                        else "D"
                    base_player.primary_position = player.position

                    eligible_positions = player.eligibleSlots
                    for position in eligible_positions:
                        if position == "BE":
                            position = "BN"
                        elif position == "RB/WR":
                            position = "FLEX_RB_WR"
                        elif position == "WR/TE":
                            position = "FLEX_TE_WR"
                        elif position == "RB/WR/TE":
                            position = "FLEX_RB_TE_WR"
                        elif position == "QB/RB/WR/TE":
                            position = "FLEX_QB_RB_TE_WR"
                        elif position == "OP":
                            position = "FLEX_OFFENSIVE_PLAYER"
                        elif position == "DP":
                            position = "FLEX_IDP"

                        base_player.eligible_positions.append(position)

                    if player.slot_position == "BE":
                        base_player.selected_position = "BN"
                    elif player.slot_position == "RB/WR":
                        base_player.selected_position = "FLEX_RB_WR"
                    elif player.slot_position == "WR/TE":
                        base_player.selected_position = "FLEX_TE_WR"
                    elif player.slot_position == "RB/WR/TE":
                        base_player.selected_position = "FLEX_RB_TE_WR"
                    elif player.slot_position == "QB/RB/WR/TE":
                        base_player.selected_position = "FLEX_QB_RB_TE_WR"
                    elif player.slot_position == "OP":
                        base_player.selected_position = "FLEX_OFFENSIVE_PLAYER"
                    elif player.slot_position == "DP":
                        base_player.selected_position = "FLEX_IDP"
                    else:
                        base_player.selected_position = player.slot_position
                    base_player.selected_position_is_flex = True if "/" in player.slot_position and \
                                                                    player.slot_position != "D/ST" else False

                    base_player.status = player_json.get("injuryStatus")

                    if player_json["stats"]:
                        for stat_id, stat_value in player_json["stats"][0][
                                "stats"].items():
                            base_stat = BaseStat()

                            base_stat.stat_id = stat_id
                            base_stat.name = None
                            base_stat.value = stat_value

                            base_player.stats.append(base_stat)

                    # add player to team roster
                    league_team.roster.append(base_player)

                    # add player to league players by week
                    league.players_by_week[str(week)][
                        base_player.player_id] = base_player

        league.current_standings = sorted(league.teams_by_week.get(
            str(self.week_for_report)).values(),
                                          key=lambda x: x.current_record.rank)

        league.current_median_standings = sorted(
            league.teams_by_week.get(str(self.week_for_report)).values(),
            key=lambda x:
            (x.current_median_record.get_wins(), -x.current_median_record.
             get_losses(), x.current_median_record.get_ties(),
             x.current_median_record.get_points_for()),
            reverse=True)

        return league
    def calculate_records(week, league: BaseLeague, custom_weekly_matchups):
        logger.debug(
            "Calculating league records for week \"{0}\".".format(week))

        standings = league.standings if league.standings else league.current_standings

        records = defaultdict(BaseRecord)
        for team in standings:  # type: BaseTeam
            if week == 1:
                record = BaseRecord(int(week),
                                    team_id=team.team_id,
                                    team_name=team.name,
                                    division=team.division)
            else:
                previous_week_record = league.records_by_week[str(
                    int(week) - 1)][team.team_id]  # type: BaseRecord
                record = BaseRecord(
                    int(week),
                    wins=previous_week_record.get_wins(),
                    ties=previous_week_record.get_ties(),
                    losses=previous_week_record.get_losses(),
                    points_for=previous_week_record.get_points_for(),
                    points_against=previous_week_record.get_points_against(),
                    streak_type=previous_week_record.get_streak_type(),
                    streak_len=previous_week_record.get_streak_length(),
                    team_id=team.team_id,
                    team_name=team.name,
                    division=team.division,
                    division_wins=previous_week_record.get_division_wins(),
                    division_ties=previous_week_record.get_division_ties(),
                    division_losses=previous_week_record.get_division_losses(),
                    division_points_for=previous_week_record.
                    get_division_points_for(),
                    division_points_against=previous_week_record.
                    get_division_points_against(),
                    division_streak_type=previous_week_record.
                    get_division_streak_type(),
                    division_streak_len=previous_week_record.
                    get_division_streak_length())

            # league.matchups_by_week[str(week)]

            for matchup in custom_weekly_matchups:
                for team_id, matchup_result in matchup.items():
                    if str(team_id) == str(team.team_id):
                        outcome = matchup_result["result"]
                        if outcome == "W":
                            record.add_win()
                            if matchup_result["division"]:
                                record.add_division_win()
                        elif outcome == "L":
                            record.add_loss()
                            if matchup_result["division"]:
                                record.add_division_loss()
                        else:
                            record.add_tie()
                            if matchup_result["division"]:
                                record.add_division_tie()
                        record.add_points_for(matchup_result["points_for"])
                        record.add_points_against(
                            matchup_result["points_against"])
                        if matchup_result["division"]:
                            record.add_division_points_for(
                                matchup_result["points_for"])
                            record.add_division_points_against(
                                matchup_result["points_against"])
                        records[team.team_id] = record

            team.record = record

        ordered_records = OrderedDict()
        standings_rank = 1
        for ordered_record in sorted(
                records.items(),
                key=lambda x: (-x[1].get_wins(), -x[1].get_losses(), -x[1].
                               get_ties(), -x[1].get_points_for())):
            ordered_record[1].rank = standings_rank
            ordered_records[ordered_record[0]] = ordered_record[1]
            standings_rank += 1

        league.records_by_week[str(week)] = ordered_records
        return records
    def map_data_to_base(self, base_league_class):
        logger.debug("Mapping Fleaflicker data to base objects.")

        league = base_league_class(self.week_for_report, self.league_id,
                                   self.config, self.data_dir, self.save_data,
                                   self.dev_offline)  # type: BaseLeague

        league.name = self.league_info.get("name")
        league.week = int(self.current_week)
        league.season = self.season
        league.num_teams = int(self.league_info.get("size"))
        league.num_playoff_slots = int(self.num_playoff_slots)
        league.num_regular_season_weeks = int(self.num_regular_season_weeks)
        league.num_divisions = self.num_divisions
        league.divisions = self.divisions
        if league.num_divisions > 0:
            league.has_divisions = True
        league.has_median_matchup = self.has_median_matchup
        league.median_score = 0
        league.faab_budget = int(self.league_info.get("defaultWaiverBudget",
                                                      0))
        if league.faab_budget > 0:
            league.is_faab = True
        league.url = self.league_url

        # league.player_data_by_week_function = None
        # league.player_data_by_week_key = None

        league.bench_positions = ["BN", "IR"]

        for position in self.roster_positions:
            pos_name = position.get("label")
            if position.get("start"):
                pos_count = int(position.get("start"))
            elif position.get("label") == "BN":
                pos_count = int(
                    position.get("max")) if position.get("max") else 0
            else:
                pos_count = 0

            if pos_name == "RB/WR":
                league.flex_positions_rb_wr = ["RB", "WR"]
                pos_name = "FLEX_RB_WR"
            if pos_name == "WR/TE":
                league.flex_positions_te_wr = ["TE", "WR"]
                pos_name = "FLEX_TE_WR"
            if pos_name == "RB/WR/TE":
                league.flex_positions_rb_te_wr = ["RB", "TE", "WR"]
                pos_name = "FLEX_RB_TE_WR"
            if pos_name == "RB/WR/TE/QB":
                league.flex_positions_qb_rb_te_wr = ["QB", "RB", "TE", "WR"]
                pos_name = "FLEX_QB_RB_TE_WR"

            pos_counter = deepcopy(pos_count)
            while pos_counter > 0:
                if pos_name not in league.bench_positions:
                    league.active_positions.append(pos_name)
                pos_counter -= 1

            league.roster_positions.append(pos_name)
            league.roster_position_counts[pos_name] = pos_count

        league_median_records_by_team = {}
        for week, matchups in self.matchups_by_week.items():
            matchups_week = matchups.get("schedulePeriod").get("value")
            matchups = matchups.get("games")

            league.teams_by_week[str(week)] = {}
            league.matchups_by_week[str(week)] = []

            for matchup in matchups:
                base_matchup = BaseMatchup()

                base_matchup.week = int(matchups_week)
                base_matchup.complete = True if bool(
                    matchup.get("isFinalScore")) else False
                base_matchup.tied = True if matchup.get(
                    "homeResult") == "TIE" else False

                for key in ["home", "away"]:
                    team_data = matchup.get(key)  # type: dict
                    base_team = BaseTeam()

                    opposite_key = "away" if key == "home" else "home"
                    team_division = self.league_teams[team_data.get("id")].get(
                        "division_id")
                    opponent_division = self.league_teams[matchup.get(
                        opposite_key).get("id")].get("division_id")
                    if team_division and opponent_division and team_division == opponent_division:
                        base_matchup.division_matchup = True

                    base_team.week = int(matchups_week)
                    base_team.name = team_data.get("name")

                    for manager in self.league_teams[team_data.get("id")].get(
                            "owners"):
                        base_manager = BaseManager()

                        base_manager.manager_id = str(manager.get("id"))
                        base_manager.email = None
                        base_manager.name = manager.get("displayName")

                        base_team.managers.append(base_manager)

                    base_team.manager_str = ", ".join(
                        [manager.name_str for manager in base_team.managers])

                    base_team.team_id = str(team_data.get("id"))
                    base_team.points = float(
                        matchup.get(key + "Score", {}).get("score",
                                                           {}).get("value", 0))
                    base_team.projected_points = None

                    # TODO: currently the fleaflicker API call only returns 1st PAGE of transactions... figure this out!
                    base_team.num_moves = str(
                        self.league_transactions_by_team[str(
                            base_team.team_id)].get("moves", 0)) + "*"
                    base_team.num_trades = str(
                        self.league_transactions_by_team[str(
                            base_team.team_id)].get("trades", 0)) + "*"

                    base_team.waiver_priority = team_data.get(
                        "waiverPosition", 0)
                    league.has_waiver_priorities = base_team.waiver_priority > 0
                    base_team.faab = team_data.get("waiverAcquisitionBudget",
                                                   {}).get("value", 0)
                    base_team.url = "https://www.fleaflicker.com/nfl/leagues/" + self.league_id + "/teams/" + \
                                    str(team_data.get("id"))

                    if team_data.get("streak").get("value"):
                        if team_data.get("streak").get("value") > 0:
                            streak_type = "W"
                        elif team_data.get("streak").get("value") < 0:
                            streak_type = "L"
                        else:
                            streak_type = "T"
                    else:
                        streak_type = "T"

                    base_team.division = team_division
                    base_team.current_record = BaseRecord(
                        wins=int(
                            team_data.get("recordOverall", {}).get("wins", 0)),
                        losses=int(
                            team_data.get("recordOverall",
                                          {}).get("losses", 0)),
                        ties=int(
                            team_data.get("recordOverall", {}).get("ties", 0)),
                        percentage=round(
                            float(
                                team_data.get("recordOverall",
                                              {}).get("winPercentage",
                                                      {}).get("value", 0)), 3),
                        points_for=float(
                            team_data.get("pointsFor", {}).get("value", 0)),
                        points_against=float(
                            team_data.get("pointsAgainst", {}).get("value",
                                                                   0)),
                        streak_type=streak_type,
                        streak_len=int(
                            abs(team_data.get("streak", {}).get("value", 0))),
                        team_id=base_team.team_id,
                        team_name=base_team.name,
                        rank=int(
                            team_data.get("recordOverall", {}).get("rank", 0)),
                        division=base_team.division,
                        division_wins=int(
                            team_data.get("recordDivision", {}).get("wins",
                                                                    0)),
                        division_losses=int(
                            team_data.get("recordDivision",
                                          {}).get("losses", 0)),
                        division_ties=int(
                            team_data.get("recordDivision", {}).get("ties",
                                                                    0)),
                        division_percentage=round(
                            float(
                                team_data.get("recordDivision",
                                              {}).get("winPercentage",
                                                      {}).get("value", 0)), 3),
                        division_rank=int(
                            team_data.get("recordDivision", {}).get("rank",
                                                                    0)))
                    base_team.streak_str = base_team.current_record.get_streak_str(
                    )
                    if base_matchup.division_matchup:
                        base_team.division_streak_str = base_team.current_record.get_division_streak_str(
                        )

                    # get median for week
                    week_median = self.median_score_by_week.get(str(week))

                    median_record = league_median_records_by_team.get(
                        str(base_team.team_id))  # type: BaseRecord
                    if not median_record:
                        median_record = BaseRecord(
                            team_id=base_team.team_id,
                            team_name=base_team.name,
                            points_for=(base_team.points - week_median),
                            points_against=week_median)
                        league_median_records_by_team[str(
                            base_team.team_id)] = median_record

                    if week_median:
                        # use this if you want the tie-break to be season total points over/under median score
                        median_record.add_points_for(base_team.points -
                                                     week_median)
                        # use this if you want the tie-break to be current week points over/under median score
                        # median_record.add_points_for(
                        #     (median_record.get_points_for() * -1) + (base_team.points - week_median))
                        median_record.add_points_against(
                            (median_record.get_points_against() * -1) +
                            week_median)
                        if base_team.points > week_median:
                            median_record.add_win()
                        elif base_team.points < week_median:
                            median_record.add_loss()
                        else:
                            median_record.add_tie()

                        base_team.current_median_record = median_record

                    # add team to matchup teams
                    base_matchup.teams.append(base_team)

                    # add team to league teams by week
                    league.teams_by_week[str(week)][str(
                        base_team.team_id)] = base_team

                    # no winner/loser if matchup is tied
                    if matchup.get(key + "Result") == "WIN":
                        base_matchup.winner = base_team
                    elif matchup.get(key + "Result") == "LOSE":
                        base_matchup.loser = base_team

                # add matchup to league matchups by week
                league.matchups_by_week[str(week)].append(base_matchup)

        for week, rosters in self.rosters_by_week.items():
            league.players_by_week[str(week)] = {}
            for team_id, roster in rosters.items():
                league_team = league.teams_by_week.get(str(week)).get(
                    str(team_id))  # type: BaseTeam

                for player in [
                        slot for group in roster.get("groups")
                        for slot in group.get("slots")
                ]:
                    flea_player_position = player.get("position")
                    flea_league_player = player.get("leaguePlayer")

                    if flea_league_player:
                        flea_pro_player = flea_league_player.get("proPlayer")

                        base_player = BasePlayer()

                        base_player.week_for_report = int(week)
                        base_player.player_id = flea_pro_player.get("id")
                        base_player.bye_week = int(
                            flea_pro_player.get("nflByeWeek", 0))
                        base_player.display_position = flea_pro_player.get(
                            "position")
                        base_player.nfl_team_id = None
                        base_player.nfl_team_abbr = flea_pro_player.get(
                            "proTeam", {}).get("abbreviation").upper()
                        base_player.nfl_team_name = flea_pro_player.get("proTeam", {}).get("location") + " " + \
                            flea_pro_player.get("proTeam", {}).get("name")
                        if flea_player_position.get("label") == "D/ST":
                            base_player.first_name = flea_pro_player.get(
                                "nameFull")
                        else:
                            base_player.first_name = flea_pro_player.get(
                                "nameFirst")
                            base_player.last_name = flea_pro_player.get(
                                "nameLast")
                        base_player.full_name = flea_pro_player.get("nameFull")
                        if flea_player_position.get("label") == "D/ST":
                            # use ESPN D/ST team logo (higher resolution) because Fleaflicker does not provide them
                            base_player.headshot_url = \
                                "https://a.espncdn.com/combiner/i?img=/i/teamlogos/nfl/500/{0}.png".format(
                                    base_player.nfl_team_abbr)
                        else:
                            base_player.headshot_url = flea_pro_player.get(
                                "headshotUrl")
                        base_player.owner_team_id = flea_league_player.get(
                            "owner", {}).get("id")
                        base_player.owner_team_name = flea_league_player.get(
                            "owner", {}).get("name")
                        base_player.percent_owned = 0
                        base_player.points = float(
                            flea_league_player.get("viewingActualPoints",
                                                   {}).get("value", 0))
                        # TODO: get season total points via summation, since this gives the end of season total, not
                        #  the total as of the selected week
                        # base_player.season_points = float(flea_league_player.get("seasonTotal", {}).get("value", 0))
                        # base_player.season_average_points = round(float(
                        #     flea_league_player.get("seasonAverage", {}).get("value", 0)), 2)
                        base_player.projected_points = None

                        base_player.position_type = "O" if flea_pro_player.get(
                            "position") in self.offensive_positions else "D"
                        base_player.primary_position = flea_pro_player.get(
                            "position")

                        eligible_positions = [
                            pos for positions in flea_league_player.get(
                                "rankFantasy", {}).get("positions", {}) for pos
                            in positions.get("position", {}).get("eligibility")
                        ]
                        for position in eligible_positions:
                            base_player.eligible_positions.append(position)
                            if position in league.flex_positions_rb_wr:
                                base_player.eligible_positions.append(
                                    "FLEX_RB_WR")
                            if position in league.flex_positions_te_wr:
                                base_player.eligible_positions.append(
                                    "FLEX_TE_WR")
                            if position in league.flex_positions_rb_te_wr:
                                base_player.eligible_positions.append(
                                    "FLEX_RB_TE_WR")
                            if position in league.flex_positions_qb_rb_te_wr:
                                base_player.eligible_positions.append(
                                    "FLEX_QB_RB_TE_WR")
                        base_player.eligible_positions = list(
                            set(base_player.eligible_positions))

                        selected_position = flea_player_position.get("label")
                        if selected_position == "RB/WR":
                            base_player.selected_position = "FLEX_RB_WR"
                        elif selected_position == "WR/TE":
                            base_player.selected_position = "FLEX_TE_WR"
                        elif selected_position == "RB/WR/TE":
                            base_player.selected_position = "FLEX_RB_TE_WR"
                        elif selected_position == "RB/WR/TE/QB":
                            base_player.selected_position = "FLEX_QB_RB_TE_WR"
                        else:
                            base_player.selected_position = selected_position
                        base_player.selected_position_is_flex = True if "/" in flea_pro_player.get(
                            "position") else False

                        base_player.status = flea_pro_player.get(
                            "injury", {}).get("typeAbbreviaition")

                        for stat in flea_league_player.get(
                                "viewingActualStats"):
                            base_stat = BaseStat()

                            base_stat.stat_id = stat.get("category",
                                                         {}).get("id")
                            base_stat.name = stat.get("category",
                                                      {}).get("abbreviation")
                            base_stat.value = stat.get("value",
                                                       {}).get("value", 0)

                            base_player.stats.append(base_stat)

                        # add player to team roster
                        league_team.roster.append(base_player)

                        # add player to league players by week
                        league.players_by_week[str(week)][
                            base_player.player_id] = base_player

        league.current_standings = sorted(league.teams_by_week.get(
            str(self.week_for_report)).values(),
                                          key=lambda x: x.current_record.rank)

        league.current_median_standings = sorted(
            league.teams_by_week.get(str(self.week_for_report)).values(),
            key=lambda x:
            (x.current_median_record.get_wins(), -x.current_median_record.
             get_losses(), x.current_median_record.get_ties(),
             x.current_median_record.get_points_for()),
            reverse=True)

        return league
Пример #4
0
    def map_data_to_base(self, base_league_class):
        logger.debug("Mapping Sleeper data to base objects.")

        league = base_league_class(self.week_for_report, self.league_id,
                                   self.config, self.data_dir, self.save_data,
                                   self.dev_offline)  # type: BaseLeague

        league.name = self.league_info.get("name")
        league.week = int(self.current_week)
        league.season = self.league_info.get("season")
        league.num_teams = int(self.league_settings.get("num_teams"))
        league.num_playoff_slots = int(self.num_playoff_slots)
        league.num_regular_season_weeks = int(self.num_regular_season_weeks)
        league.num_divisions = int(self.league_settings.get("divisions", 0))
        # TODO: missing division names
        league.divisions = None
        if league.num_divisions > 0:
            league.has_divisions = True
        league.has_median_matchup = self.has_median_matchup
        league.median_score = 0
        league.faab_budget = int(self.league_settings.get("waiver_budget"))
        if league.faab_budget > 0:
            league.is_faab = True
        # league.url = self.base_url + "league/" + str(self.league_id)
        league.url = "https://sleeper.app/leagues/" + str(self.league_id)

        # TODO: hook up to collected player stats by week
        league.player_data_by_week_function = None
        league.player_data_by_week_key = None

        league.bench_positions = ["BN", "IR"]

        for position, count in self.roster_positions.items():
            pos_name = position
            pos_count = count

            # TODO: no differentiation in API amongst Flex (WR / RB), Flex (WR / TE), and Flex (WR / RB / TE)...?
            if pos_name == "REC_FLEX":
                pos_name = "FLEX_TE_WR"
                league.flex_positions_te_wr = ["TE", "WR"]
            if pos_name == "FLEX":
                pos_name = "FLEX_RB_TE_WR"
                league.flex_positions_rb_te_wr = ["RB", "TE", "WR"]
            if pos_name == "SUPER_FLEX":
                pos_name = "FLEX_QB_RB_TE_WR"
                league.flex_positions_qb_rb_te_wr = ["QB", "RB", "TE", "WR"]
            if pos_name == "IDP_FLEX":
                pos_name = "FLEX_IDP"
                league.flex_positions_idp = ["DB", "DL", "LB"]

            pos_counter = deepcopy(pos_count)
            while pos_counter > 0:
                if pos_name not in league.bench_positions:
                    league.active_positions.append(pos_name)
                pos_counter -= 1

            league.roster_positions.append(pos_name)
            league.roster_position_counts[pos_name] = pos_count

        league_median_records_by_team = {}
        for week, matchups in self.matchups_by_week.items():
            matchups_week = str(week)
            league.teams_by_week[str(week)] = {}
            league.matchups_by_week[str(week)] = []

            for matchup in matchups:
                base_matchup = BaseMatchup()

                base_matchup.week = int(matchups_week)
                # TODO: because Sleeper doesn't tell current week of selected season, check current vs. previous season
                #  and use month to determine if it's first or second year within same season and mark matchups from
                #  previous years complete by default for the sake of this functionality working
                # base_matchup.complete = True if int(week) <= int(self.current_week) else False
                current_date = datetime.today()
                if current_date.month < 9 and int(
                        league.season) < (current_date.year - 1):
                    base_matchup.complete = True
                elif int(league.season) < current_date.year:
                    base_matchup.complete = True
                else:
                    base_matchup.complete = True if int(week) <= int(
                        self.current_week) else False
                base_matchup.tied = True if matchup[0].get(
                    "points") and matchup[1].get("points") and float(
                        matchup[0].get("points")) == float(
                            matchup[1].get("points")) else False

                for team in matchup:
                    team_info = team.get("info")
                    team_settings = team_info.get("settings")
                    base_team = BaseTeam()

                    base_team.team_id = team.get("roster_id")

                    opposite_key = 1 if matchup.index(team) == 0 else 0
                    team_standings_info = None
                    opposite_team_standings_info = None
                    team_rank = None
                    for roster in self.standings:
                        if int(roster.get("roster_id")) == int(
                                base_team.team_id):
                            team_standings_info = roster
                            team_rank = int(self.standings.index(roster) + 1)
                        elif int(roster.get("roster_id")) == int(
                                matchup[opposite_key].get("roster_id")):
                            opposite_team_standings_info = roster

                    team_division = None
                    if league.has_divisions:
                        team_division = team_standings_info.get(
                            "settings").get("division")
                        opponent_division = opposite_team_standings_info.get(
                            "settings").get("division")
                        if team_division and opponent_division and team_division == opponent_division:
                            base_matchup.division_matchup = True

                    base_team.week = int(matchups_week)

                    if team_info.get("owner"):
                        base_team.name = team_info.get("owner").get(
                            "metadata").get("team_name") if team_info.get(
                                "owner").get("metadata").get(
                                    "team_name") else team_info.get(
                                        "owner").get("display_name")
                    else:
                        base_team.name = "Team #{0}".format(
                            team_info.get("roster_id"))

                    if team_info.get("owner"):
                        for manager in [team_info.get("owner")
                                        ] + team_info.get("co_owners"):
                            base_manager = BaseManager()

                            base_manager.manager_id = manager.get("user_id")
                            base_manager.email = None
                            base_manager.name = manager.get("display_name")

                            base_team.managers.append(base_manager)
                    else:
                        base_manager = BaseManager()

                        base_manager.manager_id = "N/A"
                        base_manager.email = None
                        base_manager.name = "N/A"

                        base_team.managers.append(base_manager)

                    # base_team.manager_str = ", ".join([manager.name for manager in base_team.managers])
                    base_team.manager_str = team_info.get("owner").get("display_name") if team_info.get("owner") else \
                        "N/A"
                    base_team.points = round(float(team.get("points")),
                                             2) if team.get("points") else 0
                    base_team.num_moves = sum(
                        len(
                            self.league_transactions_by_week.get(
                                str(week), {}).get(str(base_team.team_id),
                                                   {}).get("moves", []))
                        for week in range(1,
                                          int(week) + 1))
                    base_team.num_trades = sum(
                        len(
                            self.league_transactions_by_week.get(
                                str(week), {}).get(str(base_team.team_id),
                                                   {}).get("trades", []))
                        for week in range(1,
                                          int(week) + 1))

                    base_team.waiver_priority = team_settings.get(
                        "waiver_position")
                    league.has_waiver_priorities = base_team.waiver_priority > 0
                    base_team.faab = league.faab_budget - int(
                        team_settings.get("waiver_budget_used", 0))
                    base_team.url = None

                    base_team.division = team_division
                    base_team.current_record = BaseRecord(
                        wins=int(team_settings.get("wins")),
                        losses=int(team_settings.get("losses")),
                        ties=int(team_settings.get("ties")),
                        percentage=round(
                            float(
                                int(team_settings.get("wins")) /
                                (int(team_settings.get("wins")) +
                                 int(team_settings.get("losses")) +
                                 int(team_settings.get("ties")))), 3)
                        if int(team_settings.get("wins")) +
                        int(team_settings.get("losses")) +
                        int(team_settings.get("ties")) > 0 else 0.0,
                        points_for=float(
                            str(team_settings.get("fpts")) + "." +
                            (str(team_settings.get("fpts_decimal"))
                             if team_settings.get("fpts_decimal") else "0")),
                        points_against=float(
                            (str(team_settings.get("fpts_against"))
                             if team_settings.get("fpts_against") else "0") +
                            "." +
                            (str(team_settings.get("fpts_against_decimal")) if
                             team_settings.get("fpts_against_decimal") else "0"
                             )),
                        streak_type=None,
                        streak_len=0,
                        team_id=base_team.team_id,
                        team_name=base_team.name,
                        rank=team_rank)
                    if league.has_divisions:
                        base_team.current_record.division = base_team.division

                    base_team.streak_str = base_team.current_record.get_streak_str(
                    )
                    if league.has_divisions:
                        if base_matchup.division_matchup:
                            base_team.division_streak_str = base_team.current_record.get_division_streak_str(
                            )

                    # get median for week
                    week_median = self.median_score_by_week.get(matchups_week)

                    median_record = league_median_records_by_team.get(
                        str(base_team.team_id))  # type: BaseRecord
                    if not median_record:
                        median_record = BaseRecord(
                            team_id=base_team.team_id,
                            team_name=base_team.name,
                            points_for=(base_team.points - week_median),
                            points_against=week_median)
                        league_median_records_by_team[str(
                            base_team.team_id)] = median_record

                    if week_median:
                        # use this if you want the tie-break to be season total points over/under median score
                        median_record.add_points_for(base_team.points -
                                                     week_median)
                        # use this if you want the tie-break to be current week points over/under median score
                        # median_record.add_points_for(
                        #     (median_record.get_points_for() * -1) + (base_team.points - week_median))
                        median_record.add_points_against(
                            (median_record.get_points_against() * -1) +
                            week_median)
                        if base_team.points > week_median:
                            median_record.add_win()
                        elif base_team.points < week_median:
                            median_record.add_loss()
                        else:
                            median_record.add_tie()

                        base_team.current_median_record = median_record

                    # add team to matchup teams
                    base_matchup.teams.append(base_team)

                    # add team to league teams by week
                    league.teams_by_week[str(week)][str(
                        base_team.team_id)] = base_team

                    # no winner/loser if matchup is tied
                    if not base_matchup.tied:
                        if base_team.team_id == matchup[0].get("roster_id"):
                            if matchup[0].get("points") and matchup[1].get(
                                    "points") and float(
                                        matchup[0].get("points")) > float(
                                            matchup[1].get("points")):
                                base_matchup.winner = base_team
                            else:
                                base_matchup.loser = base_team
                        elif base_team.team_id == matchup[1].get("roster_id"):
                            if matchup[1].get("points") and matchup[0].get(
                                    "points") and float(
                                        matchup[1].get("points")) > float(
                                            matchup[0].get("points")):
                                base_matchup.winner = base_team
                            else:
                                base_matchup.loser = base_team

                # add matchup to league matchups by week
                league.matchups_by_week[str(week)].append(base_matchup)

        for week, rosters in self.rosters_by_week.items():
            league.players_by_week[str(week)] = {}
            team_count = 1
            for team_id, roster in rosters.items():
                league_team = league.teams_by_week.get(str(week)).get(
                    str(team_id))  # type: BaseTeam

                team_filled_positions = [
                    position if position not in [
                        "REC_FLEX", "FLEX", "SUPER_FLEX", "IDP_FLEX"
                    ] else "FLEX_TE_WR" if position == "REC_FLEX" else
                    "FLEX_RB_TE_WR" if position == "FLEX" else
                    "FLEX_QB_RB_TE_WR" if position == "SUPER_FLEX" else
                    "FLEX_IDP" if position == "IDP_FLEX" else position
                    for position in self.league_info.get("roster_positions")
                ]

                for player in roster:
                    if player:
                        base_player = BasePlayer()

                        base_player.week_for_report = int(week)
                        base_player.player_id = player.get("player_id")
                        # TODO: missing bye
                        base_player.bye_week = None
                        base_player.display_position = player.get("position")
                        base_player.nfl_team_id = None
                        base_player.nfl_team_abbr = player.get("team")
                        # TODO: no full team name for player
                        base_player.nfl_team_name = player.get("team")
                        if base_player.display_position == "DEF":
                            base_player.first_name = player.get(
                                "first_name") + " " + player.get("last_name")
                            base_player.full_name = base_player.first_name
                            base_player.nfl_team_name = base_player.first_name
                            base_player.headshot_url = "https://sleepercdn.com/images/team_logos/nfl/" + \
                                                       str(base_player.player_id).lower() + ".png"
                        else:
                            base_player.first_name = player.get("first_name")
                            base_player.last_name = player.get("last_name")
                            base_player.full_name = player.get("full_name")
                            base_player.headshot_url = "https://sleepercdn.com/content/nfl/players/thumb/" + \
                                                       str(base_player.player_id) + ".jpg"
                        base_player.owner_team_id = None
                        base_player.owner_team_id = None
                        base_player.percent_owned = None

                        player_stats = player.get("stats")
                        base_player.points, base_player.projected_points = self.get_player_points(
                            stats=player_stats,
                            projected_stats=player.get("projected"))

                        base_player.season_points, base_player.season_projected_points = self.get_player_points(
                            stats=self.player_season_stats[str(
                                base_player.player_id)]
                            if str(base_player.player_id)
                            in self.player_season_stats.keys() else [],
                            projected_stats=self.player_season_projected_stats[
                                str(base_player.player_id)]
                            if str(base_player.player_id)
                            in self.player_season_projected_stats.keys() else
                            [])

                        base_player.position_type = "O" if base_player.display_position in self.offensive_positions \
                            else "D"
                        base_player.primary_position = player.get("position")

                        eligible_positions = player.get("fantasy_positions")
                        for position in eligible_positions:
                            base_player.eligible_positions.append(position)

                            if position in league.flex_positions_te_wr:
                                base_player.eligible_positions.append(
                                    "FLEX_TE_WR")
                            if position in league.flex_positions_rb_te_wr:
                                base_player.eligible_positions.append(
                                    "FLEX_RB_TE_WR")
                            if position in league.flex_positions_qb_rb_te_wr:
                                base_player.eligible_positions.append(
                                    "FLEX_QB_RB_TE_WR")
                            if position in league.flex_positions_idp:
                                base_player.eligible_positions.append(
                                    "FLEX_IDP")

                        base_player.eligible_positions = list(
                            set(base_player.eligible_positions))

                        if player["starter"]:
                            available_primary_slots = list(
                                set(base_player.eligible_positions).
                                intersection(
                                    set(team_filled_positions)).difference({
                                        "FLEX_TE_WR", "FLEX_RB_TE_WR",
                                        "FLEX_QB_RB_TE_WR"
                                    }))

                            available_rec_flex_slots = list(
                                set(base_player.eligible_positions).
                                intersection(set(league.flex_positions_te_wr)))

                            available_flex_slots = list(
                                set(base_player.eligible_positions).
                                intersection(
                                    set(league.flex_positions_rb_te_wr)))

                            available_super_flex_slots = list(
                                set(base_player.eligible_positions).
                                intersection(
                                    set(league.flex_positions_qb_rb_te_wr)))

                            available_idp_flex_slots = list(
                                set(base_player.eligible_positions).
                                intersection(set(league.flex_positions_idp)))

                            if len(available_primary_slots) > 0:
                                if base_player.primary_position in available_primary_slots:
                                    base_player.selected_position = base_player.primary_position
                                else:
                                    base_player.selected_position = available_primary_slots[
                                        0]
                                base_player.selected_position_is_flex = False
                                team_filled_positions.pop(
                                    team_filled_positions.index(
                                        base_player.selected_position))

                            elif len(
                                    available_rec_flex_slots
                            ) > 0 and "FLEX_TE_WR" in team_filled_positions:
                                base_player.selected_position = "FLEX_TE_WR"
                                base_player.selected_position_is_flex = True
                                team_filled_positions.pop(
                                    team_filled_positions.index(
                                        base_player.selected_position))

                            elif len(
                                    available_flex_slots
                            ) > 0 and "FLEX_RB_TE_WR" in team_filled_positions:
                                base_player.selected_position = "FLEX_RB_TE_WR"
                                base_player.selected_position_is_flex = True
                                team_filled_positions.pop(
                                    team_filled_positions.index(
                                        base_player.selected_position))

                            elif len(
                                    available_super_flex_slots
                            ) > 0 and "FLEX_QB_RB_TE_WR" in team_filled_positions:
                                base_player.selected_position = "FLEX_QB_RB_TE_WR"
                                base_player.selected_position_is_flex = True
                                team_filled_positions.pop(
                                    team_filled_positions.index(
                                        base_player.selected_position))

                            elif len(
                                    available_idp_flex_slots
                            ) > 0 and "FLEX_IDP" in team_filled_positions:
                                base_player.selected_position = "FLEX_IDP"
                                # base_player.selected_position_is_flex = True
                                team_filled_positions.pop(
                                    team_filled_positions.index(
                                        base_player.selected_position))

                            else:
                                raise ValueError(
                                    "Player position missing! Check data!")
                            league_team.projected_points += base_player.projected_points
                        else:
                            base_player.selected_position = "BN"
                            base_player.selected_position_is_flex = False

                        base_player.status = player.get("status")

                        if player_stats:
                            for stat, value in player_stats.items():
                                base_stat = BaseStat()

                                base_stat.stat_id = None
                                base_stat.name = stat
                                base_stat.value = value

                                base_player.stats.append(base_stat)

                        # add player to team roster
                        league_team.roster.append(base_player)

                        # add player to league players by week
                        league.players_by_week[str(week)][
                            base_player.player_id] = base_player

                team_count += 1

        league.current_standings = sorted(league.teams_by_week.get(
            str(self.week_for_report)).values(),
                                          key=lambda x: x.current_record.rank)

        league.current_median_standings = sorted(
            league.teams_by_week.get(str(self.week_for_report)).values(),
            key=lambda x:
            (x.current_median_record.get_wins(), -x.current_median_record.
             get_losses(), x.current_median_record.get_ties(),
             x.current_median_record.get_points_for()),
            reverse=True)

        return league
    def map_data_to_base(self, base_league_class):
        logger.debug("Mapping Yahoo data to base objects.")

        league = base_league_class(self.week_for_report, self.league_id,
                                   self.config, self.data_dir, self.save_data,
                                   self.dev_offline)  # type: BaseLeague

        league.name = self.league_info.name
        league.week = int(self.current_week)
        league.season = self.season
        league.num_teams = int(self.league_info.num_teams)
        league.num_playoff_slots = int(self.num_playoff_slots)
        league.num_regular_season_weeks = int(self.num_regular_season_weeks)
        league.num_divisions = self.num_divisions
        league.divisions = self.divisions
        if league.num_divisions > 0:
            league.has_divisions = True
        league.has_median_matchup = self.has_median_matchup
        league.median_score = 0
        league.is_faab = True if int(
            self.league_info.settings.uses_faab) == 1 else False
        if league.is_faab:
            league.faab_budget = self.config.getint("Settings",
                                                    "initial_faab_budget",
                                                    fallback=100)
        league.url = self.league_info.url

        league.player_data_by_week_function = self.get_player_data
        league.player_data_by_week_key = "player_points_value"

        league.bench_positions = ["BN", "IR"]

        for position in self.roster_positions:
            pos = position.get("roster_position")  # type: RosterPosition

            pos_name = pos.position
            pos_count = int(pos.count)

            if pos_name == "W/R":
                league.flex_positions_rb_wr = ["RB", "WR"]
                pos_name = "FLEX_RB_WR"
            if pos_name == "W/T":
                league.flex_positions_te_wr = ["TE", "WR"]
                pos_name = "FLEX_TE_WR"
            if pos_name == "W/R/T":
                league.flex_positions_rb_te_wr = ["RB", "TE", "WR"]
                pos_name = "FLEX_RB_TE_WR"
            if pos_name == "Q/W/R/T":
                league.flex_positions_qb_rb_te_wr = ["QB", "RB", "TE", "WR"]
                pos_name = "FLEX_QB_RB_TE_WR"
            if pos_name == "D":
                league.flex_positions_idp = [
                    "CB", "DB", "DE", "DL", "DT", "LB", "S"
                ]
                pos_name = "FLEX_IDP"

            pos_counter = deepcopy(pos_count)
            while pos_counter > 0:
                if pos_name not in league.bench_positions:
                    league.active_positions.append(pos_name)
                pos_counter -= 1

            league.roster_positions.append(pos_name)
            league.roster_position_counts[pos_name] = pos_count

        league_median_records_by_team = {}
        for week, matchups in self.matchups_by_week.items():
            league.teams_by_week[str(week)] = {}
            league.matchups_by_week[str(week)] = []
            for matchup in matchups:
                y_matchup = matchup.get("matchup")  # type: Matchup
                base_matchup = BaseMatchup()

                base_matchup.week = int(y_matchup.week)
                base_matchup.complete = True if y_matchup.status == "postevent" else False
                base_matchup.tied = True if (y_matchup.is_tied and int(
                    y_matchup.is_tied) == 1) else False

                for team in y_matchup.teams:  # type: dict
                    y_team = team.get("team")  # type: Team
                    base_team = BaseTeam()

                    opposite_key = 1 if y_matchup.teams.index(team) == 0 else 0
                    team_division = y_team.division_id
                    opponent_division = y_matchup.teams[opposite_key].get(
                        "team").division_id
                    if team_division and opponent_division and team_division == opponent_division:
                        base_matchup.division_matchup = True

                    base_team.week = int(y_matchup.week)
                    base_team.name = y_team.name
                    base_team.num_moves = y_team.number_of_moves
                    base_team.num_trades = y_team.number_of_trades

                    if isinstance(y_team.managers, list):
                        y_team_manager = y_team.managers
                    else:
                        y_team_manager = [y_team.managers]

                    for manager in y_team_manager:
                        y_manager = manager.get("manager")  # type: Manager
                        base_manager = BaseManager()

                        base_manager.manager_id = str(y_manager.manager_id)
                        base_manager.email = y_manager.email
                        base_manager.name = y_manager.nickname

                        base_team.managers.append(base_manager)

                    base_team.manager_str = ", ".join(
                        [manager.name_str for manager in base_team.managers])

                    base_team.team_id = str(y_team.team_id)
                    base_team.points = float(y_team.points)
                    base_team.projected_points = float(y_team.projected_points)
                    base_team.waiver_priority = y_team.waiver_priority
                    league.has_waiver_priorities = base_team.waiver_priority > 0
                    if league.is_faab:
                        base_team.faab = int(
                            y_team.faab_balance) if y_team.faab_balance else 0
                    base_team.url = y_team.url

                    team_standings_info = Team({})
                    for ranked_team in self.league_info.standings.teams:
                        ranked_team = ranked_team.get("team")
                        if int(ranked_team.team_id) == int(base_team.team_id):
                            team_standings_info = ranked_team  # type: Team

                    if team_standings_info.streak_type == "win":
                        streak_type = "W"
                    elif team_standings_info.streak_type == "loss":
                        streak_type = "L"
                    else:
                        streak_type = "T"

                    base_team.division = team_division
                    base_team.current_record = BaseRecord(
                        wins=int(team_standings_info.wins)
                        if team_standings_info.wins else 0,
                        losses=int(team_standings_info.losses)
                        if team_standings_info.losses else 0,
                        ties=int(team_standings_info.ties)
                        if team_standings_info.ties else 0,
                        percentage=float(team_standings_info.percentage)
                        if team_standings_info.percentage else 0.0,
                        points_for=float(team_standings_info.points_for)
                        if team_standings_info.points_for else 0.0,
                        points_against=float(
                            team_standings_info.points_against)
                        if team_standings_info.points_against else 0.0,
                        streak_type=streak_type,
                        streak_len=int(team_standings_info.streak_length)
                        if team_standings_info.streak_type else 0,
                        team_id=y_team.team_id,
                        team_name=y_team.name,
                        rank=int(team_standings_info.rank)
                        if team_standings_info.rank else 0,
                        division=base_team.division,
                        division_wins=int(team_standings_info.team_standings.
                                          divisional_outcome_totals.wins)
                        if team_standings_info.team_standings.
                        divisional_outcome_totals.wins else 0,
                        division_losses=int(team_standings_info.team_standings.
                                            divisional_outcome_totals.losses)
                        if team_standings_info.team_standings.
                        divisional_outcome_totals.losses else 0,
                        division_ties=int(team_standings_info.team_standings.
                                          divisional_outcome_totals.ties)
                        if team_standings_info.team_standings.
                        divisional_outcome_totals.ties else 0,
                        division_percentage=round(
                            float(team_standings_info.team_standings.
                                  divisional_outcome_totals.wins /
                                  (team_standings_info.team_standings.
                                   divisional_outcome_totals.wins +
                                   team_standings_info.team_standings.
                                   divisional_outcome_totals.ties +
                                   team_standings_info.team_standings.
                                   divisional_outcome_totals.losses)), 3) if
                        (team_standings_info.team_standings.
                         divisional_outcome_totals.wins + team_standings_info.
                         team_standings.divisional_outcome_totals.ties +
                         team_standings_info.team_standings.
                         divisional_outcome_totals.losses) > 0 else 0)
                    base_team.streak_str = base_team.current_record.get_streak_str(
                    )
                    if base_matchup.division_matchup:
                        base_team.division_streak_str = base_team.current_record.get_division_streak_str(
                        )

                    # get median for week
                    week_median = self.median_score_by_week.get(str(week))

                    median_record = league_median_records_by_team.get(
                        str(base_team.team_id))  # type: BaseRecord
                    if not median_record:
                        median_record = BaseRecord(team_id=base_team.team_id,
                                                   team_name=base_team.name)
                        league_median_records_by_team[str(
                            base_team.team_id)] = median_record

                    if week_median:
                        # use this if you want the tie-break to be season total points over/under median score
                        median_record.add_points_for(base_team.points -
                                                     week_median)
                        # use this if you want the tie-break to be current week points over/under median score
                        # median_record.add_points_for(
                        #     (median_record.get_points_for() * -1) + (base_team.points - week_median))
                        median_record.add_points_against(
                            (median_record.get_points_against() * -1) +
                            week_median)
                        if base_team.points > week_median:
                            median_record.add_win()
                        elif base_team.points < week_median:
                            median_record.add_loss()
                        else:
                            median_record.add_tie()

                        base_team.current_median_record = median_record

                    # add team to matchup teams
                    base_matchup.teams.append(base_team)

                    # add team to league teams by week
                    league.teams_by_week[str(week)][str(
                        base_team.team_id)] = base_team

                    # no winner/loser if matchup is tied
                    if not base_matchup.tied:
                        if y_team.team_key == y_matchup.winner_team_key:
                            base_matchup.winner = base_team
                        else:
                            base_matchup.loser = base_team

                # add matchup to league matchups by week
                league.matchups_by_week[str(week)].append(base_matchup)

        for week, rosters in self.rosters_by_week.items():
            league.players_by_week[str(week)] = {}
            for team_id, roster in rosters.items():
                league_team = league.teams_by_week.get(str(week)).get(
                    str(team_id))  # type: BaseTeam
                for player in roster:
                    y_player_for_week = player.get("player")  # type: Player
                    base_player = BasePlayer()

                    base_player.week_for_report = int(week)
                    base_player.player_id = y_player_for_week.player_key
                    base_player.bye_week = int(
                        y_player_for_week.bye) if y_player_for_week.bye else 0
                    base_player.display_position = y_player_for_week.display_position
                    base_player.nfl_team_id = y_player_for_week.editorial_team_key
                    base_player.nfl_team_abbr = y_player_for_week.editorial_team_abbr
                    base_player.nfl_team_name = y_player_for_week.editorial_team_full_name
                    base_player.first_name = y_player_for_week.first_name
                    base_player.last_name = y_player_for_week.last_name
                    base_player.full_name = y_player_for_week.full_name
                    if base_player.display_position != "DEF":
                        base_player.headshot_url = "https:" + y_player_for_week.headshot_url.split(
                            ":")[-1]
                    else:
                        # use ESPN D/ST team logo (higher resolution)
                        base_player.headshot_url = \
                            "https://a.espncdn.com/combiner/i?img=/i/teamlogos/nfl/500/{0}.png".format(
                                base_player.nfl_team_abbr)
                        # base_player.headshot_url = y_player_for_week.headshot_url
                    base_player.owner_team_id = y_player_for_week.ownership.owner_team_key
                    base_player.owner_team_name = y_player_for_week.ownership.owner_team_name
                    base_player.percent_owned = float(
                        y_player_for_week.percent_owned_value
                    ) if y_player_for_week.percent_owned_value else 0
                    base_player.points = float(y_player_for_week.player_points_value) if \
                        y_player_for_week.player_points_value else 0
                    base_player.position_type = y_player_for_week.position_type

                    base_player.primary_position = y_player_for_week.primary_position
                    if y_player_for_week.selected_position_value == "W/R":
                        base_player.selected_position = "FLEX_RB_WR"
                    elif y_player_for_week.selected_position_value == "W/T":
                        base_player.selected_position = "FLEX_TE_WR"
                    elif y_player_for_week.selected_position_value == "W/R/T":
                        base_player.selected_position = "FLEX_RB_TE_WR"
                    elif y_player_for_week.selected_position_value == "Q/W/R/T":
                        base_player.selected_position = "FLEX_QB_RB_TE_WR"
                    elif y_player_for_week.selected_position_value == "D":
                        base_player.selected_position = "FLEX_IDP"
                    else:
                        base_player.selected_position = y_player_for_week.selected_position_value
                    base_player.selected_position_is_flex = True if int(
                        y_player_for_week.selected_position.is_flex
                    ) == 1 else False

                    base_player.status = y_player_for_week.status

                    eligible_positions = y_player_for_week.eligible_positions
                    if isinstance(eligible_positions, dict):
                        eligible_positions = [eligible_positions]

                    for position in eligible_positions:
                        pos = position.get("position")
                        if pos == "W/R":
                            pos = "FLEX_RB_WR"
                        elif pos == "W/T":
                            pos = "FLEX_TE_WR"
                        elif pos == "W/R/T":
                            pos = "FLEX_RB_TE_WR"
                        elif pos == "Q/W/R/T":
                            pos = "FLEX_QB_RB_TE_WR"
                        elif pos == "D":
                            pos = "FLEX_IDP"
                        base_player.eligible_positions.append(pos)

                    for stat in y_player_for_week.stats:
                        y_stat = stat.get("stat")  # type: Stat
                        base_stat = BaseStat()

                        base_stat.stat_id = y_stat.stat_id
                        base_stat.name = y_stat.name
                        base_stat.value = y_stat.value

                        base_player.stats.append(base_stat)

                    # add player to team roster
                    league_team.roster.append(base_player)

                    # add player to league players by week
                    league.players_by_week[str(week)][
                        base_player.player_id] = base_player

        league.current_standings = sorted(league.teams_by_week.get(
            str(self.week_for_report)).values(),
                                          key=lambda x: x.current_record.rank)

        league.current_median_standings = sorted(
            league.teams_by_week.get(str(self.week_for_report)).values(),
            key=lambda x:
            (x.current_median_record.get_wins(), -x.current_median_record.
             get_losses(), x.current_median_record.get_ties(),
             x.current_median_record.get_points_for()),
            reverse=True)

        return league