Files
edx-platform/common/lib/capa/capa/xqueue_interface.py
Calen Pennington 4f555f6480 Merge remote-tracking branch 'origin/master' into feature/cale/xmodule-storage-model
Conflicts:
	cms/djangoapps/contentstore/course_info_model.py
	cms/djangoapps/contentstore/module_info_model.py
	cms/djangoapps/contentstore/tests/factories.py
	cms/djangoapps/contentstore/tests/test_course_settings.py
	cms/djangoapps/contentstore/views.py
	cms/djangoapps/models/settings/course_details.py
	cms/djangoapps/models/settings/course_grading.py
	cms/templates/edit_subsection.html
	common/djangoapps/mitxmako/shortcuts.py
	common/djangoapps/static_replace.py
	common/djangoapps/util/converters.py
	common/djangoapps/xmodule_modifiers.py
	common/lib/xmodule/setup.py
	common/lib/xmodule/xmodule/abtest_module.py
	common/lib/xmodule/xmodule/capa_module.py
	common/lib/xmodule/xmodule/course_module.py
	common/lib/xmodule/xmodule/discussion_module.py
	common/lib/xmodule/xmodule/error_module.py
	common/lib/xmodule/xmodule/html_module.py
	common/lib/xmodule/xmodule/js/src/video/display.coffee
	common/lib/xmodule/xmodule/mako_module.py
	common/lib/xmodule/xmodule/modulestore/mongo.py
	common/lib/xmodule/xmodule/modulestore/store_utilities.py
	common/lib/xmodule/xmodule/modulestore/xml.py
	common/lib/xmodule/xmodule/modulestore/xml_importer.py
	common/lib/xmodule/xmodule/raw_module.py
	common/lib/xmodule/xmodule/self_assessment_module.py
	common/lib/xmodule/xmodule/seq_module.py
	common/lib/xmodule/xmodule/template_module.py
	common/lib/xmodule/xmodule/tests/__init__.py
	common/lib/xmodule/xmodule/tests/test_export.py
	common/lib/xmodule/xmodule/tests/test_import.py
	common/lib/xmodule/xmodule/video_module.py
	common/lib/xmodule/xmodule/x_module.py
	common/lib/xmodule/xmodule/xml_module.py
	lms/djangoapps/courseware/access.py
	lms/djangoapps/courseware/courses.py
	lms/djangoapps/courseware/grades.py
	lms/djangoapps/courseware/models.py
	lms/djangoapps/courseware/module_render.py
	lms/djangoapps/courseware/tests/tests.py
	lms/djangoapps/courseware/views.py
	lms/djangoapps/django_comment_client/utils.py
	lms/templates/staff_problem_info.html
	lms/templates/video.html
	rakefile
2013-02-07 15:12:30 -05:00

127 lines
3.8 KiB
Python

#
# LMS Interface to external queueing system (xqueue)
#
import hashlib
import json
import logging
import requests
log = logging.getLogger(__name__)
dateformat = '%Y%m%d%H%M%S'
def make_hashkey(seed):
'''
Generate a string key by hashing
'''
h = hashlib.md5()
h.update(str(seed))
return h.hexdigest()
def make_xheader(lms_callback_url, lms_key, queue_name):
"""
Generate header for delivery and reply of queue request.
Xqueue header is a JSON-serialized dict:
{ 'lms_callback_url': url to which xqueue will return the request (string),
'lms_key': secret key used by LMS to protect its state (string),
'queue_name': designate a specific queue within xqueue server, e.g. 'MITx-6.00x' (string)
}
"""
return json.dumps({'lms_callback_url': lms_callback_url,
'lms_key': lms_key,
'queue_name': queue_name})
def parse_xreply(xreply):
"""
Parse the reply from xqueue. Messages are JSON-serialized dict:
{ 'return_code': 0 (success), 1 (fail)
'content': Message from xqueue (string)
}
"""
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)
class XQueueInterface(object):
'''
Interface to the external grading system
'''
def __init__(self, url, django_auth, requests_auth=None):
self.url = url
self.auth = django_auth
self.session = requests.session(auth=requests_auth)
def send_to_queue(self, header, body, files_to_upload=None):
"""
Submit a request to xqueue.
header: JSON-serialized dict in the format described in 'xqueue_interface.make_xheader'
body: Serialized data for the receipient behind the queueing service. The operation of
xqueue is agnostic to the contents of 'body'
files_to_upload: List of file objects to be uploaded to xqueue along with queue request
Returns (error_code, msg) where error_code != 0 indicates an error
"""
# Attempt to send to queue
(error, msg) = self._send_to_queue(header, body, files_to_upload)
# Log in, then try again
if error and (msg == 'login_required'):
(error, content) = self._login()
if error != 0:
# when the login fails
log.debug("Failed to login to queue: %s", content)
return (error, content)
if files_to_upload is not None:
# Need to rewind file pointers
for f in files_to_upload:
f.seek(0)
(error, msg) = self._send_to_queue(header, body, files_to_upload)
return (error, msg)
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, files_to_upload):
payload = {'xqueue_header': header,
'xqueue_body': body}
files = {}
if files_to_upload is not None:
for f in files_to_upload:
files.update({f.name: f})
return self._http_post(self.url + '/xqueue/submit/', payload, files=files)
def _http_post(self, url, data, files=None):
try:
r = self.session.post(url, data=data, files=files)
except requests.exceptions.ConnectionError, err:
log.error(err)
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)