Browse Source

Redeo migration for thread answer fields, rename perm provider and make build pass

Rafał Pitoń 7 years ago
parent
commit
724442eac5

+ 1 - 1
misago/conf/defaults.py

@@ -20,7 +20,7 @@ MISAGO_ACL_EXTENSIONS = [
     'misago.threads.permissions.polls',
     'misago.threads.permissions.polls',
     'misago.threads.permissions.threads',
     'misago.threads.permissions.threads',
     'misago.threads.permissions.privatethreads',
     'misago.threads.permissions.privatethreads',
-    'misago.threads.permissions.answers',
+    'misago.threads.permissions.bestanswers',
     'misago.search.permissions',
     'misago.search.permissions',
 ]
 ]
 
 

+ 0 - 31
misago/threads/migrations/0008_auto_20180304_2004.py

@@ -1,31 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.11.9 on 2018-03-04 20:04
-from __future__ import unicode_literals
-
-from django.db import migrations, models
-import django.db.models.deletion
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('misago_threads', '0007_auto_20171008_0131'),
-    ]
-
-    operations = [
-        migrations.AddField(
-            model_name='thread',
-            name='answer',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='misago_threads.Post'),
-        ),
-        migrations.AddField(
-            model_name='thread',
-            name='answer_is_protected',
-            field=models.BooleanField(default=False),
-        ),
-        migrations.AddField(
-            model_name='thread',
-            name='answer_set_on',
-            field=models.DateTimeField(blank=True, null=True),
-        ),
-    ]

+ 48 - 0
misago/threads/migrations/0008_auto_20180310_2234.py

@@ -0,0 +1,48 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.9 on 2018-03-10 22:34
+from __future__ import unicode_literals
+
+from django.conf import settings
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
+        ('misago_threads', '0007_auto_20171008_0131'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='thread',
+            name='best_answer',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='misago_threads.Post'),
+        ),
+        migrations.AddField(
+            model_name='thread',
+            name='best_answer_is_protected',
+            field=models.BooleanField(default=False),
+        ),
+        migrations.AddField(
+            model_name='thread',
+            name='best_answer_marked_by',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='marked_best_answer_set', to=settings.AUTH_USER_MODEL),
+        ),
+        migrations.AddField(
+            model_name='thread',
+            name='best_answer_marked_by_name',
+            field=models.CharField(blank=True, max_length=255, null=True),
+        ),
+        migrations.AddField(
+            model_name='thread',
+            name='best_answer_marked_by_slug',
+            field=models.CharField(blank=True, max_length=255, null=True),
+        ),
+        migrations.AddField(
+            model_name='thread',
+            name='best_answer_marked_on',
+            field=models.DateTimeField(blank=True, null=True),
+        ),
+    ]

+ 6 - 6
misago/threads/models/post.py

@@ -134,8 +134,8 @@ class Post(models.Model):
         other_post.parsed = six.text_type('\n').join((other_post.parsed, self.parsed))
         other_post.parsed = six.text_type('\n').join((other_post.parsed, self.parsed))
         update_post_checksum(other_post)
         update_post_checksum(other_post)
 
 
-        if self.thread.answer_id == self.id:
-            self.thread.answer = other_post
+        if self.thread.best_answer_id == self.id:
+            self.thread.best_answer = other_post
 
 
         from misago.threads.signals import merge_post
         from misago.threads.signals import merge_post
         merge_post.send(sender=self, other_post=other_post)
         merge_post.send(sender=self, other_post=other_post)
@@ -143,8 +143,8 @@ class Post(models.Model):
     def move(self, new_thread):
     def move(self, new_thread):
         from misago.threads.signals import move_post
         from misago.threads.signals import move_post
 
 
-        if self.thread.answer_id == self.id:
-            self.thread.answer = None
+        if self.thread.best_answer_id == self.id:
+            self.thread.clear_best_answer()
 
 
         self.category = new_thread.category
         self.category = new_thread.category
         self.thread = new_thread
         self.thread = new_thread
@@ -222,5 +222,5 @@ class Post(models.Model):
         return self.id == self.thread.first_post_id
         return self.id == self.thread.first_post_id
 
 
     @property
     @property
-    def is_answer(self):
-        return self.id == self.thread.answer_id
+    def is_best_answer(self):
+        return self.id == self.thread.best_answer_id

