users.py 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. from django import forms
  2. from django.utils.translation import gettext_lazy as _
  3. from ....admin.forms import YesNoSwitch
  4. from ....users.validators import validate_username_content
  5. from ... import settings
  6. from .base import ChangeSettingsForm
  7. class ChangeUsersSettingsForm(ChangeSettingsForm):
  8. settings = [
  9. "account_activation",
  10. "allow_custom_avatars",
  11. "avatar_upload_limit",
  12. "default_avatar",
  13. "default_gravatar_fallback",
  14. "blank_avatar",
  15. "signature_length_max",
  16. "subscribe_reply",
  17. "subscribe_start",
  18. "username_length_max",
  19. "username_length_min",
  20. "anonymous_username",
  21. "users_per_page",
  22. "users_per_page_orphans",
  23. "top_posters_ranking_length",
  24. "top_posters_ranking_size",
  25. "allow_data_downloads",
  26. "data_downloads_expiration",
  27. "allow_delete_own_account",
  28. "new_inactive_accounts_delete",
  29. "ip_storage_time",
  30. ]
  31. account_activation = forms.ChoiceField(
  32. label=_("Require new accounts activation"),
  33. choices=[
  34. ("none", _("No activation required")),
  35. ("user", _("Activation token sent to user e-mail")),
  36. ("admin", _("Activation by administrator")),
  37. ("closed", _("Disable new registrations")),
  38. ],
  39. widget=forms.RadioSelect(),
  40. )
  41. new_inactive_accounts_delete = forms.IntegerField(
  42. label=_(
  43. "Delete new inactive accounts if they weren't activated "
  44. "within this number of days"
  45. ),
  46. help_text=_("Enter 0 to never delete inactive new accounts."),
  47. min_value=0,
  48. )
  49. username_length_min = forms.IntegerField(
  50. label=_("Minimum allowed username length"), min_value=2, max_value=20
  51. )
  52. username_length_max = forms.IntegerField(
  53. label=_("Maximum allowed username length"), min_value=2, max_value=20
  54. )
  55. allow_custom_avatars = YesNoSwitch(
  56. label=_("Allow custom avatar uploads"),
  57. help_text=_(
  58. "Turning this option off will forbid forum users from uploading custom "
  59. "avatars. Good for forums adressed at young users."
  60. ),
  61. )
  62. avatar_upload_limit = forms.IntegerField(
  63. label=_("Maximum size of uploaded avatar"),
  64. help_text=_("Enter maximum allowed file size (in KB) for avatar uploads."),
  65. min_value=0,
  66. )
  67. default_avatar = forms.ChoiceField(
  68. label=_("Default avatar"),
  69. choices=[
  70. ("dynamic", _("Individual")),
  71. ("gravatar", _("Gravatar")),
  72. ("gallery", _("Random avatar from gallery")),
  73. ],
  74. widget=forms.RadioSelect(),
  75. )
  76. default_gravatar_fallback = forms.ChoiceField(
  77. label=_("Fallback for default gravatar"),
  78. help_text=_(
  79. "Select which avatar to use when user has no gravatar associated with "
  80. "their e-mail address."
  81. ),
  82. choices=[
  83. ("dynamic", _("Individual")),
  84. ("gallery", _("Random avatar from gallery")),
  85. ],
  86. widget=forms.RadioSelect(),
  87. )
  88. blank_avatar = forms.ImageField(
  89. label=_("Blank avatar"),
  90. help_text=_(
  91. "Blank avatar is displayed in the interface when user's avatar is not "
  92. "available: when user was deleted or is guest. Uploaded image should be "
  93. "a square."
  94. ),
  95. required=False,
  96. )
  97. blank_avatar_delete = forms.BooleanField(
  98. label=_("Delete custom blank avatar"), required=False
  99. )
  100. signature_length_max = forms.IntegerField(
  101. label=_("Maximum allowed signature length"), min_value=10, max_value=5000
  102. )
  103. subscribe_start = forms.ChoiceField(
  104. label=_("Started threads"),
  105. choices=[
  106. ("no", _("Don't watch")),
  107. ("watch", _("Put on watched threads list")),
  108. (
  109. "watch_email",
  110. _("Put on watched threads list and e-mail user when somebody replies"),
  111. ),
  112. ],
  113. widget=forms.RadioSelect(),
  114. )
  115. subscribe_reply = forms.ChoiceField(
  116. label=_("Replied threads"),
  117. choices=[
  118. ("no", _("Don't watch")),
  119. ("watch", _("Put on watched threads list")),
  120. (
  121. "watch_email",
  122. _("Put on watched threads list and e-mail user when somebody replies"),
  123. ),
  124. ],
  125. widget=forms.RadioSelect(),
  126. )
  127. users_per_page = forms.IntegerField(
  128. label=_("Number of users displayed on a single page"), min_value=4
  129. )
  130. users_per_page_orphans = forms.IntegerField(
  131. label=_("Maximum orphans"),
  132. help_text=_(
  133. "If number of users to be displayed on the last page is less or equal to "
  134. "number specified in this setting, those users will instead be displayed "
  135. "on previous page, reducing the total number of pages on the list."
  136. ),
  137. min_value=0,
  138. )
  139. top_posters_ranking_length = forms.IntegerField(
  140. label=_("Maximum age in days of posts that should count to the ranking"),
  141. min_value=1,
  142. )
  143. top_posters_ranking_size = forms.IntegerField(
  144. label=_("Maximum number of ranked users"), min_value=2
  145. )
  146. allow_data_downloads = YesNoSwitch(label=_("Allow users to download their data"))
  147. data_downloads_expiration = forms.IntegerField(
  148. label=_("Maximum age in hours of data downloads before they expire"),
  149. help_text=_(
  150. "Data downloads older than specified will have their files deleted and "
  151. "will be marked as expired."
  152. ),
  153. min_value=1,
  154. )
  155. allow_delete_own_account = YesNoSwitch(
  156. label=_("Allow users to delete their own accounts")
  157. )
  158. ip_storage_time = forms.IntegerField(
  159. label=_("IP storage time"),
  160. help_text=_(
  161. "Number of days for which users IP addresses are stored in forum database. "
  162. "Enter zero to store registered IP addresses forever. Deleting user "
  163. "account always deletes the IP addresses associated with it."
  164. ),
  165. min_value=0,
  166. )
  167. anonymous_username = forms.CharField(
  168. label=_("Anonymous username"),
  169. help_text=_(
  170. "This username is displayed instead of delete user's actual name "
  171. "next to their content."
  172. ),
  173. min_length=1,
  174. max_length=15,
  175. validators=[validate_username_content],
  176. )
  177. def clean_blank_avatar(self):
  178. upload = self.cleaned_data.get("blank_avatar")
  179. if not upload or upload == self.initial.get("blank_avatar"):
  180. return None
  181. if upload.image.width != upload.image.height:
  182. raise forms.ValidationError(_("Submitted image is not a square."))
  183. min_size = max(settings.MISAGO_AVATARS_SIZES)
  184. if upload.image.width < min_size:
  185. raise forms.ValidationError(
  186. _("Submitted image's edge should be at least %(size)s pixels long.")
  187. % {"size": min_size}
  188. )
  189. return upload
  190. def clean(self):
  191. cleaned_data = super().clean()
  192. if cleaned_data.get("users_per_page_orphans") > cleaned_data.get(
  193. "users_per_page"
  194. ):
  195. self.add_error(
  196. "users_per_page_orphans",
  197. _("This value must be lower than number of users per page."),
  198. )
  199. return cleaned_data