diff --git a/common/lib/capa/capa/capa_problem.py b/common/lib/capa/capa/capa_problem.py index 35c8eaf635..ee24ebd031 100644 --- a/common/lib/capa/capa/capa_problem.py +++ b/common/lib/capa/capa/capa_problem.py @@ -29,6 +29,7 @@ from xml.sax.saxutils import unescape import calc from correctmap import CorrectMap +from datetime import datetime import eia import inputtypes from util import contextualize_text, convert_files_to_filenames @@ -204,6 +205,21 @@ class LoncapaProblem(object): ''' return any([self.correct_map.is_queued(answer_id) for answer_id in self.correct_map]) + + def get_recentmost_queuetime(self): + ''' + Returns a DateTime object that represents the timestamp of the most recent queueing request, or None if not queued + ''' + if not self.is_queued(): + return None + + # Get a list of timestamps of all queueing requests, then convert it to a DateTime object + queuetimes = [self.correct_map.get_queuetime_str(answer_id) for answer_id in self.correct_map if self.correct_map.is_queued(answer_id)] + queuetimes = [datetime.strptime(qt,'%Y%m%d%H%M%S') for qt in queuetimes] + + return max(queuetimes) + + def grade_answers(self, answers): ''' Grade student responses. Called by capa_module.check_problem. diff --git a/common/lib/xmodule/xmodule/capa_module.py b/common/lib/xmodule/xmodule/capa_module.py index 6b6c0991c5..8f570bcf6c 100644 --- a/common/lib/xmodule/xmodule/capa_module.py +++ b/common/lib/xmodule/xmodule/capa_module.py @@ -7,7 +7,8 @@ import traceback import re import sys -from datetime import timedelta +from datetime import datetime, timedelta +from django.conf import settings from lxml import etree from pkg_resources import resource_string @@ -462,11 +463,13 @@ class CapaModule(XModule): self.system.track_function('save_problem_check_fail', event_info) raise NotFoundError('Problem must be reset before it can be checked again') - # Problem queued. Student should not be able to submit - ''' + # Problem queued. Students must wait XQUEUE_WAITTIME_BETWEEN_REQUESTS if self.lcp.is_queued(): - return {'success': False, 'html': 'Already queued'} - ''' + current_time = datetime.now() + prev_submit_time = self.lcp.get_recentmost_queuetime() + if (current_time-prev_submit_time).total_seconds() < settings.XQUEUE_WAITTIME_BETWEEN_REQUESTS: + msg = 'You must wait %d seconds between queueing requests' % settings.XQUEUE_WAITTIME_BETWEEN_REQUESTS + return {'success': msg, 'html': ''} try: old_state = self.lcp.get_state() diff --git a/lms/envs/dev.py b/lms/envs/dev.py index a76e6de262..fe12ee3322 100644 --- a/lms/envs/dev.py +++ b/lms/envs/dev.py @@ -63,6 +63,7 @@ XQUEUE_INTERFACE = { }, "basic_auth": ('anant', 'agarwal'), } +XQUEUE_WAITTIME_BETWEEN_REQUESTS = 5 # seconds # Make the keyedcache startup warnings go away CACHE_TIMEOUT = 0