1 # -*- coding: utf-8 -*-
 
   2 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
 
   3 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 
   5 from datetime import datetime
 
   6 from traceback import print_exc
 
   7 from celery.task import task
 
   8 from django.conf import settings
 
  11 # TODO: move to model?
 
  14         'book_count': tag.get_count(),
 
  15         'changed_at': datetime.now(),
 
  18     type(tag).objects.filter(pk=tag.pk).update(**update_dict)
 
  21 @task(ignore_result=True)
 
  22 def fix_tree_tags(book):
 
  27 def index_book(book_id, book_info=None):
 
  28     from catalogue.models import Book
 
  30         return Book.objects.get(id=book_id).search_index(book_info)
 
  32         print "Exception during index: %s" % e
 
  37 def _build_ebook(book_id, ext, transform):
 
  38     """Generic ebook builder."""
 
  39     from django.core.files import File
 
  40     from catalogue.models import Book
 
  42     book = Book.objects.get(pk=book_id)
 
  43     out = transform(book.wldocument())
 
  44     field_name = '%s_file' % ext
 
  45     # Update instead of saving the model to avoid race condition.
 
  46     getattr(book, field_name).save('%s.%s' % (book.slug, ext),
 
  47             File(open(out.get_filename())),
 
  50     Book.objects.filter(pk=book_id).update(**{
 
  51             field_name: getattr(book, field_name)
 
  55 @task(ignore_result=True)
 
  56 def build_txt(book_id):
 
  57     """(Re)builds the TXT file for a book."""
 
  58     _build_ebook(book_id, 'txt', lambda doc: doc.as_text())
 
  61 @task(ignore_result=True, rate_limit=settings.CATALOGUE_PDF_RATE_LIMIT)
 
  62 def build_pdf(book_id):
 
  63     """(Re)builds the pdf file for a book."""
 
  64     from catalogue.models import Book
 
  65     from catalogue.utils import remove_zip
 
  66     from waiter.utils import clear_cache
 
  68     _build_ebook(book_id, 'pdf',
 
  69         lambda doc: doc.as_pdf(morefloats=settings.LIBRARIAN_PDF_MOREFLOATS))
 
  70     # Remove cached downloadables
 
  71     remove_zip(settings.ALL_PDF_ZIP)
 
  72     book = Book.objects.get(pk=book_id)
 
  73     clear_cache(book.slug)
 
  76 @task(ignore_result=True, rate_limit=settings.CATALOGUE_EPUB_RATE_LIMIT)
 
  77 def build_epub(book_id):
 
  78     """(Re)builds the EPUB file for a book."""
 
  79     from catalogue.utils import remove_zip
 
  81     _build_ebook(book_id, 'epub', lambda doc: doc.as_epub())
 
  82     # remove zip with all epub files
 
  83     remove_zip(settings.ALL_EPUB_ZIP)
 
  86 @task(ignore_result=True, rate_limit=settings.CATALOGUE_MOBI_RATE_LIMIT)
 
  87 def build_mobi(book_id):
 
  88     """(Re)builds the MOBI file for a book."""
 
  89     from catalogue.utils import remove_zip
 
  91     _build_ebook(book_id, 'mobi', lambda doc: doc.as_mobi())
 
  92     # remove zip with all mobi files
 
  93     remove_zip(settings.ALL_MOBI_ZIP)
 
  96 @task(ignore_result=True, rate_limit=settings.CATALOGUE_FB2_RATE_LIMIT)
 
  97 def build_fb2(book_id, *args, **kwargs):
 
  98     """(Re)builds the FB2 file for a book."""
 
  99     from catalogue.utils import remove_zip
 
 101     _build_ebook(book_id, 'fb2', lambda doc: doc.as_fb2())
 
 102     # remove zip with all fb2 files
 
 103     remove_zip(settings.ALL_FB2_ZIP)
 
 106 @task(ignore_result=True, rate_limit=settings.CATALOGUE_CUSTOMPDF_RATE_LIMIT)
 
 107 def build_custom_pdf(book_id, customizations, file_name):
 
 108     """Builds a custom PDF file."""
 
 109     from django.core.files import File
 
 110     from django.core.files.storage import DefaultStorage
 
 111     from catalogue.models import Book
 
 113     print "will gen %s" % DefaultStorage().path(file_name)
 
 114     if not DefaultStorage().exists(file_name):
 
 115         pdf = Book.objects.get(pk=book_id).wldocument().as_pdf(
 
 116                 customizations=customizations,
 
 117                 morefloats=settings.LIBRARIAN_PDF_MOREFLOATS)
 
 118         DefaultStorage().save(file_name, File(open(pdf.get_filename())))
 
 121 @task(ignore_result=True)
 
 122 def build_cover(book_id):
 
 123     """(Re)builds the cover image."""
 
 124     from StringIO import StringIO
 
 125     from django.core.files.base import ContentFile
 
 126     from librarian.cover import WLCover
 
 127     from catalogue.models import Book
 
 129     book = Book.objects.get(pk=book_id)
 
 130     book_info = book.wldocument().book_info
 
 131     cover = WLCover(book_info).image()
 
 133     cover.save(imgstr, 'png')
 
 134     book.cover.save(None, ContentFile(imgstr.getvalue()), save=False)
 
 135     Book.objects.filter(pk=book_id).update(cover=book.cover)