the tabulations must die

This commit is contained in:
AdrienLSH
2024-02-08 12:47:10 +01:00
parent 9aa885c49d
commit f6bb48e772
32 changed files with 1070 additions and 1070 deletions

View File

@ -10,34 +10,34 @@ from .models import tournament_manager, TournamentMember, TournamentRoom, Tourna
class TournamentWebConsumer(WebsocketConsumer):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.channel_name = "tournament"
self.group_name = "tournament"
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.channel_name = "tournament"
self.group_name = "tournament"
def connect(self):
def connect(self):
self.user: User = self.scope["user"]
if (self.user.is_anonymous or not self.user.is_authenticated):
return
self.user: User = self.scope["user"]
if (self.user.is_anonymous or not self.user.is_authenticated):
return
self.channel_layer.group_add(self.group_name, self.channel_name)
self.channel_layer.group_add(self.group_name, self.channel_name)
self.tournament_id = int(self.scope['url_route']['kwargs']['tournament_id'])
self.tournament_id = int(self.scope['url_route']['kwargs']['tournament_id'])
self.room = tournament_manager.get(self.tournament_id)
self.member = TournamentMember(self.user.pk, self, self.room)
self.room = tournament_manager.get(self.tournament_id)
self.member = TournamentMember(self.user.pk, self, self.room)
if (self.room is None):
self.member.send("Tournament not found")
self.disconnect(1017)
self.room.append(self.member)
if (self.room is None):
self.member.send("Tournament not found")
self.disconnect(1017)
self.room.append(self.member)
def receive(self, text_data: str = None, bytes_data: bytes = None):
self.member.receive(text_data, bytes_data)
def receive(self, text_data: str = None, bytes_data: bytes = None):
self.member.receive(text_data, bytes_data)
def disconnect(self, close_code):
member = self.room.get_member_by_socket(self)
if (member is not None):
self.room.remove(self.member, close_code)
def disconnect(self, close_code):
member = self.room.get_member_by_socket(self)
if (member is not None):
self.room.remove(self.member, close_code)

View File

