예제 #1
0
def get_courseware_topics(request, course_key, course, topic_ids):
    """
    Returns a list of topic trees for courseware-linked topics.

    Parameters:

        request: The django request objects used for build_absolute_uri.
        course_key: The key of the course to get discussion threads for.
        course: The course for which topics are requested.
        topic_ids: A list of topic IDs for which details are requested.
            This is optional. If None then all course topics are returned.

    Returns:
        A list of courseware topics and a set of existing topics among
        topic_ids.

    """
    courseware_topics = []
    existing_topic_ids = set()

    def get_module_sort_key(module):
        """
        Get the sort key for the module (falling back to the discussion_target
        setting if absent)
        """
        return module.sort_key or module.discussion_target

    def get_sorted_modules(category):
        """Returns key sorted modules by category"""
        return sorted(modules_by_category[category], key=get_module_sort_key)

    discussion_modules = get_accessible_discussion_modules(course, request.user)
    modules_by_category = defaultdict(list)
    for module in discussion_modules:
        modules_by_category[module.discussion_category].append(module)

    for category in sorted(modules_by_category.keys()):
        children = []
        for module in get_sorted_modules(category):
            if not topic_ids or module.discussion_id in topic_ids:
                discussion_topic = DiscussionTopic(
                    module.discussion_id,
                    module.discussion_target,
                    get_thread_list_url(request, course_key, [module.discussion_id]),
                )
                children.append(discussion_topic)

                if topic_ids and module.discussion_id in topic_ids:
                    existing_topic_ids.add(module.discussion_id)

        if not topic_ids or children:
            discussion_topic = DiscussionTopic(
                None,
                category,
                get_thread_list_url(request, course_key, [item.discussion_id for item in get_sorted_modules(category)]),
                children,
            )
            courseware_topics.append(DiscussionTopicSerializer(discussion_topic).data)

    return courseware_topics, existing_topic_ids
예제 #2
0
def get_course_topics(course_key, user):
    """
    Return the course topic listing for the given course and user.

    Parameters:

    course_key: The key of the course to get topics for
    user: The requesting user, for access control

    Returns:

    A course topic listing dictionary; see discussion_api.views.CourseTopicViews
    for more detail.
    """
    def get_module_sort_key(module):
        """
        Get the sort key for the module (falling back to the discussion_target
        setting if absent)
        """
        return module.sort_key or module.discussion_target

    course = _get_course_or_404(course_key, user)
    discussion_modules = get_accessible_discussion_modules(course, user)
    modules_by_category = defaultdict(list)
    for module in discussion_modules:
        modules_by_category[module.discussion_category].append(module)
    courseware_topics = [
        {
            "id": None,
            "name": category,
            "children": [
                {
                    "id": module.discussion_id,
                    "name": module.discussion_target,
                    "children": [],
                }
                for module in sorted(modules_by_category[category], key=get_module_sort_key)
            ],
        }
        for category in sorted(modules_by_category.keys())
    ]

    non_courseware_topics = [
        {
            "id": entry["id"],
            "name": name,
            "children": [],
        }
        for name, entry in sorted(
            course.discussion_topics.items(),
            key=lambda item: item[1].get("sort_key", item[0])
        )
    ]

    return {
        "courseware_topics": courseware_topics,
        "non_courseware_topics": non_courseware_topics,
    }
