def get_queryset(self): try: if Round.objects.filter(season=Season.get_current_season()).count() > 0: return Ladders.get_season_ranked_participants( Season.get_current_season(), amount=10).prefetch_related( Prefetch('bot', queryset=Bot.objects.all().only('user_id', 'name')), Prefetch('bot__user', queryset=User.objects.all().only('patreon_level'))) # top 10 bots else: return SeasonParticipation.objects.none() except NoCurrentSeason: return SeasonParticipation.objects.none()
def __init__(self, *args, **kwargs, ): super().__init__(*args, **kwargs) # change the available fields based upon whether the bot_data is available for editing or not # and whether there's a current season if self.instance.bot_data_is_currently_frozen(): self.fields['bot_data'].disabled = True try: Season.get_current_season() # in season except NoCurrentSeason: # outside season - don't allow activation self.fields['active'].disabled = True self.fields['active'].required = False
def handle(self, *args, **options): bot_id = options['botid'] seasons = [ options['seasonid'] if options['seasonid'] is not None else Season.get_current_season().id ] if options['allseasons']: seasons = Season.objects.all() self.stdout.write(f'looping {len(seasons)} Seasons') for s in seasons: if isinstance(s, Season): season_id = s.id else: season_id = s if bot_id is not None: sp = SeasonParticipation.objects.get(season_id=season_id, bot_id=bot_id) with transaction.atomic(): sp.lock_me() self.stdout.write( f'Generating current season stats for bot {bot_id}...') StatsGenerator.update_stats(sp) else: for sp in SeasonParticipation.objects.filter( season_id=season_id): with transaction.atomic(): sp.lock_me() self.stdout.write( f'Generating current season stats for bot {sp.bot_id}...' ) StatsGenerator.update_stats(sp) self.stdout.write('Done')
def CheckEloSum(self): sumElo = SeasonParticipation.objects.filter( season=Season.get_current_season()).aggregate(Sum('elo')) self.assertEqual( sumElo['elo__sum'], ELO_START_VALUE * Bot.objects.all().count()) # starting ELO times number of bots
def stats(request): return { 'match_count_1h': Result.objects.only('id').filter(created__gte=timezone.now() - timedelta(hours=1)).count(), 'match_count_24h': Result.objects.only('id').filter(created__gte=timezone.now() - timedelta(hours=24)).count(), 'active_bots': Bot.objects.only('id').filter(active=True).count(), 'arenaclients': User.objects.only('id').filter(type='ARENA_CLIENT', is_active=True).count(), 'aiarena_settings': settings, 'random_donator': User.random_donator(), 'config': config, 'current_season': Season.get_current_season_or_none(), }
def start_next_match(requesting_user): with transaction.atomic(): # REQUESTED MATCHES match = Matches._attempt_to_start_a_requested_match( requesting_user) if match is not None: return match # a match was found - we're done # LADDER MATCHES current_season = Season.get_current_season() # Get rounds with un-started matches rounds = Round.objects.raw( """ SELECT distinct cr.id from core_round cr inner join core_match cm on cr.id = cm.round_id where season_id=%s and finished is null and cm.started is null order by number for update""", (current_season.id, )) for round in rounds: match = Matches._attempt_to_start_a_ladder_match( requesting_user, round) if match is not None: return match # a match was found - we're done # If none of the previous matches were able to start, and we don't have 2 active bots available, # then we give up. active_bots = Bot.objects.only("id").filter( active=True).select_for_update() if not Bots.available_is_more_than(active_bots, 2): raise NotEnoughAvailableBots() # If we get to here, then we have # - no matches from any existing round we can start # - at least 2 active bots available for play if Round.max_active_rounds_reached(): raise MaxActiveRounds() else: # generate new round round = Matches._attempt_to_generate_new_round(current_season) match = Matches._attempt_to_start_a_ladder_match( requesting_user, round) if match is None: raise APIException( "Failed to start match. There might not be any available participants." ) else: return match
def start_match(match, assign_to) -> bool: match.lock_me() # lock self to avoid race conditions if match.started is None: # Avoid starting a match when a participant is not available participations = MatchParticipation.objects.raw( """ SELECT cm.id FROM core_matchparticipation cm where ((cm.use_bot_data =0 or cm.update_bot_data =0) or cm.bot_id not in ( select bot_id from core_matchparticipation inner join core_match m on core_matchparticipation.match_id = m.id left join core_result cr on m.id = cr.match_id where m.started is not null and cr.type is null and (core_matchparticipation.use_bot_data = 1 or core_matchparticipation.update_bot_data =1) and m.id != %s )) and match_id = %s """, (match.id, match.id)) if len(participations) < 2: # Todo: Commented out to avoid log spam. This used to be a last second sanity check. # Todo: Investigate whether it is still the case or whether this is no longer considered a system fault # Todo: worthy of a warning message being logged. # logger.warning(f"Match {match.id} failed to start unexpectedly" # f" because one of the participants was not available.") return False if match.round: # if this is a ladder match, record the starting elo for p in participations: p.starting_elo = p.bot.seasonparticipation_set.only('elo', 'bot_id') \ .get(season=Season.get_current_season()).elo p.save() match.started = timezone.now() match.assigned_to = assign_to match.save() return True else: logger.warning( f"Match {match.id} failed to start unexpectedly as it was already started." ) return False
def get(self, request, *args, **kwargs): season = Season.get_current_season_or_none() if season is None: return render(request, 'ranking_no_season.html') else: return redirect('season', pk=season.pk)