Browse Source

#702: further cleanups

Rafał Pitoń 8 years ago
parent
commit
956d7022ad

+ 1 - 0
misago/acl/providers.py

@@ -5,6 +5,7 @@ from misago.conf import settings
 
 
 class PermissionProviders(object):
 class PermissionProviders(object):
     """manager for permission providers"""
     """manager for permission providers"""
+
     def __init__(self):
     def __init__(self):
         self._initialized = False
         self._initialized = False
         self._providers = []
         self._providers = []

+ 71 - 57
misago/core/migrations/0002_basic_settings.py

@@ -21,68 +21,82 @@ def create_basic_settings_group(apps, schema_editor):
                     "Those settings control most basic properties "
                     "Those settings control most basic properties "
                     "of your forum like its name or description."
                     "of your forum like its name or description."
                 ),
                 ),
-            'settings': ({
-                'setting': 'forum_name',
-                'name': _("Forum name"),
-                'legend': _("General"),
-                'value': "Misago",
-                'field_extra': {
-                    'min_length': 2,
-                    'max_length': 255
+            'settings': [
+                {
+                    'setting': 'forum_name',
+                    'name': _("Forum name"),
+                    'legend': _("General"),
+                    'value': "Misago",
+                    'field_extra': {
+                        'min_length': 2,
+                        'max_length': 255
+                    },
+                    'is_public': True,
                 },
                 },
-                'is_public': True,
-            }, {
-                'setting': 'forum_index_title',
-                'name': _("Index title"),
-                'description': _("You may set custon title on "
-                                 "forum index by typing it here."),
-                'legend': _("Forum index"),
-                'field_extra': {
-                    'max_length': 255
+                {
+                    'setting':
+                        'forum_index_title',
+                    'name':
+                        _("Index title"),
+                    'description':
+                        _("You may set custon title on "
+                          "forum index by typing it here."),
+                    'legend':
+                        _("Forum index"),
+                    'field_extra': {
+                        'max_length': 255
+                    },
+                    'is_public':
+                        True,
                 },
                 },
-                'is_public': True,
-            }, {
-                'setting': 'forum_index_meta_description',
-                'name': _("Meta Description"),
-                'description': _("Short description of your forum "
-                                 "for internet crawlers."),
-                'field_extra': {
-                    'max_length': 255
+                {
+                    'setting': 'forum_index_meta_description',
+                    'name': _("Meta Description"),
+                    'description': _("Short description of your forum "
+                                     "for internet crawlers."),
+                    'field_extra': {
+                        'max_length': 255
+                    },
                 },
                 },
-            }, {
-                'setting': 'forum_branding_display',
-                'name': _("Display branding"),
-                'description': _("Switch branding in forum's navbar."),
-                'legend': _("Branding"),
-                'value': True,
-                'python_type': 'bool',
-                'form_field': 'yesno',
-                'is_public': True,
-            }, {
-                'setting': 'forum_branding_text',
-                'name': _("Branding text"),
-                'description': _("Optional text displayed besides "
-                                 "brand image in navbar."),
-                'value': "Misago",
-                'field_extra': {
-                    'max_length': 255
+                {
+                    'setting': 'forum_branding_display',
+                    'name': _("Display branding"),
+                    'description': _("Switch branding in forum's navbar."),
+                    'legend': _("Branding"),
+                    'value': True,
+                    'python_type': 'bool',
+                    'form_field': 'yesno',
+                    'is_public': True,
                 },
                 },
-                'is_public': True,
-            }, {
-                'setting':
-                    'email_footer',
-                'name':
-                    _("E-mails footer"),
-                'description':
-                    _("Optional short message included "
-                      "at the end of e-mails sent by "
-                      "forum"),
-                'legend':
-                    _("Forum e-mails"),
-                'field_extra': {
-                    'max_length': 255
+                {
+                    'setting': 'forum_branding_text',
+                    'name': _("Branding text"),
+                    'description': _("Optional text displayed besides "
+                                     "brand image in navbar."),
+                    'value': "Misago",
+                    'field_extra': {
+                        'max_length': 255
+                    },
+                    'is_public': True,
                 },
                 },
-            }, )
+                {
+                    'setting':
+                        'email_footer',
+                    'name':
+                        _("E-mails footer"),
+                    'description':
+                        _(
+                            "Optional short message included "
+                            "at the end of e-mails sent by "
+                            "forum"
+                        ),
+                    'legend':
+                        _("Forum e-mails"),
+                    'field_extra': {
+                        'max_length': 255
+                    },
+                },
+            ],
         }
         }
     )
     )
 
 

+ 117 - 110
misago/legal/migrations/0001_initial.py

@@ -19,123 +19,130 @@ def create_legal_settings_group(apps, schema_editor):
             'description':
             'description':
                 _("Those settings allow you to set forum terms of "
                 _("Those settings allow you to set forum terms of "
                   "service and privacy policy"),
                   "service and privacy policy"),
