From 977e1904f975c1b757bdb1b5427d3db55a575ac4 Mon Sep 17 00:00:00 2001 From: Diana Huang Date: Wed, 6 Feb 2013 11:25:06 -0500 Subject: [PATCH 01/14] Refactor out time parsing logic into its own class. --- .../xmodule/combined_open_ended_module.py | 33 ++++++------------- .../xmodule/xmodule/peer_grading_module.py | 15 +++++++-- common/lib/xmodule/xmodule/timeinfo.py | 33 +++++++++++++++++++ 3 files changed, 56 insertions(+), 25 deletions(-) create mode 100644 common/lib/xmodule/xmodule/timeinfo.py diff --git a/common/lib/xmodule/xmodule/combined_open_ended_module.py b/common/lib/xmodule/xmodule/combined_open_ended_module.py index 15a101e876..cf1c7ef955 100644 --- a/common/lib/xmodule/xmodule/combined_open_ended_module.py +++ b/common/lib/xmodule/xmodule/combined_open_ended_module.py @@ -7,13 +7,10 @@ from lxml import etree from lxml.html import rewrite_links from path import path import os -import dateutil -import dateutil.parser -import datetime import sys -from timeparse import parse_timedelta from pkg_resources import resource_string +from timeinfo import TimeInfo from .capa_module import only_one, ComplexEncoder from .editing_module import EditingDescriptor @@ -167,26 +164,16 @@ class CombinedOpenEndedModule(XModule): 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: - try: - self.display_due_date = dateutil.parser.parse(display_due_date_string) - except ValueError: - log.error("Could not parse due date {0} for location {1}".format(display_due_date_string, location)) - raise - 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: - try: - self.grace_period = parse_timedelta(grace_period_string) - self.close_date = self.display_due_date + self.grace_period - except: - log.error("Error parsing the grace period {0} for location {1}".format(grace_period_string, location)) - raise - else: - self.grace_period = None - self.close_date = self.display_due_date + + try: + self.timeinfo = TimeInfo(display_due_date_string, grace_period_string) + except: + log.error("Error parsing due date information in location {0}".format(location)) + raise + + self.display_due_date = self.timeinfo.display_due_date # Used for progress / grading. Currently get credit just for # completion (doesn't matter if you self-assessed correct/incorrect). @@ -210,7 +197,7 @@ class CombinedOpenEndedModule(XModule): 'rubric': definition['rubric'], 'display_name': self.display_name, 'accept_file_upload': self.accept_file_upload, - 'close_date': self.close_date + 'close_date': self.timeinfo.close_date } self.task_xml = definition['task_xml'] diff --git a/common/lib/xmodule/xmodule/peer_grading_module.py b/common/lib/xmodule/xmodule/peer_grading_module.py index e853160f4a..afb3f6e0ce 100644 --- a/common/lib/xmodule/xmodule/peer_grading_module.py +++ b/common/lib/xmodule/xmodule/peer_grading_module.py @@ -22,7 +22,6 @@ import json import logging from lxml.html import rewrite_links import os - from pkg_resources import resource_string from .capa_module import only_one, ComplexEncoder from .editing_module import EditingDescriptor @@ -32,6 +31,7 @@ from .stringify import stringify_children from .x_module import XModule from .xml_module import XmlDescriptor from xmodule.modulestore import Location +from timeinfo import TimeInfo from peer_grading_service import peer_grading_service, GradingServiceError @@ -71,6 +71,17 @@ class PeerGradingModule(XModule): self.system = system self.peer_gs = peer_grading_service(self.system) + display_due_date_string = self.metadata.get('due', None) + grace_period_string = self.metadata.get('graceperiod', None) + + try: + self.timeinfo = TimeInfo(display_due_date_string, grace_period_string) + except: + log.error("Error parsing due date information in location {0}".format(location)) + raise + + self.display_due_date = self.timeinfo.display_due_date + self.use_for_single_location = self.metadata.get('use_for_single_location', USE_FOR_SINGLE_LOCATION) if isinstance(self.use_for_single_location, basestring): self.use_for_single_location = (self.use_for_single_location in TRUE_DICT) @@ -534,4 +545,4 @@ class PeerGradingDescriptor(XmlDescriptor, EditingDescriptor): for child in ['task']: add_child(child) - return elt \ No newline at end of file + return elt diff --git a/common/lib/xmodule/xmodule/timeinfo.py b/common/lib/xmodule/xmodule/timeinfo.py new file mode 100644 index 0000000000..dcb198337f --- /dev/null +++ b/common/lib/xmodule/xmodule/timeinfo.py @@ -0,0 +1,33 @@ +import dateutil +import dateutil.parser +import datetime +from timeparse import parse_timedelta + +import logging +log = logging.getLogger(__name__) + +class TimeInfo(object): + """ + This is a simple object that stores datetime information for an XModule + based on the due date string and the grace period string + """ + def __init__(self, display_due_date_string, grace_period_string): + if display_due_date_string is not None: + try: + self.display_due_date = dateutil.parser.parse(display_due_date_string) + except ValueError: + log.error("Could not parse due date {0}".format(display_due_date_string)) + raise + else: + self.display_due_date = None + + if grace_period_string is not None and self.display_due_date: + try: + self.grace_period = parse_timedelta(grace_period_string) + self.close_date = self.display_due_date + self.grace_period + except: + log.error("Error parsing the grace period {0}".format(grace_period_string)) + raise + else: + self.grace_period = None + self.close_date = self.display_due_date From 78948210b8a5837768a2c7f0975dfa2b6c144eb2 Mon Sep 17 00:00:00 2001 From: Diana Huang Date: Wed, 6 Feb 2013 11:50:35 -0500 Subject: [PATCH 02/14] Use different template when peer grading is closed. --- .../xmodule/xmodule/peer_grading_module.py | 36 ++++++++++++++----- .../peer_grading/peer_grading_closed.html | 7 ++++ 2 files changed, 35 insertions(+), 8 deletions(-) create mode 100644 lms/templates/peer_grading/peer_grading_closed.html diff --git a/common/lib/xmodule/xmodule/peer_grading_module.py b/common/lib/xmodule/xmodule/peer_grading_module.py index afb3f6e0ce..ce82da3bef 100644 --- a/common/lib/xmodule/xmodule/peer_grading_module.py +++ b/common/lib/xmodule/xmodule/peer_grading_module.py @@ -20,6 +20,7 @@ import copy import itertools import json import logging +import datetime.datetime from lxml.html import rewrite_links import os from pkg_resources import resource_string @@ -71,6 +72,16 @@ class PeerGradingModule(XModule): self.system = system self.peer_gs = peer_grading_service(self.system) + + self.use_for_single_location = self.metadata.get('use_for_single_location', USE_FOR_SINGLE_LOCATION) + if isinstance(self.use_for_single_location, basestring): + self.use_for_single_location = (self.use_for_single_location in TRUE_DICT) + + self.is_graded = self.metadata.get('is_graded', IS_GRADED) + if isinstance(self.is_graded, basestring): + self.is_graded = (self.is_graded in TRUE_DICT) + + #TODO: do we only want to allow this for single locations? display_due_date_string = self.metadata.get('due', None) grace_period_string = self.metadata.get('graceperiod', None) @@ -82,14 +93,6 @@ class PeerGradingModule(XModule): self.display_due_date = self.timeinfo.display_due_date - self.use_for_single_location = self.metadata.get('use_for_single_location', USE_FOR_SINGLE_LOCATION) - if isinstance(self.use_for_single_location, basestring): - self.use_for_single_location = (self.use_for_single_location in TRUE_DICT) - - self.is_graded = self.metadata.get('is_graded', IS_GRADED) - if isinstance(self.is_graded, basestring): - self.is_graded = (self.is_graded in TRUE_DICT) - self.link_to_location = self.metadata.get('link_to_location', USE_FOR_SINGLE_LOCATION) if self.use_for_single_location ==True: #This will raise an exception if the location is invalid @@ -105,6 +108,11 @@ class PeerGradingModule(XModule): #This could result in an exception, but not wrapping in a try catch block so it moves up the stack self.max_grade = int(self.max_grade) + def closed(self): + if self.timeinfo.close_date is not None and datetime.utcnow() > self.timeinfo.close_date: + return True + return False + def _err_response(self, msg): """ Return a HttpResponse with a json dump with success=False, and the given error message. @@ -124,6 +132,8 @@ class PeerGradingModule(XModule): Needs to be implemented by inheritors. Renders the HTML that students see. @return: """ + if self.closed(): + return self.peer_grading_closed() if not self.use_for_single_location: return self.peer_grading() else: @@ -410,6 +420,16 @@ class PeerGradingModule(XModule): log.exception("Error saving calibration grade, location: {0}, submission_id: {1}, submission_key: {2}, grader_id: {3}".format(location, submission_id, submission_key, grader_id)) return self._err_response('Could not connect to grading service') + def peer_grading_closed(self): + ''' + Show the Peer grading closed template + ''' + html = self.system.render_template('peer_grading/peer_grading_closed.html', { + 'use_for_single_location': self.use_single_location + }) + return html + + def peer_grading(self, get = None): ''' Show a peer grading interface diff --git a/lms/templates/peer_grading/peer_grading_closed.html b/lms/templates/peer_grading/peer_grading_closed.html new file mode 100644 index 0000000000..85a0a6d490 --- /dev/null +++ b/lms/templates/peer_grading/peer_grading_closed.html @@ -0,0 +1,7 @@ +
+ % if use_for_single_location: +

