from newtagging.models import TagBase, tags_updated
from newtagging import managers
from catalogue.fields import JSONField, OverwritingFileField
-from catalogue.utils import ExistingFile
+from catalogue.utils import ExistingFile, BookImportDocProvider, create_zip_task, remove_zip
from librarian import dcparser, html, epub, NoDublinCore
import mutagen
from mutagen import id3
from slughifi import slughifi
from sortify import sortify
-
+from os import unlink
TAG_CATEGORIES = (
('author', _('author')),
# not quite, but Django wants you to set a timeout
CACHE_FOREVER = 2419200 # 28 days
+
class TagSubcategoryManager(models.Manager):
def __init__(self, subcategory):
super(TagSubcategoryManager, self).__init__()
class Book(models.Model):
title = models.CharField(_('title'), max_length=120)
- sort_key = models.CharField(_('sort_key'), max_length=120, db_index=True, editable=False)
+ sort_key = models.CharField(_('sort key'), max_length=120, db_index=True, editable=False)
slug = models.SlugField(_('slug'), max_length=120, unique=True, db_index=True)
description = models.TextField(_('description'), blank=True)
created_at = models.DateTimeField(_('creation date'), auto_now_add=True, db_index=True)
xml_file = models.FileField(_('XML file'), upload_to=book_upload_path('xml'), blank=True)
html_file = models.FileField(_('HTML file'), upload_to=book_upload_path('html'), blank=True)
pdf_file = models.FileField(_('PDF file'), upload_to=book_upload_path('pdf'), blank=True)
- epub_file = models.FileField(_('EPUB file'), upload_to=book_upload_path('epub'), blank=True)
- txt_file = models.FileField(_('TXT file'), upload_to=book_upload_path('txt'), blank=True)
-
+ epub_file = models.FileField(_('EPUB file'), upload_to=book_upload_path('epub'), blank=True)
+ txt_file = models.FileField(_('TXT file'), upload_to=book_upload_path('txt'), blank=True)
+
parent = models.ForeignKey('self', blank=True, null=True, related_name='children')
objects = models.Manager()
tagged = managers.ModelTaggedItemManager(Tag)
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
-
+ has_daisy_file.boolean = True
+
+ def build_pdf(self):
+ """ (Re)builds the pdf file.
+
+ """
+ from librarian import pdf
+ from tempfile import NamedTemporaryFile
+ import os
+
+ path, fname = os.path.realpath(self.xml_file.path).rsplit('/', 1)
+ try:
+ pdf_file = NamedTemporaryFile(delete=False)
+ print("%s -> %s" % (self.xml_file.path, pdf_file))
+ pdf.transform(BookImportDocProvider(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)
+
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 DocProvider
-
- class BookImportDocProvider(DocProvider):
- """ used for joined EPUBs """
-
- def __init__(self, book):
- self.book = book
-
- def by_slug(self, slug):
- if slug == self.book.slug:
- return self.book.xml_file
- else:
- return Book.objects.get(slug=slug).xml_file
if self.parent:
# don't need an epub
return True
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_task.delay(paths, settings.ALL_EPUB_ZIP)
+ return settings.MEDIA_URL + 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_task.delay(paths, settings.ALL_PDF_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)
+ result = create_zip_task.delay(paths, self.slug)
+
+ return settings.MEDIA_URL + result.wait()
+
+ def clean_zip_files(self):
+ remove_zip(self.slug)
+ remove_zip(settings.ALL_EPUB_ZIP)
+ remove_zip(settings.ALL_PDF_ZIP)
@classmethod
def from_xml_file(cls, xml_file, **kwargs):
xml_file.close()
@classmethod
- def from_text_and_meta(cls, raw_file, book_info, overwrite=False, build_epub=True, build_txt=True):
+ def from_text_and_meta(cls, raw_file, book_info, overwrite=False, build_epub=True, build_txt=True, build_pdf=True):
import re
# check for parts before we do anything
if not settings.NO_BUILD_EPUB and build_epub:
book.root_ancestor.build_epub()
+ if not settings.NO_BUILD_PDF and build_pdf:
+ book.root_ancestor.build_pdf()
+
book_descendants = list(book.children.all())
# add l-tag to descendants and their fragments
# delete unnecessary EPUB files