From 40110cdb916b003da032cb350fad27bd22f64602 Mon Sep 17 00:00:00 2001 From: Jan Szejko Date: Mon, 7 Aug 2017 15:24:29 +0200 Subject: [PATCH 1/1] add option to select cover class in metadata + kmlu cover --- librarian/book2anything.py | 8 ++++---- librarian/cover.py | 22 ++++++++++++++++++++-- librarian/dcparser.py | 11 ++++++----- librarian/epub.py | 4 ++-- librarian/parser.py | 4 ++-- librarian/pdf.py | 4 ++-- librarian/res/kmlu-logo-white.png | Bin 0 -> 18301 bytes 7 files changed, 36 insertions(+), 17 deletions(-) create mode 100644 librarian/res/kmlu-logo-white.png diff --git a/librarian/book2anything.py b/librarian/book2anything.py index 0dcfd33..0da3b61 100755 --- a/librarian/book2anything.py +++ b/librarian/book2anything.py @@ -9,7 +9,7 @@ import optparse from librarian import DirDocProvider, ParseError from librarian.parser import WLDocument -from librarian.cover import DefaultEbookCover +from librarian.cover import make_cover class Option(object): @@ -92,11 +92,11 @@ class Book2Anything(object): # Add cover support, if any. if cls.uses_cover: if options.image_cache: - def cover_class(*args, **kwargs): - return DefaultEbookCover(image_cache=options.image_cache, *args, **kwargs) + def cover_class(book_info, *args, **kwargs): + return make_cover(book_info, image_cache=options.image_cache, *args, **kwargs) transform_args['cover'] = cover_class elif not cls.cover_optional or options.with_cover: - transform_args['cover'] = DefaultEbookCover + transform_args['cover'] = make_cover # Do some real work try: diff --git a/librarian/cover.py b/librarian/cover.py index 5093de3..9e21cf4 100644 --- a/librarian/cover.py +++ b/librarian/cover.py @@ -369,7 +369,7 @@ class WLCover(Cover): dir_y = 1 if corner_y == 0 else -1 for offset in (-1, 0, 1): draw.line((corner_x, corner_y + dir_y * metr.bleed + offset, - corner_x + dir_x * metr.bleed * line_ratio, corner_y + dir_y * metr.bleed + offset), + corner_x + dir_x * metr.bleed * line_ratio, corner_y + dir_y * metr.bleed + offset), fill='black' if offset == 0 else 'white', width=1) draw.line((corner_x + dir_x * metr.bleed + offset, corner_y, corner_x + dir_x * metr.bleed + offset, corner_y + dir_y * metr.bleed * line_ratio), @@ -539,4 +539,22 @@ class GandalfCover(Cover): format = 'PNG' -DefaultEbookCover = LogoWLCover +class KMLUCover(LogoWLCover): + gradient_logo_height = 58 + gradient_logo_spacing = 25 + gradient_logos = [ + 'res/kmlu-logo-white.png', + 'res/wl-logo-white.png', + 'res/fnp-logo-white.png', + ] + + +COVER_CLASSES = { + 'default': LogoWLCover, + 'kmlu': KMLUCover, +} + + +def make_cover(book_info, *args, **kwargs): + cover_class = COVER_CLASSES[book_info.cover_class] + return cover_class(book_info, *args, **kwargs) diff --git a/librarian/dcparser.py b/librarian/dcparser.py index 0a2822c..b5b1c22 100644 --- a/librarian/dcparser.py +++ b/librarian/dcparser.py @@ -230,10 +230,10 @@ class WorkInfo(object): Field(DCNS('type'), 'type', required=False, multiple=True), Field(DCNS('contributor.editor'), 'editors', - as_person, salias='editor', multiple=True, default=[]), + as_person, salias='editor', multiple=True, required=False), Field(DCNS('contributor.technical_editor'), 'technical_editors', - as_person, salias='technical_editor', multiple=True, default=[]), - Field(DCNS('contributor.funding'), 'funders', salias='funder', multiple=True, default=[]), + as_person, salias='technical_editor', multiple=True, required=False), + Field(DCNS('contributor.funding'), 'funders', salias='funder', multiple=True, required=False), Field(DCNS('contributor.thanks'), 'thanks', required=False), Field(DCNS('date'), 'created_at'), @@ -249,7 +249,7 @@ class WorkInfo(object): Field(DCNS('rights.license'), 'license', required=False), Field(DCNS('rights'), 'license_description'), - Field(PLMETNS('digitisationSponsor'), 'sponsors', multiple=True, default=[]), + Field(PLMETNS('digitisationSponsor'), 'sponsors', multiple=True, required=False), Field(WLNS('digitisationSponsorNote'), 'sponsor_note', required=False), Field(WLNS('developmentStage'), 'stage', required=False), ) @@ -452,7 +452,7 @@ class BookInfo(WorkInfo): Field(DCNS('subject.genre'), 'genres', salias='genre', multiple=True, required=False), Field(DCNS('contributor.translator'), 'translators', - as_person, salias='translator', multiple=True, default=[]), + as_person, salias='translator', multiple=True, required=False), Field(DCNS('relation.hasPart'), 'parts', WLURI, strict=as_wluri_strict, multiple=True, required=False), Field(DCNS('relation.isVariantOf'), 'variant_of', WLURI, strict=as_wluri_strict, required=False), @@ -462,6 +462,7 @@ class BookInfo(WorkInfo): # WLCover-specific. Field(WLNS('coverBarColor'), 'cover_bar_color', required=False), Field(WLNS('coverBoxPosition'), 'cover_box_position', required=False), + Field(WLNS('coverClass'), 'cover_class', default=['default']), Field('pdf-id', 'isbn_pdf', required=False), Field('epub-id', 'isbn_epub', required=False), Field('mobi-id', 'isbn_mobi', required=False), diff --git a/librarian/epub.py b/librarian/epub.py index 95e65f1..397dc51 100644 --- a/librarian/epub.py +++ b/librarian/epub.py @@ -19,7 +19,7 @@ from tempfile import mkdtemp, NamedTemporaryFile from shutil import rmtree from librarian import RDFNS, WLNS, NCXNS, OPFNS, XHTMLNS, DCNS, OutputFile -from librarian.cover import DefaultEbookCover +from librarian.cover import make_cover from librarian import functions, get_resource @@ -565,7 +565,7 @@ def transform(wldoc, verbose=False, style=None, html_toc=False, if cover: if cover is True: - cover = DefaultEbookCover + cover = make_cover cover_file = StringIO() bound_cover = cover(document.book_info) diff --git a/librarian/parser.py b/librarian/parser.py index e4f1340..b312da8 100644 --- a/librarian/parser.py +++ b/librarian/parser.py @@ -5,7 +5,7 @@ # from librarian import ValidationError, NoDublinCore, ParseError, NoProvider from librarian import RDFNS -from librarian.cover import DefaultEbookCover +from librarian.cover import make_cover from librarian import dcparser from xml.parsers.expat import ExpatError @@ -207,7 +207,7 @@ class WLDocument(object): def as_cover(self, cover_class=None, *args, **kwargs): if cover_class is None: - cover_class = DefaultEbookCover + cover_class = make_cover return cover_class(self.book_info, *args, **kwargs).output_file() # for debugging only diff --git a/librarian/pdf.py b/librarian/pdf.py index bbe3a92..652d4bf 100644 --- a/librarian/pdf.py +++ b/librarian/pdf.py @@ -28,7 +28,7 @@ from librarian.dcparser import Person from librarian.parser import WLDocument from librarian import ParseError, DCNS, get_resource, OutputFile from librarian import functions -from librarian.cover import DefaultEbookCover +from librarian.cover import make_cover from .sponsor import sponsor_logo @@ -220,7 +220,7 @@ def transform(wldoc, verbose=False, save_tex=None, morefloats=None, if cover: if cover is True: - cover = DefaultEbookCover + cover = make_cover bound_cover = cover(book_info, width=1200) root.set('data-cover-width', str(bound_cover.width)) root.set('data-cover-height', str(bound_cover.height)) diff --git a/librarian/res/kmlu-logo-white.png b/librarian/res/kmlu-logo-white.png new file mode 100644 index 0000000000000000000000000000000000000000..e595e71333949d829858ba331522c698707d403c GIT binary patch literal 18301 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 P00000NkvXXu0mjf6-hNL literal 0 HcmV?d00001 -- 2.20.1