示例#1
0
def inline_discussion(request, course_id, discussion_id):
    """
    Renders JSON for DiscussionModules
    """
    nr_transaction = newrelic.agent.current_transaction()
    course_id = SlashSeparatedCourseKey.from_deprecated_string(course_id)

    course = get_course_with_access(request.user, 'load_forum', course_id)

    threads, query_params = get_threads(request, course_id, discussion_id, per_page=INLINE_THREADS_PER_PAGE)
    cc_user = cc.User.from_django_user(request.user)
    user_info = cc_user.to_dict()

    with newrelic.agent.FunctionTrace(nr_transaction, "get_metadata_for_threads"):
        annotated_content_info = utils.get_metadata_for_threads(course_id, threads, request.user, user_info)
    is_staff = cached_has_permission(request.user, 'openclose_thread', course.id)
    return utils.JsonResponse({
        'discussion_data': [utils.safe_content(thread, course_id, is_staff) for thread in threads],
        'user_info': user_info,
        'annotated_content_info': annotated_content_info,
        'page': query_params['page'],
        'num_pages': query_params['num_pages'],
        'roles': utils.get_role_ids(course_id),
        'course_settings': make_course_settings(course)
    })
示例#2
0
def _create_comment(request, course_id, thread_id=None, parent_id=None):
    """
    given a course_id, thread_id, and parent_id, create a comment,
    called from create_comment to do the actual creation
    """
    post = request.POST
    comment = cc.Comment(**extract(post, ['body']))

    course = get_course_with_access(request.user, course_id, 'load')
    if course.allow_anonymous:
        anonymous = post.get('anonymous', 'false').lower() == 'true'
    else:
        anonymous = False

    if course.allow_anonymous_to_peers:
        anonymous_to_peers = post.get('anonymous_to_peers', 'false').lower() == 'true'
    else:
        anonymous_to_peers = False

    comment.update_attributes(**{
        'anonymous': anonymous,
        'anonymous_to_peers': anonymous_to_peers,
        'user_id': request.user.id,
        'course_id': course_id,
        'thread_id': thread_id,
        'parent_id': parent_id,
    })
    comment.save()
    if post.get('auto_subscribe', 'false').lower() == 'true':
        user = cc.User.from_django_user(request.user)
        user.follow(comment.thread)
    if request.is_ajax():
        return ajax_content_response(request, course_id, comment.to_dict())
    else:
        return JsonResponse(utils.safe_content(comment.to_dict()))
示例#3
0
def ajax_content_response(request, course_id, content):
    user_info = cc.User.from_django_user(request.user).to_dict()
    annotated_content_info = get_annotated_content_info(course_id, content, request.user, user_info)
    return JsonResponse({
        'content': safe_content(content),
        'annotated_content_info': annotated_content_info,
    })
示例#4
0
def forum_form_discussion(request, course_id):
    """
    Renders the main Discussion page, potentially filtered by a search query
    """
    course_id = SlashSeparatedCourseKey.from_deprecated_string(course_id)
    nr_transaction = newrelic.agent.current_transaction()

    course = get_course_with_access(request.user, 'load_forum', course_id)
    course_settings = make_course_settings(course, include_category_map=True)

    try:
        unsafethreads, query_params = get_threads(request, course_id)   # This might process a search query
        threads = [utils.safe_content(thread) for thread in unsafethreads]
    except cc.utils.CommentClientMaintenanceError:
        log.warning("Forum is in maintenance mode")
        return render_to_response('discussion/maintenance.html', {})

    user = cc.User.from_django_user(request.user)
    user_info = user.to_dict()

    with newrelic.agent.FunctionTrace(nr_transaction, "get_metadata_for_threads"):
        annotated_content_info = utils.get_metadata_for_threads(course_id, threads, request.user, user_info)

    with newrelic.agent.FunctionTrace(nr_transaction, "add_courseware_context"):
        add_courseware_context(threads, course)

    if request.is_ajax():
        return utils.JsonResponse({
            'discussion_data': threads,   # TODO: Standardize on 'discussion_data' vs 'threads'
            'annotated_content_info': annotated_content_info,
            'num_pages': query_params['num_pages'],
            'page': query_params['page'],
            'corrected_text': query_params['corrected_text'],
        })
    else:
        with newrelic.agent.FunctionTrace(nr_transaction, "get_cohort_info"):
            user_cohort_id = get_cohort_id(request.user, course_id)

        context = {
            'csrf': csrf(request)['csrf_token'],
            'course': course,
            #'recent_active_threads': recent_active_threads,
            'staff_access': has_access(request.user, 'staff', course),
            'threads': _attr_safe_json(threads),
            'thread_pages': query_params['num_pages'],
            'user_info': _attr_safe_json(user_info),
            'flag_moderator': cached_has_permission(request.user, 'openclose_thread', course.id) or has_access(request.user, 'staff', course),
            'annotated_content_info': _attr_safe_json(annotated_content_info),
            'course_id': course.id.to_deprecated_string(),
            'roles': _attr_safe_json(utils.get_role_ids(course_id)),
            'is_moderator': cached_has_permission(request.user, "see_all_cohorts", course_id),
            'cohorts': course_settings["cohorts"],  # still needed to render _thread_list_template
            'user_cohort': user_cohort_id, # read from container in NewPostView
            'is_course_cohorted': is_course_cohorted(course_id),  # still needed to render _thread_list_template
            'sort_preference': user.default_sort_key,
            'category_map': course_settings["category_map"],
            'course_settings': _attr_safe_json(course_settings)
        }
        # print "start rendering.."
        return render_to_response('discussion/index.html', context)
示例#5
0
def vote_for_comment(request, course_id, comment_id, value):
    """
    given a course_id and comment_id,
    """
    user = cc.User.from_django_user(request.user)
    comment = cc.Comment.find(comment_id)
    user.vote(comment, value)
    return JsonResponse(safe_content(comment.to_dict()))
示例#6
0
def delete_comment(request, course_id, comment_id):
    """
    given a course_id and comment_id delete this comment
    ajax only
    """
    comment = cc.Comment.find(comment_id)
    comment.delete()
    return JsonResponse(safe_content(comment.to_dict()))
示例#7
0
def delete_thread(request, course_id, thread_id):
    """
    given a course_id and thread_id, delete this thread
    this is ajax only
    """
    thread = cc.Thread.find(thread_id)
    thread.delete()
    return JsonResponse(safe_content(thread.to_dict()))
示例#8
0
def un_pin_thread(request, course_id, thread_id):
    """
    given a course id and thread id, remove pin from this thread
    ajax only
    """
    user = cc.User.from_django_user(request.user)
    thread = cc.Thread.find(thread_id)
    thread.un_pin(user, thread_id)
    return JsonResponse(safe_content(thread.to_dict()))
