Commit 35769a70 by ichuang

Merge pull request #186 from MITx/ccp0101/capa_pythonpath

Ccp0101/capa pythonpath
parents 247fa6ca d1ad8fc4
...@@ -22,6 +22,7 @@ import random ...@@ -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): ...@@ -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): ...@@ -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): ...@@ -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): ...@@ -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): ...@@ -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
''' '''
......
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