Skip to content

Commit

Permalink
catch extensions or themes unavailable to compiler, before compiling
Browse files Browse the repository at this point in the history
if you set settings.MEDIA_ROOT to a relative path, it's possible that
the Numbas compiler won't be able to find the file.
The CompileObject view now checks that the paths to extensions and the
selected theme exist before calling the compiler.
Extension and theme paths are made relative to the editor's working directory
(unless MEDIA_ROOT is set to an absolute path, as the documentation
 recommends)

This all works to catch the cases when:
 - an extension file that should exist but doesn't
 - MEDIA_ROOT is set to a path relative to the editor working directory

and throw a sensible error message rather than silently fail.

Thanks to Stuart Simpson for bringing this to my attention.
  • Loading branch information
christianp committed Dec 1, 2016
1 parent 593c40e commit a4ebdab
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 7 deletions.
4 changes: 2 additions & 2 deletions editor/models.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ def __unicode__(self):


@property @property
def extracted_path(self): def extracted_path(self):
return os.path.join(settings.MEDIA_ROOT,self.zipfile_folder,'extracted',str(self.pk)) return os.path.join(settings.GLOBAL_SETTINGS['NUMBAS_PATH'],settings.MEDIA_ROOT,self.zipfile_folder,'extracted',str(self.pk))


def save(self, *args, **kwargs): def save(self, *args, **kwargs):
self.slug = slugify(self.name) self.slug = slugify(self.name)
Expand Down Expand Up @@ -1080,7 +1080,7 @@ def theme_path(self):
if self.custom_theme: if self.custom_theme:
return self.custom_theme.extracted_path return self.custom_theme.extracted_path
else: else:
return self.theme return os.path.join(settings.GLOBAL_SETTINGS['NUMBAS_PATH'],'themes',self.theme)


@property @property
def as_numbasobject(self): def as_numbasobject(self):
Expand Down
16 changes: 12 additions & 4 deletions editor/templates/compile/error.html
Original file line number Original file line Diff line number Diff line change
@@ -1,15 +1,23 @@
{% extends "base.html" %} {% extends "base.html" %}
{% block title %}Compilation Error{% endblock %} {% block title %}Compilation Error{% endblock %}
{% block body %} {% block body %}
<div class="container">
<div class="page-header"> <div class="page-header">
<h1 class="text-warning">Compilation Error</h1> <h1 class="text-warning">Compilation Error</h1>
</div> </div>
<p><small>Attempted to compile at {% now "Y-m-d H:i:s" %}</small></p>
{% autoescape on %} {% autoescape on %}
<p id="message">{{message}} (code {{code}})</p> <p id="message">{{message}}</p>
{% if stderr %}
<h3>STDERR</h3> <h3>STDERR</h3>
<pre id="stderr"><code>{{stderr}}</code></pre> <pre id="stderr"><code>{{stderr}}</code></pre>
{% endif %}
{% if stdout %}
<h3>STDOUT</h3> <h3>STDOUT</h3>
<pre id="stdout"><code>{{stdout}}</code></pre> <pre id="stdout"><code>{{stdout}}</code></pre>
{% endautoescape %} {% endif %}
{% endautoescape %}
<button class="btn btn-primary" onclick="window.location.reload()">Try again</button>
</div>
{% endblock %} {% endblock %}


7 changes: 6 additions & 1 deletion editor/views/editoritem.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -400,10 +400,15 @@ def compile(self,numbasobject,switches,location,obj,locale='en-GB'):
Returns the path to the output produced Returns the path to the output produced
""" """


numbasobject.data['extensions'] = [e.extracted_path for e in editor.models.Extension.objects.filter(location__in=numbasobject.data.get('extensions',[]))] numbasobject.data['extensions'] = [os.path.join(os.getcwd(),e.extracted_path) for e in editor.models.Extension.objects.filter(location__in=numbasobject.data.get('extensions',[]))]
for extracted_path in numbasobject.data['extensions']:
if not os.path.exists(extracted_path):
raise CompileError("Extension not found at {}. Is MEDIA_ROOT configured correctly? It should be the absolute path to your editor media directory.".format(extracted_path))
source = str(numbasobject) source = str(numbasobject)


theme_path = obj.theme_path if hasattr(obj,'theme_path') else 'default' theme_path = obj.theme_path if hasattr(obj,'theme_path') else 'default'
if not os.path.exists(theme_path):
raise CompileError("Theme not found at {}. Is MEDIA_ROOT configured correctly? It should be the absolute path to your editor media directory.".format(theme_path))


output_location = os.path.join(settings.GLOBAL_SETTINGS['PREVIEW_PATH'], location) output_location = os.path.join(settings.GLOBAL_SETTINGS['PREVIEW_PATH'], location)
numbas_command = [ numbas_command = [
Expand Down

0 comments on commit a4ebdab

Please sign in to comment.