示例#9
0
def delete_thread(request, course_id, thread_id):
    """
    given a course_id and thread_id, delete this thread
    this is ajax only
    """
    course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id)
    thread = cc.Thread.find(thread_id)
    thread.delete()
    return JsonResponse(safe_content(thread.to_dict(), course_key))
示例#10
0
def endorse_comment(request, course_id, comment_id):
    """
    given a course_id and comment_id, toggle the endorsement of this comment,
    ajax only
    """
    comment = cc.Comment.find(comment_id)
    comment.endorsed = request.POST.get('endorsed', 'false').lower() == 'true'
    comment.save()
    return JsonResponse(safe_content(comment.to_dict()))
示例#11
0
def undo_vote_for_comment(request, course_id, comment_id):
    """
    given a course id and comment id, remove vote
    ajax only
    """
    user = cc.User.from_django_user(request.user)
    comment = cc.Comment.find(comment_id)
    user.unvote(comment)
    return JsonResponse(safe_content(comment.to_dict()))
示例#12
0
def vote_for_comment(request, course_id, comment_id, value):
    """
    given a course_id and comment_id,
    """
    course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id)
    user = cc.User.from_django_user(request.user)
    comment = cc.Comment.find(comment_id)
    user.vote(comment, value)
    return JsonResponse(safe_content(comment.to_dict(), course_key))
示例#13
0
def delete_comment(request, course_id, comment_id):
    """
    given a course_id and comment_id delete this comment
    ajax only
    """
    course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id)
    comment = cc.Comment.find(comment_id)
    comment.delete()
    return JsonResponse(safe_content(comment.to_dict(), course_key))
示例#14
0
def undo_vote_for_thread(request, course_id, thread_id):
    """
    given a course id and thread id, remove users vote for thread
    ajax only
    """
    user = cc.User.from_django_user(request.user)
    thread = cc.Thread.find(thread_id)
    user.unvote(thread)
    return JsonResponse(safe_content(thread.to_dict()))
示例#15
0
def flag_abuse_for_thread(request, course_id, thread_id):
    """
    given a course_id and thread_id flag this thread for abuse
    ajax only
    """
    user = cc.User.from_django_user(request.user)
    thread = cc.Thread.find(thread_id)
    thread.flagAbuse(user, thread)
    return JsonResponse(safe_content(thread.to_dict()))
示例#16
0
def flag_abuse_for_comment(request, course_id, comment_id):
    """
    given a course and comment id, flag comment for abuse
    ajax only
    """
    user = cc.User.from_django_user(request.user)
    comment = cc.Comment.find(comment_id)
    comment.flagAbuse(user, comment)
    return JsonResponse(safe_content(comment.to_dict()))
示例#17
0
def vote_for_thread(request, course_id, thread_id, value):
    """
    given a course id and thread id vote for this thread
    ajax only
    """
    user = cc.User.from_django_user(request.user)
    thread = cc.Thread.find(thread_id)
    user.vote(thread, value)
    return JsonResponse(safe_content(thread.to_dict()))
示例#18
0
def vote_for_thread(request, course_id, thread_id, value):
    """
    given a course id and thread id vote for this thread
    ajax only
    """
    course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id)
    user = cc.User.from_django_user(request.user)
    thread = cc.Thread.find(thread_id)
    user.vote(thread, value)
    return JsonResponse(safe_content(thread.to_dict(), course_key))
示例#19
0
def undo_vote_for_comment(request, course_id, comment_id):
    """
    given a course id and comment id, remove vote
    ajax only
    """
    course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id)
    user = cc.User.from_django_user(request.user)
    comment = cc.Comment.find(comment_id)
    user.unvote(comment)
    return JsonResponse(safe_content(comment.to_dict(), course_key))
示例#20
0
def undo_vote_for_comment(request, course_id, comment_id):
    """
    given a course id and comment id, remove vote
    ajax only
    """
    course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id)
    user = cc.User.from_django_user(request.user)
    comment = cc.Comment.find(comment_id)
    user.unvote(comment)
    return JsonResponse(safe_content(comment.to_dict(), course_key))
示例#21
0
def vote_for_thread(request, course_id, thread_id, value):
    """
    given a course id and thread id vote for this thread
    ajax only
    """
    course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id)
    user = cc.User.from_django_user(request.user)
    thread = cc.Thread.find(thread_id)
    user.vote(thread, value)
    return JsonResponse(safe_content(thread.to_dict(), course_key))
示例#22
0
def un_pin_thread(request, course_id, thread_id):
    """
    given a course id and thread id, remove pin from this thread
    ajax only
    """
    course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id)
    user = cc.User.from_django_user(request.user)
    thread = cc.Thread.find(thread_id)
    thread.un_pin(user, thread_id)
    return JsonResponse(safe_content(thread.to_dict(), course_key))
示例#23
0
def flag_abuse_for_thread(request, course_id, thread_id):
    """
    given a course_id and thread_id flag this thread for abuse
    ajax only
    """
    course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id)
    user = cc.User.from_django_user(request.user)
    thread = cc.Thread.find(thread_id)
    thread.flagAbuse(user, thread)
    return JsonResponse(safe_content(thread.to_dict(), course_key))
示例#24
0
def flag_abuse_for_comment(request, course_id, comment_id):
    """
    given a course and comment id, flag comment for abuse
    ajax only
    """
    course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id)
    user = cc.User.from_django_user(request.user)
    comment = cc.Comment.find(comment_id)
    comment.flagAbuse(user, comment)
    return JsonResponse(safe_content(comment.to_dict(), course_key))
示例#25
0
def update_thread(request, course_id, thread_id):
    """
    Given a course id and thread id, update a existing thread, used for both static and ajax submissions
    """
    thread = cc.Thread.find(thread_id)
    thread.update_attributes(**extract(request.POST, ['body', 'title']))
    thread.save()
    if request.is_ajax():
        return ajax_content_response(request, course_id, thread.to_dict())
    else:
        return JsonResponse(utils.safe_content(thread.to_dict()))
示例#26
0
def endorse_comment(request, course_id, comment_id):
    """
    given a course_id and comment_id, toggle the endorsement of this comment,
    ajax only
    """
    course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id)
    comment = cc.Comment.find(comment_id)
    comment.endorsed = request.POST.get('endorsed', 'false').lower() == 'true'
    comment.endorsement_user_id = request.user.id
    comment.save()
    return JsonResponse(safe_content(comment.to_dict(), course_key))
示例#27
0
def un_flag_abuse_for_comment(request, course_id, comment_id):
    """
    given a course_id and comment id, unflag comment for abuse
    ajax only
    """
    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()))
示例#28
0
def un_flag_abuse_for_thread(request, course_id, thread_id):
    """
    given a course id and thread id, remove abuse flag for this thread
    ajax only
    """
    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()))
