help='Don\'t build EPUB file'),
make_option('-T', '--no-build-txt', action='store_false', dest='build_txt', default=True,
help='Don\'t build TXT file'),
+ make_option('-T', '--no-build-pdf', action='store_false', dest='build_pdf', default=True,
+ help='Don\'t build PDF file'),
make_option('-w', '--wait-until', dest='wait_until', metavar='TIME',
help='Wait until specified time (Y-M-D h:m:s)'),
)
try:
book = Book.from_xml_file(file_path, overwrite=force,
build_epub=options.get('build_epub'),
- build_txt=options.get('build_txt'))
+ build_txt=options.get('build_txt'),
+ build_pdf=options.get('build_pdf'))
files_imported += 1
if os.path.isfile(file_base + '.pdf'):
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
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__()
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, ParseError
+ from tempfile import NamedTemporaryFile
+ import os
+
+ try:
+ path, fname = os.path.realpath(self.xml_file.path).rsplit('/', 1)
+ try:
+ pdf_file = NamedTemporaryFile(delete=False)
+
+ 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)
+
+ except ParseError, e:
+ print '%(file)s:%(name)s:%(message)s; use -v to see more output' % {
+ 'file': self.xml_file.path,
+ 'name': e.__class__.__name__,
+ 'message': e
+ }
+
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
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
"""
def setUp(self):
self._MEDIA_ROOT, settings.MEDIA_ROOT = settings.MEDIA_ROOT, tempfile.mkdtemp(prefix='djangotest_')
- settings.NO_BUILD_EPUB = settings.NO_BUILD_TXT = True
+ settings.NO_BUILD_PDF = settings.NO_BUILD_EPUB = settings.NO_BUILD_TXT = True
def tearDown(self):
shutil.rmtree(settings.MEDIA_ROOT, True)
# -*- coding: utf-8 -*-
-from django.core.files.base import ContentFile
+from __future__ import with_statement
+
+from django.core.files.base import ContentFile, File
from catalogue.test_utils import *
from catalogue import models
from nose.tools import raises
-
+import tempfile
+from os import unlink,path
class BookImportLogicTests(WLTestCase):
self.assertEqual(['Kot'], [tag.name for tag in themes],
'wrong related theme list')
+
+
+class BookImportGenerateTest(WLTestCase):
+ def setUp(self):
+ WLTestCase.setUp(self)
+ self.book_info = BookInfoStub(
+ url=u"http://wolnelektury.pl/example/default-book",
+ about=u"http://wolnelektury.pl/example/URI/default_book",
+ title=u"Default Book",
+ author=PersonStub(("Jim",), "Lazy"),
+ kind="X-Kind",
+ genre="X-Genre",
+ epoch="X-Epoch",
+ )
+
+ self.expected_tags = [
+ ('author', 'jim-lazy'),
+ ('genre', 'x-genre'),
+ ('epoch', 'x-epoch'),
+ ('kind', 'x-kind'),
+ ]
+ self.expected_tags.sort()
+
+ def test_gen_pdf(self):
+ input = open(path.dirname(__file__) + '/but-w-butonierce-but-w-butonierce.xml')
+ book = models.Book.from_text_and_meta(File(input), self.book_info, overwrite=True)
+ book.build_pdf()
+ self.assertTrue(path.exists(book.pdf_file.path))
+
+ def test_gen_pdf_child(self):
+ input = open(path.dirname(__file__) + "/fraszka-do-anusie.xml")
+ book = models.Book.from_text_and_meta(File(input), self.book_info, overwrite=True)
+ book.build_pdf()
+ self.assertTrue(path.exists(book.pdf_file.path))
--- /dev/null
+<?xml version='1.0' encoding='utf-8'?>
+<utwor><rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+xmlns:dc="http://purl.org/dc/elements/1.1/">
+<rdf:Description rdf:about="http://wiki.wolnepodreczniki.pl/Lektury:Jasie%C5%84ski/But/But_w_butonierce">
+<dc:creator xml:lang="pl">Jasieński, Bruno</dc:creator>
+<dc:title xml:lang="pl">But w butonierce</dc:title>
+<dc:relation.isPartOf xml:lang="pl">http://wolnelektury.pl/katalog/lektura/but-w-butonierce</dc:relation.isPartOf>
+<dc:contributor.editor xml:lang="pl">Sekuła, Aleksandra</dc:contributor.editor>
+<dc:contributor.technical_editor xml:lang="pl">Sutkowska, Olga</dc:contributor.technical_editor>
+<dc:publisher xml:lang="pl">Fundacja Nowoczesna Polska</dc:publisher>
+<dc:subject.period xml:lang="pl">Dwudziestolecie międzywojenne</dc:subject.period>
+<dc:subject.type xml:lang="pl">Liryka</dc:subject.type>
+<dc:subject.genre xml:lang="pl">Wiersz sylabotoniczny</dc:subject.genre>
+<dc:description xml:lang="pl">Publikacja zrealizowana w ramach projektu Wolne Lektury (http://wolnelektury.pl). Reprodukcja cyfrowa wykonana przez Bibliotekę Narodową z egzemplarza pochodzącego ze zbiorów BN.</dc:description>
+<dc:identifier.url xml:lang="pl">http://wolnelektury.pl/katalog/lektura/but-w-butonierce-but-w-butonierce</dc:identifier.url>
+<dc:source.URL xml:lang="pl">http://www.polona.pl/Content/14667/27384_But_w_butoni.html</dc:source.URL>
+<dc:source xml:lang="pl">Jasieński, Bruno (1901-1938), But w butonierce, Klub Futurystów "Katarynka", Warszawa, 1921</dc:source>
+<dc:rights xml:lang="pl">Domena publiczna - Bruno Jasieński zm. 1938</dc:rights>
+<dc:date.pd xml:lang="pl">1938</dc:date.pd>
+<dc:format xml:lang="pl">xml</dc:format>
+<dc:type xml:lang="pl">text</dc:type>
+<dc:type xml:lang="en">text</dc:type>
+<dc:date xml:lang="pl">2009-02-23</dc:date>
+<dc:audience xml:lang="pl">L</dc:audience>
+<dc:language xml:lang="pl">pol</dc:language>
+</rdf:Description>
+</rdf:RDF><liryka_l>
+
+<autor_utworu>Bruno Jasieński</autor_utworu>
+
+<dzielo_nadrzedne>But w butonierce</dzielo_nadrzedne>
+
+<nazwa_utworu>But w butonierce</nazwa_utworu>
+
+
+
+<strofa>Zmarnowałem podeszwy w całodziennych spieszeniach,/
+Teraz jestem słoneczny, siebiepewny i rad./
+Idę młody, genialny, trzymam ręce w kieszeniach,/
+Stawiam kroki milowe, zamaszyste, jak świat.</strofa>
+
+<strofa>Nie zatrzymam się nigdzie na rozstajach, na wiorstach,/
+Bo mnie niesie coś wiecznie, motorycznie i przed./
+Mijam strachy na wróble w eleganckich windhorstach,/
+Wszystkim kłaniam się grzecznie i poprawiam im pled.</strofa>
+
+<strofa>W parkocieniu krokietni --- jakiś meeting panieński./
+Dyskutują o sztuce, objawiając swój traf./
+One jeszcze nie wiedzą, że, gdy nastał Jasieński,/
+Bezpowrotnie umarli i Tetmajer i Staff.</strofa>
+
+<strofa>One jeszcze nie wiedzą, one jeszcze nie wierzą./
+Poezyjność, futuryzm --- niewiadoma i X./
+Chodźmy biegać, panienki, niech się główki oświeżą, ---/
+Będzie lepiej smakować poobiedni jour-fixe.</strofa>
+
+<strofa>Przeleciało gdzieś auto w białych kłębach benzyny,/
+Zafurkotał na wietrze trzepocący się szal./
+Pojechała mi bajka poza góry doliny/
+I nic jakoś mi nie żal, a powinno być żal...</strofa>
+
+<strofa>Tak mi dobrze, tak mojo, aż rechoce się serce./
+Same nogi mnie niosą gdzieś --- i po co mi, gdzie?/
+Idę młody, genialny, niosę BUT W BUTONIERCE<extra>wersaliki</extra>,/
+Tym co za mną nie zdążą echopowiem: --- Adieu! ---</strofa>
+
+</liryka_l></utwor>
--- /dev/null
+<?xml version='1.0' encoding='utf-8'?>
+<utwor>
+ <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/">
+<rdf:Description rdf:about="http://wiki.wolnepodreczniki.pl/index.php?title=Lektury:S%C4%99p-Szarzy%C5%84ski/Rytmy/Fraszka_do_Anusie">
+<dc:creator xml:lang="pl">Sęp Szarzyński, Mikołaj</dc:creator>
+<dc:title xml:lang="pl">Fraszka do Anusie</dc:title>
+<dc:contributor.editor xml:lang="pl">Sekuła, Aleksandra</dc:contributor.editor>
+<dc:contributor.technical_editor xml:lang="pl">Sutkowska, Olga</dc:contributor.technical_editor>
+<dc:publisher xml:lang="pl">Fundacja Nowoczesna Polska</dc:publisher>
+<dc:subject.period xml:lang="pl">Barok</dc:subject.period>
+<dc:subject.type xml:lang="pl">Liryka</dc:subject.type>
+<dc:subject.genre xml:lang="pl">Fraszka</dc:subject.genre>
+<dc:description xml:lang="pl">Publikacja zrealizowana w ramach projektu Wolne Lektury (http://wolnelektury.pl). Reprodukcja cyfrowa wykonana przez Bibliotekę Narodową z egzemplarza pochodzącego ze zbiorów BN.</dc:description>
+<dc:identifier.url xml:lang="pl">http://wolnelektury.pl/katalog/lektura/fraszka-do-anusie</dc:identifier.url>
+<dc:source.URL xml:lang="pl">http://www.polona.pl/Content/8759</dc:source.URL>
+<dc:source xml:lang="pl">Szarzyński Sęp, Mikołaj (ca 1550-1581), Rytmy abo Wiersze polskie w wyborze, E. Wende, Warszawa, 1914</dc:source>
+<dc:rights xml:lang="pl">Domena publiczna - Mikołaj Sęp Szarzyński zm. 1581</dc:rights>
+<dc:date.pd xml:lang="pl">1581</dc:date.pd>
+<dc:format xml:lang="pl">xml</dc:format>
+<dc:type xml:lang="pl">text</dc:type>
+<dc:type xml:lang="en">text</dc:type>
+<dc:date xml:lang="pl">2008-12-29</dc:date>
+<dc:audience xml:lang="pl">L</dc:audience>
+<dc:audience xml:lang="pl">L</dc:audience>
+<dc:language xml:lang="pl">pol</dc:language>
+</rdf:Description>
+</rdf:RDF>
+ <liryka_l>
+
+<autor_utworu>Mikołaj Sęp Szarzyński</autor_utworu>
+
+<nazwa_utworu>Fraszka do Anusie</nazwa_utworu>
+
+
+
+<strofa><begin id="b1230084410751"/><motyw id="m1230084410751">Kochanek, Łzy, Miłość, Oko, Serce, Wzrok</motyw>Jeśli oczu hamować swoich nie umiały/
+Leśnych krynic boginie, aby nie płakały,/
+Gdy baczyły<pe><slowo_obce>baczyły</slowo_obce> --- tu: zobaczyły, patrzyły na.</pe> przy studni Narcyza pięknego,/
+A on umarł prze miłość oblicza swojego;/
+Jeśli nieśmiertelnym stanom żałość rozkazuje,/
+Gdy niebaczna fortuna co niesłusznie psuje:</strofa>
+
+<strofa>Jakoż ja mam hamować, by na lice moje/
+Z oczu smutnych żałośne nie płynęły zdroje?/
+Jako serce powściągać, aby nie wzdychało/
+I od ciężkiej żałości omdlewać nie miało?<end id="e1230084410751"/></strofa>
+
+</liryka_l>
+</utwor>
from django.utils.hashcompat import sha_constructor
from django.conf import settings
+from librarian import DocProvider
+
# Use the system (hardware-based) random number generator if it exists.
if hasattr(random, 'SystemRandom'):
def close(self):
pass
+
+
+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