posting.py 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. from django.contrib import messages
  2. from django.db.transaction import atomic
  3. from django.http import JsonResponse
  4. from django.shortcuts import redirect, render
  5. from django.utils.translation import ugettext as _
  6. from django.views.generic import View
  7. from misago.core.exceptions import AjaxError
  8. from misago.forums.lists import get_forum_path
  9. from misago.threads import goto
  10. from misago.threads.posting import (PostingInterrupt, EditorFormset,
  11. START, REPLY, EDIT)
  12. from misago.threads.models import Thread, Post, Label
  13. from misago.threads.permissions import (allow_start_thread, allow_reply_thread,
  14. can_edit_post)
  15. from misago.threads.views.generic.base import ViewBase
  16. __all__ = ['PostingView']
  17. class PostingView(ViewBase):
  18. """
  19. Basic view for starting/replying/editing
  20. """
  21. template = 'misago/posting/formset.html'
  22. def find_mode(self, request, *args, **kwargs):
  23. """
  24. First step: guess from request what kind of view we are
  25. """
  26. is_submit = request.method == 'POST' and 'submit' in request.POST
  27. if is_submit:
  28. request.user.lock()
  29. forum = None
  30. thread = None
  31. post = None
  32. if 'post_id' in kwargs:
  33. post = self.get_post(request, lock=is_submit, **kwargs)
  34. forum = post.forum
  35. thread = post.thread
  36. elif 'thread_id' in kwargs:
  37. thread = self.get_thread(request, lock=is_submit, **kwargs)
  38. forum = thread.forum
  39. else:
  40. forum = self.get_forum(request, lock=is_submit, **kwargs)
  41. if thread:
  42. if post:
  43. mode = EDIT
  44. else:
  45. mode = REPLY
  46. else:
  47. mode = START
  48. thread = Thread(forum=forum)
  49. if not post:
  50. post = Post(forum=forum, thread=thread)
  51. return mode, forum, thread, post
  52. def allow_mode(self, user, mode, forum, thread, post):
  53. """
  54. Second step: check start/reply/edit permissions
  55. """
  56. if mode == START:
  57. self.allow_start(user, forum)
  58. if mode == REPLY:
  59. self.allow_reply(user, thread)
  60. if mode == EDIT:
  61. self.allow_edit(user, post)
  62. def allow_start(self, user, forum):
  63. allow_start_thread(user, forum)
  64. def allow_reply(self, user, thread):
  65. allow_reply_thread(user, thread)
  66. def allow_edit(self, user, post):
  67. can_edit_post(user, post)
  68. def dispatch(self, request, *args, **kwargs):
  69. if request.method == 'POST':
  70. with atomic():
  71. return self.real_dispatch(request, *args, **kwargs)
  72. else:
  73. return self.real_dispatch(request, *args, **kwargs)
  74. def real_dispatch(self, request, *args, **kwargs):
  75. mode_context = self.find_mode(request, *args, **kwargs)
  76. self.allow_mode(request.user, *mode_context)
  77. mode, forum, thread, post = mode_context
  78. if not request.is_ajax():
  79. response = render(request, 'misago/errorpages/wrong_way.html')
  80. response.status_code = 405
  81. return response
  82. forum.labels = Label.objects.get_forum_labels(forum)
  83. formset = EditorFormset(request=request,
  84. mode=mode,
  85. user=request.user,
  86. forum=forum,
  87. thread=thread,
  88. post=post)
  89. if request.method == 'POST':
  90. if 'submit' in request.POST:
  91. if formset.is_valid():
  92. try:
  93. formset.save()
  94. if mode == EDIT:
  95. message = _("Message was edited.")
  96. else:
  97. if mode == START:
  98. message = _("New thread was posted.")
  99. if mode == REPLY:
  100. message = _("Your reply was posted.")
  101. messages.success(request, message)
  102. return JsonResponse({
  103. 'message': message,
  104. 'post_url': goto.post(request.user, thread, post),
  105. 'parsed': post.parsed,
  106. 'original': post.original,
  107. 'title': thread.title,
  108. })
  109. except PostingInterrupt as e:
  110. return JsonResponse({'interrupt': e.message})
  111. else:
  112. return JsonResponse({'errors': formset.errors})
  113. if 'preview' in request.POST:
  114. formset.update()
  115. return JsonResponse({'preview': formset.post.parsed})
  116. return self.render(request, {
  117. 'mode': mode,
  118. 'formset': formset,
  119. 'forms': formset.get_forms_list(),
  120. 'main_forms': formset.get_main_forms(),
  121. 'supporting_forms': formset.get_supporting_forms(),
  122. 'forum': forum,
  123. 'path': get_forum_path(forum),
  124. 'thread': thread,
  125. 'post': post,
  126. 'api_url': request.path
  127. })