示例#29
0
def endorse_comment(request, course_id, comment_id):
    """
    given a course_id and comment_id, toggle the endorsement of this comment,
    ajax only
    """
    course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id)
    comment = cc.Comment.find(comment_id)
    comment.endorsed = request.POST.get('endorsed', 'false').lower() == 'true'
    comment.endorsement_user_id = request.user.id
    comment.save()
    return JsonResponse(safe_content(comment.to_dict(), course_key))
示例#30
0
def un_flag_abuse_for_thread(request, course_id, thread_id):
    """
    given a course id and thread id, remove abuse flag for this thread
    ajax only
    """
    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()))
示例#31
0
def un_flag_abuse_for_comment(request, course_id, comment_id):
    """
    given a course_id and comment id, unflag comment for abuse
    ajax only
    """
    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()))
示例#32
0
def update_thread(request, course_id, thread_id):
    """
    Given a course id and thread id, update a existing thread, used for both static and ajax submissions
    """
    thread = cc.Thread.find(thread_id)
    thread.update_attributes(**extract(request.POST, ['body', 'title', 'tags']))
    thread.save()
    if request.is_ajax():
        return ajax_content_response(request, course_id, thread.to_dict())
    else:
        return JsonResponse(utils.safe_content(thread.to_dict()))
示例#33
0
def update_comment(request, course_id, comment_id):
    """
    given a course_id and comment_id, update the comment with payload attributes
    handles static and ajax submissions
    """
    comment = cc.Comment.find(comment_id)
    comment.update_attributes(**extract(request.POST, ['body']))
    comment.save()
    if request.is_ajax():
        return ajax_content_response(request, course_id, comment.to_dict(), 'discussion/ajax_update_comment.html')
    else:
        return JsonResponse(utils.safe_content(comment.to_dict()))
示例#34
0
def openclose_thread(request, course_id, thread_id):
    """
    given a course_id and thread_id, toggle the status of this thread
    ajax only
    """
    thread = cc.Thread.find(thread_id)
    thread.closed = request.POST.get("closed", "false").lower() == "true"
    thread.save()
    thread = thread.to_dict()
    return JsonResponse(
        {"content": utils.safe_content(thread), "ability": utils.get_ability(course_id, thread, request.user)}
    )
示例#35
0
def un_flag_abuse_for_comment(request, course_id, comment_id):
    """
    given a course_id and comment id, unflag comment for abuse
    ajax only
    """
    user = cc.User.from_django_user(request.user)
    course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id)
    course = get_course_by_id(course_key)
    remove_all = cached_has_permission(request.user, 'openclose_thread', course_key) or has_access(request.user, 'staff', course)
    comment = cc.Comment.find(comment_id)
    comment.unFlagAbuse(user, comment, remove_all)
    return JsonResponse(safe_content(comment.to_dict(), course_key))
示例#36
0
def un_flag_abuse_for_comment(request, course_id, comment_id):
    """
    given a course_id and comment id, unflag comment for abuse
    ajax only
    """
    user = cc.User.from_django_user(request.user)
    course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id)
    course = get_course_by_id(course_key)
    remove_all = cached_has_permission(request.user, 'openclose_thread', course_key) or has_access(request.user, 'staff', course)
    comment = cc.Comment.find(comment_id)
    comment.unFlagAbuse(user, comment, remove_all)
    return JsonResponse(safe_content(comment.to_dict()))
示例#37
0
def un_flag_abuse_for_thread(request, course_id, thread_id):
    """
    given a course id and thread id, remove abuse flag for this thread
    ajax only
    """
    user = cc.User.from_django_user(request.user)
    course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id)
    course = get_course_by_id(course_key)
    thread = cc.Thread.find(thread_id)
    remove_all = cached_has_permission(request.user, 'openclose_thread', course_key) or has_access(request.user, 'staff', course)
    thread.unFlagAbuse(user, thread, remove_all)
    return JsonResponse(safe_content(thread.to_dict(), course_key))
示例#38
0
def un_flag_abuse_for_thread(request, course_id, thread_id):
    """
    given a course id and thread id, remove abuse flag for this thread
    ajax only
    """
    user = cc.User.from_django_user(request.user)
    course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id)
    course = get_course_by_id(course_key)
    thread = cc.Thread.find(thread_id)
    remove_all = cached_has_permission(request.user, 'openclose_thread', course_key) or has_access(request.user, 'staff', course)
    thread.unFlagAbuse(user, thread, remove_all)
    return JsonResponse(safe_content(thread.to_dict(), course_key))
示例#39
0
def ajax_content_response(request, course_id, content):
    context = {
        'course_id': course_id,
        'content': content,
    }
    user_info = cc.User.from_django_user(request.user).to_dict()
    annotated_content_info = utils.get_annotated_content_info(
        course_id, content, request.user, user_info)
    return JsonResponse({
        'content': utils.safe_content(content),
        'annotated_content_info': annotated_content_info,
    })
示例#40
0
def update_comment(request, course_id, comment_id):
    """
    given a course_id and comment_id, update the comment with payload attributes
    handles static and ajax submissions
    """
    comment = cc.Comment.find(comment_id)
    comment.update_attributes(**extract(request.POST, ['body']))
    comment.save()
    if request.is_ajax():
        return ajax_content_response(request, course_id, comment.to_dict())
    else:
        return JsonResponse(utils.safe_content(comment.to_dict()))
示例#41
0
def ajax_content_response(request, course_id, content, template_name):
    context = {
        'course_id': course_id,
        'content': content,
    }
    html = render_to_string(template_name, context)
    user_info = cc.User.from_django_user(request.user).to_dict()
    annotated_content_info = utils.get_annotated_content_info(course_id, content, request.user, user_info)
    return JsonResponse({
        'html': html,
        'content': utils.safe_content(content),
        'annotated_content_info': annotated_content_info,
    })
示例#42
0
def openclose_thread(request, course_id, thread_id):
    """
    given a course_id and thread_id, toggle the status of this thread
    ajax only
    """
    thread = cc.Thread.find(thread_id)
    thread.closed = request.POST.get('closed', 'false').lower() == 'true'
    thread.save()
    thread = thread.to_dict()
    return JsonResponse({
        'content': utils.safe_content(thread),
        'ability': utils.get_ability(course_id, thread, request.user),
    })
示例#43
0
def openclose_thread(request, course_id, thread_id):
    """
    given a course_id and thread_id, toggle the status of this thread
    ajax only
    """
    course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id)
    thread = cc.Thread.find(thread_id)
    thread.closed = request.POST.get('closed', 'false').lower() == 'true'
    thread.save()
    thread = thread.to_dict()
    return JsonResponse({
        'content': safe_content(thread, course_key),
        'ability': get_ability(course_key, thread, request.user),
    })
示例#44
0
def update_comment(request, course_id, comment_id):
    """
    given a course_id and comment_id, update the comment with payload attributes
    handles static and ajax submissions
    """
    comment = cc.Comment.find(comment_id)
    if 'body' not in request.POST or not request.POST['body'].strip():
        return JsonError(_("Body can't be empty"))
    comment.update_attributes(**extract(request.POST, ['body']))
    comment.save()
    if request.is_ajax():
        return ajax_content_response(request, course_id, comment.to_dict())
    else:
        return JsonResponse(utils.safe_content(comment.to_dict()))
