SOITA/trials/views.py
Hubert Jankowski 9867281dd8 Add tournaments
2022-05-25 00:06:44 +02:00

577 lines
20 KiB
Python

import pdb
import requests
from django.views.generic import TemplateView
from rest_framework import views, generics
from rest_framework import viewsets
from rest_framework.response import Response
from rest_framework.views import APIView
from questions.models import Question
from trials.models import Test, SolvedTest, Tournament
from trials.serializers import TestSerializer
from django.conf import settings
from django.shortcuts import render, redirect
from django import template
from django.http import HttpResponseRedirect, HttpResponse
from django.template import loader
from django.template.loader import render_to_string, get_template
from django.http import HttpRequest
import requests
from django.contrib.auth.decorators import login_required
@login_required
def addTest(request):
return render(request, 'createTest.html')
def is_visible(visible):
if visible =="public":
return True
else:
return False
def addQuestions(request, **kwargs):
if request.POST:
name = request.GET.get("name")
visible = is_visible(request.GET.get("visible"))
passing = request.GET.get("passing")
category = request.GET.get("category")
number_of_questions = request.GET.get("number_of_questions")
password = request.GET.get("password")
user = request.user
# k = dict(request.POST)["desc"]
questions = []
for i in range(0, int(number_of_questions)):
description = dict(request.POST)["desc"][i]
answer1 = {
"description": dict(request.POST)["ans1"][i],
"is_correct": False
}
answer2 = {
"description": dict(request.POST)["ans2"][i],
"is_correct": False
}
answer3 = {
"description": dict(request.POST)["ans3"][i],
"is_correct": False
}
answer4 = {
"description": dict(request.POST)["ans4"][i],
"is_correct": False
}
is_correct = dict(request.POST)["is_correct"][i]
if is_correct == "1":
answer1["is_correct"] = True
if is_correct == "2":
answer2["is_correct"] = True
if is_correct == "3":
answer3["is_correct"] = True
if is_correct == "4":
answer4["is_correct"] = True
questions.append({
"name": description,
"answers": [
answer1,
answer2,
answer3,
answer4
]
})
Test.objects.create(name=name, passing_score=passing, category=category, questions=questions, user=user,
visible=visible, password=password)
return redirect('home')
return render(request, 'addQuestions.html')
def TournamentView(request):
context = {}
context['tournaments'] = Tournament.objects.all()
return render(request, 'tournaments.html', context)
def CreateTournamentView(request, **kwargs):
if request.POST:
question_ids = []
dictt = dict(request.POST)
pyk = dictt.pop("name")
pyk2 = dictt.pop("passing_score")
name = request.POST.get("name")
passing_score = request.POST.get("passing_score")
for k, v in dictt.items():
question_ids.append(k)
Tournament.objects.create(name=name, questions=question_ids, passing_score=passing_score)
return render(request, 'home.html')
context = {}
context['questions'] = Question.objects.all()
return render(request, 'createTournament.html', context)
class AddQuestionToExistingTest(TemplateView):
template_name = settings.BASE_DIR + f"/templates/addQuestionToExistingTest.html"
def post(self, request, *args, **kwargs):
answers = []
answer1 = {
"description": dict(request.POST)["ans1"][0],
"is_correct": False
}
answer2 = {
"description": dict(request.POST)["ans2"][0],
"is_correct": False
}
answer3 = {
"description": dict(request.POST)["ans3"][0],
"is_correct": False
}
answer4 = {
"description": dict(request.POST)["ans4"][0],
"is_correct": False
}
is_correct = dict(request.POST)["is_correct"][0]
if is_correct == "1":
answer1["is_correct"] = True
if is_correct == "2":
answer2["is_correct"] = True
if is_correct == "3":
answer3["is_correct"] = True
if is_correct == "4":
answer4["is_correct"] = True
answers.append({
"answers": [
answer1,
answer2,
answer3,
answer4
]
})
description = dict(request.POST)["desc"][0]
Question.objects.addQuestionToExistingTest(name=description, answers=answers,
test=Test.objects.get(id=kwargs["test_id"]))
return redirect(f'/tests/{kwargs["test_id"]}/edit')
class RemoveQuestionFromExistingTest(TemplateView):
template_name = settings.BASE_DIR + f"/templates/removeQuestionFromExistingTest.html"
def get_queryset(self):
return Test.objects.all()
def get_context_data(self, test_id, **kwargs):
self.test_id = test_id
context = super().get_context_data(**kwargs)
context["test"] = self.get_queryset().filter(id=test_id).prefetch_related("questions__answers").first()
return context
def post(self, request, *args, **kwargs):
Question.objects.get(id=request.POST["id"]).delete()
return redirect(f'/tests/{kwargs["test_id"]}/edit')
@login_required
def myTests(request):
context = {}
user = request.user.id
context['tests'] = Test.objects.filter(created_by=user)
return render(request, 'myTests.html', context)
@login_required
def solvedTests(request):
context = {}
user_id = request.user.id
solved_tests = SolvedTest.objects.filter(user__id=user_id)
dict_with_lists_of_test_results = {}
for solved_test in solved_tests:
if solved_test.test.name_and_passing_score()["name"] in dict_with_lists_of_test_results.keys():
dict_with_lists_of_test_results[solved_test.test.name_and_passing_score()["name"]].insert(0, {
"name": solved_test.test.name_and_passing_score()["name"],
"passing_score": solved_test.test.name_and_passing_score()["passing_score"],
"score": solved_test.score,
"max": solved_test.max,
"percentage": solved_test.percentage,
"id": solved_test.test.id
})
else:
dict_with_lists_of_test_results[solved_test.test.name_and_passing_score()["name"]] = []
dict_with_lists_of_test_results[solved_test.test.name_and_passing_score()["name"]].append({
"name": solved_test.test.name_and_passing_score()["name"],
"passing_score": solved_test.test.name_and_passing_score()["passing_score"],
"score": solved_test.score,
"max": solved_test.max,
"percentage": solved_test.percentage,
"id": solved_test.test.id
})
context['tests_lists'] = dict_with_lists_of_test_results
return render(request, 'solvedTests.html', context)
@login_required
def solvedTestsDetailed(request, test_id):
context = {}
solved_tests = SolvedTest.objects.filter(test__id=test_id)
formatted_tests = list()
for solved_test in solved_tests:
formatted_tests.append({
"passing_score": solved_test.test.name_and_passing_score()["passing_score"],
"score": solved_test.score,
"max": solved_test.max,
"percentage": solved_test.percentage,
"id": solved_test.test.id
})
context['name'] = solved_tests[0].test.name_and_passing_score()["name"]
context['tests'] = formatted_tests
return render(request, 'solvedTestsDetailed.html', context)
class EditTestTemplateView(TemplateView):
template_name = settings.BASE_DIR + f"/templates/editTest.html"
def get_queryset(self):
return Test.objects.all()
def get_context_data(self, test_id, **kwargs):
self.test_id = test_id
context = super().get_context_data(**kwargs)
context["test"] = self.get_queryset().filter(id=test_id).prefetch_related("questions__answers").first()
if context["test"].created_by.email != self.request.user.email:
return render(context, "canNotEditTest.html")
return context
def post(self, request, *args, **kwargs):
return redirect(f'/tests/question/{request.POST["id"]}/edit?test_id={kwargs["test_id"]}')
class EditQuestionTemplateView(TemplateView):
template_name = settings.BASE_DIR + f"/templates/editQuestion.html"
def get_queryset(self):
return Question.objects.all()
def get_context_data(self, question_id, **kwargs):
context = super().get_context_data(**kwargs)
context["question"] = self.get_queryset().filter(id=question_id).prefetch_related("answers").first()
return context
def post(self, request, *args, **kwargs):
question_id = kwargs["question_id"]
test = request.GET.get("test_id")
answers = []
answer1 = {
"description": dict(request.POST)["ans1"][0],
"is_correct": False
}
answer2 = {
"description": dict(request.POST)["ans2"][0],
"is_correct": False
}
answer3 = {
"description": dict(request.POST)["ans3"][0],
"is_correct": False
}
answer4 = {
"description": dict(request.POST)["ans4"][0],
"is_correct": False
}
is_correct = dict(request.POST)["is_correct"][0]
if is_correct == "1":
answer1["is_correct"] = True
if is_correct == "2":
answer2["is_correct"] = True
if is_correct == "3":
answer3["is_correct"] = True
if is_correct == "4":
answer4["is_correct"] = True
answers.append({
"answers": [
answer1,
answer2,
answer3,
answer4
]
})
description = dict(request.POST)["desc"][0]
Question.objects.EditQuestion(question_id=question_id, name=description, answers=answers)
return redirect(f'/tests/{test}/edit')
@login_required
def deleteTest(request, test_id):
Test.objects.filter(id=test_id).delete()
return redirect('myTests')
@login_required
def editVisible(request, test_id):
new_visible = request.GET["visible"]
if new_visible == "public":
new_visible = True
else:
new_visible = False
test = Test.objects.get(id=test_id)
test.visible = new_visible
test.save()
return redirect(f'/tests/{test_id}/edit')
@login_required
def editName(request, test_id):
new_name = request.GET["name"]
test = Test.objects.get(id=test_id)
test.name = new_name
test.save()
return redirect(f'/tests/{test_id}/edit')
@login_required
def editPassword(request, test_id):
new_password = request.GET["password"]
test = Test.objects.get(id=test_id)
test.password = new_password
test.save()
return redirect(f'/tests/{test_id}/edit')
@login_required
def rateTest(request, test_id):
test = Test.objects.get(id=test_id)
rate = request.GET["rate"]
test.rates_amount += 1
test.total_rating += int(rate)
avg_rating = test.total_rating / test.rates_amount
test.avg_rating = int(avg_rating)
test.save()
return redirect(f'/tests/{test_id}/result')
class TestModelViewSet(viewsets.ModelViewSet):
queryset = Test.objects.all()
serializer_class = TestSerializer
class TestTemplateView(TemplateView):
PASSED = "Zaliczony"
FAILED = "Niezaliczony"
UNKNOWN = "nieznany"
PASSED = {
True: PASSED,
False: FAILED
}
permission_classes = []
template_name = settings.BASE_DIR + f"/templates/generic_test.html"
test_id = None
def get_queryset(self):
return Test.objects.all()
def get_context_data(self, test_id, **kwargs):
self.test_id = test_id
context = super().get_context_data(**kwargs)
context["test"] = self.get_queryset().filter(id=test_id).prefetch_related("questions__answers").first()
return context
def get_score(self, test: Test, answers):
return test.get_score(answers)
def get_maxscore(self, test: Test):
return test.get_maxscore()
def formatted_responses(self, unformatted_json):
formatted_response = list()
for question, answer in unformatted_json.items():
formatted_response.append(
{
"question": question,
"answer": answer
}
)
return formatted_response
def post(self, request, *args, **kwargs):
test = Test.objects.get(id=kwargs.get("test_id"))
score = self.get_score(test, self.formatted_responses(request.POST))
max = self.get_maxscore(test)
status = score >= test.passing_score
# context = {
# "status": self.PASSED.get(status, self.UNKNOWN),
# "points": score,
# "max": max,
# "passing": test.passing_score,
# "percentage": int(score / max * 100),
# "password": test.password
# }
request.session["status"] = self.PASSED.get(status, self.UNKNOWN)
request.session["points"] = score
request.session["max"] = max
request.session["passing"] = test.passing_score
request.session["percentage"] = int(score / max * 100)
request.session["password"] = test.password
SolvedTest.objects.create(
score=score,
max=max,
percentage=int(score / max * 100),
user=request.user,
test=test
)
test.completions += 1
test.total_percentage_scored_by_users += int(score / max * 100)
if test.completions >= 5:
test.avg_difficulty = float(test.total_percentage_scored_by_users) / float(test.completions)
if test.avg_difficulty > 90.0:
test.difficulty_label = 1
elif test.avg_difficulty > 75.0:
test.difficulty_label = 2
elif test.avg_difficulty > 50.0:
test.difficulty_label = 3
elif test.avg_difficulty > 25.0:
test.difficulty_label = 4
else:
test.difficulty_label = 5
test.save()
return HttpResponseRedirect(f'result')
class TournamentTemplateView(TemplateView):
PASSED = "Zaliczony"
FAILED = "Niezaliczony"
UNKNOWN = "nieznany"
PASSED = {
True: PASSED,
False: FAILED
}
permission_classes = []
template_name = settings.BASE_DIR + f"/templates/generic_tournament.html"
test_id = None
def get_queryset(self):
return Tournament.objects.all()
def get_context_data(self, tournament_id, **kwargs):
self.test_id = tournament_id
context = super().get_context_data(**kwargs)
context["tournament"] = self.get_queryset().filter(id=tournament_id)
context["questions"] = Question.objects.filter(tournament=tournament_id)
return context
def get_score(self, tournament: Tournament, answers):
return tournament.get_score(answers)
def get_maxscore(self, tournament: Tournament):
return tournament.get_maxscore()
def formatted_responses(self, unformatted_json):
formatted_response = list()
for question, answer in unformatted_json.items():
formatted_response.append(
{
"question": question,
"answer": answer
}
)
return formatted_response
def post(self, request, *args, **kwargs):
tournament = Tournament.objects.get(id=kwargs.get("tournament_id"))
score = self.get_score(tournament, self.formatted_responses(request.POST))
max = self.get_maxscore(tournament)
status = score >= tournament.passing_score
# context = {
# "status": self.PASSED.get(status, self.UNKNOWN),
# "points": score,
# "max": max,
# "passing": test.passing_score,
# "percentage": int(score / max * 100),
# "password": test.password
# }
request.session["status"] = self.PASSED.get(status, self.UNKNOWN)
request.session["points"] = score
request.session["max"] = max
request.session["passing"] = tournament.passing_score
request.session["percentage"] = int(score / max * 100)
request.session["password"] = tournament.password
# SolvedTest.objects.create(
# score=score,
# max=max,
# percentage=int(score / max * 100),
# user=request.user,
# test=test
# )
tournament.completions += 1
tournament.total_percentage_scored_by_users += int(score / max * 100)
if tournament.completions >= 5:
tournament.avg_difficulty = float(tournament.total_percentage_scored_by_users) / float(tournament.completions)
if tournament.avg_difficulty > 90.0:
tournament.difficulty_label = 1
elif tournament.avg_difficulty > 75.0:
tournament.difficulty_label = 2
elif tournament.avg_difficulty > 50.0:
tournament.difficulty_label = 3
elif tournament.avg_difficulty > 25.0:
tournament.difficulty_label = 4
else:
tournament.difficulty_label = 5
tournament.save()
return HttpResponseRedirect(f'result')
@login_required
def TestPasswordTemplateView(request, test_id):
test = Test.objects.get(id=test_id)
if test.password == "":
return redirect(f'/tests/{test_id}/show')
if request.POST:
if request.POST["password"] == test.password:
return redirect(f'/tests/{test_id}/show')
return render(request, 'testPassword.html')
@login_required
def testView(request):
permission_classes = []
template_name = settings.BASE_DIR + f"/templates/generic_test.html"
context = {}
if request.POST:
form = RegistrationForm(request.POST)
if form.is_valid():
User.objects.create(
email=form.cleaned_data["email"],
first_name=form.cleaned_data["first_name"],
last_name=form.cleaned_data["last_name"],
password=form.cleaned_data["password1"]
)
return redirect('register_success')
else:
context['registration_form'] = form
else:
context["test"] = Test.objects.all().filter(id=test_id).prefetch_related("questions__answers").first()
return render(request, 'generic_test.html', context)
class TestValidateAPIView(views.APIView):
PASSED = "passed"
FAILED = "failed"
UNKNOWN = "unknown"
PASSED = {
True: PASSED,
False: FAILED
}
def get_score(self, test: Test, answers):
return test.get_score(answers)
def post(self, request, test_id, **kwargs):
test = Test.objects.get(id=test_id)
score = self.get_score(test, request.data["answers"])
status = score >= test.passing_score
return Response({
"status": self.PASSED.get(status, self.UNKNOWN),
"points": score
})
class TestResultView(TemplateView):
permission_classes = []
template_name = settings.BASE_DIR + f"/templates/result.html"
class TournamentResultView(TemplateView):
permission_classes = []
template_name = settings.BASE_DIR + f"/templates/tournament_result.html"