202 lines
6.8 KiB
Python
202 lines
6.8 KiB
Python
import random
|
|
from datetime import datetime
|
|
|
|
from django.contrib.auth.mixins import LoginRequiredMixin
|
|
from django.contrib.auth.models import AnonymousUser
|
|
from django.core.exceptions import PermissionDenied
|
|
from django.db.models import Q
|
|
from django.http import FileResponse
|
|
from django.shortcuts import redirect
|
|
from django.urls import reverse_lazy
|
|
from django.utils.translation import gettext_lazy as _
|
|
from django.views import View
|
|
from django.views.generic import CreateView, UpdateView, DetailView, FormView
|
|
from django_tables2 import SingleTableView
|
|
|
|
from tournament.forms import TeamForm, JoinTeam
|
|
from tournament.models import Team
|
|
from tournament.views import AdminMixin, TeamMixin
|
|
from .forms import SignUpForm, TFJMUserForm, AdminUserForm, CoachUserForm
|
|
from .models import TFJMUser, Document, Solution, MotivationLetter, Synthesis
|
|
from .tables import UserTable
|
|
|
|
|
|
class CreateUserView(CreateView):
|
|
model = TFJMUser
|
|
form_class = SignUpForm
|
|
template_name = "registration/signup.html"
|
|
|
|
|
|
class MyAccountView(LoginRequiredMixin, UpdateView):
|
|
model = TFJMUser
|
|
template_name = "member/my_account.html"
|
|
|
|
def get_form_class(self):
|
|
return AdminUserForm if self.request.user.organizes else TFJMUserForm \
|
|
if self.request.user.role == "3participant" else CoachUserForm
|
|
|
|
def get_object(self, queryset=None):
|
|
return self.request.user
|
|
|
|
|
|
class UserDetailView(LoginRequiredMixin, DetailView):
|
|
model = TFJMUser
|
|
form_class = TFJMUserForm
|
|
context_object_name = "tfjmuser"
|
|
|
|
def dispatch(self, request, *args, **kwargs):
|
|
if isinstance(request.user, AnonymousUser):
|
|
raise PermissionDenied
|
|
|
|
self.object = self.get_object()
|
|
|
|
if not request.user.admin \
|
|
and (self.object.team is not None and request.user not in self.object.team.tournament.organizers.all())\
|
|
and self.request.user != self.object:
|
|
raise PermissionDenied
|
|
return super().dispatch(request, *args, **kwargs)
|
|
|
|
def post(self, request, *args, **kwargs):
|
|
if "view_as" in request.POST:
|
|
session = request.session
|
|
session["admin"] = request.user.pk
|
|
obj = self.get_object()
|
|
session["_fake_user_id"] = obj.pk
|
|
return redirect(request.path)
|
|
return self.get(request, *args, **kwargs)
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = super().get_context_data(**kwargs)
|
|
|
|
context["title"] = str(self.object)
|
|
|
|
return context
|
|
|
|
|
|
class AddTeamView(LoginRequiredMixin, CreateView):
|
|
model = Team
|
|
form_class = TeamForm
|
|
|
|
def form_valid(self, form):
|
|
if self.request.user.organizes:
|
|
form.add_error('name', _("You can't organize and participate at the same time."))
|
|
return self.form_invalid(form)
|
|
|
|
if self.request.user.team:
|
|
form.add_error('name', _("You are already in a team."))
|
|
return self.form_invalid(form)
|
|
|
|
team = form.instance
|
|
alphabet = "0123456789abcdefghijklmnopqrstuvwxyz0123456789"
|
|
code = ""
|
|
for i in range(6):
|
|
code += random.choice(alphabet)
|
|
team.access_code = code
|
|
team.validation_status = "0invalid"
|
|
|
|
team.save()
|
|
team.refresh_from_db()
|
|
|
|
self.request.user.team = team
|
|
self.request.user.save()
|
|
|
|
return super().form_valid(form)
|
|
|
|
def get_success_url(self):
|
|
return reverse_lazy("member:my_team")
|
|
|
|
|
|
class JoinTeamView(LoginRequiredMixin, FormView):
|
|
model = Team
|
|
form_class = JoinTeam
|
|
template_name = "tournament/team_form.html"
|
|
|
|
def form_valid(self, form):
|
|
team = form.cleaned_data["team"]
|
|
|
|
if self.request.user.organizes:
|
|
form.add_error('access_code', _("You can't organize and participate at the same time."))
|
|
return self.form_invalid(form)
|
|
|
|
if self.request.user.team:
|
|
form.add_error('access_code', _("You are already in a team."))
|
|
return self.form_invalid(form)
|
|
|
|
if self.request.user.role == '2coach' and team.encadrants.size() == 3:
|
|
form.add_error('access_code', _("This team is full of coachs."))
|
|
return self.form_invalid(form)
|
|
|
|
if self.request.user.role == '3participant' and team.participants.size() == 5:
|
|
form.add_error('access_code', _("This team is full of participants."))
|
|
return self.form_invalid(form)
|
|
|
|
self.request.user.team = team
|
|
self.request.user.save()
|
|
return super().form_valid(form)
|
|
|
|
def get_success_url(self):
|
|
return reverse_lazy("member:my_team")
|
|
|
|
|
|
class MyTeamView(TeamMixin, View):
|
|
def get(self, request, *args, **kwargs):
|
|
return redirect("tournament:team_detail", pk=request.user.team.pk)
|
|
|
|
|
|
class DocumentView(LoginRequiredMixin, View):
|
|
def get(self, request, *args, **kwargs):
|
|
doc = Document.objects.get(file=self.kwargs["file"])
|
|
|
|
grant = request.user.admin
|
|
|
|
if isinstance(doc, Solution) or isinstance(doc, Synthesis) or isinstance(doc, MotivationLetter):
|
|
grant = grant or doc.team == request.user.team or request.user in doc.team.tournament.organizers.all()
|
|
|
|
if isinstance(doc, Synthesis) and request.user.organizes:
|
|
grant = True
|
|
|
|
if isinstance(doc, Solution):
|
|
for pool in doc.pools.all():
|
|
if pool.round == 2 and datetime.now() < doc.tournament.date_solutions_2:
|
|
continue
|
|
if self.request.user.team in pool.teams.all():
|
|
grant = True
|
|
|
|
if not grant:
|
|
raise PermissionDenied
|
|
|
|
return FileResponse(doc.file, content_type="application/pdf")
|
|
|
|
|
|
class ProfileListView(AdminMixin, SingleTableView):
|
|
model = TFJMUser
|
|
queryset = TFJMUser.objects.order_by("role", "last_name", "first_name")
|
|
table_class = UserTable
|
|
template_name = "member/profile_list.html"
|
|
extra_context = dict(title=_("All profiles"))
|
|
|
|
|
|
class OrphanedProfileListView(AdminMixin, SingleTableView):
|
|
model = TFJMUser
|
|
queryset = TFJMUser.objects.filter((Q(role="2coach") | Q(role="3participant")) & Q(team__isnull=True))\
|
|
.order_by("role", "last_name", "first_name")
|
|
table_class = UserTable
|
|
template_name = "member/profile_list.html"
|
|
extra_context = dict(title=_("Orphaned profiles"))
|
|
|
|
|
|
class OrganizersListView(AdminMixin, SingleTableView):
|
|
model = TFJMUser
|
|
queryset = TFJMUser.objects.filter(Q(role="0admin") | Q(role="1volunteer"))\
|
|
.order_by("role", "last_name", "first_name")
|
|
table_class = UserTable
|
|
template_name = "member/profile_list.html"
|
|
extra_context = dict(title=_("Organizers"))
|
|
|
|
|
|
class ResetAdminView(AdminMixin, View):
|
|
def dispatch(self, request, *args, **kwargs):
|
|
if "_fake_user_id" in request.session:
|
|
del request.session["_fake_user_id"]
|
|
return redirect(request.GET["path"])
|