示例#45
0
def update_comment(request, course_id, comment_id):
    """
    given a course_id and comment_id, update the comment with payload attributes
    handles static and ajax submissions
    """
    course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id)
    comment = cc.Comment.find(comment_id)
    if 'body' not in request.POST or not request.POST['body'].strip():
        return JsonError(_("Body can't be empty"))
    comment.body = request.POST["body"]
    comment.save()
    if request.is_ajax():
        return ajax_content_response(request, course_key, comment.to_dict())
    else:
        return JsonResponse(safe_content(comment.to_dict(), course_key))
示例#46
0
def update_thread(request, course_id, thread_id):
    """
    Given a course id and thread id, update a existing thread, used for both static and ajax submissions
    """
    if 'title' not in request.POST or not request.POST['title'].strip():
        return JsonError(_("Title can't be empty"))
    if 'body' not in request.POST or not request.POST['body'].strip():
        return JsonError(_("Body can't be empty"))
    thread = cc.Thread.find(thread_id)
    thread.body = request.POST["body"]
    thread.title = request.POST["title"]
    thread.save()
    if request.is_ajax():
        return ajax_content_response(request, course_id, thread.to_dict())
    else:
        return JsonResponse(utils.safe_content(thread.to_dict()))
示例#47
0
def user_profile(request, course_id, user_id):
    course_id = SlashSeparatedCourseKey.from_deprecated_string(course_id)
    nr_transaction = newrelic.agent.current_transaction()

    #TODO: Allow sorting?
    course = get_course_with_access(request.user, 'load_forum', course_id)
    try:
        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 = profiled_user.active_threads(query_params)
        query_params['page'] = page
        query_params['num_pages'] = num_pages
        user_info = cc.User.from_django_user(request.user).to_dict()

        with newrelic.agent.FunctionTrace(nr_transaction, "get_metadata_for_threads"):
            annotated_content_info = utils.get_metadata_for_threads(course_id, threads, request.user, user_info)

        if request.is_ajax():
            is_staff = cached_has_permission(request.user, 'openclose_thread', course.id)
            return utils.JsonResponse({
                'discussion_data': [utils.safe_content(thread, is_staff) for thread in threads],
                'page': query_params['page'],
                'num_pages': query_params['num_pages'],
                'annotated_content_info': _attr_safe_json(annotated_content_info),
            })
        else:
            context = {
                'course': course,
                'user': request.user,
                'django_user': User.objects.get(id=user_id),
                'profiled_user': profiled_user.to_dict(),
                'threads': _attr_safe_json(threads),
                'user_info': _attr_safe_json(user_info),
                'annotated_content_info': _attr_safe_json(annotated_content_info),
                'page': query_params['page'],
                'num_pages': query_params['num_pages'],
#                'content': content,
            }

            return render_to_response('discussion/user_profile.html', context)
    except User.DoesNotExist:
        raise Http404
示例#48
0
def inline_discussion(request, course_id, discussion_id):
    """
    Renders JSON for DiscussionModules
    """
    nr_transaction = newrelic.agent.current_transaction()
    course_id = SlashSeparatedCourseKey.from_deprecated_string(course_id)

    course = get_course_with_access(request.user, 'load_forum', course_id)
    cc_user = cc.User.from_django_user(request.user)
    user_info = cc_user.to_dict()

    try:
        threads, query_params = get_threads(request,
                                            course_id,
                                            discussion_id,
                                            per_page=INLINE_THREADS_PER_PAGE)
    except ValueError:
        return HttpResponseBadRequest("Invalid group_id")

    with newrelic.agent.FunctionTrace(nr_transaction,
                                      "get_metadata_for_threads"):
        annotated_content_info = utils.get_metadata_for_threads(
            course_id, threads, request.user, user_info)
    is_staff = cached_has_permission(request.user, 'openclose_thread',
                                     course.id)
    return utils.JsonResponse({
        'discussion_data': [
            utils.safe_content(thread, course_id, is_staff)
            for thread in threads
        ],
        'user_info':
        user_info,
        'annotated_content_info':
        annotated_content_info,
        'page':
        query_params['page'],
        'num_pages':
        query_params['num_pages'],
        'roles':
        utils.get_role_ids(course_id),
        'course_settings':
        make_course_settings(course)
    })
示例#49
0
def _create_comment(request, course_id, thread_id=None, parent_id=None):
    """
    given a course_id, thread_id, and parent_id, create a comment,
    called from create_comment to do the actual creation
    """
    post = request.POST

    if 'body' not in post or not post['body'].strip():
        return JsonError(_("Body can't be empty"))
    comment = cc.Comment(**extract(post, ['body']))

    course = get_course_with_access(request.user, course_id, 'load')
    if course.allow_anonymous:
        anonymous = post.get('anonymous', 'false').lower() == 'true'
    else:
        anonymous = False

    if course.allow_anonymous_to_peers:
        anonymous_to_peers = post.get('anonymous_to_peers',
                                      'false').lower() == 'true'
    else:
        anonymous_to_peers = False

    comment.update_attributes(
        **{
            'anonymous': anonymous,
            'anonymous_to_peers': anonymous_to_peers,
            'user_id': request.user.id,
            'course_id': course_id,
            'thread_id': thread_id,
            'parent_id': parent_id,
        })
    comment.save()
    if post.get('auto_subscribe', 'false').lower() == 'true':
        user = cc.User.from_django_user(request.user)
        user.follow(comment.thread)
    if request.is_ajax():
        return ajax_content_response(request, course_id, comment.to_dict())
    else:
        return JsonResponse(utils.safe_content(comment.to_dict()))
示例#50
0
def _create_comment(request, course_key, thread_id=None, parent_id=None):
    """
    given a course_key, thread_id, and parent_id, create a comment,
    called from create_comment to do the actual creation
    """
    assert isinstance(course_key, CourseKey)
    post = request.POST

    if 'body' not in post or not post['body'].strip():
        return JsonError(_("Body can't be empty"))

    course = get_course_with_access(request.user, 'load', course_key)
    if course.allow_anonymous:
        anonymous = post.get('anonymous', 'false').lower() == 'true'
    else:
        anonymous = False

    if course.allow_anonymous_to_peers:
        anonymous_to_peers = post.get('anonymous_to_peers', 'false').lower() == 'true'
    else:
        anonymous_to_peers = False

    comment = cc.Comment(
        anonymous=anonymous,
        anonymous_to_peers=anonymous_to_peers,
        user_id=request.user.id,
        course_id=course_key.to_deprecated_string(),
        thread_id=thread_id,
        parent_id=parent_id,
        body=post["body"]
    )
    comment.save()
    if post.get('auto_subscribe', 'false').lower() == 'true':
        user = cc.User.from_django_user(request.user)
        user.follow(comment.thread)
    if request.is_ajax():
        return ajax_content_response(request, course_key, comment.to_dict())
    else:
        return JsonResponse(safe_content(comment.to_dict(), course.id))
