def thread_merge_endpoint(request, thread, viewmodel): allow_merge_thread(request.user, thread) serializer = MergeThreadSerializer( data=request.data, context={ 'request': request, 'thread': thread, 'viewmodel': viewmodel, }, ) if not serializer.is_valid(): if 'other_thread' in serializer.errors: errors = serializer.errors['other_thread'] elif 'poll' in serializer.errors: errors = serializer.errors['poll'] else: errors = list(serializer.errors.values())[0] return Response({'detail': errors[0]}, status=400) # interrupt merge with request for poll resolution? if serializer.validated_data.get('polls'): return Response({'polls': serializer.validated_data['polls']}, status=400) # merge polls other_thread = serializer.validated_data['other_thread'] poll = serializer.validated_data.get('poll') if len(serializer.polls_handler.polls) == 1: poll.move(other_thread) elif serializer.polls_handler.is_merge_conflict(): if poll and poll.thread_id != other_thread.id: other_thread.poll.delete() poll.move(other_thread) elif not poll: other_thread.poll.delete() # merge thread contents moderation.merge_thread(request, other_thread, thread) other_thread.synchronize() other_thread.save() other_thread.category.synchronize() other_thread.category.save() if thread.category != other_thread.category: thread.category.synchronize() thread.category.save() return Response({ 'id': other_thread.pk, 'title': other_thread.title, 'url': other_thread.get_absolute_url(), })
def thread_merge_endpoint(request, thread, viewmodel): allow_merge_thread(request.user, thread) serializer = MergeThreadSerializer( data=request.data, context={ 'request': request, 'thread': thread, 'viewmodel': viewmodel, }, ) serializer.is_valid(raise_exception=True) # merge conflict other_thread = serializer.validated_data['other_thread'] best_answer = serializer.validated_data.get('best_answer') if 'best_answer' in serializer.merge_conflict and not best_answer: other_thread.clear_best_answer() if best_answer and best_answer != other_thread: other_thread.best_answer_id = thread.best_answer_id other_thread.best_answer_is_protected = thread.best_answer_is_protected other_thread.best_answer_marked_on = thread.best_answer_marked_on other_thread.best_answer_marked_by_id = thread.best_answer_marked_by_id other_thread.best_answer_marked_by_name = thread.best_answer_marked_by_name other_thread.best_answer_marked_by_slug = thread.best_answer_marked_by_slug poll = serializer.validated_data.get('poll') if 'poll' in serializer.merge_conflict: if poll and poll.thread_id != other_thread.id: other_thread.poll.delete() poll.move(other_thread) elif not poll: other_thread.poll.delete() elif poll: poll.move(other_thread) # merge thread contents moderation.merge_thread(request, other_thread, thread) other_thread.synchronize() other_thread.save() other_thread.category.synchronize() other_thread.category.save() if thread.category != other_thread.category: thread.category.synchronize() thread.category.save() return Response({ 'id': other_thread.pk, 'title': other_thread.title, 'url': other_thread.get_absolute_url(), })
def test_thread_merged_event_renders(self): """merged thread event renders""" other_thread = testutils.post_thread(category=self.category) threads_moderation.merge_thread(MockRequest(self.user), self.thread, other_thread) event = self.thread.post_set.filter(is_event=True)[0] self.assertEqual(event.event_type, 'merged') # event renders response = self.client.get(self.thread.get_absolute_url()) self.assertContains(response, event.get_absolute_url()) self.assertContains(response, "thread has been merged into this thread")
def thread_merge_endpoint(request, thread, viewmodel): allow_merge_thread(request.user, thread) serializer = MergeThreadSerializer( data=request.data, context={ 'request': request, 'thread': thread, 'viewmodel': viewmodel, }, ) serializer.is_valid(raise_exception=True) # merge polls other_thread = serializer.validated_data['other_thread'] poll = serializer.validated_data['poll'] if poll: if hasattr(other_thread, 'poll') and poll != other_thread.poll: other_thread.poll.delete() poll.move(other_thread) else: if hasattr(thread, 'poll'): thread.poll.delete() if hasattr(other_thread, 'poll'): other_thread.poll.delete() # merge thread contents moderation.merge_thread(request, other_thread, thread) other_thread.synchronize() other_thread.save() other_thread.category.synchronize() other_thread.category.save() if thread.category != other_thread.category: thread.category.synchronize() thread.category.save() return Response({ 'id': other_thread.pk, 'title': other_thread.title, 'url': other_thread.get_absolute_url(), })
def thread_merge_endpoint(request, thread, viewmodel): if not thread.acl['can_merge']: raise PermissionDenied( _("You don't have permission to merge this thread with others.")) other_thread_id = get_thread_id_from_url( request, request.data.get('thread_url', None)) if not other_thread_id: return Response({'detail': _("This is not a valid thread link.")}, status=400) if other_thread_id == thread.pk: return Response({'detail': _("You can't merge thread with itself.")}, status=400) try: other_thread = viewmodel(request, other_thread_id, select_for_update=True).unwrap() if not can_reply_thread(request.user, other_thread): raise PermissionDenied( _("You can't merge this thread into thread you can't reply.")) if not other_thread.acl['can_merge']: raise PermissionDenied( _("You don't have permission to merge this thread with current one." )) except PermissionDenied as e: return Response({'detail': e.args[0]}, status=400) except Http404: return Response( { 'detail': _("The thread you have entered link to doesn't exist or you don't have permission to see it." ) }, status=400) polls_handler = PollMergeHandler([thread, other_thread]) if len(polls_handler.polls) == 1: poll = polls_handler.polls[0] poll.move(other_thread) elif polls_handler.is_merge_conflict(): if 'poll' in request.data: polls_handler.set_resolution(request.data.get('poll')) if polls_handler.is_valid(): poll = polls_handler.get_resolution() if poll and poll.thread_id != other_thread.id: other_thread.poll.delete() poll.move(other_thread) elif not poll: other_thread.poll.delete() else: return Response({'detail': _("Invalid choice.")}, status=400) else: return Response( {'polls': polls_handler.get_available_resolutions()}, status=400) moderation.merge_thread(request, other_thread, thread) other_thread.synchronize() other_thread.save() other_thread.category.synchronize() other_thread.category.save() if thread.category != other_thread.category: thread.category.synchronize() thread.category.save() return Response({ 'id': other_thread.pk, 'title': other_thread.title, 'url': other_thread.get_absolute_url() })
def thread_merge_endpoint(request, thread, viewmodel): allow_merge_thread(request.user, thread) other_thread_id = get_thread_id_from_url(request, request.data.get('thread_url', None)) if not other_thread_id: return Response({'detail': _("This is not a valid thread link.")}, status=400) if other_thread_id == thread.pk: return Response({'detail': _("You can't merge thread with itself.")}, status=400) try: other_thread = viewmodel(request, other_thread_id).unwrap() allow_merge_thread(request.user, other_thread, otherthread=True) if not can_reply_thread(request.user, other_thread): raise PermissionDenied(_("You can't merge this thread into thread you can't reply.")) except PermissionDenied as e: return Response({'detail': e.args[0]}, status=400) except Http404: return Response( { 'detail': _( "The thread you have entered link to doesn't " "exist or you don't have permission to see it." ) }, status=400, ) polls_handler = PollMergeHandler([thread, other_thread]) if len(polls_handler.polls) == 1: poll = polls_handler.polls[0] poll.move(other_thread) elif polls_handler.is_merge_conflict(): if 'poll' in request.data: polls_handler.set_resolution(request.data.get('poll')) if polls_handler.is_valid(): poll = polls_handler.get_resolution() if poll and poll.thread_id != other_thread.id: other_thread.poll.delete() poll.move(other_thread) elif not poll: other_thread.poll.delete() else: return Response({'detail': _("Invalid choice.")}, status=400) else: return Response({'polls': polls_handler.get_available_resolutions()}, status=400) moderation.merge_thread(request, other_thread, thread) other_thread.synchronize() other_thread.save() other_thread.category.synchronize() other_thread.category.save() if thread.category != other_thread.category: thread.category.synchronize() thread.category.save() return Response({ 'id': other_thread.pk, 'title': other_thread.title, 'url': other_thread.get_absolute_url(), })