Merge branch 'feature/kevin/flagging' of github.com:MITx/mitx into feature/kevin/flagging
This commit is contained in:
@@ -10,7 +10,7 @@ urlpatterns = patterns('django_comment_client.base.views',
|
||||
url(r'threads/(?P<thread_id>[\w\-]+)/reply$', 'create_comment', name='create_comment'),
|
||||
url(r'threads/(?P<thread_id>[\w\-]+)/delete', 'delete_thread', name='delete_thread'),
|
||||
url(r'threads/(?P<thread_id>[\w\-]+)/upvote$', 'vote_for_thread', {'value': 'up'}, name='upvote_thread'),
|
||||
url(r'threads/(?P<thread_id>[\w\-]+)/flagAbuse$', 'flag_abuse_for_thread', {'value': 'up'}, name='flag_abuse_for_thread'),
|
||||
url(r'threads/(?P<thread_id>[\w\-]+)/flagAbuse$', 'flag_abuse_for_thread', name='flag_abuse_for_thread'),
|
||||
url(r'threads/(?P<thread_id>[\w\-]+)/unFlagAbuse$', 'un_flag_abuse_for_thread', name='un_flag_abuse_for_thread'),
|
||||
url(r'threads/(?P<thread_id>[\w\-]+)/downvote$', 'vote_for_thread', name='downvote_thread'),
|
||||
url(r'threads/(?P<thread_id>[\w\-]+)/unvote$', 'undo_vote_for_thread', name='undo_vote_for_thread'),
|
||||
@@ -25,8 +25,8 @@ urlpatterns = patterns('django_comment_client.base.views',
|
||||
url(r'comments/(?P<comment_id>[\w\-]+)/upvote$', 'vote_for_comment', {'value': 'up'}, name='upvote_comment'),
|
||||
url(r'comments/(?P<comment_id>[\w\-]+)/downvote$', 'vote_for_comment', {'value': 'down'}, name='downvote_comment'),
|
||||
url(r'comments/(?P<comment_id>[\w\-]+)/unvote$', 'undo_vote_for_comment', name='undo_vote_for_comment'),
|
||||
url(r'threads/(?P<comment_id>[\w\-]+)/flagAbuse$', 'flag_abuse_for_comment', name='flag_abuse_for_comment'),
|
||||
url(r'threads/(?P<comment_id>[\w\-]+)/unFlagAbuse$', 'un_flag_abuse_for_comment', name='un_flag_abuse_for_comment'),
|
||||
url(r'comments/(?P<comment_id>[\w\-]+)/flagAbuse$', 'flag_abuse_for_comment', name='flag_abuse_for_comment'),
|
||||
url(r'comments/(?P<comment_id>[\w\-]+)/unFlagAbuse$', 'un_flag_abuse_for_comment', name='un_flag_abuse_for_comment'),
|
||||
|
||||
url(r'(?P<commentable_id>[\w\-]+)/threads/create$', 'create_thread', name='create_thread'),
|
||||
# TODO should we search within the board?
|
||||
|
||||
@@ -238,28 +238,28 @@ def vote_for_thread(request, course_id, thread_id, value):
|
||||
@require_POST
|
||||
@login_required
|
||||
@permitted
|
||||
def flag_abuse_for_thread(request, course_id, thread_id, value):
|
||||
def flag_abuse_for_thread(request, course_id, thread_id):
|
||||
user = cc.User.from_django_user(request.user)
|
||||
thread = cc.Thread.find(thread_id)
|
||||
thread.flagAbuse(user,thread, value)
|
||||
thread.flagAbuse(user,thread)
|
||||
return JsonResponse(utils.safe_content(thread.to_dict()))
|
||||
|
||||
def un_flag_abuse_for_thread(request, course_id, thread_id, value):
|
||||
def un_flag_abuse_for_thread(request, course_id, thread_id):
|
||||
user = cc.User.from_django_user(request.user)
|
||||
thread = cc.Thread.find(thread_id)
|
||||
thread.unFlagAbuse(user,thread, value)
|
||||
thread.unFlagAbuse(user,thread)
|
||||
return JsonResponse(utils.safe_content(thread.to_dict()))
|
||||
|
||||
def flag_abuse_for_comment(request, course_id, comment_id, value):
|
||||
def flag_abuse_for_comment(request, course_id, comment_id):
|
||||
user = cc.User.from_django_user(request.user)
|
||||
comment = cc.Comment.find(thread_id)
|
||||
comment.flagAbuse(user,comment, value)
|
||||
comment = cc.Comment.find(comment_id)
|
||||
comment.flagAbuse(user,comment)
|
||||
return JsonResponse(utils.safe_content(comment.to_dict()))
|
||||
|
||||
def un_flag_abuse_for_comment(request, course_id, comment_id, value):
|
||||
def un_flag_abuse_for_comment(request, course_id, comment_id):
|
||||
user = cc.User.from_django_user(request.user)
|
||||
comment = cc.Comment.find(thread_id)
|
||||
comment.unFlagAbuse(user,comment, value)
|
||||
comment = cc.Comment.find(comment_id)
|
||||
comment.unFlagAbuse(user,comment)
|
||||
return JsonResponse(utils.safe_content(comment.to_dict()))
|
||||
|
||||
@require_POST
|
||||
|
||||
@@ -72,7 +72,6 @@ def inline_discussion(request, course_id, discussion_id):
|
||||
"""
|
||||
Renders JSON for DiscussionModules
|
||||
"""
|
||||
|
||||
course = get_course_with_access(request.user, course_id, 'load')
|
||||
|
||||
try:
|
||||
@@ -161,26 +160,26 @@ def forum_form_discussion(request, course_id):
|
||||
|
||||
@login_required
|
||||
def single_thread(request, course_id, discussion_id, thread_id):
|
||||
|
||||
course = get_course_with_access(request.user, course_id, 'load')
|
||||
cc_user = cc.User.from_django_user(request.user)
|
||||
user_info = cc_user.to_dict()
|
||||
|
||||
try:
|
||||
thread = cc.Thread.find(thread_id).retrieve(recursive=True, user_id=request.user.id)
|
||||
thread = cc.Thread.find(thread_id).retrieve(recursive=True, user_id=request.user.id)
|
||||
except (cc.utils.CommentClientError, cc.utils.CommentClientUnknownError) as err:
|
||||
log.error("Error loading single thread.")
|
||||
raise Http404
|
||||
log.error("Error loading single thread.")
|
||||
raise Http404
|
||||
|
||||
if request.is_ajax():
|
||||
|
||||
courseware_context = get_courseware_context(thread, course)
|
||||
|
||||
annotated_content_info = utils.get_annotated_content_infos(course_id, thread, request.user, user_info=user_info)
|
||||
context = {'thread': thread.to_dict(), 'course_id': course_id}
|
||||
# TODO: Remove completely or switch back to server side rendering
|
||||
# html = render_to_string('discussion/_ajax_single_thread.html', context)
|
||||
content = utils.safe_content(thread.to_dict())
|
||||
log.debug("*************************")
|
||||
log.debug(content)
|
||||
if courseware_context:
|
||||
content.update(courseware_context)
|
||||
return utils.JsonResponse({
|
||||
|
||||
@@ -41,22 +41,22 @@ class Comment(models.Model):
|
||||
else:
|
||||
return super(Comment, cls).url(action, params)
|
||||
|
||||
def flagAbuse(self, user, voteable, value):
|
||||
def flagAbuse(self, user, voteable):
|
||||
if voteable.type == 'thread':
|
||||
url = _url_for_flag_abuse_thread(voteable.id)
|
||||
elif voteable.type == 'comment':
|
||||
url = _url_for_flag_comment(voteable.id)
|
||||
url = _url_for_flag_abuse_comment(voteable.id)
|
||||
else:
|
||||
raise CommentClientError("Can only flag/unflag threads or comments")
|
||||
params = {'user_id': user.id}
|
||||
request = perform_request('put', url, params)
|
||||
voteable.update_attributes(request)
|
||||
|
||||
def unFlagAbuse(self, user, voteable, value):
|
||||
def unFlagAbuse(self, user, voteable):
|
||||
if voteable.type == 'thread':
|
||||
url = _url_for_unflag_abuse_thread(voteable.id)
|
||||
elif voteable.type == 'comment':
|
||||
url = _url_for_unflag_comment(voteable.id)
|
||||
url = _url_for_unflag_abuse_comment(voteable.id)
|
||||
else:
|
||||
raise CommentClientError("Can flag/unflag for threads or comments")
|
||||
params = {'user_id': user.id}
|
||||
@@ -70,7 +70,7 @@ def _url_for_comment(comment_id):
|
||||
return "{prefix}/comments/{comment_id}".format(prefix=settings.PREFIX, comment_id=comment_id)
|
||||
|
||||
def _url_for_flag_abuse_comment(comment_id):
|
||||
return "{prefix}/threads/{comment_id}/abuse_flags".format(prefix=settings.PREFIX, thread_id=thread_id)
|
||||
return "{prefix}/comments/{comment_id}/abuse_flags".format(prefix=settings.PREFIX, comment_id=comment_id)
|
||||
|
||||
def _url_for_unflag_abuse_thread(comment_id):
|
||||
return "{prefix}/threads/{comment_id}/abuse_unflags".format(prefix=settings.PREFIX, thread_id=thread_id)
|
||||
def _url_for_unflag_abuse_comment(comment_id):
|
||||
return "{prefix}/comments/{comment_id}/abuse_unflags".format(prefix=settings.PREFIX, comment_id=comment_id)
|
||||
|
||||
@@ -26,6 +26,7 @@ class Thread(models.Model):
|
||||
|
||||
@classmethod
|
||||
def search(cls, query_params, *args, **kwargs):
|
||||
|
||||
default_params = {'page': 1,
|
||||
'per_page': 20,
|
||||
'course_id': query_params['course_id'],
|
||||
@@ -65,15 +66,20 @@ class Thread(models.Model):
|
||||
# that subclasses don't need to override for this.
|
||||
def _retrieve(self, *args, **kwargs):
|
||||
url = self.url(action='get', params=self.attributes)
|
||||
|
||||
request_params = {
|
||||
'recursive': kwargs.get('recursive'),
|
||||
'user_id': kwargs.get('user_id'),
|
||||
'mark_as_read': kwargs.get('mark_as_read', True),
|
||||
}
|
||||
|
||||
|
||||
def flagAbuse(self, user, voteable, value):
|
||||
# user_id may be none, in which case it shouldn't be part of the
|
||||
# request.
|
||||
request_params = strip_none(request_params)
|
||||
|
||||
response = perform_request('get', url, request_params)
|
||||
self.update_attributes(**response)
|
||||
|
||||
def flagAbuse(self, user, voteable):
|
||||
if voteable.type == 'thread':
|
||||
url = _url_for_flag_abuse_thread(voteable.id)
|
||||
elif voteable.type == 'comment':
|
||||
@@ -84,7 +90,7 @@ class Thread(models.Model):
|
||||
request = perform_request('put', url, params)
|
||||
voteable.update_attributes(request)
|
||||
|
||||
def unFlagAbuse(self, user, voteable, value):
|
||||
def unFlagAbuse(self, user, voteable):
|
||||
if voteable.type == 'thread':
|
||||
url = _url_for_unflag_abuse_thread(voteable.id)
|
||||
elif voteable.type == 'comment':
|
||||
|
||||
@@ -50,6 +50,8 @@ class @DiscussionUtil
|
||||
delete_thread : "/courses/#{$$course_id}/discussion/threads/#{param}/delete"
|
||||
flagAbuse_thread : "/courses/#{$$course_id}/discussion/threads/#{param}/flagAbuse"
|
||||
unFlagAbuse_thread : "/courses/#{$$course_id}/discussion/threads/#{param}/unFlagAbuse"
|
||||
flagAbuse_comment : "/courses/#{$$course_id}/discussion/comments/#{param}/flagAbuse"
|
||||
unFlagAbuse_comment : "/courses/#{$$course_id}/discussion/comments/#{param}/unFlagAbuse"
|
||||
upvote_thread : "/courses/#{$$course_id}/discussion/threads/#{param}/upvote"
|
||||
downvote_thread : "/courses/#{$$course_id}/discussion/threads/#{param}/downvote"
|
||||
undo_vote_for_thread : "/courses/#{$$course_id}/discussion/threads/#{param}/unvote"
|
||||
|
||||
@@ -72,17 +72,7 @@ if Backbone?
|
||||
|
||||
toggleFollowing: (event) ->
|
||||
$elem = $(event.target)
|
||||
url = nullunFlagAbuse: ->
|
||||
url = @model.urlFor("unFlagAbuse")
|
||||
DiscussionUtil.safeAjax
|
||||
$elem: @$(".discussion-flag-abuse")
|
||||
url: url
|
||||
type: "POST"
|
||||
success: (response, textStatus) =>
|
||||
if textStatus == 'success'
|
||||
temp_array = _.clone(@model.get('abuse_flaggers'));
|
||||
temp_array.pop(window.user.id)
|
||||
@model.set('abuse_flaggers', temp_array)
|
||||
url = null
|
||||
if not @model.get('subscribed')
|
||||
@model.follow()
|
||||
url = @model.urlFor("follow")
|
||||
@@ -92,7 +82,7 @@ if Backbone?
|
||||
DiscussionUtil.safeAjax
|
||||
$elem: $elem
|
||||
url: url
|
||||
type: "POST"
|
||||
type: "POST"
|
||||
|
||||
vote: ->
|
||||
window.user.vote(@model)
|
||||
|
||||
@@ -1,7 +1,14 @@
|
||||
if Backbone?
|
||||
class @ResponseCommentShowView extends DiscussionContentView
|
||||
|
||||
events:
|
||||
"click .discussion-flag-abuse": "toggleFlagAbuse"
|
||||
|
||||
tagName: "li"
|
||||
|
||||
initialize: ->
|
||||
super()
|
||||
@model.on "change", @updateModelDetails
|
||||
|
||||
render: ->
|
||||
@template = _.template($("#response-comment-show-template").html())
|
||||
@@ -11,6 +18,7 @@ if Backbone?
|
||||
@initLocal()
|
||||
@delegateEvents()
|
||||
@renderAttrs()
|
||||
@renderFlagged()
|
||||
@markAsStaff()
|
||||
@$el.find(".timeago").timeago()
|
||||
@convertMath()
|
||||
@@ -36,4 +44,15 @@ if Backbone?
|
||||
@$el.find("a.profile-link").after('<span class="community-ta-label">Community TA</span>')
|
||||
|
||||
|
||||
|
||||
renderFlagged: =>
|
||||
if window.user.id in @model.get("abuse_flaggers")
|
||||
@$("[data-role=thread-flag]").addClass("flagged")
|
||||
@$("[data-role=thread-flag]").removeClass("notflagged")
|
||||
else
|
||||
@$("[data-role=thread-flag]").removeClass("flagged")
|
||||
@$("[data-role=thread-flag]").addClass("notflagged")
|
||||
|
||||
updateModelDetails: =>
|
||||
@renderFlagged()
|
||||
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ if Backbone?
|
||||
if window.user.voted(@model)
|
||||
@$(".vote-btn").addClass("is-cast")
|
||||
@renderAttrs()
|
||||
@renderFlagged()
|
||||
@$el.find(".posted-details").timeago()
|
||||
@convertMath()
|
||||
@markAsStaff()
|
||||
@@ -94,3 +95,17 @@ if Backbone?
|
||||
url: url
|
||||
data: data
|
||||
type: "POST"
|
||||
|
||||
|
||||
renderFlagged: =>
|
||||
if window.user.id in @model.get("abuse_flaggers")
|
||||
@$("[data-role=thread-flag]").addClass("flagged")
|
||||
@$("[data-role=thread-flag]").removeClass("notflagged")
|
||||
@$(".discussion-flag-abuse .flag-label").html("Misuse Reported")
|
||||
else
|
||||
@$("[data-role=thread-flag]").removeClass("flagged")
|
||||
@$("[data-role=thread-flag]").addClass("notflagged")
|
||||
@$(".discussion-flag-abuse .flag-label").html("Report Misuse")
|
||||
|
||||
updateModelDetails: =>
|
||||
@renderFlagged()
|
||||
@@ -44,7 +44,6 @@
|
||||
</header>
|
||||
|
||||
<div class="post-body">${'<%- body %>'}</div>
|
||||
|
||||
<div class="discussion-flag-abuse notflagged" data-role="thread-flag" data-tooltip="flag">
|
||||
<i class="icon"></i><span class="flag-label">Report Misuse</span></div>
|
||||
|
||||
@@ -111,7 +110,6 @@
|
||||
<p class="posted-details" title="${'<%- created_at %>'}">${'<%- created_at %>'}</p>
|
||||
</header>
|
||||
<div class="response-local"><div class="response-body">${"<%- body %>"}</div>
|
||||
|
||||
<div class="discussion-flag-abuse notflagged" data-role="thread-flag" data-tooltip="flag">
|
||||
<i class="icon"></i><span class="flag-label">Report Misuse</span></div>
|
||||
</div>
|
||||
@@ -138,7 +136,7 @@
|
||||
<div id="comment_${'<%- id %>'}">
|
||||
<div class="response-body">${'<%- body %>'}</div>
|
||||
<div class="discussion-flag-abuse notflagged" data-role="thread-flag" data-tooltip="flag">
|
||||
<i class="icon"></i><span class="flag-label">Report Misuse</span></div>
|
||||
<i class="icon"></i><span class="flag-label"></span></div>
|
||||
<p class="posted-details">–posted <span class="timeago" title="${'<%- created_at %>'}">${'<%- created_at %>'}</span> by
|
||||
${"<% if (obj.username) { %>"}
|
||||
<a href="${'<%- user_url %>'}" class="profile-link">${'<%- username %>'}</a>
|
||||
|
||||
Reference in New Issue
Block a user