Esempio n. 1
0
def single_thread(request, course_key, discussion_id, thread_id):
    """
    Renders a response to display a single discussion thread.  This could either be a page refresh
    after navigating to a single thread, a direct link to a single thread, or an AJAX call from the
    discussions UI loading the responses/comments for a single thread.

    Depending on the HTTP headers, we'll adjust our response accordingly.
    """
    course = get_course_with_access(request.user,
                                    'load',
                                    course_key,
                                    check_if_enrolled=True)
    request.user.is_community_ta = utils.is_user_community_ta(
        request.user, course.id)

    if request.is_ajax():
        cc_user = cc.User.from_django_user(request.user)
        user_info = cc_user.to_dict()
        is_staff = has_permission(request.user, 'openclose_thread', course.id)

        try:
            _check_team_discussion_access(request, course, discussion_id)
        except TeamDiscussionHiddenFromUserException:
            return HttpResponseForbidden(TEAM_PERMISSION_MESSAGE)

        thread = _load_thread_for_viewing(
            request,
            course,
            discussion_id=discussion_id,
            thread_id=thread_id,
            raise_event=True,
        )

        with function_trace("get_annotated_content_infos"):
            annotated_content_info = utils.get_annotated_content_infos(
                course_key, thread, request.user, user_info=user_info)

        content = utils.prepare_content(thread.to_dict(), course_key, is_staff,
                                        request.user.is_community_ta)
        with function_trace("add_courseware_context"):
            add_courseware_context([content], course, request.user)

        return utils.JsonResponse({
            'content':
            content,
            'annotated_content_info':
            annotated_content_info,
        })
    else:
        course_id = str(course.id)
        tab_view = CourseTabView()
        return tab_view.get(request,
                            course_id,
                            'discussion',
                            discussion_id=discussion_id,
                            thread_id=thread_id)
Esempio n. 2
0
def forum_form_discussion(request, course_key):
    """
    Renders the main Discussion page, potentially filtered by a search query
    """
    course = get_course_with_access(request.user,
                                    'load',
                                    course_key,
                                    check_if_enrolled=True)
    request.user.is_community_ta = utils.is_user_community_ta(
        request.user, course.id)
    if request.is_ajax():
        user = cc.User.from_django_user(request.user)
        user_info = user.to_dict()

        try:
            unsafethreads, query_params = get_threads(
                request, course,
                user_info)  # This might process a search query
            is_staff = has_permission(request.user, 'openclose_thread',
                                      course.id)
            threads = [
                utils.prepare_content(thread, course_key, is_staff,
                                      request.user.is_community_ta)
                for thread in unsafethreads
            ]
        except cc.utils.CommentClientMaintenanceError:
            return HttpResponseServerError(
                'Forum is in maintenance mode',
                status=status.HTTP_503_SERVICE_UNAVAILABLE)
        except ValueError:
            return HttpResponseServerError("Invalid group_id")

        with function_trace("get_metadata_for_threads"):
            annotated_content_info = utils.get_metadata_for_threads(
                course_key, threads, request.user, user_info)

        with function_trace("add_courseware_context"):
            add_courseware_context(threads, course, request.user)

        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:
        course_id = str(course.id)
        tab_view = CourseTabView()
        return tab_view.get(request, course_id, 'discussion')
Esempio n. 3
0
def single_thread(request, course_key, discussion_id, thread_id):
    """
    Renders a response to display a single discussion thread.  This could either be a page refresh
    after navigating to a single thread, a direct link to a single thread, or an AJAX call from the
    discussions UI loading the responses/comments for a single thread.

    Depending on the HTTP headers, we'll adjust our response accordingly.
    """
    course = get_course_with_access(request.user, 'load', course_key, check_if_enrolled=True)
    request.user.is_community_ta = utils.is_user_community_ta(request.user, course.id)
    if request.is_ajax():
        cc_user = cc.User.from_django_user(request.user)
        user_info = cc_user.to_dict()
        is_staff = has_permission(request.user, 'openclose_thread', course.id)
        thread = _load_thread_for_viewing(
            request,
            course,
            discussion_id=discussion_id,
            thread_id=thread_id,
            raise_event=True,
        )

        with function_trace("get_annotated_content_infos"):
            annotated_content_info = utils.get_annotated_content_infos(
                course_key,
                thread,
                request.user,
                user_info=user_info
            )

        content = utils.prepare_content(thread.to_dict(), course_key, is_staff)
        with function_trace("add_courseware_context"):
            add_courseware_context([content], course, request.user)

        return utils.JsonResponse({
            'content': content,
            'annotated_content_info': annotated_content_info,
        })
    else:
        course_id = unicode(course.id)
        tab_view = CourseTabView()
        return tab_view.get(request, course_id, 'discussion', discussion_id=discussion_id, thread_id=thread_id)
