diff --git a/insalan/admin.py b/insalan/admin.py index 643f8e13..583e3e82 100644 --- a/insalan/admin.py +++ b/insalan/admin.py @@ -23,7 +23,7 @@ def get_app_list(self, request, app_label=None): continue app = app_dict[app_name] # Sort the models - app['models'].sort(key=lambda x: object_list.index(x['object_name'])) + app['models'].sort(key=lambda x, object_list=object_list: object_list.index(x['object_name'])) app_list.append(app) return app_list diff --git a/insalan/mailer.py b/insalan/mailer.py index 8ca803c0..cf0a4e32 100644 --- a/insalan/mailer.py +++ b/insalan/mailer.py @@ -1,17 +1,18 @@ import logging import sys from django.contrib.auth.models import Permission -from django.core.mail import EmailMessage, get_connection, send_mail +from django.core.mail import EmailMessage, get_connection from django.contrib.auth.tokens import ( PasswordResetTokenGenerator, default_token_generator, ) from django.utils.translation import gettext_lazy as _ +from apscheduler.schedulers.background import BackgroundScheduler + import insalan.settings from insalan.user.models import User from insalan.tickets.models import TicketManager -from apscheduler.schedulers.background import BackgroundScheduler class EmailConfirmationTokenGenerator(PasswordResetTokenGenerator): """ diff --git a/insalan/payment/serializers.py b/insalan/payment/serializers.py index 6db50597..b7d864c8 100644 --- a/insalan/payment/serializers.py +++ b/insalan/payment/serializers.py @@ -1,7 +1,9 @@ +import logging + from rest_framework import serializers -from .models import Transaction, TransactionStatus, Product from insalan.user.models import User -import logging + +from .models import Transaction, Product logger = logging.getLogger(__name__) @@ -12,7 +14,7 @@ class Meta: model=Transaction fields = "__all__" read_only_fields = ["amount", "payer", "payment_status", "intent_id", "creation_date", "last_modification_date"] - + def create(self, validated_data): """ Create a transaction with products based on the request""" logger.debug(f"in the serializer {validated_data}") @@ -23,6 +25,3 @@ class ProductSerializer(serializers.ModelSerializer): class Meta: model = Product fields = "__all__" - - - diff --git a/insalan/payment/views.py b/insalan/payment/views.py index 1d67ad97..7414f837 100644 --- a/insalan/payment/views.py +++ b/insalan/payment/views.py @@ -6,11 +6,8 @@ import requests -from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned -from django.http import JsonResponse, HttpResponseRedirect -from django.shortcuts import render +from django.http import JsonResponse from django.utils.translation import gettext_lazy as _ -from django.views.decorators.csrf import csrf_exempt from rest_framework import generics, permissions, status from rest_framework.views import APIView from rest_framework.response import Response @@ -47,7 +44,7 @@ def get(self, request, *args, **kwargs): Get all products """ return super().get(request, *args, **kwargs) - + class ProductDetails(generics.RetrieveUpdateDestroyAPIView): """ @@ -68,7 +65,7 @@ def get(self, request, *args, **kwargs): Get a product """ return super().get(request, *args, **kwargs) - + @swagger_auto_schema( request_body=serializers.ProductSerializer, responses={ @@ -528,4 +525,4 @@ def create(self, request): ) def post(self, request, *args, **kwargs): """Process a payment request""" - return super().post(request, *args, **kwargs) \ No newline at end of file + return super().post(request, *args, **kwargs) diff --git a/insalan/tickets/views.py b/insalan/tickets/views.py index 4077ee81..5ae2f8e3 100644 --- a/insalan/tickets/views.py +++ b/insalan/tickets/views.py @@ -22,9 +22,9 @@ from insalan.tournament.models import Team, Player, Substitute, Manager, PaymentStatus from insalan.user.models import User -from .models import Ticket, TicketManager from insalan.mailer import MailManager from insalan.settings import EMAIL_AUTH +from .models import Ticket, TicketManager @swagger_auto_schema( method='get', @@ -441,7 +441,7 @@ def unpaid(request: HttpRequest) -> JsonResponse: """ # Get all the registrations that are not paid players = Player.objects.filter( - team__validated=True, + team__validated=True, team__tournament__event__ongoing=True ).exclude(payment_status=PaymentStatus.PAID) substitutes = Substitute.objects.filter( diff --git a/insalan/tournament/admin.py b/insalan/tournament/admin.py index 36d7ee13..759dfc4e 100644 --- a/insalan/tournament/admin.py +++ b/insalan/tournament/admin.py @@ -36,6 +36,7 @@ create_group_matchs, create_swiss_matchs, ) +from insalan.admin import ADMIN_ORDERING from .models import ( BestofType, @@ -66,8 +67,6 @@ sensitive_post_parameters_m = method_decorator(sensitive_post_parameters()) -from insalan.admin import ADMIN_ORDERING - ADMIN_ORDERING += [ ('tournament', [ 'Event', @@ -97,9 +96,9 @@ class SeatCanvasWidget(forms.Widget): Custom widget for the seat canvas """ def render(self, name, value, attrs=None, renderer=None): - id = attrs["id"] if attrs else "id_" + name + element_id = attrs["id"] if attrs else "id_" + name return ( - f'' + f'' '' ) @@ -163,7 +162,7 @@ class EventAdmin(admin.ModelAdmin): list_display = ("id", "name", "description", "year", "month", "ongoing") search_fields = ["name", "year", "month", "ongoing"] - + class Media: css = { 'all': ('css/seat_canvas.css',) @@ -594,9 +593,9 @@ def get_urls(self): change_password_form = AdminPasswordChangeForm @sensitive_post_parameters_m - def team_change_password(self, request, id, form_url=""): + def team_change_password(self, request, team_id, form_url=""): """Change the password of a team""" - team = Team.objects.get(pk=id) + team = Team.objects.get(pk=team_id) if not self.has_change_permission(request, team): raise PermissionDenied if team is None: @@ -903,9 +902,9 @@ def create_group_matchs_action(self,request,queryset): for group in queryset: matchs_status = GroupMatch.objects.filter(group=group).values_list("status", flat=True) if MatchStatus.ONGOING in matchs_status or MatchStatus.COMPLETED in matchs_status: - self.message_user(request,_("Impossible de créer les matchs, des matchs existent déjà et sont en cours ou terminés."),messages.ERROR) - return - + self.message_user(request,_("Impossible de créer les matchs, des matchs existent déjà et sont en cours ou terminés."),messages.ERROR) + return + create_group_matchs(group) self.message_user(request,_("Matchs créés avec succes")) @@ -1024,6 +1023,7 @@ def create_empty_knockout_matchs_action(self,request,queryset): @admin.action(description=_("Remplir les matchs")) def fill_knockout_matchs_action(self,request,queryset): for bracket in queryset: + # TODO: Fix this # fill_knockout_matchs(bracket) pass @@ -1087,7 +1087,7 @@ class SwissRoundAdmin(admin.ModelAdmin): search_fields = ["tournament"] inlines = [SwissSeedingInline] actions = ["create_swiss_matchs_action"] - + list_filter = ["tournament","tournament__game","tournament__event"] @admin.action(description=_("Créer les matchs du système suisse")) @@ -1179,7 +1179,7 @@ def clean(self): raise ValidationError( _("Les places doivent être dans le même événement") ) - + # Ensure that all seats are not part of another slot if seats: other_slots = SeatSlot.objects.exclude(id=self.instance.id) @@ -1202,4 +1202,3 @@ def get_seats(self, obj): return ", ".join([f"({seat.x}, {seat.y})" for seat in obj.seats.all()]) admin.site.register(SeatSlot, SeatSlotAdmin) - diff --git a/insalan/tournament/models/bracket.py b/insalan/tournament/models/bracket.py index 7a48e92f..81accfdb 100644 --- a/insalan/tournament/models/bracket.py +++ b/insalan/tournament/models/bracket.py @@ -1,9 +1,10 @@ +import math +from typing import List + from django.db import models from django.utils.translation import gettext_lazy as _ from django.core.validators import MinValueValidator -import math -from typing import List from . import match, team @@ -100,4 +101,4 @@ class Meta: verbose_name_plural = _("Matchs d'arbre") def get_tournament(self): - return self.bracket.tournament \ No newline at end of file + return self.bracket.tournament diff --git a/insalan/tournament/models/caster.py b/insalan/tournament/models/caster.py index a0279983..cabd687a 100644 --- a/insalan/tournament/models/caster.py +++ b/insalan/tournament/models/caster.py @@ -32,4 +32,4 @@ class Caster(models.Model): verbose_name=_("Lien twitch ou autre"), blank=True, null=True, - ) \ No newline at end of file + ) diff --git a/insalan/tournament/models/event.py b/insalan/tournament/models/event.py index b1a8c218..1f4c30f7 100644 --- a/insalan/tournament/models/event.py +++ b/insalan/tournament/models/event.py @@ -78,4 +78,4 @@ def get_tournaments(self) -> List["Tournament"]: @staticmethod def get_ongoing_ids() -> List[int]: """Return the identifiers of ongoing events""" - return __class__.objects.filter(ongoing=True).values_list("id", flat=True) \ No newline at end of file + return __class__.objects.filter(ongoing=True).values_list("id", flat=True) diff --git a/insalan/tournament/models/game.py b/insalan/tournament/models/game.py index dad04e0a..7f3ddbd4 100644 --- a/insalan/tournament/models/game.py +++ b/insalan/tournament/models/game.py @@ -84,7 +84,7 @@ def get_substitute_players_per_team(self) -> int: def get_team_per_match(self) -> int: """Return the maximum number of teams in a match""" return self.team_per_match - + def get_name_validator(self): """Return the validators of the game""" - return get_validator(self.validators) \ No newline at end of file + return get_validator(self.validators) diff --git a/insalan/tournament/models/group.py b/insalan/tournament/models/group.py index 775ad9c7..20a94217 100644 --- a/insalan/tournament/models/group.py +++ b/insalan/tournament/models/group.py @@ -57,7 +57,7 @@ def get_teams_id(self) -> List[int]: def get_teams_seeding(self) -> List[Tuple["Team",int]]: return [(seeding.team,seeding.seeding) for seeding in Seeding.objects.filter(group=self)] - + def get_sorted_teams(self) -> List["Team"]: teams = self.get_teams_seeding() teams.sort(key=lambda e: e[1]) @@ -65,7 +65,7 @@ def get_sorted_teams(self) -> List["Team"]: def get_round_count(self) -> int: return self.round_count - + def get_leaderboard(self) -> Dict["Team",int]: leaderboard = {} @@ -78,7 +78,7 @@ def get_leaderboard(self) -> Dict["Team",int]: def get_scores(self) -> Dict[int,int]: leaderboard = self.get_leaderboard() - + return {team.id : score for team, score in leaderboard.items()} def get_matchs(self) -> List["GroupMatch"]: @@ -120,4 +120,4 @@ def get_tournament(self): # team = models.ForeignKey( # "Team", # on_delete=models.CASCADE -# ) \ No newline at end of file +# ) diff --git a/insalan/tournament/models/mailer.py b/insalan/tournament/models/mailer.py index c3c65696..13876c15 100644 --- a/insalan/tournament/models/mailer.py +++ b/insalan/tournament/models/mailer.py @@ -101,4 +101,4 @@ def save(self, *args, **kwargs): self.title, self.content, self.attachment, - ) \ No newline at end of file + ) diff --git a/insalan/tournament/models/manager.py b/insalan/tournament/models/manager.py index f6dc1bc6..afd7cd76 100644 --- a/insalan/tournament/models/manager.py +++ b/insalan/tournament/models/manager.py @@ -77,4 +77,4 @@ def clean(self): if not validators.tournament_announced(self.team.get_tournament()): raise ValidationError( _("Tournoi non annoncé") - ) \ No newline at end of file + ) diff --git a/insalan/tournament/models/match.py b/insalan/tournament/models/match.py index b48a4023..fd37b896 100644 --- a/insalan/tournament/models/match.py +++ b/insalan/tournament/models/match.py @@ -62,7 +62,7 @@ class Meta: models.Index(fields=["round_number"]), models.Index(fields=["index_in_round"]), ] - + def get_team_count(self) -> int: return len(self.get_teams()) @@ -89,7 +89,7 @@ def get_winning_score(self) -> int: """Minimum score for a team to be considered a winner""" if self.bo_type == BestofType.RANKING: return math.ceil(self.get_team_count()/2) - + return math.ceil(self.get_total_max_score()/2) def is_user_in_match(self, user: User) -> bool: @@ -98,7 +98,7 @@ def is_user_in_match(self, user: User) -> bool: for player in team.get_players(): if player.as_user() == user: return True - + return False def get_scores(self) -> Dict[int,int]: @@ -120,7 +120,7 @@ def get_winners_loosers(self) -> List[List[int]]: for team in self.get_teams_id(): if self.bo_type == BestofType.RANKING and scores[team] <= self.get_winning_score(): - winners.append((team,scores[team])) + winners.append((team,scores[team])) elif self.bo_type != BestofType.RANKING and scores[team] >= self.get_winning_score(): winners.append((team,scores[team])) else: @@ -163,4 +163,4 @@ def clean(self): if self.score > self.match.get_max_score(): raise ValidationError({ "score" :_(f"Le score est trop grand, il doit être inférieur ou égale à {self.match.get_max_score()}") - }) \ No newline at end of file + }) diff --git a/insalan/tournament/models/name_validator.py b/insalan/tournament/models/name_validator.py index 4a81f0e3..2a64e8ea 100644 --- a/insalan/tournament/models/name_validator.py +++ b/insalan/tournament/models/name_validator.py @@ -3,9 +3,11 @@ """ from django.utils.translation import gettext_lazy as _ from django.db import models -from insalan.settings import RIOT_API_KEY + import requests +from insalan.settings import RIOT_API_KEY + class EmptyNameValidator: """ NameValidator class diff --git a/insalan/tournament/models/payement_status.py b/insalan/tournament/models/payement_status.py index 6ea31fd8..12cc426c 100644 --- a/insalan/tournament/models/payement_status.py +++ b/insalan/tournament/models/payement_status.py @@ -6,4 +6,4 @@ class PaymentStatus(models.TextChoices): NOT_PAID = "NOTPAID", _("Pas payé") PAID = "PAID", _("Payé") - PAY_LATER = "LATER", _("Payera sur place") \ No newline at end of file + PAY_LATER = "LATER", _("Payera sur place") diff --git a/insalan/tournament/models/player.py b/insalan/tournament/models/player.py index 90459d43..05ffc734 100644 --- a/insalan/tournament/models/player.py +++ b/insalan/tournament/models/player.py @@ -114,4 +114,4 @@ def delete(self,*args,**kwargs): if self.team.captain == self: self.team.captain = None super().delete(*args,**kwargs) - self.team.refresh_validation() \ No newline at end of file + self.team.refresh_validation() diff --git a/insalan/tournament/models/seat_slot.py b/insalan/tournament/models/seat_slot.py index 3e214d33..fabb53b2 100644 --- a/insalan/tournament/models/seat_slot.py +++ b/insalan/tournament/models/seat_slot.py @@ -25,4 +25,3 @@ class Meta: verbose_name = _("Slot") verbose_name_plural = _("Slots") - diff --git a/insalan/tournament/models/swiss.py b/insalan/tournament/models/swiss.py index d65a255b..d151befe 100644 --- a/insalan/tournament/models/swiss.py +++ b/insalan/tournament/models/swiss.py @@ -5,67 +5,67 @@ from . import match class SwissRound(models.Model): - tournament = models.ForeignKey( - "Tournament", - verbose_name=_("Tournoi"), - on_delete=models.CASCADE - ) - min_score = models.IntegerField( - verbose_name=_("Score minimal pour la qualification") - ) + tournament = models.ForeignKey( + "Tournament", + verbose_name=_("Tournoi"), + on_delete=models.CASCADE + ) + min_score = models.IntegerField( + verbose_name=_("Score minimal pour la qualification") + ) - class Meta: - verbose_name = _("Ronde Suisse") - indexes = [ - models.Index(fields=["tournament"]) - ] - - def __str__(self) -> str: - return "Ronde Suisse" + f"({self.tournament})" + class Meta: + verbose_name = _("Ronde Suisse") + indexes = [ + models.Index(fields=["tournament"]) + ] - def get_teams(self) -> List["Team"]: - return SwissSeeding.objects.filter(swiss=self).values_list("team", flat=True) + def __str__(self) -> str: + return "Ronde Suisse" + f"({self.tournament})" - def get_teams_id(self) -> List[int]: - return self.get_teams().values_list("id", flat=True) + def get_teams(self) -> List["Team"]: + return SwissSeeding.objects.filter(swiss=self).values_list("team", flat=True) - def get_teams_seeding(self) -> List[Tuple["Team",int]]: - return [(seeding.team,seeding.seeding) for seeding in SwissSeeding.objects.filter(swiss=self)] + def get_teams_id(self) -> List[int]: + return self.get_teams().values_list("id", flat=True) - def get_sorted_teams(self) -> List[Tuple["Team",int]]: - teams = self.get_teams_seeding() - if any([team[1] == None for team in teams]): - return [team[0] for team in teams] + def get_teams_seeding(self) -> List[Tuple["Team",int]]: + return [(seeding.team,seeding.seeding) for seeding in SwissSeeding.objects.filter(swiss=self)] - teams.sort(key=lambda e: e[1]) - return [team[0] for team in teams] + def get_sorted_teams(self) -> List[Tuple["Team",int]]: + teams = self.get_teams_seeding() + if any([team[1] is None for team in teams]): + return [team[0] for team in teams] - def get_matchs(self) -> List["SwissMatch"]: - return SwissMatch.objects.filter(swiss=self) + teams.sort(key=lambda e: e[1]) + return [team[0] for team in teams] + + def get_matchs(self) -> List["SwissMatch"]: + return SwissMatch.objects.filter(swiss=self) class SwissSeeding(models.Model): - swiss = models.ForeignKey( - SwissRound, - on_delete=models.CASCADE - ) - team = models.OneToOneField( - "Team", - on_delete=models.CASCADE - ) - seeding = models.IntegerField( - null=True, - blank=True - ) + swiss = models.ForeignKey( + SwissRound, + on_delete=models.CASCADE + ) + team = models.OneToOneField( + "Team", + on_delete=models.CASCADE + ) + seeding = models.IntegerField( + null=True, + blank=True + ) class SwissMatch(match.Match): - swiss = models.ForeignKey( - SwissRound, - on_delete=models.CASCADE - ) + swiss = models.ForeignKey( + SwissRound, + on_delete=models.CASCADE + ) - class Meta: - verbose_name = _("Match de ronde suisse") - verbose_name_plural = _("Matchs de ronde suisse") + class Meta: + verbose_name = _("Match de ronde suisse") + verbose_name_plural = _("Matchs de ronde suisse") - def get_tournament(self): - return self.swiss.tournament + def get_tournament(self): + return self.swiss.tournament diff --git a/insalan/tournament/models/team.py b/insalan/tournament/models/team.py index 7955a4b1..5f9aef1a 100644 --- a/insalan/tournament/models/team.py +++ b/insalan/tournament/models/team.py @@ -6,14 +6,10 @@ from django.utils.translation import gettext_lazy as _ -from insalan.tickets.models import Ticket -from insalan.user.models import User - from . import player from . import manager from . import substitute from . import group, bracket, swiss -from . import seat_slot from . import validators from . import payement_status as ps diff --git a/insalan/tournament/models/tournament.py b/insalan/tournament/models/tournament.py index 871f49ef..4b8e9d94 100644 --- a/insalan/tournament/models/tournament.py +++ b/insalan/tournament/models/tournament.py @@ -11,8 +11,8 @@ from django.utils.translation import gettext_lazy as _ from django.contrib.postgres.fields import ArrayField -from . import team, caster, group, bracket, swiss from insalan.components.image_field import ImageField +from . import team, caster, group, bracket, swiss def in_thirty_days(): """Return now + 30 days""" @@ -297,7 +297,7 @@ def get_brackets(self) -> List["Bracket"]: def get_brackets_id(self) -> List[int]: return bracket.Bracket.objects.filter(tournament=self).values_list("id",flat=True) - + def get_swissRounds(self) -> List["SwissRound"]: return swiss.SwissRound.objects.filter(tournament=self) diff --git a/insalan/tournament/models/validators.py b/insalan/tournament/models/validators.py index 5db72040..05705f0c 100644 --- a/insalan/tournament/models/validators.py +++ b/insalan/tournament/models/validators.py @@ -25,13 +25,13 @@ def player_manager_user_unique_validator(user: User): tournament """ p_regs = { - (obj.user, obj.team.tournament) for obj in player.Player.objects.filter(user=user) + (obj.user, obj.team.tournament) for obj in play.Player.objects.filter(user=user) } m_regs = { - (obj.user, obj.team.tournament) for obj in manager.Manager.objects.filter(user=user) + (obj.user, obj.team.tournament) for obj in manage.Manager.objects.filter(user=user) } s_regs = { - (obj.user, obj.team.tournament) for obj in substitute.Substitute.objects.filter(user=user) + (obj.user, obj.team.tournament) for obj in sub.Substitute.objects.filter(user=user) } if len(m_regs.intersection(p_regs)) > 0 or len(s_regs.intersection(p_regs)) > 0 or len(s_regs.intersection(m_regs)) > 0: raise ValidationError( diff --git a/insalan/tournament/serializers.py b/insalan/tournament/serializers.py index a2fc7f8b..1c639ea7 100644 --- a/insalan/tournament/serializers.py +++ b/insalan/tournament/serializers.py @@ -422,7 +422,7 @@ class Meta: def to_representation(self, instance): """Turn a Django object into a serialized representation""" return instance.id - + class SeatSlotSerializer(serializers.ModelSerializer): """Serializer for a SeatSlot""" diff --git a/insalan/tournament/tests.py b/insalan/tournament/tests.py index 1efb0ee9..3e0a18b2 100644 --- a/insalan/tournament/tests.py +++ b/insalan/tournament/tests.py @@ -2,11 +2,9 @@ from decimal import Decimal from io import BytesIO -from types import NoneType from django.db.utils import IntegrityError -from django.contrib.auth.models import Permission -from django.contrib.auth.hashers import make_password, check_password +from django.contrib.auth.hashers import make_password from django.core.exceptions import ValidationError from django.core.files.uploadedfile import SimpleUploadedFile from django.test import TestCase, TransactionTestCase diff --git a/insalan/tournament/views/bracket.py b/insalan/tournament/views/bracket.py index 5649c1a7..6dfc643f 100644 --- a/insalan/tournament/views/bracket.py +++ b/insalan/tournament/views/bracket.py @@ -76,14 +76,14 @@ def patch(self, request, *args, **kwargs): try: match = KnockoutMatch.objects.get(pk=kwargs["match_id"],bracket=kwargs["bracket_id"]) - except: - raise NotFound() + except KnockoutMatch.DoesNotExist as e: + raise NotFound() from e if not match.is_user_in_match(user): raise PermissionDenied() error_response = validate_match_data(match, data) - if error_response != None: + if error_response is not None: return Response({k: _(v) for k,v in error_response.items()},status=status.HTTP_400_BAD_REQUEST) update_match_score(match,data) @@ -93,4 +93,7 @@ def patch(self, request, *args, **kwargs): serializer = serializers.KnockoutMatchSerializer(match, context={"request": request}) - return Response(status=status.HTTP_200_OK) \ No newline at end of file + return Response( + status=status.HTTP_200_OK, + data=serializer.data + ) diff --git a/insalan/tournament/views/event.py b/insalan/tournament/views/event.py index e7d6fb29..1e1cc8d4 100644 --- a/insalan/tournament/views/event.py +++ b/insalan/tournament/views/event.py @@ -53,7 +53,7 @@ class EventDetails(generics.RetrieveUpdateDestroyAPIView): serializer_class = serializers.EventSerializer queryset = Event.objects.all().order_by("id") permission_classes = [permissions.IsAdminUser | ReadOnly] - + @swagger_auto_schema( request_body=serializers.EventSerializer, responses={ @@ -90,7 +90,7 @@ class EventDetails(generics.RetrieveUpdateDestroyAPIView): def put(self, request, *args, **kwargs): """Update an event""" return super().put(request, *args, **kwargs) - + @swagger_auto_schema( responses={ 204: openapi.Schema( @@ -125,7 +125,7 @@ def put(self, request, *args, **kwargs): def delete(self, request, *args, **kwargs): """Delete an event""" return super().delete(request, *args, **kwargs) - + @swagger_auto_schema( responses={ 200: serializer_class, @@ -251,4 +251,4 @@ class EventByYear(generics.ListAPIView): def get_queryset(self): """Return the queryset""" - return Event.objects.filter(year=int(self.kwargs["year"])) \ No newline at end of file + return Event.objects.filter(year=int(self.kwargs["year"])) diff --git a/insalan/tournament/views/game.py b/insalan/tournament/views/game.py index 29a8e4e1..f6ac7822 100644 --- a/insalan/tournament/views/game.py +++ b/insalan/tournament/views/game.py @@ -123,7 +123,7 @@ def put(self, request, *args, **kwargs): def delete(self, request, *args, **kwargs): """Delete a game""" return super().delete(request, *args, **kwargs) - + @swagger_auto_schema( request_body=openapi.Schema( type=openapi.TYPE_OBJECT, @@ -177,4 +177,4 @@ def patch(self, request, *args, **kwargs): """ Partially update a game """ - return super().patch(request, *args, **kwargs) \ No newline at end of file + return super().patch(request, *args, **kwargs) diff --git a/insalan/tournament/views/group.py b/insalan/tournament/views/group.py index 4934a680..70863f0e 100644 --- a/insalan/tournament/views/group.py +++ b/insalan/tournament/views/group.py @@ -5,14 +5,14 @@ from rest_framework.response import Response from rest_framework.exceptions import NotFound +from drf_yasg.utils import swagger_auto_schema +from drf_yasg import openapi + import insalan.tournament.serializers as serializers from ..models import GroupMatch, validate_match_data from ..manage import update_match_score -from drf_yasg.utils import swagger_auto_schema -from drf_yasg import openapi - class GroupMatchScore(generics.GenericAPIView): """Update score of a group match""" @@ -75,18 +75,21 @@ def patch(self, request, *args, **kwargs): try: match = GroupMatch.objects.get(pk=kwargs["match_id"],group=kwargs["group_id"]) - except: - raise NotFound() + except GroupMatch.DoesNotExist as e: + raise NotFound() from e if not match.is_user_in_match(user): raise PermissionDenied() error_response = validate_match_data(match, data) - if error_response != None: + if error_response is not None: return Response({k: _(v) for k,v in error_response.items()},status=status.HTTP_400_BAD_REQUEST) update_match_score(match,data) serializer = serializers.GroupMatchSerializer(match, context={"request": request}) - return Response(status=status.HTTP_200_OK) \ No newline at end of file + return Response( + status=status.HTTP_200_OK, + data=serializer.data + ) diff --git a/insalan/tournament/views/manager.py b/insalan/tournament/views/manager.py index 07a09696..d12675f8 100644 --- a/insalan/tournament/views/manager.py +++ b/insalan/tournament/views/manager.py @@ -185,7 +185,7 @@ class ManagerRegistrationListId(generics.ListAPIView): def get_queryset(self): """Obtain the queryset fot this view""" return Manager.objects.filter(user_id=self.kwargs["user_id"]) - + @swagger_auto_schema( responses={ 200: openapi.Schema( @@ -235,7 +235,7 @@ def get_queryset(self): except User.DoesNotExist as exc: raise NotFound() from exc return Manager.objects.filter(user=user) - + @swagger_auto_schema( responses={ 200: openapi.Schema( @@ -268,4 +268,4 @@ def get(self, request, *args, **kwargs): """ Get all manager registrations of a user from their username """ - return super().get(request, *args, **kwargs) \ No newline at end of file + return super().get(request, *args, **kwargs) diff --git a/insalan/tournament/views/permissions.py b/insalan/tournament/views/permissions.py index 42e6d25b..f2db97c7 100644 --- a/insalan/tournament/views/permissions.py +++ b/insalan/tournament/views/permissions.py @@ -12,4 +12,4 @@ class Patch(BasePermission): def has_permission(self, request, _view): """Define the permissions for this class""" - return request.method == "PATCH" \ No newline at end of file + return request.method == "PATCH" diff --git a/insalan/tournament/views/player.py b/insalan/tournament/views/player.py index 5a69284d..9e93d867 100644 --- a/insalan/tournament/views/player.py +++ b/insalan/tournament/views/player.py @@ -107,7 +107,7 @@ def patch(self, request, *args, **kwargs): }, status=status.HTTP_403_FORBIDDEN) if "name_in_game" in data: - if(valid_name(player.team.tournament.game, data["name_in_game"])): + if valid_name(player.team.tournament.game, data["name_in_game"]): player.name_in_game = data["name_in_game"] else: return Response( @@ -122,7 +122,7 @@ def patch(self, request, *args, **kwargs): {"player": str(exc)}, status=status.HTTP_400_BAD_REQUEST ) - + serializer = serializers.PlayerSerializer(player, context={"request": request}) return Response(serializer.data, status=status.HTTP_200_OK) @@ -294,4 +294,4 @@ def get_queryset(self): user = User.objects.get(username=self.kwargs["username"]) except User.DoesNotExist as exc: raise NotFound() from exc - return Player.objects.filter(user=user) \ No newline at end of file + return Player.objects.filter(user=user) diff --git a/insalan/tournament/views/substitute.py b/insalan/tournament/views/substitute.py index b7053390..a0f29d28 100644 --- a/insalan/tournament/views/substitute.py +++ b/insalan/tournament/views/substitute.py @@ -50,7 +50,7 @@ def get(self, request, *args, **kwargs): Get a substitute """ return super().get(request, *args, **kwargs) - + @swagger_auto_schema( responses={ 200: serializer_class, @@ -304,4 +304,4 @@ def get_queryset(self): user = User.objects.get(username=self.kwargs["username"]) except User.DoesNotExist as exc: raise NotFound() from exc - return Substitute.objects.filter(user=user) \ No newline at end of file + return Substitute.objects.filter(user=user) diff --git a/insalan/tournament/views/swiss.py b/insalan/tournament/views/swiss.py index 2fc90c06..3414a7cf 100644 --- a/insalan/tournament/views/swiss.py +++ b/insalan/tournament/views/swiss.py @@ -71,18 +71,21 @@ def patch(self, request, *args, **kwargs): try: match = SwissMatch.objects.get(pk=kwargs["match_id"],swiss=kwargs["swiss_id"]) - except: - raise NotFound() + except SwissMatch.DoesNotExist as e: + raise NotFound() from e if not match.is_user_in_match(user): raise PermissionDenied() error_response = validate_match_data(match, data) - if error_response != None: + if error_response is not None: return Response({k: _(v) for k,v in error_response.items()},status=status.HTTP_400_BAD_REQUEST) update_match_score(match,data) serializer = serializers.SwissMatchSerializer(match, context={"request": request}) - return Response(status=status.HTTP_200_OK) \ No newline at end of file + return Response( + status=status.HTTP_200_OK, + data=serializer.data + ) diff --git a/insalan/tournament/views/team.py b/insalan/tournament/views/team.py index 22a4c752..bfb3bc33 100644 --- a/insalan/tournament/views/team.py +++ b/insalan/tournament/views/team.py @@ -3,6 +3,7 @@ from django.contrib.auth.hashers import make_password from rest_framework import generics, permissions, status +from rest_framework.exceptions import NotFound from rest_framework.response import Response from drf_yasg.utils import swagger_auto_schema @@ -118,8 +119,8 @@ def patch(self, request, *args, **kwargs): # get the team try: team = Team.objects.get(id=kwargs["pk"]) - except Team.DoesNotExist: - raise NotFound() + except Team.DoesNotExist as exc: + raise NotFound() from exc # check if the user is registered in the team player = Player.objects.filter(user=user, team=team) @@ -206,7 +207,6 @@ def patch(self, request, *args, **kwargs): return Response({ "seat_slot": _("Slot inadapté au tournoi.") }, status=status.HTTP_400_BAD_REQUEST) - team.seat_slot = seat_slot diff --git a/insalan/tournament/views/tournament.py b/insalan/tournament/views/tournament.py index fb3d858d..9658e009 100644 --- a/insalan/tournament/views/tournament.py +++ b/insalan/tournament/views/tournament.py @@ -1,6 +1,5 @@ import math -from django.core.exceptions import PermissionDenied, BadRequest -from django.http import Http404 +from django.core.exceptions import PermissionDenied from django.utils.translation import gettext_lazy as _ from rest_framework import generics, permissions, status @@ -10,18 +9,18 @@ from drf_yasg.utils import swagger_auto_schema from drf_yasg import openapi +from rest_framework.exceptions import NotFound + from insalan.tickets.models import Ticket from insalan.user.models import User import insalan.tournament.serializers as serializers from ..models import (Player, Manager, Substitute, Event, Tournament, Game, - Team, PaymentStatus, Group, Bracket, SwissRound, + Team, Group, Bracket, SwissRound, GroupMatch, KnockoutMatch, SwissMatch, Seeding, Score, - BracketType, BracketSet, MatchStatus, BestofType, + BracketType, BracketSet, MatchStatus, SwissSeeding, SeatSlot, Seat) -from .permissions import ReadOnly, Patch - -from rest_framework.exceptions import NotFound +from .permissions import ReadOnly class TournamentList(generics.ListCreateAPIView): """List all known tournaments""" @@ -83,7 +82,7 @@ class TournamentDetails(generics.RetrieveUpdateDestroyAPIView): def get(self, request, *args, **kwargs): """Get a tournament""" return super().get(request, *args, **kwargs) - + @swagger_auto_schema( responses={ 200: serializer_class, @@ -119,7 +118,7 @@ def get(self, request, *args, **kwargs): def patch(self, request, *args, **kwargs): """Patch a tournament""" return super().patch(request, *args, **kwargs) - + @swagger_auto_schema( responses={ 204: openapi.Schema( @@ -154,7 +153,7 @@ def patch(self, request, *args, **kwargs): def delete(self, request, *args, **kwargs): """Delete a tournament""" return super().delete(request, *args, **kwargs) - + @swagger_auto_schema( responses={ 200: serializer_class, @@ -217,10 +216,10 @@ def get(self, request, primary_key: int): ).data del tourney_serialized["event"]["tournaments"] - + # Add the seats tourney_serialized["event"]["seats"] = [] - + seats = Seat.objects.filter(event=tourney_serialized["event"]["id"]) for seat in seats: # Only add X and Y coord @@ -289,7 +288,7 @@ def get(self, request, primary_key: int): if not can_see_payment_status: substitute["payment_status"] = None del substitute["id"] - + # Add seat_slot id or null team_slot = SeatSlot.objects.filter(team=team["id"]) if team_slot.exists(): @@ -304,7 +303,7 @@ def get(self, request, primary_key: int): for group in tourney_serialized["groups"]: group["teams"] = Seeding.objects.filter(group=group["id"]).values_list("team", flat=True) - + matches = GroupMatch.objects.filter(group=group["id"]) group["matchs"] = serializers.FullDerefGroupMatchSerializer( matches, context={"request": request}, many=True @@ -318,7 +317,7 @@ def get(self, request, primary_key: int): group["scores"] = {team: sum(match["score"][team] for match in group["matchs"] if team in match["score"]) for team in group["teams"]} # order teams by score - group["teams"] = sorted(group["teams"], key=lambda x: group["scores"][x], reverse=True) + group["teams"] = sorted(group["teams"], key=lambda x, scores=group["scores"]: scores[x], reverse=True) # deref bracket matchs and scores tourney_serialized["brackets"] = serializers.FullDerefBracketSerializer( @@ -342,6 +341,7 @@ def get(self, request, primary_key: int): bracket["teams"] = set(matches.values_list("teams", flat=True).filter(teams__isnull=False)) bracket["winner"] = None + final = [] if bracket["bracket_type"] == BracketType.SINGLE: final = KnockoutMatch.objects.filter(round_number=1,index_in_round=1,bracket=bracket["id"],bracket_set=BracketSet.WINNER,status=MatchStatus.COMPLETED) @@ -543,17 +543,17 @@ def get(self, request, *args, **kwargs): ongoing_matchs += player.get_ongoing_match() if len(ongoing_matchs) > 0: - if type(ongoing_matchs[0]) == GroupMatch: + if isinstance(ongoing_matchs[0], GroupMatch): ongoing_match = serializers.GroupMatchSerializer(ongoing_matchs[0],context={"request": request}).data ongoing_match["match_type"] = {"type": "group", "id": ongoing_match["group"]} del ongoing_match["group"] - if type(ongoing_matchs[0]) == KnockoutMatch: + if isinstance(ongoing_matchs[0], KnockoutMatch): ongoing_match = serializers.KnockoutMatchSerializer(ongoing_matchs[0],context={"request": request}).data ongoing_match["match_type"] = {"type": "bracket", "id": ongoing_match["bracket"]} del ongoing_match["bracket"] - if type(ongoing_matchs[0]) == SwissMatch: + if isinstance(ongoing_matchs[0], SwissMatch): ongoing_match = serializers.SwissMatchSerializer(ongoing_matchs[0],context={"request": request}).data ongoing_match["match_type"] = {"type": "swiss", "id": ongoing_match["swiss"]} del ongoing_match["swiss"] diff --git a/insalan/user/admin.py b/insalan/user/admin.py index 871f2623..858a40e5 100644 --- a/insalan/user/admin.py +++ b/insalan/user/admin.py @@ -16,9 +16,9 @@ from django.utils.decorators import method_decorator from insalan.tournament.models import Player, Manager, Substitute -from .models import User from insalan.mailer import MailManager from insalan.settings import EMAIL_AUTH +from .models import User sensitive_post_parameters_m = method_decorator(sensitive_post_parameters()) @@ -144,11 +144,11 @@ def get_urls(self): ] + super().get_urls() @sensitive_post_parameters_m - def resend_email(self, request, id, form_url=""): + def resend_email(self, request, user_id, form_url=""): """ Resend the email to the user """ - user = User.objects.get(pk=id) + user = User.objects.get(pk=user_id) if not self.has_change_permission(request, user): raise PermissionDenied if user is None: @@ -156,7 +156,7 @@ def resend_email(self, request, id, form_url=""): _("%(name)s object with primary key %(key)r does not exist.") % { "name": self.opts.verbose_name, - "key": escape(id), + "key": escape(user_id), } ) if user.has_perm("email_active"): diff --git a/insalan/user/serializers.py b/insalan/user/serializers.py index 1ccc8448..5d256102 100644 --- a/insalan/user/serializers.py +++ b/insalan/user/serializers.py @@ -10,10 +10,10 @@ from rest_framework import serializers from rest_framework.validators import UniqueValidator -from .models import User from insalan.mailer import MailManager from insalan.settings import EMAIL_AUTH +from .models import User class UserSerializer(serializers.ModelSerializer): """Serializer for an User""" diff --git a/insalan/user/views.py b/insalan/user/views.py index 6e670b54..318d4f02 100644 --- a/insalan/user/views.py +++ b/insalan/user/views.py @@ -1,24 +1,22 @@ """User module API Endpoints""" -import sys - from datetime import datetime from django.contrib.auth import login, logout from django.contrib.auth.models import Group, Permission from django.contrib.auth.tokens import default_token_generator from django.contrib.auth.password_validation import validate_password -from django.core.exceptions import PermissionDenied, BadRequest +from django.core.exceptions import PermissionDenied from django.http import JsonResponse from django.utils.translation import gettext_lazy as _ from django.utils import timezone from django.views.decorators.csrf import ensure_csrf_cookie from django.views.decorators.http import require_GET +from django.core.exceptions import ValidationError from rest_framework import generics, permissions, status from rest_framework.authentication import SessionAuthentication from rest_framework.response import Response from rest_framework.views import APIView -from django.core.exceptions import ValidationError from drf_yasg.utils import swagger_auto_schema from drf_yasg import openapi @@ -65,7 +63,7 @@ class UserMe(generics.RetrieveAPIView): permission_classes = [permissions.IsAuthenticated] serializer_class = UserSerializer - def get(self, request): + def get(self, request, *args, **kwargs): """ Returns an user's own informations """ @@ -217,10 +215,10 @@ def patch(self, request): if "display_name" in data: user.display_name = data["display_name"] - + if "pronouns" in data: user.pronouns = data["pronouns"] - + if "status" in data: user.status = data["status"]