posting.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. from django.core.urlresolvers import reverse
  2. from django.shortcuts import redirect
  3. from django.template import RequestContext
  4. from django.utils import timezone
  5. from django.utils.translation import ugettext as _
  6. from misago.acl.utils import ACLError403, ACLError404
  7. from misago.forms import FormLayout
  8. from misago.forums.models import Forum
  9. from misago.markdown import post_markdown
  10. from misago.messages import Message
  11. from misago.threads.forms import PostForm
  12. from misago.threads.models import Thread, Post
  13. from misago.threads.views.base import BaseView
  14. from misago.views import error403, error404
  15. from misago.utils import make_pagination, slugify
  16. class PostingView(BaseView):
  17. def fetch_target(self, kwargs):
  18. if self.mode == 'new_thread':
  19. self.fetch_forum(kwargs)
  20. if self.mode in ('edit_thread', 'new_post', 'new_post_quick'):
  21. self.fetch_thread(kwargs)
  22. def fetch_forum(self, kwargs):
  23. self.forum = Forum.objects.get(pk=kwargs['forum'], type='forum')
  24. self.request.acl.forums.allow_forum_view(self.forum)
  25. self.request.acl.threads.allow_new_threads(self.forum)
  26. self.parents = self.forum.get_ancestors(include_self=True).filter(level__gt=1)
  27. def fetch_thread(self, kwargs):
  28. self.thread = Thread.objects.get(pk=kwargs['thread'])
  29. self.forum = self.thread.forum
  30. self.request.acl.forums.allow_forum_view(self.forum)
  31. self.request.acl.threads.allow_thread_view(self.request.user, self.thread)
  32. self.request.acl.threads.allow_reply(self.thread)
  33. self.parents = self.forum.get_ancestors(include_self=True).filter(level__gt=1)
  34. def get_form(self, bound=False):
  35. if bound:
  36. return PostForm(self.request.POST,request=self.request,mode=self.mode)
  37. return PostForm(request=self.request,mode=self.mode)
  38. def __call__(self, request, **kwargs):
  39. self.request = request
  40. self.forum = None
  41. self.thread = None
  42. self.post = None
  43. self.parents = None
  44. self.mode = kwargs.get('mode')
  45. if self.request.POST.get('quick_reply') and self.mode == 'new_post':
  46. self.mode = 'new_post_quick'
  47. try:
  48. self.fetch_target(kwargs)
  49. if not request.user.is_authenticated():
  50. raise ACLError403(_("Guest, you have to sign-in to post."))
  51. except (Forum.DoesNotExist, Thread.DoesNotExist, Post.DoesNotExist):
  52. return error404(self.request)
  53. except ACLError403 as e:
  54. return error403(request, e.message)
  55. except ACLError404 as e:
  56. return error404(request, e.message)
  57. message = request.messages.get_message('threads')
  58. if request.method == 'POST':
  59. form = self.get_form(True)
  60. if form.is_valid():
  61. now = timezone.now()
  62. moderation = False
  63. if not request.acl.threads.acl[self.forum.pk]['can_approve']:
  64. if self.mode == 'new_thread' and request.acl.threads.acl[self.forum.pk]['can_start_threads'] == 1:
  65. moderation = True
  66. if self.mode in ['new_post', 'new_post_quick'] and request.acl.threads.acl[self.forum.pk]['can_write_posts'] == 1:
  67. moderation = True
  68. # Get or create new thread
  69. if self.mode in ['new_thread']:
  70. thread = Thread.objects.create(
  71. forum=self.forum,
  72. name=form.cleaned_data['thread_name'],
  73. slug=slugify(form.cleaned_data['thread_name']),
  74. start=now,
  75. last=now,
  76. moderated=moderation,
  77. )
  78. if moderation:
  79. thread.replies_moderated += 1
  80. else:
  81. thread = self.thread
  82. # Create new message
  83. post = Post.objects.create(
  84. forum=self.forum,
  85. thread=thread,
  86. merge=thread.merges,
  87. user=request.user,
  88. user_name=request.user.username,
  89. ip=request.session.get_ip(request),
  90. agent=request.META.get('HTTP_USER_AGENT'),
  91. post=form.cleaned_data['post'],
  92. post_preparsed=post_markdown(request, form.cleaned_data['post']),
  93. date=now,
  94. moderated=moderation,
  95. )
  96. if self.mode == 'new_thread':
  97. thread.start_post = post
  98. thread.start_poster = request.user
  99. thread.start_poster_name = request.user.username
  100. thread.start_poster_slug = request.user.username_slug
  101. if request.user.rank and request.user.rank.style:
  102. thread.start_poster_style = request.user.rank.style
  103. if not moderation:
  104. thread.last = now
  105. thread.last_post = post
  106. thread.last_poster = request.user
  107. thread.last_poster_name = request.user.username
  108. thread.last_poster_slug = request.user.username_slug
  109. if request.user.rank and request.user.rank.style:
  110. thread.last_poster_style = request.user.rank.style
  111. if self.mode in ['new_post', 'new_post_quick']:
  112. if moderation:
  113. thread.replies_moderated += 1
  114. else:
  115. thread.replies += 1
  116. thread.score += 5
  117. if (self.request.settings.thread_length > 0
  118. and not thread.closed
  119. and thread.replies >= self.request.settings.thread_length):
  120. thread.closed = True
  121. post.set_checkpoint(self.request, 'limit')
  122. thread.save(force_update=True)
  123. # Update forum and monitor
  124. if not moderation:
  125. if self.mode == 'new_thread':
  126. self.request.monitor['threads'] = int(self.request.monitor['threads']) + 1
  127. self.forum.threads += 1
  128. self.forum.threads_delta += 1
  129. if self.mode in ['new_thread', 'new_post', 'new_post_quick']:
  130. self.request.monitor['posts'] = int(self.request.monitor['posts']) + 1
  131. self.forum.posts += 1
  132. self.forum.posts_delta += 1
  133. self.forum.last_thread = thread
  134. self.forum.last_thread_name = thread.name
  135. self.forum.last_thread_slug = thread.slug
  136. self.forum.last_thread_date = thread.last
  137. self.forum.last_poster = thread.last_poster
  138. self.forum.last_poster_name = thread.last_poster_name
  139. self.forum.last_poster_slug = thread.last_poster_slug
  140. self.forum.last_poster_style = thread.last_poster_style
  141. self.forum.save(force_update=True)
  142. # Update user
  143. if not moderation:
  144. if self.mode == 'new_thread':
  145. request.user.threads += 1
  146. request.user.posts += 1
  147. request.user.last_post = thread.last
  148. request.user.save(force_update=True)
  149. if self.mode == 'new_thread':
  150. if moderation:
  151. request.messages.set_flash(Message(_("New thread has been posted. It will be hidden from other members until moderator reviews it.")), 'success', 'threads')
  152. else:
  153. request.messages.set_flash(Message(_("New thread has been posted.")), 'success', 'threads')
  154. return redirect(reverse('thread', kwargs={'thread': thread.pk, 'slug': thread.slug}) + ('#post-%s' % post.pk))
  155. if self.mode in ['new_post', 'new_post_quick']:
  156. if moderation:
  157. request.messages.set_flash(Message(_("Your reply has been posted. It will be hidden from other members until moderator reviews it.")), 'success', 'threads_%s' % post.pk)
  158. else:
  159. request.messages.set_flash(Message(_("Your reply has been posted.")), 'success', 'threads_%s' % post.pk)
  160. pagination = make_pagination(0, self.request.acl.threads.filter_posts(self.request, self.thread, self.thread.post_set).count(), self.request.settings.posts_per_page)
  161. if pagination['total'] > 1:
  162. return redirect(reverse('thread', kwargs={'thread': self.thread.pk, 'slug': self.thread.slug, 'page': pagination['total']}) + ('#post-%s' % post.pk))
  163. return redirect(reverse('thread', kwargs={'thread': self.thread.pk, 'slug': self.thread.slug}) + ('#post-%s' % post.pk))
  164. message = Message(form.non_field_errors()[0], 'error')
  165. else:
  166. form = self.get_form()
  167. return request.theme.render_to_response('threads/posting.html',
  168. {
  169. 'mode': self.mode,
  170. 'forum': self.forum,
  171. 'thread': self.thread,
  172. 'post': self.post,
  173. 'parents': self.parents,
  174. 'message': message,
  175. 'form': FormLayout(form),
  176. },
  177. context_instance=RequestContext(request));