+ 20 - 3
misago/threads/models/thread.py

@@ -78,15 +78,24 @@ class Thread(models.Model):
     is_hidden = models.BooleanField(default=False)
     is_hidden = models.BooleanField(default=False)
     is_closed = models.BooleanField(default=False)
     is_closed = models.BooleanField(default=False)
 
 
-    answer = models.ForeignKey(
+    best_answer = models.ForeignKey(
         'misago_threads.Post',
         'misago_threads.Post',
         related_name='+',
         related_name='+',
         null=True,
         null=True,
         blank=True,
         blank=True,
         on_delete=models.SET_NULL,
         on_delete=models.SET_NULL,
     )
     )
-    answer_is_protected =  models.BooleanField(default=False)
-    answer_set_on = models.DateTimeField(null=True, blank=True)
+    best_answer_is_protected =  models.BooleanField(default=False)
+    best_answer_marked_on = models.DateTimeField(null=True, blank=True)
+    best_answer_marked_by = models.ForeignKey(
+        settings.AUTH_USER_MODEL,
+        related_name='marked_best_answer_set',
+        null=True,
+        blank=True,
+        on_delete=models.SET_NULL,
+    )
+    best_answer_marked_by_name = models.CharField(max_length=255, null=True, blank=True)
+    best_answer_marked_by_slug = models.CharField(max_length=255, null=True, blank=True)
 
 
     participants = models.ManyToManyField(
     participants = models.ManyToManyField(
         settings.AUTH_USER_MODEL,
         settings.AUTH_USER_MODEL,
@@ -266,3 +275,11 @@ class Thread(models.Model):
             self.last_poster_slug = post.poster.slug
             self.last_poster_slug = post.poster.slug
         else:
         else:
             self.last_poster_slug = slugify(post.poster_name)
             self.last_poster_slug = slugify(post.poster_name)
+
+    def clear_best_answer(self):
+        self.best_answer = None
+        self.best_answer_is_protected = None
+        self.best_answer_marked_on = None
+        self.best_answer_marked_by = None
+        self.best_answer_marked_by_name = None
+        self.best_answer_marked_by_slug = None

+ 1 - 1
misago/threads/permissions/__init__.py

@@ -1,4 +1,4 @@
-from .answers import *
+from .bestanswers import *
 from .privatethreads import *
 from .privatethreads import *
 from .threads import *
 from .threads import *
 from .polls import *
 from .polls import *

+ 38 - 37
misago/threads/permissions/answers.py → misago/threads/permissions/bestanswers.py

@@ -12,18 +12,18 @@ from misago.threads.models import Post
 
 
 
 
 __all__nope = [
 __all__nope = [
-    'allow_select_answer',
-    'can_select_answer',
-    'allow_remove_answer',
-    'can_remove_answer',
+    'allow_mark_as_best_answer',
+    'can_mark_as_best_answer',
+    'allow_unmark_best_answer',
+    'can_unmark_best_answer',
 ]
 ]
 
 
 
 
 class CategoryPermissionsForm(forms.Form):
 class CategoryPermissionsForm(forms.Form):
-    legend = _("Answers")
+    legend = _("Best answers")
 
 
-    can_set_answers = forms.TypedChoiceField(
-        label=_("Can set answers"),
+    can_mark_best_answers = forms.TypedChoiceField(
+        label=_("Can mark posts as best answers"),
         coerce=int,
         coerce=int,
         initial=0,
         initial=0,
         choices=[
         choices=[
@@ -32,8 +32,8 @@ class CategoryPermissionsForm(forms.Form):
             (2, _("All threads")),
             (2, _("All threads")),
         ],
         ],
     )
     )
-    can_change_answers = forms.TypedChoiceField(
-        label=_("Can change answers"),
+    can_change_marked_answers = forms.TypedChoiceField(
+        label=_("Can change marked answers"),
         coerce=int,
         coerce=int,
         initial=0,
         initial=0,
         choices=[
         choices=[
@@ -42,9 +42,9 @@ class CategoryPermissionsForm(forms.Form):
             (2, _("All threads")),
             (2, _("All threads")),
         ],
         ],
     )
     )
-    answer_change_time = forms.IntegerField(
-        label=_("Time limit for owned thread answer change, in minutes"),
-        help_text=_("Enter 0 to don't limit time for changing own thread answer."),
+    best_answer_change_time = forms.IntegerField(
+        label=_("Time limit for changing marked best answer in owned thread, in minutes"),
+        help_text=_("Enter 0 to don't limit time for changing marked best answer in owned thread."),
         initial=0,
         initial=0,
         min_value=0,
         min_value=0,
     )
     )
@@ -75,9 +75,9 @@ def build_category_acl(acl, category, categories_roles, key_name):
     category_roles = categories_roles.get(category.pk, [])
     category_roles = categories_roles.get(category.pk, [])
 
 
     final_acl = {
     final_acl = {
-        'can_set_answers': 0,
-        'can_change_answers': 0,
-        'answer_change_time': 0,
+        'can_mark_best_answers': 0,
+        'can_change_marked_answers': 0,
+        'best_answer_change_time': 0,
     }
     }
     final_acl.update(acl)
     final_acl.update(acl)
 
 
@@ -85,9 +85,9 @@ def build_category_acl(acl, category, categories_roles, key_name):
         final_acl,
         final_acl,
         roles=category_roles,
         roles=category_roles,
         key=key_name,
         key=key_name,
-        can_set_answers=algebra.greater,
-        can_change_answers=algebra.greater,
-        answer_change_time=algebra.greater_or_zero,
+        can_mark_best_answers=algebra.greater,
+        can_change_marked_answers=algebra.greater,
+        best_answer_change_time=algebra.greater_or_zero,
     )
     )
 
 
     return final_acl
     return final_acl
