Commit 85abc435 by Diana Huang

Add in the ability to handle due dates and grace periods

parent f9cca8be
...@@ -7,7 +7,11 @@ from lxml import etree ...@@ -7,7 +7,11 @@ from lxml import etree
from lxml.html import rewrite_links from lxml.html import rewrite_links
from path import path from path import path
import os import os
import dateutil
import dateutil.parser
import datetime
import sys import sys
from timeparse import parse_timedelta
from pkg_resources import resource_string from pkg_resources import resource_string
...@@ -155,12 +159,27 @@ class CombinedOpenEndedModule(XModule): ...@@ -155,12 +159,27 @@ class CombinedOpenEndedModule(XModule):
self.attempts = instance_state.get('attempts', 0) self.attempts = instance_state.get('attempts', 0)
#Allow reset is true if student has failed the criteria to move to the next child task #Allow reset is true if student has failed the criteria to move to the next child task
self.allow_reset = instance_state.get('ready_to_reset', False) self.allow_reset = instance_state.get('ready_to_reset', False)
self.max_attempts = int(self.metadata.get('attempts', MAX_ATTEMPTS)) self.max_attempts = int(self.metadata.get('attempts', MAX_ATTEMPTS))
self.is_scored = self.metadata.get('is_graded', IS_SCORED) in TRUE_DICT self.is_scored = self.metadata.get('is_graded', IS_SCORED) in TRUE_DICT
self.accept_file_upload = self.metadata.get('accept_file_upload', ACCEPT_FILE_UPLOAD) in TRUE_DICT self.accept_file_upload = self.metadata.get('accept_file_upload', ACCEPT_FILE_UPLOAD) in TRUE_DICT
display_due_date_string = self.metadata.get('due', None)
if display_due_date_string is not None:
self.display_due_date = dateutil.parser.parse(display_due_date_string)
else:
self.display_due_date = None
grace_period_string = self.metadata.get('graceperiod', None)
if grace_period_string is not None and self.display_due_date:
self.grace_period = parse_timedelta(grace_period_string)
self.close_date = self.display_due_date + self.grace_period
else:
self.grace_period = None
self.close_date = self.display_due_date
# Used for progress / grading. Currently get credit just for # Used for progress / grading. Currently get credit just for
# completion (doesn't matter if you self-assessed correct/incorrect). # completion (doesn't matter if you self-assessed correct/incorrect).
self._max_score = int(self.metadata.get('max_score', MAX_SCORE)) self._max_score = int(self.metadata.get('max_score', MAX_SCORE))
...@@ -189,12 +208,12 @@ class CombinedOpenEndedModule(XModule): ...@@ -189,12 +208,12 @@ class CombinedOpenEndedModule(XModule):
self.setup_next_task() self.setup_next_task()
def closed(self): def closed(self):
return True ''' Is the student still allowed to submit answers? '''
#''' Is the student still allowed to submit answers? ''' if self.attempts == self.max_attempts:
#if self.attempts == self.max_attempts: return True
# return True if self.close_date is not None and datetime.datetime.utcnow() > self.close_date:
#if self.close_date is not None and datetime.datetime.utcnow() > self.close_date: return True
# return True
def get_tag_name(self, xml): def get_tag_name(self, xml):
......
...@@ -2,9 +2,14 @@ ...@@ -2,9 +2,14 @@
Helper functions for handling time in the format we like. Helper functions for handling time in the format we like.
""" """
import time import time
import re
from datetime import timedelta
TIME_FORMAT = "%Y-%m-%dT%H:%M" TIME_FORMAT = "%Y-%m-%dT%H:%M"
TIMEDELTA_REGEX = re.compile(r'^((?P<days>\d+?) day(?:s?))?(\s)?((?P<hours>\d+?) hour(?:s?))?(\s)?((?P<minutes>\d+?) minute(?:s)?)?(\s)?((?P<seconds>\d+?) second(?:s)?)?$')
def parse_time(time_str): def parse_time(time_str):
""" """
Takes a time string in TIME_FORMAT Takes a time string in TIME_FORMAT
...@@ -20,3 +25,23 @@ def stringify_time(time_struct): ...@@ -20,3 +25,23 @@ def stringify_time(time_struct):
Convert a time struct to a string Convert a time struct to a string
""" """
return time.strftime(TIME_FORMAT, time_struct) return time.strftime(TIME_FORMAT, time_struct)
def parse_timedelta(time_str):
"""
time_str: A string with the following components:
<D> day[s] (optional)
<H> hour[s] (optional)
<M> minute[s] (optional)
<S> second[s] (optional)
Returns a datetime.timedelta parsed from the string
"""
parts = TIMEDELTA_REGEX.match(time_str)
if not parts:
return
parts = parts.groupdict()
time_params = {}
for (name, param) in parts.iteritems():
if param:
time_params[name] = int(param)
return timedelta(**time_params)
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