forms.py 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. from django.utils.translation import ugettext_lazy as _
  2. from django import forms
  3. from mptt.forms import TreeNodeChoiceField
  4. from misago.forms import Form, YesNoSwitch
  5. from misago.forums.models import Forum
  6. from misago.utils.validators import validate_sluggable
  7. class CategoryForm(Form):
  8. parent = False
  9. perms = False
  10. name = forms.CharField(max_length=255, validators=[validate_sluggable(
  11. _("Category name must be sluggable."),
  12. _("Category name is too long.")
  13. )])
  14. description = forms.CharField(widget=forms.Textarea, required=False)
  15. closed = forms.BooleanField(widget=YesNoSwitch, required=False)
  16. style = forms.CharField(max_length=255, required=False)
  17. attrs = forms.CharField(max_length=255, required=False)
  18. show_details = forms.BooleanField(widget=YesNoSwitch, required=False)
  19. layout = (
  20. (
  21. _("Basic Options"),
  22. (
  23. ('parent', {'label': _("Category Parent")}),
  24. ('perms', {'label': _("Copy Permissions from")}),
  25. ('name', {'label': _("Category Name")}),
  26. ('description', {'label': _("Category Description")}),
  27. ('closed', {'label': _("Closed Category")}),
  28. ),
  29. ),
  30. (
  31. _("Display Options"),
  32. (
  33. ('attrs', {'label': _("Category Attributes"), 'help_text': _('Custom templates can check categories for predefined attributes that will change way they are rendered.')}),
  34. ('show_details', {'label': _("Show Subforums Details"), 'help_text': _('Allows you to prevent this category subforums from displaying statistics, last post data, etc. ect. on forums lists.')}),
  35. ('style', {'label': _("Category Style"), 'help_text': _('You can add custom CSS classess to this category, to change way it looks on board index.')}),
  36. ),
  37. ),
  38. )
  39. def finalize_form(self):
  40. self.fields['parent'] = TreeNodeChoiceField(queryset=Forum.tree.get(token='root').get_descendants(include_self=True), level_indicator=u'- - ')
  41. self.fields['perms'] = TreeNodeChoiceField(queryset=Forum.tree.get(token='root').get_descendants(), level_indicator=u'- - ', required=False, empty_label=_("Don't copy permissions"))
  42. def clean_attrs(self):
  43. clean = []
  44. data = self.cleaned_data['attrs'].strip().split()
  45. for i in data:
  46. i = i.strip()
  47. if not i in clean:
  48. clean.append(i)
  49. return ' '.join(clean)
  50. class ForumForm(Form):
  51. parent = False
  52. perms = False
  53. name = forms.CharField(max_length=255, validators=[validate_sluggable(
  54. _("Forum name must be sluggable."),
  55. _("Forum name is too long.")
  56. )])
  57. description = forms.CharField(widget=forms.Textarea, required=False)
  58. closed = forms.BooleanField(widget=YesNoSwitch, required=False)
  59. style = forms.CharField(max_length=255, required=False)
  60. prune_start = forms.IntegerField(min_value=0, initial=0)
  61. prune_last = forms.IntegerField(min_value=0, initial=0)
  62. attrs = forms.CharField(max_length=255, required=False)
  63. show_details = forms.BooleanField(widget=YesNoSwitch, required=False)
  64. layout = (
  65. (
  66. _("Basic Options"),
  67. (
  68. ('parent', {'label': _("Forum Parent")}),
  69. ('perms', {'label': _("Copy Permissions from")}),
  70. ('name', {'label': _("Forum Name")}),
  71. ('description', {'label': _("Forum Description")}),
  72. ('closed', {'label': _("Closed Forum")}),
  73. ),
  74. ),
  75. (
  76. _("Prune Forum"),
  77. (
  78. ('prune_start', {'label': _("Delete threads with first post older than"), 'help_text': _('Enter number of days since thread start after which thread will be deleted or zero to don\'t delete threads.')}),
  79. ('prune_last', {'label': _("Delete threads with last post older than"), 'help_text': _('Enter number of days since since last reply in thread after which thread will be deleted or zero to don\'t delete threads.')}),
  80. ),
  81. ),
  82. (
  83. _("Display Options"),
  84. (
  85. ('attrs', {'label': _("Subforums List Attributes"), 'help_text': _('Custom templates can check forums for predefined attributes that will change way subforums lists are rendered.')}),
  86. ('show_details', {'label': _("Show Subforums Details"), 'help_text': _("Allows you to prevent this forum's subforums from displaying statistics, last post data, etc. ect. on subforums list.")}),
  87. ('style', {'label': _("Forum Style"), 'help_text': _('You can add custom CSS classess to this forum to change way it looks on forums lists.')}),
  88. ),
  89. ),
  90. )
  91. def finalize_form(self):
  92. self.fields['parent'] = TreeNodeChoiceField(queryset=Forum.tree.get(token='root').get_descendants(), level_indicator=u'- - ')
  93. self.fields['perms'] = TreeNodeChoiceField(queryset=Forum.tree.get(token='root').get_descendants(), level_indicator=u'- - ', required=False, empty_label=_("Don't copy permissions"))
  94. def clean_attrs(self):
  95. clean = []
  96. data = self.cleaned_data['attrs'].strip().split()
  97. for i in data:
  98. i = i.strip()
  99. if not i in clean:
  100. clean.append(i)
  101. return ' '.join(clean)
  102. class RedirectForm(Form):
  103. parent = False
  104. perms = False
  105. name = forms.CharField(max_length=255, validators=[validate_sluggable(
  106. _("Redirect name must be sluggable."),
  107. _("Redirect name is too long.")
  108. )])
  109. description = forms.CharField(widget=forms.Textarea, required=False)
  110. redirect = forms.URLField(max_length=255)
  111. style = forms.CharField(max_length=255, required=False)
  112. layout = (
  113. (
  114. _("Basic Options"),
  115. (
  116. ('parent', {'label': _("Redirect Parent")}),
  117. ('perms', {'label': _("Copy Permissions from")}),
  118. ('name', {'label': _("Redirect Name")}),
  119. ('redirect', {'label': _("Redirect URL")}),
  120. ('description', {'label': _("Redirect Description")}),
  121. ),
  122. ),
  123. (
  124. _("Display Options"),
  125. (
  126. ('style', {'label': _("Redirect Style"), 'help_text': _('You can add custom CSS classess to this redirect to change way it looks on forums lists.')}),
  127. ),
  128. ),
  129. )
  130. def finalize_form(self):
  131. self.fields['parent'] = TreeNodeChoiceField(queryset=Forum.tree.get(token='root').get_descendants(), level_indicator=u'- - ')
  132. self.fields['perms'] = TreeNodeChoiceField(queryset=Forum.tree.get(token='root').get_descendants(), level_indicator=u'- - ', required=False, empty_label=_("Don't copy permissions"))
  133. class DeleteForm(Form):
  134. layout = (
  135. (
  136. _("Delete Options"),
  137. (
  138. ('contents', {'label': _("Move threads to")}),
  139. ('subforums', {'label': _("Move subforums to")}),
  140. ),
  141. ),
  142. )
  143. def __init__(self, *args, **kwargs):
  144. self.forum = kwargs.pop('forum')
  145. super(DeleteForm, self).__init__(*args, **kwargs)
  146. def finalize_form(self):
  147. self.fields['contents'] = TreeNodeChoiceField(queryset=Forum.tree.get(token='root').get_descendants(), required=False, empty_label=_("Remove with forum"), level_indicator=u'- - ')
  148. self.fields['subforums'] = TreeNodeChoiceField(queryset=Forum.tree.get(token='root').get_descendants(), required=False, empty_label=_("Remove with forum"), level_indicator=u'- - ')
  149. def clean_contents(self):
  150. data = self.cleaned_data['contents']
  151. if data:
  152. if data.type == 'category':
  153. raise forms.ValidationError(_("Categories cannot contain threads."))
  154. if data.type == 'redirect':
  155. raise forms.ValidationError(_("Redirects cannot contain threads."))
  156. return data
  157. def clean(self):
  158. cleaned_data = super(DeleteForm, self).clean()
  159. if self.forum.type == 'forum' and cleaned_data['contents'] and cleaned_data['contents'].lft > self.forum.lft and cleaned_data['contents'].rght < self.forum.rght and not cleaned_data['subforums']:
  160. raise forms.ValidationError(_("Destination you want to move this forum's threads to will be deleted with this forum."))
  161. return cleaned_data