Browse Source

record changes of post body

Rafał Pitoń 8 years ago
parent
commit
e01c1ebcf6

+ 1 - 1
misago/conf/defaults.py

@@ -138,7 +138,7 @@ MISAGO_POSTING_MIDDLEWARES = (
     'misago.threads.api.postingendpoint.close.CloseMiddleware',
     'misago.threads.api.postingendpoint.hide.HideMiddleware',
     'misago.threads.api.postingendpoint.protect.ProtectMiddleware',
-    # 'misago.threads.api.postingendpoint.recordedit.RecordEditMiddleware',
+    'misago.threads.api.postingendpoint.recordedit.RecordEditMiddleware',
     'misago.threads.api.postingendpoint.updatestats.UpdateStatsMiddleware',
     'misago.threads.api.postingendpoint.mentions.MentionsMiddleware',
     'misago.threads.api.postingendpoint.subscribe.SubscribeMiddleware',

+ 33 - 15
misago/threads/api/postingendpoint/recordedit.py

@@ -1,23 +1,41 @@
 from django.db.models import F
 
-from . import EDIT, PostingMiddleware
+from . import PostingEndpoint, PostingMiddleware
 
 
 class RecordEditMiddleware(PostingMiddleware):
-    def __init__(self, **kwargs):
-        super(RecordEditMiddleware, self).__init__(**kwargs)
+    def use_this_middleware(self):
+        self.original_post = self.post.original
 
-        if self.mode == EDIT:
-            self.original_title = self.thread.title
-            self.original_post = self.post.original
+        return self.mode == PostingEndpoint.EDIT
 
     def save(self, serializer):
-        if self.mode == EDIT:
-            # record post or thread edit
-            is_title_changed = self.original_title != self.thread.title
-            is_post_changed = self.original_post != self.post.original
-
-            if is_title_changed or is_post_changed:
-                self.post.edits += 1
-                self.post.last_editor_name = self.user.username
-                self.post.update_fields.extend(('edits', 'last_editor_name'))
+        is_post_changed = self.original_post != self.post.original
+        if not is_post_changed:
+            return
+
+        self.post.updated_on = self.datetime
+        self.post.edits = F('edits') + 1
+
+        self.post.last_editor = self.user
+        self.post.last_editor_name = self.user.username
+        self.post.last_editor_slug = self.user.slug
+
+        self.post.update_fields.extend((
+            'updated_on',
+            'edits',
+            'last_editor',
+            'last_editor_name',
+            'last_editor_slug',
+        ))
+
+        self.post.edits_record.create(
+            category=self.post.category,
+            thread=self.thread,
+            editor=self.user,
+            editor_name=self.user.username,
+            editor_slug=self.user.slug,
+            editor_ip=self.request.user_ip,
+            edited_from=self.original_post,
+            edited_to=self.post.original
+        )

+ 0 - 7
misago/threads/api/postingendpoint/reply.py

@@ -59,13 +59,6 @@ class ReplyMiddleware(PostingMiddleware):
         self.post.original = parsing_result['original_text']
         self.post.parsed = parsing_result['parsed_text']
 
-        self.post.updated_on = self.datetime
-        self.post.edits = F('edits') + 1
-
-        self.post.last_editor = self.user
-        self.post.last_editor_name = self.user.username
-        self.post.last_editor_slug = self.user.slug
-
     def new_post(self, validated_data, parsing_result):
         self.post.thread = self.thread
         self.post.poster = self.user

+ 21 - 2
misago/threads/migrations/0001_initial.py

@@ -221,6 +221,25 @@ class Migration(migrations.Migration):
             ]),
         ),
         migrations.CreateModel(
+            name='PostEdit',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('edited_on', models.DateTimeField(default=django.utils.timezone.now)),
+                ('editor_name', models.CharField(max_length=255)),
+                ('editor_slug', models.CharField(max_length=255)),
+                ('editor_ip', models.GenericIPAddressField()),
+                ('edited_from', models.TextField()),
+                ('edited_to', models.TextField()),
+                ('category', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='misago_categories.Category')),
+                ('editor', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL)),
+                ('post', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='edits_record', to='misago_threads.Post')),
+                ('thread', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='misago_threads.Thread')),
+            ],
+            options={
+                'ordering': ['-id'],
+            },
+        ),
+        migrations.CreateModel(
             name='Attachment',
             fields=[
                 ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
@@ -284,11 +303,11 @@ class Migration(migrations.Migration):
             name='PollVote',
             fields=[
                 ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
-                ('voter_name', models.CharField(max_length=255, db_index=True)),
+                ('voter_name', models.CharField(max_length=255)),
                 ('voter_slug', models.CharField(max_length=255)),
                 ('voter_ip', models.GenericIPAddressField()),
                 ('voted_on', models.DateTimeField(default=django.utils.timezone.now)),
-                ('choice_hash', models.CharField(max_length=12)),
+                ('choice_hash', models.CharField(db_index=True, max_length=12)),
                 ('category', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='misago_categories.Category')),
                 ('poll', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='misago_threads.Poll')),
                 ('thread', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='misago_threads.Thread')),