@@ -95,8 +95,8 @@ def build_category_acl(acl, category, categories_roles, key_name):
 
 
 def add_acl_to_post(user, post):
 def add_acl_to_post(user, post):
     post.acl.update({
     post.acl.update({
-        'can_set_answer': can_set_answer(user, post),
-        'can_unset_answer': can_unset_answer(user, post),
+        'can_mark_as_best_answer': can_mark_as_best_answer(user, post),
+        'can_unmark_best_answer': can_unmark_best_answer(user, post),
     })
     })
 
 
 
 
@@ -104,7 +104,7 @@ def register_with(registry):
     registry.acl_annotator(Post, add_acl_to_post)
     registry.acl_annotator(Post, add_acl_to_post)
 
 
 
 
-def allow_set_answer(user, target):
+def allow_mark_as_best_answer(user, target):
     if user.is_anonymous:
     if user.is_anonymous:
         raise PermissionDenied(_("You have to sign in to set posts as answers."))
         raise PermissionDenied(_("You have to sign in to set posts as answers."))
 
 
@@ -113,11 +113,11 @@ def allow_set_answer(user, target):
 
 
     category_acl = user.acl_cache['categories'].get(
     category_acl = user.acl_cache['categories'].get(
         target.category_id, {
         target.category_id, {
-            'can_set_answers': 0,
+            'can_mark_best_answers': 0,
         }
         }
     )
     )
 
 
-    if not category_acl['can_set_answers']:
+    if not category_acl['can_mark_best_answers']:
         raise PermissionDenied(
         raise PermissionDenied(
             _(
             _(
                 'You don\'t have permission to set answers in the "%(category)s" category.'
                 'You don\'t have permission to set answers in the "%(category)s" category.'
@@ -126,7 +126,7 @@ def allow_set_answer(user, target):
             }
             }
         )
         )
 
 