Esempio n. 4
0
def forum_form_discussion(request, course_key):
    """
    Renders the main Discussion page, potentially filtered by a search query
    """
    course = get_course_with_access(request.user, 'load', course_key, check_if_enrolled=True)
    request.user.is_community_ta = utils.is_user_community_ta(request.user, course.id)
    if request.is_ajax():
        user = cc.User.from_django_user(request.user)
        user_info = user.to_dict()

        try:
            unsafethreads, query_params = get_threads(request, course, user_info)  # This might process a search query
            is_staff = has_permission(request.user, 'openclose_thread', course.id)
            threads = [utils.prepare_content(thread, course_key, is_staff) for thread in unsafethreads]
        except cc.utils.CommentClientMaintenanceError:
            return HttpResponseServerError('Forum is in maintenance mode', status=status.HTTP_503_SERVICE_UNAVAILABLE)
        except ValueError:
            return HttpResponseServerError("Invalid group_id")

        with function_trace("get_metadata_for_threads"):
            annotated_content_info = utils.get_metadata_for_threads(course_key, threads, request.user, user_info)

        with function_trace("add_courseware_context"):
            add_courseware_context(threads, course, request.user)

        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:
        course_id = unicode(course.id)
        tab_view = CourseTabView()
        return tab_view.get(request, course_id, 'discussion')
Esempio n. 5
0
def followed_threads(request, course_key, user_id):
    """
    Ajax-only endpoint retrieving the threads followed by a specific user.
    """
    course = get_course_with_access(request.user,
                                    'load',
                                    course_key,
                                    check_if_enrolled=True)
    try:
        profiled_user = cc.User(id=user_id, course_id=course_key)

        query_params = {
            'page': 1,
            'per_page':
            THREADS_PER_PAGE,  # more than threads_per_page to show more activities
            'sort_key': 'date',
        }
        query_params.update(
            strip_none(
                extract(request.GET, [
                    'page',
                    'sort_key',
                    'flagged',
                    'unread',
                    'unanswered',
                ])))

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

        paginated_results = profiled_user.subscribed_threads(query_params)
        print("\n \n \n paginated results \n \n \n ")
        print(paginated_results)
        query_params['page'] = paginated_results.page
        query_params['num_pages'] = paginated_results.num_pages
        user_info = cc.User.from_django_user(request.user).to_dict()

        with function_trace("get_metadata_for_threads"):
            annotated_content_info = utils.get_metadata_for_threads(
                course_key, paginated_results.collection, request.user,
                user_info)
        if request.is_ajax():
            is_staff = has_permission(request.user, 'openclose_thread',
                                      course.id)
            is_community_ta = utils.is_user_community_ta(
                request.user, course.id)
            return utils.JsonResponse({
                'annotated_content_info':
                annotated_content_info,
                'discussion_data': [
                    utils.prepare_content(thread, course_key, is_staff,
                                          is_community_ta)
                    for thread in paginated_results.collection
                ],
                'page':
                query_params['page'],
                'num_pages':
                query_params['num_pages'],
            })
        #TODO remove non-AJAX support, it does not appear to be used and does not appear to work.
        else:
            context = {
                'course': course,
                'user': request.user,
                'django_user': User.objects.get(id=user_id),
                'profiled_user': profiled_user.to_dict(),
                'threads': paginated_results.collection,
                'user_info': user_info,
                'annotated_content_info': annotated_content_info,
                #                'content': content,
            }

            return render(request, 'discussion/user_profile.html', context)
    except User.DoesNotExist:
        raise Http404  # lint-amnesty, pylint: disable=raise-missing-from
