def edit_attestation(request, attestation_id): if not (request.user.is_tutor or request.user.is_trainer or request.user.is_superuser): return access_denied(request) attest = get_object_or_404(Attestation, pk=attestation_id) if not (attest.author == request.user or request.user.is_trainer): return access_denied(request) if attest.published: # If if this attestation is already final or not by this user redirect to view_attestation return HttpResponseRedirect(reverse('view_attestation', args=[attestation_id])) solution = attest.solution model_solution = solution.task.model_solution if request.method == "POST": with transaction.atomic(): attestForm = AttestationForm(request.POST, instance=attest, prefix='attest') attestFileFormSet = AnnotatedFileFormSet(request.POST, instance=attest, prefix='attestfiles') ratingResultFormSet = RatingResultFormSet(request.POST, instance=attest, prefix='ratingresult') if attestForm.is_valid() and attestFileFormSet.is_valid() and ratingResultFormSet.is_valid(): attestForm.save() attest.final = False attest.save() attestFileFormSet.save() ratingResultFormSet.save() return HttpResponseRedirect(reverse('view_attestation', args=[attestation_id])) else: attestForm = AttestationForm(instance=attest, prefix='attest') attestFileFormSet = AnnotatedFileFormSet(instance=attest, prefix='attestfiles') ratingResultFormSet = RatingResultFormSet(instance=attest, prefix='ratingresult') show_author = not get_settings().anonymous_attestation return render_to_response("attestation/attestation_edit.html", {"attestForm": attestForm, "attestFileFormSet": attestFileFormSet, "ratingResultFormSet":ratingResultFormSet, "solution": solution, "model_solution":model_solution, "show_author":show_author}, context_instance=RequestContext(request))
def view_attestation(request, attestation_id): attest = get_object_or_404(Attestation, pk=attestation_id) may_modify = attest.author == request.user or request.user.is_trainer may_view = attest.solution.author == request.user or request.user.is_tutor or may_modify if not may_view: return access_denied(request) if request.method == "POST": if not may_modify: return access_denied(request) with transaction.atomic(): form = AttestationPreviewForm(request.POST, instance=attest) if form.is_valid(): form.save() if 'publish' in request.POST: if attest.solution.task.only_trainers_publish and not request.user.is_trainer: return access_denied(request) attest.publish(request, by = request.user) return HttpResponseRedirect(reverse('attestation_list', args=[attest.solution.task.id])) else: form = AttestationPreviewForm(instance=attest) submitable = may_modify and not attest.published withdrawable = may_modify and attest.published return render_to_response("attestation/attestation_view.html", {"attest": attest, 'submitable':submitable, 'withdrawable': withdrawable, 'form':form, 'show_author': not get_settings().anonymous_attestation, 'show_attestor': not get_settings().invisible_attestor}, context_instance=RequestContext(request))
def solution_detail(request,solution_id,full): solution = get_object_or_404(Solution, pk=solution_id) if not (solution.author == request.user or request.user.is_trainer or request.user.is_superuser or (solution.author.tutorial and solution.author.tutorial.tutors.filter(id=request.user.id))): return access_denied(request) if full and not (request.user.is_trainer or request.user.is_tutor or request.user.is_superuser): return access_denied(request) accept_all_solutions = get_settings().accept_all_solutions if (request.method == "POST"): if solution.final or solution.testupload or solution.task.expired(): return access_denied(request) if not (solution.accepted or accept_all_solutions): return access_denied(request) solution.copy() return HttpResponseRedirect(reverse('solution_list', args=[solution.task.id])) else: attestations = Attestation.objects.filter(solution__task=solution.task, author__tutored_tutorials=request.user.tutorial) attestationsPublished = attestations[0].published if attestations else False return render_to_response( "solutions/solution_detail.html", { "solution": solution, "attestationsPublished": attestationsPublished, "accept_all_solutions": accept_all_solutions, "full":full }, context_instance=RequestContext(request))
def solution_list(request, task_id, user_id=None): if (user_id and not request.user.is_trainer and not request.user.is_superuser): return access_denied(request) task = get_object_or_404(Task, pk=task_id) author = get_object_or_404(User, pk=user_id) if user_id else request.user solutions = task.solution_set.filter(author = author).order_by('-id') final_solution = task.final_solution(author) if task.publication_date >= datetime.now() and not request.user.is_trainer: raise Http404 if request.method == "POST": if task.expired() and not request.user.is_trainer: return access_denied(request) solution = Solution(task = task, author=author) formset = SolutionFormSet(request.POST, request.FILES, instance=solution) if formset.is_valid(): solution.save() formset.save() run_all_checker = bool(User.objects.filter(id=user_id, tutorial__tutors__pk=request.user.id) or request.user.is_trainer) solution.check_solution(run_all_checker) if solution.accepted: # Send submission confirmation email t = loader.get_template('solutions/submission_confirmation_email.html') c = { 'protocol': request.is_secure() and "https" or "http", 'domain': RequestSite(request).domain, 'site_name': settings.SITE_NAME, 'solution': solution, } with tempfile.NamedTemporaryFile(mode='w+') as tmp: tmp.write(t.render(c)) tmp.seek(0) [signed_mail, __, __, __, __] = execute_arglist(["openssl", "smime", "-sign", "-signer", settings.CERTIFICATE, "-inkey", settings.PRIVATE_KEY, "-in", tmp.name], ".", unsafe=True) connection = get_connection() message = ConfirmationMessage(_("%s submission confirmation") % settings.SITE_NAME, signed_mail, None, [solution.author.email], connection=connection) if solution.author.email: message.send() if solution.accepted or get_settings().accept_all_solutions: solution.final = True solution.save() return HttpResponseRedirect(reverse('solution_detail', args=[solution.id])) else: formset = SolutionFormSet() attestations = Attestation.objects.filter(solution__task=task, author__tutored_tutorials=request.user.tutorial) attestationsPublished = attestations[0].published if attestations else False return render(request, "solutions/solution_list.html", {"formset": formset, "task":task, "solutions": solutions, "final_solution":final_solution, "attestationsPublished":attestationsPublished, "author":author, "invisible_attestor":get_settings().invisible_attestor})
def solution_list(request, task_id, user_id=None): if (user_id and not request.user.is_trainer and not request.user.is_superuser): return access_denied(request) task = get_object_or_404(Task,pk=task_id) author = get_object_or_404(User,pk=user_id) if user_id else request.user solutions = task.solution_set.filter(author = author).order_by('-id') final_solution = task.final_solution(author) if task.publication_date >= datetime.now() and not request.user.is_trainer: raise Http404 if request.method == "POST": if task.expired() and not request.user.is_trainer: return access_denied(request) solution = Solution(task = task, author=author) formset = SolutionFormSet(request.POST, request.FILES, instance=solution) if formset.is_valid(): solution.save() formset.save() run_all_checker = bool(User.objects.filter(id=user_id, tutorial__tutors__pk=request.user.id) or request.user.is_trainer) solution.check(run_all_checker) if solution.accepted: # Send submission confirmation email t = loader.get_template('solutions/submission_confirmation_email.html') c = { 'protocol': request.is_secure() and "https" or "http", 'domain': RequestSite(request).domain, 'site_name': settings.SITE_NAME, 'solution': solution, } if solution.author.email: send_mail(_("%s submission confirmation") % settings.SITE_NAME, t.render(Context(c)), None, [solution.author.email]) if solution.accepted or get_settings().accept_all_solutions: solution.final = True solution.save() return HttpResponseRedirect(reverse('solution_detail', args=[solution.id])) else: formset = SolutionFormSet() attestations = Attestation.objects.filter(solution__task=task, author__tutored_tutorials=request.user.tutorial) attestationsPublished = attestations[0].published if attestations else False return render_to_response("solutions/solution_list.html", {"formset": formset, "task":task, "solutions": solutions, "final_solution":final_solution, "attestationsPublished":attestationsPublished, "author":author, "invisible_attestor":get_settings().invisible_attestor}, context_instance=RequestContext(request))
def edit_attestation(request, attestation_id): if not (request.user.is_tutor or request.user.is_trainer or request.user.is_superuser): return access_denied(request) attest = get_object_or_404(Attestation, pk=attestation_id) if not (attest.author == request.user or request.user.is_trainer): return access_denied(request) if attest.published: # If if this attestation is already final or not by this user redirect to view_attestation return HttpResponseRedirect(reverse('view_attestation', args=[attestation_id])) solution = attest.solution model_solution = solution.task.model_solution if request.method == "POST": with transaction.atomic(): attestForm = AttestationForm(request.POST, instance=attest, prefix='attest') attestFileFormSet = AnnotatedFileFormSet(request.POST, instance=attest, prefix='attestfiles') ratingResultFormSet = RatingResultFormSet(request.POST, instance=attest, prefix='ratingresult') if attestForm.is_valid() and attestFileFormSet.is_valid() and ratingResultFormSet.is_valid(): attestForm.save() attest.final = False attest.save() attestFileFormSet.save() ratingResultFormSet.save() return HttpResponseRedirect(reverse('view_attestation', args=[attestation_id])) else: attestForm = AttestationForm(instance=attest, prefix='attest') attestFileFormSet = AnnotatedFileFormSet(instance=attest, prefix='attestfiles') ratingResultFormSet = RatingResultFormSet(instance=attest, prefix='ratingresult') show_author = not get_settings().anonymous_attestation show_run_checkers = get_settings().attestation_allow_run_checkers htmlinjectors = HtmlInjector.objects.filter(task = solution.task, inject_in_attestation_edit = True) htmlinjector_snippets = [ injector.html_file.read().decode("utf-8") for injector in htmlinjectors ] return render(request, "attestation/attestation_edit.html", { "attestForm": attestForm, "attestFileFormSet": attestFileFormSet, "ratingResultFormSet": ratingResultFormSet, "solution": solution, "model_solution": model_solution, "show_author": show_author, "show_run_checkers": show_run_checkers, "htmlinjector_snippets": htmlinjector_snippets, } )
def solution_list(request, task_id, user_id=None): if (user_id and not request.user.is_trainer and not request.user.is_superuser): return access_denied(request) task = get_object_or_404(Task,pk=task_id) author = get_object_or_404(User,pk=user_id) if user_id else request.user solutions = task.solution_set.filter(author = author).order_by('-id') final_solution = task.final_solution(author) if task.publication_date >= datetime.now() and not request.user.is_trainer: raise Http404 if request.method == "POST": if task.expired() and not request.user.is_trainer: return access_denied(request) solution = Solution(task = task, author=author) formset = SolutionFormSet(request.POST, request.FILES, instance=solution) if formset.is_valid(): solution.save() formset.save() run_all_checker = bool(User.objects.filter(id=user_id, tutorial__tutors__pk=request.user.id) or request.user.is_trainer) solution.check_solution(run_all_checker) if solution.accepted: # Send submission confirmation email t = loader.get_template('solutions/submission_confirmation_email.html') c = { 'protocol': request.is_secure() and "https" or "http", 'domain': RequestSite(request).domain, 'site_name': settings.SITE_NAME, 'solution': solution, } if solution.author.email: send_mail(_("%s submission confirmation") % settings.SITE_NAME, t.render(c), None, [solution.author.email]) if solution.accepted or get_settings().accept_all_solutions: solution.final = True solution.save() return HttpResponseRedirect(reverse('solution_detail', args=[solution.id])) else: formset = SolutionFormSet() attestations = Attestation.objects.filter(solution__task=task, author__tutored_tutorials=request.user.tutorial) attestationsPublished = attestations[0].published if attestations else False return render(request, "solutions/solution_list.html", {"formset": formset, "task":task, "solutions": solutions, "final_solution":final_solution, "attestationsPublished":attestationsPublished, "author":author, "invisible_attestor":get_settings().invisible_attestor})
def solution_detail(request, solution_id, full): solution = get_object_or_404(Solution, pk=solution_id) if not (solution.author == request.user or request.user.is_trainer or request.user.is_superuser or (solution.author.tutorial and solution.author.tutorial.tutors.filter(id=request.user.id))): return access_denied(request) if full and not (request.user.is_trainer or request.user.is_tutor or request.user.is_superuser): return access_denied(request) accept_all_solutions = get_settings().accept_all_solutions if (request.method == "POST"): if solution.final or solution.testupload or solution.task.expired(): return access_denied(request) if not (solution.accepted or accept_all_solutions): return access_denied(request) solution.copy() return HttpResponseRedirect( reverse('solution_list', args=[solution.task.id])) else: attestations = Attestation.objects.filter( solution__task=solution.task, author__tutored_tutorials=request.user.tutorial) attestationsPublished = attestations[ 0].published if attestations else False htmlinjectors = [] if full: htmlinjectors = HtmlInjector.objects.filter( task=solution.task, inject_in_solution_full_view=True) else: htmlinjectors = HtmlInjector.objects.filter( task=solution.task, inject_in_solution_view=True) htmlinjector_snippets = [ injector.html_file.read().decode("utf-8") for injector in htmlinjectors ] return render( request, "solutions/solution_detail.html", { "solution": solution, "attestationsPublished": attestationsPublished, "accept_all_solutions": accept_all_solutions, "htmlinjector_snippets": htmlinjector_snippets, "full": full })
def test_upload(request, task_id): if not request.user.is_trainer and not request.user.is_tutor and not request.user.is_superuser: return access_denied(request) task = get_object_or_404(Task, pk=task_id) if request.method == "POST": solution = Solution(task=task, author=request.user, testupload=True) formset = SolutionFormSet(request.POST, request.FILES, instance=solution) if formset.is_valid(): solution.save() formset.save() solution.check_solution(run_secret=True) return HttpResponseRedirect( reverse('solution_detail_full', args=[solution.id])) else: formset = SolutionFormSet() return render(request, "solutions/solution_test_upload.html", { "formset": formset, "task": task })
def rating_overview(request): if not (request.user.is_trainer or request.user.is_superuser): return access_denied(request) tasks = Task.objects.filter(submission_date__lt = datetime.datetime.now).order_by('publication_date','submission_date') users = User.objects.filter(groups__name='User').filter(is_active=True).order_by('last_name','first_name') rating_list = user_task_attestation_map(users, tasks) FinalGradeFormSet = modelformset_factory(User, fields=('final_grade',), extra=0) # corresponding user to user_id_list in reverse order! important for easy displaying in template user = User.objects.filter(groups__name='User').filter(is_active=True).order_by('-last_name','-first_name') script = Script.objects.get_or_create(id=1)[0] if request.method == "POST": final_grade_formset = FinalGradeFormSet(request.POST, request.FILES, queryset = user) script_form = ScriptForm(request.POST, instance=script) publish_final_grade_form = PublishFinalGradeForm(request.POST, instance=get_settings()) if final_grade_formset.is_valid() and script_form.is_valid() and publish_final_grade_form.is_valid(): final_grade_formset.save() script_form.save() publish_final_grade_form.save() else: final_grade_formset = FinalGradeFormSet(queryset = user) script_form = ScriptForm(instance=script) publish_final_grade_form = PublishFinalGradeForm(instance=get_settings()) return render_to_response("attestation/rating_overview.html", {'rating_list':rating_list, 'tasks':tasks, 'final_grade_formset':final_grade_formset, 'script_form':script_form, 'publish_final_grade_form':publish_final_grade_form}, context_instance=RequestContext(request))
def rating_export(request): if not (request.user.is_trainer or request.user.is_superuser): return access_denied(request) attestations = Attestation.objects.filter(published=True, solution__plagiarism=False) attestation_dict = {} #{(task_id,user_id):rating} for attestation in attestations: attestation_dict[attestation.solution.task_id, attestation.solution.author_id] = attestation task_id_list = Task.objects.filter(submission_date__lt = datetime.datetime.now).order_by('publication_date','submission_date').values_list('id', flat=True) user_id_list = User.objects.filter(groups__name='User').filter(is_active=True).order_by('last_name','first_name').values_list('id', flat=True) task_list = map(lambda task_id:Task.objects.get(id=task_id), task_id_list) rating_list = [] for user_id in user_id_list: rating_for_user_list = [User.objects.get(id=user_id)] for task_id in task_id_list: try: rating = attestation_dict[task_id,user_id] except KeyError: rating = None rating_for_user_list.append(rating) rating_list.append(rating_for_user_list) response = HttpResponse(content_type='text/csv') response['Content-Disposition'] = 'attachment; rating_export.csv' t = loader.get_template('attestation/rating_export.csv') c = Context({'rating_list':rating_list, 'task_list':task_list}) #response.write(u'\ufeff') setting utf-8 BOM for Exel doesn't work response.write(t.render(c)) return response
def checker_result_list(request, task_id): task = get_object_or_404(Task, pk=task_id) if (not in_group(request.user, 'Trainer')): return access_denied(request) else: users_with_checkerresults = [(user,checkerresults,final_solution) \ for user in User.objects.filter(groups__name='User').order_by('mat_number') \ for final_solution in Solution.objects.filter(author=user,final=True,task=task).values() \ for checkerresults in [sorted(CheckerResult.objects.all().filter(solution=final_solution['id']),key=lambda result : result.checker.order)]] number_of_checker = None for checkerresults in users_with_checkerresults: if (number_of_checker and (len(checkerresults) != number_of_checker)): return acces_denied(request) #TODO: issue proper error message else: number_of_checker = len(checkerresults) _, prototype, _ = users_with_checkerresults[0] return render_to_response("solutions/checker_result_list.html", { "users_with_checkerresults": users_with_checkerresults, "prototype": prototype, "task": task }, context_instance=RequestContext(request))
def solution_detail(request, solution_id, full): solution = get_object_or_404(Solution, pk=solution_id) if (not (solution.author == request.user or in_group(request.user, 'Trainer') or (solution.author.tutorial and solution.author.tutorial.tutors.filter(id=request.user.id)))): return access_denied(request) if (request.method == "POST"): solution.copy() return HttpResponseRedirect( reverse('solution_list', args=[solution.task.id])) else: attestations = Attestation.objects.filter( solution__task=solution.task, author__tutored_tutorials=request.user.tutorial) attestationsPublished = attestations[ 0].published if attestations else False return object_detail(request, Solution.objects.all(), solution_id, extra_context={ "attestationsPublished": attestationsPublished, "accept_all_solutions": get_settings().accept_all_solutions, "full": full }, template_object_name='solution')
def new_attestation_for_task(request, task_id): """ Start an attestation on a restrained random set of my tutored users """ if not (request.user.is_tutor or request.user.is_trainer or request.user.is_superuser): return access_denied(request) # fetch a solution of a user i have allredy attested in the past. users_i_have_attestated = User.objects.filter( solution__attestation__author=request.user) all_available_solutions = Solution.objects.filter( task__id=task_id, final=True, plagiarism=False, author__tutorial__in=request.user.tutored_tutorials.all(), attestation=None) if (not all_available_solutions): # if an other tutor just grabed the last solution just go back to the list return HttpResponseRedirect(reverse('attestation_list', args=[task_id])) solutions = all_available_solutions.filter( author__in=users_i_have_attestated) if (solutions): solution = solutions[0] else: solution = all_available_solutions[0] return new_attestation_for_solution(request, solution.id)
def checker_result_list(request, task_id): task = get_object_or_404(Task, pk=task_id) if not request.user.is_trainer and not request.user.is_superuser: return access_denied(request) else: users_with_checkerresults = [(user, dict(checkerresults), final_solution) \ for user in User.objects.filter(groups__name='User').order_by('mat_number') \ for final_solution in Solution.objects.filter(author=user, final=True, task=task).values() \ for checkerresults in [[ (result.checker, result) for result in CheckerResult.objects.all().filter(solution=final_solution['id'])]] ] checkers_seen = set([]) for _, results, _ in users_with_checkerresults: checkers_seen |= set(results.keys()) checkers_seen = sorted(checkers_seen, key=lambda checker: checker.order) for i, (user, results, final_solution) in enumerate(users_with_checkerresults): users_with_checkerresults[i] = (user, [ results[checker] if checker in results else None for (checker) in checkers_seen ], final_solution) return render( request, "solutions/checker_result_list.html", { "users_with_checkerresults": users_with_checkerresults, 'checkers_seen': checkers_seen, "task": task })
def view_attestation(request, attestation_id): attest = get_object_or_404(Attestation, pk=attestation_id) if not (attest.solution.author == request.user or in_group( request.user, 'Tutor,Trainer') or request.user.is_superuser): return access_denied(request) if request.method == "POST": form = AttestationPreviewForm(request.POST, instance=attest) if form.is_valid(): form.save() if 'publish' in request.POST: attest.publish(request) return HttpResponseRedirect( reverse('attestation_list', args=[attest.solution.task.id])) else: form = AttestationPreviewForm(instance=attest) submitable = attest.author == request.user and not attest.published return render_to_response( "attestation/attestation_view.html", { "attest": attest, 'submitable': submitable, 'form': form, 'show_author': not get_settings().anonymous_attestation }, context_instance=RequestContext(request))
def new_attestation_for_solution(request, solution_id, force_create=False): if not (request.user.is_tutor or request.user.is_trainer or request.user.is_superuser): return access_denied(request) solution = get_object_or_404(Solution, pk=solution_id) attestations = Attestation.objects.filter(solution=solution) if ((not force_create) and attestations): return render_to_response( "attestation/attestation_already_exists_for_solution.html", { 'task': solution.task, 'attestations': attestations, 'solution': solution, 'show_author': not get_settings().anonymous_attestation }, context_instance=RequestContext(request)) attest = Attestation(solution=solution, author=request.user) attest.save() for solutionFile in solution.solutionfile_set.filter( mime_type__startswith='text'): annotatedFile = AnnotatedSolutionFile(attestation=attest, solution_file=solutionFile, content=solutionFile.content()) annotatedFile.save() for rating in solution.task.rating_set.all(): ratingResult = RatingResult(attestation=attest, rating=rating) ratingResult.save() return HttpResponseRedirect(reverse('edit_attestation', args=[attest.id]))
def rating_overview(request): full_form = request.user.is_trainer or request.user.is_superuser if not (full_form or (request.user.is_coordinator and request.method != "POST")): return access_denied(request) tasks = Task.objects.filter(submission_date__lt=datetime.datetime.now()) users = User.objects.filter(groups__name='User').filter( is_active=True).order_by('last_name', 'first_name', 'id') # corresponding user to user_id_list in reverse order! important for easy displaying in template rev_users = users.reverse() users = users.select_related("user_ptr", "user_ptr__groups__name", "user_ptr__is_active", "user_ptr__user_id") FinalGradeFormSet = modelformset_factory(User, fields=('final_grade', ), extra=0) if request.method == "POST": final_grade_option_form = FinalGradeOptionForm(request.POST, instance=get_settings()) if final_grade_option_form.is_valid(): final_grade_option_form.save() if 'save' in request.POST: # also save final grades final_grade_formset = FinalGradeFormSet(request.POST, request.FILES, queryset=rev_users) publish_final_grade_form = PublishFinalGradeForm( request.POST, instance=get_settings()) if final_grade_formset.is_valid( ) and publish_final_grade_form.is_valid(): final_grade_formset.save() publish_final_grade_form.save() else: final_grade_formset = FinalGradeFormSet(queryset=rev_users) publish_final_grade_form = PublishFinalGradeForm( instance=get_settings()) else: # all 3 forms are created without request input final_grade_option_form = FinalGradeOptionForm(instance=get_settings()) final_grade_formset = FinalGradeFormSet(queryset=rev_users) publish_final_grade_form = PublishFinalGradeForm( instance=get_settings()) rating_list = user_task_attestation_map(users, tasks) return render( request, "attestation/rating_overview.html", { 'rating_list': rating_list, 'tasks': tasks, 'final_grade_formset': final_grade_formset, 'final_grade_option_form': final_grade_option_form, 'publish_final_grade_form': publish_final_grade_form, 'full_form': full_form })
def solution_download(request,solution_id): solution = get_object_or_404(Solution, pk=solution_id) if (not (solution.author == request.user or in_group(request.user,'Trainer,Tutor'))): return access_denied(request) zip_file = get_solutions_zip([solution]) response = HttpResponse(zip_file.read(), mimetype="application/zip") response['Content-Disposition'] = 'attachment; filename=Solution.zip' return response
def solution_download(request,solution_id,full): solution = get_object_or_404(Solution, pk=solution_id) if (not (solution.author == request.user or request.user.is_tutor or request.user.is_trainer)): return access_denied(request) zip_file = get_solutions_zip([solution], full and (request.user.is_tutor or request.user.is_trainer)) response = HttpResponse(zip_file.read(), content_type="application/zip") response['Content-Disposition'] = 'attachment; filename=Solution.zip' return response
def solution_download(request, solution_id): solution = get_object_or_404(Solution, pk=solution_id) if (not (solution.author == request.user or in_group(request.user, 'Trainer,Tutor'))): return access_denied(request) zip_file = get_solutions_zip([solution]) response = HttpResponse(zip_file.read(), mimetype="application/zip") response['Content-Disposition'] = 'attachment; filename=Solution.zip' return response
def view_attestation(request, attestation_id): attest = get_object_or_404(Attestation, pk=attestation_id) may_modify = attest.author == request.user or request.user.is_trainer may_view = attest.solution.author == request.user or request.user.is_tutor or may_modify if not may_view: return access_denied(request) if request.method == "POST": if not may_modify: return access_denied(request) with transaction.atomic(): form = AttestationPreviewForm(request.POST, instance=attest) if form.is_valid(): form.save() if 'publish' in request.POST: if attest.solution.task.only_trainers_publish and not request.user.is_trainer: return access_denied(request) attest.publish(request, by=request.user) return HttpResponseRedirect( reverse('attestation_list', args=[attest.solution.task.id])) else: form = AttestationPreviewForm(instance=attest) submitable = may_modify and not attest.published withdrawable = may_modify and attest.published htmlinjectors = HtmlInjector.objects.filter( task=attest.solution.task, inject_in_attestation_view=True) htmlinjector_snippets = [ injector.html_file.read() for injector in htmlinjectors ] return render_to_response( "attestation/attestation_view.html", { "attest": attest, "submitable": submitable, "withdrawable": withdrawable, "form": form, "show_author": not get_settings().anonymous_attestation, "show_attestor": not get_settings().invisible_attestor, "htmlinjector_snippets": htmlinjector_snippets, }, context_instance=RequestContext(request))
def attestation_run_checker(request, attestation_id): if not (request.user.is_tutor or request.user.is_trainer or request.user.is_superuser): return access_denied(request) attestation = get_object_or_404(Attestation, pk=attestation_id) if not (attestation.author == request.user or request.user.is_trainer or request.user.is_superuser): return access_denied(request) if attestation.published: return access_denied(request) if not get_settings().attestation_allow_run_checkers: return access_denied(request) solution = attestation.solution check_solution(solution, True) return HttpResponseRedirect(reverse('edit_attestation', args=[attestation_id]))
def tutorial_overview(request, tutorial_id=None): if not (request.user.is_tutor or request.user.is_trainer or request.user.is_superuser): return access_denied(request) if (tutorial_id): tutorial = get_object_or_404(Tutorial, pk=tutorial_id) if request.user.is_tutor and not tutorial.tutors.filter(id=request.user.id): return access_denied(request) else: tutorials = request.user.tutored_tutorials.all() if (not tutorials): return render(request, "attestation/tutorial_none.html") tutorial = request.user.tutored_tutorials.all()[0] if request.user.is_tutor: other_tutorials = request.user.tutored_tutorials.all() else: other_tutorials = Tutorial.objects.all() other_tutorials = other_tutorials.exclude(id=tutorial.id) tasks = Task.objects.filter(submission_date__lt = datetime.datetime.now()).order_by('publication_date', 'submission_date') users = User.objects.filter(groups__name='User').filter(is_active=True, tutorial=tutorial).order_by('last_name', 'first_name') rating_list = user_task_attestation_map(users, tasks, False) def to_float(a, default, const): try: return (float(str(a.final_grade)), const) except (ValueError, TypeError, AttributeError): return (default, default) averages = [0.0 for i in range(len(tasks))] nr_of_grades = [0 for i in range(len(tasks))] for (user, attestations, _, _) in rating_list: averages = [avg+to_float(att, 0.0, None)[0] for (avg, (att, _)) in zip(averages, attestations)] nr_of_grades = [n+to_float(att, 0, 1)[1] for (n, (att, _)) in zip(nr_of_grades, attestations)] nr_of_grades = [ (n if n>0 else 1) for n in nr_of_grades] averages = [a/n for (a, n) in zip(averages, nr_of_grades)] return render(request, "attestation/tutorial_overview.html", {'other_tutorials':other_tutorials, 'tutorial':tutorial, 'rating_list':rating_list, 'tasks':tasks, 'final_grades_published': get_settings().final_grades_published, 'averages':averages})
def tutorial_overview(request, tutorial_id=None): if not (request.user.is_tutor or request.user.is_trainer or request.user.is_superuser): return access_denied(request) if (tutorial_id): tutorial = get_object_or_404(Tutorial, pk=tutorial_id) if request.user.is_tutor and not tutorial.tutors.filter(id=request.user.id): return access_denied(request) else: tutorials = request.user.tutored_tutorials.all() if (not tutorials): return render_to_response("attestation/tutorial_none.html",context_instance=RequestContext(request)) tutorial = request.user.tutored_tutorials.all()[0] if request.user.is_tutor: other_tutorials = request.user.tutored_tutorials.all() else: other_tutorials = Tutorial.objects.all() other_tutorials = other_tutorials.exclude(id=tutorial.id) tasks = Task.objects.filter(submission_date__lt = datetime.datetime.now).order_by('publication_date','submission_date') users = User.objects.filter(groups__name='User').filter(is_active=True, tutorial=tutorial).order_by('last_name','first_name') rating_list = user_task_attestation_map(users, tasks,False) def to_float(a,default,const): try: return (float(str(a.final_grade)),const) except (ValueError,TypeError,AttributeError): return (default,default) averages = [0.0 for i in range(len(tasks))] nr_of_grades = [0 for i in range(len(tasks))] for (user,attestations) in rating_list: averages = [avg+to_float(att,0.0,None)[0] for (avg,att) in zip(averages,attestations)] nr_of_grades = [n+to_float(att,0,1)[1] for (n,att) in zip(nr_of_grades,attestations)] nr_of_grades = [ (n if n>0 else 1) for n in nr_of_grades] averages = [a/n for (a,n) in zip(averages,nr_of_grades)] script = Script.objects.get_or_create(id=1)[0] return render_to_response("attestation/tutorial_overview.html", {'other_tutorials':other_tutorials, 'tutorial':tutorial, 'rating_list':rating_list, 'tasks':tasks, 'final_grades_published': get_settings().final_grades_published, 'script':script, 'averages':averages}, context_instance=RequestContext(request))
def withdraw_attestation(request, attestation_id): if not (request.user.is_tutor or request.user.is_trainer or request.user.is_superuser): return access_denied(request) attest = get_object_or_404(Attestation, pk=attestation_id) if not (attest.author == request.user or request.user.is_trainer): return access_denied(request) if attest.solution.task.only_trainers_publish and not request.user.is_trainer: return access_denied(request) if not attest.published: # If if this attestation is already final or not by this user redirect to view_attestation return HttpResponseRedirect(reverse('view_attestation', args=[attestation_id])) if request.method != "POST": return HttpResponseRedirect(reverse('view_attestation', args=[attestation_id])) attest.withdraw(request, by=request.user) return HttpResponseRedirect(reverse('edit_attestation', args=[attestation_id]))
def jplag(request, task_id): if not (request.user.is_staff): return access_denied(request) task = get_object_or_404(Task, pk=task_id) if request.method == 'POST': task.run_jplag(request.POST['lang']) return HttpResponseRedirect(reverse('solution_jplag', args=[task_id])) jplag_lang = get_settings().jplag_setting return render(request, "solutions/jplag.html", {"task":task, "jplag_lang": jplag_lang})
def solution_detail(request,solution_id,full): solution = get_object_or_404(Solution, pk=solution_id) if (not (solution.author == request.user or in_group(request.user,'Trainer') or (solution.author.tutorial and solution.author.tutorial.tutors.filter(id=request.user.id)) )): return access_denied(request) if (request.method == "POST"): solution.copy() return HttpResponseRedirect(reverse('solution_list', args=[solution.task.id])) else: attestations = Attestation.objects.filter(solution__task=solution.task, author__tutored_tutorials=request.user.tutorial) attestationsPublished = attestations[0].published if attestations else False return object_detail(request, Solution.objects.all(), solution_id, extra_context={"attestationsPublished":attestationsPublished, "accept_all_solutions":get_settings().accept_all_solutions, "full":full}, template_object_name='solution' )
def solution_download_for_task(request, task_id): if (not in_group(request.user,'Trainer,Tutor')): return access_denied(request) task = get_object_or_404(Task, pk=task_id) solutions = task.solution_set.filter(final=True) if not in_group(request.user,'Trainer'): solutions = solutions.filter(author__tutorial__id__in=request.user.tutored_tutorials.values_list('id', flat=True)) zip_file = get_solutions_zip(solutions) response = HttpResponse(zip_file.read(), mimetype="application/zip") response['Content-Disposition'] = 'attachment; filename=Solutions.zip' return response
def solution_download_for_task(request, task_id,full): if not (request.user.is_tutor or request.user.is_trainer): return access_denied(request) task = get_object_or_404(Task, pk=task_id) solutions = task.solution_set.filter(final=True) if not request.user.is_trainer: solutions = solutions.filter(author__tutorial__id__in=request.user.tutored_tutorials.values_list('id', flat=True)) zip_file = get_solutions_zip(solutions,full) response = HttpResponse(zip_file.read(), content_type="application/zip") response['Content-Disposition'] = 'attachment; filename=Solutions.zip' return response
def solution_detail(request, solution_id, full): solution = get_object_or_404(Solution, pk=solution_id) if not (solution.author == request.user or request.user.is_trainer or request.user.is_superuser or (solution.author.tutorial and solution.author.tutorial.tutors.filter(id=request.user.id))): return access_denied(request) if full and not (request.user.is_trainer or request.user.is_tutor or request.user.is_superuser): return access_denied(request) accept_all_solutions = get_settings().accept_all_solutions if (request.method == "POST"): if solution.final or solution.testupload or solution.task.expired(): return access_denied(request) if not (solution.accepted or accept_all_solutions): return access_denied(request) solution.copy() return HttpResponseRedirect(reverse('solution_list', args=[solution.task.id])) else: attestations = Attestation.objects.filter(solution__task=solution.task, author__tutored_tutorials=request.user.tutorial) attestationsPublished = attestations[0].published if attestations else False htmlinjectors = [] if full: htmlinjectors = HtmlInjector.objects.filter(task = solution.task, inject_in_solution_full_view = True) else: htmlinjectors = HtmlInjector.objects.filter(task = solution.task, inject_in_solution_view = True) htmlinjector_snippets = [ injector.html_file.read() for injector in htmlinjectors ] return render(request, "solutions/solution_detail.html", { "solution": solution, "attestationsPublished": attestationsPublished, "accept_all_solutions": accept_all_solutions, "htmlinjector_snippets": htmlinjector_snippets, "full":full } )
def view_attestation(request, attestation_id): attest = get_object_or_404(Attestation, pk=attestation_id) may_modify = attest.author == request.user or request.user.is_trainer may_view = attest.solution.author == request.user or request.user.is_tutor or may_modify if not may_view: return access_denied(request) if request.method == "POST": if not may_modify: return access_denied(request) with transaction.atomic(): form = AttestationPreviewForm(request.POST, instance=attest) if form.is_valid(): form.save() if 'publish' in request.POST: if attest.solution.task.only_trainers_publish and not request.user.is_trainer: return access_denied(request) attest.publish(request, by = request.user) return HttpResponseRedirect(reverse('attestation_list', args=[attest.solution.task.id])) else: form = AttestationPreviewForm(instance=attest) submitable = may_modify and not attest.published withdrawable = may_modify and attest.published htmlinjectors = HtmlInjector.objects.filter(task = attest.solution.task, inject_in_attestation_view = True) htmlinjector_snippets = [ injector.html_file.read() for injector in htmlinjectors ] return render(request, "attestation/attestation_view.html", { "attest": attest, "submitable": submitable, "withdrawable": withdrawable, "form": form, "show_author": not get_settings().anonymous_attestation, "show_attestor": not get_settings().invisible_attestor, "htmlinjector_snippets": htmlinjector_snippets, } )
def rating_export(request): if not (request.user.is_trainer or request.user.is_coordinator or request.user.is_superuser): return access_denied(request) tasks = Task.objects.filter(submission_date__lt = datetime.datetime.now()).order_by('publication_date', 'submission_date') users = User.objects.filter(groups__name='User').filter(is_active=True).order_by('last_name', 'first_name') rating_list = user_task_attestation_map(users, tasks) response = HttpResponse(content_type='text/csv') response['Content-Disposition'] = 'attachment; filename=rating_export.csv' t = loader.get_template('attestation/rating_export.csv') c = {'rating_list': rating_list, 'tasks': tasks} #response.write(u'\ufeff') setting utf-8 BOM for Excel doesn't work response.write(t.render(c)) return response
def new_attestation_for_solution(request, solution_id): if not (in_group(request.user,'Tutor,Trainer') or request.user.is_superuser): return access_denied(request) solution = get_object_or_404(Solution, pk=solution_id) attest = Attestation(solution = solution, author = request.user) attest.save() for solutionFile in solution.solutionfile_set.filter(mime_type__startswith='text'): annotatedFile = AnnotatedSolutionFile(attestation = attest, solution_file=solutionFile, content=solutionFile.content()) annotatedFile.save() for rating in solution.task.rating_set.all(): ratingResult = RatingResult(attestation = attest, rating=rating) ratingResult.save() return HttpResponseRedirect(reverse('edit_attestation', args=[attest.id]))
def solution_detail(request, solution_id, full): solution = get_object_or_404(Solution, pk=solution_id) if not (solution.author == request.user or request.user.is_trainer or request.user.is_superuser or (solution.author.tutorial and solution.author.tutorial.tutors.filter(id=request.user.id))): return access_denied(request) if full and not (request.user.is_trainer or request.user.is_tutor or request.user.is_superuser): return access_denied(request) accept_all_solutions = get_settings().accept_all_solutions if (request.method == "POST"): if solution.final or solution.testupload or solution.task.expired(): return access_denied(request) if not (solution.accepted or accept_all_solutions): return access_denied(request) solution.copy() return HttpResponseRedirect( reverse('solution_list', args=[solution.task.id])) else: attestations = Attestation.objects.filter( solution__task=solution.task, author__tutored_tutorials=request.user.tutorial) attestationsPublished = attestations[ 0].published if attestations else False return render_to_response("solutions/solution_detail.html", { "solution": solution, "attestationsPublished": attestationsPublished, "accept_all_solutions": accept_all_solutions, "full": full }, context_instance=RequestContext(request))
def attestation_list(request, task_id): if not (in_group(request.user,'Tutor,Trainer') or request.user.is_superuser): return access_denied(request) task = Task.objects.get(pk=task_id) attestation_stats = [] if (in_group(request.user,'Trainer')): attestation_stats = [ {'tutor': tutor, 'unattested' : Solution.objects.filter(task = task, final=True, plagiarism = False, attestation = None,author__tutorial__tutors=tutor).count(), 'final': Attestation.objects.filter(solution__task = task,final=True,author=tutor).count(), 'nonfinal': Attestation.objects.filter(solution__task = task,final=False,author=tutor).count() } for tutor in User.objects.filter(groups__name="Tutor")] for entry in attestation_stats: entry['attested'] = entry['final']+entry['nonfinal'] entry['total'] = entry['final']+entry['nonfinal']+entry['unattested'] tutored_users = User.objects.filter(groups__name="User", is_active=True).order_by('last_name') if in_group(request.user,'Trainer') or request.user.is_superuser else None unattested_solutions = Solution.objects.filter(task = task, final=True, plagiarism = False, attestation = None) if in_group(request.user,'Tutor'): # the trainer sees them all unattested_solutions = unattested_solutions.filter(author__tutorial__in = request.user.tutored_tutorials.all()) my_attestations = Attestation.objects.filter(solution__task = task, author = request.user).order_by('-created') all_attestations_for_my_tutorials = Attestation.objects.filter(solution__task = task, solution__author__tutorial__in = request.user.tutored_tutorials.all()).order_by('-created') if (in_group(request.user,'Trainer')): # show all to trainer attestations_by_others = Attestation.objects.filter(solution__task = task).order_by('-created') solutions_with_plagiarism = Solution.objects.filter(task = task, plagiarism = True) else: # show from my toturials attestations_by_others = all_attestations_for_my_tutorials.exclude(author = request.user) solutions_with_plagiarism = Solution.objects.filter(task = task, plagiarism = True, author__tutorial__in = request.user.tutored_tutorials.all()) if request.method == "POST": for attestation in all_attestations_for_my_tutorials.filter(final = True, published = False): attestation.publish(request) all_attestations_published = all_attestations_for_my_tutorials.filter(published = False).count() == 0 all_attestations_final = all_attestations_for_my_tutorials.filter(final = False).count() == 0 show_author = not get_settings().anonymous_attestation or in_group(request.user,'Trainer') or published data = {'task':task, 'tutored_users':tutored_users, 'solutions_with_plagiarism':solutions_with_plagiarism, 'my_attestations':my_attestations, 'attestations_by_others':attestations_by_others, 'unattested_solutions':unattested_solutions, 'published': all_attestations_published, 'show_author': show_author, 'attestation_stats' : attestation_stats} return render_to_response("attestation/attestation_list.html", data, context_instance=RequestContext(request))
def view_attestation(request, attestation_id): attest = get_object_or_404(Attestation, pk=attestation_id) if not (attest.solution.author == request.user or in_group(request.user,'Tutor,Trainer') or request.user.is_superuser): return access_denied(request) if request.method == "POST": form = AttestationPreviewForm(request.POST, instance=attest) if form.is_valid(): form.save() if 'publish' in request.POST: attest.publish(request) return HttpResponseRedirect(reverse('attestation_list', args=[attest.solution.task.id])) else: form = AttestationPreviewForm(instance=attest) submitable = attest.author == request.user and not attest.published return render_to_response("attestation/attestation_view.html", {"attest": attest, 'submitable':submitable, 'form':form, 'show_author': not get_settings().anonymous_attestation}, context_instance=RequestContext(request))
def new_attestation_for_task(request, task_id): """ Start an attestation on a restrained random set of my tutored users """ if not (request.user.is_tutor or request.user.is_trainer or request.user.is_superuser): return access_denied(request) # fetch a solution of a user I have already attested in the past. users_i_have_attestated = User.objects.filter(solution__attestation__author = request.user) all_available_solutions = Solution.objects.filter(task__id = task_id, final=True, author__tutorial__in = request.user.tutored_tutorials.all(), attestation = None) if (not all_available_solutions): # if an other tutor just grabbed the last solution just go back to the list return HttpResponseRedirect(reverse('attestation_list', args=[task_id])) solutions = all_available_solutions.filter(author__in = users_i_have_attestated) if (solutions): solution = solutions[0] else: solution = all_available_solutions[0] return new_attestation_for_solution(request, solution.id)
def test_upload(request, task_id): if not request.user.is_trainer and not request.user.is_tutor and not request.user.is_superuser: return access_denied(request) task = get_object_or_404(Task,pk=task_id) if request.method == "POST": solution = Solution(task = task, author=request.user, testupload = True) formset = SolutionFormSet(request.POST, request.FILES, instance=solution) if formset.is_valid(): solution.save() formset.save() solution.check_solution(run_secret = True) return HttpResponseRedirect(reverse('solution_detail_full', args=[solution.id])) else: formset = SolutionFormSet() return render(request, "solutions/solution_test_upload.html", {"formset": formset, "task":task})
def new_attestation_for_solution(request, solution_id): if not (in_group(request.user, 'Tutor,Trainer') or request.user.is_superuser): return access_denied(request) solution = get_object_or_404(Solution, pk=solution_id) attest = Attestation(solution=solution, author=request.user) attest.save() for solutionFile in solution.solutionfile_set.filter( mime_type__startswith='text'): annotatedFile = AnnotatedSolutionFile(attestation=attest, solution_file=solutionFile, content=solutionFile.content()) annotatedFile.save() for rating in solution.task.rating_set.all(): ratingResult = RatingResult(attestation=attest, rating=rating) ratingResult.save() return HttpResponseRedirect(reverse('edit_attestation', args=[attest.id]))
def new_attestation_for_solution(request, solution_id, force_create = False): if not (request.user.is_tutor or request.user.is_trainer or request.user.is_superuser): return access_denied(request) solution = get_object_or_404(Solution, pk=solution_id) attestations = Attestation.objects.filter(solution = solution) if ((not force_create) and attestations): return render(request, "attestation/attestation_already_exists_for_solution.html", { 'task' : solution.task, 'attestations' : attestations, 'solution' : solution, 'show_author': not get_settings().anonymous_attestation }) attest = Attestation(solution = solution, author = request.user) attest.save() for solutionFile in solution.solutionfile_set.filter(mime_type__startswith='text'): annotatedFile = AnnotatedSolutionFile(attestation = attest, solution_file=solutionFile, content=solutionFile.content()) annotatedFile.save() for rating in solution.task.rating_set.all(): ratingResult = RatingResult(attestation = attest, rating=rating) ratingResult.save() return HttpResponseRedirect(reverse('edit_attestation', args=[attest.id]))
def checker_result_list(request,task_id): task = get_object_or_404(Task, pk=task_id) if (not in_group(request.user,'Trainer')): return access_denied(request) else: users_with_checkerresults = [(user,checkerresults,final_solution) \ for user in User.objects.filter(groups__name='User').order_by('mat_number') \ for final_solution in Solution.objects.filter(author=user,final=True,task=task).values() \ for checkerresults in [sorted(CheckerResult.objects.all().filter(solution=final_solution['id']),key=lambda result : result.checker.order)]] number_of_checker = None for checkerresults in users_with_checkerresults: if (number_of_checker and (len(checkerresults) != number_of_checker)): return acces_denied(request) #TODO: issue proper error message else: number_of_checker = len(checkerresults) _, prototype,_ = users_with_checkerresults[0] return render_to_response("solutions/checker_result_list.html", {"users_with_checkerresults": users_with_checkerresults, "prototype": prototype, "task":task},context_instance=RequestContext(request))
def checker_result_list(request,task_id): task = get_object_or_404(Task, pk=task_id) if not request.user.is_trainer and not request.user.is_superuser: return access_denied(request) else: users_with_checkerresults = [(user,dict(checkerresults),final_solution) \ for user in User.objects.filter(groups__name='User').order_by('mat_number') \ for final_solution in Solution.objects.filter(author=user,final=True,task=task).values() \ for checkerresults in [[ (result.checker, result) for result in CheckerResult.objects.all().filter(solution=final_solution['id'])]] ] checkers_seen = set([]) for _, results,_ in users_with_checkerresults: checkers_seen |= set(results.keys()) checkers_seen = sorted(checkers_seen, key=lambda checker: checker.order) for i,(user,results,final_solution) in enumerate(users_with_checkerresults): users_with_checkerresults[i] = (user, [results[checker] if checker in results else None for (checker) in checkers_seen], final_solution) return render(request, "solutions/checker_result_list.html", {"users_with_checkerresults": users_with_checkerresults, 'checkers_seen':checkers_seen, "task":task})
def rating_overview(request): full_form = request.user.is_trainer or request.user.is_superuser if not (full_form or (request.user.is_coordinator and request.method != "POST")): return access_denied(request) tasks = Task.objects.filter(submission_date__lt = datetime.datetime.now()) users = User.objects.filter(groups__name='User').filter(is_active=True).order_by('last_name', 'first_name', 'id') # corresponding user to user_id_list in reverse order! important for easy displaying in template rev_users = users.reverse() users = users.select_related("user_ptr", "user_ptr__groups__name", "user_ptr__is_active", "user_ptr__user_id") FinalGradeFormSet = modelformset_factory(User, fields=('final_grade',), extra=0) if request.method == "POST": final_grade_option_form = FinalGradeOptionForm(request.POST, instance=get_settings()) if final_grade_option_form.is_valid(): final_grade_option_form.save() if 'save' in request.POST: # also save final grades final_grade_formset = FinalGradeFormSet(request.POST, request.FILES, queryset=rev_users) publish_final_grade_form = PublishFinalGradeForm(request.POST, instance=get_settings()) if final_grade_formset.is_valid() and publish_final_grade_form.is_valid(): final_grade_formset.save() publish_final_grade_form.save() else: final_grade_formset = FinalGradeFormSet(queryset=rev_users) publish_final_grade_form = PublishFinalGradeForm(instance=get_settings()) else: # all 3 forms are created without request input final_grade_option_form = FinalGradeOptionForm(instance=get_settings()) final_grade_formset = FinalGradeFormSet(queryset=rev_users) publish_final_grade_form = PublishFinalGradeForm(instance=get_settings()) rating_list = user_task_attestation_map(users, tasks) return render(request, "attestation/rating_overview.html", {'rating_list': rating_list, 'tasks': tasks, 'final_grade_formset': final_grade_formset, 'final_grade_option_form': final_grade_option_form, 'publish_final_grade_form': publish_final_grade_form, 'full_form': full_form})
def statistics(request, task_id): task = get_object_or_404(Task, pk=task_id) if not (request.user.is_trainer or request.user.is_tutor or request.user.is_superuser): return access_denied(request) final_solutions = task.solution_set.filter(final=True) unfinal_solutions = task.solution_set.filter(final=False) user = Group.objects.get(name='User').user_set.filter(is_active=True) tutorials = request.user.tutored_tutorials.all() if request.user.is_tutor: final_solutions = final_solutions.filter(author__tutorial__in = tutorials) unfinal_solutions = unfinal_solutions.filter(author__tutorial__in = tutorials) user = User.objects.filter(tutorial__in = tutorials) final_solution_count = final_solutions.count() user_count = user.count() submissions = [] submissions_final = [] acc_submissions = [0] creation_dates = [dict['creation_date'].date() for dict in unfinal_solutions.values('creation_date')] creation_dates_final = [dict['creation_date'].date() for dict in final_solutions.values('creation_date')] for date in daterange(task.publication_date.date(), min(task.submission_date.date(), datetime.date.today())): submissions.append(creation_dates.count(date)) submissions_final.append(creation_dates_final.count(date)) acc_submissions.append(acc_submissions[-1]+submissions_final[-1]) acc_submissions.pop(0) if (user_count > 0): acc_submissions = [submissions/user_count for submissions in acc_submissions] else: acc_submissions = 0; creation_times = [[(dict['creation_date'].time().hour*3600+dict['creation_date'].time().minute*60)*1000, dict['creation_date'].weekday()] for dict in unfinal_solutions.values('creation_date')] creation_times_final = [[(dict['creation_date'].time().hour*3600+dict['creation_date'].time().minute*60)*1000, dict['creation_date'].weekday()] for dict in final_solutions.values('creation_date')] if request.user.is_trainer: attestations = Attestation.objects.filter(solution__task__id=task.id, final=True, published=False).aggregate(final=Count('id')) attestations.update( Attestation.objects.filter(solution__task__id=task.id, final=True, published=True).aggregate(published=Count('id')) ) else: # Tutor attestations = Attestation.objects.filter(solution__task__id=task.id, final=True, published=False, author__tutored_tutorials__in = tutorials).aggregate(final=Count('id')) attestations.update( Attestation.objects.filter(solution__task__id=task.id, final=True, published=True, author__tutored_tutorials__in = tutorials).aggregate(published=Count('id'))) attestations['all'] = final_solution_count all_items = task.final_grade_rating_scale.ratingscaleitem_set.values_list('name', 'position') final_grade_rating_scale_items = "['" + "','".join([name.strip() for (name, position) in all_items]) + "']" all_ratings = [] if request.user.is_trainer: # Each Tutorials ratings for t in Tutorial.objects.all(): all_ratings.append({'title' : "Final Grades for Students in Tutorial %s" % str(t), 'desc' : "This chart shows the distribution of final grades for students from Tutorial %s. Plagiarism is excluded." % str(t), 'ratings' : RatingScaleItem.objects.filter(attestation__solution__task=task_id, attestation__solution__plagiarism=False, attestation__final=True, attestation__solution__author__tutorial = t)}) for t in User.objects.filter(groups__name='Tutor'): all_ratings.append({'title' : "Final Grades for Attestations created by %s" % str(t), 'desc' : "This chart shows the distribution of final grades for Attestations created by %s. Plagiarism is excluded." % str(t), 'ratings' : RatingScaleItem.objects.filter(attestation__solution__task=task_id, attestation__solution__plagiarism=False, attestation__final=True, attestation__author__id = t.id)}) else: # The Tutorials ratings all_ratings.append( {'title' : "Final grades (My Tutorials)", 'desc' : "This chart shows the distribution of final grades for students from any of your tutorials. Plagiarism is excluded.", 'ratings' : RatingScaleItem.objects.filter(attestation__solution__task=task_id, attestation__solution__plagiarism=False, attestation__final=True, attestation__solution__author__tutorial__in = tutorials)}) all_ratings.append( {'title' : "Final grades (My Attestations)", 'desc' : "This chart shows the distribution of final grades for your attestations. Plagiarism is excluded.", 'ratings' : RatingScaleItem.objects.filter(attestation__solution__task=task_id, attestation__solution__plagiarism=False, attestation__final=True, attestation__author__id = request.user.id)}) # Overall ratings all_ratings.append({'title' : "Final grades (overall)", 'desc' : "This chart shows the distribution of final grades for all students. Plagiarism is excluded.", 'ratings' : RatingScaleItem.objects.filter(attestation__solution__task=task_id, attestation__solution__plagiarism=False, attestation__final=True)}) for i, r in enumerate(all_ratings): all_ratings[i]['ratings'] = [list(rating) for rating in r['ratings'].annotate(Count('id')).values_list('position', 'id__count')] has_runtimes = False runtimes = [] for i, checker in enumerate(task.get_checkers()): checker_runtimes = [] for result in checker.results.order_by('creation_date').filter(runtime__gt = 0): has_runtimes = True checker_runtimes.append({ 'date': result.creation_date, 'value': result.runtime}) if checker_runtimes: first = checker_runtimes[0] last = checker_runtimes[-1] n = 20 # number of buckets buckets = [[] for x in range(n)] span = last['date'] - first['date'] + datetime.timedelta(seconds=1) for r in checker_runtimes: i = timedelta_diff((r['date'] - first['date'])*n, span) buckets[i].append(r['value']) medians = [] for i in range(n): date = first['date'] + ((span//2)*(2*i+1) // n); if buckets[i]: buckets[i].sort() value = buckets[i][((len(buckets[i])+1)//2)-1] else: value = None medians.append({'date': date, 'value': value}); runtimes.append({ 'checker': "%d: %s" % (i, checker.title()), 'runtimes': checker_runtimes, 'medians': medians }) return render(request, "attestation/statistics.html", {'task': task, 'user_count': user_count, 'solution_count': final_solution_count, 'submissions': submissions, 'submissions_final': submissions_final, 'creation_times': creation_times, 'creation_times_final': creation_times_final, 'acc_submissions': acc_submissions, 'attestations': attestations, 'final_grade_rating_scale_items': final_grade_rating_scale_items, 'all_ratings': all_ratings, 'runtimes': runtimes, 'has_runtime_chart': has_runtimes, })
def attestation_list(request, task_id): if not (request.user.is_tutor or request.user.is_trainer or request.user.is_superuser): return access_denied(request) task = Task.objects.get(pk=task_id) attestation_stats = [] if request.user.is_trainer: attestation_stats = [ {'tutor': tutor, 'unattested' : Solution.objects.filter(task = task, final=True, plagiarism = False, attestation = None,author__tutorial__tutors=tutor).count(), 'final': Attestation.objects.filter(solution__task = task,final=True,author=tutor).count(), 'nonfinal': Attestation.objects.filter(solution__task = task,final=False,author=tutor).count() } for tutor in User.objects.filter(groups__name="Tutor")] for entry in attestation_stats: entry['attested'] = entry['final']+entry['nonfinal'] entry['total'] = entry['final']+entry['nonfinal']+entry['unattested'] tutored_users = User.objects.filter(groups__name="User", is_active=True).order_by('last_name') if request.user.is_trainer or request.user.is_superuser else None unattested_solutions = Solution.objects.filter(task = task, final=True, plagiarism = False, attestation = None) if request.user.is_tutor: # the trainer sees them all unattested_solutions = unattested_solutions.filter(author__tutorial__in = request.user.tutored_tutorials.all()) all_attestations = Attestation.objects \ .filter(solution__task = task) \ .order_by('-created') \ .select_related('solution', 'solution__author', 'author') my_attestations = \ all_attestations \ .filter(author = request.user) \ all_attestations_for_my_tutorials = \ all_attestations \ .filter(solution__author__tutorial__in = request.user.tutored_tutorials.all()) \ attestations_by_others = \ all_attestations_for_my_tutorials \ .exclude(author = request.user) # for the warning about solutions marked as plagiarism if request.user.is_trainer: # show all to trainer solutions_with_plagiarism = Solution.objects.filter(task = task, plagiarism = True) else: # show from my turials to tutors solutions_with_plagiarism = Solution.objects.filter(task = task, plagiarism = True, author__tutorial__in = request.user.tutored_tutorials.all()) # the trainer sees all if not request.user.is_trainer: all_attestations = None publishable_tutorial = all_attestations_for_my_tutorials.filter(final = True, published = False) publishable_all = None if request.user.is_trainer: publishable_all = all_attestations.filter(final = True, published = False) if request.method == "POST": if request.POST['what'] == 'tutorial': if not request.user.is_tutor: return access_denied(request) if task.only_trainers_publish: return access_denied(request) for attestation in publishable_tutorial: attestation.publish(request, request.user) return HttpResponseRedirect(reverse('attestation_list', args=[task_id])) if request.POST['what'] == 'all': if not request.user.is_trainer: return access_denied(request) for attestation in publishable_all: attestation.publish(request, request.user) return HttpResponseRedirect(reverse('attestation_list', args=[task_id])) show_author = not get_settings().anonymous_attestation or request.user.is_tutor or request.user.is_trainer or published data = {'task':task, 'tutored_users':tutored_users, 'solutions_with_plagiarism':solutions_with_plagiarism, 'my_attestations':my_attestations, 'attestations_by_others':attestations_by_others, 'all_attestations':all_attestations, 'unattested_solutions':unattested_solutions, 'publishable_tutorial': publishable_tutorial, 'publishable_all': publishable_all, 'show_author': show_author, 'attestation_stats' : attestation_stats} return render_to_response("attestation/attestation_list.html", data, context_instance=RequestContext(request))
def statistics(request,task_id): task = get_object_or_404(Task, pk=task_id) if not (request.user.is_trainer or request.user.is_tutor or request.user.is_superuser): return access_denied(request) final_solutions = task.solution_set.filter(final=True) unfinal_solutions = task.solution_set.filter(final=False) user = Group.objects.get(name='User').user_set.filter(is_active=True) tutorials = request.user.tutored_tutorials.all() if request.user.is_tutor: final_solutions = final_solutions.filter(author__tutorial__in = tutorials) unfinal_solutions = unfinal_solutions.filter(author__tutorial__in = tutorials) user = User.objects.filter(tutorial__in = tutorials) final_solution_count = final_solutions.count() user_count = user.count() submissions = [] submissions_final = [] acc_submissions = [0] creation_dates = map(lambda dict:dict['creation_date'].date(), unfinal_solutions.values('creation_date')) creation_dates_final = map(lambda dict:dict['creation_date'].date(), final_solutions.values('creation_date')) for date in daterange(task.publication_date.date(), min(task.submission_date.date(), datetime.date.today())): submissions.append(creation_dates.count(date)) submissions_final.append(creation_dates_final.count(date)) acc_submissions.append(acc_submissions[-1]+submissions_final[-1]) acc_submissions.pop(0) if (user_count > 0): acc_submissions = map(lambda submissions: float(submissions)/user_count, acc_submissions) else: acc_submissions = 0; creation_times = map(lambda dict:[(dict['creation_date'].time().hour*3600+dict['creation_date'].time().minute*60)*1000, dict['creation_date'].weekday()], unfinal_solutions.values('creation_date')) creation_times_final = map(lambda dict:[(dict['creation_date'].time().hour*3600+dict['creation_date'].time().minute*60)*1000, dict['creation_date'].weekday()], final_solutions.values('creation_date')) if request.user.is_trainer: attestations = Attestation.objects.filter(solution__task__id=task.id, final=True, published=False).aggregate(final=Count('id')) attestations.update( Attestation.objects.filter(solution__task__id=task.id, final=True, published=True).aggregate(published=Count('id')) ) else: # Tutor attestations = Attestation.objects.filter(solution__task__id=task.id, final=True, published=False, author__tutored_tutorials__in = tutorials).aggregate(final=Count('id')) attestations.update( Attestation.objects.filter(solution__task__id=task.id, final=True, published=True, author__tutored_tutorials__in = tutorials).aggregate(published=Count('id'))) attestations['all'] = final_solution_count all_items = task.final_grade_rating_scale.ratingscaleitem_set.values_list('name','position') final_grade_rating_scale_items = "['" + "','".join([name.strip() for (name,position) in all_items]) + "']" all_ratings = [] if request.user.is_trainer: # Each Tutorials ratings for t in Tutorial.objects.all(): all_ratings.append({'title' : u"Final Grades for Students in Tutorial %s" % unicode(t), 'desc' : u"This chart shows the distribution of final grades for students from Tutorial %s. Plagiarism is excluded." % unicode(t), 'ratings' : RatingScaleItem.objects.filter(attestation__solution__task=task_id, attestation__solution__plagiarism=False, attestation__final=True, attestation__solution__author__tutorial = t)}) for t in User.objects.filter(groups__name='Tutor'): all_ratings.append({'title' : u"Final Grades for Attestations created by %s" % unicode(t), 'desc' : u"This chart shows the distribution of final grades for Attestations created by %s. Plagiarism is excluded." % unicode(t), 'ratings' : RatingScaleItem.objects.filter(attestation__solution__task=task_id, attestation__solution__plagiarism=False, attestation__final=True, attestation__author__id = t.id)}) else: # The Tutorials ratings all_ratings.append( {'title' : u"Final grades (My Tutorials)", 'desc' : u"This chart shows the distribution of final grades for students from any your tutorials. Plagiarism is excluded.", 'ratings' : RatingScaleItem.objects.filter(attestation__solution__task=task_id, attestation__solution__plagiarism=False, attestation__final=True, attestation__solution__author__tutorial__in = tutorials)}) all_ratings.append( {'title' : u"Final grades (My Attestations)", 'desc' : u"This chart shows the distribution of final grades for your attestations. Plagiarism is excluded.", 'ratings' : RatingScaleItem.objects.filter(attestation__solution__task=task_id, attestation__solution__plagiarism=False, attestation__final=True, attestation__author__id = request.user.id)}) # Overall ratings all_ratings.append( {'title' : u"Final grades (overall)", 'desc' : u"This chart shows the distribution of final grades for all students. Plagiarism is excluded.", 'ratings' : RatingScaleItem.objects.filter(attestation__solution__task=task_id, attestation__solution__plagiarism=False, attestation__final=True)}) for i,r in enumerate(all_ratings): all_ratings[i]['ratings'] = [list(rating) for rating in r['ratings'].annotate(Count('id')).values_list('position','id__count')] has_runtimes = False runtimes = [] for i, checker in enumerate(task.get_checkers()): checker_runtimes = [] for result in checker.results.filter(runtime__gt = 0): has_runtimes = True checker_runtimes.append({ 'date': result.creation_date, 'value': result.runtime}) runtimes.append({ 'checker': "%d: %s" % (i, checker.title()), 'runtimes': checker_runtimes }) return render_to_response("attestation/statistics.html", {'task': task, 'user_count': user_count, 'solution_count': final_solution_count, 'submissions': submissions, 'submissions_final': submissions_final, 'creation_times': creation_times, 'creation_times_final': creation_times_final, 'acc_submissions': acc_submissions, 'attestations': attestations, 'final_grade_rating_scale_items': final_grade_rating_scale_items, 'all_ratings': all_ratings, 'runtimes': runtimes, 'has_runtime_chart': has_runtimes, }, context_instance=RequestContext(request))
def attestation_list(request, task_id): if not (request.user.is_tutor or request.user.is_trainer or request.user.is_superuser): return access_denied(request) task = Task.objects.get(pk=task_id) attestation_stats = [] no_tutorial_stats = {} if request.user.is_trainer: attestation_stats = [ tutor_attestation_stats(task, tutor) for tutor in User.objects.filter(groups__name="Tutor")] no_tutorial_stats = tutor_attestation_stats(task, None) tutored_users = User.objects.filter(groups__name="User", is_active=True).order_by('last_name') if request.user.is_trainer or request.user.is_superuser else None unattested_solutions = Solution.objects.filter(task = task, final=True, attestation = None) if request.user.is_tutor: # the trainer sees them all unattested_solutions = unattested_solutions.filter(author__tutorial__in = request.user.tutored_tutorials.all()) all_attestations = Attestation.objects \ .filter(solution__task = task) \ .order_by('-created') \ .select_related('solution', 'solution__author', 'author') my_attestations = all_attestations \ .filter(author = request.user) \ all_attestations_for_my_tutorials = all_attestations \ .filter(solution__author__tutorial__in = request.user.tutored_tutorials.all()) \ attestations_by_others = all_attestations_for_my_tutorials \ .exclude(author = request.user) # for the warning about solutions marked as plagiarism if request.user.is_trainer: # show all to trainer solutions_with_plagiarism = Solution.objects.filter(task = task, plagiarism = True) else: # show from my turials to tutors solutions_with_plagiarism = Solution.objects.filter(task = task, plagiarism = True, author__tutorial__in = request.user.tutored_tutorials.all()) # the trainer sees all if not request.user.is_trainer: all_attestations = None publishable_tutorial = all_attestations_for_my_tutorials.filter(final = True, published = False) publishable_all = None if request.user.is_trainer: publishable_all = all_attestations.filter(final = True, published = False) if request.method == "POST": if request.POST['what'] == 'tutorial': if not request.user.is_tutor: return access_denied(request) if task.only_trainers_publish: return access_denied(request) for attestation in publishable_tutorial: attestation.publish(request, request.user) return HttpResponseRedirect(reverse('attestation_list', args=[task_id])) if request.POST['what'] == 'all': if not request.user.is_trainer: return access_denied(request) for attestation in publishable_all: attestation.publish(request, request.user) return HttpResponseRedirect(reverse('attestation_list', args=[task_id])) show_author = not get_settings().anonymous_attestation or request.user.is_tutor or request.user.is_trainer or published data = {'task': task, 'tutored_users': tutored_users, 'solutions_with_plagiarism': solutions_with_plagiarism, 'my_attestations': my_attestations, 'attestations_by_others': attestations_by_others, 'all_attestations': all_attestations, 'unattested_solutions': unattested_solutions, 'publishable_tutorial': publishable_tutorial, 'publishable_all': publishable_all, 'show_author': show_author, 'attestation_stats': attestation_stats, 'no_tutorial_stats': no_tutorial_stats,} return render(request, "attestation/attestation_list.html", data)