Files
edx-platform/lms/djangoapps/discussion_api/api.py
Greg Price 90f28dce31 Add thread list endpoint to the new discussion API
This is an initial implementation that only allows retrieval of all
threads for a course and only returns an easily computed subset of the
fields that are needed, in order to keep this change from getting too
large.

JIRA: MA-641
2015-05-05 11:45:09 -04:00

129 lines
3.7 KiB
Python

"""
Discussion API internal interface
"""
from django.http import Http404
from collections import defaultdict
from lms.lib.comment_client.thread import Thread
from discussion_api.pagination import get_paginated_data
from django_comment_client.utils import get_accessible_discussion_modules
def get_course_topics(course, user):
"""
Return the course topic listing for the given course and user.
Parameters:
course: 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
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,
}
def _cc_thread_to_api_thread(thread):
"""
Convert a thread data dict from the comment_client format (which is a direct
representation of the format returned by the comments service) to the format
used in this API
"""
ret = {
key: thread[key]
for key in [
"id",
"course_id",
"created_at",
"updated_at",
"type",
"title",
"pinned",
"closed",
]
}
ret.update({
"topic_id": thread["commentable_id"],
"raw_body": thread["body"],
"comment_count": thread["comments_count"],
"unread_comment_count": thread["unread_comments_count"],
})
return ret
def get_thread_list(request, course_key, page, page_size):
"""
Return the list of all discussion threads pertaining to the given course
Parameters:
request: The django request objects used for build_absolute_uri
course_key: The key of the course to get discussion threads for
page: The page number (1-indexed) to retrieve
page_size: The number of threads to retrieve per page
Returns:
A paginated result containing a list of threads; see
discussion_api.views.ThreadViewSet for more detail.
"""
threads, result_page, num_pages, _ = Thread.search({
"course_id": unicode(course_key),
"page": page,
"per_page": page_size
})
# The comments service returns the last page of results if the requested
# page is beyond the last page, but we want be consistent with DRF's general
# behavior and return a 404 in that case
if result_page != page:
raise Http404
results = [_cc_thread_to_api_thread(thread) for thread in threads]
return get_paginated_data(request, results, page, num_pages)