Esempio n. 6
0
def create_user_profile_context(request, course_key, user_id):
    """ Generate a context dictionary for the user profile. """
    user = cc.User.from_django_user(request.user)
    course = get_course_with_access(request.user,
                                    'load',
                                    course_key,
                                    check_if_enrolled=True)

    # If user is not enrolled in the course, do not proceed.
    django_user = User.objects.get(id=user_id)
    if not CourseEnrollment.is_enrolled(django_user, course.id):
        raise Http404

    query_params = {
        'page': request.GET.get('page', 1),
        'per_page':
        THREADS_PER_PAGE,  # more than threads_per_page to show more activities
    }

    group_id = get_group_id_for_comments_service(request, course_key)
    if group_id is not None:
        query_params['group_id'] = group_id
        profiled_user = cc.User(id=user_id,
                                course_id=course_key,
                                group_id=group_id)
    else:
        profiled_user = cc.User(id=user_id, course_id=course_key)

    threads, page, num_pages = profiled_user.active_threads(query_params)
    query_params['page'] = page
    query_params['num_pages'] = num_pages

    with function_trace("get_metadata_for_threads"):
        user_info = cc.User.from_django_user(request.user).to_dict()
        annotated_content_info = utils.get_metadata_for_threads(
            course_key, threads, request.user, user_info)

    is_staff = has_permission(request.user, 'openclose_thread', course.id)
    is_community_ta = utils.is_user_community_ta(request.user, course.id)
    threads = [
        utils.prepare_content(thread, course_key, is_staff, is_community_ta)
        for thread in threads
    ]
    with function_trace("add_courseware_context"):
        add_courseware_context(threads, course, request.user)

        # TODO: LEARNER-3854: If we actually implement Learner Analytics code, this
        #   code was original protected to not run in user_profile() if is_ajax().
        #   Someone should determine if that is still necessary (i.e. was that ever
        #   called as is_ajax()) and clean this up as necessary.
        user_roles = django_user.roles.filter(
            course_id=course.id).order_by("name").values_list(
                "name", flat=True).distinct()

        with function_trace("get_cohort_info"):
            course_discussion_settings = CourseDiscussionSettings.get(
                course_key)
            user_group_id = get_group_id_for_user(request.user,
                                                  course_discussion_settings)

        context = _create_base_discussion_view_context(request, course_key)
        context.update({
            'django_user':
            django_user,
            'django_user_roles':
            user_roles,
            'profiled_user':
            profiled_user.to_dict(),
            'threads':
            threads,
            'user_group_id':
            user_group_id,
            'annotated_content_info':
            annotated_content_info,
            'page':
            query_params['page'],
            'num_pages':
            query_params['num_pages'],
            'sort_preference':
            user.default_sort_key,
            'learner_profile_page_url':
            reverse('learner_profile',
                    kwargs={'username': django_user.username}),
        })
        return context