-            'settings': ({
-                'setting': 'terms_of_service_title',
-                'name': _("Terms title"),
-                'legend': _("Terms of Service"),
-                'description': _("Leave this field empty to "
-                                 "use default title."),
-                'value': "",
-                'field_extra': {
-                    'max_length': 255,
-                    'required': False,
+            'settings': [
+                {
+                    'setting': 'terms_of_service_title',
+                    'name': _("Terms title"),
+                    'legend': _("Terms of Service"),
+                    'description': _("Leave this field empty to use default title."),
+                    'value': "",
+                    'field_extra': {
+                        'max_length': 255,
+                        'required': False,
+                    },
+                    'is_public': True,
                 },
                 },
-                'is_public': True,
-            }, {
-                'setting':
-                    'terms_of_service_link',
-                'name':
-                    _("Terms link"),
-                'description':
-                    _("If terms of service are located "
-                      "on other page, enter there its link."),
-                'value':
-                    "",
-                'field_extra': {
-                    'max_length': 255,
-                    'required': False,
+                {
+                    'setting':
+                        'terms_of_service_link',
+                    'name':
+                        _("Terms link"),
+                    'description':
+                        _(
+                            "If terms of service are located "
+                            "on other page, enter there its link."
+                        ),
+                    'value':
+                        "",
+                    'field_extra': {
+                        'max_length': 255,
+                        'required': False,
+                    },
+                    'is_public':
+                        True,
                 },
                 },
-                'is_public':
-                    True,
-            }, {
-                'setting':
-                    'terms_of_service',
-                'name':
-                    _("Terms contents"),
-                'description':
-                    _(
-                        "Your forums can have custom terms of "
-                        "service page. To create it, write or "
-                        "paste here its contents. Full Misago "
-                        "markup is available for formatting."
-                    ),
-                'value':
-                    "",
-                'form_field':
-                    'textarea',
-                'field_extra': {
-                    'max_length': 128000,
-                    'required': False,
-                    'rows': 8,
+                {
+                    'setting':
+                        'terms_of_service',
+                    'name':
+                        _("Terms contents"),
+                    'description':
+                        _(
+                            "Your forums can have custom terms of "
+                            "service page. To create it, write or "
+                            "paste here its contents. Full Misago "
+                            "markup is available for formatting."
+                        ),
+                    'value':
+                        "",
+                    'form_field':
+                        'textarea',
+                    'field_extra': {
+                        'max_length': 128000,
+                        'required': False,
+                        'rows': 8,
+                    },
+                    'is_public':
+                        True,
+                    'is_lazy':
+                        True,
                 },
                 },
-                'is_public':
-                    True,
-                'is_lazy':
-                    True,
-            }, {
-                'setting': 'privacy_policy_title',
-                'name': _("Policy title"),
-                'legend': _("Privacy policy"),
-                'description': _("Leave this field empty to "
-                                 "use default title."),
-                'value': "",
-                'field_extra': {
-                    'max_length': 255,
-                    'required': False,
+                {
+                    'setting': 'privacy_policy_title',
+                    'name': _("Policy title"),
+                    'legend': _("Privacy policy"),
+                    'description': _("Leave this field empty to use default title."),
+                    'value': "",
+                    'field_extra': {
+                        'max_length': 255,
+                        'required': False,
+                    },
+                    'is_public': True,
                 },
                 },
-                'is_public': True,
-            }, {
-                'setting':
-                    'privacy_policy_link',
-                'name':
-                    _("Policy link"),
-                'description':
-                    _("If privacy policy is located on "
-                      "other page, enter there its link."),
-                'value':
-                    "",
-                'field_extra': {
-                    'max_length': 255,
-                    'required': False,
+                {
+                    'setting':
+                        'privacy_policy_link',
+                    'name':
+                        _("Policy link"),
+                    'description':
+                        _("If privacy policy is located on "
+                          "other page, enter there its link."),
+                    'value':
+                        "",
+                    'field_extra': {
+                        'max_length': 255,
+                        'required': False,
+                    },
+                    'is_public':
+                        True,
                 },
                 },
-                'is_public':
-                    True,
-            }, {
-                'setting':
-                    'privacy_policy',
-                'name':
-                    _("Policy contents"),
-                'description':
-                    _(
-                        "Your forums can have custom privacy "
-                        "policy page. To create it, write or "
-                        "paste here its contents. Full Misago "
-                        "markup is available for formatting."
-                    ),
-                'value':
-                    "",
-                'form_field':
-                    'textarea',
-                'field_extra': {
-                    'max_length': 128000,
-                    'required': False,
-                    'rows': 8,
+                {
+                    'setting':
+                        'privacy_policy',
+                    'name':
+                        _("Policy contents"),
+                    'description':
+                        _(
+                            "Your forums can have custom privacy "
+                            "policy page. To create it, write or "
+                            "paste here its contents. Full Misago "
+                            "markup is available for formatting."
+                        ),
+                    'value':
+                        "",
+                    'form_field':
+                        'textarea',
+                    'field_extra': {
+                        'max_length': 128000,
+                        'required': False,
+                        'rows': 8,
+                    },
+                    'is_public':
+                        True,
+                    'is_lazy':
+                        True,
                 },
                 },
-                'is_public':
-                    True,
-                'is_lazy':
-                    True,
-            }, {
-                'setting': 'forum_footnote',
-                'name': _("Footnote"),
-                'description': _("Short message displayed "
-                                 "in forum footer."),
-                'legend': _("Forum footer"),
-                'field_extra': {
-                    'max_length': 300
+                {
+                    'setting': 'forum_footnote',
+                    'name': _("Footnote"),
+                    'description': _("Short message displayed in forum footer."),
+                    'legend': _("Forum footer"),
+                    'field_extra': {
+                        'max_length': 300
+                    },
+                    'is_public': True,
                 },
                 },
-                'is_public': True,
-            }, )
+            ],
         }
         }
     )
     )
 
 

+ 55 - 50
misago/threads/migrations/0002_threads_settings.py

@@ -18,60 +18,65 @@ def create_threads_settings_group(apps, schema_editor):
                 _("Threads"),
                 _("Threads"),
             'description':
             'description':
                 _("Those settings control threads and posts."),
                 _("Those settings control threads and posts."),