@ -13,142 +13,142 @@ from transcendence.abstract.AbstractRoomManager import AbstractRoomManager
# Create your models here.tu
class TournamentModel(models.Model):
name = models.CharField(max_length = 100)
nb_players = models.IntegerField()
nb_players_by_game = models.IntegerField()
level = models.IntegerField()
started = models.BooleanField(default = False)
finished = models.BooleanField(default = False)
name = models.CharField(max_length = 100)
nb_players = models.IntegerField()
nb_players_by_game = models.IntegerField()
level = models.IntegerField()
started = models.BooleanField(default = False)
finished = models.BooleanField(default = False)
def create_game(self, level, players_id):
game_id = GameModel().create(players_id = players_id)
TournamentGamesModel(game_id = game_id, tournament_id = self.pk, tournament_level = level).save()
return game_id
def get_games_id_by_level(self, level):
tmp = TournamentGamesModel.objects.filter(tournament_id = self.pk, tournament_level = level)
return [instance.game_id for instance in tmp]
def create_game(self, level, players_id):
game_id = GameModel().create(players_id = players_id)
TournamentGamesModel(game_id = game_id, tournament_id = self.pk, tournament_level = level).save()
return game_id
def get_games_id_by_level(self, level):
tmp = TournamentGamesModel.objects.filter(tournament_id = self.pk, tournament_level = level)
return [instance.game_id for instance in tmp]
def get_games_id(self):
return [tournament_game.game_id for tournament_game in TournamentGamesModel.objects.filter(tournament_id = self.pk)]
def get_players_id(self):
return [model.participant_id for model in TournamentParticipantsModel.objects.filter(tournament_id=self.pk)]
def is_a_participant(self, participant_id: int):
return TournamentParticipantsModel.objects.filter(participant_id = participant_id, tournament_id = self.pk).exists()
def get_games_id(self):
return [tournament_game.game_id for tournament_game in TournamentGamesModel.objects.filter(tournament_id = self.pk)]
def get_players_id(self):
return [model.participant_id for model in TournamentParticipantsModel.objects.filter(tournament_id=self.pk)]
def is_a_participant(self, participant_id: int):
return TournamentParticipantsModel.objects.filter(participant_id = participant_id, tournament_id = self.pk).exists()
def add_participants(self, participants_id: [int]):
for participant_id in participants_id:
TournamentParticipantsModel(tournament_id = self.pk, participant_id = participant_id).save()
def add_participants(self, participants_id: [int]):
for participant_id in participants_id:
TournamentParticipantsModel(tournament_id = self.pk, participant_id = participant_id).save()
def start(self, participants_id: [int]):
self.started = True
self.add_participants(participants_id)
games_id = [int]
for i in range(0, len(participants_id), self.nb_players_by_game):
game_id = self.create_game(0, participants_id[i : i + self.nb_players_by_game])
games_id.append(game_id)
self.save()
return games_id
def start(self, participants_id: [int]):
self.started = True
self.add_participants(participants_id)
games_id = [int]
for i in range(0, len(participants_id), self.nb_players_by_game):
game_id = self.create_game(0, participants_id[i : i + self.nb_players_by_game])
games_id.append(game_id)
self.save()
return games_id
class TournamentParticipantsModel(models.Model):
tournament_id = models.IntegerField()
participant_id = models.IntegerField()
tournament_id = models.IntegerField()
participant_id = models.IntegerField()
class TournamentGamesModel(models.Model):
tournament_id = models.IntegerField()
tournament_level = models.IntegerField()
game_id = models.IntegerField()
tournament_id = models.IntegerField()
tournament_level = models.IntegerField()
game_id = models.IntegerField()
class TournamentMember(AbstractRoomMember):
def __init__(self, user_id: int, socket: WebsocketConsumer, room):
super().__init__(user_id, socket)
self.participate = False
self.room = room
def __init__(self, user_id: int, socket: WebsocketConsumer, room):
super().__init__(user_id, socket)
self.participate = False
self.room = room
def receive(self, text_data: str = None, byte_dates: bytes = None):
if (text_data is None):
return
def receive(self, text_data: str = None, byte_dates: bytes = None):
if (text_data is None):
return
data: dict = json.loads(text_data)
data: dict = json.loads(text_data)
if (data.get("participate") is not None):
self.room.update_participants(self)
if (data.get("participate") is not None):
self.room.update_participants(self)
def send_error_message(self, message: str):
self.send("error", {"error_message": message})
def send_error_message(self, message: str):
self.send("error", {"error_message": message})
def go_to(self, url: str):
self.send("go_to", {"url": url})
def send_participating(self):
self.send("is_participant", {"is_participant": self.participate})
def go_to(self, url: str):
self.send("go_to", {"url": url})
def send_participating(self):
self.send("is_participant", {"is_participant": self.participate})
class TournamentRoom(AbstractRoom):
def __init__(self, room_manager, tournament_id: int):
super().__init__(room_manager)
self.tournament_id = tournament_id
self.tournament = TournamentModel.objects.get(pk = tournament_id)
def __init__(self, room_manager, tournament_id: int):
super().__init__(room_manager)
self.tournament_id = tournament_id
self.tournament = TournamentModel.objects.get(pk = tournament_id)
def start(self):
self.broadcast("tournament_start")
games_id = self.tournament.start(self.get_participants_id())
for i, participant in enumerate(self.get_participants()):
participant: TournamentMember
participant.go_to(f"games/{games_id[i // self.tournament.nb_players_by_game]}")
def start(self):
self.broadcast("tournament_start")
games_id = self.tournament.start(self.get_participants_id())
for i, participant in enumerate(self.get_participants()):
participant: TournamentMember
participant.go_to(f"games/{games_id[i // self.tournament.nb_players_by_game]}")
def update_participants(self, member: TournamentMember):
if (self.tournament.started):
member.send_error_message("Tournament already started")
return
member.participate = not member.participate
nb_participants = self.get_nb_participants()
self.broadcast("update_participants", {"nb_participants": nb_participants})
member.send_participating()
if (nb_participants == self.tournament.nb_players):
self.start()
def update_participants(self, member: TournamentMember):
if (self.tournament.started):
member.send_error_message("Tournament already started")
return
member.participate = not member.participate
nb_participants = self.get_nb_participants()
self.broadcast("update_participants", {"nb_participants": nb_participants})
member.send_participating()
if (nb_participants == self.tournament.nb_players):
self.start()
def get_nb_participants(self):
if (self.tournament.started):
return self.tournament.nb_players
nb_participants = 0
for member in self._member_list:
member: TournamentMember
if (member.participate):
nb_participants += 1
return nb_participants
def get_nb_participants(self):
if (self.tournament.started):
return self.tournament.nb_players
nb_participants = 0
for member in self._member_list:
member: TournamentMember
if (member.participate):
nb_participants += 1
return nb_participants
def get_participants(self):
return [member for member in self._member_list if member.participate]
def get_participants(self):
return [member for member in self._member_list if member.participate]
def get_participants_id(self):
return [member.user_id for member in self._member_list if member.participate]
def get_participants_id(self):
return [member.user_id for member in self._member_list if member.participate]
def append(self, member: TournamentMember):
super().append(member)
if self.tournament.started:
member.participate = self.tournament.is_a_participant(member.user_id)
member.send_participating()
member.send("nb_participants", {"nb_participants": self.get_nb_participants()})
def append(self, member: TournamentMember):
super().append(member)
if self.tournament.started:
member.participate = self.tournament.is_a_participant(member.user_id)
member.send_participating()
member.send("nb_participants", {"nb_participants": self.get_nb_participants()})
class TournamentRoomManager(AbstractRoomManager):
def get(self, tournament_id: int):
def get(self, tournament_id: int):
for room in self._room_list:
if (room.tournament_id == tournament_id):
return room
if (TournamentModel.objects.filter(pk = tournament_id).exists()):
room = TournamentRoom(self, tournament_id)
self.append(room)
return room
return None
for room in self._room_list:
if (room.tournament_id == tournament_id):
return room
if (TournamentModel.objects.filter(pk = tournament_id).exists()):
room = TournamentRoom(self, tournament_id)
self.append(room)
return room
return None
tournament_manager: TournamentRoomManager = TournamentRoomManager()

