Ejemplo n.º 1
0
def tournament_detail(request, token):
    try:
        tournament = Tournament.objects.get(
            Q(admin_token=token) |
            Q(spectator_token=token)
        )
    except Tournament.DoesNotExist:
        return not_found_view(request)

    is_admin = token == tournament.admin_token

    data = tournament_data(tournament, is_admin)

    if request.method == 'POST':
        if not is_admin:
            return JsonResponse(
                status=405,
                data={
                    'code': 'MethodNotAllowed',
                    'message': 'Method not allowed.',
                },
            )

        game_preds = {}
        for game in tournament.games.exclude(players_in__player__isnull=True):
            race = (
                Race.objects
                .annotate(result_count=Count('results'))
                .filter(cup__game=game, result_count=0)
                .order_by('cup__number', 'number')
                .first()
            )

            if race:
                game_preds[game.name] = {
                    'cup': race.cup.number,
                    'race': race.number,
                    'positions': [
                        is_pre(is_int, is_in_range(1, 12, stop_in=True))
                        for _ in range(game.players_in.count())
                    ],
                }

        is_result = is_decodable_json_where(is_dict_union('game', game_preds))

        valid = is_result.explain(request.body)
        if not valid:
            return JsonResponse(
                status=400,
                data={
                    'code': 'BadRequest',
                    'message': 'Request body is not valid.',
                    'details': valid.dict(),
                },
            )

        race = Race.objects.get(
            cup__game__tournament=tournament,
            cup__game__name=valid.data['game'],
            cup__number=valid.data['cup'],
            number=valid.data['race'],
        )
        players = list(race.cup.game.players_in.order_by('position', 'id'))
        for player, position in zip(players, valid.data['positions']):
            Result.objects.create(
                race=race,
                slot=player,
                position=position,
            )

        new_data = tournament_data(tournament, is_admin)

        game_data = next(
            game_data
            for game_data in new_data['games']
            if game_data['name'] == valid.data['game']
        )
        if all(
            result is not None
            for cup_data in game_data['cups']
            for player_data in cup_data
            for result in player_data['races']
        ):
            for i, slot in enumerate(
                race.cup.game.players_out.order_by('position', 'id')
            ):
                slot.player = players[game_data['total'][i]['player']].player
                slot.save()

            new_data = tournament_data(tournament, is_admin)

        changes = list(diff(data, new_data))
        if changes:
            channel_layer = channels.layers.get_channel_layer()
            async_to_sync(channel_layer.group_send)(
                f'tournament-{tournament.id}',
                {'type': 'tournament_changes', 'changes': changes},
            )

        data = new_data

    return JsonResponse(data)
Ejemplo n.º 2
0
 def test_in_range_in_in(self, start, stop, value):
     pred = is_in_range(start, stop, start_in=True, stop_in=True)
     with self.subTest('explain=True == explain=False'):
         self.assertEqual(pred(value), pred.explain(value).valid)
     with self.subTest('pred correct'):
         self.assertEqual(pred(value), start <= value <= stop)