Merge branch 'master' of github.com:dementrock/mitx into discussion2
This commit is contained in:
@@ -10,30 +10,13 @@ import comment_client
|
||||
from django.core import exceptions
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.views.decorators.http import require_POST, require_GET
|
||||
from django.http import HttpResponse
|
||||
from django.utils import simplejson
|
||||
from django.views.decorators import csrf
|
||||
from django.core.files.storage import get_storage_class
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.conf import settings
|
||||
|
||||
class JsonResponse(HttpResponse):
|
||||
def __init__(self, data=None):
|
||||
content = simplejson.dumps(data,
|
||||
indent=2,
|
||||
ensure_ascii=False)
|
||||
super(JsonResponse, self).__init__(content,
|
||||
mimetype='application/json; charset=utf8')
|
||||
from django_comment_client.utils import JsonResponse, JsonError
|
||||
|
||||
class JsonError(HttpResponse):
|
||||
def __init__(self, status, error_message=""):
|
||||
content = simplejson.dumps({'errors': error_message},
|
||||
indent=2,
|
||||
ensure_ascii=False)
|
||||
super(JsonError, self).__init__(content,
|
||||
status=status,
|
||||
mimetype='application/json; charset=utf8')
|
||||
|
||||
def thread_author_only(fn):
|
||||
def verified_fn(request, *args, **kwargs):
|
||||
thread_id = args.get('thread_id', False) or \
|
||||
|
||||
@@ -60,7 +60,7 @@ def forum_form_discussion(request, course_id, discussion_id):
|
||||
search_text = request.GET.get('text', '')
|
||||
|
||||
if len(search_text) > 0:
|
||||
threads = comment_client.search(search_text, discussion_id)
|
||||
threads = comment_client.search_threads({'text': search_text, 'commentable_id': discussion_id})
|
||||
else:
|
||||
threads = comment_client.get_threads(discussion_id, recursive=False)
|
||||
|
||||
|
||||
9
lms/djangoapps/django_comment_client/middleware.py
Normal file
9
lms/djangoapps/django_comment_client/middleware.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from comment_client import CommentClientError
|
||||
from django_comment_client.utils import JsonError
|
||||
import json
|
||||
|
||||
class AjaxExceptionMiddleware(object):
|
||||
def process_exception(self, request, exception):
|
||||
if isinstance(exception, CommentClientError) and request.is_ajax():
|
||||
return JsonError(json.loads(exception.message))
|
||||
return None
|
||||
@@ -3,6 +3,8 @@ from courseware.models import StudentModuleCache
|
||||
from courseware.module_render import get_module
|
||||
from xmodule.modulestore import Location
|
||||
from xmodule.modulestore.django import modulestore
|
||||
from django.http import HttpResponse
|
||||
from django.utils import simplejson
|
||||
|
||||
from django.conf import settings
|
||||
import operator
|
||||
@@ -88,3 +90,19 @@ def initialize_discussion_info(request, course):
|
||||
'discussion_id': url_course_id,
|
||||
'category': 'General',
|
||||
}]
|
||||
|
||||
class JsonResponse(HttpResponse):
|
||||
def __init__(self, data=None):
|
||||
content = simplejson.dumps(data,
|
||||
indent=2,
|
||||
ensure_ascii=False)
|
||||
super(JsonResponse, self).__init__(content,
|
||||
mimetype='application/json; charset=utf8')
|
||||
|
||||
class JsonError(HttpResponse):
|
||||
def __init__(self, error_message=""):
|
||||
content = simplejson.dumps({'errors': error_message},
|
||||
indent=2,
|
||||
ensure_ascii=False)
|
||||
super(JsonError, self).__init__(content,
|
||||
mimetype='application/json; charset=utf8')
|
||||
|
||||
@@ -273,6 +273,7 @@ TEMPLATE_LOADERS = (
|
||||
|
||||
MIDDLEWARE_CLASSES = (
|
||||
'util.middleware.ExceptionLoggingMiddleware',
|
||||
'django_comment_client.middleware.AjaxExceptionMiddleware',
|
||||
'django.middleware.common.CommonMiddleware',
|
||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||
'django.middleware.csrf.CsrfViewMiddleware',
|
||||
|
||||
@@ -6,7 +6,8 @@ SERVICE_HOST = 'http://localhost:4567'
|
||||
PREFIX = SERVICE_HOST + '/api/v1'
|
||||
|
||||
class CommentClientError(Exception):
|
||||
pass
|
||||
def __init__(self, msg):
|
||||
self.message = msg
|
||||
|
||||
class CommentClientUnknownError(CommentClientError):
|
||||
pass
|
||||
|
||||
@@ -168,6 +168,9 @@ Discussion =
|
||||
else
|
||||
editView = $("<div>").addClass("discussion-content-edit")
|
||||
|
||||
errorsField = $("<ul>").addClass("discussion-errors")
|
||||
editView.append(errorsField)
|
||||
|
||||
textarea = $("<div>").addClass("comment-edit")
|
||||
editView.append(textarea)
|
||||
|
||||
@@ -221,7 +224,11 @@ Discussion =
|
||||
autowatch = false || $local(".discussion-auto-watch").is(":checked")
|
||||
|
||||
$.post url, {body: body, anonymous: anonymous, autowatch: autowatch}, (response, textStatus) ->
|
||||
if textStatus == "success"
|
||||
if response.errors
|
||||
errorsField = $local(".discussion-errors").empty()
|
||||
for error in response.errors
|
||||
errorsField.append($("<li>").addClass("new-post-form-error").html(error))
|
||||
else
|
||||
Discussion.handleAnchorAndReload(response)
|
||||
, 'json'
|
||||
|
||||
@@ -232,6 +239,10 @@ Discussion =
|
||||
if textStatus == "success"
|
||||
Discussion.handleAnchorAndReload(response)
|
||||
, 'json'
|
||||
|
||||
handleEditThread = (elem) ->
|
||||
|
||||
handleEditComment = (elem) ->
|
||||
|
||||
$local(".discussion-reply").click ->
|
||||
handleReply(this)
|
||||
@@ -245,6 +256,13 @@ Discussion =
|
||||
$local(".discussion-vote-down").click ->
|
||||
handleVote(this, "down")
|
||||
|
||||
$local(".discussion-edit").click ->
|
||||
if $content.hasClass("thread")
|
||||
handleEditThread(this)
|
||||
else
|
||||
handleEditComment(this)
|
||||
|
||||
|
||||
initializeContent: (content) ->
|
||||
$content = $(content)
|
||||
$local = generateLocal($content.children(".discussion-content"))
|
||||
@@ -272,13 +290,17 @@ Discussion =
|
||||
tags = $local(".new-post-tags").val()
|
||||
url = Discussion.urlFor('create_thread', $local(".new-post-form").attr("_id"))
|
||||
$.post url, {title: title, body: body, tags: tags}, (response, textStatus) ->
|
||||
if textStatus == "success"
|
||||
if response.errors
|
||||
errorsField = $local(".discussion-errors").empty()
|
||||
for error in response.errors
|
||||
errorsField.append($("<li>").addClass("new-post-form-error").html(error))
|
||||
else
|
||||
Discussion.handleAnchorAndReload(response)
|
||||
, 'json'
|
||||
|
||||
$local(".discussion-search-form").submit (event) ->
|
||||
event.preventDefault()
|
||||
text = $local(".discussion-search-text").val()
|
||||
text = $local(".searchInput").val()
|
||||
isSearchWithinBoard = $local(".discussion-search-within-board").is(":checked")
|
||||
handleSearch(text, isSearchWithinBoard)
|
||||
|
||||
|
||||
@@ -7,7 +7,8 @@
|
||||
</div>
|
||||
${search_bar}
|
||||
<form class="new-post-form" _id="${discussion_id}">
|
||||
<input type="text" class="new-post-title" placeholder="Title"/>
|
||||
<ul class="discussion-errors"></ul>
|
||||
<input type="text" class="new-post-title" placeholder="Title"/>
|
||||
<div class="new-post-body"></div>
|
||||
<input class="new-post-tags" placeholder="Tags"/>
|
||||
<a class="discussion-new-post" href="javascript:void(0)">New Post</a>
|
||||
|
||||
@@ -4,70 +4,78 @@
|
||||
<%! import urllib %>
|
||||
|
||||
<%def name="render_thread(course_id, thread, edit_thread=False, show_comments=False)">
|
||||
<%
|
||||
if show_comments:
|
||||
url_for_thread = ""
|
||||
else:
|
||||
thread_id = thread['id']
|
||||
url_for_thread = reverse('django_comment_client.forum.views.single_thread', args=[course_id, thread_id])
|
||||
def url_for_tags(tags):
|
||||
return reverse('django_comment_client.forum.views.search', args=[course_id]) + '?' + urllib.urlencode({'tags': ",".join(tags)})
|
||||
%>
|
||||
|
||||
<div class="thread" _id="${thread['id']}">
|
||||
<div class="discussion-content">
|
||||
<div class="discussion-upper-wrapper clearfix">
|
||||
${render_vote(thread)}
|
||||
<div class="discussion-right-wrapper clearfix">
|
||||
<a class="thread-title" name="${thread['id']}" href="${url_for_thread}">${thread['title'] | h}</a>
|
||||
<div class="discussion-content-view">
|
||||
<div class="content-body thread-body">${thread['body'] | h}</div>
|
||||
<div class="thread-tags">
|
||||
% for tag in thread['tags']:
|
||||
<a class="thread-tag" href="${url_for_tags([tag])}">${tag}</a>
|
||||
% endfor
|
||||
</div>
|
||||
<div class="info">
|
||||
${render_info(thread)}
|
||||
% if edit_thread:
|
||||
${render_reply()}
|
||||
${render_edit()}
|
||||
% endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
${render_content(thread, "thread", edit_thread=edit_thread, show_comments=show_comments)}
|
||||
% if show_comments:
|
||||
<div class="comments">
|
||||
${render_comments(thread['children'])}
|
||||
</div>
|
||||
${render_comments(thread['children'])}
|
||||
% endif
|
||||
</div>
|
||||
</%def>
|
||||
|
||||
<%def name="render_comments(comments)">
|
||||
% for comment in comments:
|
||||
<div class="comment" _id="${comment['id']}">
|
||||
<div class="discussion-content">
|
||||
<div class="discussion-upper-wrapper clearfix">
|
||||
${render_vote(comment)}
|
||||
<div class="discussion-right-wrapper">
|
||||
<div class="discussion-content-view">
|
||||
<a class="content-body comment-body" name="${comment['id']}">${comment['body'] | h}</a>
|
||||
<div class="info">
|
||||
${render_info(comment)}
|
||||
${render_reply()}
|
||||
${render_edit()}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="comments">
|
||||
% for comment in comments:
|
||||
<div class="comment" _id="${comment['id']}">
|
||||
${render_content(comment, "comment")}
|
||||
<div class="comments">
|
||||
${render_comments(comment['children'])}
|
||||
</div>
|
||||
</div>
|
||||
<div class="comments">
|
||||
${render_comments(comment['children'])}
|
||||
% endfor
|
||||
</div>
|
||||
</%def>
|
||||
|
||||
<%def name="render_content(content, type, **kwargs)">
|
||||
<div class="discussion-content">
|
||||
<div class="discussion-upper-wrapper clearfix">
|
||||
${render_vote(content)}
|
||||
<div class="discussion-right-wrapper clearfix">
|
||||
${render_title(content, type, **kwargs)}
|
||||
<div class="discussion-content-view">
|
||||
<div class="content-body ${type}-body">${content['body'] | h}</div>
|
||||
${render_tags(content, type, **kwargs)}
|
||||
${render_bottom_bar(content, type, **kwargs)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
% endfor
|
||||
</div>
|
||||
</%def>
|
||||
|
||||
<%def name="render_title(content, type, **kwargs)">
|
||||
<%
|
||||
if kwargs.get('show_comments', False):
|
||||
url_for_thread = ""
|
||||
else:
|
||||
url_for_thread = reverse('django_comment_client.forum.views.single_thread', args=[course_id, content['id']])
|
||||
%>
|
||||
% if type == "thread":
|
||||
<a class="thread-title" name="${content['id']}" href="${url_for_thread}">${content['title'] | h}</a>
|
||||
% endif
|
||||
</%def>
|
||||
|
||||
<%def name="render_tags(content, type, **kwargs)">
|
||||
<%
|
||||
def url_for_tags(tags):
|
||||
return reverse('django_comment_client.forum.views.search', args=[course_id]) + '?' + urllib.urlencode({'tags': ",".join(tags)})
|
||||
%>
|
||||
% if type == "thread":
|
||||
<div class="thread-tags">
|
||||
% for tag in content['tags']:
|
||||
<a class="thread-tag" href="${url_for_tags([tag])}">${tag}</a>
|
||||
% endfor
|
||||
</div>
|
||||
% endif
|
||||
</%def>
|
||||
|
||||
<%def name="render_bottom_bar(content, type, **kwargs)">
|
||||
<div class="info">
|
||||
${render_info(content)}
|
||||
% if type == "thread" and kwargs['edit_thread'] or type == "comment":
|
||||
${render_link("discussion-link discussion-reply", "Reply")}
|
||||
${render_link("discussion-link discussion-edit", "Edit")}
|
||||
% endif
|
||||
</div>
|
||||
</%def>
|
||||
|
||||
<%def name="render_info(content)">
|
||||
@@ -79,26 +87,14 @@
|
||||
% endif
|
||||
</%def>
|
||||
|
||||
<%def name="render_reply()">
|
||||
<a class="discussion-link discussion-reply" href="javascript:void(0)">Reply</a>
|
||||
</%def>
|
||||
|
||||
<%def name="render_edit()">
|
||||
<a class="discussion-link discussion-edit" href="javascript:void(0)">Edit</a>
|
||||
</%def>
|
||||
|
||||
<%def name="render_watch_thread()">
|
||||
<a class="discussion-link discussion-watch-thread" href="javascript:void(0)">Watch</a>
|
||||
<%def name="render_link(cls, html)">
|
||||
<a class="${cls}" href="javascript:void(0)">${html}</a>
|
||||
</%def>
|
||||
|
||||
<%def name="render_vote(content)">
|
||||
<%
|
||||
upvote = "˄"
|
||||
downvote = "˅"
|
||||
%>
|
||||
<div class="discussion-votes" title="Current votes: ${content['votes']['point']}">
|
||||
<a class="discussion-vote discussion-vote-up" href="javascript:void(0)" title="Current votes: ${content['votes']['point']}">${upvote}</a>
|
||||
<div class="discussion-votes">
|
||||
${render_link("discussion-vote discussion-vote-up", "˄")}
|
||||
${content['votes']['point']}
|
||||
<a class="discussion-vote discussion-vote-down" href="javascript:void(0)" title="Current votes: ${content['votes']['point']}">${downvote}</a>
|
||||
${render_link("discussion-vote discussion-vote-down", "˅")}
|
||||
</div>
|
||||
</%def>
|
||||
|
||||
Reference in New Issue
Block a user