Esempio n. 7
0
def _create_discussion_board_context(request, base_context, thread=None):
    """
    Returns the template context for rendering the discussion board.
    """
    context = base_context.copy()
    course = context['course']
    course_key = course.id
    thread_id = thread.id if thread else None
    discussion_id = thread.commentable_id if thread else None
    course_settings = context['course_settings']
    user = context['user']
    cc_user = cc.User.from_django_user(user)
    user_info = context['user_info']
    if thread:
        _check_team_discussion_access(request, course, discussion_id)
        # Since we're in page render mode, and the discussions UI will request the thread list itself,
        # we need only return the thread information for this one.
        threads = [thread.to_dict()]

        for thread in threads:  # lint-amnesty, pylint: disable=redefined-argument-from-local
            # patch for backward compatibility with comments service
            if "pinned" not in thread:
                thread["pinned"] = False
        thread_pages = 1
        root_url = reverse('forum_form_discussion', args=[str(course.id)])
    else:
        threads, query_params = get_threads(
            request, course, user_info)  # This might process a search query
        thread_pages = query_params['num_pages']
        root_url = request.path
    is_staff = has_permission(user, 'openclose_thread', course.id)
    is_community_ta = utils.is_user_community_ta(request.user, course.id)
    threads = [
        utils.prepare_content(thread, course_key, is_staff, is_community_ta)
        for thread in threads
    ]

    with function_trace("get_metadata_for_threads"):
        annotated_content_info = utils.get_metadata_for_threads(
            course_key, threads, user, user_info)

    with function_trace("add_courseware_context"):
        add_courseware_context(threads, course, user)

    with function_trace("get_cohort_info"):
        course_discussion_settings = CourseDiscussionSettings.get(course_key)
        user_group_id = get_group_id_for_user(user, course_discussion_settings)

    context.update({
        'root_url':
        root_url,
        'discussion_id':
        discussion_id,
        'thread_id':
        thread_id,
        'threads':
        threads,
        'thread_pages':
        thread_pages,
        'annotated_content_info':
        annotated_content_info,
        'is_moderator':
        has_permission(user, "see_all_cohorts", course_key),
        'groups':
        course_settings[
            "groups"],  # still needed to render _thread_list_template
        'user_group_id':
        user_group_id,  # read from container in NewPostView
        'sort_preference':
        cc_user.default_sort_key,
        'category_map':
        course_settings["category_map"],
        'course_settings':
        course_settings,
        'is_commentable_divided':
        is_commentable_divided(course_key, discussion_id,
                               course_discussion_settings),
        # If the default topic id is None the front-end code will look for a topic that contains "General"
        'discussion_default_topic_id':
        _get_discussion_default_topic_id(course),
        'enable_daily_digest':
        is_forum_daily_digest_enabled()
    })
    context.update(get_experiment_user_metadata_context(
        course,
        user,
    ))
    return context
Esempio n. 8
0
def inline_discussion(request, course_key, discussion_id):
    """
    Renders JSON for DiscussionModules
    """
    with function_trace('get_course_and_user_info'):
        course = get_course_with_access(request.user,
                                        'load',
                                        course_key,
                                        check_if_enrolled=True)
        cc_user = cc.User.from_django_user(request.user)
        user_info = cc_user.to_dict()

    try:
        with function_trace('get_threads'):
            threads, query_params = get_threads(
                request,
                course,
                user_info,
                discussion_id,
                per_page=INLINE_THREADS_PER_PAGE)
    except ValueError:
        return HttpResponseServerError('Invalid group_id')
    except TeamDiscussionHiddenFromUserException:
        return HttpResponseForbidden(TEAM_PERMISSION_MESSAGE)

    with function_trace('get_metadata_for_threads'):
        annotated_content_info = utils.get_metadata_for_threads(
            course_key, threads, request.user, user_info)

    with function_trace('determine_group_permissions'):
        is_staff = has_permission(request.user, 'openclose_thread', course.id)
        is_community_ta = utils.is_user_community_ta(request.user, course.id)
        course_discussion_settings = CourseDiscussionSettings.get(course.id)
        group_names_by_id = get_group_names_by_id(course_discussion_settings)
        course_is_divided = course_discussion_settings.division_scheme is not CourseDiscussionSettings.NONE

    with function_trace('prepare_content'):
        threads = [
            utils.prepare_content(thread, course_key, is_staff,
                                  is_community_ta, course_is_divided,
                                  group_names_by_id) for thread in threads
        ]

    return utils.JsonResponse({
        'is_commentable_divided':
        is_commentable_divided(course_key, discussion_id),
        'discussion_data':
        threads,
        'user_info':
        user_info,
        'user_group_id':
        get_group_id_for_user(request.user, course_discussion_settings),
        'annotated_content_info':
        annotated_content_info,
        'page':
        query_params['page'],
        'num_pages':
        query_params['num_pages'],
        'roles':
        utils.get_role_ids(course_key),
        'course_settings':
        make_course_settings(course, request.user, False)
    })