posting.py 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  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
  5. from django.utils import html
  6. from django.utils.translation import ugettext as _
  7. from django.views.generic import View
  8. from misago.categories.lists import get_category_path
  9. from misago.core.errorpages import not_allowed
  10. from misago.core.exceptions import AjaxError
  11. from misago.threads import goto
  12. from misago.threads.posting import (PostingInterrupt, EditorFormset,
  13. START, REPLY, EDIT)
  14. from misago.threads.models import Thread, Post, Label
  15. from misago.threads.permissions import (allow_start_thread, allow_reply_thread,
  16. allow_edit_post)
  17. from misago.threads.views.generic.base import ViewBase
  18. __all__ = ['PostingView']
  19. class PostingView(ViewBase):
  20. """
  21. Basic view for starting/replying/editing
  22. """
  23. template = 'misago/posting/formset.html'
  24. def find_mode(self, request, *args, **kwargs):
  25. """
  26. First step: guess from request what kind of view we are
  27. """
  28. is_submit = request.method == 'POST' and 'submit' in request.POST
  29. if is_submit:
  30. request.user.lock()
  31. category = None
  32. thread = None
  33. post = None
  34. if 'post_id' in kwargs:
  35. post = self.get_post(request, lock=is_submit, **kwargs)
  36. category = post.category
  37. thread = post.thread
  38. elif 'thread_id' in kwargs:
  39. thread = self.get_thread(request, lock=is_submit, **kwargs)
  40. category = thread.category
  41. else:
  42. category = self.get_category(request, lock=is_submit, **kwargs)
  43. if thread:
  44. if post:
  45. mode = EDIT
  46. else:
  47. mode = REPLY
  48. else:
  49. mode = START
  50. thread = Thread(category=category)
  51. if not post:
  52. post = Post(category=category, thread=thread)
  53. return mode, category, thread, post
  54. def allow_mode(self, user, mode, category, thread, post):
  55. """
  56. Second step: check start/reply/edit permissions
  57. """
  58. if mode == START:
  59. self.allow_start(user, category)
  60. if mode == REPLY:
  61. self.allow_reply(user, thread)
  62. if mode == EDIT:
  63. self.allow_edit(user, post)
  64. def allow_start(self, user, category):
  65. allow_start_thread(user, category)
  66. def allow_reply(self, user, thread):
  67. allow_reply_thread(user, thread)
  68. def allow_edit(self, user, post):
  69. allow_edit_post(user, post)
  70. def dispatch(self, request, *args, **kwargs):
  71. if not request.is_ajax():
  72. return not_allowed(request)
  73. if request.method == 'POST':
  74. with atomic():
  75. return self.real_dispatch(request, *args, **kwargs)
  76. else:
  77. return self.real_dispatch(request, *args, **kwargs)
  78. def real_dispatch(self, request, *args, **kwargs):
  79. mode_context = self.find_mode(request, *args, **kwargs)
  80. self.allow_mode(request.user, *mode_context)
  81. mode, category, thread, post = mode_context
  82. category.labels = Label.objects.get_category_labels(category)
  83. formset = EditorFormset(request=request,
  84. mode=mode,
  85. user=request.user,
  86. category=category,
  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. return self.handle_submit(request, formset)
  95. except PostingInterrupt as e:
  96. return JsonResponse({'interrupt': e.message})
  97. else:
  98. return JsonResponse({'errors': formset.errors})
  99. if 'preview' in request.POST:
  100. formset.update()
  101. return JsonResponse({'preview': formset.post.parsed})
  102. return self.render(request, {
  103. 'mode': mode,
  104. 'formset': formset,
  105. 'forms': formset.get_forms_list(),
  106. 'main_forms': formset.get_main_forms(),
  107. 'supporting_forms': formset.get_supporting_forms(),
  108. 'category': category,
  109. 'path': get_category_path(category),
  110. 'thread': thread,
  111. 'post': post,
  112. 'api_url': request.path
  113. })
  114. def handle_submit(self, request, formset):
  115. mode, category, thread, post = (formset.mode, formset.category,
  116. formset.thread, formset.post)
  117. if mode == EDIT:
  118. message = _("Changes saved.")
  119. else:
  120. if mode == START:
  121. message = _("New thread was posted.")
  122. if mode == REPLY:
  123. message = _("Your reply was posted.")
  124. messages.success(request, message)
  125. posts_qs = self.exclude_invisible_posts(thread.post_set,
  126. request.user,
  127. category,
  128. thread)
  129. post_url = goto.post(thread, posts_qs, post)
  130. return JsonResponse({
  131. 'message': message,
  132. 'post_url': post_url,
  133. 'parsed': post.parsed,
  134. 'original': post.original,
  135. 'title': thread.title,
  136. 'title_escaped': html.escape(thread.title),
  137. })