def apply_fix(transaction):
                Logger.info(f"Processing league {league.id}")
                rosters = self.league_roster_repo.get_all(
                    league.id, transaction)
                schedule = self.league_config_repo.get_schedule_config(
                    league.id, transaction)

                previews: Dict[str, UserLeaguePreview] = {}
                for roster in rosters:
                    preview = self.user_league_repo.get(
                        roster.id, league.id, transaction)
                    previews[roster.id] = (preview)

                for roster in rosters:
                    week: ScheduleWeek = next(
                        week for week in schedule.weeks
                        if week.week_number == current_week)
                    matchup = next((m for m in week.matchups
                                    if (m.away and m.away.id == roster.id) or (
                                        m.home and m.home.id == roster.id)),
                                   None)
                    preview = previews[roster.id]

                    if not preview:
                        return False

                    preview.matchup = MatchupPreview.from_matchup(
                        matchup) if matchup else None
                    self.user_league_repo.set(roster.id, preview, transaction)

                return True
            def apply_fix(transaction):
                Logger.info(f"Processing league {league.id}")
                schedule = self.league_config_repo.get_schedule_config(
                    league.id, transaction)

                save_required = False
                for week in schedule.weeks:
                    for matchup in week.matchups:
                        if matchup.away and matchup.away.waiver_bids:
                            matchup.away.waiver_bids = []
                            save_required = True
                        if matchup.away and matchup.away.processed_waiver_bids:
                            matchup.away.processed_waiver_bids = []
                            save_required = True

                        if matchup.home and matchup.home.waiver_bids:
                            matchup.home.waiver_bids = []
                            save_required = True
                        if matchup.home and matchup.home.processed_waiver_bids:
                            matchup.home.processed_waiver_bids = []
                            save_required = True

                if save_required:
                    self.league_config_repo.set_schedule_config(
                        league.id, schedule, transaction)

                return save_required
Exemple #3
0
    def update_status_from_game_rosters(self, rostered_players: Dict[str,
                                                                     Player]):
        current_week = self.state_repo.get().current_week
        games = self.game_repo.for_week(self.season, current_week)

        teams_with_rosters: List[int] = []
        player_ids_on_game_roster: List[str] = []

        for game in games:
            if game.away_roster:
                teams_with_rosters.append(game.teams.away.id)
                ids = [p.id for p in game.away_roster.values()]
                player_ids_on_game_roster.extend(ids)

            if game.home_roster:
                teams_with_rosters.append(game.teams.home.id)
                ids = [p.id for p in game.home_roster.values()]
                player_ids_on_game_roster.extend(ids)

        for rostered_player in rostered_players.values():
            scratched = rostered_player.team.id in teams_with_rosters and rostered_player.id not in player_ids_on_game_roster
            if rostered_player.status_current == STATUS_ACTIVE and scratched:
                rostered_player.status_current = STATUS_INACTIVE
                rostered_player.hash = hash_dict(rostered_player.dict())
                Logger.info(f"Scratched {rostered_player.display_name}")
Exemple #4
0
def run_check(name: str, target: Callable):
    try:
        Logger.info(f"Starting test '{name}'")
        target()
        Logger.info(f"Test '{name}' completed successfully")
        return True
    except BaseException as ex:
        Logger.error(f"Test '{name}' failed", exc_info=ex)
        return False
Exemple #5
0
            def apply_fix(transaction):
                Logger.info(f"Processing league {league.id}")
                config = self.league_config_repo.get_scoring_config(league.id, transaction)

                if config.field_goal_returns_yards != config.kick_returns_yards:
                    config.field_goal_returns_yards = config.kick_returns_yards
                    self.league_config_repo.set_scoring_config(league.id, config, transaction)
                    return 1
                else:
                    return 0
Exemple #6
0
 def create_push_subscription(self,
                              subscription_name: str,
                              topic_name: str,
                              endpoint: str,
                              config: SubscriptionConfig = None):
     # return PubSubPublisher(self.project_id).create_push_subscription(subscription_name, topic_name, endpoint, config)
     Logger.info(
         f"Created virtual push subscription '{subscription_name}' on topic '{topic_name}' to {endpoint}"
     )
     return Subscription(name=subscription_name)
