Browse Source

fix #384: pm's preference setting

Rafał Pitoń 10 years ago
parent
commit
2b36924447

+ 1 - 1
misago/conf/defaults.py

@@ -181,8 +181,8 @@ MISAGO_ACL_EXTENSIONS = (
     'misago.users.permissions.moderation',
     'misago.users.permissions.moderation',
     'misago.users.permissions.delete',
     'misago.users.permissions.delete',
     'misago.forums.permissions',
     'misago.forums.permissions',
-    'misago.threads.permissions.privatethreads',
     'misago.threads.permissions.threads',
     'misago.threads.permissions.threads',
+    'misago.threads.permissions.privatethreads',
 )
 )
 
 
 MISAGO_MARKUP_EXTENSIONS = ()
 MISAGO_MARKUP_EXTENSIONS = ()

+ 15 - 0
misago/templates/misago/admin/users/edit.html

@@ -68,6 +68,21 @@ class="form-horizontal"
     {% form_row form.signature_lock_staff_message label_class field_class %}
     {% form_row form.signature_lock_staff_message label_class field_class %}
 
 
   </fieldset>
   </fieldset>
+  <fieldset>
+    <legend>{% trans "Forum options" %}</legend>
+
+    {% form_row form.is_hiding_presence label_class field_class %}
+    {% form_row form.limits_private_thread_invites_to label_class field_class %}
+    {% form_row form.timezone label_class field_class %}
+
+  </fieldset>
+  <fieldset>
+    <legend>{% trans "Automatic subscription preferences" %}</legend>
+
+    {% form_row form.subscribe_to_started_threads label_class field_class %}
+    {% form_row form.subscribe_to_replied_threads label_class field_class %}
+
+  </fieldset>
   {% endwith %}
   {% endwith %}
 </div>
 </div>
 {% endblock form-body %}
 {% endblock form-body %}

+ 1 - 0
misago/templates/misago/usercp/change_forum_options.html

@@ -21,6 +21,7 @@
       <fieldset>
       <fieldset>
         <legend>{% trans "Forum options" %}</legend>
         <legend>{% trans "Forum options" %}</legend>
 
 
+        {% form_row form.limits_private_thread_invites_to label_class field_class %}
         {% form_row form.is_hiding_presence label_class field_class %}
         {% form_row form.is_hiding_presence label_class field_class %}
         {% form_row form.timezone label_class field_class %}
         {% form_row form.timezone label_class field_class %}
 
 

+ 3 - 1
misago/threads/permissions/privatethreads.py

@@ -59,7 +59,7 @@ def build_acl(acl, roles, key_name):
 
 
     new_acl.update(acl)
     new_acl.update(acl)
 
 
-    acl = algebra.sum_acls(new_acl, roles=roles, key=key_name,
+    algebra.sum_acls(new_acl, roles=roles, key=key_name,
         can_use_private_threads=algebra.greater,
         can_use_private_threads=algebra.greater,
         can_start_private_threads=algebra.greater,
         can_start_private_threads=algebra.greater,
         max_private_thread_participants=algebra.greater_or_zero,
         max_private_thread_participants=algebra.greater_or_zero,
@@ -67,3 +67,5 @@ def build_acl(acl, roles, key_name):
         can_report_private_threads=algebra.greater,
         can_report_private_threads=algebra.greater,
         can_moderate_private_threads=algebra.greater
         can_moderate_private_threads=algebra.greater
     )
     )
+
+    return new_acl

+ 27 - 3
misago/users/forms/admin.py

@@ -2,11 +2,13 @@ from django.contrib.auth import get_user_model
 from django.utils.translation import ugettext_lazy as _, ungettext
 from django.utils.translation import ugettext_lazy as _, ungettext
 
 
 from misago.conf import settings
 from misago.conf import settings
-from misago.core import forms, threadstore
+from misago.core import forms, threadstore, timezones
 from misago.core.validators import validate_sluggable
 from misago.core.validators import validate_sluggable
 from misago.acl.models import Role
 from misago.acl.models import Role
 
 
