Commit 95ad1826 by cahrens

Hide show_timezone from Advanced Settings and migrate courses with…

Hide show_timezone from Advanced Settings and migrate courses with show_timezone=False to using due_date_display_format.
parent 08d99429
...@@ -20,7 +20,8 @@ class CourseMetadata(object): ...@@ -20,7 +20,8 @@ class CourseMetadata(object):
'enrollment_end', 'enrollment_end',
'tabs', 'tabs',
'graceperiod', 'graceperiod',
'checklists'] 'checklists',
'show_timezone']
@classmethod @classmethod
def fetch(cls, course_location): def fetch(cls, course_location):
......
...@@ -337,7 +337,10 @@ class CourseFields(object): ...@@ -337,7 +337,10 @@ class CourseFields(object):
"action_external": False}]} "action_external": False}]}
]) ])
info_sidebar_name = String(scope=Scope.settings, default='Course Handouts') info_sidebar_name = String(scope=Scope.settings, default='Course Handouts')
show_timezone = Boolean(help="True if timezones should be shown on dates in the courseware", scope=Scope.settings, default=True) show_timezone = Boolean(
help="True if timezones should be shown on dates in the courseware. Deprecated in favor of due_date_display_format.",
scope=Scope.settings, default=True
)
due_date_display_format = String( due_date_display_format = String(
help="Format supported by strftime for displaying due dates. Takes precedence over show_timezone.", help="Format supported by strftime for displaying due dates. Takes precedence over show_timezone.",
scope=Scope.settings, default=None scope=Scope.settings, default=None
...@@ -395,7 +398,13 @@ class CourseDescriptor(CourseFields, SequenceDescriptor): ...@@ -395,7 +398,13 @@ class CourseDescriptor(CourseFields, SequenceDescriptor):
elif isinstance(self.location, CourseLocator): elif isinstance(self.location, CourseLocator):
self.wiki_slug = self.location.course_id or self.display_name self.wiki_slug = self.location.course_id or self.display_name
msg = None if self.due_date_display_format is None and self.show_timezone is False:
# For existing courses with show_timezone set to False (and no due_date_display_format specified),
# set the due_date_display_format to what would have been shown previously (with no timezone).
# Then remove show_timezone so that if the user clears out the due_date_display_format,
# they get the default date display.
self.due_date_display_format = u"%b %d, %Y at %H:%M"
delattr(self, 'show_timezone')
# NOTE: relies on the modulestore to call set_grading_policy() right after # NOTE: relies on the modulestore to call set_grading_policy() right after
# init. (Modulestore is in charge of figuring out where to load the policy from) # init. (Modulestore is in charge of figuring out where to load the policy from)
......
...@@ -12,12 +12,6 @@ def test_get_default_time_display(): ...@@ -12,12 +12,6 @@ def test_get_default_time_display():
assert_equals( assert_equals(
"Mar 12, 1992 at 15:03 UTC", "Mar 12, 1992 at 15:03 UTC",
get_default_time_display(test_time)) get_default_time_display(test_time))
assert_equals(
"Mar 12, 1992 at 15:03 UTC",
get_default_time_display(test_time, True))
assert_equals(
"Mar 12, 1992 at 15:03",
get_default_time_display(test_time, False))
def test_get_default_time_display_notz(): def test_get_default_time_display_notz():
...@@ -25,12 +19,6 @@ def test_get_default_time_display_notz(): ...@@ -25,12 +19,6 @@ def test_get_default_time_display_notz():
assert_equals( assert_equals(
"Mar 12, 1992 at 15:03 UTC", "Mar 12, 1992 at 15:03 UTC",
get_default_time_display(test_time)) get_default_time_display(test_time))
assert_equals(
"Mar 12, 1992 at 15:03 UTC",
get_default_time_display(test_time, True))
assert_equals(
"Mar 12, 1992 at 15:03",
get_default_time_display(test_time, False))
def test_get_time_display_return_empty(): def test_get_time_display_return_empty():
...@@ -42,17 +30,16 @@ def test_get_time_display_return_empty(): ...@@ -42,17 +30,16 @@ def test_get_time_display_return_empty():
def test_get_time_display(): def test_get_time_display():
test_time = datetime(1992, 3, 12, 15, 3, 30, tzinfo=UTC) test_time = datetime(1992, 3, 12, 15, 3, 30, tzinfo=UTC)
assert_equals("dummy text", get_time_display(test_time, 'dummy text')) assert_equals("dummy text", get_time_display(test_time, 'dummy text'))
assert_equals("Mar 12 1992", get_time_display(test_time, '%b %d %Y', True)) assert_equals("Mar 12 1992", get_time_display(test_time, '%b %d %Y'))
assert_equals("Mar 12 1992 UTC", get_time_display(test_time, '%b %d %Y %Z', False)) assert_equals("Mar 12 1992 UTC", get_time_display(test_time, '%b %d %Y %Z'))
assert_equals("Mar 12 15:03", get_time_display(test_time, '%b %d %H:%M', False)) assert_equals("Mar 12 15:03", get_time_display(test_time, '%b %d %H:%M'))
def test_get_time_pass_through(): def test_get_time_pass_through():
test_time = datetime(1992, 3, 12, 15, 3, 30, tzinfo=UTC) test_time = datetime(1992, 3, 12, 15, 3, 30, tzinfo=UTC)
assert_equals("Mar 12, 1992 at 15:03 UTC", get_time_display(test_time)) assert_equals("Mar 12, 1992 at 15:03 UTC", get_time_display(test_time))
assert_equals("Mar 12, 1992 at 15:03", get_time_display(test_time, None, False)) assert_equals("Mar 12, 1992 at 15:03 UTC", get_time_display(test_time, None))
assert_equals("Mar 12, 1992 at 15:03", get_time_display(test_time, "%", False)) assert_equals("Mar 12, 1992 at 15:03 UTC", get_time_display(test_time, "%"))
assert_equals("Mar 12, 1992 at 15:03 UTC", get_time_display(test_time, "%", True))
# pylint: disable=W0232 # pylint: disable=W0232
...@@ -72,12 +59,6 @@ def test_get_default_time_display_no_tzname(): ...@@ -72,12 +59,6 @@ def test_get_default_time_display_no_tzname():
assert_equals( assert_equals(
"Mar 12, 1992 at 15:03-0300", "Mar 12, 1992 at 15:03-0300",
get_default_time_display(test_time)) get_default_time_display(test_time))
assert_equals(
"Mar 12, 1992 at 15:03-0300",
get_default_time_display(test_time, True))
assert_equals(
"Mar 12, 1992 at 15:03",
get_default_time_display(test_time, False))
def test_almost_same_datetime(): def test_almost_same_datetime():
......
...@@ -2,51 +2,46 @@ ...@@ -2,51 +2,46 @@
Convenience methods for working with datetime objects Convenience methods for working with datetime objects
""" """
from datetime import timedelta from datetime import timedelta
from django.utils.translation import ugettext as _
def get_default_time_display(dt, show_timezone=True): def get_default_time_display(dt):
""" """
Converts a datetime to a string representation. This is the default Converts a datetime to a string representation. This is the default
representation used in Studio and LMS. representation used in Studio and LMS.
It is of the form "Apr 09, 2013 at 16:00" or "Apr 09, 2013 at 16:00 UTC", It is of the form "Apr 09, 2013 at 16:00 UTC".
depending on the value of show_timezone.
If None is passed in for dt, an empty string will be returned. If None is passed in for dt, an empty string will be returned.
The default value of show_timezone is True.
""" """
if dt is None: if dt is None:
return u"" return u""
timezone = u"" if dt.tzinfo is not None:
if show_timezone: try:
if dt.tzinfo is not None: timezone = u" " + dt.tzinfo.tzname(dt)
try: except NotImplementedError:
timezone = u" " + dt.tzinfo.tzname(dt) timezone = dt.strftime('%z')
except NotImplementedError: else:
timezone = dt.strftime('%z') timezone = u" UTC"
else: return unicode(dt.strftime(u"%b %d, %Y at %H:%M{tz}")).format(
timezone = u" UTC" tz=timezone).strip()
return unicode(dt.strftime(u"%b %d, %Y {at} %H:%M{tz}")).format(
at=_(u"at"), tz=timezone).strip()
def get_time_display(dt, format_string=None):
def get_time_display(dt, format_string=None, show_timezone=True):
""" """
Converts a datetime to a string representation. Converts a datetime to a string representation.
If None is passed in for dt, an empty string will be returned. If None is passed in for dt, an empty string will be returned.
If the format_string is None, or if format_string is improperly If the format_string is None, or if format_string is improperly
formatted, this method will return the value from `get_default_time_display` formatted, this method will return the value from `get_default_time_display`.
(passing in the show_timezone argument).
If the format_string is specified, show_timezone is ignored.
format_string should be a unicode string that is a valid argument for datetime's strftime method. format_string should be a unicode string that is a valid argument for datetime's strftime method.
""" """
if dt is None or format_string is None: if dt is None or format_string is None:
return get_default_time_display(dt, show_timezone) return get_default_time_display(dt)
try: try:
return unicode(dt.strftime(format_string)) return unicode(dt.strftime(format_string))
except ValueError: except ValueError:
return get_default_time_display(dt, show_timezone) return get_default_time_display(dt)
def almost_same_datetime(dt1, dt2, allowed_delta=timedelta(minutes=1)): def almost_same_datetime(dt1, dt2, allowed_delta=timedelta(minutes=1)):
......
{"course/2013_fall": {"tabs": [{"type": "courseware"}, {"type": "course_info", "name": "Course Info"}, {"type": "textbooks"}, {"type": "discussion", "name": "Discussion"}, {"type": "wiki", "name": "Wiki"}, {"type": "progress", "name": "Progress"}], "display_name": "due_date", "discussion_topics": {"General": {"id": "i4x-edX-due_date-course-2013_fall"}}}} {"course/2013_fall": {"tabs": [{"type": "courseware"}, {"type": "course_info", "name": "Course Info"}, {"type": "textbooks"}, {"type": "discussion", "name": "Discussion"}, {"type": "wiki", "name": "Wiki"}, {"type": "progress", "name": "Progress"}], "display_name": "due_date", "discussion_topics": {"General": {"id": "i4x-edX-due_date-course-2013_fall"}}, "show_timezone": "false"}}
\ No newline at end of file \ No newline at end of file
...@@ -14,7 +14,7 @@ from student.models import CourseEnrollment ...@@ -14,7 +14,7 @@ from student.models import CourseEnrollment
from student.tests.factories import AdminFactory from student.tests.factories import AdminFactory
from mitxmako.middleware import MakoMiddleware from mitxmako.middleware import MakoMiddleware
from xmodule.modulestore.django import modulestore from xmodule.modulestore.django import modulestore, clear_existing_modulestores
import courseware.views as views import courseware.views as views
from xmodule.modulestore import Location from xmodule.modulestore import Location
...@@ -254,6 +254,8 @@ class ViewsTestCase(TestCase): ...@@ -254,6 +254,8 @@ class ViewsTestCase(TestCase):
def set_show_timezone(show_timezone): def set_show_timezone(show_timezone):
""" """
Sets the show_timezone property and returns value from get_text function. Sets the show_timezone property and returns value from get_text function.
Note that show_timezone is deprecated and cannot be set by the user.
""" """
course.show_timezone = show_timezone course.show_timezone = show_timezone
course.save() course.save()
...@@ -268,38 +270,51 @@ class ViewsTestCase(TestCase): ...@@ -268,38 +270,51 @@ class ViewsTestCase(TestCase):
return get_text() return get_text()
request.user = self.user request.user = self.user
# Clear out the modulestores, so we start with the test course in its default state.
clear_existing_modulestores()
course = modulestore().get_course("edX/due_date/2013_fall") course = modulestore().get_course("edX/due_date/2013_fall")
# Default case show_timezone = True time_with_utc = "due Sep 18, 2013 at 11:30 UTC"
text = set_show_timezone(True) time_without_utc = "due Sep 18, 2013 at 11:30"
self.assertIn("due Sep 18, 2013 at 11:30 UTC", text)
# The test course being used has show_timezone = False in the policy file
# show_timezone = False # (and no due_date_display_format set). This is to test our backwards compatibility--
text = set_show_timezone(False) # in course_module's init method, the date_display_format will be set accordingly to
self.assertNotIn("due Sep 18, 2013 at 11:30 UTC", text) # remove the timezone.
self.assertIn("due Sep 18, 2013 at 11:30", text) text = get_text()
self.assertIn(time_without_utc, text)
self.assertNotIn(time_with_utc, text)
# Test that show_timezone has been cleared (which means you get the default value of True).
self.assertTrue(course.show_timezone)
# Clear out the due date format and verify you get the default (with timezone).
delattr(course, 'due_date_display_format')
course.save()
text = get_text()
self.assertIn(time_with_utc, text)
# Same for setting the due date to None
text = set_due_date_format(None)
self.assertIn(time_with_utc, text)
# plain text due date # plain text due date
text = set_due_date_format("foobar") text = set_due_date_format("foobar")
self.assertNotIn("due Sep 18, 2013 at 11:30", text) self.assertNotIn(time_with_utc, text)
self.assertIn("due foobar", text) self.assertIn("due foobar", text)
# due date with no time # due date with no time
text = set_due_date_format(u"%b %d %Y") text = set_due_date_format(u"%b %d %y")
self.assertNotIn("due Sep 18, 2013 at 11:30", text) self.assertNotIn(time_with_utc, text)
self.assertIn("due Sep 18 2013", text) self.assertIn("due Sep 18 13", text)
# hide due date completely # hide due date completely
text = set_due_date_format(u"") text = set_due_date_format(u"")
self.assertNotIn("due ", text) self.assertNotIn("due ", text)
# improperly formatted due_date_display_format falls through to default with show_timezone arg # improperly formatted due_date_display_format falls through to default
# (value of show_timezone does not matter-- setting to False to make that clear).
set_show_timezone(False)
text = set_due_date_format(u"%%%") text = set_due_date_format(u"%%%")
self.assertNotIn("%%%", text) self.assertNotIn("%%%", text)
self.assertIn("due Sep 18, 2013 at 11:30", text) self.assertIn(time_with_utc, text)
self.assertNotIn("due Sep 18, 2013 at 11:30 UTC", text)
set_show_timezone(True)
text = set_due_date_format(u"%%%")
self.assertNotIn("%%%", text)
self.assertIn("due Sep 18, 2013 at 11:30 UTC", text)
...@@ -98,7 +98,6 @@ def render_accordion(request, course, chapter, section, field_data_cache): ...@@ -98,7 +98,6 @@ def render_accordion(request, course, chapter, section, field_data_cache):
context = dict([('toc', toc), context = dict([('toc', toc),
('course_id', course.id), ('course_id', course.id),
('csrf', csrf(request)['csrf_token']), ('csrf', csrf(request)['csrf_token']),
('show_timezone', course.show_timezone),
('due_date_display_format', course.due_date_display_format)] + template_imports.items()) ('due_date_display_format', course.due_date_display_format)] + template_imports.items())
return render_to_string('courseware/accordion.html', context) return render_to_string('courseware/accordion.html', context)
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
if section.get('due') is None: if section.get('due') is None:
due_date = '' due_date = ''
else: else:
formatted_string = get_time_display(section['due'], due_date_display_format, show_timezone) formatted_string = get_time_display(section['due'], due_date_display_format)
due_date = '' if len(formatted_string)==0 else _('due {date}'.format(date=formatted_string)) due_date = '' if len(formatted_string)==0 else _('due {date}'.format(date=formatted_string))
%> %>
<p class="subtitle">${section['format']} ${due_date}</p> <p class="subtitle">${section['format']} ${due_date}</p>
......
...@@ -70,7 +70,7 @@ ${progress_graph.body(grade_summary, course.grade_cutoffs, "grade-detail-graph", ...@@ -70,7 +70,7 @@ ${progress_graph.body(grade_summary, course.grade_cutoffs, "grade-detail-graph",
%if section.get('due') is not None: %if section.get('due') is not None:
<% <%
formatted_string = get_time_display(section['due'], course.due_date_display_format, course.show_timezone) formatted_string = get_time_display(section['due'], course.due_date_display_format)
due_date = '' if len(formatted_string)==0 else _('due {date}'.format(date=formatted_string)) due_date = '' if len(formatted_string)==0 else _('due {date}'.format(date=formatted_string))
%> %>
<em> <em>
......
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