~dholbach/developer-ubuntu-com/fix-consistency-command

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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
from django.core.management.base import BaseCommand
from django.core.urlresolvers import NoReverseMatch

from cms.models import Page


def find_pages_without_publisher_draft():
    return [p for p in Page.objects.all()
            if not hasattr(p, 'publisher_draft')]


def find_pages_with_broken_slugs():
    page_ids = set()
    for p in Page.objects.all():
        try:
            url = p.get_absolute_url()
        except NoReverseMatch:
            page_ids.add(p.pk)
    return Page.objects.filter(pk__in=page_ids)


def find_duplicates_pages(draft=False):
    urls = []
    for p in Page.objects.filter(publisher_is_draft=draft):
        try:
            url = p.get_absolute_url()
        except NoReverseMatch:
            url = p.get_slug()
        urls += [url]
    return [p for p in Page.objects.filter(publisher_is_draft=draft)
            if urls.count(url) == 2]


def print_pages(pages):
    for p in pages:
        try:
            url = p.get_absolute_url()
        except NoReverseMatch:
            url = p.get_slug()
        print('{}: {} ({})'.format
              (p.pk, url,
               'Draft' if p.publisher_is_draft else 'Public'))


def delete_pages(pages):
    for p in pages:
        try:
            url = p.get_absolute_url()
        except NoReverseMatch:
            url = p.get_slug()
        print('Deleting page: {} ({})'.format
              (url,
               'Draft' if p.publisher_is_draft else 'Public'))
        p.delete()


class Command(BaseCommand):
    help = "Make sure the CMS database is consistent."

    def add_arguments(self, parser):
        parser.add_argument(
            '--delete',
            action='store_true',
            dest='delete',
            default=False,
            help='Delete broken and inconsistent entries.')

    def handle(self, *args, **options):
        print('-----------------------------')
        found = False
        pages = find_pages_without_publisher_draft()
        print('Pages without .publisher_draft: {}'.format(len(pages)))
        if pages:
            found = True
            if options['delete']:
                delete_pages(pages)
            else:
                print_pages(pages)

        print('-----------------------------')
        pages = find_pages_with_broken_slugs()
        print('Pages with broken slugs: {}'.format(len(pages)))
        if pages:
            found = True
            if options['delete']:
                delete_pages(pages)
            else:
                print_pages(pages)

        print('-----------------------------')
        pages = find_duplicates_pages(draft=False)
        print('Duplicate public pages: {}'.format(len(pages)))
        if pages:
            print_pages(pages)
            if options['delete']:
                print('Please remove them manually.')

        print('-----------------------------')
        pages = find_duplicates_pages(draft=True)
        print('Duplicate draft pages: {}'.format(len(pages)))
        if pages:
            print_pages(pages)
            if options['delete']:
                print('Please remove them manually.')

        if found and not options['delete']:
            print('-----------------------------')
            print('If you want any inconsistencies fixed, please re-run this '
                  'command with the --delete option.')