posting.py 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  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 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_reply(self.thread)
  32. self.parents = self.forum.get_ancestors(include_self=True).filter(level__gt=1)
  33. def get_form(self, bound=False):
  34. if bound:
  35. return PostForm(self.request.POST,request=self.request,mode=self.mode)
  36. return PostForm(request=self.request,mode=self.mode)
  37. def __call__(self, request, **kwargs):
  38. self.request = request
  39. self.forum = None
  40. self.thread = None
  41. self.post = None
  42. self.parents = None
  43. self.mode = kwargs.get('mode')
  44. if self.request.POST.get('quick_reply') and self.mode == 'new_post':
  45. self.mode = 'new_post_quick'
  46. try:
  47. self.fetch_target(kwargs)
  48. if not request.user.is_authenticated():
  49. raise ACLError403(_("Guest, you have to sign-in to post."))
  50. except (Forum.DoesNotExist, Thread.DoesNotExist, Post.DoesNotExist):
  51. return error404(self.request)
  52. except ACLError403 as e:
  53. return error403(request, e.message)
  54. except ACLError404 as e:
  55. return error404(request, e.message)
  56. message = request.messages.get_message('threads')
  57. if request.method == 'POST':
  58. form = self.get_form(True)
  59. if form.is_valid():
  60. now = timezone.now()
  61. # Get or create new thread
  62. if self.mode in ['new_thread', 'edit_thread']:
  63. thread = Thread.objects.create(
  64. forum=self.forum,
  65. name=form.cleaned_data['thread_name'],
  66. slug=slugify(form.cleaned_data['thread_name']),
  67. start=now,
  68. last=now,
  69. )
  70. else:
  71. thread = self.thread
  72. # Create new message
  73. post = Post.objects.create(
  74. forum=self.forum,
  75. thread=thread,
  76. user=request.user,
  77. user_name=request.user.username,
  78. ip=request.session.get_ip(request),
  79. agent=request.META.get('HTTP_USER_AGENT'),
  80. post=form.cleaned_data['post'],
  81. post_preparsed=post_markdown(request, form.cleaned_data['post']),
  82. date=now
  83. )
  84. if self.mode == 'new_thread':
  85. thread.start_post = post
  86. thread.start_poster = request.user
  87. thread.start_poster_name = request.user.username
  88. thread.start_poster_slug = request.user.username_slug
  89. if request.user.rank and request.user.rank.style:
  90. thread.start_poster_style = request.user.rank.style
  91. thread.last = now
  92. thread.last_post = post
  93. thread.last_poster = request.user
  94. thread.last_poster_name = request.user.username
  95. thread.last_poster_slug = request.user.username_slug
  96. if request.user.rank and request.user.rank.style:
  97. thread.last_poster_style = request.user.rank.style
  98. if self.mode in ['new_post', 'new_post_quick']:
  99. thread.replies += 1
  100. thread.save(force_update=True)
  101. # Update forum
  102. if self.mode == 'new_thread':
  103. self.forum.threads += 1
  104. self.forum.threads_delta += 1
  105. if self.mode in ['new_post', 'new_post_quick']:
  106. self.forum.posts += 1
  107. self.forum.posts_delta += 1
  108. self.forum.last_thread = thread
  109. self.forum.last_thread_name = thread.name
  110. self.forum.last_thread_slug = thread.slug
  111. self.forum.last_thread_date = thread.last
  112. self.forum.last_poster = thread.last_poster
  113. self.forum.last_poster_name = thread.last_poster_name
  114. self.forum.last_poster_slug = thread.last_poster_slug
  115. self.forum.last_poster_style = thread.last_poster_style
  116. self.forum.save(force_update=True)
  117. # Update user
  118. if self.mode == 'new_thread':
  119. request.user.threads += 1
  120. request.user.posts += 1
  121. request.user.last_post = thread.last
  122. request.user.save(force_update=True)
  123. if self.mode == 'new_thread':
  124. request.messages.set_flash(Message(_("New thread has been posted.")), 'success', 'threads')
  125. return redirect(reverse('thread', kwargs={'thread': thread.pk, 'slug': thread.slug}) + ('#post-%s' % post.pk))
  126. if self.mode in ['new_post', 'new_post_quick']:
  127. request.messages.set_flash(Message(_("Your reply has been posted.")), 'success', 'threads')
  128. return redirect(reverse('thread', kwargs={'thread': self.thread.pk, 'slug': self.thread.slug}) + ('#post-%s' % post.pk))
  129. message = Message(form.non_field_errors()[0], 'error')
  130. else:
  131. form = self.get_form()
  132. return request.theme.render_to_response('threads/posting.html',
  133. {
  134. 'mode': self.mode,
  135. 'forum': self.forum,
  136. 'thread': self.thread,
  137. 'post': self.post,
  138. 'parents': self.parents,
  139. 'message': message,
  140. 'form': FormLayout(form),
  141. },
  142. context_instance=RequestContext(request));