示例#51
0
def single_thread(request, course_id, discussion_id, thread_id):
    nr_transaction = newrelic.agent.current_transaction()

    course = get_course_with_access(request.user, course_id, 'load_forum')
    cc_user = cc.User.from_django_user(request.user)
    user_info = cc_user.to_dict()

    # Currently, the front end always loads responses via AJAX, even for this
    # page; it would be a nice optimization to avoid that extra round trip to
    # the comments service.
    try:
        thread = cc.Thread.find(thread_id).retrieve(
            recursive=request.is_ajax(),
            user_id=request.user.id,
            response_skip=request.GET.get("resp_skip"),
            response_limit=request.GET.get("resp_limit"))
    except cc.utils.CommentClientRequestError as e:
        if e.status_code == 404:
            raise Http404
        raise

    if request.is_ajax():
        with newrelic.agent.FunctionTrace(nr_transaction,
                                          "get_annotated_content_infos"):
            annotated_content_info = utils.get_annotated_content_infos(
                course_id, thread, request.user, user_info=user_info)
        content = utils.safe_content(thread.to_dict())
        with newrelic.agent.FunctionTrace(nr_transaction,
                                          "add_courseware_context"):
            add_courseware_context([content], course)
        return utils.JsonResponse({
            'content':
            content,
            'annotated_content_info':
            annotated_content_info,
        })

    else:
        with newrelic.agent.FunctionTrace(nr_transaction,
                                          "get_discussion_category_map"):
            category_map = utils.get_discussion_category_map(course)

        threads, query_params = get_threads(request, course_id)
        threads.append(thread.to_dict())

        course = get_course_with_access(request.user, course_id, 'load_forum')

        with newrelic.agent.FunctionTrace(nr_transaction,
                                          "add_courseware_context"):
            add_courseware_context(threads, course)

        for thread in threads:
            if thread.get('group_id') and not thread.get('group_name'):
                thread['group_name'] = get_cohort_by_id(
                    course_id, thread.get('group_id')).name

            #patch for backward compatibility with comments service
            if not "pinned" in thread:
                thread["pinned"] = False

        threads = [utils.safe_content(thread) for thread in threads]

        with newrelic.agent.FunctionTrace(nr_transaction,
                                          "get_metadata_for_threads"):
            annotated_content_info = utils.get_metadata_for_threads(
                course_id, threads, request.user, user_info)

        with newrelic.agent.FunctionTrace(nr_transaction, "get_cohort_info"):
            cohorts = get_course_cohorts(course_id)
            cohorted_commentables = get_cohorted_commentables(course_id)
            user_cohort = get_cohort_id(request.user, course_id)

        context = {
            'discussion_id':
            discussion_id,
            'csrf':
            csrf(request)['csrf_token'],
            'init':
            '',  # TODO: What is this?
            'user_info':
            saxutils.escape(json.dumps(user_info), escapedict),
            'annotated_content_info':
            saxutils.escape(json.dumps(annotated_content_info), escapedict),
            'course':
            course,
            #'recent_active_threads': recent_active_threads,
            'course_id':
            course.id,  # TODO: Why pass both course and course.id to template?
            'thread_id':
            thread_id,
            'threads':
            saxutils.escape(json.dumps(threads), escapedict),
            'category_map':
            category_map,
            'roles':
            saxutils.escape(json.dumps(utils.get_role_ids(course_id)),
                            escapedict),
            '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
        }

        return render_to_response('discussion/index.html', context)
示例#52
0
def forum_form_discussion(request, course_id):
    """
    Renders the main Discussion page, potentially filtered by a search query
    """
    nr_transaction = newrelic.agent.current_transaction()

    course = get_course_with_access(request.user, course_id, 'load_forum')
    with newrelic.agent.FunctionTrace(nr_transaction,
                                      "get_discussion_category_map"):
        category_map = utils.get_discussion_category_map(course)

    try:
        unsafethreads, query_params = get_threads(
            request, course_id)  # This might process a search query
        threads = [utils.safe_content(thread) for thread in unsafethreads]
    except cc.utils.CommentClientMaintenanceError:
        log.warning("Forum is in maintenance mode")
        return render_to_response('discussion/maintenance.html', {})

    user = cc.User.from_django_user(request.user)
    user_info = user.to_dict()

    with newrelic.agent.FunctionTrace(nr_transaction,
                                      "get_metadata_for_threads"):
        annotated_content_info = utils.get_metadata_for_threads(
            course_id, threads, request.user, user_info)

    with newrelic.agent.FunctionTrace(nr_transaction,
                                      "add_courseware_context"):
        add_courseware_context(threads, course)

    if request.is_ajax():
        return utils.JsonResponse({
            'discussion_data':
            threads,  # TODO: Standardize on 'discussion_data' vs 'threads'
            'annotated_content_info': annotated_content_info,
            'num_pages': query_params['num_pages'],
            'page': query_params['page'],
        })
    else:
        with newrelic.agent.FunctionTrace(nr_transaction, "get_cohort_info"):
            cohorts = get_course_cohorts(course_id)
            cohorted_commentables = get_cohorted_commentables(course_id)

            user_cohort_id = get_cohort_id(request.user, course_id)

        context = {
            'csrf':
            csrf(request)['csrf_token'],
            'course':
            course,
            #'recent_active_threads': recent_active_threads,
            'staff_access':
            has_access(request.user, course, 'staff'),
            '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,
            'roles':
            saxutils.escape(json.dumps(utils.get_role_ids(course_id)),
                            escapedict),
            'is_moderator':
            cached_has_permission(request.user, "see_all_cohorts", course_id),
            'cohorts':
            cohorts,
            'user_cohort':
            user_cohort_id,
            'cohorted_commentables':
            cohorted_commentables,
            'is_course_cohorted':
            is_course_cohorted(course_id)
        }
        # print "start rendering.."
        return render_to_response('discussion/index.html', context)
