Off by one error
[wolnelektury.git] / apps / 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
10
11 class Command(BaseCommand):
12     option_list = BaseCommand.option_list + (
13         make_option('-q', '--quiet', action='store_false', dest='verbose', default=True,
14             help='Suppress output'),
15         make_option('-d', '--dry-run', action='store_true', dest='dry_run', default=False,
16             help="Just check for problems, don't fix them"),
17     )
18     help = 'Checks integrity of catalogue data.'
19
20     def handle(self, **options):
21         from django.db import transaction
22
23         verbose = options['verbose']
24
25         with transaction.commit_on_success():
26             for book in Book.objects.all().iterator():
27                 try:
28                     info = book.wldocument().book_info
29                 except:
30                     if verbose:
31                         print "ERROR! Bad XML for book:", book.slug
32                         print "To resolve: republish."
33                         print
34                 else:
35                     should_be = [p.slug for p in info.parts]
36                     is_now = [p.slug for p in book.children.all().order_by('parent_number')]
37                     if should_be != is_now:
38                         if verbose:
39                             print "ERROR! Wrong children for book:", book.slug
40                             print "Is:       ", is_now
41                             print "Should be:", should_be
42                             print "To resolve: republish parent book."
43                             print
44
45                 # Check for parent l-tags.
46                 parents = []
47                 parent = book.parent
48                 while parent:
49                     parents.append(parent)
50                     parent = parent.parent
51                 ltags = [b.book_tag() for b in parents]
52                 if set(ltags) != set(book.tags.filter(category='book')):
53                     if options['verbose']:
54                         print "Wrong book tags for book:", book
55                         print "Is:       ", ", ".join(sorted(t.slug for t in book.tags.filter(category='book')))
56                         print "Should be:", ", ".join(sorted(t.slug for t in ltags))
57                     if not options['dry_run']:
58                         book.tags = ltags + list(book.tags.exclude(category='book'))
59                         if options['verbose']:
60                             print "Fixed."
61                     if options['verbose']:
62                         print
63
64                 # TODO: check metadata tags, reset counters