Exemple #1
0
def create_thread(request, thread_data):
    """
    Create a thread.

    Arguments:

        request: The django request object used for build_absolute_uri and
          determining the requesting user.

        thread_data: The data for the created thread.

    Returns:

        The created thread; see discussion.rest_api.views.ThreadViewSet for more
        detail.
    """
    course_id = thread_data.get("course_id")
    user = request.user
    if not course_id:
        raise ValidationError({"course_id": ["This field is required."]})
    try:
        course_key = CourseKey.from_string(course_id)
        course = _get_course(course_key, user)
    except InvalidKeyError:
        raise ValidationError({"course_id": ["Invalid value."]})  # lint-amnesty, pylint: disable=raise-missing-from

    if not discussion_open_for_user(course, user):
        raise DiscussionBlackOutException

    context = get_context(course, request)
    _check_initializable_thread_fields(thread_data, context)
    discussion_settings = get_course_discussion_settings(course_key)
    if ("group_id" not in thread_data and is_commentable_divided(
            course_key, thread_data.get("topic_id"), discussion_settings)):
        thread_data = thread_data.copy()
        thread_data["group_id"] = get_group_id_for_user(
            user, discussion_settings)
    serializer = ThreadSerializer(data=thread_data, context=context)
    actions_form = ThreadActionsForm(thread_data)
    if not (serializer.is_valid() and actions_form.is_valid()):
        raise ValidationError(
            dict(
                list(serializer.errors.items()) +
                list(actions_form.errors.items())))
    serializer.save()
    cc_thread = serializer.instance
    thread_created.send(sender=None, user=user, post=cc_thread)
    api_thread = serializer.data
    _do_extra_actions(api_thread, cc_thread, list(thread_data.keys()),
                      actions_form, context, request)

    track_thread_created_event(request, course, cc_thread,
                               actions_form.cleaned_data["following"])

    return api_thread
Exemple #2
0
 def save_and_reserialize(self, data, instance=None):
     """
     Create a serializer with the given data and (if updating) instance,
     ensure that it is valid, save the result, and return the full thread
     data from the serializer.
     """
     serializer = ThreadSerializer(instance,
                                   data=data,
                                   partial=(instance is not None),
                                   context=get_context(
                                       self.course, self.request))
     assert serializer.is_valid()
     serializer.save()
     return serializer.data
Exemple #3
0
 def save_and_reserialize(self, data, instance=None):
     """
     Create a serializer with the given data and (if updating) instance,
     ensure that it is valid, save the result, and return the full thread
     data from the serializer.
     """
     serializer = ThreadSerializer(
         instance,
         data=data,
         partial=(instance is not None),
         context=get_context(self.course, self.request)
     )
     self.assertTrue(serializer.is_valid())
     serializer.save()
     return serializer.data
Exemple #4
0
def create_thread(request, thread_data):
    """
    Create a thread.

    Arguments:

        request: The django request object used for build_absolute_uri and
          determining the requesting user.

        thread_data: The data for the created thread.

    Returns:

        The created thread; see discussion.rest_api.views.ThreadViewSet for more
        detail.
    """
    course_id = thread_data.get("course_id")
    user = request.user
    if not course_id:
        raise ValidationError({"course_id": ["This field is required."]})
    try:
        course_key = CourseKey.from_string(course_id)
        course = _get_course(course_key, user)
    except InvalidKeyError:
        raise ValidationError({"course_id": ["Invalid value."]})

    context = get_context(course, request)
    _check_initializable_thread_fields(thread_data, context)
    discussion_settings = get_course_discussion_settings(course_key)
    if (
            "group_id" not in thread_data and
            is_commentable_divided(course_key, thread_data.get("topic_id"), discussion_settings)
    ):
        thread_data = thread_data.copy()
        thread_data["group_id"] = get_group_id_for_user(user, discussion_settings)
    serializer = ThreadSerializer(data=thread_data, context=context)
    actions_form = ThreadActionsForm(thread_data)
    if not (serializer.is_valid() and actions_form.is_valid()):
        raise ValidationError(dict(serializer.errors.items() + actions_form.errors.items()))
    serializer.save()
    cc_thread = serializer.instance
    thread_created.send(sender=None, user=user, post=cc_thread)
    api_thread = serializer.data
    _do_extra_actions(api_thread, cc_thread, thread_data.keys(), actions_form, context, request)

    track_thread_created_event(request, course, cc_thread, actions_form.cleaned_data["following"])

    return api_thread
Exemple #5
0
def update_thread(request, thread_id, update_data):
    """
    Update a thread.

    Arguments:

        request: The django request object used for build_absolute_uri and
          determining the requesting user.

        thread_id: The id for the thread to update.

        update_data: The data to update in the thread.

    Returns:

        The updated thread; see discussion.rest_api.views.ThreadViewSet for more
        detail.
    """
    cc_thread, context = _get_thread_and_context(
        request, thread_id, retrieve_kwargs={"with_responses": True})
    _check_editable_fields(cc_thread, update_data, context)
    serializer = ThreadSerializer(cc_thread,
                                  data=update_data,
                                  partial=True,
                                  context=context)
    actions_form = ThreadActionsForm(update_data)
    if not (serializer.is_valid() and actions_form.is_valid()):
        raise ValidationError(
            dict(
                list(serializer.errors.items()) +
                list(actions_form.errors.items())))
    # Only save thread object if some of the edited fields are in the thread data, not extra actions
    if set(update_data) - set(actions_form.fields):
        serializer.save()
        # signal to update Teams when a user edits a thread
        thread_edited.send(sender=None, user=request.user, post=cc_thread)
    api_thread = serializer.data
    _do_extra_actions(api_thread, cc_thread, list(update_data.keys()),
                      actions_form, context, request)

    # always return read as True (and therefore unread_comment_count=0) as reasonably
    # accurate shortcut, rather than adding additional processing.
    api_thread['read'] = True
    api_thread['unread_comment_count'] = 0
    return api_thread
Exemple #6
0
def update_thread(request, thread_id, update_data):
    """
    Update a thread.

    Arguments:

        request: The django request object used for build_absolute_uri and
          determining the requesting user.

        thread_id: The id for the thread to update.

        update_data: The data to update in the thread.

    Returns:

        The updated thread; see discussion.rest_api.views.ThreadViewSet for more
        detail.
    """
    cc_thread, context = _get_thread_and_context(request, thread_id, retrieve_kwargs={"with_responses": True})
    _check_editable_fields(cc_thread, update_data, context)
    serializer = ThreadSerializer(cc_thread, data=update_data, partial=True, context=context)
    actions_form = ThreadActionsForm(update_data)
    if not (serializer.is_valid() and actions_form.is_valid()):
        raise ValidationError(dict(serializer.errors.items() + actions_form.errors.items()))
    # Only save thread object if some of the edited fields are in the thread data, not extra actions
    if set(update_data) - set(actions_form.fields):
        serializer.save()
        # signal to update Teams when a user edits a thread
        thread_edited.send(sender=None, user=request.user, post=cc_thread)
    api_thread = serializer.data
    _do_extra_actions(api_thread, cc_thread, update_data.keys(), actions_form, context, request)

    # always return read as True (and therefore unread_comment_count=0) as reasonably
    # accurate shortcut, rather than adding additional processing.
    api_thread['read'] = True
    api_thread['unread_comment_count'] = 0
    return api_thread