Browse Source

#600: polls and private threads migration

Rafał Pitoń 8 years ago
parent
commit
8584a5a45e

+ 16 - 1
misago/datamover/management/commands/movethreads.py

@@ -1,4 +1,4 @@
-from ... import attachments, threads
+from ... import attachments, polls, threads
 from ..base import BaseCommand
 from ..base import BaseCommand
 
 
 
 
@@ -37,3 +37,18 @@ class Command(BaseCommand):
         attachments.move_attachments(self.stdout, self.style)
         attachments.move_attachments(self.stdout, self.style)
         self.stdout.write(
         self.stdout.write(
             self.style.SUCCESS("Moved attachments in %s" % self.stop_timer()))
             self.style.SUCCESS("Moved attachments in %s" % self.stop_timer()))
+
+        self.start_timer()
+        polls.move_polls()
+        self.stdout.write(
+            self.style.SUCCESS("Moved polls in %s" % self.stop_timer()))
+
+        self.start_timer()
+        threads.move_participants()
+        self.stdout.write(
+            self.style.SUCCESS("Moved threads participants in %s" % self.stop_timer()))
+
+        self.start_timer()
+        threads.clean_private_threads(self.stdout, self.style)
+        self.stdout.write(
+            self.style.SUCCESS("Cleaned private threads in %s" % self.stop_timer()))

+ 72 - 0
misago/datamover/polls.py

@@ -0,0 +1,72 @@
+from django.contrib.auth import get_user_model
+from django.utils.crypto import get_random_string
+
+from misago.threads.models import Thread, Poll, PollVote
+
+from . import fetch_assoc, movedids, localise_datetime
+
+
+UserModel = get_user_model()
+
+
+def move_polls():
+    for poll in fetch_assoc('SELECT * FROM misago_poll ORDER BY thread_id'):
+        thread_pk = movedids.get('thread', poll['thread_id'])
+        thread = Thread.objects.select_related().get(pk=thread_pk)
+
+        poster = None
+        if poll['user_id']:
+            poster_pk = movedids.get('user', poll['user_id'])
+            poster = UserModel.objects.get(pk=poster_pk)
+
+        choices = []
+        choices_map = {}
+
+        query = 'SELECT * FROM misago_polloption WHERE poll_id = %s ORDER BY id'
+        for choice in fetch_assoc(query, [poll['thread_id']]):
+            choices.append({
+                'hash': get_random_string(12),
+                'label': choice['name'],
+                'votes': choice['votes']
+            })
+
+            choices_map[choice['id']] = choices[-1]['hash']
+
+        new_poll = Poll.objects.create(
+            category=thread.category,
+            thread=thread,
+            poster=poster,
+            poster_name=poll['user_name'],
+            poster_slug=poll['user_slug'],
+            poster_ip=thread.post_set.order_by('id').first().poster_ip,
+            posted_on=localise_datetime(poll['start_date']),
+            length=poll['length'],
+            question=poll['question'],
+            choices=choices,
+            allowed_choices=poll['max_choices'],
+            allow_revotes=poll['vote_changing'],
+            votes=poll['votes'],
+            is_public=poll['public'],
+        )
+
+        query = 'SELECT * FROM misago_pollvote WHERE poll_id = %s ORDER BY id'
+        for vote in fetch_assoc(query, [poll['thread_id']]):
+            if not vote['option_id']:
+                continue
+
+            voter = None
+            if vote['user_id']:
+                voter_pk = movedids.get('user', vote['user_id'])
+                voter = UserModel.objects.get(pk=voter_pk)
+
+            PollVote.objects.create(
+                category=thread.category,
+                thread=thread,
+                poll=new_poll,
+                voter=voter,
+                voter_name=vote['user_name'],
+                voter_slug=vote['user_slug'],
+                voter_ip=vote['ip'],
+                voted_on=localise_datetime(vote['date']),
+                choice_hash=choices_map[vote['option_id']],
+            )

+ 40 - 1
misago/datamover/threads.py

@@ -5,7 +5,8 @@ from django.utils import timezone
 
 
 from misago.categories.models import Category
 from misago.categories.models import Category
 from misago.threads.checksums import update_post_checksum
 from misago.threads.checksums import update_post_checksum
-from misago.threads.models import Thread, Post, PostEdit, PostLike
+from misago.threads.models import (
+    Thread, ThreadParticipant, Post, PostEdit, PostLike)
 
 
 from . import fetch_assoc, markup, movedids, localise_datetime
 from . import fetch_assoc, markup, movedids, localise_datetime
 
 
@@ -226,6 +227,44 @@ def move_likes():
         post.save(update_fields=['last_likes'])
         post.save(update_fields=['last_likes'])
 
 
 
 
+def move_participants():
+    for participant in fetch_assoc('SELECT * FROM misago_thread_participants'):
+        thread_pk = movedids.get('thread', participant['thread_id'])
+        thread = Thread.objects.get(pk=thread_pk)
+
+        user_pk = movedids.get('user', participant['user_id'])
+        user = UserModel.objects.get(pk=user_pk)
+
+        starter = thread.post_set.order_by('id').first().poster
+
+        ThreadParticipant.objects.create(
+            thread=thread,
+            user=user,
+            is_owner=(user == starter)
+        )
+
+
+def clean_private_threads(stdout, style):
+    category = Category.objects.private_threads()
+
+    # prune threads without participants
+    participated_threads = ThreadParticipant.objects.values_list(
+        'thread_id', flat=True).distinct()
+    for thread in category.thread_set.exclude(pk__in=participated_threads):
+        thread.delete()
+
+    # close threads with single participant, delete empty ones
+    for thread in category.thread_set.iterator():
+        participants_count = thread.participants.count()
+        if participants_count == 1:
+            thread.is_closed = True
+            thread.save()
+        elif participants_count == 0:
+            thread.delete()
+            stdout.write(style.ERROR(
+                "Delete empty private thread: %s" % thread.title))
+
+
 def get_special_categories_dict():
 def get_special_categories_dict():
     special_categories = {}
     special_categories = {}
 
 

+ 2 - 1
misago/threads/api/threadpoll.py

@@ -18,7 +18,8 @@ from ..permissions.polls import (
     allow_start_poll,
     allow_start_poll,
     can_start_poll
     can_start_poll
 )
 )
-from ..serializers import EditPollSerializer, NewPollSerializer, PollSerializer, PollVoteSerializer
+from ..serializers import (
+    EditPollSerializer, NewPollSerializer, PollSerializer, PollVoteSerializer)
 from ..viewmodels import ForumThread
 from ..viewmodels import ForumThread
 from .pollvotecreateendpoint import poll_vote_create
 from .pollvotecreateendpoint import poll_vote_create