示例#53
0
def followed_threads(request, course_id, user_id):
    course_id = SlashSeparatedCourseKey.from_deprecated_string(course_id)
    nr_transaction = newrelic.agent.current_transaction()

    course = get_course_with_access(request.user, 'load_forum', course_id)
    try:
        profiled_user = cc.User(id=user_id, course_id=course_id)

        default_query_params = {
            'page': 1,
            'per_page':
            THREADS_PER_PAGE,  # more than threads_per_page to show more activities
            'sort_key': 'date',
            'sort_order': 'desc',
        }

        query_params = merge_dict(
            default_query_params,
            strip_none(
                extract(request.GET, [
                    'page',
                    'sort_key',
                    'sort_order',
                    'flagged',
                    'unread',
                    'unanswered',
                ])))

        try:
            group_id = get_group_id_for_comments_service(request, course_id)
        except ValueError:
            return HttpResponseBadRequest("Invalid group_id")
        if group_id is not None:
            query_params['group_id'] = group_id

        threads, page, num_pages = profiled_user.subscribed_threads(
            query_params)
        query_params['page'] = page
        query_params['num_pages'] = num_pages
        user_info = cc.User.from_django_user(request.user).to_dict()

        with newrelic.agent.FunctionTrace(nr_transaction,
                                          "get_metadata_for_threads"):
            annotated_content_info = utils.get_metadata_for_threads(
                course_id, threads, request.user, user_info)
        if request.is_ajax():
            is_staff = cached_has_permission(request.user, 'openclose_thread',
                                             course.id)
            return utils.JsonResponse({
                'annotated_content_info':
                annotated_content_info,
                'discussion_data': [
                    utils.safe_content(thread, course_id, is_staff)
                    for thread in threads
                ],
                'page':
                query_params['page'],
                'num_pages':
                query_params['num_pages'],
            })
        else:

            context = {
                'course': course,
                'user': request.user,
                'django_user': User.objects.get(id=user_id),
                'profiled_user': profiled_user.to_dict(),
                'threads': _attr_safe_json(threads),
                'user_info': _attr_safe_json(user_info),
                'annotated_content_info':
                _attr_safe_json(annotated_content_info),
                #                'content': content,
            }

            return render_to_response('discussion/user_profile.html', context)
    except User.DoesNotExist:
        raise Http404
示例#54
0
def forum_form_discussion(request, course_id):
    """
    Renders the main Discussion page, potentially filtered by a search query
    """
    course_id = SlashSeparatedCourseKey.from_deprecated_string(course_id)
    nr_transaction = newrelic.agent.current_transaction()

    course = get_course_with_access(request.user, 'load_forum', course_id)
    course_settings = make_course_settings(course, include_category_map=True)

    try:
        unsafethreads, query_params = get_threads(request, course_id)   # This might process a search query
        is_staff = cached_has_permission(request.user, 'openclose_thread', course.id)
        threads = [utils.safe_content(thread, is_staff) for thread in unsafethreads]
    except cc.utils.CommentClientMaintenanceError:
        log.warning("Forum is in maintenance mode")
        return render_to_response('discussion/maintenance.html', {})

    user = cc.User.from_django_user(request.user)
    user_info = user.to_dict()

    with newrelic.agent.FunctionTrace(nr_transaction, "get_metadata_for_threads"):
        annotated_content_info = utils.get_metadata_for_threads(course_id, threads, request.user, user_info)

    with newrelic.agent.FunctionTrace(nr_transaction, "add_courseware_context"):
        add_courseware_context(threads, course)

    if request.is_ajax():
        return utils.JsonResponse({
            'discussion_data': threads,   # TODO: Standardize on 'discussion_data' vs 'threads'
            'annotated_content_info': annotated_content_info,
            'num_pages': query_params['num_pages'],
            'page': query_params['page'],
            'corrected_text': query_params['corrected_text'],
        })
    else:
        with newrelic.agent.FunctionTrace(nr_transaction, "get_cohort_info"):
            user_cohort_id = get_cohort_id(request.user, course_id)

        context = {
            'csrf': csrf(request)['csrf_token'],
            'course': course,
            #'recent_active_threads': recent_active_threads,
            'staff_access': has_access(request.user, 'staff', course),
            'threads': _attr_safe_json(threads),
            'thread_pages': query_params['num_pages'],
            'user_info': _attr_safe_json(user_info),
            'flag_moderator': cached_has_permission(request.user, 'openclose_thread', course.id) or has_access(request.user, 'staff', course),
            'annotated_content_info': _attr_safe_json(annotated_content_info),
            'course_id': course.id.to_deprecated_string(),
            'roles': _attr_safe_json(utils.get_role_ids(course_id)),
            'is_moderator': cached_has_permission(request.user, "see_all_cohorts", course_id),
            'cohorts': course_settings["cohorts"],  # still needed to render _thread_list_template
            'user_cohort': user_cohort_id, # read from container in NewPostView
            'is_course_cohorted': is_course_cohorted(course_id),  # still needed to render _thread_list_template
            'sort_preference': user.default_sort_key,
            'category_map': course_settings["category_map"],
            'course_settings': _attr_safe_json(course_settings)
        }
        # print "start rendering.."
        return render_to_response('discussion/index.html', context)
示例#55
0
def mobi_forum_course_discussion(request, course_id):
    """
    mobile api
    get all discussions about the course
    """
    course_id = course_id.replace('.', '/')
    nr_transaction = newrelic.agent.current_transaction()

    course = get_course_with_access(request.user, course_id, 'load_forum')
    with newrelic.agent.FunctionTrace(nr_transaction,
                                      "get_discussion_category_map"):
        category_map = utils.get_discussion_category_map(course)

    try:
        unsafethreads, query_params = get_threads(
            request, course_id)  # This might process a search query
        threads = [utils.safe_content(thread) for thread in unsafethreads]
    except cc.utils.CommentClientMaintenanceError:
        return JsonResponse({'success': False, 'errmsg': 'errors occur!'})

    user = cc.User.from_django_user(request.user)
    user_info = user.to_dict()

    with newrelic.agent.FunctionTrace(nr_transaction,
                                      "add_courseware_context"):
        add_courseware_context(threads, course)

    page = request.GET.get('page') or 0

    num_pages = query_params['num_pages']
    threads_list = []

    if int(page) <= num_pages:
        for th in threads:

            def format_thread_info(thread_id):
                thread = cc.Thread.find(thread_id).to_dict()

                if thread:
                    return {
                        "id":
                        thread['id'],
                        "course_id":
                        thread['course_id'].replace('/', '.'),
                        "time":
                        dateutil.parser.parse(thread['created_at']).strftime(
                            "%Y-%m-%d %H:%M:%S"),
                        "name":
                        thread['title'],
                        "number":
                        len(thread['children'])
                    }
                else:
                    raise Exception

            try:
                threads_list.append(format_thread_info(th['id']))
            except:
                continue

    return JsonResponse({
        'course_threads': threads_list,
        "success": True,
        'page': page,
        'num_pages': num_pages
    })
