X-Git-Url: https://git.mdrn.pl/wolnelektury.git/blobdiff_plain/dec752edfc0f7f863ad78dfe86b08b5e392fdb19..af77776a9ff93ac89cfe941c8a97e3e4cac1bd2e:/apps/catalogue/models.py diff --git a/apps/catalogue/models.py b/apps/catalogue/models.py index 128fe8124..bb207747d 100644 --- a/apps/catalogue/models.py +++ b/apps/catalogue/models.py @@ -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.utils.datastructures import SortedDict from django.utils.safestring import mark_safe from django.utils.translation import get_language from django.core.urlresolvers import reverse @@ -220,10 +221,11 @@ class BookMedia(models.Model): if slughifi(self.name) != slughifi(old.name): self.file.save(None, ExistingFile(self.file.path), save=False, leave=True) + super(BookMedia, self).save(*args, **kwargs) + # remove the zip package for book with modified media remove_zip(self.book.slug) - super(BookMedia, self).save(*args, **kwargs) extra_info = self.get_extra_info_value() extra_info.update(self.read_meta()) self.set_extra_info_value(extra_info) @@ -305,6 +307,7 @@ class Book(models.Model): tags = managers.TagDescriptor(Tag) html_built = django.dispatch.Signal() + published = django.dispatch.Signal() class AlreadyExists(Exception): pass @@ -466,9 +469,6 @@ class Book(models.Model): from tempfile import NamedTemporaryFile import os - # remove zip with all pdf files - remove_zip(settings.ALL_PDF_ZIP) - try: pdf_file = NamedTemporaryFile(delete=False) pdf.transform(ORMDocProvider(self), @@ -480,6 +480,9 @@ class Book(models.Model): finally: unlink(pdf_file.name) + # remove zip with all pdf files + remove_zip(settings.ALL_PDF_ZIP) + def build_mobi(self): """ (Re)builds the MOBI file. @@ -488,9 +491,6 @@ class Book(models.Model): from tempfile import NamedTemporaryFile import os - # remove zip with all pdf files - remove_zip(settings.ALL_MOBI_ZIP) - try: mobi_file = NamedTemporaryFile(suffix='.mobi', delete=False) mobi.transform(ORMDocProvider(self), verbose=1, @@ -502,6 +502,9 @@ class Book(models.Model): finally: unlink(mobi_file.name) + # remove zip with all mobi files + remove_zip(settings.ALL_MOBI_ZIP) + def build_epub(self, remove_descendants=True): """ (Re)builds the epub file. If book has a parent, does nothing. @@ -515,9 +518,6 @@ class Book(models.Model): # don't need an epub return - # remove zip package with all epub files - remove_zip(settings.ALL_EPUB_ZIP) - epub_file = StringIO() try: epub.transform(ORMDocProvider(self), self.slug, output_file=epub_file) @@ -535,6 +535,9 @@ class Book(models.Model): child_book.save() book_descendants += list(child_book.children.all()) + # remove zip package with all epub files + remove_zip(settings.ALL_EPUB_ZIP) + def build_txt(self): from StringIO import StringIO from django.core.files.base import ContentFile @@ -601,35 +604,24 @@ class Book(models.Model): return False @staticmethod - def zip_epub(): - books = Book.objects.all() - - paths = filter(lambda x: x is not None, - map(lambda b: b.epub_file and b.epub_file.path or None, books)) - result = create_zip.delay(paths, settings.ALL_EPUB_ZIP) + def zip_format(format_): + def pretty_file_name(book): + return "%s/%s.%s" % ( + b.get_extra_info_value()['author'], + b.slug, + format_) + + field_name = "%s_file" % format_ + books = Book.objects.filter(parent=None).exclude(**{field_name: ""}) + paths = [(pretty_file_name(b), getattr(b, field_name).path) + for b in books] + result = create_zip.delay(paths, + getattr(settings, "ALL_%s_ZIP" % format_.upper())) return result.wait() - @staticmethod - def zip_pdf(): - books = Book.objects.all() - - paths = filter(lambda x: x is not None, - map(lambda b: b.pdf_file and b.pdf_file.path or None, books)) - result = create_zip.delay(paths, settings.ALL_PDF_ZIP) - return result.wait() - - @staticmethod - def zip_mobi(): - books = Book.objects.all() - - paths = filter(lambda x: x is not None, - map(lambda b: b.mobi_file and b.mobi_file.path or None, books)) - result = create_zip.delay(paths, settings.ALL_MOBI_ZIP) - return settings.MEDIA_URL + result.wait() - def zip_audiobooks(self): - bm = BookMedia.objects.filter(book=self) - paths = map(lambda bm: bm.file.path, bm) + bm = BookMedia.objects.filter(book=self, type='mp3') + paths = map(lambda bm: (None, bm.file.path), bm) result = create_zip.delay(paths, self.slug) return result.wait() @@ -744,6 +736,7 @@ class Book(models.Model): book.reset_tag_counter() book.reset_theme_counter() + cls.published.send(sender=book) return book def reset_tag_counter(self): @@ -837,6 +830,43 @@ class Book(models.Model): 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))