posting.py 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  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. user=request.user,
  87. user_name=request.user.username,
  88. ip=request.session.get_ip(request),
  89. agent=request.META.get('HTTP_USER_AGENT'),
  90. post=form.cleaned_data['post'],
  91. post_preparsed=post_markdown(request, form.cleaned_data['post']),
  92. date=now,
  93. moderated=moderation,
  94. )
  95. if self.mode == 'new_thread':
  96. thread.start_post = post
  97. thread.start_poster = request.user
  98. thread.start_poster_name = request.user.username
  99. thread.start_poster_slug = request.user.username_slug
  100. if request.user.rank and request.user.rank.style:
  101. thread.start_poster_style = request.user.rank.style
  102. thread.last = now
  103. thread.last_post = post
  104. thread.last_poster = request.user
  105. thread.last_poster_name = request.user.username
  106. thread.last_poster_slug = request.user.username_slug
  107. if request.user.rank and request.user.rank.style:
  108. thread.last_poster_style = request.user.rank.style
  109. if self.mode in ['new_post', 'new_post_quick']:
  110. if moderation:
  111. thread.replies_moderated += 1
  112. else:
  113. thread.replies += 1
  114. thread.score += 5
  115. thread.save(force_update=True)
  116. # Update forum and monitor
  117. if not moderation:
  118. if self.mode == 'new_thread':
  119. self.request.monitor['threads'] = int(self.request.monitor['threads']) + 1
  120. self.forum.threads += 1
  121. self.forum.threads_delta += 1
  122. if self.mode in ['new_thread', 'new_post', 'new_post_quick']:
  123. self.request.monitor['posts'] = int(self.request.monitor['posts']) + 1
  124. self.forum.posts += 1
  125. self.forum.posts_delta += 1
  126. self.forum.last_thread = thread
  127. self.forum.last_thread_name = thread.name
  128. self.forum.last_thread_slug = thread.slug
  129. self.forum.last_thread_date = thread.last
  130. self.forum.last_poster = thread.last_poster
  131. self.forum.last_poster_name = thread.last_poster_name
  132. self.forum.last_poster_slug = thread.last_poster_slug
  133. self.forum.last_poster_style = thread.last_poster_style
  134. self.forum.save(force_update=True)
  135. # Update user
  136. if not moderation:
  137. if self.mode == 'new_thread':
  138. request.user.threads += 1
  139. request.user.posts += 1
  140. request.user.last_post = thread.last
  141. request.user.save(force_update=True)
  142. if self.mode == 'new_thread':
  143. if moderation:
  144. request.messages.set_flash(Message(_("New thread has been posted. It will be hidden from other members until moderator reviews it.")), 'success', 'threads')
  145. else:
  146. request.messages.set_flash(Message(_("New thread has been posted.")), 'success', 'threads')
  147. return redirect(reverse('thread', kwargs={'thread': thread.pk, 'slug': thread.slug}) + ('#post-%s' % post.pk))
  148. if self.mode in ['new_post', 'new_post_quick']:
  149. if moderation:
  150. 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)
  151. else:
  152. request.messages.set_flash(Message(_("Your reply has been posted.")), 'success', 'threads_%s' % post.pk)
  153. 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)
  154. if pagination['total'] > 1:
  155. return redirect(reverse('thread', kwargs={'thread': self.thread.pk, 'slug': self.thread.slug, 'page': pagination['total']}) + ('#post-%s' % post.pk))
  156. return redirect(reverse('thread', kwargs={'thread': self.thread.pk, 'slug': self.thread.slug}) + ('#post-%s' % post.pk))
  157. message = Message(form.non_field_errors()[0], 'error')
  158. else:
  159. form = self.get_form()
  160. return request.theme.render_to_response('threads/posting.html',
  161. {
  162. 'mode': self.mode,
  163. 'forum': self.forum,
  164. 'thread': self.thread,
  165. 'post': self.post,
  166. 'parents': self.parents,
  167. 'message': message,
  168. 'form': FormLayout(form),
  169. },
  170. context_instance=RequestContext(request));