forms.py 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. from django import forms
  2. from django.utils.translation import gettext_lazy as _
  3. from ...admin.forms import YesNoSwitch
  4. from ..cache import clear_settings_cache
  5. class ChangeSettingsForm(forms.Form):
  6. settings = []
  7. def save(self, settings):
  8. self.save_settings(settings)
  9. self.clear_cache()
  10. def save_settings(self, settings):
  11. for setting in self.settings:
  12. setting_obj = settings[setting]
  13. new_value = self.cleaned_data.get(setting)
  14. if setting_obj.python_type == "image":
  15. if new_value and new_value != self.initial.get(setting):
  16. self.save_image(setting_obj, new_value)
  17. elif self.cleaned_data.get("%s_delete" % setting):
  18. self.delete_image(setting_obj)
  19. else:
  20. self.save_setting(setting_obj, new_value)
  21. def delete_image(self, setting):
  22. if setting.image:
  23. setting.image.delete()
  24. def save_image(self, setting, value):
  25. if setting.image:
  26. setting.image.delete(save=False)
  27. setting.value = value
  28. setting.save()
  29. def save_setting(self, setting, value):
  30. setting.value = value
  31. setting.save()
  32. def clear_cache(self):
  33. clear_settings_cache()
  34. class ChangeCaptchaSettingsForm(ChangeSettingsForm):
  35. settings = [
  36. "captcha_type",
  37. "recaptcha_site_key",
  38. "recaptcha_secret_key",
  39. "qa_question",
  40. "qa_help_text",
  41. "qa_answers",
  42. ]
  43. captcha_type = forms.ChoiceField(
  44. label=_("Enable CAPTCHA"),
  45. choices=[
  46. ("no", _("No CAPTCHA")),
  47. ("re", _("reCaptcha")),
  48. ("qa", _("Question and answer")),
  49. ],
  50. widget=forms.RadioSelect(),
  51. )
  52. recaptcha_site_key = forms.CharField(
  53. label=_("Site key"), max_length=100, required=False
  54. )
  55. recaptcha_secret_key = forms.CharField(
  56. label=_("Secret key"), max_length=100, required=False
  57. )
  58. qa_question = forms.CharField(
  59. label=_("Test question"), max_length=100, required=False
  60. )
  61. qa_help_text = forms.CharField(
  62. label=_("Question help text"), max_length=250, required=False
  63. )
  64. qa_answers = forms.CharField(
  65. label=_("Valid answers"),
  66. help_text=_("Enter each answer in new line. Answers are case-insensitive."),
  67. widget=forms.Textarea({"rows": 4}),
  68. max_length=250,
  69. required=False,
  70. )
  71. def clean(self):
  72. cleaned_data = super().clean()
  73. if cleaned_data.get("captcha_type") == "re":
  74. if not cleaned_data.get("recaptcha_site_key"):
  75. self.add_error(
  76. "recaptcha_site_key",
  77. _(
  78. "You need to enter site key if "
  79. "selected CAPTCHA type is reCaptcha."
  80. ),
  81. )
  82. if not cleaned_data.get("recaptcha_secret_key"):
  83. self.add_error(
  84. "recaptcha_secret_key",
  85. _(
  86. "You need to enter secret key if "
  87. "selected CAPTCHA type is reCaptcha."
  88. ),
  89. )
  90. if cleaned_data.get("captcha_type") == "qa":
  91. if not cleaned_data.get("qa_question"):
  92. self.add_error(
  93. "qa_question",
  94. _("You need to set question if selected CAPTCHA type is Q&A."),
  95. )
  96. if not cleaned_data.get("qa_answers"):
  97. self.add_error(
  98. "qa_answers",
  99. _(
  100. "You need to set question answers if "
  101. "selected CAPTCHA type is Q&A."
  102. ),
  103. )
  104. return cleaned_data
  105. class ChangeGeneralSettingsForm(ChangeSettingsForm):
  106. settings = [
  107. "forum_name",
  108. "forum_index_title",
  109. "forum_index_meta_description",
  110. "logo",
  111. "logo_small",
  112. "logo_text",
  113. "forum_footnote",
  114. "email_footer",
  115. ]
  116. forum_name = forms.CharField(label=_("Forum name"), min_length=2, max_length=255)
  117. forum_index_title = forms.CharField(
  118. label=_("Title"),
  119. help_text=_("You may set a custom title on forum index by typing it here."),
  120. max_length=255,
  121. required=False,
  122. )
  123. forum_index_meta_description = forms.CharField(
  124. label=_("Meta Description"),
  125. help_text=_("Short description of your forum for internet crawlers."),
  126. max_length=255,
  127. required=False,
  128. )
  129. logo = forms.ImageField(
  130. label=_("Logo"),
  131. help_text=_("Image that will displayed in forum navbar."),
  132. required=False,
  133. )
  134. logo_delete = forms.BooleanField(label=_("Delete current logo"), required=False)
  135. logo_small = forms.ImageField(
  136. label=_("Small logo"),
  137. help_text=_(
  138. "Image that will be displayed in compact forum navbar. "
  139. "When set, it will replace icon pointing to forum index."
  140. ),
  141. required=False,
  142. )
  143. logo_small_delete = forms.BooleanField(
  144. label=_("Delete current small logo"), required=False
  145. )
  146. logo_text = forms.CharField(
  147. label=_("Text"),
  148. help_text=_(
  149. "Text displayed in forum navbar. If logo image was uploaded, text will "
  150. "be displayed right next to it. Never displayed by the compact navbar."
  151. ),
  152. max_length=255,
  153. required=False,
  154. )
  155. forum_footnote = forms.CharField(
  156. label=_("Forum footnote"),
  157. help_text=_("Short message displayed in forum footer."),
  158. max_length=300,
  159. required=False,
  160. )
  161. email_footer = forms.CharField(
  162. label=_("E-mails footer"),
  163. help_text=_(
  164. "Optional short message included at the end of e-mails sent by forum."
  165. ),
  166. max_length=255,
  167. required=False,
  168. )
  169. class ChangeThreadsSettingsForm(ChangeSettingsForm):
  170. settings = [
  171. "post_length_max",
  172. "post_length_min",
  173. "thread_title_length_max",
  174. "thread_title_length_min",
  175. ]
  176. post_length_max = forms.IntegerField(
  177. label=_("Maximum allowed post length"), min_value=0
  178. )
  179. post_length_min = forms.IntegerField(
  180. label=_("Minimum required post length"), min_value=1
  181. )
  182. thread_title_length_max = forms.IntegerField(
  183. label=_("Maximum allowed thread title length"), min_value=2, max_value=255
  184. )
  185. thread_title_length_min = forms.IntegerField(
  186. label=_("Minimum required thread title length"), min_value=2, max_value=255
  187. )
  188. class ChangeUsersSettingsForm(ChangeSettingsForm):
  189. settings = [
  190. "account_activation",
  191. "allow_custom_avatars",
  192. "avatar_upload_limit",
  193. "default_avatar",
  194. "default_gravatar_fallback",
  195. "signature_length_max",
  196. "subscribe_reply",
  197. "subscribe_start",
  198. "username_length_max",
  199. "username_length_min",
  200. ]
  201. account_activation = forms.ChoiceField(
  202. label=_("Require new accounts activation"),
  203. choices=[
  204. ("none", _("No activation required")),
  205. ("user", _("Activation token sent to user e-mail")),
  206. ("admin", _("Activation by administrator")),
  207. ("closed", _("Disable new registrations")),
  208. ],
  209. widget=forms.RadioSelect(),
  210. )
  211. username_length_min = forms.IntegerField(
  212. label=_("Minimum allowed username length"), min_value=2, max_value=20
  213. )
  214. username_length_max = forms.IntegerField(
  215. label=_("Maximum allowed username length"), min_value=2, max_value=20
  216. )
  217. allow_custom_avatars = YesNoSwitch(
  218. label=_("Allow custom avatar uploads"),
  219. help_text=_(
  220. "Turning this option off will forbid forum users from uploading custom "
  221. "avatars. Good for forums adressed at young users."
  222. ),
  223. )
  224. avatar_upload_limit = forms.IntegerField(
  225. label=_("Maximum size of uploaded avatar"),
  226. help_text=_("Enter maximum allowed file size (in KB) for avatar uploads."),
  227. min_value=0,
  228. )
  229. default_avatar = forms.ChoiceField(
  230. label=_("Default avatar"),
  231. choices=[
  232. ("dynamic", _("Individual")),
  233. ("gravatar", _("Gravatar")),
  234. ("gallery", _("Random avatar from gallery")),
  235. ],
  236. widget=forms.RadioSelect(),
  237. )
  238. default_gravatar_fallback = forms.ChoiceField(
  239. label=_("Fallback for default gravatar"),
  240. help_text=_(
  241. "Select which avatar to use when user has no gravatar associated with "
  242. "their e-mail address."
  243. ),
  244. choices=[
  245. ("dynamic", _("Individual")),
  246. ("gallery", _("Random avatar from gallery")),
  247. ],
  248. widget=forms.RadioSelect(),
  249. )
  250. signature_length_max = forms.IntegerField(
  251. label=_("Maximum allowed signature length"), min_value=10, max_value=5000
  252. )
  253. subscribe_start = forms.ChoiceField(
  254. label=_("Started threads"),
  255. choices=[
  256. ("no", _("Don't watch")),
  257. ("watch", _("Put on watched threads list")),
  258. (
  259. "watch_email",
  260. _("Put on watched threads list and e-mail user when somebody replies"),
  261. ),
  262. ],
  263. widget=forms.RadioSelect(),
  264. )
  265. subscribe_reply = forms.ChoiceField(
  266. label=_("Replied threads"),
  267. choices=[
  268. ("no", _("Don't watch")),
  269. ("watch", _("Put on watched threads list")),
  270. (
  271. "watch_email",
  272. _("Put on watched threads list and e-mail user when somebody replies"),
  273. ),
  274. ],
  275. widget=forms.RadioSelect(),
  276. )