-from misago.users.models import (BANS_CHOICES, RESTRICTIONS_CHOICES,
+from misago.users.models import (AUTO_SUBSCRIBE_CHOICES,
+                                 PRIVATE_THREAD_INVITES_LIMITS_CHOICES,
+                                 BANS_CHOICES, RESTRICTIONS_CHOICES,
                                  Ban, Rank, WarningLevel)
                                  Ban, Rank, WarningLevel)
 from misago.users.validators import (validate_username, validate_email,
 from misago.users.validators import (validate_username, validate_email,
                                      validate_password)
                                      validate_password)
@@ -110,6 +112,18 @@ class EditUserForm(UserBaseForm):
         widget=forms.Textarea(attrs={'rows': 3}),
         widget=forms.Textarea(attrs={'rows': 3}),
         required=False)
         required=False)
 
 
+    is_hiding_presence = forms.YesNoSwitch(label=_("Hides presence"))
+    limits_private_thread_invites_to = forms.TypedChoiceField(
+        label=_("Who can add user to private threads"),
+        coerce=int,
+        choices=PRIVATE_THREAD_INVITES_LIMITS_CHOICES)
+
+    subscribe_to_started_threads = forms.TypedChoiceField(
+        label=_("Started threads"), coerce=int, choices=AUTO_SUBSCRIBE_CHOICES)
+    subscribe_to_replied_threads = forms.TypedChoiceField(
+        label=_("Replid threads"), coerce=int,
+        choices=AUTO_SUBSCRIBE_CHOICES)
+
     class Meta:
     class Meta:
         model = get_user_model()
         model = get_user_model()
         fields = [
         fields = [
@@ -121,8 +135,14 @@ class EditUserForm(UserBaseForm):
             'avatar_lock_staff_message',
             'avatar_lock_staff_message',
             'signature',
             'signature',
             'is_signature_locked',
             'is_signature_locked',
+            'timezone',
+            'is_hiding_presence',
+            'limits_private_thread_invites_to',
             'signature_lock_user_message',
             'signature_lock_user_message',
-            'signature_lock_staff_message'
+            'signature_lock_staff_message',
+            'subscribe_to_started_threads',
+            'subscribe_to_replied_threads'
+
         ]
         ]
 
 
     def clean_signature(self):
     def clean_signature(self):
@@ -158,6 +178,10 @@ def UserFormFactory(FormType, instance):
         initial=instance.roles.all() if instance.pk else None,
         initial=instance.roles.all() if instance.pk else None,
         widget=forms.CheckboxSelectMultiple)
         widget=forms.CheckboxSelectMultiple)
 
 
+    if instance.pk:
+        extra_fields['timezone'] = forms.ChoiceField(
+            label=_("Timezone"), choices=timezones.choices())
+
     return type('UserFormFinal', (FormType,), extra_fields)
     return type('UserFormFinal', (FormType,), extra_fields)
 
 
 
 

+ 14 - 4
misago/users/forms/usercp.py

@@ -4,7 +4,8 @@ from django.utils.translation import ugettext_lazy as _, ungettext
 from misago.conf import settings
 from misago.conf import settings
 from misago.core import forms, timezones
 from misago.core import forms, timezones
 
 
-from misago.users.models import AUTO_SUBSCRIBE_CHOICES
+from misago.users.models import (AUTO_SUBSCRIBE_CHOICES,
+                                 PRIVATE_THREAD_INVITES_LIMITS_CHOICES)
 from misago.users.validators import validate_email, validate_password
 from misago.users.validators import validate_email, validate_password
 
 
 
 
@@ -19,6 +20,11 @@ class ChangeForumOptionsBaseForm(forms.ModelForm):
         help_text=_("If you hide your presence, only members with permission "
         help_text=_("If you hide your presence, only members with permission "
                     "to see hidden will see when you are online."))
                     "to see hidden will see when you are online."))
 
 
