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/code_server.py | 2 +- yaksh/models.py | 11 ++-- yaksh/static/yaksh/js/question.js | 12 ----- yaksh/static/yaksh/js/requesthandler.js | 90 +++++++++++++++++++++++++++++++++ yaksh/templates/yaksh/question.html | 51 +++---------------- yaksh/urls.py | 1 + yaksh/views.py | 79 +++++++++++++++++++---------- 7 files changed, 155 insertions(+), 91 deletions(-) mode change 100644 => 100755 yaksh/code_server.py delete mode 100644 yaksh/static/yaksh/js/question.js create mode 100644 yaksh/static/yaksh/js/requesthandler.js diff --git a/yaksh/code_server.py b/yaksh/code_server.py old mode 100644 new mode 100755 index 7bacc7f..d74d35b --- a/yaksh/code_server.py +++ b/yaksh/code_server.py @@ -208,7 +208,7 @@ def get_result(url, uid, block=False): ''' def _get_data(): r = requests.get(urllib.parse.urljoin(url, str(uid))) - return json.loads(r.content) + return json.loads(r.content.decode('utf-8')) data = _get_data() if block: while data.get('status') != 'done': diff --git a/yaksh/models.py b/yaksh/models.py index 87e6260..9b3cabe 100644 --- a/yaksh/models.py +++ b/yaksh/models.py @@ -24,7 +24,7 @@ import zipfile import tempfile from textwrap import dedent from .file_utils import extract_files, delete_files -from yaksh.xmlrpc_clients import code_server +from yaksh.code_server import submit, SERVER_POOL_PORT from django.conf import settings @@ -1266,7 +1266,7 @@ class AnswerPaper(models.Model): if question.type == 'code': return self.answers.filter(question=question).order_by('-id') - def validate_answer(self, user_answer, question, json_data=None): + def validate_answer(self, user_answer, question, json_data=None, uid=None): """ Checks whether the answer submitted by the user is right or wrong. If right then returns correct = True, success and @@ -1327,10 +1327,9 @@ class AnswerPaper(models.Model): elif question.type == 'code' or question.type == "upload": user_dir = self.user.profile.get_user_dir() - json_result = code_server.run_code( - question.language, json_data, user_dir - ) - result = json.loads(json_result) + url = 'http://localhost:%s' % SERVER_POOL_PORT + submit(url, uid, json_data, user_dir) + result = {'uid': uid, 'state': 'running'} return result def regrade(self, question_id): diff --git a/yaksh/static/yaksh/js/question.js b/yaksh/static/yaksh/js/question.js deleted file mode 100644 index 96ff3de..0000000 --- a/yaksh/static/yaksh/js/question.js +++ /dev/null @@ -1,12 +0,0 @@ -function submitCode() -{ - document.forms["code"].submit(); - var x = document.getElementById("status"); - x.innerHTML = "Checking answer ..."; - x = document.getElementById("check"); - x.disabled = true; - x.value = "Checking Answer ..."; - if (document.getElementById("skip")!=null) { - document.getElementById("skip").disabled = true; - } -} diff --git a/yaksh/static/yaksh/js/requesthandler.js b/yaksh/static/yaksh/js/requesthandler.js new file mode 100644 index 0000000..9d023cc --- /dev/null +++ b/yaksh/static/yaksh/js/requesthandler.js @@ -0,0 +1,90 @@ +request_status = "initial" +function submitRequest(){ + document.forms["code"].submit(); +} + +function check_state(state, uid, success) { + if (state == "running") { + setTimeout(get_result(uid), 2000); + } +} + +function get_result(uid){ + $.ajax({ + method: "GET", + url: "/exam/get_results/"+uid+"/", + dataType: "html", // Your server can response html, json, xml format. + success: function(data, status, xhr) { + content_type = xhr.getResponseHeader("content-type"); + if(content_type.includes("text/html")) { + request_status = "initial"; + document.open(); + document.write(data); + document.close(); + } else if(content_type.includes("application/json")) { + res = JSON.parse(data); + request_status = res.status; + check_state(request_status, uid, res.success); + } + } + }); +} + +var global_editor = {}; +$(document).ready(function(){ + // Codemirror object, language modes and initial content + // Get the textarea node + var textarea_node = document.querySelector('#answer'); + + var mode_dict = { + 'python': 'python', + 'c': 'text/x-csrc', + 'cpp': 'text/x-c++src', + 'java': 'text/x-java', + 'bash': 'text/x-sh', + 'scilab': 'text/x-csrc' + } + + // Code mirror Options + var options = { + mode: mode_dict[lang], + gutter: true, + lineNumbers: true, + onChange: function (instance, changes) { + render(); + } + }; + + // Initialize the codemirror editor + global_editor.editor = CodeMirror.fromTextArea(textarea_node, options); + + // Setting code editors initial content + global_editor.editor.setValue(init_val); + + function reset_editor() { + global_editor.editor.setValue(init_val); + global_editor.editor.clearHistory(); + } + $('#code').submit(function(e) { + $.ajax({ + type: 'POST', + url: $(this).attr("action"), + data: $(this).serializeArray(), + dataType: "html", // Your server can response html, json, xml format. + success: function(data, status, xhr) { + content_type = xhr.getResponseHeader("content-type"); + if(content_type.includes("text/html")) { + document.open(); + document.write(data); + document.close(); + } else if(content_type.includes("application/json")) { + res = JSON.parse(data); + var uid = res.uid; + request_status = res.state; + check_state(request_status, uid, false); + } + } + }); + e.preventDefault(); // To stop the default form submission. + }); +}); diff --git a/yaksh/templates/yaksh/question.html b/yaksh/templates/yaksh/question.html index ee33523..9df2fef 100644 --- a/yaksh/templates/yaksh/question.html +++ b/yaksh/templates/yaksh/question.html @@ -15,7 +15,7 @@ {% endblock %} {% block script %} - + @@ -79,7 +79,7 @@ function validate(){ } else { - return true; + send_request(); } } @@ -89,47 +89,8 @@ function call_skip(url) form.action = url form.submit(); } - - {% endblock script %} @@ -239,13 +200,13 @@ function call_skip(url)