-            'settings': ({
-                'setting': 'thread_title_length_min',
-                'name': _("Minimum length"),
-                'description': _("Minimum allowed thread title length."),
-                'legend': _("Thread titles"),
-                'python_type': 'int',
-                'value': 5,
-                'field_extra': {
-                    'min_value': 2,
-                    'max_value': 255,
+            'settings': [
+                {
+                    'setting': 'thread_title_length_min',
+                    'name': _("Minimum length"),
+                    'description': _("Minimum allowed thread title length."),
+                    'legend': _("Thread titles"),
+                    'python_type': 'int',
+                    'value': 5,
+                    'field_extra': {
+                        'min_value': 2,
+                        'max_value': 255,
+                    },
+                    'is_public': True,
                 },
                 },
-                'is_public': True,
-            }, {
-                'setting': 'thread_title_length_max',
-                'name': _("Maximum length"),
-                'description': _("Maximum allowed thread length."),
-                'python_type': 'int',
-                'value': 90,
-                'field_extra': {
-                    'min_value': 2,
-                    'max_value': 255,
+                {
+                    'setting': 'thread_title_length_max',
+                    'name': _("Maximum length"),
+                    'description': _("Maximum allowed thread length."),
+                    'python_type': 'int',
+                    'value': 90,
+                    'field_extra': {
+                        'min_value': 2,
+                        'max_value': 255,
+                    },
+                    'is_public': True,
                 },
                 },
-                'is_public': True,
-            }, {
-                'setting': 'post_length_min',
-                'name': _("Minimum length"),
-                'description': _("Minimum allowed user post length."),
-                'legend': _("Posts"),
-                'python_type': 'int',
-                'value': 5,
-                'field_extra': {
-                    'min_value': 1,
+                {
+                    'setting': 'post_length_min',
+                    'name': _("Minimum length"),
+                    'description': _("Minimum allowed user post length."),
+                    'legend': _("Posts"),
+                    'python_type': 'int',
+                    'value': 5,
+                    'field_extra': {
+                        'min_value': 1,
+                    },
+                    'is_public': True,
                 },
                 },
-                'is_public': True,
-            }, {
-                'setting':
-                    'post_length_max',
-                'name':
-                    _("Maximum length"),
-                'description':
-                    _(
-                        "Maximum allowed user post length. Enter zero to disable. "
-                        "Longer posts are more costful to parse and index."
-                    ),
-                'python_type':
-                    'int',
-                'value':
-                    60000,
-                'field_extra': {
-                    'min_value': 0,
+                {
+                    'setting':
+                        'post_length_max',
+                    'name':
+                        _("Maximum length"),
+                    'description':
+                        _(
+                            "Maximum allowed user post length. Enter zero to disable. "
+                            "Longer posts are more costful to parse and index."
+                        ),
+                    'python_type':
+                        'int',
+                    'value':
+                        60000,
+                    'field_extra': {
+                        'min_value': 0,
+                    },
+                    'is_public':
+                        True,
                 },
                 },
-                'is_public':
-                    True,
-            }, )
+            ],
         }
         }
     )
     )
 
 

+ 55 - 50
misago/threads/migrations/0004_update_settings.py

@@ -18,60 +18,65 @@ def update_threads_settings(apps, schema_editor):
                 _("Threads"),
                 _("Threads"),
             'description':
             'description':
                 _("Those settings control threads and posts."),
                 _("Those settings control threads and posts."),
-            'settings': ({
-                'setting': 'thread_title_length_min',
-                'name': _("Minimum length"),
-                'description': _("Minimum allowed thread title length."),
-                'legend': _("Thread titles"),
-                'python_type': 'int',
-                'default_value': 5,
-                'field_extra': {
-                    'min_value': 2,
-                    'max_value': 255,
+            'settings': [
+                {
+                    'setting': 'thread_title_length_min',
+                    'name': _("Minimum length"),
+                    'description': _("Minimum allowed thread title length."),
+                    'legend': _("Thread titles"),
+                    'python_type': 'int',
+                    'default_value': 5,
+                    'field_extra': {
+                        'min_value': 2,
+                        'max_value': 255,
+                    },
+                    'is_public': True,
                 },
                 },
-                'is_public': True,
-            }, {
-                'setting': 'thread_title_length_max',
-                'name': _("Maximum length"),
-                'description': _("Maximum allowed thread length."),
-                'python_type': 'int',
-                'default_value': 90,
-                'field_extra': {
-                    'min_value': 2,
-                    'max_value': 255,
+                {
+                    'setting': 'thread_title_length_max',
+                    'name': _("Maximum length"),
+                    'description': _("Maximum allowed thread length."),
+                    'python_type': 'int',
+                    'default_value': 90,
+                    'field_extra': {
+                        'min_value': 2,
+                        'max_value': 255,
+                    },
+                    'is_public': True,
                 },
                 },
-                'is_public': True,
-            }, {
-                'setting': 'post_length_min',
-                'name': _("Minimum length"),
-                'description': _("Minimum allowed user post length."),
-                'legend': _("Posts"),
-                'python_type': 'int',
-                'default_value': 5,
-                'field_extra': {
-                    'min_value': 1,
+                {
+                    'setting': 'post_length_min',
+                    'name': _("Minimum length"),
+                    'description': _("Minimum allowed user post length."),
+                    'legend': _("Posts"),
+                    'python_type': 'int',
+                    'default_value': 5,
+                    'field_extra': {
+                        'min_value': 1,
+                    },
+                    'is_public': True,
                 },
                 },
-                'is_public': True,
-            }, {
-                'setting':
-                    'post_length_max',
-                'name':
-                    _("Maximum length"),
-                'description':
-                    _(
-                        "Maximum allowed user post length. Enter zero to disable. "
-                        "Longer posts are more costful to parse and index."
-                    ),
-                'python_type':
-                    'int',
-                'default_value':
-                    60000,
-                'field_extra': {
-                    'min_value': 0,
+                {
+                    'setting':
+                        'post_length_max',
+                    'name':
+                        _("Maximum length"),
+                    'description':
+                        _(
+                            "Maximum allowed user post length. Enter zero to disable. "
+                            "Longer posts are more costful to parse and index."
+                        ),
+                    'python_type':
+                        'int',
+                    'default_value':
+                        60000,
+                    'field_extra': {
+                        'min_value': 0,
+                    },
+                    'is_public':
+                        True,
                 },
                 },
-                'is_public':
-                    True,
-            }, )
+            ],
         }
         }
     )
     )
 
 

+ 0 - 1
misago/users/api/auth.py

@@ -50,7 +50,6 @@ def login(request):
         )
         )
 
 
 
 
-
 @api_view()
 @api_view()
 def session_user(request):
 def session_user(request):
     """GET /auth/ will return current auth user, either User or AnonymousUser"""
     """GET /auth/ will return current auth user, either User or AnonymousUser"""

+ 23 - 7
misago/users/forms/admin.py

