diff --git a/numbas_lti/forms.py b/numbas_lti/forms.py index 885efd41..fd6e5b56 100644 --- a/numbas_lti/forms.py +++ b/numbas_lti/forms.py @@ -205,6 +205,7 @@ def save(self, commit=True): class CreateExamForm(ModelForm): package = forms.FileField(required=False) + class Meta: model = Exam fields = ['package','retrieve_url','rest_url'] diff --git a/numbas_lti/models.py b/numbas_lti/models.py index 072721cd..0ad9adbf 100644 --- a/numbas_lti/models.py +++ b/numbas_lti/models.py @@ -285,6 +285,34 @@ def duration(self): return self._duration + def get_feedback_settings(self, completed, review_allowed): + content = self.source() + + def get(node, attr, default=None): + return node.get(attr, node.get(attr.lower(), default)) + + feedback = get(content, 'feedback', {}) + + def resolve_feedback_setting(setting): + return { + 'always': True, + 'oncompletion': completed, + 'inreview': review_allowed, + 'never': False, + }[setting] + + info = [ + (_('Maximum available score'), get(feedback,'showTotalMark', 'always')), + (_('Whether answers are correct'), get(feedback,'showAnswerState', 'always')), + (_('Awarded scores'), get(feedback,'showActualMark', 'always')), + (_('Feedback messages for each question part'), get(feedback, 'showPartFeedbackMessages', 'always')), + (_('Expected answers to each part'), get(feedback, 'revealExpectedAnswers', 'inreview')), + (_('Advice for each question'), get(feedback, 'revealAdvice', 'inreview')), + ] + + return info + + GRADING_METHODS = [ ('highest',_('Highest score')), ('last',_('Last attempt')), diff --git a/numbas_lti/templates/numbas_lti/review_not_allowed.html b/numbas_lti/templates/numbas_lti/review_not_allowed.html deleted file mode 100644 index 1178cc46..00000000 --- a/numbas_lti/templates/numbas_lti/review_not_allowed.html +++ /dev/null @@ -1 +0,0 @@ -{% load i18n %}{% blocktranslate with time_iso=allow_review_from|date:"c" time=allow_review_from %}Review will be available from .{% endblocktranslate %} diff --git a/numbas_lti/templates/numbas_lti/show_attempts.html b/numbas_lti/templates/numbas_lti/show_attempts.html index 65d9dafe..559e6733 100644 --- a/numbas_lti/templates/numbas_lti/show_attempts.html +++ b/numbas_lti/templates/numbas_lti/show_attempts.html @@ -71,15 +71,9 @@

{% if attempt.completed %} - {% if attempt.review_allowed %} - {% icon 'play' %} {% translate "Review this attempt" %} - - {% else %} - {% if attempt.resource.allow_review_from %} - {% include "numbas_lti/review_not_allowed.html" with allow_review_from=attempt.resource.allow_review_from %} - {% endif %} - {% endif %} + {% icon 'play' %} {% translate "Review this attempt" %} + {% else %} {% if attempt.resume_allowed %} @@ -92,6 +86,34 @@

{% endfor %} + + {% if resource.show_marks_when == 'review' and resource.allow_review_from %} +

{% blocktranslate with time_iso=resource.allow_review_from|date:"c" time=resource.allow_review_from %}Full review will be available from .{% endblocktranslate %}

+ {% endif %} + +

{% blocktranslate %}These are the feedback settings for this activity:{% endblocktranslate %}

+ + + + + + + + + + {% for label, when in exam_info %} + + + + + {% endfor %} + +
{% translate "Feedback" %}{% translate "Available from" %}
{{label}} + {% if when == 'always' %}{% translate "The start of the attempt" %}{% endif %} + {% if when == 'oncompletion' %}{% translate "Immediately after finishing" %}{% endif %} + {% if when == 'inreview' %}{% translate "When full review is allowed" %}{% endif %} + {% if when == 'never' %}{% translate "Never" %}{% endif %} +
{% include "numbas_lti/footer.html" %} diff --git a/numbas_lti/views/attempt.py b/numbas_lti/views/attempt.py index c8bc93c8..92376ea8 100644 --- a/numbas_lti/views/attempt.py +++ b/numbas_lti/views/attempt.py @@ -200,8 +200,11 @@ def dispatch(self,request,*args,**kwargs): def get_context_data(self,*args,**kwargs): context = super(ShowAttemptsView,self).get_context_data(*args,**kwargs) - context['resource'] = self.request.resource + resource = self.request.resource + + context['resource'] = resource context['can_start_new_attempt'] = self.request.resource.can_start_new_attempt(self.request.user) + context['exam_info'] = resource.exam.get_feedback_settings(completed=False,review_allowed=False) return context @@ -251,12 +254,6 @@ def get_mode(self): raise PermissionDenied(gettext("You're not allowed to review this attempt.")) if attempt.completed(): - if not attempt.review_allowed(): - if attempt.resource.allow_review_from: - template = get_template('numbas_lti/review_not_allowed.html') - raise PermissionDenied(template.render({'allow_review_from': attempt.resource.allow_review_from})) - else: - raise PermissionDenied(_("You're not allowed to review this attempt.")) return 'review' else: return 'normal' @@ -371,6 +368,7 @@ def get_data(self): 'numbas.user_role': 'instructor' if request_is_instructor(self.request) else 'student', 'numbas.duration_extension.amount': duration_extension_amount, 'numbas.duration_extension.units': duration_extension_units, + 'numbas.review_allowed': attempt.review_allowed(), } now = datetime.datetime.now().timestamp()