Files
edx-platform/lms/djangoapps/discussion_api/views.py
2015-05-21 11:35:39 -04:00

220 lines
7.3 KiB
Python

"""
Discussion API views
"""
from django.core.exceptions import ValidationError
from rest_framework.authentication import OAuth2Authentication, SessionAuthentication
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.viewsets import ViewSet
from opaque_keys.edx.locator import CourseLocator
from discussion_api.api import get_comment_list, get_course_topics, get_thread_list
from discussion_api.forms import CommentListGetForm, ThreadListGetForm
from openedx.core.lib.api.view_utils import DeveloperErrorViewMixin
class _ViewMixin(object):
"""
Mixin to provide common characteristics and utility functions for Discussion
API views
"""
authentication_classes = (OAuth2Authentication, SessionAuthentication)
permission_classes = (IsAuthenticated,)
class CourseTopicsView(_ViewMixin, DeveloperErrorViewMixin, APIView):
"""
**Use Cases**
Retrieve the topic listing for a course. Only topics accessible to the
authenticated user are included.
**Example Requests**:
GET /api/discussion/v1/course_topics/{course_id}
**Response Values**:
* courseware_topics: The list of topic trees for courseware-linked
topics. Each item in the list includes:
* id: The id of the discussion topic (null for a topic that only
has children but cannot contain threads itself).
* name: The display name of the topic.
* children: A list of child subtrees of the same format.
* non_courseware_topics: The list of topic trees that are not linked to
courseware. Items are of the same format as in courseware_topics.
"""
def get(self, request, course_id):
"""Implements the GET method as described in the class docstring."""
course_key = CourseLocator.from_string(course_id)
return Response(get_course_topics(course_key, request.user))
class ThreadViewSet(_ViewMixin, DeveloperErrorViewMixin, ViewSet):
"""
**Use Cases**
Retrieve the list of threads for a course.
**Example Requests**:
GET /api/discussion/v1/threads/?course_id=ExampleX/Demo/2015
**GET Parameters**:
* course_id (required): The course to retrieve threads for
* page: The (1-indexed) page to retrieve (default is 1)
* page_size: The number of items per page (default is 10, max is 100)
**Response Values**:
* results: The list of threads. Each item in the list includes:
* id: The id of the thread
* course_id: The id of the thread's course
* topic_id: The id of the thread's topic
* created_at: The ISO 8601 timestamp for the creation of the thread
* updated_at: The ISO 8601 timestamp for the last modification of
the thread, which may not have been an update of the title/body
* type: The thread's type (either "question" or "discussion")
* title: The thread's title
* raw_body: The thread's raw body text without any rendering applied
* pinned: Boolean indicating whether the thread has been pinned
* closed: Boolean indicating whether the thread has been closed
* comment_count: The number of comments within the thread
* unread_comment_count: The number of comments within the thread
that were created or updated since the last time the user read
the thread
* next: The URL of the next page (or null if first page)
* previous: The URL of the previous page (or null if last page)
"""
def list(self, request):
"""
Implements the GET method for the list endpoint as described in the
class docstring.
"""
form = ThreadListGetForm(request.GET)
if not form.is_valid():
raise ValidationError(form.errors)
return Response(
get_thread_list(
request,
form.cleaned_data["course_id"],
form.cleaned_data["page"],
form.cleaned_data["page_size"]
)
)
class CommentViewSet(_ViewMixin, DeveloperErrorViewMixin, ViewSet):
"""
**Use Cases**
Retrieve the list of comments in a thread.
**Example Requests**:
GET /api/discussion/v1/comments/?thread_id=0123456789abcdef01234567
**GET Parameters**:
* thread_id (required): The thread to retrieve comments for
* endorsed: If specified, only retrieve the endorsed or non-endorsed
comments accordingly. Required for a question thread, must be absent
for a discussion thread.
* page: The (1-indexed) page to retrieve (default is 1)
* page_size: The number of items per page (default is 10, max is 100)
**Response Values**:
* results: The list of comments. Each item in the list includes:
* id: The id of the comment
* thread_id: The id of the comment's thread
* parent_id: The id of the comment's parent
* author: The username of the comment's author, or None if the
comment is anonymous
* author_label: A label indicating whether the author has a special
role in the course, either "staff" for moderators and
administrators or "community_ta" for community TAs
* created_at: The ISO 8601 timestamp for the creation of the comment
* updated_at: The ISO 8601 timestamp for the last modification of
the comment, which may not have been an update of the body
* raw_body: The comment's raw body text without any rendering applied
* endorsed: Boolean indicating whether the comment has been endorsed
(by a privileged user or, for a question thread, the thread
author)
* endorsed_by: The username of the endorsing user, if available
* endorsed_by_label: A label indicating whether the endorsing user
has a special role in the course (see author_label)
* endorsed_at: The ISO 8601 timestamp for the endorsement, if
available
* abuse_flagged: Boolean indicating whether the requesting user has
flagged the comment for abuse
* voted: Boolean indicating whether the requesting user has voted
for the comment
* vote_count: The number of votes for the comment
* children: The list of child comments (with the same format)
* next: The URL of the next page (or null if first page)
* previous: The URL of the previous page (or null if last page)
"""
def list(self, request):
"""
Implements the GET method for the list endpoint as described in the
class docstring.
"""
form = CommentListGetForm(request.GET)
if not form.is_valid():
raise ValidationError(form.errors)
return Response(
get_comment_list(
request,
form.cleaned_data["thread_id"],
form.cleaned_data["endorsed"],
form.cleaned_data["page"],
form.cleaned_data["page_size"]
)
)