@@ -327,11 +327,17 @@ def SearchUsersForm(*args, **kwargs):
     extra_fields = {
     extra_fields = {
         'rank':
         'rank':
             forms.TypedChoiceField(
             forms.TypedChoiceField(
-                label=_("Has rank"), coerce=int, required=False, choices=ranks_choices,
+                label=_("Has rank"),
+                coerce=int,
+                required=False,
+                choices=ranks_choices,
             ),
             ),
         'role':
         'role':
             forms.TypedChoiceField(
             forms.TypedChoiceField(
-                label=_("Has role"), coerce=int, required=False, choices=roles_choices,
+                label=_("Has role"),
+                coerce=int,
+                required=False,
+                choices=roles_choices,
             )
             )
     }
     }
 
 
@@ -432,7 +438,9 @@ class BanUsersForm(forms.Form):
         max_length=1000,
         max_length=1000,
         help_text=_("Optional message displayed to users instead of default one."),
         help_text=_("Optional message displayed to users instead of default one."),
         widget=forms.Textarea(attrs={'rows': 3}),
         widget=forms.Textarea(attrs={'rows': 3}),
-        error_messages={'max_length': _("Message can't be longer than 1000 characters."),}
+        error_messages={
+            'max_length': _("Message can't be longer than 1000 characters."),
+        }
     )
     )
     staff_message = forms.CharField(
     staff_message = forms.CharField(
         label=_("Team message"),
         label=_("Team message"),
@@ -440,7 +448,9 @@ class BanUsersForm(forms.Form):
         max_length=1000,
         max_length=1000,
         help_text=_("Optional ban message for moderators and administrators."),
         help_text=_("Optional ban message for moderators and administrators."),
         widget=forms.Textarea(attrs={'rows': 3}),
         widget=forms.Textarea(attrs={'rows': 3}),
-        error_messages={'max_length': _("Message can't be longer than 1000 characters."),}
+        error_messages={
+            'max_length': _("Message can't be longer than 1000 characters."),
+        }
     )
     )
     expires_on = IsoDateTimeField(
     expires_on = IsoDateTimeField(
         label=_("Expires on"),
         label=_("Expires on"),
@@ -459,7 +469,9 @@ class BanForm(forms.ModelForm):
             'for rought matches. For example, making IP ban for value '
             'for rought matches. For example, making IP ban for value '
             '"83.*" will ban all IP addresses beginning with "83.".'
             '"83.*" will ban all IP addresses beginning with "83.".'
         ),
         ),
