Commit ffb341f6 by ichuang

Merge pull request #186 from MITx/ccp0101/capa_pythonpath

Ccp0101/capa pythonpath
parents c3437342 8365c2fd
......@@ -22,6 +22,7 @@ import random
import re
import scipy
import struct
import sys
from lxml import etree
from xml.sax.saxutils import unescape
......@@ -78,7 +79,7 @@ class LoncapaProblem(object):
- id (string): identifier for this problem; often a filename (no spaces)
- state (dict): student state
- 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
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
oldcmap = self.correct_map # old CorrectMap
......@@ -276,6 +277,34 @@ class LoncapaProblem(object):
parent.remove(inc)
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
'''
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['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')
if stype:
if 'javascript' in stype:
......@@ -308,7 +350,8 @@ class LoncapaProblem(object):
except Exception:
log.exception("Error while execing script code: " + code)
raise responsetypes.LoncapaProblemError("Error while executing script code")
return context
finally:
sys.path = original_path
def _extract_html(self, problemtree): # private
'''
......
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