From e2f4995bc9aef918acf806580e43d7da91512a0c Mon Sep 17 00:00:00 2001 From: kimth Date: Tue, 31 Jul 2012 08:57:28 -0400 Subject: [PATCH 1/7] LMS provides fully qualified callback URL --- common/lib/capa/capa/responsetypes.py | 4 ++-- lms/djangoapps/courseware/module_render.py | 9 +++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/common/lib/capa/capa/responsetypes.py b/common/lib/capa/capa/responsetypes.py index 944b84bf61..9694e3ea6d 100644 --- a/common/lib/capa/capa/responsetypes.py +++ b/common/lib/capa/capa/responsetypes.py @@ -905,7 +905,7 @@ class CodeResponse(LoncapaResponse): def _send_to_queue(self, extra_payload): # Prepare payload xmlstr = etree.tostring(self.xml, pretty_print=True) - header = {'return_url': self.system.xqueue_callback_url, + header = {'lms_callback_url': self.system.xqueue_callback_url, 'queue_name': self.queue_name, } @@ -914,7 +914,7 @@ class CodeResponse(LoncapaResponse): h.update(str(self.system.seed)) h.update(str(time.time())) queuekey = int(h.hexdigest(), 16) - header.update({'queuekey': queuekey}) + header.update({'lms_key': queuekey}) body = {'xml': xmlstr, 'edX_cmd': 'get_score', diff --git a/lms/djangoapps/courseware/module_render.py b/lms/djangoapps/courseware/module_render.py index bf7d1f4c51..7ad8d5e441 100644 --- a/lms/djangoapps/courseware/module_render.py +++ b/lms/djangoapps/courseware/module_render.py @@ -140,8 +140,11 @@ def get_module(user, request, location, student_module_cache, position=None): # TODO (vshnayder): fix hardcoded urls (use reverse) # Setup system context for module instance ajax_url = settings.MITX_ROOT_URL + '/modx/' + descriptor.location.url() + '/' - xqueue_callback_url = (settings.MITX_ROOT_URL + '/xqueue/' + - str(user.id) + '/' + descriptor.location.url() + '/') + + # Fully qualified callback URL for xqueue + xqueue_callback_url = (request.build_absolute_uri('/') + settings.MITX_ROOT_URL + + 'xqueue/' + str(user.id) + '/' + descriptor.location.url() + '/' + + 'score_update') def _get_module(location): (module, _, _, _) = get_module(user, request, location, @@ -202,8 +205,6 @@ def get_module(user, request, location, student_module_cache, position=None): return (module, instance_module, shared_module, descriptor.category) - -# TODO: TEMPORARY BYPASS OF AUTH! @csrf_exempt def xqueue_callback(request, userid, id, dispatch): # Parse xqueue response From 22af531b0b21a3d6406f56aeec8b9c886347bfbd Mon Sep 17 00:00:00 2001 From: kimth Date: Tue, 31 Jul 2012 10:09:47 -0400 Subject: [PATCH 2/7] Hardcoded URL moved to LMS for now --- lms/djangoapps/courseware/module_render.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lms/djangoapps/courseware/module_render.py b/lms/djangoapps/courseware/module_render.py index 7ad8d5e441..d764091ccf 100644 --- a/lms/djangoapps/courseware/module_render.py +++ b/lms/djangoapps/courseware/module_render.py @@ -142,7 +142,8 @@ def get_module(user, request, location, student_module_cache, position=None): ajax_url = settings.MITX_ROOT_URL + '/modx/' + descriptor.location.url() + '/' # Fully qualified callback URL for xqueue - xqueue_callback_url = (request.build_absolute_uri('/') + settings.MITX_ROOT_URL + + #xqueue_callback_url = (request.build_absolute_uri('/') + settings.MITX_ROOT_URL + # TODO: build_absolute_uri on sandbox instance returns 127.0.0.1 + xqueue_callback_url = ('http://18.189.52.120:8000/' + settings.MITX_ROOT_URL + # Sandbox URL 'xqueue/' + str(user.id) + '/' + descriptor.location.url() + '/' + 'score_update') @@ -231,7 +232,7 @@ def xqueue_callback(request, userid, id, dispatch): # Transfer 'queuekey' from xqueue response header to 'get'. This is required to # use the interface defined by 'handle_ajax' - get.update({'queuekey': header['queuekey']}) + get.update({'queuekey': header['lms_key']}) # We go through the "AJAX" path # So far, the only dispatch from xqueue will be 'score_update' From 3968e117e11f3435003bb256cf039a35718a62e6 Mon Sep 17 00:00:00 2001 From: kimth Date: Tue, 31 Jul 2012 10:42:32 -0400 Subject: [PATCH 3/7] Simplify dict load in xqueue_callback --- lms/djangoapps/courseware/module_render.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lms/djangoapps/courseware/module_render.py b/lms/djangoapps/courseware/module_render.py index d764091ccf..6fcedbbfe8 100644 --- a/lms/djangoapps/courseware/module_render.py +++ b/lms/djangoapps/courseware/module_render.py @@ -211,7 +211,7 @@ def xqueue_callback(request, userid, id, dispatch): # Parse xqueue response get = request.POST.copy() try: - header = json.loads(get.pop('xqueue_header')[0]) # 'dict' + header = json.loads(get['xqueue_header']) except Exception as err: msg = "Error in xqueue_callback %s: Invalid return format" % err raise Exception(msg) From 27e142dd2fb5628cb4c8bb43e3502eb5c745b2a8 Mon Sep 17 00:00:00 2001 From: kimth Date: Tue, 31 Jul 2012 12:58:32 -0400 Subject: [PATCH 4/7] Extra empty line --- lms/djangoapps/courseware/module_render.py | 1 + 1 file changed, 1 insertion(+) diff --git a/lms/djangoapps/courseware/module_render.py b/lms/djangoapps/courseware/module_render.py index 6fcedbbfe8..3299f79358 100644 --- a/lms/djangoapps/courseware/module_render.py +++ b/lms/djangoapps/courseware/module_render.py @@ -206,6 +206,7 @@ def get_module(user, request, location, student_module_cache, position=None): return (module, instance_module, shared_module, descriptor.category) + @csrf_exempt def xqueue_callback(request, userid, id, dispatch): # Parse xqueue response From 0879f3e0a8cb54bc85f43b053f37dbfe824c0ba4 Mon Sep 17 00:00:00 2001 From: kimth Date: Tue, 31 Jul 2012 13:21:45 -0400 Subject: [PATCH 5/7] Use build_absolute_uri rather than hardcoded sandbox URL --- lms/djangoapps/courseware/module_render.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lms/djangoapps/courseware/module_render.py b/lms/djangoapps/courseware/module_render.py index 3299f79358..beb9155670 100644 --- a/lms/djangoapps/courseware/module_render.py +++ b/lms/djangoapps/courseware/module_render.py @@ -142,8 +142,8 @@ def get_module(user, request, location, student_module_cache, position=None): ajax_url = settings.MITX_ROOT_URL + '/modx/' + descriptor.location.url() + '/' # Fully qualified callback URL for xqueue - #xqueue_callback_url = (request.build_absolute_uri('/') + settings.MITX_ROOT_URL + # TODO: build_absolute_uri on sandbox instance returns 127.0.0.1 - xqueue_callback_url = ('http://18.189.52.120:8000/' + settings.MITX_ROOT_URL + # Sandbox URL + xqueue_callback_url = (request.build_absolute_uri('/') + settings.MITX_ROOT_URL + + #xqueue_callback_url = ('http://18.189.52.120:8000/' + settings.MITX_ROOT_URL + # Sandbox URL 'xqueue/' + str(user.id) + '/' + descriptor.location.url() + '/' + 'score_update') From 2e3c5de1a50fb7631dc948e0339ce4992d409eea Mon Sep 17 00:00:00 2001 From: kimth Date: Tue, 31 Jul 2012 14:08:02 -0400 Subject: [PATCH 6/7] Remove hardcoding of LMS callback URL and default queuename --- common/lib/capa/capa/responsetypes.py | 2 +- common/lib/xmodule/xmodule/x_module.py | 3 ++- lms/djangoapps/courseware/module_render.py | 9 +++++++-- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/common/lib/capa/capa/responsetypes.py b/common/lib/capa/capa/responsetypes.py index 9694e3ea6d..75ed92ab3e 100644 --- a/common/lib/capa/capa/responsetypes.py +++ b/common/lib/capa/capa/responsetypes.py @@ -811,7 +811,7 @@ class CodeResponse(LoncapaResponse): def setup_response(self): xml = self.xml self.url = xml.get('url', "http://107.20.215.194/xqueue/submit/") # FIXME -- hardcoded url - self.queue_name = xml.get('queuename', 'python') # TODO: Default queue_name should be course-specific + self.queue_name = xml.get('queuename', self.system.xqueue_default_queuename) answer = xml.find('answer') if answer is not None: diff --git a/common/lib/xmodule/xmodule/x_module.py b/common/lib/xmodule/xmodule/x_module.py index 3406bcb99c..7bb98dcdc5 100644 --- a/common/lib/xmodule/xmodule/x_module.py +++ b/common/lib/xmodule/xmodule/x_module.py @@ -587,7 +587,7 @@ class ModuleSystem(object): def __init__(self, ajax_url, track_function, get_module, render_template, replace_urls, user=None, filestore=None, debug=False, - xqueue_callback_url=None): + xqueue_callback_url=None, xqueue_default_queuename="null"): ''' Create a closure around the system environment. @@ -616,6 +616,7 @@ class ModuleSystem(object): ''' self.ajax_url = ajax_url self.xqueue_callback_url = xqueue_callback_url + self.xqueue_default_queuename = xqueue_default_queuename self.track_function = track_function self.filestore = filestore self.get_module = get_module diff --git a/lms/djangoapps/courseware/module_render.py b/lms/djangoapps/courseware/module_render.py index beb9155670..80a4ef90fc 100644 --- a/lms/djangoapps/courseware/module_render.py +++ b/lms/djangoapps/courseware/module_render.py @@ -141,12 +141,16 @@ def get_module(user, request, location, student_module_cache, position=None): # Setup system context for module instance ajax_url = settings.MITX_ROOT_URL + '/modx/' + descriptor.location.url() + '/' - # Fully qualified callback URL for xqueue + # Fully qualified callback URL for external queueing system xqueue_callback_url = (request.build_absolute_uri('/') + settings.MITX_ROOT_URL + - #xqueue_callback_url = ('http://18.189.52.120:8000/' + settings.MITX_ROOT_URL + # Sandbox URL 'xqueue/' + str(user.id) + '/' + descriptor.location.url() + '/' + 'score_update') + # Default queuename is course-specific and is derived from the course that + # contains the current module. + # TODO: Queuename should be derived from 'course_settings.json' of each course + xqueue_default_queuename = descriptor.location.org + '-' + descriptor.location.course + def _get_module(location): (module, _, _, _) = get_module(user, request, location, student_module_cache, position) @@ -159,6 +163,7 @@ def get_module(user, request, location, student_module_cache, position=None): render_template=render_to_string, ajax_url=ajax_url, xqueue_callback_url=xqueue_callback_url, + xqueue_default_queuename=xqueue_default_queuename.replace(' ','_'), # TODO (cpennington): Figure out how to share info between systems filestore=descriptor.system.resources_fs, get_module=_get_module, From 11495563fabf0913ac9bad6643988f4971197da5 Mon Sep 17 00:00:00 2001 From: kimth Date: Tue, 31 Jul 2012 16:42:17 -0400 Subject: [PATCH 7/7] Tweaks to CodeMirror: fix indentation, textarea is vertically resizable --- common/lib/capa/capa/inputtypes.py | 12 +++++++++--- common/lib/capa/capa/templates/textbox.html | 9 +++++++-- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/common/lib/capa/capa/inputtypes.py b/common/lib/capa/capa/inputtypes.py index 31482214b3..8b3867be5b 100644 --- a/common/lib/capa/capa/inputtypes.py +++ b/common/lib/capa/capa/inputtypes.py @@ -313,14 +313,20 @@ def textbox(element, value, status, render_template, msg=''): size = element.get('size') rows = element.get('rows') or '30' cols = element.get('cols') or '80' - mode = element.get('mode') or 'python' # mode for CodeMirror, eg "python" or "xml" hidden = element.get('hidden', '') # if specified, then textline is hidden and id is stored in div of name given by hidden - linenumbers = element.get('linenumbers','true') # for CodeMirror + if not value: value = element.text # if no student input yet, then use the default input given by the problem + + # For CodeMirror + mode = element.get('mode') or 'python' # mode, eg "python" or "xml" + linenumbers = element.get('linenumbers','true') # for CodeMirror + tabsize = element.get('tabsize','4') + tabsize = int(tabsize) + context = {'id': eid, 'value': value, 'state': status, 'count': count, 'size': size, 'msg': msg, 'mode': mode, 'linenumbers': linenumbers, 'rows': rows, 'cols': cols, - 'hidden': hidden, + 'hidden': hidden, 'tabsize': tabsize, } html = render_template("textbox.html", context) try: diff --git a/common/lib/capa/capa/templates/textbox.html b/common/lib/capa/capa/templates/textbox.html index d553ba16e5..d37eda7284 100644 --- a/common/lib/capa/capa/templates/textbox.html +++ b/common/lib/capa/capa/templates/textbox.html @@ -35,15 +35,20 @@ lineNumbers: true, % endif mode: "${mode}", - tabsize: 4, + matchBrackets: true, + lineWrapping: true, + indentUnit: "${tabsize}", + tabSize: "${tabsize}", + smartIndent: false }); });