-        error_messages={'max_length': _("Banned value can't be longer than 250 characters."),}
+        error_messages={
+            'max_length': _("Banned value can't be longer than 250 characters."),
+        }
     )
     )
     user_message = forms.CharField(
     user_message = forms.CharField(
         label=_("User message"),
         label=_("User message"),
@@ -467,7 +479,9 @@ class BanForm(forms.ModelForm):
         max_length=1000,
         max_length=1000,
         help_text=_("Optional message displayed to user instead of default one."),
         help_text=_("Optional message displayed to user instead of default one."),
         widget=forms.Textarea(attrs={'rows': 3}),
         widget=forms.Textarea(attrs={'rows': 3}),
-        error_messages={'max_length': _("Message can't be longer than 1000 characters."),}
+        error_messages={
+            'max_length': _("Message can't be longer than 1000 characters."),
+        }
     )
     )
     staff_message = forms.CharField(
     staff_message = forms.CharField(
         label=_("Team message"),
         label=_("Team message"),
@@ -475,7 +489,9 @@ class BanForm(forms.ModelForm):
         max_length=1000,
         max_length=1000,
         help_text=_("Optional ban message for moderators and administrators."),
         help_text=_("Optional ban message for moderators and administrators."),
         widget=forms.Textarea(attrs={'rows': 3}),
         widget=forms.Textarea(attrs={'rows': 3}),
-        error_messages={'max_length': _("Message can't be longer than 1000 characters."),}
+        error_messages={
+            'max_length': _("Message can't be longer than 1000 characters."),
+        }
     )
     )
     expires_on = IsoDateTimeField(
     expires_on = IsoDateTimeField(
         label=_("Expires on"),
         label=_("Expires on"),

+ 240 - 199
misago/users/migrations/0002_users_settings.py

@@ -20,157 +20,188 @@ def create_users_settings_group(apps, schema_editor):
                 _(
                 _(
                     "Those settings control user accounts default behaviour and features availability."
                     "Those settings control user accounts default behaviour and features availability."
                 ),
                 ),
-            'settings': ({
-                'setting': 'account_activation',
-                'name': _("New accounts activation"),
-                'legend': _("New accounts"),
-                'value': 'none',
-                'form_field': 'select',
-                'field_extra': {
-                    'choices': (('none', _("No activation required")),
-                                ('user', _("Activation token sent to User")),
-                                ('admin', _("Activation by administrator")),
-                                ('closed', _("Don't allow new registrations")))
+            'settings': [
+                {
+                    'setting': 'account_activation',
+                    'name': _("New accounts activation"),
+                    'legend': _("New accounts"),
+                    'value': 'none',
+                    'form_field': 'select',
+                    'field_extra': {
+                        'choices': [
+                            ('none', _("No activation required")),
+                            ('user', _("Activation token sent to User")),
+                            ('admin', _("Activation by administrator")),
+                            ('closed', _("Don't allow new registrations")),
+                        ],
+                    },
+                    'is_public': True,
                 },
                 },
-                'is_public': True,
-            }, {
-                'setting': 'username_length_min',
-                'name': _("Minimum length"),
-                'description': _("Minimum allowed username length."),
-                'legend': _("User names"),
-                'python_type': 'int',
-                'value': 3,
-                'field_extra': {
-                    'min_value': 2,
-                    'max_value': 20,
+                {
+                    'setting': 'username_length_min',
+                    'name': _("Minimum length"),
+                    'description': _("Minimum allowed username length."),
+                    'legend': _("User names"),
+                    'python_type': 'int',
+                    'value': 3,
+                    'field_extra': {
+                        'min_value': 2,
+                        'max_value': 20,
+                    },
+                    'is_public': True,
                 },
                 },
-                'is_public': True,
-            }, {
-                'setting': 'username_length_max',
-                'name': _("Maximum length"),
-                'description': _("Maximum allowed username length."),
-                'python_type': 'int',
-                'value': 14,
-                'field_extra': {
-                    'min_value': 2,
-                    'max_value': 20,
+                {
+                    'setting': 'username_length_max',
+                    'name': _("Maximum length"),
+                    'description': _("Maximum allowed username length."),
+                    'python_type': 'int',
+                    'value': 14,
+                    'field_extra': {
+                        'min_value': 2,
+                        'max_value': 20,
+                    },
+                    'is_public': True,
                 },
                 },
-                'is_public': True,
-            }, {
-                'setting': 'password_length_min',
-                'name': _("Minimum length"),
-                'description': _("Minimum allowed user password length."),
-                'legend': _("Passwords"),
-                'python_type': 'int',
-                'value': 5,
-                'field_extra': {
-                    'min_value': 2,
-                    'max_value': 255,
+                {
+                    'setting': 'password_length_min',
+                    'name': _("Minimum length"),
+                    'description': _("Minimum allowed user password length."),
+                    'legend': _("Passwords"),
+                    'python_type': 'int',
+                    'value': 5,
+                    'field_extra': {
+                        'min_value': 2,
+                        'max_value': 255,
+                    },
+                    'is_public': True,
                 },
                 },
-                'is_public': True,
-            }, {
-                'setting':
-                    'allow_custom_avatars',
-                'name':
-                    _("Allow custom avatars"),
-                'legend':
-                    _("Avatars"),
-                'description':
-                    _(
-                        "Turning this option off will forbid "
-                        "forum users from using avatars from "
-                        "outside forums. Good for forums "
-                        "adressed at young users."
-                    ),
-                'python_type':
-                    'bool',
-                'value':
-                    True,
-                'form_field':
-                    'yesno',
-            }, {
-                'setting': 'default_avatar',
-                'name': _("Default avatar"),
-                'value': 'gravatar',
-                'form_field': 'select',
-                'field_extra': {
-                    'choices': (('dynamic', _("Individual")), ('gravatar', _("Gravatar")),
-                                ('gallery', _("Random avatar from gallery")), ),
+                {
+                    'setting':
+                        'allow_custom_avatars',
+                    'name':
+                        _("Allow custom avatars"),
+                    'legend':
+                        _("Avatars"),
+                    'description':
+                        _(
+                            "Turning this option off will forbid "
+                            "forum users from using avatars from "
+                            "outside forums. Good for forums "
+                            "adressed at young users."
+                        ),
+                    'python_type':
+                        'bool',
+                    'value':
+                        True,
+                    'form_field':
+                        'yesno',
                 },
                 },
-            }, {
-                'setting':
-                    'default_gravatar_fallback',
-                'name':
-                    _("Fallback for default gravatar"),
-                'description':
-                    _(
-                        "Select which avatar to use when user "
-                        "has no gravatar associated with his "
-                        "e-mail address."
-                    ),
-                'value':
-                    'dynamic',
-                'form_field':
-                    'select',
-                'field_extra': {
-                    'choices': (('dynamic', _("Individual")),
-                                ('gallery', _("Random avatar from gallery")), ),
+                {
+                    'setting': 'default_avatar',
+                    'name': _("Default avatar"),
+                    'value': 'gravatar',
+                    'form_field': 'select',
+                    'field_extra': {
+                        'choices': [
+                            ('dynamic', _("Individual")),
+                            ('gravatar', _("Gravatar")),
+                            ('gallery', _("Random avatar from gallery")),
+                        ],
+                    },
                 },
                 },
-            }, {
-                'setting': 'avatar_upload_limit',
-                'name': _("Maximum size of uploaded avatar"),
-                'description': _("Enter maximum allowed file size "
-                                 "(in KB) for avatar uploads"),
-                'python_type': 'int',
-                'value': 1536,
-                'field_extra': {
-                    'min_value': 0,
+                {
+                    'setting':
+                        'default_gravatar_fallback',
+                    'name':
+                        _("Fallback for default gravatar"),
+                    'description':
+                        _(
+                            "Select which avatar to use when user "
+                            "has no gravatar associated with his "
+                            "e-mail address."
+                        ),
+                    'value':
+                        'dynamic',
+                    'form_field':
+                        'select',
+                    'field_extra': {
+                        'choices': [
+                            ('dynamic', _("Individual")),
+                            ('gallery', _("Random avatar from gallery")),
+                        ],
+                    },
                 },
                 },
-                'is_public': True,
-            }, {
-                'setting': 'signature_length_max',
-                'name': _("Maximum length"),
-                'legend': _("Signatures"),
-                'description': _("Maximum allowed signature length."),
-                'python_type': 'int',
-                'value': 256,
-                'field_extra': {
-                    'min_value': 10,
-                    'max_value': 5000,
+                {
+                    'setting':
+                        'avatar_upload_limit',
+                    'name':
+                        _("Maximum size of uploaded avatar"),
+                    'description':
+                        _("Enter maximum allowed file size "
+                          "(in KB) for avatar uploads"),
+                    'python_type':
+                        'int',
+                    'value':
+                        1536,
+                    'field_extra': {
+                        'min_value': 0,
+                    },
+                    'is_public':
+                        True,
                 },
                 },
-                'is_public': True,
-            }, {
-                'setting': 'subscribe_start',
-                'name': _("Started threads"),
-                'legend': _("Default subscriptions settings"),
-                'value': 'watch_email',
-                'form_field': 'select',
-                'field_extra': {
-                    'choices': (('no', _("Don't watch")),
-                                ('watch', _("Put on watched threads list")), (
-                                    'watch_email', _(
-                                        "Put on watched threads "
-                                        "list and e-mail user when "
-                                        "somebody replies"
-                                    )
-                                ), ),
+                {
+                    'setting': 'signature_length_max',
+                    'name': _("Maximum length"),
+                    'legend': _("Signatures"),
+                    'description': _("Maximum allowed signature length."),
+                    'python_type': 'int',
+                    'value': 256,
+                    'field_extra': {
+                        'min_value': 10,
+                        'max_value': 5000,
+                    },
+                    'is_public': True,
                 },
                 },
-            }, {
-                'setting': 'subscribe_reply',
-                'name': _("Replied threads"),
-                'value': 'watch_email',
-                'form_field': 'select',
-                'field_extra': {
-                    'choices': (('no', _("Don't watch")),
-                                ('watch', _("Put on watched threads list")), (
-                                    'watch_email', _(
-                                        "Put on watched threads "
-                                        "list and e-mail user when "
-                                        "somebody replies"
-                                    )
-                                ), ),
+                {
+                    'setting': 'subscribe_start',
+                    'name': _("Started threads"),
+                    'legend': _("Default subscriptions settings"),
+                    'value': 'watch_email',
+                    'form_field': 'select',
+                    'field_extra': {
+                        'choices': [
+                            ('no', _("Don't watch")),
+                            ('watch', _("Put on watched threads list")),
+                            (
+                                'watch_email', _(
+                                    "Put on watched threads "
+                                    "list and e-mail user when "
+                                    "somebody replies"
+                                )
+                            ),
+                        ],
+                    },
                 },
                 },
-            }, )
+                {
+                    'setting': 'subscribe_reply',
+                    'name': _("Replied threads"),
+                    'value': 'watch_email',
+                    'form_field': 'select',
+                    'field_extra': {
+                        'choices': [
+                            ('no', _("Don't watch")),
+                            ('watch', _("Put on watched threads list")),
+                            (
+                                'watch_email', _(
+                                    "Put on watched threads "
+                                    "list and e-mail user when "
+                                    "somebody replies"
+                                )
+                            ),
+                        ],
+                    },
+                },
+            ],
         }
         }
     )
     )
 
 