-    if category_acl['can_set_answers'] == 1 and target.thread.starter != user:
+    if category_acl['can_mark_best_answers'] == 1 and target.thread.starter != user:
         raise PermissionDenied(
         raise PermissionDenied(
             _(
             _(
                 "You dont't have permission to set this post as an answer "
                 "You dont't have permission to set this post as an answer "
@@ -146,11 +146,12 @@ def allow_set_answer(user, target):
     if target.is_answer:
     if target.is_answer:
         raise PermissionDenied(_("This post is already set as an answer."))
         raise PermissionDenied(_("This post is already set as an answer."))
 
 
-    if target.thread.answer_id:
-        if not category_acl['can_change_answers']:
+    if target.thread.best_answer_id:
+        if not category_acl['can_change_marked_answers']:
             raise PermissionDenied(_("You don't have permission to change selected answer."))
             raise PermissionDenied(_("You don't have permission to change selected answer."))
 
 
-        if category_acl['can_change_answers'] == 1 and not has_time_to_change_answer(user, target):
+        if (category_acl['can_change_marked_answers'] == 1 and
+                not has_time_to_change_answer(user, target)):
             raise PermissionDenied(
             raise PermissionDenied(
                 ungettext(
                 ungettext(
                     (
                     (
@@ -165,7 +166,7 @@ def allow_set_answer(user, target):
                 }
                 }
             )
             )
 
 
-        if target.thread.answer_is_protected and not category_acl['can_protect_posts']:
+        if target.thread.best_answer_is_protected and not category_acl['can_protect_posts']:
             raise PermissionDenied(
             raise PermissionDenied(
                 _(
                 _(
                     "You don't have permission to change this thread's answer because moderator "
                     "You don't have permission to change this thread's answer because moderator "
@@ -193,24 +194,24 @@ def allow_set_answer(user, target):
 
 
     if target.is_protected and not category_acl['can_protect_posts']:
     if target.is_protected and not category_acl['can_protect_posts']:
         raise PermissionDenied(
         raise PermissionDenied(
-            _("You can't sets this post as an answer because moderator has protected it.")
+            _("You can't set this post as an answer because moderator has protected it.")
         )
         )
 
 
 
 
-can_set_answer = return_boolean(allow_set_answer)
+can_mark_as_best_answer = return_boolean(allow_mark_as_best_answer)
 
 
 
 
-def allow_unset_answer(user, target):
+def allow_unmark_best_answer(user, target):
     if user.is_anonymous:
     if user.is_anonymous:
         raise PermissionDenied(_("You have to sign in to unset threads answers."))
         raise PermissionDenied(_("You have to sign in to unset threads answers."))
 
 
     category_acl = user.acl_cache['categories'].get(
     category_acl = user.acl_cache['categories'].get(
         target.category_id, {
         target.category_id, {
-            'can_change_answers': 0,
+            'can_mark_best_answers': 0,
         }
         }
     )
     )
 
 
-    if not category_acl['can_change_answers']:
+    if not category_acl['can_mark_best_answers']:
         raise PermissionDenied(
         raise PermissionDenied(
             _(
             _(
                 'You don\'t have permission to unset threads answers in the "%(category)s" '
                 'You don\'t have permission to unset threads answers in the "%(category)s" '
@@ -227,7 +228,7 @@ def allow_unset_answer(user, target):
             )
             )
         )
         )
 
 
-    if category_acl['can_change_answers'] == 1:
+    if category_acl['can_mark_best_answers'] == 1:
         if target.thread.starter != user:
         if target.thread.starter != user:
             raise PermissionDenied(
             raise PermissionDenied(
                 _(
                 _(
@@ -276,15 +277,15 @@ def allow_unset_answer(user, target):
         )
         )
 
 
 
 
-can_unset_answer = return_boolean(allow_unset_answer)
+can_unmark_best_answer = return_boolean(allow_unmark_best_answer)
 
 
 
 
 def has_time_to_change_answer(user, target):
 def has_time_to_change_answer(user, target):
     category_acl = user.acl_cache['categories'].get(target.category_id, {})
     category_acl = user.acl_cache['categories'].get(target.category_id, {})
-    change_time = category_acl.get('answer_change_time', 0)
+    change_time = category_acl.get('best_answer_change_time', 0)
 
 
     if change_time:
     if change_time:
-        diff = timezone.now() - target.thread.answer_set_on
+        diff = timezone.now() - target.thread.best_answer_set_on
         diff_minutes = int(diff.total_seconds() / 60)
         diff_minutes = int(diff.total_seconds() / 60)
         return diff_minutes < change_time
         return diff_minutes < change_time
     else:
     else:

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

@@ -132,6 +132,9 @@ def build_acl(acl, roles, key_name):
         'can_see_posts_likes': 0,
         'can_see_posts_likes': 0,
         'can_like_posts': 0,
         'can_like_posts': 0,
         'can_hide_events': 0,
         'can_hide_events': 0,
+        'can_mark_best_answers': 0,
+        'can_change_marked_answers': 0,
+        'best_answer_change_time': 0,
     }
     }
 
 
     if new_acl['can_moderate_private_threads']:
     if new_acl['can_moderate_private_threads']: