summaryrefslogtreecommitdiffstats
path: root/askbot/management/commands/merge_users.py
blob: 4691c4b3a984edec2c538782688c4ac8de932c8f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
from django.core.management.base import CommandError, BaseCommand
from askbot.models import User


class Command(BaseCommand):
    args = '<from_user_id> <to_user_id>'
    help = 'Merge an account and all information from a <user_id> to a <user_id>, deleting the <from_user>'

    def parse_arguments(self, *arguments):
        if len(arguments) != 2:
            raise CommandError('Arguments are <from_user_id> to <to_user_id>')
        self.from_user = User.objects.get(id = arguments[0])
        self.to_user = User.objects.get(id = arguments[1])

    def handle(self, *arguments, **options):
        self.parse_arguments(*arguments)

        for rel in User._meta.get_all_related_objects():
            try:
                self.process_field(rel.model, rel.field.name)
            except Exception, error:
                self.stdout.write(u'Warning: %s\n' % error)

        for rel in User._meta.get_all_related_many_to_many_objects():
            try:
                self.process_m2m_field(rel.model, rel.field.name)
            except Exception, error:
                self.stdout.write(u'Warning: %s\n' % error)
           
        self.to_user.reputation += self.from_user.reputation - 1
        self.to_user.gold += self.from_user.gold
        self.to_user.silver += self.from_user.silver
        self.to_user.bronze += self.from_user.bronze

        if self.from_user.last_seen > self.to_user.last_seen:
            self.to_user.last_seen = self.from_user.last_seen

        if self.from_user.date_joined < self.to_user.date_joined:
            self.to_user.date_joined = self.from_user.date_joined

        self.to_user.save()

        self.from_user.delete()

    def process_field(self, model, field_name):
        """reassigns the related object to the new user"""
        filter_condition = {field_name: self.from_user}
        related_objects_qs = model.objects.filter(**filter_condition)
        update_condition = {field_name: self.to_user}
        related_objects_qs.update(**update_condition)

    def process_m2m_field(self, model, field_name):
        """removes the old user from the M2M relation
        and adds the new user"""
        filter_condition = {field_name: self.from_user}
        related_objects_qs = model.objects.filter(**filter_condition)
        for obj in related_objects_qs:
            m2m_field = getattr(obj, field_name)
            m2m_field.remove(self.from_user)
            m2m_field.add(self.to_user)