@@ -183,70 +214,80 @@ def create_users_settings_group(apps, schema_editor):
             'description':
             'description':
                 _("Those settings allow you to combat automatic "
                 _("Those settings allow you to combat automatic "
                   "registrations on your forum."),
                   "registrations on your forum."),
-            'settings': ({
-                'setting': 'captcha_type',
-                'name': _("Select CAPTCHA type"),
-                'legend': _("CAPTCHA type"),
-                'value': 'no',
-                'form_field': 'select',
-                'field_extra': {
-                    'choices': (('no', _("No CAPTCHA")), ('re', _("reCaptcha")),
-                                ('qa', _("Question and answer")), ),
+            'settings': [
+                {
+                    'setting': 'captcha_type',
+                    'name': _("Select CAPTCHA type"),
+                    'legend': _("CAPTCHA type"),
+                    'value': 'no',
+                    'form_field': 'select',
+                    'field_extra': {
+                        'choices': [
+                            ('no', _("No CAPTCHA")),
+                            ('re', _("reCaptcha")),
+                            ('qa', _("Question and answer")),
+                        ],
+                    },
+                    'is_public': True,
                 },
                 },
-                'is_public': True,
-            }, {
-                'setting': 'recaptcha_site_key',
-                'name': _("Site key"),
-                'legend': _("reCAPTCHA"),
-                'value': '',
-                'field_extra': {
-                    'required': False,
-                    'max_length': 100,
+                {
+                    'setting': 'recaptcha_site_key',
+                    'name': _("Site key"),
+                    'legend': _("reCAPTCHA"),
+                    'value': '',
+                    'field_extra': {
+                        'required': False,
+                        'max_length': 100,
+                    },
+                    'is_public': True,
                 },
                 },
-                'is_public': True,
-            }, {
-                'setting': 'recaptcha_secret_key',
-                'name': _("Secret key"),
-                'value': '',
-                'field_extra': {
-                    'required': False,
-                    'max_length': 100,
+                {
+                    'setting': 'recaptcha_secret_key',
+                    'name': _("Secret key"),
+                    'value': '',
+                    'field_extra': {
+                        'required': False,
+                        'max_length': 100,
+                    },
                 },
                 },
-            }, {
-                'setting': 'qa_question',
-                'name': _("Test question"),
-                'legend': _("Question and answer"),
-                'value': '',
-                'field_extra': {
-                    'required': False,
-                    'max_length': 250,
+                {
+                    'setting': 'qa_question',
+                    'name': _("Test question"),
+                    'legend': _("Question and answer"),
+                    'value': '',
+                    'field_extra': {
+                        'required': False,
+                        'max_length': 250,
+                    },
                 },
                 },
-            }, {
-                'setting': 'qa_help_text',
-                'name': _("Question help text"),
-                'value': '',
-                'field_extra': {
-                    'required': False,
-                    'max_length': 250,
+                {
+                    'setting': 'qa_help_text',
+                    'name': _("Question help text"),
+                    'value': '',
+                    'field_extra': {
+                        'required': False,
+                        'max_length': 250,
+                    },
                 },
                 },
-            }, {
-                'setting':
-                    'qa_answers',
-                'name':
-                    _("Valid answers"),
-                'description':
-                    _("Enter each answer in new line. "
-                      "Answers are case-insensitive."),
-                'value':
-                    '',
-                'form_field':
-                    'textarea',
-                'field_extra': {
-                    'rows': 4,
-                    'required': False,
-                    'max_length': 250,
+                {
+                    'setting':
+                        'qa_answers',
+                    'name':
+                        _("Valid answers"),
+                    'description':
+                        _("Enter each answer in new line. "
+                          "Answers are case-insensitive."),
+                    'value':
+                        '',
+                    'form_field':
+                        'textarea',
+                    'field_extra': {
+                        'rows': 4,
+                        'required': False,
+                        'max_length': 250,
+                    },
                 },
                 },
-            }, )
+            ],
         }
         }
     )
     )
 
 

+ 158 - 128
misago/users/migrations/0006_update_settings.py

@@ -21,143 +21,173 @@ def update_users_settings(apps, schema_editor):
                 _(
                 _(
                     "Those settings control user accounts default behaviour and features availability."
                     "Those settings control user accounts default behaviour and features availability."
                 ),
                 ),
