Merge master
This commit is contained in:
@@ -92,7 +92,7 @@ def add_histogram(get_html, module):
|
||||
if settings.MITX_FEATURES.get('ENABLE_LMS_MIGRATION'):
|
||||
[filepath, filename] = module.definition.get('filename','')
|
||||
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)
|
||||
data_dir = osfs.root_path.rsplit('/')[-1]
|
||||
edit_link = "https://github.com/MITx/%s/tree/master/%s" % (data_dir,filepath)
|
||||
|
||||
@@ -31,7 +31,6 @@ import xqueue_interface
|
||||
|
||||
log = logging.getLogger('mitx.' + __name__)
|
||||
|
||||
qinterface = xqueue_interface.XqueueInterface()
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Exceptions
|
||||
@@ -981,7 +980,7 @@ class CodeResponse(LoncapaResponse):
|
||||
|
||||
def setup_response(self):
|
||||
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')
|
||||
if answer is not None:
|
||||
@@ -1029,10 +1028,11 @@ class CodeResponse(LoncapaResponse):
|
||||
|
||||
# Prepare xqueue request
|
||||
#------------------------------------------------------------
|
||||
qinterface = self.system.xqueue['interface']
|
||||
|
||||
# Generate header
|
||||
queuekey = xqueue_interface.make_hashkey(self.system.seed)
|
||||
xheader = xqueue_interface.make_xheader(lms_callback_url=self.system.xqueue_callback_url,
|
||||
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'],
|
||||
lms_key=queuekey,
|
||||
queue_name=self.queue_name)
|
||||
|
||||
@@ -1061,7 +1061,7 @@ class CodeResponse(LoncapaResponse):
|
||||
msg='Unable to deliver your submission to grader. (Reason: %s.) Please try again later.' % msg)
|
||||
else:
|
||||
# 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
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
lineWrapping: true,
|
||||
indentUnit: "${tabsize}",
|
||||
tabSize: "${tabsize}",
|
||||
indentWithTabs: true,
|
||||
smartIndent: false
|
||||
});
|
||||
});
|
||||
@@ -48,7 +49,7 @@
|
||||
border: 1px solid black;
|
||||
font-size: 14px;
|
||||
line-height: 18px;
|
||||
resize: vertical;
|
||||
resize: both;
|
||||
}
|
||||
</style>
|
||||
</section>
|
||||
|
||||
@@ -47,7 +47,12 @@ def parse_xreply(xreply):
|
||||
'content': Message from xqueue (string)
|
||||
}
|
||||
'''
|
||||
xreply = json.loads(xreply)
|
||||
try:
|
||||
xreply = json.loads(xreply)
|
||||
except ValueError, err:
|
||||
log.error(err)
|
||||
return (1, 'unexpected reply from server')
|
||||
|
||||
return_code = xreply['return_code']
|
||||
content = xreply['content']
|
||||
return (return_code, content)
|
||||
@@ -61,7 +66,7 @@ class XqueueInterface:
|
||||
def __init__(self, url=XQUEUE_URL, auth=XQUEUE_LMS_AUTH):
|
||||
self.url = url
|
||||
self.auth = auth
|
||||
self.s = requests.session()
|
||||
self.session = requests.session()
|
||||
self._login()
|
||||
|
||||
def send_to_queue(self, header, body, file_to_upload=None):
|
||||
@@ -86,29 +91,32 @@ class XqueueInterface:
|
||||
|
||||
return (error, msg)
|
||||
|
||||
def _login(self):
|
||||
try:
|
||||
r = self.s.post(self.url+'/xqueue/login/', data={ 'username': self.auth['username'],
|
||||
'password': self.auth['password'] })
|
||||
except requests.exceptions.ConnectionError, err:
|
||||
log.error(err)
|
||||
return (1, 'cannot connect to server')
|
||||
|
||||
return parse_xreply(r.text)
|
||||
def _login(self):
|
||||
payload = { 'username': self.auth['username'],
|
||||
'password': self.auth['password'] }
|
||||
return self._http_post(self.url+'/xqueue/login/', payload)
|
||||
|
||||
|
||||
def _send_to_queue(self, header, body, file_to_upload=None):
|
||||
|
||||
payload = {'xqueue_header': header,
|
||||
'xqueue_body' : body}
|
||||
|
||||
files = None
|
||||
if file_to_upload is not None:
|
||||
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:
|
||||
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:
|
||||
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)
|
||||
|
||||
qinterface = XqueueInterface()
|
||||
|
||||
@@ -13,6 +13,7 @@ class @Problem
|
||||
bind: =>
|
||||
MathJax.Hub.Queue ["Typeset", MathJax.Hub]
|
||||
window.update_schematics()
|
||||
@inputs = @$("[id^=input_#{@element_id.replace(/problem_/, '')}_]")
|
||||
@$('section.action input:button').click @refreshAnswers
|
||||
@$('section.action input.check').click @check_fd
|
||||
#@$('section.action input.check').click @check
|
||||
@@ -114,8 +115,8 @@ class @Problem
|
||||
return
|
||||
|
||||
fd = new FormData()
|
||||
|
||||
@$("[id^=input_#{@element_id.replace(/problem_/, '')}_]").each (index, element) ->
|
||||
|
||||
@inputs.each (index, element) ->
|
||||
if element.type is 'file'
|
||||
if element.files[0] instanceof File
|
||||
fd.append(element.id, element.files[0])
|
||||
@@ -206,7 +207,7 @@ class @Problem
|
||||
element.schematic.update_value()
|
||||
@$(".CodeMirror").each (index, element) ->
|
||||
element.CodeMirror.save() if element.CodeMirror.save
|
||||
@answers = @$("[id^=input_#{@element_id.replace(/problem_/, '')}_]").serialize()
|
||||
@answers = @inputs.serialize()
|
||||
|
||||
inputtypeSetupMethods:
|
||||
javascriptinput: (element) =>
|
||||
|
||||
@@ -643,8 +643,7 @@ class ModuleSystem(object):
|
||||
user=None,
|
||||
filestore=None,
|
||||
debug=False,
|
||||
xqueue_callback_url=None,
|
||||
xqueue_default_queuename="null",
|
||||
xqueue = None,
|
||||
is_staff=False):
|
||||
'''
|
||||
Create a closure around the system environment.
|
||||
@@ -668,6 +667,9 @@ class ModuleSystem(object):
|
||||
filestore - A filestore ojbect. Defaults to an instance of OSFS based
|
||||
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
|
||||
that capa_module can use to fix up the static urls in
|
||||
ajax results.
|
||||
@@ -676,8 +678,7 @@ class ModuleSystem(object):
|
||||
TODO (vshnayder): this will need to change once we have real user roles.
|
||||
'''
|
||||
self.ajax_url = ajax_url
|
||||
self.xqueue_callback_url = xqueue_callback_url
|
||||
self.xqueue_default_queuename = xqueue_default_queuename
|
||||
self.xqueue = xqueue
|
||||
self.track_function = track_function
|
||||
self.filestore = filestore
|
||||
self.get_module = get_module
|
||||
|
||||
@@ -8,6 +8,7 @@ from django.views.decorators.csrf import csrf_exempt
|
||||
|
||||
from django.contrib.auth.models import User
|
||||
from xmodule.modulestore.django import modulestore
|
||||
from capa.xqueue_interface import qinterface
|
||||
from mitxmako.shortcuts import render_to_string
|
||||
from models import StudentModule, StudentModuleCache
|
||||
from static_replace import replace_urls
|
||||
@@ -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
|
||||
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):
|
||||
(module, _, _, _) = get_module(user, request, location,
|
||||
student_module_cache, position)
|
||||
@@ -168,8 +173,7 @@ def get_module(user, request, location, student_module_cache, position=None):
|
||||
system = ModuleSystem(track_function=make_track_function(request),
|
||||
render_template=render_to_string,
|
||||
ajax_url=ajax_url,
|
||||
xqueue_callback_url=xqueue_callback_url,
|
||||
xqueue_default_queuename=xqueue_default_queuename.replace(' ','_'),
|
||||
xqueue=xqueue,
|
||||
# TODO (cpennington): Figure out how to share info between systems
|
||||
filestore=descriptor.system.resources_fs,
|
||||
get_module=_get_module,
|
||||
@@ -222,6 +226,9 @@ def get_module(user, request, location, student_module_cache, position=None):
|
||||
|
||||
@csrf_exempt
|
||||
def xqueue_callback(request, userid, id, dispatch):
|
||||
'''
|
||||
Entry point for graded results from the queueing system.
|
||||
'''
|
||||
# Parse xqueue response
|
||||
get = request.POST.copy()
|
||||
try:
|
||||
|
||||
Reference in New Issue
Block a user