From 8a453e99ca826fe948c18ca732f6f67a4898ccc0 Mon Sep 17 00:00:00 2001 From: David Ormsbee Date: Thu, 1 Nov 2012 04:36:54 -0400 Subject: [PATCH 1/3] Implement basic ability to close off a forum for a given course such that Students can no longer post or edit, but can still view. --- common/lib/xmodule/xmodule/course_module.py | 16 ++++++++++++++++ lms/djangoapps/django_comment_client/models.py | 7 +++++++ .../_discussion_course_navigation.html | 3 +++ lms/templates/discussion/_discussion_module.html | 2 ++ .../discussion/_underscore_templates.html | 6 ++++++ 5 files changed, 34 insertions(+) diff --git a/common/lib/xmodule/xmodule/course_module.py b/common/lib/xmodule/xmodule/course_module.py index de8eddd0b8..64e947a5a1 100644 --- a/common/lib/xmodule/xmodule/course_module.py +++ b/common/lib/xmodule/xmodule/course_module.py @@ -276,6 +276,22 @@ class CourseDescriptor(SequenceDescriptor): more sensible framework later.""" return self.metadata.get('discussion_link', None) + @property + def forum_posts_allowed(self): + try: + blackout_periods = [(parse_time(start), parse_time(end)) + for start, end + in self.metadata.get('discussion_blackouts', [])] + now = time.gmtime() + for start, end in blackout_periods: + if start <= now <= end: + return False + except: + log.exception("Error parsing discussion_blackouts for course {0}".format(self.id)) + raise + + return True + @property def hide_progress_tab(self): """TODO: same as above, intended to let internal CS50 hide the progress tab diff --git a/lms/djangoapps/django_comment_client/models.py b/lms/djangoapps/django_comment_client/models.py index 605a731517..ff2146afac 100644 --- a/lms/djangoapps/django_comment_client/models.py +++ b/lms/djangoapps/django_comment_client/models.py @@ -2,6 +2,7 @@ from django.db import models from django.contrib.auth.models import User import logging +from courseware.courses import get_course_by_id class Role(models.Model): name = models.CharField(max_length=30, null=False, blank=False) @@ -23,6 +24,12 @@ class Role(models.Model): self.permissions.add(Permission.objects.get_or_create(name=permission)[0]) def has_permission(self, permission): + course = get_course_by_id(self.course_id) + if self.name == "Student" and \ + (permission.startswith('edit') or permission.startswith('update') or permission.startswith('create')) and \ + (not course.forum_posts_allowed): + return False + return self.permissions.filter(name=permission).exists() diff --git a/lms/templates/discussion/_discussion_course_navigation.html b/lms/templates/discussion/_discussion_course_navigation.html index 13b291196b..d770cacc96 100644 --- a/lms/templates/discussion/_discussion_course_navigation.html +++ b/lms/templates/discussion/_discussion_course_navigation.html @@ -1,5 +1,8 @@ +<%! from django_comment_client.permissions import has_permission %> <%inherit file="../courseware/course_navigation.html" /> <%block name="extratabs"> +% if has_permission(user, 'create_thread', course.id):
  • New Post
  • +% endif \ No newline at end of file diff --git a/lms/templates/discussion/_discussion_module.html b/lms/templates/discussion/_discussion_module.html index bb172093f6..8fced92f7f 100644 --- a/lms/templates/discussion/_discussion_module.html +++ b/lms/templates/discussion/_discussion_module.html @@ -3,4 +3,6 @@
    Show Discussion New Post + +
    diff --git a/lms/templates/discussion/_underscore_templates.html b/lms/templates/discussion/_underscore_templates.html index 0a691ac36f..be238811c2 100644 --- a/lms/templates/discussion/_underscore_templates.html +++ b/lms/templates/discussion/_underscore_templates.html @@ -1,3 +1,5 @@ +<%! from django_comment_client.permissions import has_permission %> + @@ -75,6 +79,7 @@
    1. + % if course is UNDEFINED or has_permission(user, 'create_sub_comment', course.id):
        Submit
        + % endif
      From 8f756f030476d862c34322cc35a63152ddc2b54d Mon Sep 17 00:00:00 2001 From: David Ormsbee Date: Thu, 1 Nov 2012 04:45:00 -0400 Subject: [PATCH 2/3] Document advertised_start and discussion_blackouts attributes of course --- doc/xml-format.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/xml-format.md b/doc/xml-format.md index d9c0d27653..0491641903 100644 --- a/doc/xml-format.md +++ b/doc/xml-format.md @@ -250,9 +250,11 @@ Values are dictionaries of the form {"metadata-key" : "metadata-value"}. Supported fields at the course level: * "start" -- specify the start date for the course. Format-by-example: "2012-09-05T12:00". +* "advertised_start" -- specify what you want displayed as the start date of the course in the course listing and course about pages. This can be useful if you want to let people in early before the formal start. Format-by-example: "2012-09-05T12:00". * "enrollment_start", "enrollment_end" -- when can students enroll? (if not specified, can enroll anytime). Same format as "start". * "end" -- specify the end date for the course. Format-by-example: "2012-11-05T12:00". * "tabs" -- have custom tabs in the courseware. See below for details on config. +* "discussion_blackouts" -- An array of time intervals during which you want to disable a student's ability to create or edit posts in the forum. Moderators, Community TAs, and Admins are unaffected. You might use this during exam periods, but please be aware that the forum is often a very good place to catch mistakes and clarify points to students. The better long term solution would be to have better flagging/moderation mechanisms, but this is the hammer we have today. Format by example: [["2012-10-29T04:00", "2012-11-03T04:00"], ["2012-12-30T04:00", "2013-01-02T04:00"]] * TODO: there are others ### Grading policy file contents From ddc4f705e0d02892f42ef8e28f1d03fe134e31f8 Mon Sep 17 00:00:00 2001 From: David Ormsbee Date: Thu, 1 Nov 2012 04:49:45 -0400 Subject: [PATCH 3/3] Remove raise that was there just for debugging purposes --- common/lib/xmodule/xmodule/course_module.py | 1 - 1 file changed, 1 deletion(-) diff --git a/common/lib/xmodule/xmodule/course_module.py b/common/lib/xmodule/xmodule/course_module.py index 64e947a5a1..fc27a692ea 100644 --- a/common/lib/xmodule/xmodule/course_module.py +++ b/common/lib/xmodule/xmodule/course_module.py @@ -288,7 +288,6 @@ class CourseDescriptor(SequenceDescriptor): return False except: log.exception("Error parsing discussion_blackouts for course {0}".format(self.id)) - raise return True