+ def has_mp3_file(self):
+ return bool(self.has_media("mp3"))
+ has_mp3_file.short_description = 'MP3'
+ has_mp3_file.boolean = True
+
+ def has_ogg_file(self):
+ return bool(self.has_media("ogg"))
+ has_ogg_file.short_description = 'OGG'
+ has_ogg_file.boolean = True
+
+ def has_daisy_file(self):
+ return bool(self.has_media("daisy"))
+ has_daisy_file.short_description = 'DAISY'
+ has_daisy_file.boolean = True
+
+ def build_pdf(self):
+ """ (Re)builds the pdf file.
+
+ """
+ from tempfile import NamedTemporaryFile
+ from os import unlink
+ from django.core.files import File
+ from librarian import pdf
+ from catalogue.utils import ORMDocProvider, remove_zip
+
+ try:
+ pdf_file = NamedTemporaryFile(delete=False)
+ pdf.transform(ORMDocProvider(self),
+ file_path=str(self.xml_file.path),
+ output_file=pdf_file,
+ )
+
+ self.pdf_file.save('%s.pdf' % self.slug, File(open(pdf_file.name)))
+ 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.
+
+ """
+ from tempfile import NamedTemporaryFile
+ from os import unlink
+ from django.core.files import File
+ from librarian import mobi
+ from catalogue.utils import ORMDocProvider, remove_zip
+
+ try:
+ mobi_file = NamedTemporaryFile(suffix='.mobi', delete=False)
+ mobi.transform(ORMDocProvider(self), verbose=1,
+ file_path=str(self.xml_file.path),
+ output_file=mobi_file.name,
+ )
+
+ self.mobi_file.save('%s.mobi' % self.slug, File(open(mobi_file.name)))
+ 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.
+ Unless remove_descendants is False, descendants' epubs are removed.
+ """
+ from StringIO import StringIO
+ from hashlib import sha1
+ from django.core.files.base import ContentFile
+ from librarian import epub, NoDublinCore
+ from catalogue.utils import ORMDocProvider, remove_zip
+
+ if self.parent:
+ # don't need an epub
+ return
+
+ epub_file = StringIO()
+ try:
+ epub.transform(ORMDocProvider(self), self.slug, output_file=epub_file)
+ self.epub_file.save('%s.epub' % self.slug, ContentFile(epub_file.getvalue()))
+ FileRecord(slug=self.slug, type='epub', sha1=sha1(epub_file.getvalue()).hexdigest()).save()
+ except NoDublinCore:
+ pass
+
+ book_descendants = list(self.children.all())
+ while len(book_descendants) > 0:
+ child_book = book_descendants.pop(0)
+ if remove_descendants and child_book.has_epub_file():
+ child_book.epub_file.delete()
+ # save anyway, to refresh short_html
+ 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
+ from librarian import text
+
+ out = StringIO()
+ text.transform(open(self.xml_file.path), out)
+ self.txt_file.save('%s.txt' % self.slug, ContentFile(out.getvalue()))
+
+
+ def build_html(self):
+ from tempfile import NamedTemporaryFile
+ from markupstring import MarkupString
+ from django.core.files import File
+ from slughifi import slughifi
+ from librarian import html
+
+ meta_tags = list(self.tags.filter(
+ category__in=('author', 'epoch', 'genre', 'kind')))
+ book_tag = self.book_tag()
+
+ html_file = NamedTemporaryFile()
+ if html.transform(self.xml_file.path, html_file, parse_dublincore=False):
+ self.html_file.save('%s.html' % self.slug, File(html_file))
+
+ # get ancestor l-tags for adding to new fragments
+ ancestor_tags = []
+ p = self.parent
+ while p:
+ ancestor_tags.append(p.book_tag())
+ p = p.parent
+
+ # Delete old fragments and create them from scratch
+ self.fragments.all().delete()
+ # Extract fragments
+ closed_fragments, open_fragments = html.extract_fragments(self.html_file.path)
+ for fragment in closed_fragments.values():
+ try:
+ theme_names = [s.strip() for s in fragment.themes.split(',')]
+ except AttributeError:
+ continue
+ themes = []
+ for theme_name in theme_names:
+ if not theme_name:
+ continue
+ tag, created = Tag.objects.get_or_create(slug=slughifi(theme_name), category='theme')
+ if created:
+ tag.name = theme_name
+ tag.sort_key = theme_name.lower()
+ tag.save()
+ themes.append(tag)
+ if not themes:
+ continue
+
+ text = fragment.to_string()
+ short_text = ''
+ if (len(MarkupString(text)) > 240):
+ short_text = unicode(MarkupString(text)[:160])
+ new_fragment = Fragment.objects.create(anchor=fragment.id, book=self,
+ text=text, short_text=short_text)
+
+ new_fragment.save()
+ new_fragment.tags = set(meta_tags + themes + [book_tag] + ancestor_tags)
+ self.save()
+ self.html_built.send(sender=self)
+ return True
+ return False
+
+ @staticmethod
+ 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()
+
+ def zip_audiobooks(self):
+ 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()