Peer grading for this problem is closed at this time.

+ %else: +

Peer grading is closed at this time.

+ %endif +
From 042ae2da295006d9e7e575feb29497aab4f2aed1 Mon Sep 17 00:00:00 2001 From: Diana Huang Date: Wed, 6 Feb 2013 12:51:52 -0500 Subject: [PATCH 03/14] Fix some bugs with the grading module and make the 'closed' page a little nicer --- common/lib/xmodule/xmodule/peer_grading_module.py | 4 ++-- lms/templates/peer_grading/peer_grading_closed.html | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/common/lib/xmodule/xmodule/peer_grading_module.py b/common/lib/xmodule/xmodule/peer_grading_module.py index ce82da3bef..f91b4d02f9 100644 --- a/common/lib/xmodule/xmodule/peer_grading_module.py +++ b/common/lib/xmodule/xmodule/peer_grading_module.py @@ -20,7 +20,7 @@ import copy import itertools import json import logging -import datetime.datetime +from datetime import datetime from lxml.html import rewrite_links import os from pkg_resources import resource_string @@ -425,7 +425,7 @@ class PeerGradingModule(XModule): Show the Peer grading closed template ''' html = self.system.render_template('peer_grading/peer_grading_closed.html', { - 'use_for_single_location': self.use_single_location + 'use_for_single_location': self.use_for_single_location }) return html diff --git a/lms/templates/peer_grading/peer_grading_closed.html b/lms/templates/peer_grading/peer_grading_closed.html index 85a0a6d490..97d08e64db 100644 --- a/lms/templates/peer_grading/peer_grading_closed.html +++ b/lms/templates/peer_grading/peer_grading_closed.html @@ -1,4 +1,5 @@
+

Peer Grading

% if use_for_single_location:

Peer grading for this problem is closed at this time.

%else: From 04f6d6d0ff2f4d1f616dc9f8e36be0c1c45eee94 Mon Sep 17 00:00:00 2001 From: Diana Huang Date: Wed, 6 Feb 2013 15:00:08 -0500 Subject: [PATCH 04/14] Improve documentation --- common/lib/xmodule/xmodule/peer_grading_module.py | 1 - common/lib/xmodule/xmodule/timeinfo.py | 8 +++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/common/lib/xmodule/xmodule/peer_grading_module.py b/common/lib/xmodule/xmodule/peer_grading_module.py index 99180720dc..0e6beb8c74 100644 --- a/common/lib/xmodule/xmodule/peer_grading_module.py +++ b/common/lib/xmodule/xmodule/peer_grading_module.py @@ -82,7 +82,6 @@ class PeerGradingModule(XModule): if isinstance(self.is_graded, basestring): self.is_graded = (self.is_graded in TRUE_DICT) - #TODO: do we only want to allow this for single locations? display_due_date_string = self.metadata.get('due', None) grace_period_string = self.metadata.get('graceperiod', None) diff --git a/common/lib/xmodule/xmodule/timeinfo.py b/common/lib/xmodule/xmodule/timeinfo.py index dcb198337f..6c6a72e700 100644 --- a/common/lib/xmodule/xmodule/timeinfo.py +++ b/common/lib/xmodule/xmodule/timeinfo.py @@ -8,8 +8,14 @@ log = logging.getLogger(__name__) class TimeInfo(object): """ - This is a simple object that stores datetime information for an XModule + This is a simple object that calculates and stores datetime information for an XModule based on the due date string and the grace period string + + So far it parses out three different pieces of time information: + self.display_due_date - the 'official' due date that gets displayed to students + self.grace_period - the length of the grace period + self.close_date - the real due date + """ def __init__(self, display_due_date_string, grace_period_string): if display_due_date_string is not None: From 97655d03584689d45f5ee053d6eee3a007e5efde Mon Sep 17 00:00:00 2001 From: Diana Huang Date: Thu, 7 Feb 2013 09:40:30 -0500 Subject: [PATCH 05/14] Remove the requirement that the problem peer grading module has to have a certain naming structure --- .../xmodule/xmodule/peer_grading_module.py | 45 ++++++++++++++++++- lms/templates/peer_grading/peer_grading.html | 14 +++++- 2 files changed, 57 insertions(+), 2 deletions(-) diff --git a/common/lib/xmodule/xmodule/peer_grading_module.py b/common/lib/xmodule/xmodule/peer_grading_module.py index 0e6beb8c74..0cb131ae9b 100644 --- a/common/lib/xmodule/xmodule/peer_grading_module.py +++ b/common/lib/xmodule/xmodule/peer_grading_module.py @@ -32,6 +32,7 @@ from .stringify import stringify_children from .x_module import XModule from .xml_module import XmlDescriptor from xmodule.modulestore import Location +from xmodule.modulestore.django import modulestore from timeinfo import TimeInfo from peer_grading_service import peer_grading_service, GradingServiceError @@ -109,10 +110,14 @@ class PeerGradingModule(XModule): self.max_grade = int(self.max_grade) def closed(self): - if self.timeinfo.close_date is not None and datetime.utcnow() > self.timeinfo.close_date: + return self._closed(self.timeinfo) + + def _closed(self, timeinfo): + if timeinfo.close_date is not None and datetime.utcnow() > timeinfo.close_date: return True return False + def _err_response(self, msg): """ Return a HttpResponse with a json dump with success=False, and the given error message. @@ -456,6 +461,44 @@ class PeerGradingModule(XModule): error_text = "Could not get problem list" success = False + + # grab all peer grading module descriptors for this course + peer_grading_modules = modulestore().get_items(['i4x', self.location.org, self.location.course, 'peergrading', None], self.system.course_id) + + # construct a dictionary for fast lookups + module_dict = {} + for module in peer_grading_modules: + linked_location = module.metadata.get("link_to_location", None) + if linked_location: + module_dict[linked_location] = module + + def _find_corresponding_module_for_location(location): + if location in module_dict: + return module_dict[location] + else: + return None + + for problem in problem_list: + problem_location = problem['location'] + descriptor = _find_corresponding_module_for_location(problem_location) + if descriptor: + problem['due'] = descriptor.metadata.get('due', None) + grace_period_string = descriptor.metadata.get('graceperiod', None) + try: + problem_timeinfo = TimeInfo(problem['due'], grace_period_string) + except: + log.error("Malformed due date or grace period string for location {0}".format(problem_location)) + raise + if self._closed(problem_timeinfo): + problem['closed'] = True + else: + problem['closed'] = False + else: + # if we can't find the due date, assume that it doesn't have one + problem['due'] = None + problem['closed'] = False + + ajax_url = self.ajax_url html = self.system.render_template('peer_grading/peer_grading.html', { 'course_id': self.system.course_id, diff --git a/lms/templates/peer_grading/peer_grading.html b/lms/templates/peer_grading/peer_grading.html index d309b4486c..0485b698b2 100644 --- a/lms/templates/peer_grading/peer_grading.html +++ b/lms/templates/peer_grading/peer_grading.html @@ -14,6 +14,7 @@ + @@ -22,7 +23,18 @@ %for problem in problem_list: +
Problem NameDue date Graded Available Required
- ${problem['problem_name']} + %if problem['closed']: + ${problem['problem_name']} + %else: + ${problem['problem_name']} + %endif + + % if problem['due']: + ${problem['due']} + % else: + No due date + % endif ${problem['num_graded']} From 12ff015bff50d482bcc1ac26275e68f4d725aa1f Mon Sep 17 00:00:00 2001 From: Diana Huang Date: Thu, 7 Feb 2013 10:00:05 -0500 Subject: [PATCH 06/14] Include due date parsing in new versioned xmodule. --- .../xmodule/combined_open_ended_modulev1.py | 34 +++++-------------- 1 file changed, 9 insertions(+), 25 deletions(-) diff --git a/common/lib/xmodule/xmodule/combined_open_ended_modulev1.py b/common/lib/xmodule/xmodule/combined_open_ended_modulev1.py index 8bd7df86c1..80e3124a35 100644 --- a/common/lib/xmodule/xmodule/combined_open_ended_modulev1.py +++ b/common/lib/xmodule/xmodule/combined_open_ended_modulev1.py @@ -12,6 +12,7 @@ import sys from pkg_resources import resource_string from .capa_module import only_one, ComplexEncoder +from timeinfo import TimeInfo from .editing_module import EditingDescriptor from .html_checker import check_html from progress import Progress @@ -23,10 +24,6 @@ import self_assessment_module import open_ended_module from combined_open_ended_rubric import CombinedOpenEndedRubric, RubricParsingError from .stringify import stringify_children -import dateutil -import dateutil.parser -import datetime -from timeparse import parse_timedelta log = logging.getLogger("mitx.courseware") @@ -166,26 +163,13 @@ class CombinedOpenEndedV1Module(): 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: - try: - self.display_due_date = dateutil.parser.parse(display_due_date_string) - except ValueError: - log.error("Could not parse due date {0} for location {1}".format(display_due_date_string, location)) - raise - 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: - try: - self.grace_period = parse_timedelta(grace_period_string) - self.close_date = self.display_due_date + self.grace_period - except: - log.error("Error parsing the grace period {0} for location {1}".format(grace_period_string, location)) - raise - else: - self.grace_period = None - self.close_date = self.display_due_date + try: + self.timeinfo = TimeInfo(display_due_date_string, grace_period_string) + except: + log.error("Error parsing due date information in location {0}".format(location)) + raise + self.display_due_date = self.timeinfo.display_due_date # Used for progress / grading. Currently get credit just for # completion (doesn't matter if you self-assessed correct/incorrect). @@ -203,7 +187,7 @@ class CombinedOpenEndedV1Module(): 'rubric': definition['rubric'], 'display_name': self.display_name, 'accept_file_upload': self.accept_file_upload, - 'close_date' : self.close_date, + 'close_date' : self.timeinfo.close_date, } self.task_xml = definition['task_xml'] @@ -722,4 +706,4 @@ class CombinedOpenEndedV1Descriptor(XmlDescriptor, EditingDescriptor): for child in ['task']: add_child(child) - return elt \ No newline at end of file + return elt From cab9bfcd557e6da46b13be2b365f63dee0a6c377 Mon Sep 17 00:00:00 2001 From: Diana Huang Date: Thu, 7 Feb 2013 10:08:34 -0500 Subject: [PATCH 07/14] Minor cleanup --- common/lib/xmodule/xmodule/combined_open_ended_module.py | 1 - common/lib/xmodule/xmodule/peer_grading_module.py | 6 +++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/common/lib/xmodule/xmodule/combined_open_ended_module.py b/common/lib/xmodule/xmodule/combined_open_ended_module.py index 76f2acd843..a3de34b427 100644 --- a/common/lib/xmodule/xmodule/combined_open_ended_module.py +++ b/common/lib/xmodule/xmodule/combined_open_ended_module.py @@ -10,7 +10,6 @@ import os import sys from pkg_resources import resource_string -from timeinfo import TimeInfo from .capa_module import only_one, ComplexEncoder from .editing_module import EditingDescriptor diff --git a/common/lib/xmodule/xmodule/peer_grading_module.py b/common/lib/xmodule/xmodule/peer_grading_module.py index 0cb131ae9b..489459ceda 100644 --- a/common/lib/xmodule/xmodule/peer_grading_module.py +++ b/common/lib/xmodule/xmodule/peer_grading_module.py @@ -463,7 +463,8 @@ class PeerGradingModule(XModule): # grab all peer grading module descriptors for this course - peer_grading_modules = modulestore().get_items(['i4x', self.location.org, self.location.course, 'peergrading', None], self.system.course_id) + peer_grading_modules = modulestore().get_items( + ['i4x', self.location.org, self.location.course, 'peergrading', None], self.system.course_id) # construct a dictionary for fast lookups module_dict = {} @@ -473,6 +474,9 @@ class PeerGradingModule(XModule): module_dict[linked_location] = module def _find_corresponding_module_for_location(location): + ''' + find the peer grading module that links to the given location + ''' if location in module_dict: return module_dict[location] else: From d45c539c6dc6b81b7192a857892a595d196e2826 Mon Sep 17 00:00:00 2001 From: Diana Huang Date: Tue, 12 Feb 2013 10:49:06 -0500 Subject: [PATCH 08/14] Make the peer grading due date a property of the problem metadata, not the peer grading module metadata. --- .../xmodule/xmodule/peer_grading_module.py | 26 ++++++------------- 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/common/lib/xmodule/xmodule/peer_grading_module.py b/common/lib/xmodule/xmodule/peer_grading_module.py index 489459ceda..1cdb35d48c 100644 --- a/common/lib/xmodule/xmodule/peer_grading_module.py +++ b/common/lib/xmodule/xmodule/peer_grading_module.py @@ -96,8 +96,11 @@ class PeerGradingModule(XModule): self.link_to_location = self.metadata.get('link_to_location', USE_FOR_SINGLE_LOCATION) if self.use_for_single_location == True: - #This will raise an exception if the location is invalid - link_to_location_object = Location(self.link_to_location) + self.linked_problem = modulestore().get_instance(self.system.course_id, self.link_to_location) + log.debug("problem metadata: {0}".format(self.linked_problem.metadata)) + due_date = self.linked_problem.metadata.get('peer_grading_due', None) + if due_date: + self.metadata['due'] = due_date self.ajax_url = self.system.ajax_url if not self.ajax_url.endswith("/"): @@ -462,31 +465,18 @@ class PeerGradingModule(XModule): success = False - # grab all peer grading module descriptors for this course - peer_grading_modules = modulestore().get_items( - ['i4x', self.location.org, self.location.course, 'peergrading', None], self.system.course_id) - - # construct a dictionary for fast lookups - module_dict = {} - for module in peer_grading_modules: - linked_location = module.metadata.get("link_to_location", None) - if linked_location: - module_dict[linked_location] = module - def _find_corresponding_module_for_location(location): ''' find the peer grading module that links to the given location ''' - if location in module_dict: - return module_dict[location] - else: - return None + return modulestore().get_instance(self.system.course_id, location) + for problem in problem_list: problem_location = problem['location'] descriptor = _find_corresponding_module_for_location(problem_location) if descriptor: - problem['due'] = descriptor.metadata.get('due', None) + problem['due'] = descriptor.metadata.get('peer_grading_due', None) grace_period_string = descriptor.metadata.get('graceperiod', None) try: problem_timeinfo = TimeInfo(problem['due'], grace_period_string) From 7658cd7a505c8fa1dfcacdd4502f7b86efcd997e Mon Sep 17 00:00:00 2001 From: Diana Huang Date: Tue, 12 Feb 2013 11:10:59 -0500 Subject: [PATCH 09/14] Make the text on the peer grading closed page clearer --- lms/templates/peer_grading/peer_grading_closed.html | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lms/templates/peer_grading/peer_grading_closed.html b/lms/templates/peer_grading/peer_grading_closed.html index 97d08e64db..712ad8b380 100644 --- a/lms/templates/peer_grading/peer_grading_closed.html +++ b/lms/templates/peer_grading/peer_grading_closed.html @@ -1,8 +1,10 @@

Peer Grading

+

The due date has passed, and % if use_for_single_location: -

Peer grading for this problem is closed at this time.

+ peer grading for this problem is closed at this time. %else: -

Peer grading is closed at this time.

+ peer grading is closed at this time. %endif +

From 9ead4ebb352919c3139444e7a2e1d66a489b222e Mon Sep 17 00:00:00 2001 From: Vik Paruchuri Date: Tue, 12 Feb 2013 13:30:56 -0500 Subject: [PATCH 10/14] Wire through ability to skip basic checks --- .../combined_open_ended_modulev1.py | 6 ++++++ .../xmodule/open_ended_grading_classes/open_ended_module.py | 3 ++- .../xmodule/open_ended_grading_classes/openendedchild.py | 1 + 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/common/lib/xmodule/xmodule/open_ended_grading_classes/combined_open_ended_modulev1.py b/common/lib/xmodule/xmodule/open_ended_grading_classes/combined_open_ended_modulev1.py index d1355c1130..ac5b952def 100644 --- a/common/lib/xmodule/xmodule/open_ended_grading_classes/combined_open_ended_modulev1.py +++ b/common/lib/xmodule/xmodule/open_ended_grading_classes/combined_open_ended_modulev1.py @@ -48,6 +48,10 @@ HUMAN_TASK_TYPE = { 'openended' : "edX Assessment", } +#Default value that controls whether or not to skip basic spelling checks in the controller +#Metadata overrides this +SKIP_BASIC_CHECKS = False + class CombinedOpenEndedV1Module(): """ This is a module that encapsulates all open ended grading (self assessment, peer assessment, etc). @@ -146,6 +150,7 @@ class CombinedOpenEndedV1Module(): self.max_attempts = int(self.metadata.get('attempts', MAX_ATTEMPTS)) 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.skip_basic_checks = self.metadata.get('skip_spelling_checks', SKIP_BASIC_CHECKS) display_due_date_string = self.metadata.get('due', None) if display_due_date_string is not None: @@ -187,6 +192,7 @@ class CombinedOpenEndedV1Module(): 'accept_file_upload': self.accept_file_upload, 'close_date' : self.close_date, 's3_interface' : self.system.s3_interface, + 'skip_basic_checks' : self.skip_basic_checks, } self.task_xml = definition['task_xml'] diff --git a/common/lib/xmodule/xmodule/open_ended_grading_classes/open_ended_module.py b/common/lib/xmodule/xmodule/open_ended_grading_classes/open_ended_module.py index 54db1b6557..95c631c8fd 100644 --- a/common/lib/xmodule/xmodule/open_ended_grading_classes/open_ended_module.py +++ b/common/lib/xmodule/xmodule/open_ended_grading_classes/open_ended_module.py @@ -110,7 +110,8 @@ class OpenEndedModule(openendedchild.OpenEndedChild): 'rubric': rubric_string, 'initial_display': self.initial_display, 'answer': self.answer, - 'problem_id': self.display_name + 'problem_id': self.display_name, + 'skip_basic_checks': self.skip_basic_checks, }) updated_grader_payload = json.dumps(parsed_grader_payload) diff --git a/common/lib/xmodule/xmodule/open_ended_grading_classes/openendedchild.py b/common/lib/xmodule/xmodule/open_ended_grading_classes/openendedchild.py index ba8a74cc31..1700dcaa07 100644 --- a/common/lib/xmodule/xmodule/open_ended_grading_classes/openendedchild.py +++ b/common/lib/xmodule/xmodule/open_ended_grading_classes/openendedchild.py @@ -99,6 +99,7 @@ class OpenEndedChild(object): self.accept_file_upload = static_data['accept_file_upload'] self.close_date = static_data['close_date'] self.s3_interface = static_data['s3_interface'] + self.skip_basic_checks = static_data['skip_basic_checks'] # Used for progress / grading. Currently get credit just for # completion (doesn't matter if you self-assessed correct/incorrect). From 482d97d321a13b3ff3743812871273bec83f7280 Mon Sep 17 00:00:00 2001 From: Diana Huang Date: Tue, 12 Feb 2013 13:41:26 -0500 Subject: [PATCH 11/14] Better error messages for when a linked problem cannot be found --- common/lib/xmodule/xmodule/peer_grading_module.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/common/lib/xmodule/xmodule/peer_grading_module.py b/common/lib/xmodule/xmodule/peer_grading_module.py index 1cdb35d48c..48aea0cfd0 100644 --- a/common/lib/xmodule/xmodule/peer_grading_module.py +++ b/common/lib/xmodule/xmodule/peer_grading_module.py @@ -96,8 +96,12 @@ class PeerGradingModule(XModule): self.link_to_location = self.metadata.get('link_to_location', USE_FOR_SINGLE_LOCATION) if self.use_for_single_location == True: - self.linked_problem = modulestore().get_instance(self.system.course_id, self.link_to_location) - log.debug("problem metadata: {0}".format(self.linked_problem.metadata)) + try: + self.linked_problem = modulestore().get_instance(self.system.course_id, self.link_to_location) + except: + log.error("Linked location {0} for peer grading module {1} does not exist".format( + self.link_to_location, self.location)) + raise due_date = self.linked_problem.metadata.get('peer_grading_due', None) if due_date: self.metadata['due'] = due_date @@ -469,7 +473,12 @@ class PeerGradingModule(XModule): ''' find the peer grading module that links to the given location ''' - return modulestore().get_instance(self.system.course_id, location) + try: + return modulestore().get_instance(self.system.course_id, location) + except: + # the linked problem doesn't exist + log.error("Problem {0} does not exist in this course".format(location)) + raise for problem in problem_list: From d0bd7466b413d3a36b6bf1a3ada9144dcdf4f3e7 Mon Sep 17 00:00:00 2001 From: Diana Huang Date: Wed, 20 Feb 2013 11:22:58 -0500 Subject: [PATCH 12/14] Fix import statement for TimeInfo --- .../open_ended_grading_classes/combined_open_ended_modulev1.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/lib/xmodule/xmodule/open_ended_grading_classes/combined_open_ended_modulev1.py b/common/lib/xmodule/xmodule/open_ended_grading_classes/combined_open_ended_modulev1.py index bba223cb7e..bf6c51ac15 100644 --- a/common/lib/xmodule/xmodule/open_ended_grading_classes/combined_open_ended_modulev1.py +++ b/common/lib/xmodule/xmodule/open_ended_grading_classes/combined_open_ended_modulev1.py @@ -2,7 +2,7 @@ import json import logging from lxml import etree from lxml.html import rewrite_links -from timeinfo import TimeInfo +from xmodule.timeinfo import TimeInfo from xmodule.capa_module import only_one, ComplexEncoder from xmodule.editing_module import EditingDescriptor from xmodule.html_checker import check_html From 7be76fe1244a88eb9c8edec3fff2cab21442ca51 Mon Sep 17 00:00:00 2001 From: Vik Paruchuri Date: Wed, 20 Feb 2013 11:54:57 -0500 Subject: [PATCH 13/14] Fix tests --- common/lib/xmodule/xmodule/tests/test_combined_open_ended.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/common/lib/xmodule/xmodule/tests/test_combined_open_ended.py b/common/lib/xmodule/xmodule/tests/test_combined_open_ended.py index ef6344eb57..5f6496f823 100644 --- a/common/lib/xmodule/xmodule/tests/test_combined_open_ended.py +++ b/common/lib/xmodule/xmodule/tests/test_combined_open_ended.py @@ -48,6 +48,7 @@ class OpenEndedChildTest(unittest.TestCase): 'close_date': None, 's3_interface' : "", 'open_ended_grading_interface' : {}, + 'skip_basic_checks' : False, } definition = Mock() descriptor = Mock() @@ -167,6 +168,7 @@ class OpenEndedModuleTest(unittest.TestCase): 'close_date': None, 's3_interface' : test_util_open_ended.S3_INTERFACE, 'open_ended_grading_interface' : test_util_open_ended.OPEN_ENDED_GRADING_INTERFACE, + 'skip_basic_checks' : False, } oeparam = etree.XML(''' @@ -301,6 +303,7 @@ class CombinedOpenEndedModuleTest(unittest.TestCase): 'close_date' : "", 's3_interface' : test_util_open_ended.S3_INTERFACE, 'open_ended_grading_interface' : test_util_open_ended.OPEN_ENDED_GRADING_INTERFACE, + 'skip_basic_checks' : False, } oeparam = etree.XML(''' From c48998b30a7644043ff8437e3b7880f3cb39c0fa Mon Sep 17 00:00:00 2001 From: Vik Paruchuri Date: Wed, 20 Feb 2013 11:57:29 -0500 Subject: [PATCH 14/14] Fix SA tests --- common/lib/xmodule/xmodule/tests/test_self_assessment.py | 1 + 1 file changed, 1 insertion(+) diff --git a/common/lib/xmodule/xmodule/tests/test_self_assessment.py b/common/lib/xmodule/xmodule/tests/test_self_assessment.py index fe55c88e82..83f6c0a8bc 100644 --- a/common/lib/xmodule/xmodule/tests/test_self_assessment.py +++ b/common/lib/xmodule/xmodule/tests/test_self_assessment.py @@ -51,6 +51,7 @@ class SelfAssessmentTest(unittest.TestCase): 'close_date': None, 's3_interface' : test_util_open_ended.S3_INTERFACE, 'open_ended_grading_interface' : test_util_open_ended.OPEN_ENDED_GRADING_INTERFACE, + 'skip_basic_checks' : False, } self.module = SelfAssessmentModule(test_system, self.location,