示例#56
0
def mobi_disscussion_search(request, course_id):
    nr_transaction = newrelic.agent.current_transaction()

    course_id = course_id.replace('.', '/')
    try:
        course = get_course_with_access(request.user, course_id, 'load_forum')
    except:
        return JsonResponse({
            "success":
            False,
            "errmsg":
            "can not find a course with " + course_id.replace('/', '.') + " id"
        })

    with newrelic.agent.FunctionTrace(nr_transaction,
                                      "get_discussion_category_map"):
        category_map = utils.get_discussion_category_map(course)

    try:
        unsafethreads, query_params = get_threads(
            request, course_id)  # This might process a search query
        threads = [utils.safe_content(thread) for thread in unsafethreads]
    except cc.utils.CommentClientMaintenanceError:
        log.warning("Forum is in maintenance mode")
        # return render_to_response('discussion/maintenance.html', {})
        return JsonResponse({
            "success": False,
            "errmsg": "Forum is in maintenance mode"
        })

    user = cc.User.from_django_user(request.user)
    user_info = user.to_dict()

    with newrelic.agent.FunctionTrace(nr_transaction,
                                      "get_metadata_for_threads"):
        annotated_content_info = utils.get_metadata_for_threads(
            course_id, threads, request.user, user_info)

    with newrelic.agent.FunctionTrace(nr_transaction,
                                      "add_courseware_context"):
        add_courseware_context(threads, course)

    search_list = []

    page = request.GET.get('page') or 0
    num_pages = query_params['num_pages']
    if int(page) <= num_pages:
        for thread in threads:
            thread = cc.Thread.find(thread['id']).to_dict()
            thread_info = {}
            if thread:
                thread_info['id'] = thread['id']
                thread_info['course_id'] = thread['course_id'].replace(
                    '/', '.')
                thread_info['name'] = thread['title']
                thread_info['time'] = dateutil.parser.parse(
                    thread['created_at']).strftime("%Y-%m-%d %H:%M:%S")
                thread_info['number'] = len(thread['children'])

                search_list.append(thread_info)
            else:
                continue
    else:
        page = 0

    return JsonResponse({
        'count': len(search_list),
        'search_results': search_list,
        'success': True,
        'page': page,
        'num_pages': num_pages
    })
示例#57
0
def single_thread(request, course_id, discussion_id, thread_id):
    course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id)
    nr_transaction = newrelic.agent.current_transaction()

    course = get_course_with_access(request.user, 'load_forum', course_key)
    course_settings = make_course_settings(course, include_category_map=True)
    cc_user = cc.User.from_django_user(request.user)
    user_info = cc_user.to_dict()
    is_moderator = cached_has_permission(request.user, "see_all_cohorts",
                                         course_key)

    # Currently, the front end always loads responses via AJAX, even for this
    # page; it would be a nice optimization to avoid that extra round trip to
    # the comments service.
    try:
        thread = cc.Thread.find(thread_id).retrieve(
            recursive=request.is_ajax(),
            user_id=request.user.id,
            response_skip=request.GET.get("resp_skip"),
            response_limit=request.GET.get("resp_limit"))
    except cc.utils.CommentClientRequestError as e:
        if e.status_code == 404:
            raise Http404
        raise

    # verify that the thread belongs to the requesting student's cohort
    if is_commentable_cohorted(course_key, discussion_id) and not is_moderator:
        user_group_id = get_cohort_id(request.user, course_key)
        if hasattr(thread, "group_id") and user_group_id != thread.group_id:
            raise Http404

    is_staff = cached_has_permission(request.user, 'openclose_thread',
                                     course.id)
    if request.is_ajax():
        with newrelic.agent.FunctionTrace(nr_transaction,
                                          "get_annotated_content_infos"):
            annotated_content_info = utils.get_annotated_content_infos(
                course_key, thread, request.user, user_info=user_info)
        content = utils.safe_content(thread.to_dict(), course_key, is_staff)
        add_thread_group_name(content, course_key)
        with newrelic.agent.FunctionTrace(nr_transaction,
                                          "add_courseware_context"):
            add_courseware_context([content], course)
        return utils.JsonResponse({
            'content':
            content,
            'annotated_content_info':
            annotated_content_info,
        })

    else:
        try:
            threads, query_params = get_threads(request, course_key)
        except ValueError:
            return HttpResponseBadRequest("Invalid group_id")
        threads.append(thread.to_dict())

        with newrelic.agent.FunctionTrace(nr_transaction,
                                          "add_courseware_context"):
            add_courseware_context(threads, course)

        for thread in threads:
            add_thread_group_name(thread, course_key)

            #patch for backward compatibility with comments service
            if not "pinned" in thread:
                thread["pinned"] = False

        threads = [
            utils.safe_content(thread, course_key, is_staff)
            for thread in threads
        ]

        with newrelic.agent.FunctionTrace(nr_transaction,
                                          "get_metadata_for_threads"):
            annotated_content_info = utils.get_metadata_for_threads(
                course_key, threads, request.user, user_info)

        with newrelic.agent.FunctionTrace(nr_transaction, "get_cohort_info"):
            user_cohort = get_cohort_id(request.user, course_key)

        context = {
            'discussion_id':
            discussion_id,
            'csrf':
            csrf(request)['csrf_token'],
            'init':
            '',  # TODO: What is this?
            'user_info':
            _attr_safe_json(user_info),
            'annotated_content_info':
            _attr_safe_json(annotated_content_info),
            'course':
            course,
            #'recent_active_threads': recent_active_threads,
            'course_id':
            course.id.to_deprecated_string(
            ),  # TODO: Why pass both course and course.id to template?
            'thread_id':
            thread_id,
            'threads':
            _attr_safe_json(threads),
            'roles':
            _attr_safe_json(utils.get_role_ids(course_key)),
            'is_moderator':
            is_moderator,
            'thread_pages':
            query_params['num_pages'],
            'is_course_cohorted':
            is_course_cohorted(course_key),
            'flag_moderator':
            cached_has_permission(request.user, 'openclose_thread', course.id)
            or has_access(request.user, 'staff', course),
            'cohorts':
            course_settings["cohorts"],
            'user_cohort':
            user_cohort,
            'sort_preference':
            cc_user.default_sort_key,
            'category_map':
            course_settings["category_map"],
            'course_settings':
            _attr_safe_json(course_settings)
        }
        return render_to_response('discussion/index.html', context)
