def create_game(srid=None, status='scheduled', away=None, home=None, site_sport=None, round_start_times=False): # site_sport, created = SiteSport.objects.get_or_create(name=sport) ssm = SiteSportManager() season_model_class = ssm.get_season_class(site_sport) dum_srid = '%s' % site_sport dum_season_year = 2016 dum_season_type = 'reg' dum_season, created = season_model_class.objects.get_or_create( srid=dum_srid, season_year=dum_season_year, season_type=dum_season_type, ) if srid is None: srid = "srid-%s" % int(round(time.time() * 1000)), if away is None: away = Dummy.create_team(alias='AWAY', site_sport=site_sport) if home is None: home = Dummy.create_team(alias='HOME', site_sport=site_sport) dt_now = timezone.now() if round_start_times: # zero out the seconds and microseconds! dt_now = dt_now.replace(dt_now.year, dt_now.month, dt_now.day, dt_now.hour, dt_now.minute, 0, 0) if site_sport is None: game = GameChild() else: ssm = SiteSportManager() game_model = ssm.get_game_class(site_sport) game = game_model() game.season = dum_season # cant be None game.srid = srid game.start = dt_now game.status = status game.away = away game.home = home game.save() return game
def handle(self, *args, **options): values = [] for x in options['values']: values.append(x) game_srid = values[0] duration = 500 try: duration = int(values[1]) # defaults to except IndexError: pass # there wasnt a duration specified, just use the default # find the Game -- check all sports ssm = SiteSportManager() game = None the_sport = None for sport in SiteSportManager.SPORTS: game_class = ssm.get_game_class(sport) try: game = game_class.objects.get(srid=game_srid) the_sport = sport break except game_class.DoesNotExist: pass self.stdout.write('checked %s for Game but it wasnt found' % sport) if game is None or the_sport is None: self.stdout.write('No game found for any sport ' '%s matching srid: %s\n' % (SiteSportManager.SPORTS, game_srid)) # get a prize structure that hopefully exists prize_structures = PrizeStructure.objects.all() count = prize_structures.count() r = Random() prize_structure = prize_structures[r.randint(0, count - 1)] self.stdout.write('randomly chosen prize structure: %s' % str(prize_structure)) # contest_pool_creator = ContestPoolCreator(the_sport, prize_structure, game.start, duration) contest_pool_creator.get_or_create()
def get_games(self, draft_group): """ Return the sports.<sport>.Game objects of the DraftGroup instance. This method simply gets the distinct('game_srid') rows from the QuerySet returned by get_game_teams(). :param draft_group: :return: QuerySet of sports.<sport>.Game objects """ # get the distinct games from the gameteam model distinct_gameteam_games = self.get_game_teams( draft_group=draft_group).distinct('game_srid') game_srids = [x.game_srid for x in distinct_gameteam_games] # get the sports game_model (ie: sports.<sport>.Game) ssm = SiteSportManager() game_model = ssm.get_game_class( sport=draft_group.salary_pool.site_sport) return game_model.objects.filter(srid__in=game_srids)
def create_player_stats_model(self, game_srid, player_srid, my_player_stats_instance): """ create a new PlayerStats model instance from the fields of the 'mongo_obj' :param mongo_obj: :return: """ site_sport_manager = SiteSportManager() site_sport = site_sport_manager.get_site_sport('nfl') player_model_class = site_sport_manager.get_player_class(site_sport) game_model_class = site_sport_manager.get_game_class(site_sport) try: player = player_model_class.objects.get(srid=player_srid) except player_model_class.DoesNotExist: # if they were never in the database, they wont be in draft group and we should not # deal with that here! - Probably means they are defensive players. return player_stats_model_class = self.get_player_stats_model_class() # get new instance player_stats = player_stats_model_class() # set all properties with these fieldnames to 0 player_stats.position = player.position # use the position from their Player object player_stats.srid_game = game_srid player_stats.game = game_model_class.objects.get(srid=game_srid) player_stats.srid_player = player_srid player_stats.player = player for fieldname, var in my_player_stats_instance.get_vars().items(): setattr(player_stats, fieldname, var) player_stats.save() logger.info( 'Missing PlayerStats model created for player: %s | srid: %s' % (player, player_srid))
def find_games_within_time_span(site_sport, start, end): # # we will use the SiteSportManager the model class for player, game ssm = SiteSportManager() game_model = ssm.get_game_class(site_sport) # get all games equal to or greater than start, and less than end. games = game_model.objects.filter(start__gte=start, start__lte=end).order_by('start') if len(games) == 0: err_msg = 'there are ZERO games in [%s until %s]' % (start, end) raise mysite.exceptions.NoGamesInRangeException(err_msg) elif len(games) < 2: raise NotEnoughGamesException() # # throw an exception if the specified start time does not coincide with any games if game_model.objects.filter(start=start).count() == 0: raise NoGamesAtStartTimeException() # Keep track of teams that are playing today. team_srids = [] for game in games: # make sure we do not encounter the same team multiple times! for check_team in [game.away, game.home]: if check_team.srid in team_srids: logger.warning("Excluding doubleheader game: %s" % game) # If we find a game that has a team that is already playing today, # exclude the second game. games = games.exclude(pk=game.pk) # Add the teams to our list of srids. team_srids.append(game.away.srid) team_srids.append(game.home.srid) return games
class BuyinTest(AbstractTest): """ create a basic contest, and use the BuyinManager to buy into it. """ def setUp(self): super().setUp() # ensure the default ticket TicketManager.create_default_ticket_amounts(verbose=False) # add funds to user self.user = self.get_basic_user() ct = CashTransaction(self.user) ct.deposit(100) # salary_generator = Dummy.generate_salaries() # self.salary_pool = salary_generator.pool # start # # self.verbose = True # set to False to disable print statements # # The sport we are going to build fake stats for. # Lets use nfl, but it doesnt matter what sport we use self.sport = 'nfl' # # Ensure there are Games by using the Dummy to generate fake stats. # The ScheduleManager requires that Game objects exist # because when it creates scheduled Contest objects # it is required to create a draft group. self.dummy = Dummy(sport=self.sport) self.generator = self.dummy.generate() self.salary_pool = self.generator.pool self.site_sport = self.dummy.site_sport # stash the site_sport for easy use self.site_sport_manager = SiteSportManager() self.game_model = self.site_sport_manager.get_game_class( self.site_sport) # ie: sports.nfl.models.Game self.games = self.game_model.objects.all() # there should be handful now, for today if self.games.count() <= 0: raise Exception( 'buyin.tests.BuyinTest - we meant to create games.... but none were created!') # end # create a simple prize pool self.first = 100.0 self.second = 50.0 self.third = 25.0 self.buyin = 10 cps = CashPrizeStructureCreator(name='test') cps.add(1, self.first) cps.add(2, self.second) cps.add(3, self.third) cps.set_buyin(self.buyin) cps.save() cps.prize_structure.save() self.prize_structure = cps.prize_structure self.ranks = cps.ranks # # create the Contest # now = timezone.now() # start = DfsDateTimeUtil.create(now.date(), time(23,0)) # end = DfsDateTimeUtil.create(now.date() + timedelta(days=1), time(0,0)) start = self.games[0].start + timedelta(minutes=5) end = self.games[self.games.count() - 1].start # set 'end' to start of last game cc = ContestCreator("test_contest", self.sport, self.prize_structure, start, end) self.draft_group2 = DraftGroup() self.draft_group2.salary_pool = self.salary_pool self.draft_group2.start = start self.draft_group2.end = end self.draft_group2.save() self.contest_pool, created = ContestPoolCreator( self.sport, self.prize_structure, start, (end - start).seconds * 60, self.draft_group2 ).get_or_create() self.contest = cc.create() self.contest.status = Contest.RESERVABLE self.contest.save() self.draft_group = DraftGroup() self.draft_group.salary_pool = self.salary_pool self.draft_group.start = start self.draft_group.end = end self.draft_group.save() def test_incorrect_contest_type(self): bm = BuyinManager(self.user) self.assertRaises(mysite.exceptions.IncorrectVariableTypeException, lambda: bm.buyin(0)) def test_incorrect_lineup_type(self): bm = BuyinManager(self.user) self.assertRaises(mysite.exceptions.IncorrectVariableTypeException, lambda: bm.buyin(self.contest, 0)) def test_simple_buyin(self): bm = BuyinManager(self.user) bm.buyin(self.contest_pool) def test_simple_ticket_buyin(self): tm = TicketManager(self.user) try: tm.get_ticket_amount(self.buyin) except Exception: ta = TicketAmount() ta.amount = self.buyin ta.save() tm.deposit(amount=self.buyin) bm = BuyinManager(self.user) bm.buyin(self.contest_pool) tm.ticket.refresh_from_db() self.assertEqual((tm.ticket.consume_transaction is not None), True) def test_lineup_no_contest_draft_group(self): lineup = Lineup() lineup.draft_group = self.draft_group2 lineup.user = self.user lineup.save() bm = BuyinManager(self.user) contest_pool = self.contest_pool contest_pool.draft_group = None contest_pool.save() self.assertRaises(exceptions.ContestIsNotAcceptingLineupsException, lambda: bm.buyin(contest_pool, lineup)) def test_lineup_share_draft_group(self): lineup = Lineup() lineup.draft_group = self.draft_group lineup.user = self.user bm = BuyinManager(self.user) self.assertRaises(exceptions.ContestLineupMismatchedDraftGroupsException, lambda: bm.buyin(self.contest_pool, lineup)) def test_contest_full(self): self.contest_pool.current_entries = 19 self.contest_pool.entries = 1 self.contest_pool.save() bm = BuyinManager(self.user) self.assertRaises(exceptions.ContestIsFullException, lambda: bm.buyin(self.contest_pool)) # def test_contest_is_in_progress(self): # self.contest.status = self.contest.INPROGRESS # self.contest.save() # self.should_raise_contest_is_in_progress_or_closed_exception() # # def test_contest_is_cancelled(self): # self.contest.status = self.contest.CANCELLED # self.contest.save() # self.should_raise_contest_is_in_progress_or_closed_exception() # # def test_contest_is_closed(self): # self.contest.status = self.contest.CLOSED # self.contest.save() # self.should_raise_contest_is_in_progress_or_closed_exception() # # def test_contest_is_completed(self): # self.contest.status = self.contest.COMPLETED # self.contest.save() # self.should_raise_contest_is_in_progress_or_closed_exception() # # def should_raise_contest_is_in_progress_or_closed_exception(self): # bm = BuyinManager(self.user) # self.assertRaises(exceptions.ContestIsInProgressOrClosedException, # lambda: bm.buyin(self.contest)) def test_user_owns_lineup(self): lineup = Lineup() lineup.draft_group = self.draft_group2 lineup.user = self.get_admin_user() bm = BuyinManager(self.user) self.assertRaises(LineupDoesNotMatchUser, lambda: bm.buyin(self.contest_pool, lineup)) def test_user_submits_past_max_entries(self): self.contest_pool.max_entries = 1 self.contest_pool.entries = 3 self.contest_pool.save() bm = BuyinManager(self.user) bm.buyin(self.contest_pool) bm = BuyinManager(self.user) self.assertRaises(exceptions.ContestMaxEntriesReachedException, lambda: bm.buyin(self.contest_pool))
class BlockManager(object): def __init__(self, block): self.block = block self.cutoff = self.block.get_utc_cutoff() self.block_prize_structures = BlockPrizeStructure.objects.filter(block=self.block) self.site_sport_manager = SiteSportManager() self.game_model_class = self.site_sport_manager.get_game_class(self.block.site_sport) def get_included_games(self): """ Based on the block's cutoff and dfsday_end times, get all the sport's games that fall in between the 2 times. :return: """ return self.game_model_class.objects.filter( start__gte=self.cutoff, start__lt=self.block.dfsday_end ).order_by('start') def create_contest_pools(self): """ to determine the start of the earliest game in the block, we look for all games between the dfsday_start and dfsday_end of the block, and get the earliest start time of games after the cutoff. this ensures we capture all the games in the range, as opposed to relying on the BlockGame objects which have a very low chance of not including very recent scheduling changes! """ # If we've already created pools for this block, don't attempt to create more, # that would cause us to have multiple slates of pools per day. if self.block.contest_pools_created: logger.info('Contests pools have already been created for this block, ' 'not creating more. %s' % self.block) return # Don't make contest pools for should_create_contest_pools == False. if not self.block.should_create_contest_pools: raise Exception( 'Not creating contest pools: Block.should_create_contest_pools is set to False.' ' - %s' % self.block) # default num_contest_pools_created = 0 # determine the start time included_games = self.get_included_games() logger.info('% included games' % included_games.count()) # we will not check if there are enough games here, and # ultimately let the draft group creator raise an exception # if it cant find enough games! if included_games.count() >= 1: earliest_start_time = included_games[0].start # duration is the # of minutes until the end of the Block (dfsday_end) td = self.block.dfsday_end - earliest_start_time duration = int(td.total_seconds() / 60) # convert seconds to minutes # create all required ContestPools logger.info('%s formats based on default %s PrizeStructure(s)' % ( len(self.block_prize_structures), self.block.site_sport) ) for block_prize_structure in self.block_prize_structures: # additional (optional) ContestPoolCreator arguments: # draft_group=None, user_entry_limit=None, entry_cap=None contest_pool_creator = ContestPoolCreator( self.block.site_sport.name, block_prize_structure.prize_structure, earliest_start_time, duration, set_name=True) # because this method may attempt to create a DraftGroup, # we must be able to handle the DraftGroup exceptions that # could potentially be thrown. contest_pool = contest_pool_creator.get_or_create() num_contest_pools_created += 1 logger.info('creating ContestPool: %s for Block: %s' % (contest_pool, self.block)) # # we really want to let exceptions propagate up to the admin # so were not currently catching any in here... if num_contest_pools_created != 0: self.block.contest_pools_created = True self.block.save() logger.info( '%s ContestPool(s) created for Block: %s' % (num_contest_pools_created, self.block))
class ScheduleDay(object): """ This is a factory that produces SportDays for each type of sport (MlbDay, NhlDay, etc). A SportDay is an object that has some properties that tell us when games for that sport usually start. With this info a Block is created. A block is a group of IRL games. """ tzinfo_est = pytz_timezone('America/New_York') datetime_format_date = '%Y-%m-%d' datetime_format_time = '%I:%M %p' default_season_types = ['reg', 'pst'] class SportDay(object): tzinfo_est = pytz_timezone('America/New_York') datetime_format_date = '%Y-%m-%d' datetime_format_time = '%I:%M %p' weekday = None saturday = None sunday = None weekday_values = [0, 1, 2, 3, 4] saturday_values = [5] sunday_values = [6] def __init__(self, site_sport, datetime_obj, games): self.site_sport = site_sport self.the_datetime = datetime_obj self.games = games # self.get_data() self.data = { 'weekday': None, 'type': None, 'total': None, 'include': None, 'exclude': None, 'include_times': None, 'exclude_times': None, 'include_pct': None, } self.get_data() def get_excluded_game_ids(self): return self.data['exclude'] def get_excluded_games(self): return self.games.filter(pk__in=self.get_excluded_game_ids()) def get_included_game_ids(self): return self.data['include'] def get_included_games(self): return self.games.filter(pk__in=self.get_included_game_ids()) def get_cutoff(self): """ get the 'cutoff_time' from the internal data """ return self.data['cutoff_time'] # def get_cutoff_datetime(self): # return self.data['cutoff_datetime'] def get_data(self): if self.games.count() == 0: return None weekday = None # 0 - 6 day index. its poorly named, but its NOT the self.weekday time() cutoff include = [] exclude = [] include_times = [] exclude_times = [] for game in self.games: if weekday is None: # weekday = game.start.weekday() # ... i think its actually this: weekday = self.get_local_datetime(game.start).weekday() datetime_start_est = self.get_local_datetime(game.start) if weekday in [0, 1, 2, 3, 4] and self.include_in_weekday_block(datetime_start_est): include.append(game.pk) include_times.append(self.get_str_local_time(game.start)) elif weekday in [5] and self.include_in_saturday_block(datetime_start_est): include.append(game.pk) include_times.append(self.get_str_local_time(game.start)) elif weekday in [6] and self.include_in_sunday_block(datetime_start_est): include.append(game.pk) include_times.append(self.get_str_local_time(game.start)) else: exclude.append(game.pk) exclude_times.append(self.get_str_local_time(game.start)) # self.data = { # 'weekday' : weekday, # 'type' : self.weekday_to_str(weekday), # 'total' : self.games.count(), # 'include' : include, # 'exclude' : exclude, # 'include_times' : include_times, # 'exclude_times' : exclude_times, # 'include_pct' : float(float(len(include)) / float(self.games.count())) # } self.save_internal_data(weekday, self.weekday_to_str(weekday), self.games.count(), include, exclude, include_times, exclude_times) return self.data def save_internal_data(self, weekday, type, total, include, exclude, include_times, exclude_times): self.data = { 'weekday': weekday, 'type': type, 'total': total, 'include': include, 'exclude': exclude, 'include_times': include_times, 'exclude_times': exclude_times, 'include_pct': float(float(len(include)) / float(total)), 'cutoff_time': self.get_weekday_cutoff_time(weekday), } def __str__(self): include_pct = self.data['include_pct'] if include_pct is None: include_pct = 0.0 else: include_pct = int(include_pct * 100.0) included = self.data['include'] if included is None: included = 0 else: included = len(included) return 'type: %s, weekday:%s, included games:%s pct (%s of %s) >>> included times %s ((excluded times %s))' \ '' % (self.data['type'], self.data['weekday'], include_pct, included, str(self.data['total']), str(self.data['include_times']), str(self.data['exclude_times'])) def weekday_to_str(self, weekday): if weekday in self.weekday_values: return 'Weekday' elif weekday in self.saturday_values: return 'Saturday' elif weekday in self.sunday_values: return 'Sunday' def get_weekday_cutoff_time(self, weekday): """ this is an internal method. use method get_cutoff() to retrieve the datetime.time() specifically related to the day of this instance after this sportday has been updated """ if weekday in self.weekday_values: return self.weekday elif weekday in self.saturday_values: return self.saturday elif weekday in self.sunday_values: return self.sunday def get_local_datetime(self, utc_datetime_obj): return utc_datetime_obj.astimezone(self.tzinfo_est) def get_str_local_time(self, datetime_obj): local_dt = datetime_obj.astimezone(self.tzinfo_est) return local_dt.strftime(self.datetime_format_time) def get_str_local_date(self, datetime_obj): local_dt = datetime_obj.astimezone(self.tzinfo_est) return local_dt.strftime(self.datetime_format_date) def include_in_weekday_block(self, datetime_obj): return datetime_obj.time() >= self.weekday def include_in_saturday_block(self, datetime_obj): return datetime_obj.time() >= self.saturday def include_in_sunday_block(self, datetime_obj): return datetime_obj.time() >= self.sunday class MlbDay(SportDay): weekday = time(19, 0) # 7pm + saturday = time(16, 0) # 4pm + sunday = time(13, 0) # 1pm + def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) class NhlDay(SportDay): weekday = time(19, 0) # 7pm + saturday = time(19, 0) # 7pm + sunday = time(15, 0) # 3pm + def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) class NbaDay(SportDay): weekday = time(19, 0) # 7pm + saturday = time(19, 0) # 7pm + sunday = time(18, 0) # 6pm + def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) class NflDay(SportDay): weekday = time(19, 0) # 7pm + (thursday night games) saturday = time(13, 0) # 1pm + (saturday games) sunday = time(13, 0) # 1pm + (sunday games) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) @staticmethod def factory(sport): if sport == 'nba': return ScheduleDay.NbaDay if sport == 'nhl': return ScheduleDay.NhlDay if sport == 'mlb': return ScheduleDay.MlbDay if sport == 'nfl': return ScheduleDay.NflDay else: raise Exception('ScheduleDay for sport: %s - UNIMPLEMENTED' % sport) # def get_data(self): # if self.games.count() == 0: # return None # # weekday = None # include = [] # exclude = [] # include_times = [] # exclude_times = [] # for game in self.games: # # if weekday is None: # weekday = game.start.weekday() # # datetime_start_est = self.get_local_datetime(game.start) # if weekday in [0,1,2,3,4] and self.include_in_weekday_block(datetime_start_est): # include.append(game.pk) # include_times.append(self.get_str_local_time(game.start)) # elif weekday in [5] and self.include_in_saturday_block(datetime_start_est): # include.append(game.pk) # include_times.append(self.get_str_local_time(game.start)) # elif weekday in [6] and self.include_in_sunday_block(datetime_start_est): # include.append(game.pk) # include_times.append(self.get_str_local_time(game.start)) # else: # exclude.append(game.pk) # exclude_times.append(self.get_str_local_time(game.start)) # # self.data = { # 'weekday' : weekday, # 'type' : self.weekday_to_str(weekday), # 'total' : self.games.count(), # 'include' : include, # 'exclude' : exclude, # 'include_times' : include_times, # 'exclude_times' : exclude_times, # 'include_pct' : float(float(len(include)) / float(self.games.count())) # } # # return self.data def __init__(self, sport, season=None, season_types=None): self.data = None self.sport = sport self.sport_day_class = ScheduleDay.factory(self.sport) self.site_sport_manager = SiteSportManager() self.site_sport = self.site_sport_manager.get_site_sport(self.sport) self.game_model_class = self.site_sport_manager.get_game_class(self.site_sport) self.season = season # season is None, only get games for the season type after 'now' self.season_types = season_types if self.season_types is None: self.season_types = self.default_season_types # setup the datetime range with a start and end self.start = None self.end = None def get_data(self): return self.data def update_range(self, days_ago): """ add timedelta(days=days) to the start and end datetime object :param days_ago: :return: """ dfs_date_range = DfsDate.get_current_dfs_date_range() # set our dfsday range to start on the first day of the games we found self.start = dfs_date_range[0] - timedelta(days=days_ago) self.end = dfs_date_range[1] - timedelta(days=days_ago) def get_day_range(self): return self.start, self.end def get_days_since(self, datetime_obj): td = (timezone.now() - datetime_obj) return abs(td.days) + 1 def increment_day_range(self): self.start = self.start + timedelta(days=1) self.end = self.end + timedelta(days=1) def update(self, verbose=False): """ update the list of dfs days, with tuples of the start times and lists of all the games with their own unique start times """ # if running for the first time, its very likely you wont want to add 1 day to start time # dfs_date_tomorrow = DfsDate.get_current_dfs_date_range()[0] + timedelta(days=1) dfs_date_tomorrow = DfsDate.get_current_dfs_date_range()[0] logger.info("Looking for games later than: %s" % dfs_date_tomorrow) games = [] # default self.data = [] if self.season is None: # we are going to have to find the following dfs day... and check gte its start time games = self.game_model_class.objects.filter( start__gte=dfs_date_tomorrow, season__season_type__in=self.season_types).order_by('start') # oldest first else: games = self.game_model_class.objects.filter( season__season_year=self.season, season__season_type__in=self.season_types).order_by('start') # oldest first if games.count() <= 0: logger.info('0 games found. exiting...') return else: logger.info('%s games found, as old as %s' % (games.count(), games[0].start)) # days_ago = self.get_days_since(games[0].start) self.update_range(days_ago) day_range = self.get_day_range() # logger.info('first day (dt range)', str(day_range)) # Weekdays@7pm or later # Saturdays@7pm or later # Sundays@6pm or later # idx = 0 while games.filter(start__gte=self.get_day_range()[0]).count() > 0: # get all the games for the dfs day daily_games = games.filter(start__range=self.get_day_range()) if daily_games.count() >= 2: # there must be more than 2 games for DFS! dt = self.get_day_range()[0] date_str = self.get_str_local_date(dt) self.data.append((date_str, self.sport_day_class(self.site_sport, dt, daily_games))) # self.increment_day_range() def get_str_local_time(self, datetime_obj): local_dt = datetime_obj.astimezone(self.tzinfo_est) return local_dt.strftime(self.datetime_format_time) def get_str_local_date(self, datetime_obj): local_dt = datetime_obj.astimezone(self.tzinfo_est) return local_dt.strftime(self.datetime_format_date) def show_time_blocks(self): self.update() for date_str, sport_day in self.data: print(date_str, str(sport_day))
def __get_game_model(self): ssm = SiteSportManager() return ssm.get_game_class(self.site_sport)
def handle(self, *args, **options): for name in settings.CACHES.keys(): cache = caches[name] cache.clear() self.stdout.write('[%s] cache cleared!\n' % name) ssm = SiteSportManager() game_class = None sport = None pbp_list = [] for sport_string in options['sport']: sport = sport_string game_class = ssm.get_game_class(sport_string) for game_srid in options['srid']: # Since we can't query by game_srid, we need to grab all events that are timestamped # after the game began, then loop though them trying to match game_srid in order # to determine if they are for the specified game or not. # Get the Game model. print('Getting Game for srid: %s' % game_srid) game = game_class.objects.get(srid=game_srid) print("Game found: %s" % game) # Find any dataden Updates that might be for that game, based on the timestamp. updates = Update.objects.filter(ts__gte=game.start) print( 'Found %s potential PBP events. (not all of these are matches)' % updates.count()) game_ids = set([]) for update in updates: # The actual data is stored as a string'd python object. Eval it so we can check # it's game_srid. update_data = ast.literal_eval(update.o) game_id = update_data.get('game__id') game_ids.add(game_id) if not game_id: game_id = update_data.get('id') if game_id and game_id == game_srid: pbp_list.append(update_data) # send it through parser! # Ideally we'd take the output of the parser here and output it to a file, # but the system isn't setup like that. Instead I made an optional setting # that will pipe anything we'd normally send to Pusher and output it to # a text file. You can see that in `push.classes`, look # for: settings.PUSHER_OUTPUT_TO_FILE to see the logic. parser = DataDenParser() ns_parts = update.ns.split( '.') # split namespace on dot for db and coll db = ns_parts[0] collection = ns_parts[1] parser.parse_obj(db, collection, ast.literal_eval(update.o), async=False) # If you want to dump out the objects we got from Dataden, before they were run # through the parsers, uncomment these lines. # # file_path = 'tmp/dataden_events--%s_game__%s.json' % (sport, game_srid) # print("Writing out %s Dataden PBP events for this game to `%s`" % ( # len(pbp_list), file_path)) # # with open(file_path, 'w') as outfile: # json.dump(pbp_list, outfile) print('Done!') print( "\nIf you didn't find any events with this id, maybe try one of these game ids:\n\n" ) print(game_ids) print('\n\n')