report bad audiobooks,
[wolnelektury.git] / apps / catalogue / models.py
index a0f737f..bb20774 100644 (file)
@@ -12,6 +12,7 @@ from django.utils.translation import ugettext_lazy as _
 from django.contrib.auth.models import User
 from django.core.files import File
 from django.template.loader import render_to_string
 from django.contrib.auth.models import User
 from django.core.files import File
 from django.template.loader import render_to_string
+from django.utils.datastructures import SortedDict
 from django.utils.safestring import mark_safe
 from django.utils.translation import get_language
 from django.core.urlresolvers import reverse
 from django.utils.safestring import mark_safe
 from django.utils.translation import get_language
 from django.core.urlresolvers import reverse
@@ -306,6 +307,7 @@ class Book(models.Model):
     tags     = managers.TagDescriptor(Tag)
 
     html_built = django.dispatch.Signal()
     tags     = managers.TagDescriptor(Tag)
 
     html_built = django.dispatch.Signal()
+    published = django.dispatch.Signal()
 
     class AlreadyExists(Exception):
         pass
 
     class AlreadyExists(Exception):
         pass
@@ -615,6 +617,7 @@ class Book(models.Model):
                     for b in books]
         result = create_zip.delay(paths,
                     getattr(settings, "ALL_%s_ZIP" % format_.upper()))
                     for b in books]
         result = create_zip.delay(paths,
                     getattr(settings, "ALL_%s_ZIP" % format_.upper()))
+        return result.wait()
 
     def zip_audiobooks(self):
         bm = BookMedia.objects.filter(book=self, type='mp3')
 
     def zip_audiobooks(self):
         bm = BookMedia.objects.filter(book=self, type='mp3')
@@ -733,6 +736,7 @@ class Book(models.Model):
         book.reset_tag_counter()
         book.reset_theme_counter()
 
         book.reset_tag_counter()
         book.reset_theme_counter()
 
+        cls.published.send(sender=book)
         return book
 
     def reset_tag_counter(self):
         return book
 
     def reset_tag_counter(self):
@@ -826,6 +830,43 @@ class Book(models.Model):
 
         return objects
 
 
         return objects
 
+    @classmethod
+    def book_list(cls, filter=None):
+        """Generates a hierarchical listing of all books.
+
+        Books are optionally filtered with a test function.
+
+        """
+
+        books_by_parent = {}
+        books = cls.objects.all().order_by('parent_number', 'sort_key').only('title', 'parent', 'slug')
+        if filter:
+            books = books.filter(filter).distinct()
+            book_ids = set((book.pk for book in books))
+            for book in books:
+                parent = book.parent_id
+                if parent not in book_ids:
+                    parent = None
+                books_by_parent.setdefault(parent, []).append(book)
+        else:
+            for book in books:
+                books_by_parent.setdefault(book.parent_id, []).append(book)
+
+        orphans = []
+        books_by_author = SortedDict()
+        for tag in Tag.objects.filter(category='author'):
+            books_by_author[tag] = []
+
+        for book in books_by_parent.get(None,()):
+            authors = list(book.tags.filter(category='author'))
+            if authors:
+                for author in authors:
+                    books_by_author[author].append(book)
+            else:
+                orphans.append(book)
+
+        return books_by_author, orphans, books_by_parent
+
 
 def _has_factory(ftype):
     has = lambda self: bool(getattr(self, "%s_file" % ftype))
 
 def _has_factory(ftype):
     has = lambda self: bool(getattr(self, "%s_file" % ftype))