X-Git-Url: https://git.mdrn.pl/librarian.git/blobdiff_plain/262c7082c23ab266254175438d1524470996c4d2..3754989331c91f1d78cd5c1904f768a4cf80f07a:/librarian/cover.py?ds=sidebyside diff --git a/librarian/cover.py b/librarian/cover.py index f93e709..be34e26 100644 --- a/librarian/cover.py +++ b/librarian/cover.py @@ -3,8 +3,10 @@ # This file is part of Librarian, licensed under GNU Affero GPLv3 or later. # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. # +import re import Image, ImageFont, ImageDraw, ImageFilter -from librarian import get_resource +from StringIO import StringIO +from librarian import get_resource, OutputFile, URLOpener class TextBox(object): @@ -33,9 +35,10 @@ class TextBox(object): """Skips some vertical space.""" self.height += height - def text(self, text, color='#000', font=None, line_height=20, + def text(self, text, color='#000', font=None, line_height=20, shadow_color=None): """Writes some centered text.""" + text = re.sub(r'\s+', ' ', text) if shadow_color: if not self.shadow_img: self.shadow_img = Image.new('RGBA', self.img.size) @@ -117,9 +120,11 @@ class Cover(object): 'PNG': 'image/png', } - def __init__(self, book_info): - self.author = book_info.author.readable() + def __init__(self, book_info, format=None): + self.author = ", ".join(auth.readable() for auth in book_info.authors) self.title = book_info.title + if format is not None: + self.format = format def pretty_author(self): """Allows for decorating author's name.""" @@ -154,7 +159,7 @@ class Cover(object): self.author_lineskip, self.author_shadow) text_img = tbox.image() img.paste(text_img, (self.author_margin_left, top), text_img) - + top += text_img.size[1] + self.title_top tbox = TextBox( self.width - self.title_margin_left - self.title_margin_right, @@ -178,9 +183,16 @@ class Cover(object): def save(self, *args, **kwargs): return self.image().save(format=self.format, *args, **kwargs) + def output_file(self, *args, **kwargs): + imgstr = StringIO() + self.save(imgstr, *args, **kwargs) + return OutputFile.from_string(imgstr.getvalue()) + class WLCover(Cover): """Default Wolne Lektury cover generator.""" + width = 600 + height = 833 uses_dc_cover = True author_font = ImageFont.truetype( get_resource('fonts/JunicodeWL-Regular.ttf'), 20) @@ -192,44 +204,51 @@ class WLCover(Cover): bar_width = 35 background_color = '#444' author_color = '#444' + default_background = get_resource('res/cover.png') + format = 'JPEG' - epochs = { - u'Starożytność': 0, - u'Średniowiecze': 30, - u'Renesans': 60, - u'Barok': 90, - u'Oświecenie': 120, - u'Romantyzm': 150, - u'Pozytywizm': 180, - u'Modernizm': 210, - u'Dwudziestolecie międzywojenne': 240, - u'Współczesność': 270, + epoch_colors = { + u'Starożytność': '#9e3610', + u'Średniowiecze': '#564c09', + u'Renesans': '#8ca629', + u'Barok': '#a6820a', + u'Oświecenie': '#f2802e', + u'Romantyzm': '#db4b16', + u'Pozytywizm': '#961060', + u'Modernizm': '#7784e0', + u'Dwudziestolecie międzywojenne': '#3044cf', + u'Współczesność': '#06393d', } - def __init__(self, book_info): - super(WLCover, self).__init__(book_info) + def __init__(self, book_info, format=None, image_cache=None): + super(WLCover, self).__init__(book_info, format=format) self.kind = book_info.kind self.epoch = book_info.epoch if book_info.cover_url: - from urllib2 import urlopen - from StringIO import StringIO - - bg_src = urlopen(book_info.cover_url) + url = book_info.cover_url + bg_src = None + if image_cache: + from urllib import quote + try: + bg_src = URLOpener().open(image_cache + quote(url, safe="")) + except: + pass + if bg_src is None: + bg_src = URLOpener().open(url) self.background_img = StringIO(bg_src.read()) bg_src.close() + else: + self.background_img = self.default_background def pretty_author(self): return self.author.upper() def image(self): - from colorsys import hsv_to_rgb - img = Image.new('RGB', (self.width, self.height), self.background_color) draw = ImageDraw.Draw(img) - if self.epoch in self.epochs: - epoch_color = tuple(int(255 * c) for c in hsv_to_rgb( - float(self.epochs[self.epoch]) / 360, .7, .7)) + if self.epoch in self.epoch_colors: + epoch_color = self.epoch_colors[self.epoch] else: epoch_color = '#000' draw.rectangle((0, 0, self.bar_width, self.height), fill=epoch_color) @@ -253,12 +272,12 @@ class WLCover(Cover): cut = (resized[0] - trg_size[0]) / 2 src = src.resize(resized) src = src.crop((cut, 0, src.size[0] - cut, src.size[1])) - + img.paste(src, (self.bar_width, 0)) del src box = TextBox(self.title_box_width, self.height, padding_y=20) - box.text(self.pretty_author(), + box.text(self.pretty_author(), font=self.author_font, line_height=self.author_lineskip, color=self.author_color, @@ -266,7 +285,7 @@ class WLCover(Cover): ) box.skip(10) - box.draw.line((75, box.height, 275, box.height), + box.draw.line((75, box.height, 275, box.height), fill=self.author_color, width=2) box.skip(15) @@ -288,9 +307,9 @@ class WLCover(Cover): # center box_top = (self.height - box_img.size[1]) / 2 - box_left = self.bar_width + (self.width - self.bar_width - + box_left = self.bar_width + (self.width - self.bar_width - box_img.size[0]) / 2 - draw.rectangle((box_left, box_top, + draw.rectangle((box_left, box_top, box_left + box_img.size[0], box_top + box_img.size[1]), fill='#fff') img.paste(box_img, (box_left, box_top), box_img)