View File

@ -2,5 +2,5 @@ from django.urls import re_path
from . import consumers
websocket_urlpatterns = [
re_path(r'ws/tournaments/(?P<tournament_id>\d+)$', consumers.TournamentWebConsumer.as_asgi())
re_path(r'ws/tournaments/(?P<tournament_id>\d+)$', consumers.TournamentWebConsumer.as_asgi())
]

View File

@ -4,35 +4,35 @@ from games.serializers import GameSerializer
class TournamentSerializer(serializers.ModelSerializer):
levels = serializers.SerializerMethodField(read_only=True, required=False)
level = serializers.ReadOnlyField()
started = serializers.ReadOnlyField()
finished = serializers.ReadOnlyField()
name = serializers.CharField(default="")
levels = serializers.SerializerMethodField(read_only=True, required=False)
level = serializers.ReadOnlyField()
started = serializers.ReadOnlyField()
finished = serializers.ReadOnlyField()
name = serializers.CharField(default="")
class Meta:
model = TournamentModel
fields = ["name", "nb_players", "nb_players_by_game", "level", "started", "finished", "levels", "id"]
class Meta:
model = TournamentModel
fields = ["name", "nb_players", "nb_players_by_game", "level", "started", "finished", "levels", "id"]
def get_levels(self, instance: TournamentModel):
levels: list[list[int]] = []
for i in range(instance.level):
games_id: [int] = instance.get_games_id_by_level(i)
if (games_id == []):
break
levels.append(games_id)
return levels
def get_levels(self, instance: TournamentModel):
levels: list[list[int]] = []
for i in range(instance.level):
games_id: [int] = instance.get_games_id_by_level(i)
if (games_id == []):
break
levels.append(games_id)
return levels
def validate_nb_players(self, value: int):
if (value < 2):
raise serializers.ValidationError("The numbers of players must be greather than 2.")
return value
def validate_nb_players_by_game(self, value: int):
if (value < 2):
raise serializers.ValidationError("The numbers of players by game must be greather than 2.")
nb_players: str = self.initial_data.get("nb_players")
if (nb_players is not None and nb_players.isnumeric()):
nb_players: int = int(nb_players)
if (value > nb_players):
raise serializers.ValidationError("The numbers of players by game must be smaller than the numbers of players.")
return value
def validate_nb_players(self, value: int):
if (value < 2):
raise serializers.ValidationError("The numbers of players must be greather than 2.")
return value
def validate_nb_players_by_game(self, value: int):
if (value < 2):
raise serializers.ValidationError("The numbers of players by game must be greather than 2.")
nb_players: str = self.initial_data.get("nb_players")
if (nb_players is not None and nb_players.isnumeric()):
nb_players: int = int(nb_players)
if (value > nb_players):
raise serializers.ValidationError("The numbers of players by game must be smaller than the numbers of players.")
return value

