def __init__(self, *args, **kwargs):
super(DownloadFormatsForm, self).__init__(*args, **kwargs)
+
+PDF_PAGE_SIZES = (
+ ('a4paper', _('A4')),
+ ('a5paper', _('A5')),
+)
+
+
+PDF_LEADINGS = (
+ ('', _('Normal leading')),
+ ('onehalfleading', _('One and a half leading')),
+ ('doubleleading', _('Double leading')),
+ )
+
+PDF_FONT_SIZES = (
+ ('11pt', _('Default')),
+ ('13pt', _('Big'))
+ )
+
+
+class CustomPDFForm(forms.Form):
+ nofootnotes = forms.BooleanField(required=False, label=_("Don't show footnotes"))
+ nothemes = forms.BooleanField(required=False, label=_("Don't disply themes"))
+ nowlfont = forms.BooleanField(required=False, label=_("Don't use our custom font"))
+ ## pagesize = forms.ChoiceField(PDF_PAGE_SIZES, required=True, label=_("Paper size"))
+ leading = forms.ChoiceField(PDF_LEADINGS, required=False, label=_("Leading"))
+ fontsize = forms.ChoiceField(PDF_FONT_SIZES, required=True, label=_("Font size"))
+
+ @property
+ def customizations(self):
+ c = []
+ if self.cleaned_data['nofootnotes']:
+ c.append('nofootnotes')
+
+ if self.cleaned_data['nothemes']:
+ c.append('nothemes')
+
+ if self.cleaned_data['nowlfont']:
+ c.append('nowlfont')
+
+ ## c.append(self.cleaned_data['pagesize'])
+ c.append(self.cleaned_data['fontsize'])
+
+ if self.cleaned_data['leading']:
+ c.append(self.cleaned_data['leading'])
+
+ c.sort()
+
+ return c
+
from newtagging import managers
from catalogue.fields import JSONField, OverwritingFileField
from catalogue.utils import create_zip
+from shutil import copy
+
+from os import path
TAG_CATEGORIES = (
return '/'.join((Tag.categories_dict[self.category], self.slug))
+def get_dynamic_path(media, filename, ext=None, maxlen=100):
+ from slughifi import slughifi
+
+ # how to put related book's slug here?
+ if not ext:
+ if media.type == 'daisy':
+ ext = 'daisy.zip'
+ else:
+ ext = media.type
+ if media is None or not media.name:
+ name = slughifi(filename.split(".")[0])
+ else:
+ name = slughifi(media.name)
+ return 'book/%s/%s.%s' % (ext, name[:maxlen-len('book/%s/.%s' % (ext, ext))-4], ext)
+
+
# TODO: why is this hard-coded ?
def book_upload_path(ext=None, maxlen=100):
- def get_dynamic_path(media, filename, ext=ext):
- from slughifi import slughifi
-
- # how to put related book's slug here?
- if not ext:
- if media.type == 'daisy':
- ext = 'daisy.zip'
- else:
- ext = media.type
- if not media.name:
- name = slughifi(filename.split(".")[0])
- else:
- name = slughifi(media.name)
- return 'book/%s/%s.%s' % (ext, name[:maxlen-len('book/%s/.%s' % (ext, ext))-4], ext)
- return get_dynamic_path
+ return lambda *args: get_dynamic_path(*args, ext=ext, maxlen=maxlen)
class BookMedia(models.Model):
has_daisy_file.short_description = 'DAISY'
has_daisy_file.boolean = True
- def build_pdf(self):
+ def build_pdf(self, customizations=None, file_name=None):
""" (Re)builds the pdf file.
-
+ customizations - customizations which are passed to LaTeX class file.
+ file_name - save the pdf file under a different name and DO NOT save it in db.
"""
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
+ from django.core.files.move import file_move_safe
try:
pdf_file = NamedTemporaryFile(delete=False)
pdf.transform(ORMDocProvider(self),
file_path=str(self.xml_file.path),
output_file=pdf_file,
+ customizations=customizations
)
- self.pdf_file.save('%s.pdf' % self.slug, File(open(pdf_file.name)))
+ if file_name is None:
+ self.pdf_file.save('%s.pdf' % self.slug, File(open(pdf_file.name)))
+ else:
+ copy(pdf_file.name, path.join(settings.MEDIA_ROOT, get_dynamic_path(None, file_name, ext='pdf')))
finally:
unlink(pdf_file.name)
from nose.tools import raises
import tempfile
-from os import unlink,path
+from os import unlink, path, makedirs
class BookImportLogicTests(WLTestCase):
parent = models.Book.from_xml_file(input)
parent.build_pdf()
self.assertTrue(path.exists(parent.pdf_file.path))
+
+ def test_custom_pdf(self):
+ out = models.get_dynamic_path(None, 'test-custom', ext='pdf')
+ absoulute_path = path.join(settings.MEDIA_ROOT, out)
+
+ if not path.exists(path.dirname(absoulute_path)):
+ makedirs(path.dirname(absoulute_path))
+
+ self.book.build_pdf(customizations=['nofootnotes', '13pt', 'a4paper'], file_name='test-custom')
+ self.assertTrue(path.exists(absoulute_path))
url(r'^(?P<tags>[a-zA-Z0-9-/]*)/$', 'tagged_object_list', name='tagged_object_list'),
url(r'^audiobooki/(?P<type>mp3|ogg|daisy|all).xml$', AudiobookFeed(), name='audiobook_feed'),
+
+ url(r'^custompdf/(?P<slug>[a-zA-Z0-9-]+).pdf', 'download_custom_pdf'),
)
import time
from base64 import urlsafe_b64encode
+from django.http import HttpResponse, HttpResponseRedirect, Http404, HttpResponsePermanentRedirect
from django.core.files.uploadedfile import UploadedFile
from django.utils.hashcompat import sha_constructor
from django.conf import settings
from zipfile import ZipFile
from librarian import DocProvider
-
+from reporting.utils import read_chunks
+from celery.task import task
+import catalogue.models
# Use the system (hardware-based) random number generator if it exists.
if hasattr(random, 'SystemRandom'):
except OSError as oe:
if oe.errno != ENOENT:
raise oe
+
+
+class AttachmentHttpResponse(HttpResponse):
+ """Response serving a file to be downloaded.
+ """
+ def __init__ (self, file_path, file_name, mimetype):
+ super(AttachmentHttpResponse, self).__init__(mimetype=mimetype)
+ self['Content-Disposition'] = 'attachment; filename=%s' % file_name
+ self.file_path = file_path
+ self.file_name = file_name
+
+ with open(self.file_path) as f:
+ for chunk in read_chunks(f):
+ self.write(chunk)
+
+@task
+def create_custom_pdf(book_id, customizations, file_name):
+ book = catalogue.models.Book.objects.get(id=book_id)
+ if not path.exists(file_name):
+ book.build_pdf(customizations=customizations, file_name=file_name)
from catalogue import models
from catalogue import forms
-from catalogue.utils import split_tags
+from catalogue.utils import split_tags, AttachmentHttpResponse, create_custom_pdf
from pdcounter import models as pdcounter_models
from pdcounter import views as pdcounter_views
from suggest.forms import PublishingSuggestForm
+from os import path
staff_required = user_passes_test(lambda user: user.is_staff)
projects = sorted(projects)
form = forms.SearchForm()
+ custom_pdf_form = forms.CustomPDFForm()
return render_to_response('catalogue/book_detail.html', locals(),
context_instance=RequestContext(request))
else:
raise Http404('No format specified for zip package')
return HttpResponseRedirect(urlquote_plus(settings.MEDIA_URL + url, safe='/?='))
+
+
+def download_custom_pdf(request, slug):
+ book = models.Book.objects.get(slug=slug)
+ if request.method == 'GET':
+ form = forms.CustomPDFForm(request.GET)
+ if form.is_valid():
+ cust = form.customizations
+ h = hash(tuple(cust))
+ pdf_name = '%s-custom-%s' % (book.slug, h)
+ pdf_file = path.join(settings.MEDIA_ROOT, models.get_dynamic_path(None, pdf_name, ext='pdf'))
+
+ if not path.exists(pdf_file):
+ result = create_custom_pdf.delay(book.id, cust, pdf_name)
+ result.wait()
+ return AttachmentHttpResponse(file_name=("%s.pdf" % book.slug), file_path=pdf_file, mimetype="application/pdf")
+ else:
+ raise Http404(_('Incorrect customization options for PDF'))
+ else:
+ raise Http404(_('Bad method'))
padding: 0 10px 0 10px;
}
+#formats .wrap div.download .custom-pdf {
+ text-align: left;
+}
+
+
#czytamysluchajac {
margin-top: 2.5em;
}
}
});
}*/
-
+ $("#custom-pdf-link").toggle(
+ function(ev) { $(".custom-pdf").show(); return false; },
+ function(ev) { $(".custom-pdf").hide(); return false; }
+ );
});
})(jQuery)
{% for media in book.get_odt %}
<a href="{{ media.file.url }}"><img src="{{ STATIC_URL }}img/odt.png" title="{% trans "Download ODT" %} – {% trans "for reading" %} {% trans "and editing using" %} OpenOffice.org: {{ media.name }}" alt="{% trans "Download ODT" %}" /></a>
{% endfor %}
+
+ {% if book.pdf_file %}
+ <br/><a href="#" id="custom-pdf-link">{% trans "Dowload customized PDF" %}</a>.
+ {% endif %}
+ <div style="display: none" class="custom-pdf">
+ <form action="{% url catalogue.views.download_custom_pdf book.slug %}" method="GET">
+ {{custom_pdf_form.as_p}}
+ <input type="submit" value="{% trans "Download" %}"/>
+ </form>
+ </div>
</div>
{% if book.has_mp3_file or book.has_ogg_file or book.has_daisy_file %}
<p class="header">