diff --git a/common/lib/capa/capa/responsetypes.py b/common/lib/capa/capa/responsetypes.py index ba9f03549e..6346b08a42 100644 --- a/common/lib/capa/capa/responsetypes.py +++ b/common/lib/capa/capa/responsetypes.py @@ -1730,9 +1730,9 @@ class ImageResponse(LoncapaResponse): Regions is list of lists [region1, region2, region3, ...] where regionN is disordered list of points: [[1,1], [100,100], [50,50], [20, 70]]. - + If there is only one region in the list, simpler notation can be used: - regions="[[10,10], [30,30], [10, 30], [30, 10]]" (without explicitly + regions="[[10,10], [30,30], [10, 30], [30, 10]]" (without explicitly setting outer list) Returns: @@ -1817,19 +1817,24 @@ class ImageResponse(LoncapaResponse): class OpenEndedResponse(LoncapaResponse): """ - Grade student open ended responses using an external queueing server, called 'xqueue' + Grade student open ended responses using an external grading system, + accessed through the xqueue system. + + Expects 'xqueue' dict in ModuleSystem with the following keys that are + needed by OpenEndedResponse: - Expects 'xqueue' dict in ModuleSystem with the following keys that are needed by OpenEndedResponse: system.xqueue = { 'interface': XqueueInterface object, 'callback_url': Per-StudentModule callback URL where results are posted (string), - 'default_queuename': Default queuename to submit request (string) } External requests are only submitted for student submission grading (i.e. and not for getting reference answers) + + By default, uses the OpenEndedResponse.DEFAULT_QUEUE queue. """ + DEFAULT_QUEUE = 'open-ended' response_tag = 'openendedresponse' allowed_inputfields = ['openendedinput'] max_inputfields = 1 @@ -1841,7 +1846,7 @@ class OpenEndedResponse(LoncapaResponse): xml = self.xml # TODO: XML can override external resource (grader/queue) URL self.url = xml.get('url', None) - self.queue_name = xml.get('queuename', self.system.xqueue['default_queuename']) + self.queue_name = xml.get('queuename', self.DEFAULT_QUEUE) #Look for tag named openendedparam that encapsulates all grader settings oeparam = self.xml.find('openendedparam') @@ -1883,11 +1888,12 @@ class OpenEndedResponse(LoncapaResponse): #Update grader payload with student id. If grader payload not json, error. try: grader_payload=json.loads(grader_payload) - location=self.system.ajax_url.split("://")[1] - org,course,type,name=location.split("/") + # NOTE: self.system.location is valid because the capa_module + # __init__ adds it (easiest way to get problem location into + # response types) grader_payload.update({ - 'location' : location, - 'course_id' : "{0}/{1}".format(org,course), + 'location' : self.system.location, + 'course_id' : self.system.course_id, 'prompt' : prompt_string, 'rubric' : rubric_string, }) @@ -1997,7 +2003,6 @@ class OpenEndedResponse(LoncapaResponse): msg='Invalid grader reply. Please contact the course staff.') return oldcmap - correctness = 'correct' if correct else 'incorrect' # TODO: Find out how this is used elsewhere, if any diff --git a/common/lib/xmodule/xmodule/capa_module.py b/common/lib/xmodule/xmodule/capa_module.py index 47d5d5c423..ead138a225 100644 --- a/common/lib/xmodule/xmodule/capa_module.py +++ b/common/lib/xmodule/xmodule/capa_module.py @@ -146,6 +146,11 @@ class CapaModule(XModule): else: self.seed = None + # Need the problem location in openendedresponse to send out. Adding + # it to the system here seems like the least clunky way to get it + # there. + self.system.set('location', self.location) + try: # TODO (vshnayder): move as much as possible of this work and error # checking to descriptor load time diff --git a/common/lib/xmodule/xmodule/x_module.py b/common/lib/xmodule/xmodule/x_module.py index 6f3fb73356..19a592191e 100644 --- a/common/lib/xmodule/xmodule/x_module.py +++ b/common/lib/xmodule/xmodule/x_module.py @@ -809,7 +809,8 @@ class ModuleSystem(object): debug=False, xqueue=None, node_path="", - anonymous_student_id=''): + anonymous_student_id='', + course_id=None): ''' Create a closure around the system environment. @@ -844,6 +845,8 @@ class ModuleSystem(object): ajax results. anonymous_student_id - Used for tracking modules with student id + + course_id - the course_id containing this module ''' self.ajax_url = ajax_url self.xqueue = xqueue @@ -856,6 +859,7 @@ class ModuleSystem(object): self.replace_urls = replace_urls self.node_path = node_path self.anonymous_student_id = anonymous_student_id + self.course_id = course_id self.user_is_staff = user is not None and user.is_staff def get(self, attr): diff --git a/lms/djangoapps/courseware/module_render.py b/lms/djangoapps/courseware/module_render.py index eb7b41b1e9..bd919eeb15 100644 --- a/lms/djangoapps/courseware/module_render.py +++ b/lms/djangoapps/courseware/module_render.py @@ -225,6 +225,7 @@ def _get_module(user, request, location, student_module_cache, course_id, positi replace_urls=replace_urls, node_path=settings.NODE_PATH, anonymous_student_id=unique_id_for_user(user), + course_id=course_id, ) # pass position specified in URL to module through ModuleSystem system.set('position', position)