switch to fnp-django-pagination
[wolnelektury.git] / src / catalogue / management / commands / checkintegrity.py
1 # -*- coding: utf-8 -*-
2 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
3 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
4 #
5 from optparse import make_option
6 from django.core.management.base import BaseCommand
7
8 from catalogue.models import Book
9 from librarian import ParseError
10
11
12 class Command(BaseCommand):
13     option_list = BaseCommand.option_list + (
14         make_option('-q', '--quiet', action='store_false', dest='verbose', default=True,
15                     help='Suppress output'),
16         make_option('-d', '--dry-run', action='store_true', dest='dry_run', default=False,
17                     help="Just check for problems, don't fix them"),
18     )
19     help = 'Checks integrity of catalogue data.'
20
21     def handle(self, **options):
22         from django.db import transaction
23
24         verbose = options['verbose']
25
26         with transaction.atomic():
27             for book in Book.objects.all().iterator():
28                 try:
29                     info = book.wldocument().book_info
30                 except ParseError:
31                     if verbose:
32                         print "ERROR! Bad XML for book:", book.slug
33                         print "To resolve: republish."
34                         print
35                 else:
36                     should_be = [p.slug for p in info.parts]
37                     is_now = [p.slug for p in book.children.all().order_by('parent_number')]
38                     if should_be != is_now:
39                         if verbose:
40                             print "ERROR! Wrong children for book:", book.slug
41                             print "Is:       ", is_now
42                             print "Should be:", should_be
43                             print "To resolve: republish parent book."
44                             print
45
46                 # Check for ancestry.
47                 parents = []
48                 parent = book.parent
49                 while parent:
50                     parents.append(parent)
51                     parent = parent.parent
52                 ancestors = list(book.ancestor.all())
53                 if set(ancestors) != set(parents):
54                     if options['verbose']:
55                         print "Wrong ancestry for book:", book
56                         print "Is:       ", ", ".join(ancestors)
57                         print "Should be:", ", ".join(parents)
58                     if not options['dry_run']:
59                         book.repopulate_ancestors()
60                         if options['verbose']:
61                             print "Fixed."
62                     if options['verbose']:
63                         print
64
65                 # TODO: check metadata tags, reset counters