View File

@ -9,36 +9,36 @@ import json
import uuid
class CreateTest(TestCase):
def setUp(self):
self.client = Client()
def setUp(self):
self.client = Client()
self.url = "/api/tournaments/"
self.url = "/api/tournaments/"
self.username = str(uuid.uuid4())
self.password = str(uuid.uuid4())
self.username = str(uuid.uuid4())
self.password = str(uuid.uuid4())
self.nb_players_by_game = 2
self.nb_players = 8
self.nb_players_by_game = 2
self.nb_players = 8
user: User = User.objects.create_user(username=self.username, password=self.password)
self.client.login(username=self.username, password=self.password)
user: User = User.objects.create_user(username=self.username, password=self.password)
self.client.login(username=self.username, password=self.password)
def test_normal(self):
response: HttpResponse = self.client.post(self.url, {"nb_players_by_game": self.nb_players_by_game, "nb_players": self.nb_players})
response_data: dict = json.loads(response.content)
self.assertDictContainsSubset({"name": ""}, response_data)
def test_normal(self):
response: HttpResponse = self.client.post(self.url, {"nb_players_by_game": self.nb_players_by_game, "nb_players": self.nb_players})
response_data: dict = json.loads(response.content)
self.assertDictContainsSubset({"name": ""}, response_data)
def test_too_small_nb_players_by_game(self):
response: HttpResponse = self.client.post(self.url, {"nb_players_by_game": 1, "nb_players": self.nb_players})
response_data = json.loads(response.content)
self.assertDictEqual(response_data, {'nb_players_by_game': ['The numbers of players by game must be greather than 2.']})
def test_too_small_nb_players(self):
response: HttpResponse = self.client.post(self.url, {"nb_players_by_game": self.nb_players_by_game, "nb_players": 1})
response_data = json.loads(response.content)
self.assertDictEqual(response_data, {'nb_players': ['The numbers of players must be greather than 2.'], 'nb_players_by_game': ['The numbers of players by game must be smaller than the numbers of players.']})
def test_too_small_nb_players_by_game(self):
response: HttpResponse = self.client.post(self.url, {"nb_players_by_game": 1, "nb_players": self.nb_players})
response_data = json.loads(response.content)
self.assertDictEqual(response_data, {'nb_players_by_game': ['The numbers of players by game must be greather than 2.']})
def test_too_small_nb_players(self):
response: HttpResponse = self.client.post(self.url, {"nb_players_by_game": self.nb_players_by_game, "nb_players": 1})
response_data = json.loads(response.content)
self.assertDictEqual(response_data, {'nb_players': ['The numbers of players must be greather than 2.'], 'nb_players_by_game': ['The numbers of players by game must be smaller than the numbers of players.']})
def test_nb_players_smaller_nb_players_by_game(self):
response: HttpResponse = self.client.post(self.url, {"nb_players_by_game": 5, "nb_players": 3})
response_data = json.loads(response.content)
self.assertDictEqual(response_data, {'nb_players_by_game': ['The numbers of players by game must be smaller than the numbers of players.']})
def test_nb_players_smaller_nb_players_by_game(self):
response: HttpResponse = self.client.post(self.url, {"nb_players_by_game": 5, "nb_players": 3})
response_data = json.loads(response.content)
self.assertDictEqual(response_data, {'nb_players_by_game': ['The numbers of players by game must be smaller than the numbers of players.']})

