forms.py 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  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. "index_header",
  109. "index_title",
  110. "index_meta_description",
  111. "logo",
  112. "logo_small",
  113. "logo_text",
  114. "forum_footnote",
  115. "email_footer",
  116. ]
  117. forum_name = forms.CharField(label=_("Forum name"), min_length=2, max_length=255)
  118. index_header = forms.CharField(
  119. label=_("Header text"),
  120. help_text=_("This text will replace forum name in page header."),
  121. max_length=255,
  122. required=False,
  123. )
  124. index_title = forms.CharField(label=_("Page title"), max_length=255, required=False)
  125. index_meta_description = forms.CharField(
  126. label=_("Meta Description"),
  127. help_text=_(
  128. "Short description of your forum that search and social sites may "
  129. "display next to link to your forum's index."
  130. ),
  131. max_length=255,
  132. required=False,
  133. )
  134. logo = forms.ImageField(
  135. label=_("Logo"),
  136. help_text=_("Image that will displayed in forum navbar."),
  137. required=False,
  138. )
  139. logo_delete = forms.BooleanField(label=_("Delete current logo"), required=False)
  140. logo_small = forms.ImageField(
  141. label=_("Small logo"),
  142. help_text=_(
  143. "Image that will be displayed in compact forum navbar. "
  144. "When set, it will replace icon pointing to forum index."
  145. ),
  146. required=False,
  147. )
  148. logo_small_delete = forms.BooleanField(
  149. label=_("Delete current small logo"), required=False
  150. )
  151. logo_text = forms.CharField(
  152. label=_("Text"),
  153. help_text=_(
  154. "Text displayed in forum navbar. If logo image was uploaded, text will "
  155. "be displayed right next to it. Never displayed by the compact navbar."
  156. ),
  157. max_length=255,
  158. required=False,
  159. )
  160. forum_footnote = forms.CharField(
  161. label=_("Forum footnote"),
  162. help_text=_("Short message displayed in forum footer."),
  163. max_length=300,
  164. required=False,
  165. )
  166. email_footer = forms.CharField(
  167. label=_("E-mails footer"),
  168. help_text=_(
  169. "Optional short message included at the end of e-mails sent by forum."
  170. ),
  171. max_length=255,
  172. required=False,
  173. )
  174. class ChangeThreadsSettingsForm(ChangeSettingsForm):
  175. settings = [
  176. "post_length_max",
  177. "post_length_min",
  178. "thread_title_length_max",
  179. "thread_title_length_min",
  180. ]
  181. post_length_max = forms.IntegerField(
  182. label=_("Maximum allowed post length"), min_value=0
  183. )
  184. post_length_min = forms.IntegerField(
  185. label=_("Minimum required post length"), min_value=1
  186. )
  187. thread_title_length_max = forms.IntegerField(
  188. label=_("Maximum allowed thread title length"), min_value=2, max_value=255
  189. )
  190. thread_title_length_min = forms.IntegerField(
  191. label=_("Minimum required thread title length"), min_value=2, max_value=255
  192. )
  193. class ChangeUsersSettingsForm(ChangeSettingsForm):
  194. settings = [
  195. "account_activation",
  196. "allow_custom_avatars",
  197. "avatar_upload_limit",
  198. "default_avatar",
  199. "default_gravatar_fallback",
  200. "signature_length_max",
  201. "subscribe_reply",
  202. "subscribe_start",
  203. "username_length_max",
  204. "username_length_min",
  205. ]
  206. account_activation = forms.ChoiceField(
  207. label=_("Require new accounts activation"),
  208. choices=[
  209. ("none", _("No activation required")),
  210. ("user", _("Activation token sent to user e-mail")),
  211. ("admin", _("Activation by administrator")),
  212. ("closed", _("Disable new registrations")),
  213. ],
  214. widget=forms.RadioSelect(),
  215. )
  216. username_length_min = forms.IntegerField(
  217. label=_("Minimum allowed username length"), min_value=2, max_value=20
  218. )
  219. username_length_max = forms.IntegerField(
  220. label=_("Maximum allowed username length"), min_value=2, max_value=20
  221. )
  222. allow_custom_avatars = YesNoSwitch(
  223. label=_("Allow custom avatar uploads"),
  224. help_text=_(
  225. "Turning this option off will forbid forum users from uploading custom "
  226. "avatars. Good for forums adressed at young users."
  227. ),
  228. )
  229. avatar_upload_limit = forms.IntegerField(
  230. label=_("Maximum size of uploaded avatar"),
  231. help_text=_("Enter maximum allowed file size (in KB) for avatar uploads."),
  232. min_value=0,
  233. )
  234. default_avatar = forms.ChoiceField(
  235. label=_("Default avatar"),
  236. choices=[
  237. ("dynamic", _("Individual")),
  238. ("gravatar", _("Gravatar")),
  239. ("gallery", _("Random avatar from gallery")),
  240. ],
  241. widget=forms.RadioSelect(),
  242. )
  243. default_gravatar_fallback = forms.ChoiceField(
  244. label=_("Fallback for default gravatar"),
  245. help_text=_(
  246. "Select which avatar to use when user has no gravatar associated with "
  247. "their e-mail address."
  248. ),
  249. choices=[
  250. ("dynamic", _("Individual")),
  251. ("gallery", _("Random avatar from gallery")),
  252. ],
  253. widget=forms.RadioSelect(),
  254. )
  255. signature_length_max = forms.IntegerField(
  256. label=_("Maximum allowed signature length"), min_value=10, max_value=5000
  257. )
  258. subscribe_start = forms.ChoiceField(
  259. label=_("Started threads"),
  260. choices=[
  261. ("no", _("Don't watch")),
  262. ("watch", _("Put on watched threads list")),
  263. (
  264. "watch_email",
  265. _("Put on watched threads list and e-mail user when somebody replies"),
  266. ),
  267. ],
  268. widget=forms.RadioSelect(),
  269. )
  270. subscribe_reply = forms.ChoiceField(
  271. label=_("Replied threads"),
  272. choices=[
  273. ("no", _("Don't watch")),
  274. ("watch", _("Put on watched threads list")),
  275. (
  276. "watch_email",
  277. _("Put on watched threads list and e-mail user when somebody replies"),
  278. ),
  279. ],
  280. widget=forms.RadioSelect(),
  281. )