from generic.views import get_question_and_content_type from django.core.exceptions import PermissionDenied from django.shortcuts import render, get_object_or_404, redirect from django.views.decorators.csrf import csrf_exempt from django import forms # from django.contrib.auth.models import User from django.contrib.auth.decorators import login_required, user_passes_test from django.contrib.auth.models import User from django.contrib.contenttypes.models import ContentType from django.contrib.auth.mixins import LoginRequiredMixin from django.views.generic.edit import CreateView, UpdateView, DeleteView from django.views.generic import ListView from django.db.models.functions import Lower from django.core.cache import cache from django.urls import reverse_lazy, reverse from django.http import Http404, JsonResponse from django.http import HttpResponseRedirect, HttpResponse from physics.models import CidUserAnswer as PhysicsCidUserAnswer, Question from physics.models import Exam as PhysicsExam from physics.models import Question as SbasQuestion from anatomy.models import CidUserAnswer as AnatomyCidUserAnswer from anatomy.models import Exam as AnatomyExam from anatomy.models import AnatomyQuestion from anatomy.models import Answer as AnatomyAnswer from rapids.models import CidUserAnswer as RapidsCidUserAnswer from rapids.models import Exam as RapidsExam from rapids.models import Rapid from rapids.models import Answer as RapidAnswer from longs.models import CidUserAnswer as LongsCidUserAnswer from longs.models import Exam as LongsExam from longs.models import Long from sbas.models import CidUserAnswer as SbasCidUserAnswer from sbas.models import Exam as SbasExam from sbas.models import Question as SbasQuestion from anatomy.views import AnatomyExamViews from rapids.views import RapidExamViews from longs.views import LongExamViews from generic.forms import QuestionNoteForm from generic.models import QuestionNote import json from django.template import RequestContext def feedback_checker(user): return user.groups.filter(name="feedback_checker").exists() @login_required def profile(request): user = request.user return render(request, "profile.html", {"user": user}) def cid_selector(request): return render( request, "cid_selector.html", ) def cid_scores(request, pk): # exam = get_object_or_404(Exam, pk=pk) # TODO:Need some kind of test for cid cid = pk # questions = exam.exam_questions.all() physics_answers = PhysicsCidUserAnswer.objects.filter(cid=cid) anatomy_answers = AnatomyCidUserAnswer.objects.filter(cid=cid) rapids_answers = RapidsCidUserAnswer.objects.filter(cid=cid) longs_answers = LongsCidUserAnswer.objects.filter(cid=cid) sbas_answers = SbasCidUserAnswer.objects.filter(cid=cid) if ( not physics_answers and not anatomy_answers and not rapids_answers and not longs_answers and not sbas_answers ): raise Http404("cid not found") kwargs = {"publish_results": True} if request.user.groups.filter(name="view_all_results").exists(): kwargs = {} physics_exam_ids = physics_answers.values_list("exam").distinct() physics_exams = PhysicsExam.objects.filter(id__in=physics_exam_ids, **kwargs) anatomy_exam_ids = anatomy_answers.values_list("exam").distinct() anatomy_exams = AnatomyExam.objects.filter(id__in=anatomy_exam_ids, **kwargs) rapids_exam_ids = rapids_answers.values_list("exam").distinct() rapids_exams = RapidsExam.objects.filter(id__in=rapids_exam_ids, **kwargs) longs_exam_ids = longs_answers.values_list("exam").distinct() longs_exams = LongsExam.objects.filter(id__in=longs_exam_ids, **kwargs) sbas_exam_ids = sbas_answers.values_list("exam").distinct() sbas_exams = SbasExam.objects.filter(id__in=sbas_exam_ids, **kwargs) return render( request, "cid_scores.html", { "physics_exams": physics_exams, "anatomy_exams": anatomy_exams, "rapids_exams": rapids_exams, "longs_exams": longs_exams, "sbas_exams": sbas_exams, "cid": cid, }, ) def active_exams(request): anatomy_exams = AnatomyExamViews.active_exams(request, False) rapid_exams = RapidExamViews.active_exams(request, False) long_exams = LongExamViews.active_exams(request, False) exams = [] exams.extend(anatomy_exams) exams.extend(rapid_exams) exams.extend(long_exams) active_exams = {"exams": exams} if request.user: active_exams["user"] = request.user.username else: active_exams["user"] = False return JsonResponse(active_exams) def active_exams_unbased(request): anatomy_exams = AnatomyExamViews.active_exams(request, False, False) rapid_exams = RapidExamViews.active_exams(request, False, False) long_exams = LongExamViews.active_exams(request, False, False) exams = [] exams.extend(anatomy_exams) exams.extend(rapid_exams) exams.extend(long_exams) active_exams = {"exams": exams} return JsonResponse(active_exams) @csrf_exempt def exam_submit(request): if request.is_ajax and request.method == "POST": exam_type, exam_id = request.POST.get("eid").split("/") if exam_type == "anatomy": return AnatomyExamViews.postExamAnswers(request) elif exam_type == "rapid": return RapidExamViews.postExamAnswers(request) elif exam_type == "long": return LongExamViews.postExamAnswers(request) return JsonResponse({"success": False, "error": "Invalid exam type"}) # postExamAnswers return JsonResponse({"success": False, "error": "Invalid data"}) def feedback_create(request, question_type, pk): if question_type == "anatomy": question = AnatomyQuestion elif question_type == "rapid": question = Rapid elif question_type == "long": question = Long return JsonResponse({"success": False, "error": "Invalid exam type"}) class AddQuestionNote(CreateView): model = QuestionNote form_class = QuestionNoteForm #fields = ("author", "note_type", "note") def get_form_kwargs(self): kwargs = super(AddQuestionNote, self).get_form_kwargs() # update the kwargs for the form init method with yours kwargs.update(self.kwargs) # self.kwargs contains all url conf params kwargs.update({"user": self.request.user}) return kwargs def get_initial(self): pk = self.kwargs["pk"] self.question_type = self.kwargs["question_type"] question, content_type = get_question_and_content_type(self.question_type) self.question = get_object_or_404(question, pk=pk) return { "content_type" : content_type, "object_id" : pk } def get_context_data(self, **kwargs): # This can also be accessed via view.**** in the template context = super(AddQuestionNote, self).get_context_data(**kwargs) context['question'] = self.question context['question_type'] = self.question_type return context def form_valid(self, form): model = form.save(commit=False) if self.request.user.is_authenticated: model.user_author = self.request.user model.save() response = super().form_valid(form) return response @user_passes_test(lambda u: u.is_superuser) def feedback_note_delete(request, pk): q = get_object_or_404(QuestionNote, pk=pk) q.delete() return redirect(q.get_object_url()) @login_required def feedback_mark_complete(request, pk): q = get_object_or_404(QuestionNote, pk=pk) if request.user not in q.question.author.all() and not request.user.groups.filter(name="feedback_checker").exists(): raise PermissionDenied() q.complete = True q.save() return redirect(q.get_object_url()) @csrf_exempt def answer_suggestion_submit(request): if request.is_ajax and request.method == "POST": post_data = json.loads(request.body) question_type, qid = post_data["qid"].split("/") answer_string = post_data["answer"] status = post_data["status"] if str(status) not in " 012": return JsonResponse({"success": False, "error": "Invalid status"}) if question_type == "anatomy": AnswerModel = AnatomyAnswer question = AnatomyQuestion elif question_type == "rapid": AnswerModel = RapidAnswer question = Rapid else: return JsonResponse({"success": False, "error": "Invalid question type"}) q = get_object_or_404(question, pk=qid) if AnswerModel.objects.filter(answer=answer_string, question=q): return JsonResponse({"success": False, "error": "Answer already exists"}) a = AnswerModel(question=q, answer=answer_string, status=status, proposed=True) a.save() return JsonResponse({"success": True, "error": "Answer submited"}) # postExamAnswers return JsonResponse({"success": False, "error": "Invalid data"}) @login_required def answer_submit(request): if request.is_ajax and request.method == "POST": qid = request.POST.get("qid") question_type = request.POST.get("question_type") answer_string = request.POST.get("answer") status = request.POST.get("status") if str(status) not in "012": return JsonResponse({"success": False, "error": "Invalid status"}) if question_type == "anatomy": AnswerModel = AnatomyAnswer question = AnatomyQuestion elif question_type == "rapid": AnswerModel = RapidAnswer question = Rapid else: return JsonResponse({"success": False, "error": "Invalid question type"}) q = get_object_or_404(question, pk=qid) if AnswerModel.objects.filter(answer=answer_string, question=q): return JsonResponse({"success": False, "error": "Answer already exists"}) a = AnswerModel(question=q, answer=answer_string, status=status) a.save() return JsonResponse({"success": True, "error": "Answer added"}) return JsonResponse({"success": False, "error": "Invalid data"}) @login_required def answer_suggestion_confirm(request): if request.is_ajax and request.method == "POST": question_type = request.POST.get("question_type") aid = request.POST.get("aid") status = request.POST.get("status") if question_type == "anatomy": AnswerModel = AnatomyAnswer question = AnatomyQuestion elif question_type == "rapid": AnswerModel = RapidAnswer question = Rapid else: return JsonResponse({"success": False, "error": "Invalid question type"}) answer = get_object_or_404(AnswerModel, pk=aid) answer.proposed = False answer.status = status answer.save() return JsonResponse({"success": True, "error": "Answer changed"}) @login_required @user_passes_test(feedback_checker) def view_feedback(request): # exam = get_object_or_404(Exam, pk=pk) feedback_notes = QuestionNote.objects.filter(complete=False) return render( request, "view_feedback.html", { "notes": feedback_notes, }, ) # HTTP Error 400 def page_not_found(request, exception): response = render(request, '404.html', {}) #response.status_code = 404 return response def page_forbidden(request, exception): response = render(request, '403.html', {}) #response.status_code = 404 return response def server_error(request): response = render(request, '500.html', {}) #response.status_code = 404 return response