View File

@ -13,44 +13,44 @@ from .serializers import TournamentSerializer
# Create your views here.
class TournamentViewSet(viewsets.ModelViewSet):
queryset = TournamentModel.objects.all
serializer_class = TournamentSerializer
permission_classes = (permissions.IsAuthenticated,)
authentication_classes = (SessionAuthentication,)
queryset = TournamentModel.objects.all
serializer_class = TournamentSerializer
permission_classes = (permissions.IsAuthenticated,)
authentication_classes = (SessionAuthentication,)
def perform_create(self, serializer: TournamentSerializer):
def perform_create(self, serializer: TournamentSerializer):
nb_players = serializer.validated_data["nb_players"]
nb_players_by_game = serializer.validated_data["nb_players_by_game"]
level = 1
number: int = nb_players
while (number != nb_players_by_game):
number = number // 2 + (number % 2)
level += 1
nb_players = serializer.validated_data["nb_players"]
nb_players_by_game = serializer.validated_data["nb_players_by_game"]
level = 1
number: int = nb_players
while (number != nb_players_by_game):
number = number // 2 + (number % 2)
level += 1
tournament = serializer.save(level = level)
return Response(self.serializer_class(tournament).data, status=status.HTTP_201_CREATED)
def list(self, request: HttpRequest, state: str = ""):
query: QuerySet
match state:
case "started":
query = TournamentModel.objects.filter(started=True, finished=False)
case "finished":
query = TournamentModel.objects.filter(finished=True)
case "waiting":
query = TournamentModel.objects.filter(started=False, finished=False)
case _:
query = TournamentModel.objects.all()
serializer = TournamentSerializer(query, many=True)
return Response(serializer.data)
tournament = serializer.save(level = level)
return Response(self.serializer_class(tournament).data, status=status.HTTP_201_CREATED)
def list(self, request: HttpRequest, state: str = ""):
query: QuerySet
match state:
case "started":
query = TournamentModel.objects.filter(started=True, finished=False)
case "finished":
query = TournamentModel.objects.filter(finished=True)
case "waiting":
query = TournamentModel.objects.filter(started=False, finished=False)
case _:
query = TournamentModel.objects.all()
serializer = TournamentSerializer(query, many=True)
return Response(serializer.data)
def retrieve(self, request: HttpRequest, pk):
def retrieve(self, request: HttpRequest, pk):
if (not TournamentModel.objects.filter(pk=pk).exists()):
return Response({"detail": "Tournament not found."}, status=status.HTTP_404_NOT_FOUND)
tournament = TournamentModel.objects.get(pk=pk)
if (not TournamentModel.objects.filter(pk=pk).exists()):
return Response({"detail": "Tournament not found."}, status=status.HTTP_404_NOT_FOUND)
tournament = TournamentModel.objects.get(pk=pk)
return Response(self.serializer_class(tournament).data, status=status.HTTP_200_OK)
return Response(self.serializer_class(tournament).data, status=status.HTTP_200_OK)