+ 1 - 0
misago/threads/models/__init__.py

@@ -1,5 +1,6 @@
 # flake8: noqa
 from .post import Post
+from .postedit import PostEdit
 from .thread import *
 from .threadparticipant import ThreadParticipant
 from .subscription import Subscription

+ 27 - 0
misago/threads/models/postedit.py

@@ -0,0 +1,27 @@
+from django.conf import settings
+from django.db import models
+from django.utils import timezone
+
+
+class PostEdit(models.Model):
+    category = models.ForeignKey('misago_categories.Category')
+    thread = models.ForeignKey('misago_threads.Thread')
+    post = models.ForeignKey('misago_threads.Post', related_name='edits_record')
+
+    edited_on = models.DateTimeField(default=timezone.now)
+
+    editor = models.ForeignKey(
+        settings.AUTH_USER_MODEL,
+        blank=True,
+        null=True,
+        on_delete=models.SET_NULL,
+    )
+    editor_name = models.CharField(max_length=255)
+    editor_slug = models.CharField(max_length=255)
+    editor_ip = models.GenericIPAddressField()
+
+    edited_from = models.TextField()
+    edited_to = models.TextField()
+
+    class Meta:
+        ordering = ['-id']

+ 37 - 0
misago/threads/tests/test_thread_editreply_api.py

@@ -188,9 +188,36 @@ class EditReplyTests(AuthenticatedUserTestCase):
             ]
         })
 
+    def test_edit_reply_no_change(self):
+        """endpoint isn't bumping edits count if no change was made to post's body"""
+        self.override_acl()
+        self.assertEqual(self.post.edits_record.count(), 0)
+
+        response = self.put(self.api_link, data={
+            'post': self.post.original
+        })
+        self.assertEqual(response.status_code, 200)
+
+        thread = Thread.objects.get(pk=self.thread.pk)
+
+        self.override_acl()
+        response = self.client.get(self.thread.get_absolute_url())
+        self.assertContains(response, self.post.parsed)
+
+        post = self.thread.post_set.order_by('id').last()
+        self.assertEqual(post.edits, 0)
+        self.assertEqual(post.original, self.post.original)
+        self.assertIsNone(post.last_editor_id, self.user.id)
+        self.assertIsNone(post.last_editor_name, self.user.username)
+        self.assertIsNone(post.last_editor_slug, self.user.slug)
+
+        self.assertEqual(self.post.edits_record.count(), 0)
+
     def test_edit_reply(self):
         """endpoint updates reply"""
         self.override_acl()
+        self.assertEqual(self.post.edits_record.count(), 0)
+
         response = self.put(self.api_link, data={
             'post': "This is test edit!"
         })
@@ -209,6 +236,16 @@ class EditReplyTests(AuthenticatedUserTestCase):
         self.assertEqual(post.last_editor_name, self.user.username)
         self.assertEqual(post.last_editor_slug, self.user.slug)
 
+        self.assertEqual(self.post.edits_record.count(), 1)
+
+        post_edit = post.edits_record.last()
+        self.assertEqual(post_edit.edited_from, self.post.original)
+        self.assertEqual(post_edit.edited_to, post.original)
+
+        self.assertEqual(post_edit.editor_id, self.user.id)
+        self.assertEqual(post_edit.editor_name, self.user.username)
+        self.assertEqual(post_edit.editor_slug, self.user.slug)
+
     def test_edit_first_post_hidden(self):
         """endpoint updates hidden thread's first post"""
         self.override_acl({