+    limits_private_thread_invites_to = forms.TypedChoiceField(
+        label=_("Who can add me to private threads"),
+        coerce=int,
+        choices=PRIVATE_THREAD_INVITES_LIMITS_CHOICES)
+
     subscribe_to_started_threads = forms.TypedChoiceField(
     subscribe_to_started_threads = forms.TypedChoiceField(
         label=_("Threads I start"), coerce=int, choices=AUTO_SUBSCRIBE_CHOICES)
         label=_("Threads I start"), coerce=int, choices=AUTO_SUBSCRIBE_CHOICES)
 
 
@@ -28,9 +34,13 @@ class ChangeForumOptionsBaseForm(forms.ModelForm):
 
 
     class Meta:
     class Meta:
         model = get_user_model()
         model = get_user_model()
-        fields = ['timezone', 'is_hiding_presence',
-                  'subscribe_to_started_threads',
-                  'subscribe_to_replied_threads']
+        fields = [
+            'timezone',
+            'is_hiding_presence',
+            'limits_private_thread_invites_to',
+            'subscribe_to_started_threads',
+            'subscribe_to_replied_threads'
+        ]
 
 
 
 
 def ChangeForumOptionsForm(*args, **kwargs):
 def ChangeForumOptionsForm(*args, **kwargs):

+ 1 - 1
misago/users/migrations/0001_initial.py

@@ -55,7 +55,7 @@ class Migration(migrations.Migration):
                 ('following', models.PositiveIntegerField(default=0)),
                 ('following', models.PositiveIntegerField(default=0)),
                 ('followers', models.PositiveIntegerField(default=0)),
                 ('followers', models.PositiveIntegerField(default=0)),
                 ('new_notifications', models.PositiveIntegerField(default=0)),
                 ('new_notifications', models.PositiveIntegerField(default=0)),
-                ('limit_private_thread_invites', models.PositiveIntegerField(default=0)),
+                ('limits_private_thread_invites_to', models.PositiveIntegerField(default=0)),
                 ('unread_private_threads', models.PositiveIntegerField(default=0)),
                 ('unread_private_threads', models.PositiveIntegerField(default=0)),
                 ('sync_unred_private_threads', models.BooleanField(default=False)),
                 ('sync_unred_private_threads', models.BooleanField(default=False)),
                 ('subscribe_to_started_threads', models.PositiveIntegerField(default=0)),
                 ('subscribe_to_started_threads', models.PositiveIntegerField(default=0)),

+ 25 - 6
misago/users/models/user.py

@@ -27,11 +27,18 @@ from misago.users.utils import hash_email
 
 
 
 
 __all__ = [
 __all__ = [
-    'ACTIVATION_REQUIRED_NONE', 'ACTIVATION_REQUIRED_USER',
-    'ACTIVATION_REQUIRED_ADMIN', 'AUTO_SUBSCRIBE_NONE',
-    'AUTO_SUBSCRIBE_WATCH', 'AUTO_SUBSCRIBE_WATCH_AND_EMAIL',
-    'AUTO_SUBSCRIBE_CHOICES', 'AnonymousUser', 'User', 'UsernameChange',
-    'Online',
+    'ACTIVATION_REQUIRED_NONE',
+    'ACTIVATION_REQUIRED_USER',
+    'ACTIVATION_REQUIRED_ADMIN',
+    'AUTO_SUBSCRIBE_NONE',
+    'AUTO_SUBSCRIBE_WATCH',
+    'AUTO_SUBSCRIBE_WATCH_AND_EMAIL',
+    'AUTO_SUBSCRIBE_CHOICES',
+    'LIMITS_PRIVATE_THREAD_INVITES_TO_NONE',
+    'LIMITS_PRIVATE_THREAD_INVITES_TO_FOLLOWED',
+    'LIMITS_PRIVATE_THREAD_INVITES_TO_NOBODY',
+    'PRIVATE_THREAD_INVITES_LIMITS_CHOICES',
+    'AnonymousUser', 'User', 'UsernameChange', 'Online',
 ]
 ]
 
 
 
 
@@ -52,6 +59,17 @@ AUTO_SUBSCRIBE_CHOICES = (
 )
 )
 
 
 
 
