From ce995e06e3509a1340061c51dfa08a65c69eef66 Mon Sep 17 00:00:00 2001 From: prathamesh Date: Mon, 14 Aug 2017 12:10:42 +0530 Subject: Front-end modification for improved code server Added JQuery to handle request. Sends ajax request and gets json as response. json contains token i.e uid which is answer id. Using uid, an ajax request is sent after every 2 secs till the server gives the desire result. If the code result has error then html is written on the document. If the result has correct answer then next question is displayed. *includes function for string will not work for older browers. Will substitute with a different function in next commit. --- yaksh/views.py | 79 ++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 52 insertions(+), 27 deletions(-) (limited to 'yaksh/views.py') diff --git a/yaksh/views.py b/yaksh/views.py index c10ba6a..f6243a7 100644 --- a/yaksh/views.py +++ b/yaksh/views.py @@ -4,7 +4,7 @@ import os from datetime import datetime, timedelta import collections import csv -from django.http import HttpResponse +from django.http import HttpResponse, JsonResponse from django.core.urlresolvers import reverse from django.contrib.auth import login, logout, authenticate from django.shortcuts import render_to_response, get_object_or_404, redirect @@ -30,6 +30,7 @@ try: except ImportError: from io import BytesIO as string_io # Local imports. +from yaksh.code_server import get_result, SERVER_POOL_PORT from yaksh.models import get_model_class, Quiz, Question, QuestionPaper, QuestionSet, Course from yaksh.models import Profile, Answer, AnswerPaper, User, TestCase, FileUpload,\ has_profile, StandardTestCase, McqTestCase,\ @@ -539,6 +540,7 @@ def check(request, q_id, attempt_num=None, questionpaper_id=None): new_answer = Answer(question=current_question, answer=user_answer, correct=False, error=json.dumps([])) new_answer.save() + uid = new_answer.id paper.answers.add(new_answer) # If we were not skipped, we were asked to check. For any non-mcq # questions, we obtain the results via XML-RPC with the code executed @@ -547,38 +549,61 @@ def check(request, q_id, attempt_num=None, questionpaper_id=None): if current_question.type == 'code' or \ current_question.type == 'upload' else None result = paper.validate_answer(user_answer, current_question, - json_data + json_data, uid ) - if result.get('success'): - new_answer.marks = (current_question.points * result['weight'] / - current_question.get_maximum_test_case_weight()) \ - if current_question.partial_grading and \ - current_question.type == 'code' or current_question.type == 'upload' \ - else current_question.points - new_answer.correct = result.get('success') - error_message = None - new_answer.error = json.dumps(result.get('error')) - next_question = paper.add_completed_question(current_question.id) + if current_question.type in ['code', 'upload']: + return JsonResponse(result) else: - new_answer.marks = (current_question.points * result['weight'] / - current_question.get_maximum_test_case_weight()) \ - if current_question.partial_grading and \ - current_question.type == 'code' or current_question.type == 'upload' \ - else 0 - error_message = result.get('error') if current_question.type == 'code' \ - or current_question.type == 'upload' else None - new_answer.error = json.dumps(result.get('error')) - next_question = current_question if current_question.type == 'code' \ - or current_question.type == 'upload' \ - else paper.add_completed_question(current_question.id) - new_answer.save() - paper.update_marks('inprogress') - paper.set_end_time(timezone.now()) - return show_question(request, next_question, paper, error_message) + next_question, error_message, paper = _update_paper(request, uid, result) + return show_question(request, next_question, paper, error_message) else: return show_question(request, current_question, paper) +@csrf_exempt +def get_results(request, uid): + url = 'http://localhost:%s' % SERVER_POOL_PORT + result_state = get_result(url, uid) + result = json.loads(result_state.get('result')) + next_question, error_message, paper = _update_paper(request, uid, result) + result['status'] = result_state.get('status') + if result['status']== 'done': + return show_question(request, next_question, paper, error_message) + return JsonResponse(result) + + +def _update_paper(request, uid, result): + new_answer = Answer.objects.get(id=uid) + current_question = new_answer.question + paper = new_answer.answerpaper_set.first() + + if result.get('success'): + new_answer.marks = (current_question.points * result['weight'] / + current_question.get_maximum_test_case_weight()) \ + if current_question.partial_grading and \ + current_question.type == 'code' or current_question.type == 'upload' \ + else current_question.points + new_answer.correct = result.get('success') + error_message = None + new_answer.error = json.dumps(result.get('error')) + next_question = paper.add_completed_question(current_question.id) + else: + new_answer.marks = (current_question.points * result['weight'] / + current_question.get_maximum_test_case_weight()) \ + if current_question.partial_grading and \ + current_question.type == 'code' or current_question.type == 'upload' \ + else 0 + error_message = result.get('error') if current_question.type == 'code' \ + or current_question.type == 'upload' else None + new_answer.error = json.dumps(result.get('error')) + next_question = current_question if current_question.type == 'code' \ + or current_question.type == 'upload' \ + else paper.add_completed_question(current_question.id) + new_answer.save() + paper.update_marks('inprogress') + paper.set_end_time(timezone.now()) + return next_question, error_message, paper + def quit(request, reason=None, attempt_num=None, questionpaper_id=None): """Show the quit page when the user logs out.""" -- cgit From 49615e5a24ecfdd0b22bae080e7f9bb2507bbfd7 Mon Sep 17 00:00:00 2001 From: prathamesh Date: Mon, 14 Aug 2017 14:51:39 +0530 Subject: To handle unknown status response from code server --- yaksh/views.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'yaksh/views.py') diff --git a/yaksh/views.py b/yaksh/views.py index f6243a7..0e9835d 100644 --- a/yaksh/views.py +++ b/yaksh/views.py @@ -562,12 +562,13 @@ def check(request, q_id, attempt_num=None, questionpaper_id=None): @csrf_exempt def get_results(request, uid): + result = {} url = 'http://localhost:%s' % SERVER_POOL_PORT result_state = get_result(url, uid) - result = json.loads(result_state.get('result')) - next_question, error_message, paper = _update_paper(request, uid, result) result['status'] = result_state.get('status') - if result['status']== 'done': + if result['status'] == 'done': + result = json.loads(result_state.get('result')) + next_question, error_message, paper = _update_paper(request, uid, result) return show_question(request, next_question, paper, error_message) return JsonResponse(result) -- cgit From f730a531cf041620209abb812792080cb2d63b4d Mon Sep 17 00:00:00 2001 From: prathamesh Date: Mon, 14 Aug 2017 22:33:02 +0530 Subject: Changes related to front-end Removed snippet append in the check view as snippet is not posted in request. Added an overlay when an user submits a code, with a status text on it. This is to block user from triggering any other event when JS is running. Overlay disappears when JS complete its execution. On time out a request is posted via JS, it receives a JSON response but cannot display user the error as time is over. So in such case, the django itself handles the result and does not return JSONv response. --- yaksh/views.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'yaksh/views.py') diff --git a/yaksh/views.py b/yaksh/views.py index 0e9835d..fc550ed 100644 --- a/yaksh/views.py +++ b/yaksh/views.py @@ -475,7 +475,6 @@ def check(request, q_id, attempt_num=None, questionpaper_id=None): current_question = get_object_or_404(Question, pk=q_id) if request.method == 'POST': - snippet_code = request.POST.get('snippet') # Add the answer submitted, regardless of it being correct or not. if current_question.type == 'mcq': user_answer = request.POST.get('answer') @@ -532,8 +531,7 @@ def check(request, q_id, attempt_num=None, questionpaper_id=None): next_q = paper.add_completed_question(current_question.id) return show_question(request, next_q, paper) else: - user_code = request.POST.get('answer') - user_answer = snippet_code + "\n" + user_code if snippet_code else user_code + user_answer = request.POST.get('answer') if not user_answer: msg = ["Please submit a valid option or code"] return show_question(request, current_question, paper, notification=msg) @@ -552,7 +550,15 @@ def check(request, q_id, attempt_num=None, questionpaper_id=None): json_data, uid ) if current_question.type in ['code', 'upload']: - return JsonResponse(result) + if paper.time_left() <= 0: + url = 'http://localhost:%s' % SERVER_POOL_PORT + result = get_result(url, uid, block=True) + result = json.loads(result.get('result')) + next_question, error_message, paper = _update_paper(request, uid, + result) + return show_question(request, next_question, paper, error_message) + else: + return JsonResponse(result) else: next_question, error_message, paper = _update_paper(request, uid, result) return show_question(request, next_question, paper, error_message) -- cgit From 3d9bce5471d04bf50e03155d3cd67bdae44a4fcc Mon Sep 17 00:00:00 2001 From: prathamesh Date: Thu, 31 Aug 2017 16:28:57 +0530 Subject: updated travis config and added print to debug on travis --- yaksh/views.py | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'yaksh/views.py') diff --git a/yaksh/views.py b/yaksh/views.py index fc550ed..dd50d24 100644 --- a/yaksh/views.py +++ b/yaksh/views.py @@ -475,6 +475,7 @@ def check(request, q_id, attempt_num=None, questionpaper_id=None): current_question = get_object_or_404(Question, pk=q_id) if request.method == 'POST': + print("check post") # Add the answer submitted, regardless of it being correct or not. if current_question.type == 'mcq': user_answer = request.POST.get('answer') @@ -558,6 +559,8 @@ def check(request, q_id, attempt_num=None, questionpaper_id=None): result) return show_question(request, next_question, paper, error_message) else: + print("post response") + print(result) return JsonResponse(result) else: next_question, error_message, paper = _update_paper(request, uid, result) @@ -576,6 +579,7 @@ def get_results(request, uid): result = json.loads(result_state.get('result')) next_question, error_message, paper = _update_paper(request, uid, result) return show_question(request, next_question, paper, error_message) + print("get result") return JsonResponse(result) -- cgit From e2c65655dcdc5558cfb4ab668c3012024d27ac75 Mon Sep 17 00:00:00 2001 From: prathamesh Date: Fri, 1 Sep 2017 16:51:37 +0530 Subject: Removed all the checkpoints set for selenium tests on travis javascript strings includes method changed to indexOf, as includes belongs to ES6. This was the main reason for failure of selenium tests on travis. --- yaksh/views.py | 4 ---- 1 file changed, 4 deletions(-) (limited to 'yaksh/views.py') diff --git a/yaksh/views.py b/yaksh/views.py index dd50d24..fc550ed 100644 --- a/yaksh/views.py +++ b/yaksh/views.py @@ -475,7 +475,6 @@ def check(request, q_id, attempt_num=None, questionpaper_id=None): current_question = get_object_or_404(Question, pk=q_id) if request.method == 'POST': - print("check post") # Add the answer submitted, regardless of it being correct or not. if current_question.type == 'mcq': user_answer = request.POST.get('answer') @@ -559,8 +558,6 @@ def check(request, q_id, attempt_num=None, questionpaper_id=None): result) return show_question(request, next_question, paper, error_message) else: - print("post response") - print(result) return JsonResponse(result) else: next_question, error_message, paper = _update_paper(request, uid, result) @@ -579,7 +576,6 @@ def get_results(request, uid): result = json.loads(result_state.get('result')) next_question, error_message, paper = _update_paper(request, uid, result) return show_question(request, next_question, paper, error_message) - print("get result") return JsonResponse(result) -- cgit From 75a06dee77b5cc470c693648ee31431898e97d47 Mon Sep 17 00:00:00 2001 From: prathamesh Date: Sat, 2 Sep 2017 02:56:48 +0530 Subject: Resolved Conflicts --- yaksh/views.py | 44 +++++--------------------------------------- 1 file changed, 5 insertions(+), 39 deletions(-) (limited to 'yaksh/views.py') diff --git a/yaksh/views.py b/yaksh/views.py index 66ad1fa..af7951f 100644 --- a/yaksh/views.py +++ b/yaksh/views.py @@ -31,18 +31,7 @@ except ImportError: from io import BytesIO as string_io import re # Local imports. -<<<<<<< HEAD from yaksh.code_server import get_result, SERVER_POOL_PORT -from yaksh.models import get_model_class, Quiz, Question, QuestionPaper, QuestionSet, Course -from yaksh.models import Profile, Answer, AnswerPaper, User, TestCase, FileUpload,\ - StandardTestCase, McqTestCase,\ - StdIOBasedTestCase, HookTestCase, IntegerTestCase,\ - FloatTestCase, StringTestCase -from yaksh.forms import UserRegisterForm, UserLoginForm, QuizForm,\ - QuestionForm, RandomQuestionForm,\ - QuestionFilterForm, CourseForm, ProfileForm, UploadFileForm,\ - get_object_form, FileForm, QuestionPaperForm -======= from yaksh.models import ( Answer, AnswerPaper, AssignmentUpload, Course, FileUpload, FloatTestCase, HookTestCase, IntegerTestCase, McqTestCase, Profile, @@ -55,9 +44,7 @@ from yaksh.forms import ( RandomQuestionForm, QuestionFilterForm, CourseForm, ProfileForm, UploadFileForm, get_object_form, FileForm, QuestionPaperForm ) ->>>>>>> 97a96d1678cb55b95ed14eb9a2b2790415d30abc from .settings import URL_ROOT -from yaksh.models import AssignmentUpload from .file_utils import extract_files from .send_emails import send_user_mail, generate_activation_key, send_bulk_mail from .decorators import email_verified, has_profile @@ -616,12 +603,11 @@ def check(request, q_id, attempt_num=None, questionpaper_id=None): # questions, we obtain the results via XML-RPC with the code executed # safely in a separate process (the code_server.py) running as nobody. json_data = current_question.consolidate_answer_data(user_answer, user) \ -<<<<<<< HEAD - if current_question.type == 'code' or \ - current_question.type == 'upload' else None - result = paper.validate_answer(user_answer, current_question, - json_data, uid - ) + if current_question.type == 'code' or \ + current_question.type == 'upload' else None + result = paper.validate_answer( + user_answer, current_question, json_data, uid + ) if current_question.type in ['code', 'upload']: if paper.time_left() <= 0: url = 'http://localhost:%s' % SERVER_POOL_PORT @@ -632,23 +618,6 @@ def check(request, q_id, attempt_num=None, questionpaper_id=None): return show_question(request, next_question, paper, error_message) else: return JsonResponse(result) -======= - if current_question.type == 'code' or \ - current_question.type == 'upload' else None - result = paper.validate_answer( - user_answer, current_question, json_data - ) - if result.get('success'): - new_answer.marks = (current_question.points * result['weight'] / - current_question.get_maximum_test_case_weight()) \ - if current_question.partial_grading and \ - current_question.type == 'code' or current_question.type == 'upload' \ - else current_question.points - new_answer.correct = result.get('success') - error_message = None - new_answer.error = json.dumps(result.get('error')) - next_question = paper.add_completed_question(current_question.id) ->>>>>>> 97a96d1678cb55b95ed14eb9a2b2790415d30abc else: next_question, error_message, paper = _update_paper(request, uid, result) return show_question(request, next_question, paper, error_message) @@ -656,7 +625,6 @@ def check(request, q_id, attempt_num=None, questionpaper_id=None): return show_question(request, current_question, paper) -<<<<<<< HEAD @csrf_exempt def get_results(request, uid): result = {} @@ -703,8 +671,6 @@ def _update_paper(request, uid, result): return next_question, error_message, paper -======= ->>>>>>> 97a96d1678cb55b95ed14eb9a2b2790415d30abc def quit(request, reason=None, attempt_num=None, questionpaper_id=None): """Show the quit page when the user logs out.""" paper = AnswerPaper.objects.get(user=request.user, -- cgit From 360af260ed71c40b4ed320baaf6e34f2fef2f694 Mon Sep 17 00:00:00 2001 From: prathamesh Date: Sat, 2 Sep 2017 03:07:31 +0530 Subject: Issue after merge resolved --- yaksh/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'yaksh/views.py') diff --git a/yaksh/views.py b/yaksh/views.py index af7951f..ba957db 100644 --- a/yaksh/views.py +++ b/yaksh/views.py @@ -424,7 +424,7 @@ def start(request, questionpaper_id=None, attempt_num=None): if not last_attempt: attempt_number = 1 else: - last_attempt.attempt_number + 1 + attempt_number = last_attempt.attempt_number + 1 context = { 'user': user, 'questionpaper': quest_paper, -- cgit From ad020f9039e33fc6c29e9f0e1de8fd56c2f78406 Mon Sep 17 00:00:00 2001 From: prathamesh Date: Fri, 8 Sep 2017 13:41:40 +0530 Subject: Modification as per comments on the PR --- yaksh/views.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'yaksh/views.py') diff --git a/yaksh/views.py b/yaksh/views.py index 0b601f2..97da29c 100644 --- a/yaksh/views.py +++ b/yaksh/views.py @@ -31,7 +31,7 @@ except ImportError: from io import BytesIO as string_io import re # Local imports. -from yaksh.code_server import get_result, SERVER_POOL_PORT +from yaksh.code_server import get_result as get_result_from_code_server, SERVER_POOL_PORT from yaksh.models import ( Answer, AnswerPaper, AssignmentUpload, Course, FileUpload, FloatTestCase, HookTestCase, IntegerTestCase, McqTestCase, Profile, @@ -616,7 +616,7 @@ def check(request, q_id, attempt_num=None, questionpaper_id=None): if current_question.type in ['code', 'upload']: if paper.time_left() <= 0: url = 'http://localhost:%s' % SERVER_POOL_PORT - result = get_result(url, uid, block=True) + result = get_result_from_code_server(url, uid, block=True) result = json.loads(result.get('result')) next_question, error_message, paper = _update_paper(request, uid, result) @@ -631,10 +631,10 @@ def check(request, q_id, attempt_num=None, questionpaper_id=None): @csrf_exempt -def get_results(request, uid): +def get_result(request, uid): result = {} url = 'http://localhost:%s' % SERVER_POOL_PORT - result_state = get_result(url, uid) + result_state = get_result_from_code_server(url, uid) result['status'] = result_state.get('status') if result['status'] == 'done': result = json.loads(result_state.get('result')) -- cgit From f65102cf4b6a117a3ff86971ad9c1ddd3362c9fd Mon Sep 17 00:00:00 2001 From: prathamesh Date: Tue, 12 Sep 2017 12:50:44 +0530 Subject: Change in variable name --- yaksh/views.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'yaksh/views.py') diff --git a/yaksh/views.py b/yaksh/views.py index 97da29c..3f9f622 100644 --- a/yaksh/views.py +++ b/yaksh/views.py @@ -616,8 +616,8 @@ def check(request, q_id, attempt_num=None, questionpaper_id=None): if current_question.type in ['code', 'upload']: if paper.time_left() <= 0: url = 'http://localhost:%s' % SERVER_POOL_PORT - result = get_result_from_code_server(url, uid, block=True) - result = json.loads(result.get('result')) + result_details = get_result_from_code_server(url, uid, block=True) + result = json.loads(result_details.get('result')) next_question, error_message, paper = _update_paper(request, uid, result) return show_question(request, next_question, paper, error_message) -- cgit