Exemple #7
0
        def end_of_day(transaction: Transaction) -> EndOfDayResult:
            scoreboard = self.public_repo.get_scoreboard(transaction)

            state = self.state_repo.get(transaction)

            if not state.waivers_active:
                Logger.info("Waivers not active")
                week_complete = scoreboard.all_games_complete()

                if not week_complete:
                    Logger.info("Week not yet complete")
                    return EndOfDayResult(command=command)

                now = datetime.now(tz=pytz.UTC)
                hours_since_last_game = hours_since(
                    scoreboard.last_game_start_time(), now)
                if hours_since_last_game < self.settings.min_stat_correction_hours:
                    Logger.info(
                        "Week complete but not enough time since last game",
                        extra={
                            "hours_since": hours_since_last_game,
                            "min_hours":
                            self.settings.min_stat_correction_hours
                        })
                    return EndOfDayResult(command=command)

                Logger.info(
                    "Week is complete, enabling waivers and publishing end of week"
                )
                state.waivers_active = True
                state.waivers_end = datetime.now().today() + timedelta(days=1)
                state.locks = Locks.reset()
                completed_week_number = scoreboard.week()
                state.current_week = completed_week_number + 1

                self.state_repo.set(state, transaction)

                return EndOfDayResult(
                    command=command,
                    state=state,
                    waivers_enabled=True,
                    completed_week_number=completed_week_number)
            else:
                Logger.info(
                    "Waivers are active, initializing waiver processing")
                state.waivers_active = False
                state.waivers_end = None
                self.state_repo.set(state, transaction)

                return EndOfDayResult(command=command,
                                      state=state,
                                      waivers_complete=True)
Exemple #8
0
            def apply_fix(transaction):
                Logger.info(f"Processing league {league.id}")
                rosters = self.league_roster_repo.get_all(
                    league.id, transaction)

                for roster in rosters:
                    roster.this_week_points_for = 0
                    roster.this_week_bench_points_for = 0

                    for position in roster.positions.values():
                        position.game_score = 0

                    self.league_roster_repo.set(league.id, roster, transaction)
Exemple #9
0
 def create_topic(self, topic_name: str):
     topic_path = self.get_topic_path(topic_name)
     try:
         try:
             self.publisher.get_topic(topic=topic_path)
             Logger.info("Topic exists", extra={"topic_name": topic_name})
         except NotFound:
             self.publisher.create_topic(name=topic_path)
             Logger.info("Topic created", extra={"topic_name": topic_name})
     except BaseException as ex:
         Logger.error("Failed to create topic",
                      extra={"topic_name": topic_name},
                      exc_info=ex)
         raise ex
    def execute(self, command: TCommand) -> TResult:
        name = type(self).__name__
        extra = {"command": command.json()}

        Logger.info(f"{name} executing", extra=extra)
        try:
            result = self.on_execute(command)
        except Exception as ex:
            Logger.error(f"Error executing {name}", exc_info=ex, extra=extra)
            raise ex

        Logger.info(f"{name} completed")

        return result
Exemple #11
0
    def create_push_subscription(
            self,
            subscription_name: str,
            topic_name: str,
            endpoint: str,
            config: SubscriptionConfig = None) -> Subscription:
        subscriber: SubscriberWrapper = SubscriberClient()
        subcription_path = subscriber.subscription_path(
            self.project_id, subscription_name)
        topic_path = self.get_topic_path(topic_name)

        if not config:
            config = SubscriptionConfig()

        logging_extra = {
            "subscription_name": subscription_name,
            "topic_name": topic_name,
            "config": config.dict(),
        }

        with subscriber:
            try:
                try:
                    subscription = subscriber.get_subscription(
                        request={"subscription": subcription_path})
                    Logger.info("Push subscription exists", logging_extra)
                    return subscription
                except NotFound:
                    request = Subscription(
                        name=subcription_path,
                        topic=topic_path,
                        push_config=PushConfig(push_endpoint=endpoint),
                        ack_deadline_seconds=60,
                        expiration_policy=ExpirationPolicy(ttl=Duration(
                            seconds=config.expiration_days *
                            86400) if config.expiration_days else None),
                        retry_policy=RetryPolicy(),
                        message_retention_duration=Duration(
                            seconds=config.retention_days * 86400))
                    subscription = subscriber.create_subscription(
                        request=request)
                    Logger.info("Push subscription created", logging_extra)
                    return subscription

            except BaseException as ex:
                Logger.error("Failed to create push subscription",
                             exc_info=ex,
                             extra=logging_extra)
                raise ex