+LIMITS_PRIVATE_THREAD_INVITES_TO_NONE = 0
+LIMITS_PRIVATE_THREAD_INVITES_TO_FOLLOWED = 1
+LIMITS_PRIVATE_THREAD_INVITES_TO_NOBODY = 2
+
+PRIVATE_THREAD_INVITES_LIMITS_CHOICES = (
+    (LIMITS_PRIVATE_THREAD_INVITES_TO_NONE, _("Everybody")),
+    (LIMITS_PRIVATE_THREAD_INVITES_TO_FOLLOWED, _("Users I follow")),
+    (LIMITS_PRIVATE_THREAD_INVITES_TO_NOBODY, _("Nobody")),
+)
+
+
 class UserManager(BaseUserManager):
 class UserManager(BaseUserManager):
     def create_user(self, username, email, password=None,
     def create_user(self, username, email, password=None,
                     set_default_avatar=False, **extra_fields):
                     set_default_avatar=False, **extra_fields):
@@ -205,7 +223,8 @@ class User(AbstractBaseUser, PermissionsMixin):
 
 
     new_notifications = models.PositiveIntegerField(default=0)
     new_notifications = models.PositiveIntegerField(default=0)
 
 
-    limit_private_thread_invites = models.PositiveIntegerField(default=0)
+    limits_private_thread_invites_to = models.PositiveIntegerField(
+        default=LIMITS_PRIVATE_THREAD_INVITES_TO_NONE)
     unread_private_threads = models.PositiveIntegerField(default=0)
     unread_private_threads = models.PositiveIntegerField(default=0)
     sync_unred_private_threads = models.BooleanField(default=False)
     sync_unred_private_threads = models.BooleanField(default=False)
 
 

+ 5 - 0
misago/users/tests/test_useradmin_views.py

@@ -194,8 +194,13 @@ class UserAdminViewsTests(AdminTestCase):
                 'staff_level': '0',
                 'staff_level': '0',
                 'signature': 'Hello world!',
                 'signature': 'Hello world!',
                 'is_signature_locked': '1',
                 'is_signature_locked': '1',
+                'timezone': 'utc',
+                'is_hiding_presence': '0',
+                'limits_private_thread_invites_to': '0',
                 'signature_lock_staff_message': 'Staff message',
                 'signature_lock_staff_message': 'Staff message',
                 'signature_lock_user_message': 'User message',
                 'signature_lock_user_message': 'User message',
+                'subscribe_to_started_threads': '2',
+                'subscribe_to_replied_threads': '2',
             })
             })
         self.assertEqual(response.status_code, 302)
         self.assertEqual(response.status_code, 302)
 
 

+ 4 - 2
misago/users/tests/test_usercp_views.py

@@ -28,7 +28,8 @@ class ChangeForumOptionsTests(AuthenticatedUserTestCase):
         response = self.client.post(self.view_link, data={
         response = self.client.post(self.view_link, data={
                 'timezone': 'Asia/Qatar',
                 'timezone': 'Asia/Qatar',
                 'is_hiding_presence': '1',
                 'is_hiding_presence': '1',
-                'subscribe_to_started_threads': '0',
+                'limits_private_thread_invites_to': '1',
+                'subscribe_to_started_threads': '1',
                 'subscribe_to_replied_threads': '1',
                 'subscribe_to_replied_threads': '1',
             })
             })
 
 
@@ -37,7 +38,8 @@ class ChangeForumOptionsTests(AuthenticatedUserTestCase):
         test_user = get_user_model().objects.get(pk=self.user.pk)
         test_user = get_user_model().objects.get(pk=self.user.pk)
         self.assertEqual(test_user.timezone, 'Asia/Qatar')
         self.assertEqual(test_user.timezone, 'Asia/Qatar')
         self.assertEqual(test_user.is_hiding_presence, 1)
         self.assertEqual(test_user.is_hiding_presence, 1)
-        self.assertEqual(test_user.subscribe_to_started_threads, 0)
+        self.assertEqual(test_user.limits_private_thread_invites_to, 1)
+        self.assertEqual(test_user.subscribe_to_started_threads, 1)
         self.assertEqual(test_user.subscribe_to_replied_threads, 1)
         self.assertEqual(test_user.subscribe_to_replied_threads, 1)