Commit 2f84e0ca by Arjun Singh

Merge master

parents 99e7d007 926763a3
...@@ -92,7 +92,7 @@ def add_histogram(get_html, module): ...@@ -92,7 +92,7 @@ def add_histogram(get_html, module):
if settings.MITX_FEATURES.get('ENABLE_LMS_MIGRATION'): if settings.MITX_FEATURES.get('ENABLE_LMS_MIGRATION'):
[filepath, filename] = module.definition.get('filename','') [filepath, filename] = module.definition.get('filename','')
osfs = module.system.filestore osfs = module.system.filestore
if osfs.exists(filename): if filename is not None and osfs.exists(filename):
filepath = filename # if original, unmangled filename exists then use it (github doesn't like symlinks) filepath = filename # if original, unmangled filename exists then use it (github doesn't like symlinks)
data_dir = osfs.root_path.rsplit('/')[-1] data_dir = osfs.root_path.rsplit('/')[-1]
edit_link = "https://github.com/MITx/%s/tree/master/%s" % (data_dir,filepath) edit_link = "https://github.com/MITx/%s/tree/master/%s" % (data_dir,filepath)
......
...@@ -31,7 +31,6 @@ import xqueue_interface ...@@ -31,7 +31,6 @@ import xqueue_interface
log = logging.getLogger('mitx.' + __name__) log = logging.getLogger('mitx.' + __name__)
qinterface = xqueue_interface.XqueueInterface()
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
# Exceptions # Exceptions
...@@ -981,7 +980,7 @@ class CodeResponse(LoncapaResponse): ...@@ -981,7 +980,7 @@ class CodeResponse(LoncapaResponse):
def setup_response(self): def setup_response(self):
xml = self.xml xml = self.xml
self.queue_name = xml.get('queuename', self.system.xqueue_default_queuename) self.queue_name = xml.get('queuename', self.system.xqueue['default_queuename'])
answer = xml.find('answer') answer = xml.find('answer')
if answer is not None: if answer is not None:
...@@ -1029,10 +1028,11 @@ class CodeResponse(LoncapaResponse): ...@@ -1029,10 +1028,11 @@ class CodeResponse(LoncapaResponse):
# Prepare xqueue request # Prepare xqueue request
#------------------------------------------------------------ #------------------------------------------------------------
qinterface = self.system.xqueue['interface']
# Generate header # Generate header
queuekey = xqueue_interface.make_hashkey(self.system.seed) queuekey = xqueue_interface.make_hashkey(str(self.system.seed)+self.answer_id)
xheader = xqueue_interface.make_xheader(lms_callback_url=self.system.xqueue_callback_url, xheader = xqueue_interface.make_xheader(lms_callback_url=self.system.xqueue['callback_url'],
lms_key=queuekey, lms_key=queuekey,
queue_name=self.queue_name) queue_name=self.queue_name)
...@@ -1061,7 +1061,7 @@ class CodeResponse(LoncapaResponse): ...@@ -1061,7 +1061,7 @@ class CodeResponse(LoncapaResponse):
msg='Unable to deliver your submission to grader. (Reason: %s.) Please try again later.' % msg) msg='Unable to deliver your submission to grader. (Reason: %s.) Please try again later.' % msg)
else: else:
# Non-null CorrectMap['queuekey'] indicates that the problem has been queued # Non-null CorrectMap['queuekey'] indicates that the problem has been queued
cmap.set(self.answer_id, queuekey=queuekey, msg='Submitted to grader') cmap.set(self.answer_id, queuekey=queuekey, msg='Submitted to grader. (Queue length: %s)' % msg)
return cmap return cmap
......
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
lineWrapping: true, lineWrapping: true,
indentUnit: "${tabsize}", indentUnit: "${tabsize}",
tabSize: "${tabsize}", tabSize: "${tabsize}",
indentWithTabs: true,
smartIndent: false smartIndent: false
}); });
}); });
...@@ -48,7 +49,7 @@ ...@@ -48,7 +49,7 @@
border: 1px solid black; border: 1px solid black;
font-size: 14px; font-size: 14px;
line-height: 18px; line-height: 18px;
resize: vertical; resize: both;
} }
</style> </style>
</section> </section>
...@@ -47,7 +47,12 @@ def parse_xreply(xreply): ...@@ -47,7 +47,12 @@ def parse_xreply(xreply):
'content': Message from xqueue (string) 'content': Message from xqueue (string)
} }
''' '''
try:
xreply = json.loads(xreply) xreply = json.loads(xreply)
except ValueError, err:
log.error(err)
return (1, 'unexpected reply from server')
return_code = xreply['return_code'] return_code = xreply['return_code']
content = xreply['content'] content = xreply['content']
return (return_code, content) return (return_code, content)
...@@ -61,7 +66,7 @@ class XqueueInterface: ...@@ -61,7 +66,7 @@ class XqueueInterface:
def __init__(self, url=XQUEUE_URL, auth=XQUEUE_LMS_AUTH): def __init__(self, url=XQUEUE_URL, auth=XQUEUE_LMS_AUTH):
self.url = url self.url = url
self.auth = auth self.auth = auth
self.s = requests.session() self.session = requests.session()
self._login() self._login()
def send_to_queue(self, header, body, file_to_upload=None): def send_to_queue(self, header, body, file_to_upload=None):
...@@ -86,29 +91,32 @@ class XqueueInterface: ...@@ -86,29 +91,32 @@ class XqueueInterface:
return (error, msg) return (error, msg)
def _login(self): def _login(self):
try: payload = { 'username': self.auth['username'],
r = self.s.post(self.url+'/xqueue/login/', data={ 'username': self.auth['username'], 'password': self.auth['password'] }
'password': self.auth['password'] }) return self._http_post(self.url+'/xqueue/login/', payload)
except requests.exceptions.ConnectionError, err:
log.error(err)
return (1, 'cannot connect to server')
return parse_xreply(r.text)
def _send_to_queue(self, header, body, file_to_upload=None): def _send_to_queue(self, header, body, file_to_upload=None):
payload = {'xqueue_header': header, payload = {'xqueue_header': header,
'xqueue_body' : body} 'xqueue_body' : body}
files = None files = None
if file_to_upload is not None: if file_to_upload is not None:
files = { file_to_upload.name: file_to_upload } files = { file_to_upload.name: file_to_upload }
return self._http_post(self.url+'/xqueue/submit/', payload, files)
def _http_post(self, url, data, files=None):
try: try:
r = self.s.post(self.url+'/xqueue/submit/', data=payload, files=files) r = self.session.post(url, data=data, files=files)
except requests.exceptions.ConnectionError, err: except requests.exceptions.ConnectionError, err:
log.error(err) log.error(err)
return (1, 'cannot connect to server') return (1, 'cannot connect to server')
if r.status_code not in [200]:
return (1, 'unexpected HTTP status code [%d]' % r.status_code)
return parse_xreply(r.text) return parse_xreply(r.text)
qinterface = XqueueInterface()
...@@ -13,6 +13,7 @@ class @Problem ...@@ -13,6 +13,7 @@ class @Problem
bind: => bind: =>
MathJax.Hub.Queue ["Typeset", MathJax.Hub] MathJax.Hub.Queue ["Typeset", MathJax.Hub]
window.update_schematics() window.update_schematics()
@inputs = @$("[id^=input_#{@element_id.replace(/problem_/, '')}_]")
@$('section.action input:button').click @refreshAnswers @$('section.action input:button').click @refreshAnswers
@$('section.action input.check').click @check_fd @$('section.action input.check').click @check_fd
#@$('section.action input.check').click @check #@$('section.action input.check').click @check
...@@ -115,7 +116,7 @@ class @Problem ...@@ -115,7 +116,7 @@ class @Problem
fd = new FormData() fd = new FormData()
@$("[id^=input_#{@element_id.replace(/problem_/, '')}_]").each (index, element) -> @inputs.each (index, element) ->
if element.type is 'file' if element.type is 'file'
if element.files[0] instanceof File if element.files[0] instanceof File
fd.append(element.id, element.files[0]) fd.append(element.id, element.files[0])
...@@ -206,7 +207,7 @@ class @Problem ...@@ -206,7 +207,7 @@ class @Problem
element.schematic.update_value() element.schematic.update_value()
@$(".CodeMirror").each (index, element) -> @$(".CodeMirror").each (index, element) ->
element.CodeMirror.save() if element.CodeMirror.save element.CodeMirror.save() if element.CodeMirror.save
@answers = @$("[id^=input_#{@element_id.replace(/problem_/, '')}_]").serialize() @answers = @inputs.serialize()
inputtypeSetupMethods: inputtypeSetupMethods:
javascriptinput: (element) => javascriptinput: (element) =>
......
...@@ -643,8 +643,7 @@ class ModuleSystem(object): ...@@ -643,8 +643,7 @@ class ModuleSystem(object):
user=None, user=None,
filestore=None, filestore=None,
debug=False, debug=False,
xqueue_callback_url=None, xqueue = None,
xqueue_default_queuename="null",
is_staff=False): is_staff=False):
''' '''
Create a closure around the system environment. Create a closure around the system environment.
...@@ -668,6 +667,9 @@ class ModuleSystem(object): ...@@ -668,6 +667,9 @@ class ModuleSystem(object):
filestore - A filestore ojbect. Defaults to an instance of OSFS based filestore - A filestore ojbect. Defaults to an instance of OSFS based
at settings.DATA_DIR. at settings.DATA_DIR.
xqueue - Dict containing XqueueInterface object, as well as parameters
for the specific StudentModule
replace_urls - TEMPORARY - A function like static_replace.replace_urls replace_urls - TEMPORARY - A function like static_replace.replace_urls
that capa_module can use to fix up the static urls in that capa_module can use to fix up the static urls in
ajax results. ajax results.
...@@ -676,8 +678,7 @@ class ModuleSystem(object): ...@@ -676,8 +678,7 @@ class ModuleSystem(object):
TODO (vshnayder): this will need to change once we have real user roles. TODO (vshnayder): this will need to change once we have real user roles.
''' '''
self.ajax_url = ajax_url self.ajax_url = ajax_url
self.xqueue_callback_url = xqueue_callback_url self.xqueue = xqueue
self.xqueue_default_queuename = xqueue_default_queuename
self.track_function = track_function self.track_function = track_function
self.filestore = filestore self.filestore = filestore
self.get_module = get_module self.get_module = get_module
......
...@@ -8,6 +8,7 @@ from django.views.decorators.csrf import csrf_exempt ...@@ -8,6 +8,7 @@ from django.views.decorators.csrf import csrf_exempt
from django.contrib.auth.models import User from django.contrib.auth.models import User
from xmodule.modulestore.django import modulestore from xmodule.modulestore.django import modulestore
from capa.xqueue_interface import qinterface
from mitxmako.shortcuts import render_to_string from mitxmako.shortcuts import render_to_string
from models import StudentModule, StudentModuleCache from models import StudentModule, StudentModuleCache
from static_replace import replace_urls from static_replace import replace_urls
...@@ -157,6 +158,10 @@ def get_module(user, request, location, student_module_cache, position=None): ...@@ -157,6 +158,10 @@ def get_module(user, request, location, student_module_cache, position=None):
# TODO: Queuename should be derived from 'course_settings.json' of each course # TODO: Queuename should be derived from 'course_settings.json' of each course
xqueue_default_queuename = descriptor.location.org + '-' + descriptor.location.course xqueue_default_queuename = descriptor.location.org + '-' + descriptor.location.course
xqueue = { 'interface': qinterface,
'callback_url': xqueue_callback_url,
'default_queuename': xqueue_default_queuename.replace(' ','_') }
def _get_module(location): def _get_module(location):
(module, _, _, _) = get_module(user, request, location, (module, _, _, _) = get_module(user, request, location,
student_module_cache, position) student_module_cache, position)
...@@ -168,8 +173,7 @@ def get_module(user, request, location, student_module_cache, position=None): ...@@ -168,8 +173,7 @@ def get_module(user, request, location, student_module_cache, position=None):
system = ModuleSystem(track_function=make_track_function(request), system = ModuleSystem(track_function=make_track_function(request),
render_template=render_to_string, render_template=render_to_string,
ajax_url=ajax_url, ajax_url=ajax_url,
xqueue_callback_url=xqueue_callback_url, xqueue=xqueue,
xqueue_default_queuename=xqueue_default_queuename.replace(' ','_'),
# TODO (cpennington): Figure out how to share info between systems # TODO (cpennington): Figure out how to share info between systems
filestore=descriptor.system.resources_fs, filestore=descriptor.system.resources_fs,
get_module=_get_module, get_module=_get_module,
...@@ -222,6 +226,9 @@ def get_module(user, request, location, student_module_cache, position=None): ...@@ -222,6 +226,9 @@ def get_module(user, request, location, student_module_cache, position=None):
@csrf_exempt @csrf_exempt
def xqueue_callback(request, userid, id, dispatch): def xqueue_callback(request, userid, id, dispatch):
'''
Entry point for graded results from the queueing system.
'''
# Parse xqueue response # Parse xqueue response
get = request.POST.copy() get = request.POST.copy()
try: try:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment