187 lines
6.1 KiB
Python
187 lines
6.1 KiB
Python
from django.forms import formset_factory
|
|
from django.shortcuts import render, redirect, get_object_or_404
|
|
from django.urls import reverse_lazy
|
|
from django.views.generic.edit import CreateView
|
|
from django.views.generic import TemplateView
|
|
from django.contrib.auth.decorators import login_required
|
|
from django.db import transaction
|
|
from functools import reduce
|
|
|
|
from .forms import CustomUserCreationForm, CustomUserChangeForm, StudentForm
|
|
from .models import Announcement, Edition, Student
|
|
|
|
|
|
class SignUpView(CreateView):
|
|
form_class = CustomUserCreationForm
|
|
success_url = reverse_lazy('login')
|
|
template_name = 'registration/signup.html'
|
|
|
|
|
|
@login_required
|
|
def UpdateAccountView(request):
|
|
if request.method == 'POST':
|
|
form = CustomUserChangeForm(request.POST, instance=request.user)
|
|
if form.is_valid():
|
|
form.save()
|
|
else:
|
|
form = CustomUserChangeForm(instance=request.user)
|
|
|
|
return render(request, 'user/account.html', {'account_page': 'is-active', 'account_tab': 'is-active', 'ongoing': Edition.current(), 'form': form})
|
|
|
|
|
|
@login_required
|
|
def SubmitStudentsView(request):
|
|
edition = Edition.current()
|
|
|
|
if edition is not None:
|
|
|
|
context = {
|
|
'account_page': 'is-active',
|
|
'submission_tab': 'is-active',
|
|
'ongoing': edition,
|
|
}
|
|
|
|
if edition.submissions is not True:
|
|
ranking = {}
|
|
for index, student in enumerate(sorted(Student.objects.filter(identifier__startswith=f'{edition.year}-'), key=lambda x: x.score_first*x.score_second, reverse=True)):
|
|
ranking[student.identifier] = index + 1
|
|
|
|
queryset = Student.objects.filter(
|
|
identifier__startswith=f'{edition.year}-{request.user.id}-').order_by('identifier')
|
|
|
|
students = [{**student.__dict__, 'ranking': ranking[student.identifier]} for student in queryset]
|
|
|
|
return render(request, 'user/submission.html', {'students': students, **context})
|
|
|
|
queryset = Student.objects.filter(identifier__startswith=f'{edition.year}-{request.user.id}-')
|
|
ArticleFormSet = formset_factory(StudentForm, extra=3, max_num=3, min_num=0)
|
|
|
|
if request.method == 'POST':
|
|
with transaction.atomic():
|
|
formset = ArticleFormSet(request.POST)
|
|
if formset.is_valid():
|
|
queryset.delete()
|
|
|
|
students = filter(lambda x: x != {}, formset.cleaned_data)
|
|
for index, data in enumerate(students):
|
|
Student.objects.update_or_create(
|
|
identifier=f'{edition.year}-{request.user.id}-{index + 1}', defaults=data)
|
|
else:
|
|
formset = ArticleFormSet(initial=list(map(lambda x: x.__dict__, queryset)))
|
|
|
|
return render(request, 'user/submit.html', {'formset': formset, 'students': len(queryset), **context})
|
|
else:
|
|
return redirect(reverse_lazy('account'))
|
|
|
|
|
|
class AboutContestView(TemplateView):
|
|
template_name = 'home.html'
|
|
extra_context = {
|
|
'aboutcontest_page': 'is-active'
|
|
}
|
|
|
|
|
|
class NewsView(TemplateView):
|
|
template_name = 'news.html'
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = super().get_context_data(**kwargs)
|
|
context['news_page'] = 'is-active'
|
|
context['announcements'] = Announcement.objects.all()
|
|
|
|
return context
|
|
|
|
|
|
class RulesView(TemplateView):
|
|
template_name = 'rules.html'
|
|
extra_context = {
|
|
'rules_page': 'is-active'
|
|
}
|
|
|
|
|
|
class TestsView(TemplateView):
|
|
template_name = 'tests.html'
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = super().get_context_data(**kwargs)
|
|
context['tests_page'] = 'is-active'
|
|
context['editions'] = Edition.objects.order_by('-year')
|
|
|
|
return context
|
|
|
|
|
|
def ScoresView(request, year=None):
|
|
if year is not None:
|
|
edition = get_object_or_404(Edition, year=year)
|
|
else:
|
|
edition = Edition.objects.filter(scores_available=True).order_by('-year').first()
|
|
|
|
if edition is None:
|
|
edition = Edition.objects.order_by('-year').first()
|
|
|
|
year = edition.year
|
|
|
|
context = {
|
|
'scores_page': 'is-active',
|
|
'year': year,
|
|
'scores_available': edition.scores_available or request.user.is_superuser,
|
|
'editions': Edition.objects.order_by('year')
|
|
}
|
|
|
|
students = Student.objects.filter(identifier__startswith=year)
|
|
|
|
schools = map(lambda x: {
|
|
'id': x.identifier.split('-')[1],
|
|
'name': x.school_name,
|
|
'town': x.school_town
|
|
}, students)
|
|
schools = list({school['id']: school for school in schools}.values())
|
|
|
|
individual = filter(lambda x: x['score'] >= edition.award_threshold,
|
|
map(lambda x: {
|
|
**x.__dict__,
|
|
'score': x.score_first * x.score_second,
|
|
'title': 'Laureat' if x.score_first * x.score_second >= edition.laureate_threshold else 'Wyróżnienie'
|
|
}, students.filter(score_first__gte=edition.entry_threshold)))
|
|
|
|
teams = []
|
|
for school in schools:
|
|
team = students.filter(identifier__startswith=f'{year}-' + school['id'] + '-')
|
|
|
|
score_first = reduce(lambda x, y: x + y.score_first, team, 0)
|
|
score_second = reduce(lambda x, y: x + y.score_second, team, 0)
|
|
|
|
if score_first*score_second > 0:
|
|
teams.append({**school, 'score': score_first * score_second})
|
|
|
|
context = {
|
|
'individual': sorted(individual, key=lambda x: -x['score']),
|
|
'teams': sorted(teams, key=lambda x: -x['score']),
|
|
**context
|
|
}
|
|
|
|
return render(request, 'scores.html', context)
|
|
|
|
|
|
class ContactView(TemplateView):
|
|
template_name = 'contact.html'
|
|
extra_context = {
|
|
'contact_page': 'is-active'
|
|
}
|
|
|
|
|
|
class RobotsView(TemplateView):
|
|
template_name = 'robots.txt'
|
|
content_type = 'text/plain'
|
|
|
|
|
|
class SitemapView(TemplateView):
|
|
template_name = 'sitemap.xml'
|
|
content_type = 'text/xml'
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = super().get_context_data(**kwargs)
|
|
context['latest'] = Announcement.objects.first()
|
|
|
|
return context
|