fixes #932: bookimport works with parent-child relations in unsorted xml files
[wolnelektury.git] / apps / catalogue / management / commands / importbooks.py
index 239da77..be65bd9 100644 (file)
@@ -1,3 +1,7 @@
+# -*- coding: utf-8 -*-
+# This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
+# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
+#
 import os
 import sys
 from optparse import make_option
@@ -35,34 +39,42 @@ class Command(BaseCommand):
 
         files_imported = 0
         files_skipped = 0
-        
+
         for dir_name in directories:
             if not os.path.isdir(dir_name):
                 print self.style.ERROR("%s: Not a directory. Skipping." % dir_name)
             else:
-                for file_name in 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)
-                    
+
                     # Skip files that are not XML files
                     if not ext == '.xml':
                         continue
-                    
+
                     if verbose > 0:
                         print "Parsing '%s'" % file_path
                     else:
                         sys.stdout.write('.')
                         sys.stdout.flush()
-                    
+
                     # Import book files
                     try:
                         book = Book.from_xml_file(file_path, overwrite=force)
                         files_imported += 1
-                        
+
                         if os.path.isfile(file_base + '.pdf'):
                             book.pdf_file.save('%s.pdf' % book.slug, File(file(file_base + '.pdf')))
                             if verbose:
-                                print "Importing %s.pdf" % file_base 
+                                print "Importing %s.pdf" % file_base
+                        if os.path.isfile(file_base + '.epub'):
+                            book.epub_file.save('%s.epub' % book.slug, File(file(file_base + '.epub')))
+                            if verbose:
+                                print "Importing %s.epub" % file_base
                         if os.path.isfile(file_base + '.odt'):
                             book.odt_file.save('%s.odt' % book.slug, File(file(file_base + '.odt')))
                             if verbose:
@@ -71,20 +83,43 @@ class Command(BaseCommand):
                             book.txt_file.save('%s.txt' % book.slug, File(file(file_base + '.txt')))
                             if verbose:
                                 print "Importing %s.txt" % file_base
-                    
+                        if os.path.isfile(os.path.join(dir_name, book.slug + '.mp3')):
+                            book.mp3_file.save('%s.mp3' % book.slug, File(file(os.path.join(dir_name, book.slug + '.mp3'))))
+                            if verbose:
+                                print "Importing %s.mp3" % book.slug
+                        if os.path.isfile(os.path.join(dir_name, book.slug + '.ogg')):
+                            book.ogg_file.save('%s.ogg' % book.slug, File(file(os.path.join(dir_name, book.slug + '.ogg'))))
+                            if verbose:
+                                print "Importing %s.ogg" % book.slug
+                        if os.path.isfile(os.path.join(dir_name, book.slug + '.daisy.zip')):
+                            book.ogg_file.save('%s.daisy.zip' % book.slug, File(file(os.path.join(dir_name, book.slug + '.daisy.zip'))))
+                            if verbose:
+                                print "Importing %s.daisy.zip" % book.slug
+
                         book.save()
-                    
+
                     except Book.AlreadyExists, msg:
                         print self.style.ERROR('%s: Book already imported. Skipping. To overwrite use --force.' %
                             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." % (
             files_imported, files_skipped, files_imported + files_skipped)
         print
-                        
+
         transaction.commit()
         transaction.leave_transaction_management()