posting.py 4.3 KB

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