Revert "fix merge conflict"
This reverts commitacfd0d9fd6, reversing changes made toe4194c99d8.
This commit is contained in:
@@ -11,8 +11,6 @@ urlpatterns = patterns('django_comment_client.base.views',
|
||||
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\-]+)/downvote$', 'vote_for_thread', {'value': 'down'}, name='downvote_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\-]+)/unvote$', 'undo_vote_for_thread', name='undo_vote_for_thread'),
|
||||
url(r'threads/(?P<thread_id>[\w\-]+)/pin$', 'pin_thread', name='pin_thread'),
|
||||
url(r'threads/(?P<thread_id>[\w\-]+)/unpin$', 'un_pin_thread', name='un_pin_thread'),
|
||||
@@ -27,8 +25,7 @@ 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'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?
|
||||
url(r'^(?P<commentable_id>[\w\-.]+)/threads/search_similar$', 'search_similar_threads', name='search_similar_threads'),
|
||||
|
||||
@@ -20,7 +20,7 @@ from django.utils.translation import ugettext as _
|
||||
from django.contrib.auth.models import User
|
||||
|
||||
from mitxmako.shortcuts import render_to_response, render_to_string
|
||||
from courseware.courses import get_course_with_access, get_course_by_id
|
||||
from courseware.courses import get_course_with_access
|
||||
from course_groups.cohorts import get_cohort_id, is_commentable_cohorted
|
||||
|
||||
from django_comment_client.utils import JsonResponse, JsonError, extract, get_courseware_context
|
||||
@@ -119,7 +119,7 @@ def create_thread(request, course_id, commentable_id):
|
||||
#patch for backward compatibility to comments service
|
||||
if not 'pinned' in thread.attributes:
|
||||
thread['pinned'] = False
|
||||
|
||||
|
||||
if post.get('auto_subscribe', 'false').lower() == 'true':
|
||||
user = cc.User.from_django_user(request.user)
|
||||
user.follow(thread)
|
||||
@@ -284,50 +284,6 @@ def vote_for_thread(request, course_id, thread_id, value):
|
||||
return JsonResponse(utils.safe_content(thread.to_dict()))
|
||||
|
||||
|
||||
@require_POST
|
||||
@login_required
|
||||
@permitted
|
||||
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)
|
||||
return JsonResponse(utils.safe_content(thread.to_dict()))
|
||||
|
||||
|
||||
@require_POST
|
||||
@login_required
|
||||
@permitted
|
||||
def un_flag_abuse_for_thread(request, course_id, thread_id):
|
||||
user = cc.User.from_django_user(request.user)
|
||||
course = get_course_by_id(course_id)
|
||||
thread = cc.Thread.find(thread_id)
|
||||
removeAll = cached_has_permission(request.user, 'openclose_thread', course_id) or has_access(request.user, course, 'staff')
|
||||
thread.unFlagAbuse(user, thread, removeAll)
|
||||
return JsonResponse(utils.safe_content(thread.to_dict()))
|
||||
|
||||
|
||||
@require_POST
|
||||
@login_required
|
||||
@permitted
|
||||
def flag_abuse_for_comment(request, course_id, comment_id):
|
||||
user = cc.User.from_django_user(request.user)
|
||||
comment = cc.Comment.find(comment_id)
|
||||
comment.flagAbuse(user, comment)
|
||||
return JsonResponse(utils.safe_content(comment.to_dict()))
|
||||
|
||||
|
||||
@require_POST
|
||||
@login_required
|
||||
@permitted
|
||||
def un_flag_abuse_for_comment(request, course_id, comment_id):
|
||||
user = cc.User.from_django_user(request.user)
|
||||
course = get_course_by_id(course_id)
|
||||
removeAll = cached_has_permission(request.user, 'openclose_thread', course_id) or has_access(request.user, course, 'staff')
|
||||
comment = cc.Comment.find(comment_id)
|
||||
comment.unFlagAbuse(user, comment, removeAll)
|
||||
return JsonResponse(utils.safe_content(comment.to_dict()))
|
||||
|
||||
|
||||
@require_POST
|
||||
@login_required
|
||||
@permitted
|
||||
@@ -337,21 +293,19 @@ def undo_vote_for_thread(request, course_id, thread_id):
|
||||
user.unvote(thread)
|
||||
return JsonResponse(utils.safe_content(thread.to_dict()))
|
||||
|
||||
|
||||
@require_POST
|
||||
@login_required
|
||||
@permitted
|
||||
def pin_thread(request, course_id, thread_id):
|
||||
user = cc.User.from_django_user(request.user)
|
||||
thread = cc.Thread.find(thread_id)
|
||||
thread.pin(user, thread_id)
|
||||
thread.pin(user,thread_id)
|
||||
return JsonResponse(utils.safe_content(thread.to_dict()))
|
||||
|
||||
|
||||
def un_pin_thread(request, course_id, thread_id):
|
||||
user = cc.User.from_django_user(request.user)
|
||||
thread = cc.Thread.find(thread_id)
|
||||
thread.un_pin(user, thread_id)
|
||||
thread.un_pin(user,thread_id)
|
||||
return JsonResponse(utils.safe_content(thread.to_dict()))
|
||||
|
||||
|
||||
@@ -498,11 +452,16 @@ def upload(request, course_id): # ajax upload file to a question or answer
|
||||
if not file_extension in cc_settings.ALLOWED_UPLOAD_FILE_TYPES:
|
||||
file_types = "', '".join(cc_settings.ALLOWED_UPLOAD_FILE_TYPES)
|
||||
msg = _("allowed file types are '%(file_types)s'") % \
|
||||
{'file_types': file_types}
|
||||
{'file_types': file_types}
|
||||
raise exceptions.PermissionDenied(msg)
|
||||
|
||||
# generate new file name
|
||||
new_file_name = str(time.time()).replace('.', str(random.randint(0, 100000))) + file_extension
|
||||
new_file_name = str(
|
||||
time.time()
|
||||
).replace(
|
||||
'.',
|
||||
str(random.randint(0, 100000))
|
||||
) + file_extension
|
||||
|
||||
file_storage = get_storage_class()()
|
||||
# use default storage to store file
|
||||
@@ -513,7 +472,7 @@ def upload(request, course_id): # ajax upload file to a question or answer
|
||||
if size > cc_settings.MAX_UPLOAD_FILE_SIZE:
|
||||
file_storage.delete(new_file_name)
|
||||
msg = _("maximum upload file size is %(file_size)sK") % \
|
||||
{'file_size': cc_settings.MAX_UPLOAD_FILE_SIZE}
|
||||
{'file_size': cc_settings.MAX_UPLOAD_FILE_SIZE}
|
||||
raise exceptions.PermissionDenied(msg)
|
||||
|
||||
except exceptions.PermissionDenied, e:
|
||||
|
||||
@@ -9,10 +9,9 @@ from django.contrib.auth.models import User
|
||||
|
||||
from mitxmako.shortcuts import render_to_response, render_to_string
|
||||
from courseware.courses import get_course_with_access
|
||||
from course_groups.cohorts import (is_course_cohorted, get_cohort_id, is_commentable_cohorted,
|
||||
from course_groups.cohorts import (is_course_cohorted, get_cohort_id, is_commentable_cohorted,
|
||||
get_cohorted_commentables, get_course_cohorts, get_cohort_by_id)
|
||||
from courseware.access import has_access
|
||||
from django_comment_client.models import Role
|
||||
|
||||
from django_comment_client.permissions import cached_has_permission
|
||||
from django_comment_client.utils import (merge_dict, extract, strip_none, get_courseware_context)
|
||||
@@ -80,7 +79,7 @@ def get_threads(request, course_id, discussion_id=None, per_page=THREADS_PER_PAG
|
||||
strip_none(extract(request.GET,
|
||||
['page', 'sort_key',
|
||||
'sort_order', 'text',
|
||||
'tags', 'commentable_ids', 'flagged'])))
|
||||
'tags', 'commentable_ids'])))
|
||||
|
||||
threads, page, num_pages = cc.Thread.search(query_params)
|
||||
|
||||
@@ -93,7 +92,7 @@ def get_threads(request, course_id, discussion_id=None, per_page=THREADS_PER_PAG
|
||||
else:
|
||||
thread['group_name'] = ""
|
||||
thread['group_string'] = "This post visible to everyone."
|
||||
|
||||
|
||||
#patch for backward compatibility to comments service
|
||||
if not 'pinned' in thread:
|
||||
thread['pinned'] = False
|
||||
@@ -109,6 +108,7 @@ def inline_discussion(request, course_id, discussion_id):
|
||||
"""
|
||||
Renders JSON for DiscussionModules
|
||||
"""
|
||||
|
||||
course = get_course_with_access(request.user, course_id, 'load')
|
||||
|
||||
try:
|
||||
@@ -219,7 +219,6 @@ def forum_form_discussion(request, course_id):
|
||||
'threads': saxutils.escape(json.dumps(threads), escapedict),
|
||||
'thread_pages': query_params['num_pages'],
|
||||
'user_info': saxutils.escape(json.dumps(user_info), escapedict),
|
||||
'flag_moderator': cached_has_permission(request.user, 'openclose_thread', course.id) or has_access(request.user, course, 'staff'),
|
||||
'annotated_content_info': saxutils.escape(json.dumps(annotated_content_info), escapedict),
|
||||
'course_id': course.id,
|
||||
'category_map': category_map,
|
||||
@@ -242,12 +241,19 @@ def single_thread(request, course_id, discussion_id, thread_id):
|
||||
|
||||
try:
|
||||
thread = cc.Thread.find(thread_id).retrieve(recursive=True, user_id=request.user.id)
|
||||
|
||||
#patch for backward compatibility with comments service
|
||||
if not 'pinned' in thread.attributes:
|
||||
thread['pinned'] = False
|
||||
|
||||
except (cc.utils.CommentClientError, cc.utils.CommentClientUnknownError) as err:
|
||||
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
|
||||
@@ -319,7 +325,6 @@ def single_thread(request, course_id, discussion_id, thread_id):
|
||||
'thread_pages': query_params['num_pages'],
|
||||
'is_course_cohorted': is_course_cohorted(course_id),
|
||||
'is_moderator': cached_has_permission(request.user, "see_all_cohorts", course_id),
|
||||
'flag_moderator': cached_has_permission(request.user, 'openclose_thread', course.id) or has_access(request.user, course, 'staff'),
|
||||
'cohorts': cohorts,
|
||||
'user_cohort': get_cohort_id(request.user, course_id),
|
||||
'cohorted_commentables': cohorted_commentables
|
||||
@@ -407,7 +412,7 @@ def followed_threads(request, course_id, user_id):
|
||||
'user_info': saxutils.escape(json.dumps(user_info), escapedict),
|
||||
'annotated_content_info': saxutils.escape(json.dumps(annotated_content_info), escapedict),
|
||||
# 'content': content,
|
||||
}
|
||||
}
|
||||
|
||||
return render_to_response('discussion/user_profile.html', context)
|
||||
except (cc.utils.CommentClientError, cc.utils.CommentClientUnknownError):
|
||||
|
||||
@@ -6,11 +6,10 @@ from django.core.management.base import BaseCommand, CommandError
|
||||
from django.contrib.auth.models import User
|
||||
import comment_client as cc
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = 'Reload forum (comment client) users from existing users'
|
||||
|
||||
def adduser(self, user):
|
||||
def adduser(self,user):
|
||||
print user
|
||||
try:
|
||||
cc_user = cc.User.from_django_user(user)
|
||||
@@ -23,7 +22,8 @@ class Command(BaseCommand):
|
||||
uset = [User.objects.get(username=x) for x in args]
|
||||
else:
|
||||
uset = User.objects.all()
|
||||
|
||||
|
||||
for user in uset:
|
||||
self.adduser(user)
|
||||
|
||||
|
||||
|
||||
@@ -73,6 +73,7 @@ def check_conditions_permissions(user, permissions, course_id, **kwargs):
|
||||
return True in results
|
||||
elif operator == "and":
|
||||
return not False in results
|
||||
|
||||
return test(user, permissions, operator="or")
|
||||
|
||||
|
||||
@@ -88,10 +89,6 @@ VIEW_PERMISSIONS = {
|
||||
'vote_for_comment' : [['vote', 'is_open']],
|
||||
'undo_vote_for_comment': [['unvote', 'is_open']],
|
||||
'vote_for_thread' : [['vote', 'is_open']],
|
||||
'flag_abuse_for_thread': [['vote', 'is_open']],
|
||||
'un_flag_abuse_for_thread': [['vote', 'is_open']],
|
||||
'flag_abuse_for_comment': [['vote', 'is_open']],
|
||||
'un_flag_abuse_for_comment': [['vote', 'is_open']],
|
||||
'undo_vote_for_thread': [['unvote', 'is_open']],
|
||||
'pin_thread': ['create_comment'],
|
||||
'un_pin_thread': ['create_comment'],
|
||||
|
||||
@@ -39,3 +39,4 @@ class CloseThreadTextTest(TestCase):
|
||||
self.assertEqual(mustache_helpers.close_thread_text(self.contentOpen), 'Close thread')
|
||||
|
||||
#########################################################################################
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import time
|
||||
from collections import defaultdict
|
||||
import logging
|
||||
import time
|
||||
@@ -105,12 +104,12 @@ def filter_unstarted_categories(category_map):
|
||||
result_map = {}
|
||||
|
||||
unfiltered_queue = [category_map]
|
||||
filtered_queue = [result_map]
|
||||
filtered_queue = [result_map]
|
||||
|
||||
while len(unfiltered_queue) > 0:
|
||||
|
||||
unfiltered_map = unfiltered_queue.pop()
|
||||
filtered_map = filtered_queue.pop()
|
||||
filtered_map = filtered_queue.pop()
|
||||
|
||||
filtered_map["children"] = []
|
||||
filtered_map["entries"] = {}
|
||||
@@ -175,7 +174,8 @@ def initialize_discussion_info(course):
|
||||
category = " / ".join([x.strip() for x in category.split("/")])
|
||||
last_category = category.split("/")[-1]
|
||||
discussion_id_map[id] = {"location": module.location, "title": last_category + " / " + title}
|
||||
unexpanded_category_map[category].append({"title": title, "id": id, "sort_key": sort_key, "start_date": module.lms.start})
|
||||
unexpanded_category_map[category].append({"title": title, "id": id,
|
||||
"sort_key": sort_key, "start_date": module.lms.start})
|
||||
|
||||
category_map = {"entries": defaultdict(dict), "subcategories": defaultdict(dict)}
|
||||
for category_path, entries in unexpanded_category_map.items():
|
||||
@@ -202,9 +202,9 @@ def initialize_discussion_info(course):
|
||||
level = path[-1]
|
||||
if level not in node:
|
||||
node[level] = {"subcategories": defaultdict(dict),
|
||||
"entries": defaultdict(dict),
|
||||
"sort_key": level,
|
||||
"start_date": category_start_date}
|
||||
"entries": defaultdict(dict),
|
||||
"sort_key": level,
|
||||
"start_date": category_start_date}
|
||||
else:
|
||||
if node[level]["start_date"] > category_start_date:
|
||||
node[level]["start_date"] = category_start_date
|
||||
@@ -284,12 +284,12 @@ class QueryCountDebugMiddleware(object):
|
||||
|
||||
def get_ability(course_id, content, user):
|
||||
return {
|
||||
'editable': check_permissions_by_view(user, course_id, content, "update_thread" if content['type'] == 'thread' else "update_comment"),
|
||||
'can_reply': check_permissions_by_view(user, course_id, content, "create_comment" if content['type'] == 'thread' else "create_sub_comment"),
|
||||
'can_endorse': check_permissions_by_view(user, course_id, content, "endorse_comment") if content['type'] == 'comment' else False,
|
||||
'can_delete': check_permissions_by_view(user, course_id, content, "delete_thread" if content['type'] == 'thread' else "delete_comment"),
|
||||
'can_openclose': check_permissions_by_view(user, course_id, content, "openclose_thread") if content['type'] == 'thread' else False,
|
||||
'can_vote': check_permissions_by_view(user, course_id, content, "vote_for_thread" if content['type'] == 'thread' else "vote_for_comment"),
|
||||
'editable': check_permissions_by_view(user, course_id, content, "update_thread" if content['type'] == 'thread' else "update_comment"),
|
||||
'can_reply': check_permissions_by_view(user, course_id, content, "create_comment" if content['type'] == 'thread' else "create_sub_comment"),
|
||||
'can_endorse': check_permissions_by_view(user, course_id, content, "endorse_comment") if content['type'] == 'comment' else False,
|
||||
'can_delete': check_permissions_by_view(user, course_id, content, "delete_thread" if content['type'] == 'thread' else "delete_comment"),
|
||||
'can_openclose': check_permissions_by_view(user, course_id, content, "openclose_thread") if content['type'] == 'thread' else False,
|
||||
'can_vote': check_permissions_by_view(user, course_id, content, "vote_for_thread" if content['type'] == 'thread' else "vote_for_comment"),
|
||||
}
|
||||
|
||||
#TODO: RENAME
|
||||
@@ -318,7 +318,6 @@ def get_annotated_content_infos(course_id, thread, user, user_info):
|
||||
Get metadata for a thread and its children
|
||||
"""
|
||||
infos = {}
|
||||
|
||||
def annotate(content):
|
||||
infos[str(content['id'])] = get_annotated_content_info(course_id, content, user, user_info)
|
||||
for child in content.get('children', []):
|
||||
@@ -383,8 +382,8 @@ def get_courseware_context(content, course):
|
||||
location = id_map[id]["location"].url()
|
||||
title = id_map[id]["title"]
|
||||
|
||||
url = reverse('jump_to', kwargs={"course_id": course.location.course_id,
|
||||
"location": location})
|
||||
url = reverse('jump_to', kwargs={"course_id":course.location.course_id,
|
||||
"location": location})
|
||||
|
||||
content_info = {"courseware_url": url, "courseware_title": title}
|
||||
return content_info
|
||||
@@ -397,8 +396,7 @@ def safe_content(content):
|
||||
'updated_at', 'depth', 'type', 'commentable_id', 'comments_count',
|
||||
'at_position_list', 'children', 'highlighted_title', 'highlighted_body',
|
||||
'courseware_title', 'courseware_url', 'tags', 'unread_comments_count',
|
||||
'read', 'group_id', 'group_name', 'group_string', 'pinned', 'abuse_flaggers'
|
||||
|
||||
'read', 'group_id', 'group_name', 'group_string', 'pinned'
|
||||
]
|
||||
|
||||
if (content.get('anonymous') is False) and (content.get('anonymous_to_peers') is False):
|
||||
|
||||
@@ -11,12 +11,12 @@ class Comment(models.Model):
|
||||
'id', 'body', 'anonymous', 'anonymous_to_peers', 'course_id',
|
||||
'endorsed', 'parent_id', 'thread_id', 'username', 'votes', 'user_id',
|
||||
'closed', 'created_at', 'updated_at', 'depth', 'at_position_list',
|
||||
'type', 'commentable_id', 'abuse_flaggers'
|
||||
'type', 'commentable_id',
|
||||
]
|
||||
|
||||
updatable_fields = [
|
||||
'body', 'anonymous', 'anonymous_to_peers', 'course_id', 'closed',
|
||||
'user_id', 'endorsed'
|
||||
'user_id', 'endorsed',
|
||||
]
|
||||
|
||||
initializable_fields = updatable_fields
|
||||
@@ -42,32 +42,6 @@ class Comment(models.Model):
|
||||
else:
|
||||
return super(Comment, cls).url(action, params)
|
||||
|
||||
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_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, removeAll):
|
||||
if voteable.type == 'thread':
|
||||
url = _url_for_unflag_abuse_thread(voteable.id)
|
||||
elif voteable.type == 'comment':
|
||||
url = _url_for_unflag_abuse_comment(voteable.id)
|
||||
else:
|
||||
raise CommentClientError("Can flag/unflag for threads or comments")
|
||||
params = {'user_id': user.id}
|
||||
|
||||
if removeAll:
|
||||
params['all'] = True
|
||||
|
||||
request = perform_request('put', url, params)
|
||||
voteable.update_attributes(request)
|
||||
|
||||
|
||||
def _url_for_thread_comments(thread_id):
|
||||
return "{prefix}/threads/{thread_id}/comments".format(prefix=settings.PREFIX, thread_id=thread_id)
|
||||
@@ -75,11 +49,3 @@ def _url_for_thread_comments(thread_id):
|
||||
|
||||
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}/comments/{comment_id}/abuse_flags".format(prefix=settings.PREFIX, comment_id=comment_id)
|
||||
|
||||
|
||||
def _url_for_unflag_abuse_comment(comment_id):
|
||||
return "{prefix}/comments/{comment_id}/abuse_unflags".format(prefix=settings.PREFIX, comment_id=comment_id)
|
||||
|
||||
@@ -29,6 +29,7 @@ def search_trending_tags(course_id, query_params={}, *args, **kwargs):
|
||||
def tags_autocomplete(value, *args, **kwargs):
|
||||
return perform_request('get', _url_for_threads_tags_autocomplete(), {'value': value}, *args, **kwargs)
|
||||
|
||||
|
||||
def _url_for_search_similar_threads():
|
||||
return "{prefix}/search/threads/more_like_this".format(prefix=settings.PREFIX)
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
from .utils import *
|
||||
|
||||
import models
|
||||
import settings
|
||||
|
||||
@@ -10,7 +11,7 @@ class Thread(models.Model):
|
||||
'closed', 'tags', 'votes', 'commentable_id', 'username', 'user_id',
|
||||
'created_at', 'updated_at', 'comments_count', 'unread_comments_count',
|
||||
'at_position_list', 'children', 'type', 'highlighted_title',
|
||||
'highlighted_body', 'endorsed', 'read', 'group_id', 'group_name', 'pinned', 'abuse_flaggers'
|
||||
'highlighted_body', 'endorsed', 'read', 'group_id', 'group_name', 'pinned'
|
||||
]
|
||||
|
||||
updatable_fields = [
|
||||
@@ -26,13 +27,11 @@ 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'],
|
||||
'recursive': False}
|
||||
params = merge_dict(default_params, strip_blank(strip_none(query_params)))
|
||||
|
||||
if query_params.get('text') or query_params.get('tags') or query_params.get('commentable_ids'):
|
||||
url = cls.url(action='search')
|
||||
else:
|
||||
@@ -55,7 +54,6 @@ class Thread(models.Model):
|
||||
|
||||
@classmethod
|
||||
def url(cls, action, params={}):
|
||||
|
||||
if action in ['get_all', 'post']:
|
||||
return cls.url_for_threads(params)
|
||||
elif action == 'search':
|
||||
@@ -68,11 +66,12 @@ 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),
|
||||
}
|
||||
'recursive': kwargs.get('recursive'),
|
||||
'user_id': kwargs.get('user_id'),
|
||||
'mark_as_read': kwargs.get('mark_as_read', True),
|
||||
}
|
||||
|
||||
# user_id may be none, in which case it shouldn't be part of the
|
||||
# request.
|
||||
@@ -80,57 +79,23 @@ class Thread(models.Model):
|
||||
|
||||
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':
|
||||
url = _url_for_flag_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, removeAll):
|
||||
if voteable.type == 'thread':
|
||||
url = _url_for_unflag_abuse_thread(voteable.id)
|
||||
elif voteable.type == 'comment':
|
||||
url = _url_for_unflag_comment(voteable.id)
|
||||
else:
|
||||
raise CommentClientError("Can only flag/unflag for threads or comments")
|
||||
params = {'user_id': user.id}
|
||||
#if you're an admin, when you unflag, remove ALL flags
|
||||
if removeAll:
|
||||
params['all'] = True
|
||||
|
||||
request = perform_request('put', url, params)
|
||||
voteable.update_attributes(request)
|
||||
|
||||
|
||||
def pin(self, user, thread_id):
|
||||
url = _url_for_pin_thread(thread_id)
|
||||
params = {'user_id': user.id}
|
||||
request = perform_request('put', url, params)
|
||||
self.update_attributes(request)
|
||||
self.update_attributes(request)
|
||||
|
||||
def un_pin(self, user, thread_id):
|
||||
url = _url_for_un_pin_thread(thread_id)
|
||||
params = {'user_id': user.id}
|
||||
request = perform_request('put', url, params)
|
||||
self.update_attributes(request)
|
||||
|
||||
|
||||
def _url_for_flag_abuse_thread(thread_id):
|
||||
return "{prefix}/threads/{thread_id}/abuse_flags".format(prefix=settings.PREFIX, thread_id=thread_id)
|
||||
|
||||
|
||||
def _url_for_unflag_abuse_thread(thread_id):
|
||||
return "{prefix}/threads/{thread_id}/abuse_unflags".format(prefix=settings.PREFIX, thread_id=thread_id)
|
||||
|
||||
|
||||
self.update_attributes(request)
|
||||
|
||||
|
||||
def _url_for_pin_thread(thread_id):
|
||||
return "{prefix}/threads/{thread_id}/pin".format(prefix=settings.PREFIX, thread_id=thread_id)
|
||||
|
||||
|
||||
return "{prefix}/threads/{thread_id}/pin".format(prefix=settings.PREFIX, thread_id=thread_id)
|
||||
|
||||
def _url_for_un_pin_thread(thread_id):
|
||||
return "{prefix}/threads/{thread_id}/unpin".format(prefix=settings.PREFIX, thread_id=thread_id)
|
||||
return "{prefix}/threads/{thread_id}/unpin".format(prefix=settings.PREFIX, thread_id=thread_id)
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 40 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 38 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 362 B |
@@ -95,7 +95,6 @@
|
||||
|
||||
|
||||
body.discussion {
|
||||
|
||||
.new-post-form-errors {
|
||||
display: none;
|
||||
background: $error-red;
|
||||
@@ -1281,8 +1280,8 @@ body.discussion {
|
||||
.discussion-article {
|
||||
position: relative;
|
||||
padding: 40px;
|
||||
min-height: 468px;
|
||||
|
||||
min-height: 468px;
|
||||
|
||||
a {
|
||||
word-wrap: break-word;
|
||||
}
|
||||
@@ -1335,9 +1334,6 @@ body.discussion {
|
||||
background-position: 0 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
.discussion-post {
|
||||
@@ -2440,6 +2436,7 @@ body.discussion {
|
||||
@extend .discussion-module
|
||||
}
|
||||
|
||||
|
||||
.group-visibility-label {
|
||||
font-size: 12px;
|
||||
color:#000;
|
||||
@@ -2494,39 +2491,4 @@ body.discussion {
|
||||
.pinned-false
|
||||
{
|
||||
display:none;
|
||||
}
|
||||
|
||||
.discussion-flag-abuse {
|
||||
font-size: 12px;
|
||||
float:right;
|
||||
padding-right: 5px;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.notflagged .icon
|
||||
{
|
||||
display: inline-block;
|
||||
width: 10px;
|
||||
height: 14px;
|
||||
padding-right: 3px;
|
||||
background: transparent url('../images/notflagged.png') no-repeat 0 0;
|
||||
}
|
||||
|
||||
.flagged .icon
|
||||
{
|
||||
display: inline-block;
|
||||
width: 10px;
|
||||
height: 14px;
|
||||
padding-right: 3px;
|
||||
background: transparent url('../images/flagged.png') no-repeat 0 0;
|
||||
}
|
||||
|
||||
.flagged span {
|
||||
color: #B82066;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.notflagged span {
|
||||
color: #888;
|
||||
font-style: italic;
|
||||
}
|
||||
@@ -33,14 +33,6 @@
|
||||
<span class="board-name" data-discussion_id='#all'>Show All Discussions</span>
|
||||
</a>
|
||||
</li>
|
||||
%if flag_moderator:
|
||||
<li>
|
||||
<a href="#">
|
||||
<span class="board-name" data-discussion_id='#flagged'>Show Flagged Discussions</span>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
%endif
|
||||
<li>
|
||||
<a href="#">
|
||||
<span class="board-name" data-discussion_id='#following'>Following</span>
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
<script type="text/template" id="thread-template">
|
||||
<article class="discussion-article" data-id="${'<%- id %>'}">
|
||||
<div class="thread-content-wrapper"></div>
|
||||
|
||||
<ol class="responses">
|
||||
<li class="loading"><div class="loading-animation"></div></li>
|
||||
</ol>
|
||||
@@ -31,8 +30,7 @@
|
||||
<div class="group-visibility-label">${"<%- obj.group_string%>"}</div>
|
||||
${"<% } %>"}
|
||||
|
||||
<a href="#" class="vote-btn discussion-vote discussion-vote-up" data-role="discussion-vote" data-tooltip="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" data-tooltip="vote"><span class="plus-icon">+</span> <span class='votes-count-number'>${'<%- votes["up_count"] %>'}</span></a>
|
||||
<h1>${'<%- title %>'}</h1>
|
||||
<p class="posted-details">
|
||||
${"<% if (obj.username) { %>"}
|
||||
@@ -47,10 +45,6 @@
|
||||
</header>
|
||||
|
||||
<div class="post-body">${'<%- body %>'}</div>
|
||||
<div class="discussion-flag-abuse notflagged" data-role="thread-flag" data-tooltip="report misuse">
|
||||
<i class="icon"></i><span class="flag-label">Report Misuse</span></div>
|
||||
|
||||
|
||||
% if course and has_permission(user, 'openclose_thread', course.id):
|
||||
<div class="admin-pin discussion-pin notpinned" data-role="thread-pin" data-tooltip="pin this thread">
|
||||
<i class="icon"></i><span class="pin-label">Pin Thread</span></div>
|
||||
@@ -124,10 +118,7 @@
|
||||
${"<% } else {print('<span class=\"anonymous\"><em>anonymous</em></span>');} %>"}
|
||||
<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="report misuse">
|
||||
<i class="icon"></i><span class="flag-label">Report Misuse</span></div>
|
||||
</div>
|
||||
<div class="response-local"><div class="response-body">${"<%- body %>"}</div></div>
|
||||
<ul class="moderator-actions response-local">
|
||||
<li style="display: none"><a class="action-edit" href="javascript:void(0)"><span class="edit-icon"></span> Edit</a></li>
|
||||
<li style="display: none"><a class="action-delete" href="javascript:void(0)"><span class="delete-icon"></span> Delete</a></li>
|
||||
@@ -150,8 +141,6 @@
|
||||
<script type="text/template" id="response-comment-show-template">
|
||||
<div id="comment_${'<%- id %>'}">
|
||||
<div class="response-body">${'<%- body %>'}</div>
|
||||
<div class="discussion-flag-abuse notflagged" data-role="thread-flag" data-tooltip="report misuse">
|
||||
<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>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
<%include file="_new_post.html" />
|
||||
|
||||
<section class="discussion container" id="discussion-container" data-roles="${roles}" data-course-id="${course_id}" data-user-info="${user_info}" data-threads="${threads}" data-thread-pages="${thread_pages}" data-content-info="${annotated_content_info}" data-flag-moderator="${flag_moderator}">
|
||||
<section class="discussion container" id="discussion-container" data-roles="${roles}" data-course-id="${course_id}" data-user-info="${user_info}" data-threads="${threads}" data-thread-pages="${thread_pages}" data-content-info="${annotated_content_info}">
|
||||
<div class="discussion-body">
|
||||
<div class="sidebar"></div>
|
||||
<div class="discussion-column">
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
<%include file="_new_post.html" />
|
||||
|
||||
<section class="discussion container" id="discussion-container" data-roles="${roles}" data-course-id="${course_id}" data-user-info="${user_info}" data-threads="${threads}" data-content-info="${annotated_content_info}" data-thread-pages="${thread_pages}" data-flag-moderator="${flag_moderator}">
|
||||
<section class="discussion container" id="discussion-container" data-roles="${roles}" data-course-id="${course_id}" data-user-info="${user_info}" data-threads="${threads}" data-content-info="${annotated_content_info}" data-thread-pages="${thread_pages}">
|
||||
<div class="discussion-body">
|
||||
<div class="sidebar"></div>
|
||||
<div class="discussion-column"></div>
|
||||
|
||||
Reference in New Issue
Block a user