reply.py 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. from django.utils.translation import ugettext_lazy as _, ungettext
  2. from misago.conf import settings
  3. from misago.core import forms
  4. from misago.core.validators import validate_sluggable
  5. from misago.markup import Editor, common_flavour
  6. from misago.threads.checksums import update_post_checksum
  7. from misago.threads.forms.posting import (EditorFormsetMiddleware,
  8. START, REPLY, EDIT)
  9. class ReplyForm(forms.Form):
  10. is_main = True
  11. legend = _("Reply")
  12. template = "misago/threads/replyform.html"
  13. js_template = "misago/threads/replyform_js.html"
  14. post = forms.CharField(label=_("Message body"), required=False)
  15. def __init__(self, post=None, *args, **kwargs):
  16. self.post_instance = post
  17. self.parsing_result = {}
  18. super(ReplyForm, self).__init__(*args, **kwargs)
  19. def validate_post(self, post):
  20. post_len = len(post)
  21. if not post_len:
  22. raise forms.ValidationError(_("Enter message."))
  23. if post_len < settings.post_length_min:
  24. message = ungettext(
  25. "Posted message should be at least %(limit)s character long.",
  26. "Posted message should be at least %(limit)s characters long.",
  27. settings.post_length_min)
  28. message = message % {'limit': settings.post_length_min}
  29. raise forms.ValidationError(message)
  30. if settings.post_length_max and post_len > settings.post_length_max:
  31. message = ungettext(
  32. "Posted message can't be longer than %(limit)s character.",
  33. "Posted message can't be longer than %(limit)s characters.",
  34. settings.post_length_max,)
  35. message = message % {'limit': settings.post_length_max}
  36. raise forms.ValidationError(message)
  37. self.parsing_result = common_flavour(post, self.post_instance.poster)
  38. self.post_instance.post = self.parsing_result['original_text']
  39. self.post_instance.post_parsed = self.parsing_result['parsed_text']
  40. def validate_data(self, data):
  41. self.validate_post(data.get('post', ''))
  42. def clean(self):
  43. data = super(ReplyForm, self).clean()
  44. self.validate_data(data)
  45. return data
  46. class ThreadForm(ReplyForm):
  47. legend = _("Thread ")
  48. title = forms.CharField(label=_("Thread title"), required=False)
  49. def __init__(self, thread=None, *args, **kwargs):
  50. self.thread_instance = thread
  51. super(ThreadForm, self).__init__(*args, **kwargs)
  52. def validate_title(self, title):
  53. title_len = len(title)
  54. if not title_len:
  55. raise forms.ValidationError(_("Enter thread title."))
  56. if title_len < settings.thread_title_length_min:
  57. message = ungettext(
  58. "Thread title should be at least %(limit)s character long.",
  59. "Thread title should be at least %(limit)s characters long.",
  60. settings.thread_title_length_min)
  61. message = message % {'limit': settings.thread_title_length_min}
  62. raise forms.ValidationError(message)
  63. if title_len > settings.thread_title_length_max:
  64. message = ungettext(
  65. "Thread title can't be longer than %(limit)s character.",
  66. "Thread title can't be longer than %(limit)s characters.",
  67. settings.thread_title_length_max,)
  68. message = message % {'limit': settings.thread_title_length_max}
  69. raise forms.ValidationError(message)
  70. error_not_sluggable = _("Thread title should contain "
  71. "alpha-numeric characters.")
  72. error_slug_too_long = _("Thread title is too long.")
  73. slug_validator = validate_sluggable(error_not_sluggable,
  74. error_slug_too_long)
  75. slug_validator(title)
  76. def validate_data(self, data):
  77. errors = []
  78. if not data.get('title') and not data.get('post'):
  79. raise forms.ValidationError(_("Enter thread title and message."))
  80. try:
  81. self.validate_title(data.get('title', ''))
  82. except forms.ValidationError as e:
  83. errors.append(e)
  84. try:
  85. self.validate_post(data.get('post', ''))
  86. except forms.ValidationError as e:
  87. errors.append(e)
  88. if errors:
  89. raise forms.ValidationError(errors)
  90. class PrefixedThreadForm(ThreadForm):
  91. pass
  92. class ReplyFormMiddleware(EditorFormsetMiddleware):
  93. def make_form(self):
  94. initial_data = {'title': self.thread.title, 'post': self.post.post}
  95. if self.mode == START:
  96. if self.request.method == 'POST':
  97. form = ThreadForm(self.thread, self.post, self.request.POST)
  98. else:
  99. form = ThreadForm(self.thread, self.post, initial=initial_data)
  100. else:
  101. if self.request.method == 'POST':
  102. form = ReplyForm(self.post, self.request.POST)
  103. else:
  104. form = ReplyForm(self.post, initial=initial_data)
  105. form.post_editor = Editor(form['post'])
  106. return form
  107. def save(self, form):
  108. if self.mode == START:
  109. self.thread.set_title(form.cleaned_data['title'])
  110. self.thread.starter_name = '-'
  111. self.thread.starter_slug = '-'
  112. self.thread.last_poster_name = '-'
  113. self.thread.last_poster_slug = '-'
  114. self.thread.started_on = self.datetime
  115. self.thread.last_post_on = self.datetime
  116. self.thread.save()
  117. self.post.updated_on = self.datetime
  118. if self.mode == EDIT:
  119. self.post.last_editor_name = self.user
  120. self.post.poster_name = self.user.username
  121. self.post.poster_slug = self.user.slug
  122. else:
  123. self.post.thread = self.thread
  124. self.post.poster = self.user
  125. self.post.poster_name = self.user.username
  126. self.post.poster_ip = self.request._misago_real_ip
  127. self.post.posted_on = self.datetime
  128. self.post.post_checksum = update_post_checksum(self.post)
  129. self.post.save()
  130. if self.mode == START:
  131. self.forum.threads += 1
  132. self.thread.set_first_post(self.post)
  133. if self.mode != EDIT:
  134. self.thread.set_last_post(self.post)
  135. if self.mode != REPLY:
  136. self.thread.replies += 1
  137. self.thread.save()
  138. if self.mode != EDIT:
  139. self.forum.set_last_thread(self.thread)
  140. self.forum.posts += 1
  141. self.forum.save()