Merge pull request #186 from MITx/ccp0101/capa_pythonpath
Ccp0101/capa pythonpath
This commit is contained in:
@@ -22,6 +22,7 @@ import random
|
|||||||
import re
|
import re
|
||||||
import scipy
|
import scipy
|
||||||
import struct
|
import struct
|
||||||
|
import sys
|
||||||
|
|
||||||
from lxml import etree
|
from lxml import etree
|
||||||
from xml.sax.saxutils import unescape
|
from xml.sax.saxutils import unescape
|
||||||
@@ -78,7 +79,7 @@ class LoncapaProblem(object):
|
|||||||
- id (string): identifier for this problem; often a filename (no spaces)
|
- id (string): identifier for this problem; often a filename (no spaces)
|
||||||
- state (dict): student state
|
- state (dict): student state
|
||||||
- seed (int): random number generator seed (int)
|
- seed (int): random number generator seed (int)
|
||||||
- system (I4xSystme): I4xSystem instance which provides OS, rendering, and user context
|
- system (I4xSystem): I4xSystem instance which provides OS, rendering, and user context
|
||||||
|
|
||||||
'''
|
'''
|
||||||
|
|
||||||
@@ -196,7 +197,7 @@ class LoncapaProblem(object):
|
|||||||
|
|
||||||
Thus, for example, input_ID123 -> ID123, and input_fromjs_ID123 -> fromjs_ID123
|
Thus, for example, input_ID123 -> ID123, and input_fromjs_ID123 -> fromjs_ID123
|
||||||
|
|
||||||
Calles the Response for each question in this problem, to do the actual grading.
|
Calls the Response for each question in this problem, to do the actual grading.
|
||||||
'''
|
'''
|
||||||
self.student_answers = answers
|
self.student_answers = answers
|
||||||
oldcmap = self.correct_map # old CorrectMap
|
oldcmap = self.correct_map # old CorrectMap
|
||||||
@@ -276,6 +277,34 @@ class LoncapaProblem(object):
|
|||||||
parent.remove(inc)
|
parent.remove(inc)
|
||||||
log.debug('Included %s into %s' % (file, self.problem_id))
|
log.debug('Included %s into %s' % (file, self.problem_id))
|
||||||
|
|
||||||
|
def _extract_system_path(self, script):
|
||||||
|
'''
|
||||||
|
Extracts and normalizes additional paths for code execution.
|
||||||
|
For now, there's a default path of data/course/code; this may be removed
|
||||||
|
at some point.
|
||||||
|
'''
|
||||||
|
|
||||||
|
DEFAULT_PATH = ['code']
|
||||||
|
|
||||||
|
# Separate paths by :, like the system path.
|
||||||
|
raw_path = script.get('system_path', '').split(":") + DEFAULT_PATH
|
||||||
|
|
||||||
|
# find additional comma-separated modules search path
|
||||||
|
path = []
|
||||||
|
|
||||||
|
for dir in raw_path:
|
||||||
|
|
||||||
|
if not dir:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# path is an absolute path or a path relative to the data dir
|
||||||
|
dir = os.path.join(self.system.filestore.root_path, dir)
|
||||||
|
abs_dir = os.path.normpath(dir)
|
||||||
|
log.debug("appending to path: %s" % abs_dir)
|
||||||
|
path.append(abs_dir)
|
||||||
|
|
||||||
|
return path
|
||||||
|
|
||||||
def _extract_context(self, tree, seed=struct.unpack('i', os.urandom(4))[0]): # private
|
def _extract_context(self, tree, seed=struct.unpack('i', os.urandom(4))[0]): # private
|
||||||
'''
|
'''
|
||||||
Extract content of <script>...</script> from the problem.xml file, and exec it in the
|
Extract content of <script>...</script> from the problem.xml file, and exec it in the
|
||||||
@@ -291,7 +320,20 @@ class LoncapaProblem(object):
|
|||||||
context['the_lcp'] = self # pass instance of LoncapaProblem in
|
context['the_lcp'] = self # pass instance of LoncapaProblem in
|
||||||
context['script_code'] = ''
|
context['script_code'] = ''
|
||||||
|
|
||||||
for script in tree.findall('.//script'):
|
self._execute_scripts(tree.findall('.//script'), context)
|
||||||
|
|
||||||
|
return context
|
||||||
|
|
||||||
|
def _execute_scripts(self, scripts, context):
|
||||||
|
'''
|
||||||
|
Executes scripts in the given context.
|
||||||
|
'''
|
||||||
|
original_path = sys.path
|
||||||
|
|
||||||
|
for script in scripts:
|
||||||
|
|
||||||
|
sys.path = original_path + self._extract_system_path(script)
|
||||||
|
|
||||||
stype = script.get('type')
|
stype = script.get('type')
|
||||||
if stype:
|
if stype:
|
||||||
if 'javascript' in stype:
|
if 'javascript' in stype:
|
||||||
@@ -308,7 +350,8 @@ class LoncapaProblem(object):
|
|||||||
except Exception:
|
except Exception:
|
||||||
log.exception("Error while execing script code: " + code)
|
log.exception("Error while execing script code: " + code)
|
||||||
raise responsetypes.LoncapaProblemError("Error while executing script code")
|
raise responsetypes.LoncapaProblemError("Error while executing script code")
|
||||||
return context
|
finally:
|
||||||
|
sys.path = original_path
|
||||||
|
|
||||||
def _extract_html(self, problemtree): # private
|
def _extract_html(self, problemtree): # private
|
||||||
'''
|
'''
|
||||||
|
|||||||
Reference in New Issue
Block a user