forms.py 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. from django import forms
  2. from django.utils.translation import ungettext, ugettext_lazy as _
  3. from mptt.forms import TreeNodeChoiceField
  4. from misago.forms import Form
  5. from misago.forums.models import Forum
  6. from misago.utils import slugify
  7. class ThreadNameMixin(object):
  8. def clean_thread_name(self):
  9. data = self.cleaned_data['thread_name']
  10. slug = slugify(data)
  11. if len(slug) < self.request.settings['thread_name_min']:
  12. raise forms.ValidationError(ungettext(
  13. "Thread name must contain at least one alpha-numeric character.",
  14. "Thread name must contain at least %(count)d alpha-numeric characters.",
  15. self.request.settings['thread_name_min']
  16. ) % {'count': self.request.settings['thread_name_min']})
  17. return data
  18. class PostForm(Form, ThreadNameMixin):
  19. thread_name = forms.CharField(max_length=255)
  20. post = forms.CharField(widget=forms.Textarea)
  21. def __init__(self, data=None, file=None, request=None, mode=None, *args, **kwargs):
  22. self.mode = mode
  23. super(PostForm, self).__init__(data, file, request=request, *args, **kwargs)
  24. def finalize_form(self):
  25. self.layout = [
  26. [
  27. None,
  28. [
  29. ('thread_name', {'label': _("Thread Name")}),
  30. ('post', {'label': _("Post Content")}),
  31. ],
  32. ],
  33. ]
  34. if self.mode not in ['edit_thread', 'new_thread']:
  35. del self.fields['thread_name']
  36. del self.layout[0][1][0]
  37. def clean_post(self):
  38. data = self.cleaned_data['post']
  39. if len(data) < self.request.settings['post_length_min']:
  40. raise forms.ValidationError(ungettext(
  41. "Post content cannot be empty.",
  42. "Post content cannot be shorter than %(count)d characters.",
  43. self.request.settings['post_length_min']
  44. ) % {'count': self.request.settings['post_length_min']})
  45. return data
  46. class QuickReplyForm(Form):
  47. post = forms.CharField(widget=forms.Textarea)
  48. class MoveThreadsForm(Form):
  49. error_source = 'new_forum'
  50. def __init__(self, data=None, request=None, forum=None, *args, **kwargs):
  51. self.forum = forum
  52. super(MoveThreadsForm, self).__init__(data, request=request, *args, **kwargs)
  53. def finalize_form(self):
  54. self.fields['new_forum'] = TreeNodeChoiceField(queryset=Forum.tree.get(token='root').get_descendants().filter(pk__in=self.request.acl.forums.acl['can_browse']),level_indicator=u'- - ')
  55. self.layout = [
  56. [
  57. _("Thread Options"),
  58. [
  59. ('new_forum', {'label': _("Move Thread to"), 'help_text': _("Select forum you want to move threads to.")}),
  60. ],
  61. ],
  62. ]
  63. def clean_new_forum(self):
  64. new_forum = self.cleaned_data['new_forum']
  65. # Assert its forum and its not current forum
  66. if new_forum.type != 'forum':
  67. raise forms.ValidationError(_("This is not forum."))
  68. if new_forum.pk == self.forum.pk:
  69. raise forms.ValidationError(_("New forum is same as current one."))
  70. return new_forum
  71. class MergeThreadsForm(Form, ThreadNameMixin):
  72. def __init__(self, data=None, request=None, threads=[], *args, **kwargs):
  73. self.threads = threads
  74. super(MergeThreadsForm, self).__init__(data, request=request, *args, **kwargs)
  75. def finalize_form(self):
  76. self.fields['thread_name'] = forms.CharField(max_length=255, initial=self.threads[0].name)
  77. self.layout = [
  78. [
  79. _("Thread Options"),
  80. [
  81. ('thread_name', {'label': _("Thread Name"), 'help_text': _("Name of new thread that will be created as result of merge.")}),
  82. ],
  83. ],
  84. [
  85. _("Merge Order"),
  86. [
  87. ],
  88. ],
  89. ]
  90. choices = []
  91. for i, thread in enumerate(self.threads):
  92. choices.append((str(i), i + 1))
  93. for i, thread in enumerate(self.threads):
  94. self.fields['thread_%s' % thread.pk] = forms.ChoiceField(choices=choices,initial=str(i))
  95. self.layout[1][1].append(('thread_%s' % thread.pk, {'label': thread.name}))
  96. def clean(self):
  97. cleaned_data = super(MergeThreadsForm, self).clean()
  98. self.merge_order = {}
  99. lookback = []
  100. for thread in self.threads:
  101. order = int(cleaned_data['thread_%s' % thread.pk])
  102. if order in lookback:
  103. raise forms.ValidationError(_("One or more threads have same position in merge order."))
  104. lookback.append(order)
  105. self.merge_order[order] = thread
  106. return cleaned_data