Exemple #12
0
    def get_roster(self, roster_id):
        Logger.info(f"[CFL API] Fetching roster id {roster_id}")
        url = f"{self.endpoint}{roster_id}"
        response = requests.get(url)
        data = response.json()

        try:
            if data["success"] == 1:
                return data["players"]
            else:
                raise ApiException(data["message"])
        except Exception as ex:
            Logger.exception(
                f"[CFL API] Failed to fetch team rosters for {roster_id}",
                exc_info=ex)
            raise ApiException("Failed to retrieve rosters")
    def on_execute(
        self, command: UpdatePlayerStatsForWeekCommand
    ) -> UpdatePlayerStatsForWeekResult:
        Logger.info(f"Updating player stats for week {command.week}")

        season = command.season

        if self.public_repo.get_switches().enable_score_testing:
            season = 2019
            Logger.warn("SCORE TESTING SWITCH IS ENABLED")

        current_games = self.get_current_games(season, command.week)
        player_updates = get_players(current_games)

        transaction = self.game_repo.firestore.create_transaction()

        @firestore.transactional
        def update(transaction, players: List[GamePlayerStats]):

            pending_player_updates = []

            for player_update in players:
                player = self.player_repo.get(season, player_update.player.id,
                                              transaction)
                game_id = player_update.game_id
                if not player:
                    player = from_game_player(player_update.player,
                                              player_update.team)

                if not player.game_stats:
                    player.game_stats = {}

                player.game_stats[game_id] = PlayerGameStats(
                    team=player.team, **player_update.stats.dict())
                pending_player_updates.append(player)

            for player in pending_player_updates:
                self.player_repo.set(season, player, transaction)

            return pending_player_updates

        update(transaction, player_updates)

        return UpdatePlayerStatsForWeekResult(command=command, )
Exemple #14
0
def get_message_data(push: Dict) -> Dict:
    Logger.info(f"[PUB/SUB] {push}")

    if not push:
        raise InvalidPushException()

    message = push["message"]
    if not message:
        raise InvalidPushException()

    data = message["data"]
    if not data:
        raise InvalidPushException()

    try:
        payload = base64.b64decode(data)
        return json.loads(payload)
    except Exception:
        return data
Exemple #15
0
    def get(self, path: str) -> dict:
        url = f"{self.settings.cfl_api_endpoint}/{path}"
        url_no_key = url

        if "?" in url:
            url += f"&key={self.settings.cfl_api_key}"
        else:
            url += f"?key={self.settings.cfl_api_key}"

        Logger.info(f"[CFL API] Fetching {url_no_key}")
        response = requests.get(url)

        if response.ok:
            return response.json()
        else:
            Logger.error(
                f"[CFL API] Error fetching data from {url_no_key}: {response.text}"
            )
            raise CflApiException(response.text)
Exemple #16
0
def smoke_test(state_repo: StateRepository = Depends(
    create_state_repository)) -> Tuple[List[str], List[str]]:
    checks = {
        "firebase:state": state_repo.get,
    }

    Logger.info("Smoke test started")
    passes: List[str] = []
    failures: List[str] = []

    for name in checks:
        check = checks[name]
        passed = run_check(name, check)
        if passed:
            passes.append(name)
        else:
            failures.append(name)

    if failures:
        Logger.error("Smoke test completed with errors")
    else:
        Logger.info("Smoke test completed successfully")
    return passes, failures
