630 lines
22 KiB
Python
630 lines
22 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, RateTournament, RateTest, TournamentClassification
|
|
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 redirect('home')
|
|
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):
|
|
user = request.user
|
|
test = Test.objects.get(id=test_id)
|
|
|
|
if RateTest.objects.filter(user=user, test=test).exists():
|
|
return redirect(f'/tests/{test_id}/result?message=Nie mozesz ocenić ponownie tego testu!')
|
|
else:
|
|
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()
|
|
RateTest.objects.create(user=user, test=test)
|
|
return redirect(f'/tests/{test_id}/result')
|
|
|
|
|
|
@login_required
|
|
def rateTournament(request, tournament_id):
|
|
user = request.user
|
|
tournament = Test.objects.get(id=tournament_id)
|
|
if RateTournament.objects.filter(user=user, test=test).exists():
|
|
redirect(f'/tests/{tournament_id}/tournament/result?message=Nie mozesz ocenić ponownie tego testu!')
|
|
else:
|
|
rate = request.GET["rate"]
|
|
tournament.rates_amount += 1
|
|
tournament.total_rating += int(rate)
|
|
avg_rating = tournament.total_rating / tournament.rates_amount
|
|
tournament.avg_rating = int(avg_rating)
|
|
tournament.save()
|
|
RateTournament.objects.create(user=user, test=test)
|
|
return redirect(f'/tests/{tournament_id}/tournament/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 > 80.0:
|
|
test.difficulty_label = 1
|
|
elif test.avg_difficulty > 60.0:
|
|
test.difficulty_label = 2
|
|
elif test.avg_difficulty > 40.0:
|
|
test.difficulty_label = 3
|
|
elif test.avg_difficulty > 20.0:
|
|
test.difficulty_label = 4
|
|
else:
|
|
test.difficulty_label = 5
|
|
test.save()
|
|
return HttpResponseRedirect(f'result')
|
|
|
|
# here
|
|
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
|
|
# )
|
|
TournamentClassification.objects.create(
|
|
user=request.user,
|
|
tournament=tournament,
|
|
score=score,
|
|
)
|
|
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"
|
|
|
|
|
|
class TournamentClassificationView(TemplateView):
|
|
permission_classes = []
|
|
template_name = settings.BASE_DIR + f"/templates/tournament_classification.html"
|
|
|
|
def get_queryset(self):
|
|
return TournamentClassification.objects.all()
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = super().get_context_data(**kwargs)
|
|
context["tournament_names"] = self.get_queryset().values_list("tournament__name", flat=True).order_by("tournament__name").distinct()
|
|
return context
|
|
|
|
def post(self, request, *args, **kwargs):
|
|
context = super().get_context_data(**kwargs)
|
|
name = request.POST["name"]
|
|
context["tournament_names"] = self.get_queryset().values_list("tournament__name", flat=True).order_by("tournament__name").distinct()
|
|
context["final_tournaments"] = TournamentClassification.objects.filter(tournament__name=name).values("tournament__name","score", "date", "user__email").order_by("-score", "date")
|
|
return render(request, 'tournament_classification.html', context)
|
|
|
|
|
|
|