-            'settings': ({
-                'setting': 'account_activation',
-                'name': _("New accounts activation"),
-                'legend': _("New accounts"),
-                'value': 'none',
-                'form_field': 'select',
-                'field_extra': {
-                    'choices': (('none', _("No activation required")),
-                                ('user', _("Activation token sent to User")),
-                                ('admin', _("Activation by administrator")),
-                                ('closed', _("Don't allow new registrations")))
+            'settings': [
+                {
+                    'setting': 'account_activation',
+                    'name': _("New accounts activation"),
+                    'legend': _("New accounts"),
+                    'value': 'none',
+                    'form_field': 'select',
+                    'field_extra': {
+                        'choices': [
+                            ('none', _("No activation required")),
+                            ('user', _("Activation token sent to User")),
+                            ('admin', _("Activation by administrator")),
+                            ('closed', _("Don't allow new registrations")),
+                        ],
+                    },
+                    'is_public': True,
                 },
                 },
-                'is_public': True,
-            }, {
-                'setting': 'username_length_min',
-                'name': _("Minimum length"),
-                'description': _("Minimum allowed username length."),
-                'legend': _("User names"),
-                'python_type': 'int',
-                'default_value': 3,
-                'field_extra': {
-                    'min_value': 2,
-                    'max_value': 20,
+                {
+                    'setting': 'username_length_min',
+                    'name': _("Minimum length"),
+                    'description': _("Minimum allowed username length."),
+                    'legend': _("User names"),
+                    'python_type': 'int',
+                    'default_value': 3,
+                    'field_extra': {
+                        'min_value': 2,
+                        'max_value': 20,
+                    },
                 },
                 },
-            }, {
-                'setting': 'username_length_max',
-                'name': _("Maximum length"),
-                'description': _("Maximum allowed username length."),
-                'python_type': 'int',
-                'default_value': 14,
-                'field_extra': {
-                    'min_value': 2,
-                    'max_value': 20,
+                {
+                    'setting': 'username_length_max',
+                    'name': _("Maximum length"),
+                    'description': _("Maximum allowed username length."),
+                    'python_type': 'int',
+                    'default_value': 14,
+                    'field_extra': {
+                        'min_value': 2,
+                        'max_value': 20,
+                    },
                 },
                 },
-            }, {
-                'setting':
-                    'allow_custom_avatars',
-                'name':
-                    _("Allow custom avatars"),
-                'legend':
-                    _("Avatars"),
-                'description':
-                    _(
-                        "Turning this option off will forbid "
-                        "forum users from using avatars from "
-                        "outside forums. Good for forums "
-                        "adressed at young users."
-                    ),
-                'python_type':
-                    'bool',
-                'value':
-                    True,
-                'form_field':
-                    'yesno',
-            }, {
-                'setting': 'default_avatar',
-                'name': _("Default avatar"),
-                'value': 'gravatar',
-                'form_field': 'select',
-                'field_extra': {
-                    'choices': (('dynamic', _("Individual")), ('gravatar', _("Gravatar")),
-                                ('gallery', _("Random avatar from gallery")), ),
+                {
+                    'setting':
+                        'allow_custom_avatars',
+                    'name':
+                        _("Allow custom avatars"),
+                    'legend':
+                        _("Avatars"),
+                    'description':
+                        _(
+                            "Turning this option off will forbid "
+                            "forum users from using avatars from "
+                            "outside forums. Good for forums "
+                            "adressed at young users."
+                        ),
+                    'python_type':
+                        'bool',
+                    'value':
+                        True,
+                    'form_field':
+                        'yesno',
                 },
                 },
-            }, {
-                'setting':
-                    'default_gravatar_fallback',
-                'name':
-                    _("Fallback for default gravatar"),
-                'description':
-                    _(
-                        "Select which avatar to use when user "
-                        "has no gravatar associated with his "
-                        "e-mail address."
-                    ),
-                'value':
-                    'dynamic',
-                'form_field':
-                    'select',
-                'field_extra': {
-                    'choices': (('dynamic', _("Individual")),
-                                ('gallery', _("Random avatar from gallery")), ),
+                {
+                    'setting': 'default_avatar',
+                    'name': _("Default avatar"),
+                    'value': 'gravatar',
+                    'form_field': 'select',
+                    'field_extra': {
+                        'choices': [
+                            ('dynamic', _("Individual")),
+                            ('gravatar', _("Gravatar")),
+                            ('gallery', _("Random avatar from gallery")),
+                        ],
+                    },
                 },
                 },
-            }, {
-                'setting': 'avatar_upload_limit',
-                'name': _("Maximum size of uploaded avatar"),
-                'description': _("Enter maximum allowed file size "
-                                 "(in KB) for avatar uploads"),
-                'python_type': 'int',
-                'default_value': 1536,
-                'field_extra': {
-                    'min_value': 0,
+                {
+                    'setting':
+                        'default_gravatar_fallback',
+                    'name':
+                        _("Fallback for default gravatar"),
+                    'description':
+                        _(
+                            "Select which avatar to use when user "
+                            "has no gravatar associated with his "
+                            "e-mail address."
+                        ),
+                    'value':
+                        'dynamic',
+                    'form_field':
+                        'select',
+                    'field_extra': {
+                        'choices': [
+                            ('dynamic', _("Individual")),
+                            ('gallery', _("Random avatar from gallery")),
+                        ],
+                    },
                 },
                 },
-                'is_public': True,
-            }, {
-                'setting': 'signature_length_max',
-                'name': _("Maximum length"),
-                'legend': _("Signatures"),
-                'description': _("Maximum allowed signature length."),
-                'python_type': 'int',
-                'default_value': 256,
-                'field_extra': {
-                    'min_value': 10,
-                    'max_value': 5000,
+                {
+                    'setting':
+                        'avatar_upload_limit',
+                    'name':
+                        _("Maximum size of uploaded avatar"),
+                    'description':
+                        _("Enter maximum allowed file size "
+                          "(in KB) for avatar uploads"),
+                    'python_type':
+                        'int',
+                    'default_value':
+                        1536,
+                    'field_extra': {
+                        'min_value': 0,
+                    },
+                    'is_public':
+                        True,
                 },
                 },
-                'is_public': True,
-            }, {
-                'setting': 'subscribe_start',
-                'name': _("Started threads"),
-                'legend': _("Default subscriptions settings"),
-                'value': 'watch_email',
-                'form_field': 'select',
-                'field_extra': {
-                    'choices': (('no', _("Don't watch")),
-                                ('watch', _("Put on watched threads list")), (
-                                    'watch_email', _(
-                                        "Put on watched threads "
-                                        "list and e-mail user when "
-                                        "somebody replies"
-                                    )
-                                ), ),
+                {
+                    'setting': 'signature_length_max',
+                    'name': _("Maximum length"),
+                    'legend': _("Signatures"),
+                    'description': _("Maximum allowed signature length."),
+                    'python_type': 'int',
+                    'default_value': 256,
+                    'field_extra': {
+                        'min_value': 10,
+                        'max_value': 5000,
+                    },
+                    'is_public': True,
                 },
                 },
-            }, {
-                'setting': 'subscribe_reply',
-                'name': _("Replied threads"),
-                'value': 'watch_email',
-                'form_field': 'select',
-                'field_extra': {
-                    'choices': (('no', _("Don't watch")),
-                                ('watch', _("Put on watched threads list")), (
-                                    'watch_email', _(
-                                        "Put on watched threads "
-                                        "list and e-mail user when "
-                                        "somebody replies"
-                                    )
-                                ), ),
+                {
+                    'setting': 'subscribe_start',
+                    'name': _("Started threads"),
+                    'legend': _("Default subscriptions settings"),
+                    'value': 'watch_email',
+                    'form_field': 'select',
+                    'field_extra': {
+                        'choices': [
+                            ('no', _("Don't watch")),
+                            ('watch', _("Put on watched threads list")),
+                            (
+                                'watch_email', _(
+                                    "Put on watched threads "
+                                    "list and e-mail user when "
+                                    "somebody replies"
+                                )
+                            ),
+                        ],
+                    },
                 },
                 },
-            }, )
+                {
+                    'setting': 'subscribe_reply',
+                    'name': _("Replied threads"),
+                    'value': 'watch_email',
+                    'form_field': 'select',
+                    'field_extra': {
+                        'choices': [
+                            ('no', _("Don't watch")),
+                            ('watch', _("Put on watched threads list")),
+                            (
+                                'watch_email', _(
+                                    "Put on watched threads "
+                                    "list and e-mail user when "
+                                    "somebody replies"
+                                )
+                            ),
+                        ],
+                    },
+                },
+            ],
         }
         }
     )
     )
 
 