示例#58
0
def forum_form_discussion(request, course_id):
    """
    Renders the main Discussion page, potentially filtered by a search query
    """
    course = get_course_with_access(request.user, course_id, 'load')
    category_map = utils.get_discussion_category_map(course)

    try:
        unsafethreads, query_params = get_threads(
            request, course_id)  # This might process a search query
        threads = [utils.safe_content(thread) for thread in unsafethreads]
    except cc.utils.CommentClientMaintenanceError:
        log.warning("Forum is in maintenance mode")
        return render_to_response('discussion/maintenance.html', {})
    except (cc.utils.CommentClientError,
            cc.utils.CommentClientUnknownError) as err:
        log.error("Error loading forum discussion threads: %s", str(err))
        raise Http404

    user = cc.User.from_django_user(request.user)
    user_info = user.to_dict()

    annotated_content_info = utils.get_metadata_for_threads(
        course_id, threads, request.user, user_info)

    for thread in threads:
        courseware_context = get_courseware_context(thread, course)
        if courseware_context:
            thread.update(courseware_context)
    if request.is_ajax():
        return utils.JsonResponse({
            'discussion_data':
            threads,  # TODO: Standardize on 'discussion_data' vs 'threads'
            'annotated_content_info': annotated_content_info,
            'num_pages': query_params['num_pages'],
            'page': query_params['page'],
        })
    else:
        #recent_active_threads = cc.search_recent_active_threads(
        #    course_id,
        #    recursive=False,
        #    query_params={'follower_id': request.user.id},
        #)

        #trending_tags = cc.search_trending_tags(
        #    course_id,
        #)
        cohorts = get_course_cohorts(course_id)
        cohorted_commentables = get_cohorted_commentables(course_id)

        user_cohort_id = get_cohort_id(request.user, course_id)

        context = {
            'csrf':
            csrf(request)['csrf_token'],
            'course':
            course,
            #'recent_active_threads': recent_active_threads,
            #'trending_tags': trending_tags,
            'staff_access':
            has_access(request.user, course, 'staff'),
            '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,
            'roles':
            saxutils.escape(json.dumps(utils.get_role_ids(course_id)),
                            escapedict),
            'is_moderator':
            cached_has_permission(request.user, "see_all_cohorts", course_id),
            'cohorts':
            cohorts,
            'user_cohort':
            user_cohort_id,
            'cohorted_commentables':
            cohorted_commentables,
            'is_course_cohorted':
            is_course_cohorted(course_id)
        }
        # print "start rendering.."
        return render_to_response('discussion/index.html', context)
示例#59
0
def create_thread(request, course_id, commentable_id):
    """
    Given a course and commentble ID, create the thread
    """

    log.debug("Creating new thread in %r, id %r", course_id, commentable_id)
    course = get_course_with_access(request.user, course_id, 'load')
    post = request.POST

    if course.allow_anonymous:
        anonymous = post.get('anonymous', 'false').lower() == 'true'
    else:
        anonymous = False

    if course.allow_anonymous_to_peers:
        anonymous_to_peers = post.get('anonymous_to_peers',
                                      'false').lower() == 'true'
    else:
        anonymous_to_peers = False

    if 'title' not in post or not post['title'].strip():
        return JsonError(_("Title can't be empty"))
    if 'body' not in post or not post['body'].strip():
        return JsonError(_("Body can't be empty"))

    thread = cc.Thread(**extract(post, ['body', 'title']))
    thread.update_attributes(
        **{
            'anonymous': anonymous,
            'anonymous_to_peers': anonymous_to_peers,
            'commentable_id': commentable_id,
            'course_id': course_id,
            'user_id': request.user.id,
        })

    user = cc.User.from_django_user(request.user)

    #kevinchugh because the new requirement is that all groups will be determined
    #by the group id in the request this all goes away
    #not anymore, only for admins

    # Cohort the thread if the commentable is cohorted.
    if is_commentable_cohorted(course_id, commentable_id):
        user_group_id = get_cohort_id(user, course_id)

        # TODO (vshnayder): once we have more than just cohorts, we'll want to
        # change this to a single get_group_for_user_and_commentable function
        # that can do different things depending on the commentable_id
        if cached_has_permission(request.user, "see_all_cohorts", course_id):
            # admins can optionally choose what group to post as
            group_id = post.get('group_id', user_group_id)
        else:
            # regular users always post with their own id.
            group_id = user_group_id

        if group_id:
            thread.update_attributes(group_id=group_id)

    thread.save()

    #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)
    data = thread.to_dict()
    add_courseware_context([data], course)
    if request.is_ajax():
        return ajax_content_response(request, course_id, data)
    else:
        return JsonResponse(utils.safe_content(data))
示例#60
0
def single_thread(request, course_id, discussion_id, thread_id):
    nr_transaction = newrelic.agent.current_transaction()

    course = get_course_with_access(request.user, course_id, 'load_forum')
    cc_user = cc.User.from_django_user(request.user)
    user_info = cc_user.to_dict()

    thread = cc.Thread.find(thread_id).retrieve(recursive=True,
                                                user_id=request.user.id)

    if request.is_ajax():
        with newrelic.agent.FunctionTrace(nr_transaction,
                                          "get_annotated_content_infos"):
            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())
        with newrelic.agent.FunctionTrace(nr_transaction,
                                          "add_courseware_context"):
            add_courseware_context([content], course)
        return utils.JsonResponse({
            #'html': html,
            'content':
            content,
            'annotated_content_info':
            annotated_content_info,
        })

    else:
        with newrelic.agent.FunctionTrace(nr_transaction,
                                          "get_discussion_category_map"):
            category_map = utils.get_discussion_category_map(course)

        threads, query_params = get_threads(request, course_id)
        threads.append(thread.to_dict())

        course = get_course_with_access(request.user, course_id, 'load_forum')

        with newrelic.agent.FunctionTrace(nr_transaction,
                                          "add_courseware_context"):
            add_courseware_context(threads, course)

        for thread in threads:
            if thread.get('group_id') and not thread.get('group_name'):
                thread['group_name'] = get_cohort_by_id(
                    course_id, thread.get('group_id')).name

            #patch for backward compatibility with comments service
            if not "pinned" in thread:
                thread["pinned"] = False

        threads = [utils.safe_content(thread) for thread in threads]

        #recent_active_threads = cc.search_recent_active_threads(
        #    course_id,
        #    recursive=False,
        #    query_params={'follower_id': request.user.id},
        #)

        #trending_tags = cc.search_trending_tags(
        #    course_id,
        #)

        with newrelic.agent.FunctionTrace(nr_transaction,
                                          "get_metadata_for_threads"):
            annotated_content_info = utils.get_metadata_for_threads(
                course_id, threads, request.user, user_info)

        with newrelic.agent.FunctionTrace(nr_transaction, "get_cohort_info"):
            cohorts = get_course_cohorts(course_id)
            cohorted_commentables = get_cohorted_commentables(course_id)
            user_cohort = get_cohort_id(request.user, course_id)

        context = {
            'discussion_id':
            discussion_id,
            'csrf':
            csrf(request)['csrf_token'],
            'init':
            '',  # TODO: What is this?
            'user_info':
            saxutils.escape(json.dumps(user_info), escapedict),
            'annotated_content_info':
            saxutils.escape(json.dumps(annotated_content_info), escapedict),
            'course':
            course,
            #'recent_active_threads': recent_active_threads,
            #'trending_tags': trending_tags,
            'course_id':
            course.id,  # TODO: Why pass both course and course.id to template?
            'thread_id':
            thread_id,
            'threads':
            saxutils.escape(json.dumps(threads), escapedict),
            'category_map':
            category_map,
            'roles':
            saxutils.escape(json.dumps(utils.get_role_ids(course_id)),
                            escapedict),
            '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
        }

        return render_to_response('discussion/single_thread.html', context)