Commit d05c92ba by Ibrahim Awwal

Merge branch 'feature/arjun/new-discussions' of github.com:MITx/mitx into…

Merge branch 'feature/arjun/new-discussions' of github.com:MITx/mitx into feature/arjun/new-discussions
parents a665f3aa 8f63ec4d
...@@ -62,19 +62,31 @@ def ajax_content_response(request, course_id, content, template_name): ...@@ -62,19 +62,31 @@ def ajax_content_response(request, course_id, content, template_name):
@login_required @login_required
@permitted @permitted
def create_thread(request, course_id, commentable_id): def create_thread(request, course_id, commentable_id):
course = get_course_with_access(request.user, course_id, 'load')
post = request.POST post = request.POST
if course.metadata.get("allow_anonymous", True):
anonymous = post.get('anonymous', 'false').lower() == 'true'
else:
anonymous = False
if course.metadata.get("allow_anonymous_to_peers", False):
anonymous_to_peers = post.get('anonymous_to_peers', 'false').lower() == 'true'
else:
anonymous_to_peers = False
thread = cc.Thread(**extract(post, ['body', 'title', 'tags'])) thread = cc.Thread(**extract(post, ['body', 'title', 'tags']))
thread.update_attributes(**{ thread.update_attributes(**{
'anonymous' : post.get('anonymous', 'false').lower() == 'true', 'anonymous' : anonymous,
'commentable_id' : commentable_id, 'anonymous_to_peers' : anonymous_to_peers,
'course_id' : course_id, 'commentable_id' : commentable_id,
'user_id' : request.user.id, 'course_id' : course_id,
'user_id' : request.user.id,
}) })
thread.save() thread.save()
if post.get('auto_subscribe', 'false').lower() == 'true': if post.get('auto_subscribe', 'false').lower() == 'true':
user = cc.User.from_django_user(request.user) user = cc.User.from_django_user(request.user)
user.follow(thread) user.follow(thread)
course = get_course_with_access(request.user, course_id, 'load')
courseware_context = get_courseware_context(thread, course) courseware_context = get_courseware_context(thread, course)
data = thread.to_dict() data = thread.to_dict()
if courseware_context: if courseware_context:
...@@ -99,8 +111,20 @@ def update_thread(request, course_id, thread_id): ...@@ -99,8 +111,20 @@ def update_thread(request, course_id, thread_id):
def _create_comment(request, course_id, thread_id=None, parent_id=None): def _create_comment(request, course_id, thread_id=None, parent_id=None):
post = request.POST post = request.POST
comment = cc.Comment(**extract(post, ['body'])) comment = cc.Comment(**extract(post, ['body']))
if course.metadata.get("allow_anonymous", True):
anonymous = post.get('anonymous', 'false').lower() == 'true'
else:
anonymous = False
if course.metadata.get("allow_anonymous_to_peers", False):
anonymous_to_peers = post.get('anonymous_to_peers', 'false').lower() == 'true'
else:
anonymous_to_peers = False
comment.update_attributes(**{ comment.update_attributes(**{
'anonymous' : post.get('anonymous', 'false').lower() == 'true', 'anonymous' : anonymous,
'anonymous_to_peers' : anonymous_to_peers,
'user_id' : request.user.id, 'user_id' : request.user.id,
'course_id' : course_id, 'course_id' : course_id,
'thread_id' : thread_id, 'thread_id' : thread_id,
......
...@@ -92,6 +92,8 @@ def inline_discussion(request, course_id, discussion_id): ...@@ -92,6 +92,8 @@ def inline_discussion(request, course_id, discussion_id):
Renders JSON for DiscussionModules Renders JSON for DiscussionModules
""" """
course = get_course_with_access(request.user, course_id, 'load')
try: try:
threads, query_params = get_threads(request, course_id, discussion_id, per_page=INLINE_THREADS_PER_PAGE) threads, query_params = get_threads(request, course_id, discussion_id, per_page=INLINE_THREADS_PER_PAGE)
user_info = cc.User.from_django_user(request.user).to_dict() user_info = cc.User.from_django_user(request.user).to_dict()
...@@ -106,6 +108,9 @@ def inline_discussion(request, course_id, discussion_id): ...@@ -106,6 +108,9 @@ def inline_discussion(request, course_id, discussion_id):
annotated_content_info = reduce(merge_dict, map(infogetter, threads), {}) annotated_content_info = reduce(merge_dict, map(infogetter, threads), {})
allow_anonymous = course.metadata.get("allow_anonymous", True)
allow_anonymous_to_peers = course.metadata.get("allow_anonymous_to_peers", False)
return utils.JsonResponse({ return utils.JsonResponse({
'discussion_data': map(utils.safe_content, threads), 'discussion_data': map(utils.safe_content, threads),
'user_info': user_info, 'user_info': user_info,
...@@ -113,6 +118,8 @@ def inline_discussion(request, course_id, discussion_id): ...@@ -113,6 +118,8 @@ def inline_discussion(request, course_id, discussion_id):
'page': query_params['page'], 'page': query_params['page'],
'num_pages': query_params['num_pages'], 'num_pages': query_params['num_pages'],
'roles': utils.get_role_ids(course_id), 'roles': utils.get_role_ids(course_id),
'allow_anonymous_to_peers': allow_anonymous_to_peers,
'allow_anonymous': allow_anonymous,
}) })
@login_required @login_required
......
...@@ -188,7 +188,9 @@ def initialize_discussion_info(course): ...@@ -188,7 +188,9 @@ def initialize_discussion_info(course):
"sort_key": entry["sort_key"], "sort_key": entry["sort_key"],
"start_date": entry["start_date"]} "start_date": entry["start_date"]}
for topic, entry in course.metadata.get('discussion_topics', {}).items(): default_topics = {'General': course.location.html_id()}
discussion_topics = course.metadata.get('discussion_topics', default_topics)
for topic, entry in discussion_topics.items():
category_map['entries'][topic] = {"id": entry["id"], category_map['entries'][topic] = {"id": entry["id"],
"sort_key": entry.get("sort_key", topic), "sort_key": entry.get("sort_key", topic),
"start_date": time.gmtime()} "start_date": time.gmtime()}
...@@ -327,15 +329,14 @@ def get_courseware_context(content, course): ...@@ -327,15 +329,14 @@ def get_courseware_context(content, course):
def safe_content(content): def safe_content(content):
fields = [ fields = [
'id', 'title', 'body', 'course_id', 'anonymous', 'endorsed', 'id', 'title', 'body', 'course_id', 'anonymous', 'anonymous_to_peers',
'parent_id', 'thread_id', 'votes', 'closed', 'endorsed', 'parent_id', 'thread_id', 'votes', 'closed', 'created_at',
'created_at', 'updated_at', 'depth', 'type', 'updated_at', 'depth', 'type', 'commentable_id', 'comments_count',
'commentable_id', 'comments_count', 'at_position_list', 'at_position_list', 'children', 'highlighted_title', 'highlighted_body',
'children', 'highlighted_title', 'highlighted_body',
'courseware_title', 'courseware_location', 'tags' 'courseware_title', 'courseware_location', 'tags'
] ]
if content.get('anonymous') is False: if (content.get('anonymous') is False) and (content.get('anonymous_to_peers') is False):
fields += ['username', 'user_id'] fields += ['username', 'user_id']
return strip_none(extract(content, fields)) return strip_none(extract(content, fields))
...@@ -7,15 +7,14 @@ import settings ...@@ -7,15 +7,14 @@ import settings
class Comment(models.Model): class Comment(models.Model):
accessible_fields = [ accessible_fields = [
'id', 'body', 'anonymous', 'course_id', 'id', 'body', 'anonymous', 'anonymous_to_peers', 'course_id',
'endorsed', 'parent_id', 'thread_id', 'endorsed', 'parent_id', 'thread_id', 'username', 'votes', 'user_id',
'username', 'votes', 'user_id', 'closed', 'closed', 'created_at', 'updated_at', 'depth', 'at_position_list',
'created_at', 'updated_at', 'depth', 'type', 'commentable_id',
'at_position_list', 'type', 'commentable_id',
] ]
updatable_fields = [ updatable_fields = [
'body', 'anonymous', 'course_id', 'closed', 'body', 'anonymous', 'anonymous_to_peers', 'course_id', 'closed',
'user_id', 'endorsed', 'user_id', 'endorsed',
] ]
......
...@@ -6,17 +6,14 @@ import settings ...@@ -6,17 +6,14 @@ import settings
class Thread(models.Model): class Thread(models.Model):
accessible_fields = [ accessible_fields = [
'id', 'title', 'body', 'anonymous', 'id', 'title', 'body', 'anonymous', 'anonymous_to_peers', 'course_id',
'course_id', 'closed', 'tags', 'votes', 'closed', 'tags', 'votes', 'commentable_id', 'username', 'user_id',
'commentable_id', 'username', 'user_id', 'created_at', 'updated_at', 'comments_count', 'at_position_list',
'created_at', 'updated_at', 'comments_count', 'children', 'type', 'highlighted_title', 'highlighted_body', 'endorsed'
'at_position_list', 'children', 'type',
'highlighted_title', 'highlighted_body',
'endorsed'
] ]
updatable_fields = [ updatable_fields = [
'title', 'body', 'anonymous', 'course_id', 'title', 'body', 'anonymous', 'anonymous_to_peers', 'course_id',
'closed', 'tags', 'user_id', 'commentable_id', 'closed', 'tags', 'user_id', 'commentable_id',
] ]
......
...@@ -68,10 +68,12 @@ if Backbone? ...@@ -68,10 +68,12 @@ if Backbone?
window.user = new DiscussionUser(response.user_info) window.user = new DiscussionUser(response.user_info)
Content.loadContentInfos(response.annotated_content_info) Content.loadContentInfos(response.annotated_content_info)
DiscussionUtil.loadRoles(response.roles) DiscussionUtil.loadRoles(response.roles)
allow_anonymous = response.allow_anonymous
allow_anonymous_to_peers = response.allow_anonymous_to_peers
# $elem.html("Hide Discussion") # $elem.html("Hide Discussion")
@discussion = new Discussion() @discussion = new Discussion()
@discussion.reset(response.discussion_data, {silent: false}) @discussion.reset(response.discussion_data, {silent: false})
$discussion = $(Mustache.render $("script#_inline_discussion").html(), {'threads':response.discussion_data, 'discussionId': discussionId}) $discussion = $(Mustache.render $("script#_inline_discussion").html(), {'threads':response.discussion_data, 'discussionId': discussionId, 'allow_anonymous_to_peers': allow_anonymous_to_peers, 'allow_anonymous': allow_anonymous})
if @$('section.discussion').length if @$('section.discussion').length
@$('section.discussion').replaceWith($discussion) @$('section.discussion').replaceWith($discussion)
else else
......
...@@ -134,6 +134,6 @@ if Backbone? ...@@ -134,6 +134,6 @@ if Backbone?
renderTemplate: -> renderTemplate: ->
@template = DiscussionUtil.getTemplate('_inline_thread_show') @template = DiscussionUtil.getTemplate('_inline_thread_show')
params = @model.toJSON() params = @model.toJSON()
if not @model.get('anonymous') if @model.get('username')?
params = $.extend(params, user:{username: @model.username, user_url: @model.user_url}) params = $.extend(params, user:{username: @model.username, user_url: @model.user_url})
Mustache.render(@template, params) Mustache.render(@template, params)
...@@ -8,7 +8,9 @@ if Backbone? ...@@ -8,7 +8,9 @@ if Backbone?
@maxNameWidth = 100 @maxNameWidth = 100
DiscussionUtil.makeWmdEditor @$el, $.proxy(@$, @), "new-post-body" DiscussionUtil.makeWmdEditor @$el, $.proxy(@$, @), "new-post-body"
@$(".new-post-tags").tagsInput DiscussionUtil.tagsInputOptions()
# TODO tags: commenting out til we know what to do with them
#@$(".new-post-tags").tagsInput DiscussionUtil.tagsInputOptions()
events: events:
"submit .new-post-form": "createPost" "submit .new-post-form": "createPost"
...@@ -23,9 +25,12 @@ if Backbone? ...@@ -23,9 +25,12 @@ if Backbone?
event.preventDefault() event.preventDefault()
title = @$(".new-post-title").val() title = @$(".new-post-title").val()
body = @$(".new-post-body").find(".wmd-input").val() body = @$(".new-post-body").find(".wmd-input").val()
tags = @$(".new-post-tags").val()
anonymous = false || @$("input.discussion-anonymous").is(":checked") # TODO tags: commenting out til we know what to do with them
#tags = @$(".new-post-tags").val()
anonymous = false || @$("input.discussion-anonymous").is(":checked")
anonymous_to_peers = false || @$("input.discussion-anonymous-to-peers").is(":checked")
follow = false || @$("input.discussion-follow").is(":checked") follow = false || @$("input.discussion-follow").is(":checked")
url = DiscussionUtil.urlFor('create_thread', @topicId) url = DiscussionUtil.urlFor('create_thread', @topicId)
...@@ -40,8 +45,12 @@ if Backbone? ...@@ -40,8 +45,12 @@ if Backbone?
data: data:
title: title title: title
body: body body: body
tags: tags
# TODO tags: commenting out til we know what to do with them
#tags: tags
anonymous: anonymous anonymous: anonymous
anonymous_to_peers: anonymous_to_peers
auto_subscribe: follow auto_subscribe: follow
error: DiscussionUtil.formErrorHandler(@$(".new-post-form-errors")) error: DiscussionUtil.formErrorHandler(@$(".new-post-form-errors"))
success: (response, textStatus) => success: (response, textStatus) =>
...@@ -51,6 +60,9 @@ if Backbone? ...@@ -51,6 +60,9 @@ if Backbone?
@$el.hide() @$el.hide()
@$(".new-post-title").val("").attr("prev-text", "") @$(".new-post-title").val("").attr("prev-text", "")
@$(".new-post-body textarea").val("").attr("prev-text", "") @$(".new-post-body textarea").val("").attr("prev-text", "")
@$(".new-post-tags").val("")
@$(".new-post-tags").importTags("") # TODO tags, commenting out til we know what to do with them
#@$(".new-post-tags").val("")
#@$(".new-post-tags").importTags("")
@collection.add thread @collection.add thread
...@@ -116,8 +116,9 @@ if Backbone? ...@@ -116,8 +116,9 @@ if Backbone?
body = @$(".new-post-body").find(".wmd-input").val() body = @$(".new-post-body").find(".wmd-input").val()
tags = @$(".new-post-tags").val() tags = @$(".new-post-tags").val()
anonymous = false || @$("input.discussion-anonymous").is(":checked") anonymous = false || @$("input.discussion-anonymous").is(":checked")
follow = false || @$("input.discussion-follow").is(":checked") anonymous_to_peers = false || @$("input.discussion-anonymous-to-peers").is(":checked")
follow = false || @$("input.discussion-follow").is(":checked")
$formTopicDropBtn.bind('click', showFormTopicDrop) $formTopicDropBtn.bind('click', showFormTopicDrop)
$formTopicDropMenu.bind('click', setFormTopic) $formTopicDropMenu.bind('click', setFormTopic)
...@@ -136,6 +137,7 @@ if Backbone? ...@@ -136,6 +137,7 @@ if Backbone?
body: body body: body
tags: tags tags: tags
anonymous: anonymous anonymous: anonymous
anonymous_to_peers: anonymous_to_peers
auto_subscribe: follow auto_subscribe: follow
error: DiscussionUtil.formErrorHandler(@$(".new-post-form-errors")) error: DiscussionUtil.formErrorHandler(@$(".new-post-form-errors"))
success: (response, textStatus) => success: (response, textStatus) =>
......
...@@ -7,7 +7,11 @@ ...@@ -7,7 +7,11 @@
<div class="options"> <div class="options">
<input type="checkbox" name="follow" class="discussion-follow" class="discussion-follow" id="new-post-follow" checked><label for="new-post-follow">follow this post</label> <input type="checkbox" name="follow" class="discussion-follow" class="discussion-follow" id="new-post-follow" checked><label for="new-post-follow">follow this post</label>
<br> <br>
<input type="checkbox" name="anonymous" class="discussion-anonymous" id="new-post-anonymous"><label for="new-post-anonymous">post anonymously</label> % if course.metadata.get("allow_anonymous", True):
<input type="checkbox" name="anonymous" class="discussion-anonymous" id="new-post-anonymous"><label for="new-post-anonymous">post anonymously</label>
%elif course.metadata.get("allow_anonymous_to_peers", False):
<input type="checkbox" name="anonymous_to_peers" class="discussion-anonymous-to-peers" id="new-post-anonymous-to-peers"><label for="new-post-anonymous-to-peers">post anonymously to classmates</label>
%endif
</div> </div>
</div> </div>
<div class="right-column"> <div class="right-column">
...@@ -18,9 +22,10 @@ ...@@ -18,9 +22,10 @@
<div class="new-post-body" name="body" placeholder="Enter your question or comment&hellip;"></div> <div class="new-post-body" name="body" placeholder="Enter your question or comment&hellip;"></div>
<!---<div class="new-post-preview"><span class="new-post-preview-label">Preview</span></div>--> <!---<div class="new-post-preview"><span class="new-post-preview-label">Preview</span></div>-->
</div> </div>
<div class="form-row"> ## TODO commenting out tags til we figure out what to do with them
<input type="text" class="new-post-tags" name="tags" placeholder="Tags"> ##<div class="form-row">
</div> ## <input type="text" class="new-post-tags" name="tags" placeholder="Tags">
##</div>
<input type="submit" class="submit" value="Add post"> <input type="submit" class="submit" value="Add post">
<a href="#" class="new-post-cancel">Cancel</a> <a href="#" class="new-post-cancel">Cancel</a>
</div> </div>
......
...@@ -40,7 +40,11 @@ ...@@ -40,7 +40,11 @@
<div class="options"> <div class="options">
<input type="checkbox" name="follow" class="discussion-follow" class="discussion-follow" id="new-post-follow" checked><label for="new-post-follow">follow this post</label> <input type="checkbox" name="follow" class="discussion-follow" class="discussion-follow" id="new-post-follow" checked><label for="new-post-follow">follow this post</label>
<br> <br>
<input type="checkbox" name="anonymous" class="discussion-anonymous" id="new-post-anonymous"><label for="new-post-anonymous">post anonymously</label> % if course.metadata.get("allow_anonymous", True):
<input type="checkbox" name="anonymous" class="discussion-anonymous" id="new-post-anonymous"><label for="new-post-anonymous">post anonymously</label>
%elif course.metadata.get("allow_anonymous_to_peers", False):
<input type="checkbox" name="anonymous_to_peers" class="discussion-anonymous-to-peers" id="new-post-anonymous-to-peers"><label for="new-post-anonymous-to-peers">post anonymously to classmates</label>
%endif
</div> </div>
</div> </div>
<div class="right-column"> <div class="right-column">
...@@ -52,9 +56,10 @@ ...@@ -52,9 +56,10 @@
<div class="new-post-body" name="body" placeholder="Enter your question or comment…"></div> <div class="new-post-body" name="body" placeholder="Enter your question or comment…"></div>
<!---<div class="new-post-preview"><span class="new-post-preview-label">Preview</span></div>--> <!---<div class="new-post-preview"><span class="new-post-preview-label">Preview</span></div>-->
</div> </div>
<div class="form-row"> ## TODO tags commenting out til we figure out what to do w/ tags
<input type="text" class="new-post-tags" name="tags" placeholder="Tags"> ##<div class="form-row">
</div> ## <input type="text" class="new-post-tags" name="tags" placeholder="Tags">
##</div>
<input type="submit" class="submit" value="Add post"> <input type="submit" class="submit" value="Add post">
<a href="#" class="new-post-cancel">Cancel</a> <a href="#" class="new-post-cancel">Cancel</a>
</div> </div>
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
<a href="#" class="vote-btn discussion-vote discussion-vote-up" data-role="discussion-vote"><span class="plus-icon">+</span> <span class='votes-count-number'>${'<%- votes["up_count"] %>'}</span></a> <a href="#" class="vote-btn discussion-vote discussion-vote-up" data-role="discussion-vote"><span class="plus-icon">+</span> <span class='votes-count-number'>${'<%- votes["up_count"] %>'}</span></a>
<h1>${'<%- title %>'}</h1> <h1>${'<%- title %>'}</h1>
<p class="posted-details"> <p class="posted-details">
${"<% if (!obj.anonymous) { %>"} ${"<% if (obj.username) { %>"}
<a href="${'<%- user_url %>'}" class="username">${'<%- username %>'}</a> <a href="${'<%- user_url %>'}" class="username">${'<%- username %>'}</a>
${"<% } else {print('anonymous');} %>"} ${"<% } else {print('anonymous');} %>"}
<span class="timeago" title="${'<%- created_at %>'}">${'<%- created_at %>'}</span> <span class="timeago" title="${'<%- created_at %>'}">${'<%- created_at %>'}</span>
......
...@@ -14,15 +14,21 @@ ...@@ -14,15 +14,21 @@
<div class="new-post-body" name="body" placeholder="Enter your question or comment&hellip;"></div> <div class="new-post-body" name="body" placeholder="Enter your question or comment&hellip;"></div>
<!---<div class="new-post-preview"><span class="new-post-preview-label">Preview</span></div>--> <!---<div class="new-post-preview"><span class="new-post-preview-label">Preview</span></div>-->
</div> </div>
<div class="form-row"> {{! TODO tags: Getting rid of tags for now. }}
<input type="text" class="new-post-tags" name="tags" placeholder="Tags"> {{!<div class="form-row">}}
</div> {{! <input type="text" class="new-post-tags" name="tags" placeholder="Tags">}}
{{!</div>}}
<input type="submit" class="submit" value="Add post"> <input type="submit" class="submit" value="Add post">
<a href="#" class="new-post-cancel">Cancel</a> <a href="#" class="new-post-cancel">Cancel</a>
<div class="options"> <div class="options">
<input type="checkbox" name="follow" class="discussion-follow" class="discussion-follow" id="new-post-follow" checked><label for="new-post-follow">follow this post</label> <input type="checkbox" name="follow" class="discussion-follow" class="discussion-follow" id="new-post-follow" checked><label for="new-post-follow">follow this post</label>
<br> <br>
<input type="checkbox" name="anonymous" class="discussion-anonymous" id="new-post-anonymous"><label for="new-post-anonymous">post anonymously</label> {{#allow_anonymous}}
<input type="checkbox" name="anonymous" class="discussion-anonymous" id="new-post-anonymous"><label for="new-post-anonymous">post anonymously</label>
{{/allow_anonymous}}
{{#allow_anonymous_to_peers}}
<input type="checkbox" name="anonymous" class="discussion-anonymous-to-peers" id="new-post-anonymous-to-peers"><label for="new-post-anonymous-to-peers">post anonymously to classmates</label>
{{/allow_anonymous_to_peers}}
</div> </div>
</form> </form>
</div> </div>
......
...@@ -3,7 +3,8 @@ ...@@ -3,7 +3,8 @@
<input type="text" class="new-post-title title-input" placeholder="Title" /> <input type="text" class="new-post-title title-input" placeholder="Title" />
<div class="new-post-similar-posts-wrapper" style="display: none"></div> <div class="new-post-similar-posts-wrapper" style="display: none"></div>
<div class="new-post-body reply-body"></div> <div class="new-post-body reply-body"></div>
<input class="new-post-tags" placeholder="Tags" /> {{! TODO tags: Getting rid of tags for now. }}
{{! <input class="new-post-tags" placeholder="Tags" /> }}
<div class="post-options"> <div class="post-options">
<input type="checkbox" class="discussion-post-anonymously" id="discussion-post-anonymously-${discussion_id}"> <input type="checkbox" class="discussion-post-anonymously" id="discussion-post-anonymously-${discussion_id}">
<label for="discussion-post-anonymously-${discussion_id}">post anonymously</label> <label for="discussion-post-anonymously-${discussion_id}">post anonymously</label>
......
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