Commit e49226e9 by Rocky Duan

some refactor

parent 1c1d449a
......@@ -64,7 +64,7 @@ def ajax_content_response(request, course_id, content, template_name):
def create_thread(request, course_id, commentable_id):
post = request.POST
thread = cc.Thread(**extract(post, ['body', 'title', 'tags']))
thread.update_attributes({
thread.update_attributes(**{
'anonymous' : post.get('anonymous', 'false').lower() == 'true',
'commentable_id' : commentable_id,
'course_id' : course_id,
......@@ -94,7 +94,7 @@ def update_thread(request, course_id, thread_id):
def _create_comment(request, course_id, thread_id=None, parent_id=None):
post = request.POST
comment = cc.Comment(**extract(post, ['body']))
comment.update_attributes({
comment.update_attributes(**{
'anonymous' : post.get('anonymous', 'false').lower() == 'true',
'user_id' : request.user.id,
'course_id' : course_id,
......
......@@ -12,13 +12,14 @@ from courseware.courses import get_course_with_access
from dateutil.tz import tzlocal
from datehelper import time_ago_in_words
import django_comment_client.utils as utils
from urllib import urlencode
from django_comment_client.permissions import check_permissions_by_view
from django_comment_client.utils import merge_dict, extract, strip_none
import json
import comment_client as cc
import dateutil
import django_comment_client.utils as utils
import comment_client as cc
THREADS_PER_PAGE = 5
......@@ -65,11 +66,8 @@ def render_discussion(request, course_id, threads, *args, **kwargs):
'user': (lambda: reverse('django_comment_client.forum.views.user_profile', args=[course_id, user_id])),
}[discussion_type]()
print "start annotating"
annotated_content_infos = map(lambda x: utils.get_annotated_content_infos(course_id, x, request.user), threads)
print "start merging annotations"
annotated_content_info = reduce(utils.merge_dict, annotated_content_infos, {})
print "finished annotating"
annotated_content_info = reduce(merge_dict, annotated_content_infos, {})
context = {
'threads': threads,
......@@ -82,7 +80,7 @@ def render_discussion(request, course_id, threads, *args, **kwargs):
'pages_nearby_delta': PAGES_NEARBY_DELTA,
'discussion_type': discussion_type,
'base_url': base_url,
'query_params': utils.strip_none(utils.extract(query_params, ['page', 'sort_key', 'sort_order', 'tags', 'text'])),
'query_params': strip_none(extract(query_params, ['page', 'sort_key', 'sort_order', 'tags', 'text'])),
'annotated_content_info': json.dumps(annotated_content_info),
}
context = dict(context.items() + query_params.items())
......@@ -98,17 +96,21 @@ def render_user_discussion(*args, **kwargs):
return render_discussion(discussion_type='user', *args, **kwargs)
def get_threads(request, course_id, discussion_id=None):
query_params = {
'page': request.GET.get('page', 1),
'per_page': THREADS_PER_PAGE, #TODO maybe change this later
'sort_key': request.GET.get('sort_key', 'activity'),
'sort_order': request.GET.get('sort_order', 'desc'),
'text': request.GET.get('text', ''),
'tags': request.GET.get('tags', ''),
default_query_params = {
'page': 1,
'per_page': THREADS_PER_PAGE,
'sort_key': 'activity',
'sort_order': 'desc',
'text': '',
'tags': '',
'commentable_id': discussion_id,
'course_id': course_id,
}
query_params = merge_dict(default_query_params,
strip_none(extract(request.GET, ['page', 'sort_key', 'sort_order', 'text', 'tags'])))
threads, page, num_pages = cc.Thread.search(query_params)
query_params['page'] = page
......@@ -138,7 +140,6 @@ def forum_form_discussion(request, course_id):
threads, query_params = get_threads(request, course_id)
content = render_forum_discussion(request, course_id, threads, discussion_id=_general_discussion_id(course_id), query_params=query_params)
recent_active_threads = cc.search_recent_active_threads(
course_id,
recursive=False,
......@@ -159,6 +160,7 @@ def forum_form_discussion(request, course_id):
'recent_active_threads': recent_active_threads,
'trending_tags': trending_tags,
}
print "start rendering.."
return render_to_response('discussion/index.html', context)
def render_single_thread(request, discussion_id, course_id, thread_id):
......@@ -209,14 +211,14 @@ def single_thread(request, course_id, discussion_id, thread_id):
def user_profile(request, course_id, user_id):
course = get_course_with_access(request.user, course_id, 'load')
discussion_user = cc.User(id=user_id, course_id=course_id)
profiled_user = cc.User(id=user_id, course_id=course_id)
query_params = {
'page': request.GET.get('page', 1),
'per_page': THREADS_PER_PAGE, # more than threads_per_page to show more activities
}
threads, page, num_pages = discussion_user.active_threads(query_params)
threads, page, num_pages = profiled_user.active_threads(query_params)
query_params['page'] = page
query_params['num_pages'] = num_pages
......@@ -230,7 +232,7 @@ def user_profile(request, course_id, user_id):
'course': course,
'user': request.user,
'django_user': User.objects.get(id=user_id),
'discussion_user': discussion_user.to_dict(),
'profiled_user': profiled_user.to_dict(),
'content': content,
}
......
......@@ -20,9 +20,12 @@ def extract(dic, keys):
return {k: dic.get(k) for k in keys}
def strip_none(dic):
def _is_none(v):
return v is None or (isinstance(v, str) and len(v.strip()) == 0)
return dict([(k, v) for k, v in dic.iteritems() if not _is_none(v)])
return dict([(k, v) for k, v in dic.iteritems() if v is not None])
def strip_blank(dic):
def _is_blank(v):
return isinstance(v, str) and len(v.strip()) == 0
return dict([(k, v) for k, v in dic.iteritems() if not _is_blank(v)])
def merge_dict(dic1, dic2):
return dict(dic1.items() + dic2.items())
......
......@@ -41,7 +41,7 @@ PERFSTATS = False
# Features
MITX_FEATURES = {
'SAMPLE' : False,
'USE_DJANGO_PIPELINE' : True,
'USE_DJANGO_PIPELINE' : False,
'DISPLAY_HISTOGRAMS_TO_STAFF' : True,
'REROUTE_ACTIVATION_EMAIL' : False, # nonempty string = address for all activation emails
'DEBUG_LEVEL' : 0, # 0 = lowest level, least verbose, 255 = max level, most verbose
......
......@@ -30,8 +30,8 @@ class Thread(models.Model):
'per_page': 20,
'course_id': query_params['course_id'],
'recursive': False}
params = merge_dict(default_params, strip_none(query_params))
if query_params['text'] or query_params['tags']:
params = merge_dict(default_params, strip_blank(strip_none(query_params)))
if query_params.get('text') or query_params.get('tags'):
url = cls.url(action='search')
else:
url = cls.url(action='get_all', params=extract(params, 'commentable_id'))
......
......@@ -2,9 +2,12 @@ import requests
import json
def strip_none(dic):
def _is_none(v):
return v is None or (isinstance(v, str) and len(v.strip()) == 0)
return dict([(k, v) for k, v in dic.iteritems() if not _is_none(v)])
return dict([(k, v) for k, v in dic.iteritems() if v is not None])
def strip_blank(dic):
def _is_blank(v):
return isinstance(v, str) and len(v.strip()) == 0
return dict([(k, v) for k, v in dic.iteritems() if not _is_blank(v)])
def extract(dic, keys):
if isinstance(keys, str):
......
......@@ -402,5 +402,5 @@ initializeFollowThread = (thread) ->
$local(".admin-delete").remove()
if not Discussion.getContentInfo id, 'can_openclose'
$local(".discussion-openclose").remove()
if not Discussion.getContentInfo id, 'can_vote'
$local(".discussion-vote").css "visibility", "hidden"
#if not Discussion.getContentInfo id, 'can_vote'
# $local(".discussion-vote").css "visibility", "hidden"
<%namespace name="renderer" file="_thread.html"/>
<%! from django.template.defaultfilters import escapejs %>
<section class="discussion forum-discussion" _id="${discussion_id}">
......@@ -24,16 +23,4 @@
% endif
</section>
<%!
def escape_quotes(text):
return text.replace('\"', '\\\"').replace("\'", "\\\'")
%>
<script type="text/javascript">
var $$user_info = JSON.parse("${user_info | escapejs}");
var $$course_id = "${course_id | escapejs}";
if (typeof $$annotated_content_info === undefined || $$annotated_content_info === null) {
var $$annotated_content_info = {};
}
$$annotated_content_info = $.extend($$annotated_content_info, JSON.parse("${annotated_content_info | escapejs}"));
</script>
<%include file="_js_data.html" />
<%namespace name="renderer" file="_thread.html"/>
<%! from django.template.defaultfilters import escapejs %>
<section class="discussion inline-discussion" _id="${discussion_id}">
......@@ -14,11 +13,4 @@
<%include file="_paginator.html" />
</section>
<script type="text/javascript">
var $$user_info = JSON.parse("${user_info | escapejs}");
var $$course_id = "${course_id | escapejs}";
if (typeof $$annotated_content_info === undefined || $$annotated_content_info === null) {
var $$annotated_content_info = {};
}
$$annotated_content_info = $.extend($$annotated_content_info, JSON.parse("${annotated_content_info | escapejs}"));
</script>
<%include file="_js_data.html" />
<%! from django.template.defaultfilters import escapejs %>
<script type="text/javascript">
var $$user_info = JSON.parse("${user_info | escapejs}");
var $$course_id = "${course_id | escapejs}";
if (typeof $$annotated_content_info === undefined || $$annotated_content_info === null) {
var $$annotated_content_info = {};
}
$$annotated_content_info = $.extend($$annotated_content_info, JSON.parse("${annotated_content_info | escapejs}"));
</script>
<%namespace name='static' file='../static_content.html'/>
<!-- The configuration below is different from the main mathjax config because dollar signs make it easier
to integrate with Markdown. -->
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
tex2jax: {
inlineMath: [
["\\(","\\)"],
],
displayMath: [
["\\[","\\]"],
]
}
});
</script>
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
tex2jax: {
inlineMath: [
["\\(","\\)"],
],
displayMath: [
["\\[","\\]"],
]
}
});
</script>
## This must appear after all mathjax-config blocks, so it is after the imports from the other templates.
## It can't be run through static.url because MathJax uses crazy url introspection to do lazy loading of MathJax extension libraries
<script type="text/javascript" src="/static/js/vendor/mathjax-MathJax-c9db6ac/MathJax.js?config=TeX-MML-AM_HTMLorMML-full"></script>
<!---<script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js"> </script>-->
<script type="text/javascript" src="${static.url('js/split.js')}"></script>
<script type="text/javascript" src="${static.url('js/jquery.ajaxfileupload.js')}"></script>
<script type="text/javascript" src="${static.url('js/Markdown.Converter.js')}"></script>
<script type="text/javascript" src="${static.url('js/Markdown.Sanitizer.js')}"></script>
<script type="text/javascript" src="${static.url('js/Markdown.Editor.js')}"></script>
<script type="text/javascript" src="${static.url('js/jquery.autocomplete.js')}"></script>
<script type="text/javascript" src="${static.url('js/jquery.tagsinput.js')}"></script>
<script type="text/javascript" src="${static.url('js/mustache.js')}"></script>
<script type="text/javascript" src="${static.url('js/URI.min.js')}"></script>
<link href="${static.url('css/vendor/jquery.tagsinput.css')}" rel="stylesheet" type="text/css">
<link href="${static.url('css/vendor/jquery.autocomplete.css')}" rel="stylesheet" type="text/css">
## This must appear after all mathjax-config blocks, so it is after the imports from the other templates.
## It can't be run through static.url because MathJax uses crazy url introspection to do lazy loading of MathJax extension libraries
<script type="text/javascript" src="/static/js/vendor/mathjax-MathJax-c9db6ac/MathJax.js?config=TeX-MML-AM_HTMLorMML-full"></script>
<!---<script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js"> </script>-->
<script type="text/javascript" src="${static.url('js/split.js')}"></script>
<script type="text/javascript" src="${static.url('js/jquery.ajaxfileupload.js')}"></script>
<script type="text/javascript" src="${static.url('js/Markdown.Converter.js')}"></script>
<script type="text/javascript" src="${static.url('js/Markdown.Sanitizer.js')}"></script>
<script type="text/javascript" src="${static.url('js/Markdown.Editor.js')}"></script>
<script type="text/javascript" src="${static.url('js/jquery.autocomplete.js')}"></script>
<script type="text/javascript" src="${static.url('js/jquery.tagsinput.js')}"></script>
<script type="text/javascript" src="${static.url('js/mustache.js')}"></script>
<script type="text/javascript" src="${static.url('js/URI.min.js')}"></script>
<link href="${static.url('css/vendor/jquery.tagsinput.css')}" rel="stylesheet" type="text/css">
<link href="${static.url('css/vendor/jquery.autocomplete.css')}" rel="stylesheet" type="text/css">
<%namespace name="renderer" file="_thread.html"/>
<%! from django.template.defaultfilters import escapejs %>
<section class="discussion" _id="${discussion_id}">
<a class="discussion-title" href="javascript:void(0)">Discussion</a>
${renderer.render_thread(course_id, thread, show_comments=True)}
</section>
<script type="text/javascript">
var $$user_info = JSON.parse("${user_info | escapejs}");
var $$course_id = "${course_id | escapejs}";
if (typeof $$annotated_content_info === undefined || $$annotated_content_info === null) {
var $$annotated_content_info = {};
}
$$annotated_content_info = $.extend($$annotated_content_info, JSON.parse("${annotated_content_info | escapejs}"));
</script>
<%include file="_js_data.html" />
......@@ -5,15 +5,23 @@
<%! import urllib %>
<%!
def user_id_with_anonymity(content):
if content.get('anonymous', False):
def show_if(text, condition):
if condition:
return text
else:
return ''
%>
<%!
def close_thread_text(content):
if content.get('closed'):
return 'Re-open thread'
else:
return content['user_id']
return 'Close thread'
%>
<%def name="render_thread(course_id, thread, show_comments=False)">
<div class="thread" _id="${thread['id']}" _discussion_id="${thread['commentable_id']}" _author_id="${user_id_with_anonymity(thread)}">
<div class="thread" _id="${thread['id']}" _discussion_id="${thread['commentable_id']}" _author_id="${show_if(thread['user_id'], thread.get('anonymous'))}">
${render_content(thread, "thread", show_comments=show_comments)}
% if show_comments:
${render_comments(thread.get('children', []))}
......@@ -22,11 +30,7 @@
</%def>
<%def name="render_comment(comment)">
% if comment['endorsed']:
<div class="comment endorsed" _id="${comment['id']}" _author_id="${user_id_with_anonymity(comment)}">
% else:
<div class="comment" _id="${comment['id']}" _author_id="${user_id_with_anonymity(comment)}">
% endif
<div class="comment ${show_if('endorsed', comment.get('endorsed'))}" _id="${comment['id']}" _author_id="${show_if(comment['user_id'], comment.get('anonymous'))}">
${render_content(comment, "comment")}
<div class="comments">
${render_comments(comment.get('children', []))}
......@@ -45,7 +49,6 @@
<%def name="render_content(content, type, **kwargs)">
<div class="discussion-content">
<div class="discussion-content-wrapper">
${render_vote(content)}
<div class="discussion-right-wrapper">
<ul class="admin-actions">
......@@ -55,24 +58,13 @@
<li><a href="javascript:void(0)" class="admin-edit">Edit</a></li>
<li><a href="javascript:void(0)" class="admin-delete">Delete</a></li>
% if type == "thread":
<li>
% if content['closed']:
<a class="discussion-openclose" id="discussion-openclose-${content['id']}" href="javascript:void(0);">Re-open thread</a>
% else:
<a class="discussion-openclose" id="discussion-openclose-${content['id']}" href="javascript:void(0);">Close thread</a>
% endif
</li>
<li><a class="discussion-openclose" id="discussion-openclose-${content['id']}" href="javascript:void(0);">${close_thread_text(content)}</a></li>
% endif
</ul>
${render_title(content, type, **kwargs)}
<div class="discussion-content-view">
<a name="${content['id']}" style="width: 0; height: 0; padding: 0; border: none;"></a>
% if content.get('highlighted_body', None):
<div class="content-body ${type}-body" id="content-body-${content['id']}">${content['highlighted_body'] | h}</div>
% else:
<div class="content-body ${type}-body" id="content-body-${content['id']}">${content['body'] | h}</div>
% endif
<div class="content-body ${type}-body" id="content-body-${content['id']}">${(content.get('highlighted_body') or content['body']) | h}</div>
<div class="content-raw-body ${type}-raw-body" style="display: none">${content['body'] | h}</div>
${render_tags(content, type, **kwargs)}
${render_bottom_bar(content, type, **kwargs)}
......@@ -84,11 +76,7 @@
<%def name="render_title(content, type, **kwargs)">
% if type == "thread":
% if content.get('highlighted_title', None):
<a class="thread-title" name="${content['id']}" href="javascript:void(0)">${content['highlighted_title'] | h}</a>
% else:
<a class="thread-title" name="${content['id']}" href="javascript:void(0)">${content['title'] | h}</a>
% endif
<a class="thread-title" name="${content['id']}" href="javascript:void(0)">${(content.get('highlighted_title') or content['title']) | h}</a>
<div class="thread-raw-title" style="display: none">${content['title']}</div>
% endif
</%def>
......@@ -110,7 +98,7 @@
<%def name="render_bottom_bar(content, type, **kwargs)">
<div class="info">
${render_info(content, type, **kwargs)}
${render_info(content, type, **kwargs)}
<ul class="discussion-actions">
<li>${render_link("discussion-link discussion-reply discussion-reply-" + type, "Reply")}</li>
<li><div class="follow-wrapper"></div></li>
......
<%namespace name="renderer" file="_thread.html"/>
<%! from django.template.defaultfilters import escapejs %>
<section class="discussion user-active-discussion">
......@@ -14,11 +13,4 @@
<%include file="_paginator.html" />
</section>
<script type="text/javascript">
var $$user_info = JSON.parse("${user_info | escapejs}");
var $$course_id = "${course_id | escapejs}";
if (typeof $$annotated_content_info === undefined || $$annotated_content_info === null) {
var $$annotated_content_info = {};
}
$$annotated_content_info = $.extend($$annotated_content_info, JSON.parse("${annotated_content_info | escapejs}"));
</script>
<%include file="_js_data.html" />
<%! from django_comment_client.utils import pluralize %>
<%! from django_comment_client.permissions import has_permission, check_permissions_by_view %>
<%! from operator import attrgetter %>
<div class="user-profile">
<%
role_names = sorted(map(lambda x: x.name, django_user.roles.all()))
role_names = sorted(map(attrgetter('name'), django_user.roles.all()))
%>
<div class="sidebar-username">${django_user.username}</div>
<div class="sidebar-user-roles">
${", ".join(role_names)}
</div>
<div class="sidebar-threads-count"><span>${discussion_user['threads_count']}</span> ${pluralize('discussion', discussion_user['threads_count'])} started</div>
<div class="sidebar-comments-count"><span>${discussion_user['comments_count']}</span> ${pluralize('comment', discussion_user['comments_count'])}</div>
<div class="sidebar-threads-count"><span>${profiled_user['threads_count']}</span> ${pluralize('discussion', profiled_user['threads_count'])} started</div>
<div class="sidebar-comments-count"><span>${profiled_user['comments_count']}</span> ${pluralize('comment', profiled_user['comments_count'])}</div>
% if check_permissions_by_view(user, course.id, content=None, name='update_moderator_status'):
% if "Moderator" in role_names:
<a href="javascript:void(0)" class="sidebar-revoke-moderator-button">Revoke Moderator provileges</a>
......
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