fixes #932: bookimport works with parent-child relations in unsorted xml files
authorRadek Czajka <radoslaw.czajka@nowoczesnapolska.org.pl>
Tue, 2 Nov 2010 13:45:04 +0000 (14:45 +0100)
committerRadek Czajka <radoslaw.czajka@nowoczesnapolska.org.pl>
Tue, 2 Nov 2010 13:45:04 +0000 (14:45 +0100)
apps/catalogue/management/commands/importbooks.py
apps/catalogue/models.py

index ffe0de8..be65bd9 100644 (file)
@@ -44,7 +44,11 @@ class Command(BaseCommand):
             if not os.path.isdir(dir_name):
                 print self.style.ERROR("%s: Not a directory. Skipping." % dir_name)
             else:
-                for file_name in sorted(os.listdir(dir_name)):
+                # files queue
+                files = sorted(os.listdir(dir_name))
+                postponed = {}
+                while files:
+                    file_name = files.pop(0)
                     file_path = os.path.join(dir_name, file_name)
                     file_base, ext = os.path.splitext(file_path)
 
@@ -99,6 +103,17 @@ class Command(BaseCommand):
                             file_path)
                         files_skipped += 1
 
+                    except Book.DoesNotExist, e:
+                        if file_name not in postponed or postponed[file_name] < files_imported:
+                            # push it back into the queue, maybe the missing child will show up
+                            if verbose:
+                                print self.style.NOTICE('Waiting for missing children')
+                            files.append(file_name)
+                            postponed[file_name] = files_imported
+                        else:
+                            # we're in a loop, nothing's being imported - some child is really missing
+                            raise e
+
         # Print results
         print
         print "Results: %d files imported, %d skipped, %d total." % (
index eb55b98..b1ffdb6 100644 (file)
@@ -395,6 +395,17 @@ class Book(models.Model):
         from markupstring import MarkupString
         from django.core.files.storage import default_storage
 
+        # check for parts before we do anything
+        children = []
+        if hasattr(book_info, 'parts'):
+            for part_url in book_info.parts:
+                base, slug = part_url.rsplit('/', 1)
+                try:
+                    children.append(Book.objects.get(slug=slug))
+                except Book.DoesNotExist, e:
+                    raise Book.DoesNotExist(_('Book with slug = "%s" does not exist.') % slug)
+
+
         # Read book metadata
         book_base, book_slug = book_info.url.rsplit('/', 1)
         book, created = Book.objects.get_or_create(slug=book_slug)
@@ -435,16 +446,10 @@ class Book(models.Model):
 
         book_tag = book.book_tag()
 
-        if hasattr(book_info, 'parts'):
-            for n, part_url in enumerate(book_info.parts):
-                base, slug = part_url.rsplit('/', 1)
-                try:
-                    child_book = Book.objects.get(slug=slug)
-                    child_book.parent = book
-                    child_book.parent_number = n
-                    child_book.save()
-                except Book.DoesNotExist, e:
-                    raise Book.DoesNotExist(_('Book with slug = "%s" does not exist.') % slug)
+        for n, child_book in enumerate(children):
+            child_book.parent = book
+            child_book.parent_number = n
+            child_book.save()
 
         # Save XML and HTML files
         book.xml_file.save('%s.xml' % book.slug, raw_file, save=False)