예제 #3
0
def get_course_topics(course_key, user):
    """
    Return the course topic listing for the given course and user.

    Parameters:

    course_key: The key of the course to get topics for
    user: The requesting user, for access control

    Returns:

    A course topic listing dictionary; see discussion_api.views.CourseTopicViews
    for more detail.
    """
    def get_module_sort_key(module):
        """
        Get the sort key for the module (falling back to the discussion_target
        setting if absent)
        """
        return module.sort_key or module.discussion_target

    course = _get_course_or_404(course_key, user)
    discussion_modules = get_accessible_discussion_modules(course, user)
    modules_by_category = defaultdict(list)
    for module in discussion_modules:
        modules_by_category[module.discussion_category].append(module)
    courseware_topics = [
        {
            "id": None,
            "name": category,
            "children": [
                {
                    "id": module.discussion_id,
                    "name": module.discussion_target,
                    "children": [],
                }
                for module in sorted(modules_by_category[category], key=get_module_sort_key)
            ],
        }
        for category in sorted(modules_by_category.keys())
    ]

    non_courseware_topics = [
        {
            "id": entry["id"],
            "name": name,
            "children": [],
        }
        for name, entry in sorted(
            course.discussion_topics.items(),
            key=lambda item: item[1].get("sort_key", item[0])
        )
    ]

    return {
        "courseware_topics": courseware_topics,
        "non_courseware_topics": non_courseware_topics,
    }
예제 #4
0
def get_courseware_topics(request, course_key, course, topic_ids):
    """
    Returns a list of topic trees for courseware-linked topics.

    Parameters:

        request: The django request objects used for build_absolute_uri.
        course_key: The key of the course to get discussion threads for.
        course: The course for which topics are requested.
        topic_ids: A list of topic IDs for which details are requested.
            This is optional. If None then all course topics are returned.

    Returns:
        A list of courseware topics and a set of existing topics among
        topic_ids.

    """
    courseware_topics = []
    existing_topic_ids = set()

    def get_module_sort_key(module):
        """
        Get the sort key for the module (falling back to the discussion_target
        setting if absent)
        """
        return module.sort_key or module.discussion_target

    def get_sorted_modules(category):
        """Returns key sorted modules by category"""
        return sorted(modules_by_category[category], key=get_module_sort_key)

    discussion_modules = get_accessible_discussion_modules(
        course, request.user)
    modules_by_category = defaultdict(list)
    for module in discussion_modules:
        modules_by_category[module.discussion_category].append(module)

    for category in sorted(modules_by_category.keys()):
        children = []
        for module in get_sorted_modules(category):
            if not topic_ids or module.discussion_id in topic_ids:
                discussion_topic = DiscussionTopic(
                    module.discussion_id,
                    module.discussion_target,
                    get_thread_list_url(request, course_key,
                                        [module.discussion_id]),
                )
                children.append(discussion_topic)

                if topic_ids and module.discussion_id in topic_ids:
                    existing_topic_ids.add(module.discussion_id)

        if not topic_ids or children:
            discussion_topic = DiscussionTopic(
                None,
                category,
                get_thread_list_url(request, course_key, [
                    item.discussion_id for item in get_sorted_modules(category)
                ]),
                children,
            )
            courseware_topics.append(
                DiscussionTopicSerializer(discussion_topic).data)

    return courseware_topics, existing_topic_ids
예제 #5
0
파일: views.py 프로젝트: ataki/edx-platform
def single_thread(request, course_key, discussion_id, thread_id):
    """
    Renders a response to display a single discussion thread.
    """
    nr_transaction = newrelic.agent.current_transaction()

    course = get_course_with_access(request.user, 'load_forum', course_key)
    course_settings = make_course_settings(course, request.user)
    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)

    # Verify that the student has access to this thread if belongs to a discussion module
    accessible_discussion_ids = [
        module.discussion_id
        for module in utils.get_accessible_discussion_modules(
            course, request.user)
    ]
    if discussion_id not in set(course.top_level_discussion_topic_ids +
                                accessible_discussion_ids):
        raise Http404

    # 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 getattr(thread, "group_id",
                   None) is not None 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.prepare_content(thread.to_dict(), course_key, is_staff)
        with newrelic.agent.FunctionTrace(nr_transaction,
                                          "add_courseware_context"):
            add_courseware_context([content], course, request.user)
        return utils.JsonResponse({
            'content':
            content,
            'annotated_content_info':
            annotated_content_info,
        })

    else:
        try:
            threads, query_params = get_threads(request, course)
        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, request.user)

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

        threads = [
            utils.prepare_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)