From 5e21deb4e04d14a28c5c5957835f4a12f850e9ae Mon Sep 17 00:00:00 2001 From: Giulio Gratta Date: Thu, 9 Nov 2017 16:29:58 -0800 Subject: [PATCH] Makes xblock due_date & graceperiod aware - Adds mixin to check subsection duedate and course graceperiod - Pushes version to 0.1.8 --- freetextresponse/freetextresponse.py | 15 +++++++-- freetextresponse/mixins.py | 33 +++++++++++++++++++ .../templates/freetextresponse_view.html | 14 ++++---- package.json | 2 +- setup.py | 2 +- 5 files changed, 56 insertions(+), 10 deletions(-) create mode 100644 freetextresponse/mixins.py diff --git a/freetextresponse/freetextresponse.py b/freetextresponse/freetextresponse.py index 836aeb9d..65b2884d 100644 --- a/freetextresponse/freetextresponse.py +++ b/freetextresponse/freetextresponse.py @@ -18,10 +18,11 @@ from xblock.fragment import Fragment from xblock.validation import ValidationMessage from xblockutils.studio_editable import StudioEditableXBlockMixin +from .mixins import EnforceDueDates @XBlock.needs("i18n") -class FreeTextResponse(StudioEditableXBlockMixin, XBlock): +class FreeTextResponse(EnforceDueDates, StudioEditableXBlockMixin, XBlock): # pylint: disable=too-many-ancestors, too-many-instance-attributes """ Enables instructors to create questions with free-text responses. @@ -264,6 +265,7 @@ def student_view(self, context={}): 'problem_progress': self._get_problem_progress(), 'prompt': self.prompt, 'student_answer': self.student_answer, + 'is_past_due': self.is_past_due(), 'used_attempts_feedback': self._get_used_attempts_feedback(), 'visibility_class': self._get_indicator_visibility_class(), 'word_count_message': self._get_word_count_message(), @@ -539,6 +541,15 @@ def _get_user_alert(self, ignore_attempts=False): result = self._get_invalid_word_count_message(ignore_attempts) return result + def _can_submit(self): + if self.is_past_due(): + return False + if self.max_attempts == 0: + return True + if self.count_attempts < self.max_attempts: + return True + return False + @XBlock.json_handler def submit(self, data, suffix=''): # pylint: disable=unused-argument @@ -547,7 +558,7 @@ def submit(self, data, suffix=''): """ # Fails if the UI submit/save buttons were shut # down on the previous sumbisson - if self.max_attempts == 0 or self.count_attempts < self.max_attempts: + if self._can_submit(): self.student_answer = data['student_answer'] # Counting the attempts and publishing a score # even if word count is invalid. diff --git a/freetextresponse/mixins.py b/freetextresponse/mixins.py new file mode 100644 index 00000000..1e10ab42 --- /dev/null +++ b/freetextresponse/mixins.py @@ -0,0 +1,33 @@ +""" +Mixins for the Free Text Response XBlock +""" +import datetime +import pytz +from django.conf import settings + +TIME_ZONE = pytz.timezone(getattr(settings, 'TIME_ZONE', pytz.utc.zone)) + + +class EnforceDueDates(object): # pylint: disable=too-few-public-methods + """ + xBlock Mixin to allow xblocks to check the due date + (taking the graceperiod into account) of the + subsection in which they are placed + """ + + # These values are pulled from platform. + # They are defaulted to None for tests. + due = None + graceperiod = None + + def is_past_due(self): + """ + Determine if component is past-due + """ + now = datetime.datetime.utcnow().replace(tzinfo=TIME_ZONE) + if self.due is not None: + due_date = self.due + if self.graceperiod is not None: + due_date = due_date + self.graceperiod + return now > due_date + return False diff --git a/freetextresponse/templates/freetextresponse_view.html b/freetextresponse/templates/freetextresponse_view.html index 2ddf367d..bd63f654 100644 --- a/freetextresponse/templates/freetextresponse_view.html +++ b/freetextresponse/templates/freetextresponse_view.html @@ -12,12 +12,14 @@

{{ display_name }}

{{ submitted_message }}
- - + {% if not is_past_due %} + + + {% endif %}
{{ used_attempts_feedback }}
{{ user_alert }}
diff --git a/package.json b/package.json index 6aea1794..ed366d3a 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "xblock-free-text-response", "title": "FreeTextResponse XBlock", "description": "Enables instructors to create questions with free-text responses.", - "version": "0.1.7", + "version": "0.1.8", "homepage": "https://github.com/Stanford-Online/xblock-free-text-response", "author": { "name": "Azim Pradhan", diff --git a/setup.py b/setup.py index 1bd74323..f2c09629 100644 --- a/setup.py +++ b/setup.py @@ -27,7 +27,7 @@ def run_tests(self): setup( name="xblock-free-text-response", - version="0.1.7", + version="0.1.8", description="Enables instructors to create questions with free-text responses.", license='AGPL-3.0', packages=[