Exemple #17
0
    def on_execute(self, command: UpdateGamesCommand) -> UpdateGamesResult:
        Logger.info(f"Updating games for week {command.week}")

        season = command.season

        if self.public_repo.get_switches().enable_score_testing:
            season = 2019
            Logger.warn("SCORE TESTING SWITCH IS ENABLED")

        current_games = self.get_current_games(season, command.week)
        stored_games = self.get_stored_games(season, command.week)

        roster_added = False
        for game_id in current_games:
            current_game = current_games[game_id]
            stored_game = stored_games.get(game_id, None)
            if current_game.away_roster and (not stored_game
                                             or not stored_game.away_roster):
                roster_added = True

            if current_game.home_roster and (not stored_game
                                             or not stored_game.home_roster):
                roster_added = True

        game_updates = get_changed_games(current_games, stored_games)
        player_updates = get_changed_players(game_updates, stored_games)

        transaction = self.game_repo.firestore.create_transaction()

        locked_teams: List[str] = []
        active_games_count = 0

        opponents: Dict[str, str] = {}

        for game in current_games.values():
            if game.event_status.event_status_id == EVENT_STATUS_POSTPONED:
                continue

            opponents[
                game.teams.away.abbreviation] = game.teams.home.abbreviation
            opponents[
                game.teams.home.abbreviation] = game.teams.away.abbreviation

            if game.event_status.has_started():
                active_games_count += 1
                locked_teams.append(game.teams.away.abbreviation)
                locked_teams.append(game.teams.home.abbreviation)

        all_games_active = active_games_count == len(current_games)

        new_locks_state = Locks.create(locked_teams, all_games_active)

        new_scoreboard = Scoreboard.create(current_games.values())
        new_opponents = Opponents.create(opponents)

        @firestore.transactional
        def update_games(transaction, games: Dict[str, Game],
                         players: List[GamePlayerStats]):
            state = self.state_repo.get()

            new_state = state.copy()
            new_state.locks = new_locks_state

            current_scoreboard = self.public_repo.get_scoreboard()
            current_opponents = self.public_repo.get_opponents()

            pending_player_updates = []

            for player_update in players:
                player = self.player_repo.get(season, player_update.player.id,
                                              transaction)
                game_id = player_update.game_id
                if not player:
                    player = from_game_player(player_update.player,
                                              player_update.team)

                if not player.game_stats:
                    player.game_stats = {}

                player.game_stats[game_id] = PlayerGameStats(
                    team=player.team, **player_update.stats.dict())
                player.recalc_season_stats()  # Should this be here?
                pending_player_updates.append(player)

            for game_id in games:
                game = game_updates[game_id]
                self.game_repo.set(season, game, transaction)

            for player in pending_player_updates:
                self.player_repo.set(season, player, transaction)

            if new_state.changed(state):
                self.state_repo.set(new_state, transaction)

            if new_scoreboard.changed(current_scoreboard):
                self.public_repo.set_scoreboard(new_scoreboard, transaction)

            if new_opponents.changed(current_opponents):
                self.public_repo.set_opponents(new_opponents, transaction)

            return pending_player_updates

        update_games(transaction, game_updates, player_updates)
        payloads = self.publish_changed_players(player_updates)

        if roster_added:
            self.publisher.publish(BaseModel(), UPDATE_PLAYERS_TOPIC)

        return UpdateGamesResult(
            command=command,
            changed_games=[game_updates[game_id] for game_id in game_updates],
            changed_players=payloads)
Exemple #18
0
 def create_topic(self, topic_name: str):
     # PubSubPublisher(self.project_id).create_topic(topic_name)
     Logger.info(f"Created virtual topic '{topic_name}'")
Exemple #19
0
    def publish(self, payload: BaseModel, topic_name: str):
        topic_path = self.get_topic_path(topic_name)
        data = payload.json()

        Logger.info(f"Published virtual pub/sub message to '{topic_path}")
        Logger.info(data)
Exemple #20
0
async def info():
    Logger.info("This is a test info log entry")
    Logger.info("This is a test info log entry with extra info",
                extra={"foo": "bar"})
    return {"logger": Logger.logger_type()}