+ 0 - 1
misago/users/permissions/profiles.py

@@ -22,7 +22,6 @@ __all__ = [
     'can_see_ban_details',
     'can_see_ban_details',
 ]
 ]
 
 
-
 CAN_BROWSE_USERS_LIST = YesNoSwitch(label=_("Can browse users list"), initial=1)
 CAN_BROWSE_USERS_LIST = YesNoSwitch(label=_("Can browse users list"), initial=1)
 CAN_SEARCH_USERS = YesNoSwitch(label=_("Can search user profiles"), initial=1)
 CAN_SEARCH_USERS = YesNoSwitch(label=_("Can search user profiles"), initial=1)
 CAN_SEE_USER_NAME_HISTORY = YesNoSwitch(label=_("Can see other members name history"))
 CAN_SEE_USER_NAME_HISTORY = YesNoSwitch(label=_("Can see other members name history"))

+ 5 - 2
misago/users/serializers/auth.py

@@ -32,8 +32,11 @@ class AuthenticatedUserSerializer(UserSerializer, AuthFlags):
     class Meta:
     class Meta:
         model = UserModel
         model = UserModel
         fields = UserSerializer.Meta.fields + [
         fields = UserSerializer.Meta.fields + [
-            'is_hiding_presence', 'limits_private_thread_invites_to',
-            'subscribe_to_started_threads', 'subscribe_to_replied_threads', 'is_authenticated',
+            'is_hiding_presence',
+            'limits_private_thread_invites_to',
+            'subscribe_to_started_threads',
+            'subscribe_to_replied_threads',
+            'is_authenticated',
             'is_anonymous',
             'is_anonymous',
         ]
         ]
 
 

+ 20 - 10
misago/users/serializers/user.py

@@ -107,16 +107,26 @@ class UserSerializer(serializers.ModelSerializer, MutableFields):
 
 
     def get_api_url(self, obj):
     def get_api_url(self, obj):
         return {
         return {
-            'root': reverse('misago:api:user-detail', kwargs={'pk': obj.pk}),
-            'follow': reverse('misago:api:user-follow', kwargs={'pk': obj.pk}),
-            'ban': reverse('misago:api:user-ban', kwargs={'pk': obj.pk}),
-            'moderate_avatar': reverse('misago:api:user-moderate-avatar', kwargs={'pk': obj.pk}),
-            'moderate_username': reverse('misago:api:user-moderate-username', kwargs={'pk': obj.pk}),
-            'delete': reverse('misago:api:user-delete', kwargs={'pk': obj.pk}),
-            'followers': reverse('misago:api:user-followers', kwargs={'pk': obj.pk}),
-            'follows': reverse('misago:api:user-follows', kwargs={'pk': obj.pk}),
-            'threads': reverse('misago:api:user-threads', kwargs={'pk': obj.pk}),
-            'posts':  reverse('misago:api:user-posts', kwargs={'pk': obj.pk}),
+            'root':
+                reverse('misago:api:user-detail', kwargs={'pk': obj.pk}),
+            'follow':
+                reverse('misago:api:user-follow', kwargs={'pk': obj.pk}),
+            'ban':
+                reverse('misago:api:user-ban', kwargs={'pk': obj.pk}),
+            'moderate_avatar':
+                reverse('misago:api:user-moderate-avatar', kwargs={'pk': obj.pk}),
+            'moderate_username':
+                reverse('misago:api:user-moderate-username', kwargs={'pk': obj.pk}),
+            'delete':
+                reverse('misago:api:user-delete', kwargs={'pk': obj.pk}),
+            'followers':
+                reverse('misago:api:user-followers', kwargs={'pk': obj.pk}),
+            'follows':
+                reverse('misago:api:user-follows', kwargs={'pk': obj.pk}),
+            'threads':
+                reverse('misago:api:user-threads', kwargs={'pk': obj.pk}),
+            'posts':
+                reverse('misago:api:user-posts', kwargs={'pk': obj.pk}),
         }
         }