posting.py 10 KB

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